Commit a778c23c authored by xiaoye's avatar xiaoye

fix

parent 11dddfa6
<template>
<uni-card class = 'API'>
<uni-list>
<uni-list-item
v-show = 'api.list.length == 0'
title = '暂无密钥'
>
</uni-list-item>
<view v-for = '(i, v) in api.list'>
<uni-list-item
:clickable = true
>
<template v-slot:header>
<view id = 'header'>
<span>{{ i.name }}</span>
<br>
<span class = 'small'>{{ i.description }}</span>
<br v-if = 'i.expireAt'>
<span class = 'small' v-if = 'i.expireAt'>{{ `过期时间:${new Date(i.expireAt).toLocaleString()}` }}</span>
</view>
</template>
<template v-slot:footer>
<view id = 'footer'>
<view
class = 'button'
@click = 'api.change(v)'
>
<uni-icons :type = "api.changing == v ? 'closeempty' : 'settings'"></uni-icons>
</view>
<view
class = 'button'
@click = 'api.copy(i)'
>
<uni-icons type = 'redo'></uni-icons>
</view>
<view
class = 'button'
style = "border: 1px solid red;"
@click = 'api.del(i)'
>
<uni-icons type = 'trash' color = 'red'></uni-icons>
</view>
</view>
</template>
</uni-list-item>
<uni-forms v-show = 'api.changing == v'>
<uni-datetime-picker type = 'datetime' v-model = 'api.changeInfo.date'/>
<uni-easyinput type = 'text' placeholder = '名称' v-model = 'api.changeInfo.name'/>
<uni-easyinput type = 'text' placeholder = '描述' v-model = 'api.changeInfo.description'/>
<view
class = 'button'
@click = 'api.update(i.id, v)'
>
<uni-icons type = 'upload'></uni-icons>
</view>
</uni-forms>
</view>
<br>
<hr>
<view>
<br>
<h2>添加密钥</h2>
<br>
<uni-forms>
<uni-forms-item>
<uni-datetime-picker type = 'datetime' v-model = 'api.date'/>
<uni-easyinput type = 'text' placeholder = '名称' v-model = 'api.info.name'/>
<uni-easyinput type = 'text' placeholder = '描述' v-model = 'api.info.description'/>
</uni-forms-item>
<view
class = 'button'
@click = 'api.add()'
>
<uni-icons type = 'plusempty'></uni-icons>
</view>
</uni-forms>
</view>
</uni-list>
<br>
<uni-pagination
:current = 'api.page'
v-model = 'api.page'
pageSize = 20
:total = 'api.total'
@change = 'api.search()'
>
</uni-pagination>
</uni-card>
</template>
<script setup lang = 'ts'>
import { ref, reactive, onMounted, onUnmounted, onBeforeMount, watch} from 'vue';
import emitter from '../../script/emitter.ts';
import Const from '../../script/const.ts'
import Mycard from '../../script/mycard.ts';
import ApiKey from '../../script/apikey.ts';
import UniApp from '../../script/uniapp.ts';
import { Tabulator} from '../../script/post.ts';
import { ApiKeyCreateObject, ApiKeyFindObject} from '../../script/type.ts';
let api = reactive({
list : [] as Array<ApiKey>,
page : 1,
total : 0,
search : async () : Promise<void> => {
const res = await Tabulator.ApiKey.FindALL(Mycard.token, {
pageCount : api.page,
userId : Mycard.id
});
api.list = res.api;
api.total = res.total;
},
del : async (i : ApiKey) : Promise<void> => {
if (await Tabulator.ApiKey.Delete(Mycard.token, i.id))
api.search();
},
add : async () : Promise<void> => {
if (await Tabulator.ApiKey.Create(Mycard.token, api.info)) {
api.clear();
api.search();
}
},
clear : () : void => {
api.info = {
name : '',
description : '',
expireAt : undefined as undefined | Date
} as ApiKeyCreateObject;
api.date = '';
},
copy : (i : ApiKey) : void => {
UniApp.copy(i.key);
},
change : (v : number) : void => {
if (api.changing == v) {
api.changing = -1;
api.changeInfo = {
date : '',
name : '',
description : '',
expireAt : undefined as undefined | Date
};
} else {
const i = api.list[v];
api.changeInfo = {
date : i.expireAt,
name : i.name,
description : i.description,
expireAt : new Date(i.expireAt)
};
api.changing = v;
}
},
update : async (id : number, v : number) : Promise<void> => {
if (await Tabulator.ApiKey.Update(Mycard.token, id, {
name : api.changeInfo.name,
description : api.changeInfo.description,
expireAt : api.changeInfo.expireAt
} as ApiKeyCreateObject))
api.search();
},
info : {
name : '',
description : '',
expireAt : undefined as undefined | Date
} as ApiKeyCreateObject,
date : '',
changing : -1,
changeInfo : {
date : '',
name : '',
description : '',
expireAt : undefined as undefined | Date
}
});
watch(() => { return api.date; }, () => {
const toDate = () => {
api.info.expireAt = new Date(api.date);
};
const toUndefined = () => {
api.info.expireAt = undefined;
};
api.date.length > 0 ? toDate() : toUndefined();
});
watch(() => { return api.list; }, () => {
api.changing = -1;
api.changeInfo = {
date : '',
name : '',
description : '',
expireAt : undefined as undefined | Date
};
}, { deep : true });
watch(() => { return api.changeInfo.date; }, () => {
const toDate = () => {
api.changeInfo.expireAt = new Date(api.changeInfo.date);
};
const toUndefined = () => {
api.changeInfo.expireAt = undefined;
};
api.changeInfo.date.length > 0 ? toDate() : toUndefined();
});
onBeforeMount(() : void => {
api.search();
});
onUnmounted(() : void => {
});
</script>
<style lang = 'scss'>
#footer {
display: flex;
justify-content: center;
justify-items: center;
align-items: center;
column-gap: 10%;
}
.small {
margin-top: 6px;
color: #999;
font-size: 12px;
overflow: hidden;
}
</style>
\ No newline at end of file
<template>
<uni-card class = 'Searcher' v-if = 'search'>
<uni-datetime-picker type = 'daterange' v-model = 'search.date'/>
<uni-easyinput
prefixIcon = 'search'
type = 'number'
placeholder = '组织者id'
cancelButton = 'none'
v-model = 'search.creator'
></uni-easyinput>
<view class = 'button' @click = 'search.mine()'>
我组织的比赛
</view>
<uni-easyinput
prefixIcon = 'search'
type = 'text'
placeholder = '比赛名称'
cancelButton = 'none'
v-model = 'search.info.name'
></uni-easyinput>
<uni-easyinput
prefixIcon = 'search'
type = 'number'
placeholder = '比赛id'
cancelButton = 'none'
v-model = 'search.id'
></uni-easyinput>
<uni-data-select
placeholder = '比赛规则'
v-model = 'search.info.rule'
:localdata = 'search.rule.range'
>
</uni-data-select>
<uni-data-select
placeholder = '状态'
v-model = 'search.info.status'
:localdata = 'search.status.range'
>
</uni-data-select>
<uni-data-select
placeholder = '可见性'
v-model = 'search.info.visibility'
:localdata = 'search.visibility.range'
v-show = 'Mycard.id >= 0'
>
</uni-data-select>
<br>
<view class = 'button' @click = 'search.on()'>
<view>
<span>搜索</span>
<uni-icons type = 'search'></uni-icons>
</view>
</view>
</uni-card>
</template>
<script setup lang = 'ts'>
import { ref, reactive, onMounted, onUnmounted, onBeforeMount, watch} from 'vue';
import emitter from '../../script/emitter.ts';
import Const from '../../script/const.ts'
import Mycard from '../../script/mycard.ts';
let search;
const init = (s) : void => {
search = s;
};
onBeforeMount(() : void => {
emitter.on(Const.searcherInit, init)
});
onUnmounted(() : void => {
emitter.off(Const.searcherInit, init)
});
</script>
\ No newline at end of file
......@@ -92,9 +92,9 @@
};
onBeforeMount(() : void => {
emitter.on(Const.searcherInit, init)
emitter.on(Const.settingInit, init)
});
onUnmounted(() : void => {
emitter.off(Const.searcherInit, init)
emitter.off(Const.settingInit, init)
});
</script>
\ No newline at end of file
......@@ -38,7 +38,8 @@
<view
v-show = 'Mycard.id >= 0'
class = 'user'
><span>获取api_key</span></view>
@click = 'page.show.api()'
><span>api_key</span></view>
<hr v-show = 'Mycard.id >= 0'>
<view
v-show = 'Mycard.id >= 0'
......@@ -55,71 +56,19 @@
</uni-card>
</transition>
<transition name = 'move_left'>
<uni-card
<Searcher
class = 'click'
id = 'drawer'
v-show = 'page.drawer && page.menu && !page.create'
v-show = 'page.drawer && page.menu && !(page.create || page.apikey)'
title = '搜索'
:style = "{ '--size' : `${size.width > size.height ? size.width / 4 : size.width / 2}px` }"
>
<uni-datetime-picker type = 'daterange' v-model = 'search.date'/>
<uni-easyinput
prefixIcon = 'search'
type = 'number'
placeholder = '组织者id'
cancelButton = 'none'
v-model = 'search.creator'
></uni-easyinput>
<view class = 'button' @click = 'search.mine()'>
我组织的比赛
</view>
<uni-easyinput
prefixIcon = 'search'
type = 'text'
placeholder = '比赛名称'
cancelButton = 'none'
v-model = 'search.info.name'
></uni-easyinput>
<uni-easyinput
prefixIcon = 'search'
type = 'number'
placeholder = '比赛id'
cancelButton = 'none'
v-model = 'search.id'
></uni-easyinput>
<uni-data-select
placeholder = '比赛规则'
v-model = 'search.info.rule'
:localdata = 'search.rule.range'
>
</uni-data-select>
<uni-data-select
placeholder = '状态'
v-model = 'search.info.status'
:localdata = 'search.status.range'
>
</uni-data-select>
<uni-data-select
placeholder = '可见性'
v-model = 'search.info.visibility'
:localdata = 'search.visibility.range'
v-show = 'Mycard.id >= 0'
>
</uni-data-select>
<br>
<view class = 'button' @click = 'search.on()'>
<view>
<span>搜索</span>
<uni-icons type = 'search'></uni-icons>
</view>
</view>
</uni-card>
></Searcher>
</transition>
<transition name = 'move_left'>
<Setting
class = 'click'
id = 'drawer'
v-show = 'page.drawer && page.tournament && !page.create'
v-show = 'page.drawer && page.tournament && !(page.create || page.apikey)'
title = '比赛设置'
:style = "{ '--size' : `${size.width > size.height ? size.width / 4 : size.width / 2}px` }"
></Setting>
......@@ -134,6 +83,16 @@
>
</Create>
</transition>
<transition name = 'move_left'>
<API
class = 'click'
id = 'drawer'
v-show = 'page.drawer && page.apikey'
title = '我的api密钥'
:style = "{ '--size' : `${size.width > size.height ? size.width / 4 : size.width / 2}px` }"
>
</API>
</transition>
<br>
<transition name = 'switch'>
<view
......@@ -177,9 +136,8 @@
import { ref, reactive, onMounted, onUnmounted, onBeforeMount, watch} from 'vue';
import { TournamentFindObject, TournamentCreateObject, ruleSettings, UserObject } from '../script/type.ts';
import Uniapp from '../script/uniapp.ts';
import {Tabulator, User} from '../script/post.ts';
import { Tabulator, User} from '../script/post.ts';
import Tournament from '../script/tournament.ts';
import ApiKey from '../script/apikey.ts';
import Mycard from '../script/mycard.ts';
import emitter from '../script/emitter.ts'
import Const from '../script/const.ts'
......@@ -187,6 +145,8 @@
import Create from './drawer/creator.vue';
import Pics from './pics.vue';
import Setting from './drawer/setting.vue';
import Searcher from './drawer/searcher.vue';
import API from './drawer/api.vue';
let page = reactive({
user : false,
......@@ -194,6 +154,7 @@
menu : true,
tournament : false,
create : false,
apikey : false,
show : {
user : () : void => {
page.user = !page.user;
......@@ -202,6 +163,8 @@
page.drawer = !page.drawer;
if (!page.drawer && page.create)
page.create = false;
if (!page.drawer && page.apikey)
page.apikey = false;
if (!page.drawer && page.tournament)
tournament.init(tournament.this as Tournament);
},
......@@ -227,6 +190,14 @@
page.create = true;
page.show.drawer();
},
api : async(): Promise<void> => {
if (page.drawer) {
page.show.drawer();
await (new Promise(resolve => setTimeout(resolve, 500)));
}
page.apikey = true;
page.show.drawer();
},
clear : (e) : void => {
let element = e.target;
let chk = false;
......@@ -286,7 +257,8 @@
pageCount : 1,
id : 0,
creator : 0,
before : undefined,
after : undefined,
name : '',
rule : '',
visibility : '',
......@@ -451,7 +423,8 @@
});
onMounted(() => {
emitter.emit(Const.searcherInit, tournament);
emitter.emit(Const.settingInit, tournament);
emitter.emit(Const.searcherInit, search);
});
onUnmounted(() => {
......@@ -463,14 +436,15 @@
});
watch(() => { return search.date; }, () => {
search.date.length > 0 ? () => {
const toDate = () => {
search.info.after = new Date(search.date[0]);
search.info.before = new Date(`${search.date[1]}T23:59:59.999`);
} : () => {
};
const toUndefined = () => {
search.info.after = undefined;
search.info.before = undefined;
}
};
search.date.length > 0 ? toDate() : toUndefined();
});
watch(() => { return search.id; }, () => {
......
<template>
<view class = 'Pics'>
<transition name = 'move_right'>
<view v-show = 'deck.participant'>
<uni-card
v-show = 'deck.participant'
:title = "`${deck.participant?.name ?? '...'} 的卡组`"
>
<!-- <view
class = 'button'
v-show = 'deck.main.length > 0 || deck.side.length > 0'
@click = 'deck.download()'
>
<uni-icons type = 'download'></uni-icons>
</view> -->
<uni-card :title = "deck.main.length > 0 ? '主卡组' : '暂无主卡组'">
<image class = 'deck_cards' v-for = '(i, v) in deck.main' :src = 'getImg(i)' mode = 'aspectFit' @error = 'changeImg.main(v)'></image>
</uni-card>
<uni-card :title = "deck.side.length > 0 ? '副卡组' : '暂无副卡组'">
<image class = 'deck_cards' v-for = '(i, v) in deck.side' :src = 'getImg(i)' mode = 'aspectFit' @error = 'changeImg.main(v)'></image>
</uni-card>
</view>
</uni-card>
</transition>
</view>
</template>
......@@ -17,6 +27,7 @@
import emitter from '../script/emitter.ts'
import Const from '../script/const.ts'
import Participant from '../script/participant.ts';
import Download from '../script/download.js';
const getImg = (i : number) => {
return i == 0 || Math.floor(Math.log10(Math.abs(i))) < 8 ? `https://cdn.233.momobako.com/ygopro/pics/${i}.jpg!half` : `https://cdn02.moecube.com:444/ygopro-super-pre/data/pics/${i}.jpg`
......@@ -36,10 +47,12 @@
chk : false,
main : [] as Array<number>,
side : [] as Array<number>,
blob : undefined as Blob | undefined,
init : (i : {
participant : Participant,
main : Array<number>,
side : Array<number>
side : Array<number>,
blob : Blob,
}) : void => {
if (deck.chk) return;
const participant = i.participant ?? undefined;
......@@ -49,6 +62,7 @@
}
deck.main = i.main;
deck.side = i.side;
deck.blob = i.blob;
deck.participant = participant;
},
off : async () : Promise<void> => {
......@@ -58,6 +72,7 @@
deck.main = [];
deck.side = [];
deck.chk = false;
deck.blob = undefined;
},
clickClear : (e) : void => {
let element = e.target;
......@@ -67,6 +82,9 @@
element = element.parentElement;
}
deck.off();
},
download : () : void => {
Download.start(deck.blob, `${deck.participant?.name}`);
}
});
......@@ -83,5 +101,14 @@
});
</script>
<style scoped lang = 'scss'>
@import '../style/transition.scss';
.button {
border: 1px solid #409eff;
display: flex;
width: 20%;
justify-content: center;
&:hover {
cursor: pointer;
background-color: #e6e6e6;
}
}
</style>
\ No newline at end of file
......@@ -22,7 +22,7 @@
</view>
<view class = 'button' @click = 'page.copyUrl()'>
<span>分享</span>
<uni-icons type = 'redo'></uni-icons>
<uni-icons type = 'paperclip'></uni-icons>
</view>
<view class = 'button' @click = 'page.clear()'>
<span>关闭</span>
......@@ -482,6 +482,7 @@
participant : i,
main : i.getDeck().main,
side : i.getDeck().side,
blob : i.Blob()
})
}
}
......@@ -533,14 +534,7 @@
match.submit.chk = match.array.map(i => [i.player1Score ?? 0, i.player2Score ?? 0]);
},
copyUrl : () => {
uni.setClipboardData({
data : `${window.location.href.split('/?')[0]}`,
success : () => {
uni.showToast({
title : '复制成功'
})
}
})
UniApp.copy(`${window.location.href.split('/?')[0]}`);
}
});
......
......@@ -6,6 +6,7 @@ class ConstData {
createOff = 'createOff';
picsOpen = 'picsOpen';
searcherInit = 'searcherInit';
settingInit = 'settingInit';
}
const Const = new ConstData();
......
class DownloadFile {
start = async (blob, fileName) => {
// #ifdef H5
if (window.showSaveFilePicker) {
let opts = {
suggestedName: `${fileName}.ydk`,
types: [{
description: '',
accept: {
'application/octet-stream': ['.ydk']
}
}],
excludeAcceptAllOption: true
};
let handle = await window.showSaveFilePicker(opts);
let writable = await handle.createWritable();
await writable.write(blob);
await writable.close();
} else {
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = `${fileName}.ydk`;
link.click();
setTimeout(() => {
document.body.removeChild(link);
URL.revokeObjectURL(url);
}, 10000);
}
// #endif
// #ifdef APP-PLUS
// #endif
};
}
const Download = new DownloadFile();
export default Download;
\ No newline at end of file
......@@ -35,6 +35,11 @@ class Participant {
side : this.deck?.side.slice() ?? [],
};
}
Blob = () : Blob => {
const data = this.deck?.toYdkString() ?? '';
return new Blob([data], { type: 'text/plain' });
}
}
export default Participant;
\ No newline at end of file
......@@ -20,6 +20,7 @@ import {
AllTournament,
AllParticipant,
AllMatch,
AllAPI,
UserObject,
TournamentAParticipant
} from './type.ts'
......@@ -485,7 +486,7 @@ class TabulatorAPI {
}
}
}
ApiKeyObject = {
ApiKey = {
Create : async (token : string, Data : ApiKeyCreateObject) : Promise<boolean> => {
let response : {
data : {
......@@ -493,7 +494,11 @@ class TabulatorAPI {
}
};
try {
response = await this.url.post(`/api/api-key`, Data, {
response = await this.url.post(`/api/api-key`, {
name : Data.name,
description : Data.description?.length ?? 0 > 0 ? Data.description : undefined,
expireAt : Data.expireAt?.toISOString() ?? undefined
}, {
headers : {
'x-user-token' : token
}
......@@ -501,6 +506,11 @@ class TabulatorAPI {
return response.data.success;
}
catch(error) {
uni.showModal({
title : '创建失败',
content : error.message,
showCancel : false
});
console.error(error);
return false;
}
......@@ -524,14 +534,15 @@ class TabulatorAPI {
return undefined;
}
},
FindALL : async (token : string, obj : ApiKeyFindObject = {}) : Promise<Array<ApiKey>> => {
FindALL : async (token : string, obj : ApiKeyFindObject = {}) : Promise<AllAPI> => {
let response : {
data : {
data : Array<ApiKeyObject>;
total : number;
}
};
try {
response = await this.url.get(`/api/match`, {
response = await this.url.get(`/api/api-key`, {
params : {
recordsPerPage : 20,
pageCount : obj.pageCount ?? 1,
......@@ -547,11 +558,17 @@ class TabulatorAPI {
response.data.data.forEach((i : ApiKeyObject) => {
keys.push(new ApiKey(i));
})
return keys;
return {
total : response.data.total,
api : keys
};
}
catch(error) {
console.error(error);
return [];
return {
total : 0,
api : []
};
}
},
Update : async (token : string, id : number, Data : ApiKeyCreateObject) : Promise<boolean> => {
......@@ -561,7 +578,12 @@ class TabulatorAPI {
}
};
try {
response = await this.url.patch(`/api/api-key/${id}`, Data, {
console.log(Data.expireAt?.toISOString())
response = await this.url.patch(`/api/api-key/${id}`, {
name : Data.name,
description : Data.description?.length ?? 0 > 0 ? Data.description : '',
expireAt : Data.expireAt?.toISOString() ?? new Date(2038, 0, 1).toISOString()
}, {
headers : {
'x-user-token' : token
}
......
......@@ -121,8 +121,8 @@ interface ApiKeyFindObject {
interface ApiKeyCreateObject {
name : string;
description : string;
expireAt : string;
description ?: string;
expireAt ?: Date;
}
interface ApiKeyObject extends ApiKeyCreateObject {
......@@ -147,6 +147,10 @@ interface AllMatch extends All {
matchs : Array<Match>;
}
interface AllAPI extends All {
api : Array<ApiKey>;
}
interface TournamentAParticipant {
tournament : Tournament | undefined;
participant : AllParticipant
......@@ -182,6 +186,7 @@ export {
AllTournament,
AllParticipant,
AllMatch,
AllAPI,
ruleSettings,
UserObject,
TournamentAParticipant,
......
......@@ -69,6 +69,22 @@ class UniappFuncs {
uni.offDeviceOrientationChange(chk)
// #endif
}
copy (string) : void {
uni.setClipboardData({
data: string,
success: () => {
uni.showToast({
title: '复制成功',
});
},
fail: () => {
uni.showToast({
title: '复制失败',
});
}
});
}
}
const UniApp = new UniappFuncs()
......
......@@ -43,7 +43,7 @@
:deep(.uni-list-item) {
.small {
margin-top: 6rpx;
margin-top: 6px;
color: #999;
font-size: 12px;
overflow: hidden;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment