From 950043254bae4bd53f3d123e9cfcfd0495533b95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A5=9E=E4=BB=A3=E7=B6=BA=E5=87=9B?= Date: Thu, 1 Feb 2024 17:28:20 +0800 Subject: [PATCH] feat: new json storage service fix #265 --- README.md | 1 - src/components/material/DataSyncDialog.vue | 29 --------------- src/data/changelog.json | 8 +++- src/locales/cn/cultivate.json | 3 +- src/locales/jp/cultivate.json | 3 +- src/locales/tw/cultivate.json | 3 +- src/locales/us/cultivate.json | 3 +- src/utils/ajax.js | 43 +++++++++------------- src/views/Home.vue | 5 --- src/views/Material/index.js | 32 ++++------------ 10 files changed, 35 insertions(+), 95 deletions(-) diff --git a/README.md b/README.md index 91cda99a..f839fe93 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,6 @@ - [明日方舟一图流](https://ark.yituliu.cn/)(材料价值数据) - [材料获取最优策略](https://bbs.nga.cn/read.php?tid=17507710)(思路) - [OCR Space](https://ocr.space/)(OCR) -- [ExtendsClass](https://extendsclass.com/json-storage.html)(数据同步) - Wiki - CN - [PRTS Wiki](http://prts.wiki/) - US - [GamePress](https://gamepress.gg/arknights/) diff --git a/src/components/material/DataSyncDialog.vue b/src/components/material/DataSyncDialog.vue index 4711fde7..a7d4a53e 100644 --- a/src/components/material/DataSyncDialog.vue +++ b/src/components/material/DataSyncDialog.vue @@ -50,39 +50,10 @@ > - - -
- - -
- - - - -

{{ $t('cultivate.panel.sync.cloudSyncReadme') }}

-

{{ $t('cultivate.panel.sync.apiKeyReadme') }}

{{ $t('cultivate.panel.sync.autoSyncUploadTip') }}

-

Powered by - ExtendsClass.

{{ $t('cultivate.panel.sync.localBackup') }}
diff --git a/src/data/changelog.json b/src/data/changelog.json index 0b2a0ef6..5ef42fb0 100644 --- a/src/data/changelog.json +++ b/src/data/changelog.json @@ -1,6 +1,12 @@ [ { - "time": "2023-10-17", + "time": "2024-02-01", + "changes": [ + "【精英材料计算】ExtendsClass 不再提供 JSON 储存服务,所以我自己写了个,以后不用换来换去了😅" + ] + }, + { + "time": "2023-10-18", "changes": ["【精英材料计算】艾丽妮专精计算器增加自定义开始时间设置"] }, { diff --git a/src/locales/cn/cultivate.json b/src/locales/cn/cultivate.json index 47accd12..7778f6e3 100644 --- a/src/locales/cn/cultivate.json +++ b/src/locales/cn/cultivate.json @@ -51,8 +51,7 @@ "restoreDataTitle": "导入备份", "restoreDataLabel": "请在文本框中粘贴上次保存的内容", "copy2clipboard": "复制到剪贴板", - "cloudSyncReadme": "当同步码为空时,点击备份将会自动生成同步码,并将当前预设、材料“需求”和“已有”以及刷图规划@:(cultivate.panel.plannerSetting.stageSelectTitle)备份到云端,在其他设备上的此处输入同步码便可方便地通过云端备份恢复数据。", - "apiKeyReadme": "API Key 是非必须的,但是如果出现 API 调用达到限制的情况,请前往 ExtendsClass 注册账号,将 API Key 填入此处。每个 API Key 只能读取或修改由该 API Key 创建的同步码所对应的数据。", + "cloudSyncReadme": "当同步码为空时,点击备份将会自动生成同步码,并将当前预设、材料“需求”和“已有”以及刷图规划@:(cultivate.panel.plannerSetting.stageSelectTitle)备份到云端,在其他设备上的此处输入同步码便可方便地通过云端备份恢复数据。若超过 90 天未使用该同步码备份数据,云端数据可能会被清除,需要删除同步码后再备份以重新生成。", "localBackupReadme": "旧的备份方式,每次都必须复制代码到其他设备恢复,可以用于临时备份。", "autoSyncUpload": "自动备份", "autoSyncUploadTip": "自动备份:每当材料输入变化时都会自动备份到云端(节流 5 秒),考虑到数据安全所以没有自动恢复,恢复需要自行点击。" diff --git a/src/locales/jp/cultivate.json b/src/locales/jp/cultivate.json index 201ac038..0cf407a1 100644 --- a/src/locales/jp/cultivate.json +++ b/src/locales/jp/cultivate.json @@ -49,8 +49,7 @@ "restoreDataTitle": "@:common.import", "restoreDataLabel": "テキストエリアで前回保存した内容を貼り付けてください", "copy2clipboard": "コピー", - "cloudSyncReadme": "同期コードが空の場合、「バックアップ」をクリックすると、同期コードが自動的に生成され、現在の@:(common.preset)、素材カードの入力値、プランナー設定の@:(cultivate.panel.plannerSetting.stageSelectTitle)がクラウドにバックアップされます。他のデバイスに同期コードを入力して、クラウドバックアップでデータをリストアできます。", - "apiKeyReadme": "API Key 必須ではありませんが、API 呼び出しが制限に達した場合は、ExtendsClass にアクセスしてアカウントを登録し、ここに API Key を入力してください。 各 API Key は、API Key によって作成された同期コードに対応するデータのみを読み取ったり変更したりできます。", + "cloudSyncReadme": "同期コードが空の場合、「バックアップ」をクリックすると、同期コードが自動的に生成され、現在の@:(common.preset)、素材カードの入力値、プランナー設定の@:(cultivate.panel.plannerSetting.stageSelectTitle)がクラウドにバックアップされます。他のデバイスに同期コードを入力して、クラウドバックアップでデータをリストアできます。同期コードでバックアップしたデータは、90日間バックアップを行わなかった場合、クラウド上のデータが削除される可能性があります。再度バックアップを行うには、同期コードを削除して再生成する必要があります。", "localBackupReadme": "古いバックアップ方法です。毎回他のデバイスにコピーする必要があります。一時バックアップに使用可能です。", "autoSyncUpload": "自動バックアップ", "autoSyncUploadTip": "自動バックアップ:材料の入力が変わるたびに自動的にクラウドにバックアップされます(スロットル5秒)。データの安全を考慮して自動的にリストアは行いません。" diff --git a/src/locales/tw/cultivate.json b/src/locales/tw/cultivate.json index 88313777..01de0f8f 100644 --- a/src/locales/tw/cultivate.json +++ b/src/locales/tw/cultivate.json @@ -48,8 +48,7 @@ "restoreDataTitle": "導入備份", "restoreDataLabel": "請在文字方塊中貼上上次儲存的內容", "copy2clipboard": "複製到剪貼簿", - "cloudSyncReadme": "當同步碼為空時,點擊備份將會自動生成同步碼,並將當前預設、材料「需求」和「已有」以及刷圖規劃@:(cultivate.panel.plannerSetting.stageSelectTitle)備份到雲端,在其他裝置上的此處輸入同步碼便可方便地通過雲端備份恢復資料。", - "apiKeyReadme": "API Key 是非必須的,但是如果出現 API 調用達到限制的情況,請前往 ExtendsClass 註冊帳號,將 API Key 填入此處。 每個 API Key 只能讀取或修改由該 API Key 建立的同步碼所對應的資料。", + "cloudSyncReadme": "當同步碼為空時,點擊備份將會自動生成同步碼,並將當前預設、材料「需求」和「已有」以及刷圖規劃@:(cultivate.panel.plannerSetting.stageSelectTitle)備份到雲端,在其他裝置上的此處輸入同步碼便可方便地通過雲端備份恢復資料。若超過 90 天未使用該同步碼備份資料,雲端資料可能會被清除,需要刪除同步碼後再備份以重新生成。", "localBackupReadme": "舊的備份方式,每次都必須複製代碼到其他裝置恢復,可以用於臨時備份。", "autoSyncUpload": "自動備份", "autoSyncUploadTip": "自動備份:每當材料輸入變化時都會自動備份到雲端(節流 5 秒),考慮到資料安全所以沒有自動恢復,恢復需要自行點擊。" diff --git a/src/locales/us/cultivate.json b/src/locales/us/cultivate.json index c50f65e0..9b50a1ac 100644 --- a/src/locales/us/cultivate.json +++ b/src/locales/us/cultivate.json @@ -50,8 +50,7 @@ "restoreDataTitle": "Restore", "restoreDataLabel": "Please paste code below", "copy2clipboard": "Copy to Clipboard", - "cloudSyncReadme": "When the sync code is empty, clicking \"Backup\" will generate a sync code and backup the current preset, inputs and planner stage selections to the server. Enter the sync code on other devices to restore the data.", - "apiKeyReadme": "The API Key is not required, but if the API call reaches the limit, please go to ExtendsClass to register an account and fill in the API Key here. Each API Key can only read or modify the data corresponding to the sync code created by the API Key.", + "cloudSyncReadme": "When the sync code is empty, clicking \"Backup\" will generate a sync code and backup the current preset, inputs and planner stage selections to the server. Enter the sync code on other devices to restore the data. Data backed up with a sync code may be deleted from the cloud if no backup is performed for 90 days. To back up again, you'll need to delete the sync code and regenerate one.", "localBackupReadme": "This is a legacy backup method which can be used for local temporary backup. Backup code must be saved in order to restore your data.", "autoSyncUpload": "Auto Upload", "autoSyncUploadTip": "Auto Upload: Backup to cloud upon input (and every 5s). Your data won't be restored automatically for security reasons, please click the button manually to restore them." diff --git a/src/utils/ajax.js b/src/utils/ajax.js index 4870ab61..ca64d8db 100644 --- a/src/utils/ajax.js +++ b/src/utils/ajax.js @@ -1,9 +1,12 @@ import Mdui from 'mdui'; import _ from 'lodash'; +import { IS_DEV } from './env'; const { ajax } = Mdui.JQ; -const JSON_STORAGE_BASE_URL = 'https://json.extendsclass.com/bin'; +const JSON_STORAGE_BASE_URL = IS_DEV + ? 'http://localhost:8787/material' + : 'https://arknights-toolbox-json-storage.lolicon.app/material'; const promisedAjax = options => new Promise((resolve, reject) => { @@ -46,32 +49,20 @@ export default { headers: { apikey: apikey || 'helloworld' }, }); }, - createJson: (obj, apiKey) => - promisedAjax({ + createJson: obj => + fetch(JSON_STORAGE_BASE_URL, { method: 'POST', - url: JSON_STORAGE_BASE_URL, - processData: false, - data: JSON.stringify(obj), - dataType: 'json', - contentType: 'application/json', - headers: { 'api-key': apiKey || 'noaccount' }, - }).then(({ id }) => id), - getJson: async (code, apiKey) => - promisedAjax({ - method: 'GET', - url: `${JSON_STORAGE_BASE_URL}/${code}`, - dataType: 'json', - contentType: 'application/json', - headers: { 'api-key': apiKey || 'noaccount' }, - }), - updateJson: async (code, obj, apiKey) => - promisedAjax({ + body: JSON.stringify(obj), + headers: { contentType: 'application/json' }, + mode: 'cors', + }).then(r => r.json()), + getJson: async id => + fetch(`${JSON_STORAGE_BASE_URL}/${id}`, { mode: 'cors' }).then(r => r.json()), + updateJson: async (id, obj) => + fetch(`${JSON_STORAGE_BASE_URL}/${id}`, { method: 'PUT', - url: `${JSON_STORAGE_BASE_URL}/${code}`, - processData: false, - data: JSON.stringify(obj), - dataType: 'json', - contentType: 'application/json', - headers: { 'api-key': apiKey || 'noaccount' }, + body: JSON.stringify(obj), + headers: { contentType: 'application/json' }, + mode: 'cors', }), }; diff --git a/src/views/Home.vue b/src/views/Home.vue index 3f92510a..61a7c074 100644 --- a/src/views/Home.vue +++ b/src/views/Home.vue @@ -212,11 +212,6 @@ export default defineComponent({ type: 'OCR', url: 'https://ocr.space/', }, - { - name: 'ExtendsClass', - type: '数据同步', - url: 'https://extendsclass.com/json-storage.html', - }, ], }; }, diff --git a/src/views/Material/index.js b/src/views/Material/index.js index 4bbb51a7..d3bc92be 100644 --- a/src/views/Material/index.js +++ b/src/views/Material/index.js @@ -3,7 +3,6 @@ import { defineComponent, computed, markRaw } from 'vue'; import { mapState, mapActions } from 'pinia'; import { Base64 } from 'js-base64'; import Linprog from 'javascript-lp-solver'; -import md5 from 'js-md5'; import { Drag, DropList } from 'vue-easy-dnd'; import VueTagsInput from '@johmun/vue-tags-input'; @@ -33,8 +32,7 @@ import { useMaterialValueStore } from '@/store/materialValue'; const multiAccount = new MultiAccount('material'); -const SYNC_CODE_VER = 6; -const SYNC_API_KEY_VER = 1; +const SYNC_CODE_VER = 7; const enumOccPer = { '-1': 'SYNT', @@ -104,7 +102,6 @@ const defaultData = { planCardExpFirst: false, planCardExpFirstThreshold: 1, [`syncCodeV${SYNC_CODE_VER}`]: '', - [`syncApiKeyV${SYNC_API_KEY_VER}`]: '', autoSyncUpload: false, planStageBlacklist: [], simpleModeOrderedByRareFirst: false, @@ -286,14 +283,6 @@ export default defineComponent({ this.setting[`syncCodeV${SYNC_CODE_VER}`] = val; }, }, - syncApiKey: { - get() { - return this.setting[`syncApiKeyV${SYNC_API_KEY_VER}`]; - }, - set(val) { - this.setting[`syncApiKeyV${SYNC_API_KEY_VER}`] = val; - }, - }, // TODO: 企鹅物流暂时不支持繁中服 isPenguinDataSupportedServer() { return this.$root.server !== 'tw'; @@ -1267,9 +1256,6 @@ export default defineComponent({ async copySyncCode() { if (await clipboard.setText(this.syncCode)) this.$snackbar(this.$t('common.copied')); }, - async copySyncApiKey() { - if (await clipboard.setText(this.syncApiKey)) this.$snackbar(this.$t('common.copied')); - }, saveData() { this.$refs.dataSyncDialog.close(); const data = this.dataForSave; @@ -1313,13 +1299,9 @@ export default defineComponent({ }, cloudSaveData(silence = false) { const data = this.dataForSave; - const obj = { - md5: md5(JSON.stringify(data)), - data, - }; this.dataSyncing = true; if (this.syncCode) { - Ajax.updateJson(this.syncCode, obj, this.syncApiKey) + Ajax.updateJson(this.syncCode, data) .then(() => { this.dataSyncing = false; if (!silence) this.$snackbar(this.$t('cultivate.snackbar.backupSucceeded')); @@ -1331,8 +1313,8 @@ export default defineComponent({ ); }); } else { - Ajax.createJson(obj, this.syncApiKey) - .then(id => { + Ajax.createJson(data) + .then(({ id }) => { this.dataSyncing = false; this.syncCode = id; this.$snackbar(this.$t('cultivate.snackbar.backupSucceeded')); @@ -1354,9 +1336,9 @@ export default defineComponent({ cloudRestoreData() { if (!this.syncCode) return; this.dataSyncing = true; - Ajax.getJson(this.syncCode, this.syncApiKey) - .then(({ md5: _md5, data }) => { - if (!_md5 || !data || _md5 !== md5(JSON.stringify(data))) { + Ajax.getJson(this.syncCode) + .then(data => { + if (!data) { this.dataSyncing = false; this.$snackbar(this.$t('cultivate.snackbar.restoreFailed')); return;