Browse Source

新增上传/下载存档功能

v1.0
许孟阳 6 days ago
parent
commit
c2aa4ade18
  1. 54
      src/api/base.ts
  2. 24
      src/api/index.ts
  3. 4
      src/config/i18n/zh/index.ts
  4. 1
      src/store/state.ts
  5. 4
      src/tool/crypot.ts
  6. 34
      src/views/archive.vue
  7. 4
      src/views/index.vue
  8. 64
      src/views/login.vue
  9. 1
      src/views/menu.vue

54
src/api/base.ts

@ -1,6 +1,14 @@ @@ -1,6 +1,14 @@
let commit;
export const setCommit = (data) => {
commit = data;
};
export const post = (url, data) => {
const options = {
const t = new Date().getTime();
data.t = t;
const options: any = {
method: 'POST',
credentials: 'same-origin', // 设置为 同源 以发送 Cookie
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json',
@ -8,8 +16,46 @@ export const post = (url, data) => { @@ -8,8 +16,46 @@ export const post = (url, data) => {
};
return new Promise((reslove, reject) => {
fetch(url, options)
.then((response) => response.json())
.then((data) => console.log(data))
.catch((error) => console.error('Error:', error));
.then(responseToJson)
.then((data) => reslove(getResult(data)))
.catch((error) => reslove(false));
});
};
export const get = (url, data?) => {
const t = new Date().getTime();
if (data) {
data.t = t;
const params = new URLSearchParams(data);
url += '?' + params;
} else {
url += '?t=' + t;
}
const options: any = {
method: 'GET',
credentials: 'same-origin', // 设置为 同源 以发送 Cookie
headers: {
'Content-Type': 'application/json',
},
};
return new Promise((reslove, reject) => {
fetch(url.toString(), options)
.then(responseToJson)
.then((data) => reslove(getResult(data)))
.catch((error) => reslove(false));
});
};
const responseToJson = (response) => {
if (response.ok) {
return response.json();
} else {
commit('set_sys_info', { msg: '网络错误', type: 'warning' });
}
};
const getResult = (data) => {
if (data.message) {
commit('set_sys_info', { msg: data.message, type: data.success ? 'win' : 'warning' });
}
return data.data;
};

24
src/api/index.ts

@ -1,11 +1,21 @@ @@ -1,11 +1,21 @@
import { post } from './base';
import { post, get, setCommit } from './base';
let commit;
export { setCommit };
export const setCommit = (data) => {
commit = data;
export const api_root = '/api';
const urls = {
login: api_root + '/public/login',
archive: api_root + '/archive',
};
export const login = (param) => {
post('api/public/login', param);
export const loginOrRegister = (param) => {
return post(urls.login, param);
};
export const getUser = () => {
return get(urls.login);
};
export const uploadArchive = (archive) => {
return post(urls.archive, archive);
};
export const downArchive = () => {
return get(urls.archive);
};

4
src/config/i18n/zh/index.ts

@ -156,6 +156,8 @@ export default class Zh { @@ -156,6 +156,8 @@ export default class Zh {
copyArchive = ['复制存档', '已经复制存档了,建议保存到备忘录', '复制存档失败', '复制旧存档'];
pasteArchive = ['粘贴存档', '粘贴存档内容到输入框成功', '粘贴失败'];
cleanArchive = ['删除存档'];
uploadArchive = '上传存档';
downArchive = '下载存档';
importArchive = ['导入', '导入存档成功,继续游戏吧!', '导入存档失败', '存档版本已过期,无法导入!'];
experiential = ['导入体验存档成功,体验时间${0}分钟。', '体验存档无法保存!', '体验时间已过,自动读取本地存档。'];
@ -165,4 +167,6 @@ export default class Zh { @@ -165,4 +167,6 @@ export default class Zh {
version = ['版本信息和更新日志(U)'];
update = ['版本更新通知', '检测到有服务器有新版本,是否刷新刷新页面更新版本?', '刷新页面', '暂时不管'];
login = ['登录', '用户名', '密码', '登录/注册', '请输入用户名', '请输入密码', '登录成功'];
}

1
src/store/state.ts

@ -36,4 +36,5 @@ export default { @@ -36,4 +36,5 @@ export default {
upward: true,
},
experiential: false,
showLogin: false,
};

4
src/tool/crypot.ts

@ -39,3 +39,7 @@ export const AES_CBC_DECRYPT = (textBase64, secretKey) => { @@ -39,3 +39,7 @@ export const AES_CBC_DECRYPT = (textBase64, secretKey) => {
});
return CryptoJS.enc.Utf8.stringify(decrypt);
};
export const MD5 = (str) => {
return CryptoJS.MD5(str).toString().toUpperCase();
};

34
src/views/archive.vue

@ -14,8 +14,8 @@ @@ -14,8 +14,8 @@
<button class="button" @click="importArchive">{{ t('importArchive.0') }}</button>
</div>
<div class="footer">
<button class="button" @click="uploadArchive">上传存档</button>
<button class="button" @click="uploadArchive">下载存档</button>
<button class="button" @click="uploadArchive">{{ t('uploadArchive') }}</button>
<button class="button" @click="downArchive">{{ t('downArchive') }}</button>
</div>
</Dialog>
@ -27,13 +27,11 @@ import { computed, onMounted, ref, onBeforeUnmount } from "vue"; @@ -27,13 +27,11 @@ import { computed, onMounted, ref, onBeforeUnmount } from "vue";
import { useI18n } from "vue3-i18n";
import { Tooltip, Dialog } from "@/components"
import { menu_icons } from "@/config";
import { getArchive, AES_CBC_ENCRYPT, AES_CBC_DECRYPT, checkImportArchive, saveArchive, replace, archive_version } from "@/tool";
import { setCommit, login } from "@/api";
import { getArchive, AES_CBC_ENCRYPT, AES_CBC_DECRYPT, checkImportArchive, saveArchive, replace, archive_version, MD5 } from "@/tool";
import * as API from "@/api";
const { t } = useI18n();
const { state, commit, dispatch } = useStore();
setCommit(commit);
const showArchive = computed(() => {
return state.curMenu == 'archive';
});
@ -73,8 +71,25 @@ const copyArchive = (archive) => { @@ -73,8 +71,25 @@ const copyArchive = (archive) => {
}
const uploadArchive = () => {
const archive = localStorage.getItem('transmigration_game_archive') || '';
copyArchive(archive);
API.getUser().then(user => {
if (user) {
const palyer = state.playerAttribute.attribute;
const data = { version: archive_version, lv: palyer.lv, coins: palyer.coins, archive: archive.value }
API.uploadArchive(data).then(rsp => rsp && showMenu());
} else {
state.showLogin = true;
}
});
}
const downArchive = () => {
API.getUser().then(user => {
if (user) {
API.downArchive().then(rsp => rsp && showMenu());
} else {
state.showLogin = true;
}
});
}
const pasteArchive = () => {
@ -123,7 +138,6 @@ const keydown = (e) => { @@ -123,7 +138,6 @@ const keydown = (e) => {
}
onMounted(() => {
document.addEventListener('keydown', keydown);
login({ username: 'mengyxu', password: '123456' });
});
onBeforeUnmount(() => {
document.removeEventListener('keydown', keydown);
@ -146,7 +160,7 @@ onMounted(() => { }); @@ -146,7 +160,7 @@ onMounted(() => { });
}
.textarea {
width: 30rem;
width: 25rem;
height: 15rem;
user-select: text;
background: rgba($color: #ffffff, $alpha: 0.8);

4
src/views/index.vue

@ -7,6 +7,7 @@ @@ -7,6 +7,7 @@
<Menu />
</div>
<EquipTips />
<Login />
</template>
<script lang="ts" setup>
@ -16,9 +17,12 @@ import { useI18n } from "vue3-i18n"; @@ -16,9 +17,12 @@ import { useI18n } from "vue3-i18n";
import Message from "./message";
import Menu from "./menu.vue";
import { EquipTips } from "@/components";
import { setCommit } from "@/api";
import Login from "./login.vue";
const { t } = useI18n();
const { state, commit, dispatch } = useStore();
setCommit(commit);
const playFlag = ref(false);
const playBackgound = () => {

64
src/views/login.vue

@ -0,0 +1,64 @@ @@ -0,0 +1,64 @@
<template>
<Dialog :title="t('login.0')" v-model="state.showLogin" :top="state.mobile ? '5rem' : '10rem'"
:left="state.mobile ? '5rem' : '10rem'" padding="0" :z="50" :obscured="true">
<div class="login">
<div class="item">
<div class="label">{{ t('login.1') }}: </div>
<input type="text" v-model="user.username"><br>
</div>
<div class="item">
<div class="label">{{ t('login.2') }}: </div>
<input type="password" v-model="user.passowrd"><br>
</div>
<button class="button" @click="login">{{ t('login.3') }}</button>
</div>
</Dialog>
</template>
<script lang="ts" setup>
import { useStore } from "vuex";
import { reactive, onMounted, ref, computed } from "vue";
import { useI18n } from "vue3-i18n";
import { Dialog } from "@/components";
import { deepCopy, MD5 } from "@/tool";
import { loginOrRegister } from "@/api";
const { t } = useI18n();
const { state, commit, dispatch } = useStore();
const user = reactive({
username: '',
passowrd: '',
})
const login = () => {
const username = user.username;
const passowrd = user.passowrd;
if (!username) {
commit('set_sys_info', { msg: t('login.4'), type: 'warning' })
return;
}
if (!passowrd) {
commit('set_sys_info', { msg: t('login.5'), type: 'warning' })
return;
}
const param = { username: username, passowrd: MD5(passowrd) };
loginOrRegister(param).then(rsp => {
rsp && (state.showLogin = false);
})
}
onMounted(() => { });
</script>
<style lang="scss" scoped>
.login {
padding: 1rem;
.item {
padding: 0.5rem 0;
.label {
text-align: left;
}
}
}
</style>

1
src/views/menu.vue

@ -19,7 +19,6 @@ import { useI18n } from "vue3-i18n"; @@ -19,7 +19,6 @@ import { useI18n } from "vue3-i18n";
import Backpack from "./backpack";
import Shop from "./shop";
import Dungeon from './dungeon';
import Reborn from "./reborn";
import Point from "./point";
import SaveGame from "./save-game.vue";
import Archive from "./archive.vue";

Loading…
Cancel
Save