Browse Source

add:实现gitee第三方登陆

master
秋田弘 6 months ago
parent
commit
8a60a6a71c
  1. 11
      frontend/components.d.ts
  2. 2
      frontend/package.json
  3. 31
      frontend/pnpm-lock.yaml
  4. 0
      frontend/public/image/login/sina.png
  5. 0
      frontend/public/image/login/wechat.png
  6. BIN
      frontend/src/assets/login/GitHub.png
  7. BIN
      frontend/src/assets/login/QQ.png
  8. BIN
      frontend/src/assets/login/gitee.png
  9. BIN
      frontend/src/assets/login/sina.png
  10. BIN
      frontend/src/assets/login/wechat.png
  11. 97
      frontend/src/components/desktop/LockDesktop.vue
  12. 154
      frontend/src/components/setting/SetLang.vue
  13. 517
      frontend/src/components/window/IframeFile.vue

11
frontend/components.d.ts

@ -67,18 +67,26 @@ declare module 'vue' {
ElCard: typeof import('element-plus/es')['ElCard'] ElCard: typeof import('element-plus/es')['ElCard']
ElCarousel: typeof import('element-plus/es')['ElCarousel'] ElCarousel: typeof import('element-plus/es')['ElCarousel']
ElCarouselItem: typeof import('element-plus/es')['ElCarouselItem'] ElCarouselItem: typeof import('element-plus/es')['ElCarouselItem']
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
ElCol: typeof import('element-plus/es')['ElCol'] ElCol: typeof import('element-plus/es')['ElCol']
ElColorPicker: typeof import('element-plus/es')['ElColorPicker'] ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
ElContainer: typeof import('element-plus/es')['ElContainer'] ElContainer: typeof import('element-plus/es')['ElContainer']
ElDialog: typeof import('element-plus/es')['ElDialog'] ElDialog: typeof import('element-plus/es')['ElDialog']
ElDrawer: typeof import('element-plus/es')['ElDrawer'] ElDrawer: typeof import('element-plus/es')['ElDrawer']
ElDropdown: typeof import('element-plus/es')['ElDropdown']
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
ElEmpty: typeof import('element-plus/es')['ElEmpty'] ElEmpty: typeof import('element-plus/es')['ElEmpty']
ElFooter: typeof import('element-plus/es')['ElFooter']
ElForm: typeof import('element-plus/es')['ElForm'] ElForm: typeof import('element-plus/es')['ElForm']
ElFormItem: typeof import('element-plus/es')['ElFormItem'] ElFormItem: typeof import('element-plus/es')['ElFormItem']
ElHeader: typeof import('element-plus/es')['ElHeader'] ElHeader: typeof import('element-plus/es')['ElHeader']
ElIcon: typeof import('element-plus/es')['ElIcon'] ElIcon: typeof import('element-plus/es')['ElIcon']
ElImage: typeof import('element-plus/es')['ElImage'] ElImage: typeof import('element-plus/es')['ElImage']
ElInput: typeof import('element-plus/es')['ElInput'] ElInput: typeof import('element-plus/es')['ElInput']
ElMain: typeof import('element-plus/es')['ElMain']
ElMenu: typeof import('element-plus/es')['ElMenu']
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
ElOption: typeof import('element-plus/es')['ElOption'] ElOption: typeof import('element-plus/es')['ElOption']
ElPageHeader: typeof import('element-plus/es')['ElPageHeader'] ElPageHeader: typeof import('element-plus/es')['ElPageHeader']
ElPagination: typeof import('element-plus/es')['ElPagination'] ElPagination: typeof import('element-plus/es')['ElPagination']
@ -97,6 +105,8 @@ declare module 'vue' {
ElTag: typeof import('element-plus/es')['ElTag'] ElTag: typeof import('element-plus/es')['ElTag']
ElText: typeof import('element-plus/es')['ElText'] ElText: typeof import('element-plus/es')['ElText']
ElTooltip: typeof import('element-plus/es')['ElTooltip'] ElTooltip: typeof import('element-plus/es')['ElTooltip']
ElTransfer: typeof import('element-plus/es')['ElTransfer']
ElTree: typeof import('element-plus/es')['ElTree']
Error: typeof import('./src/components/taskbar/Error.vue')['default'] Error: typeof import('./src/components/taskbar/Error.vue')['default']
FileIcon: typeof import('./src/components/builtin/FileIcon.vue')['default'] FileIcon: typeof import('./src/components/builtin/FileIcon.vue')['default']
FileIconImg: typeof import('./src/components/builtin/FileIconImg.vue')['default'] FileIconImg: typeof import('./src/components/builtin/FileIconImg.vue')['default']
@ -106,7 +116,6 @@ declare module 'vue' {
FilePwd: typeof import('./src/components/oa/FilePwd.vue')['default'] FilePwd: typeof import('./src/components/oa/FilePwd.vue')['default']
FileTree: typeof import('./src/components/builtin/FileTree.vue')['default'] FileTree: typeof import('./src/components/builtin/FileTree.vue')['default']
FileViewer: typeof import('./src/components/builtin/FileViewer.vue')['default'] FileViewer: typeof import('./src/components/builtin/FileViewer.vue')['default']
GithubNext: typeof import('./src/components/desktop/GithubNext.vue')['default']
IframeFile: typeof import('./src/components/window/IframeFile.vue')['default'] IframeFile: typeof import('./src/components/window/IframeFile.vue')['default']
ImageViewer: typeof import('./src/components/builtin/ImageViewer.vue')['default'] ImageViewer: typeof import('./src/components/builtin/ImageViewer.vue')['default']
Install: typeof import('./src/components/install/Install.vue')['default'] Install: typeof import('./src/components/install/Install.vue')['default']

2
frontend/package.json

@ -19,6 +19,7 @@
"jszip": "^3.10.1", "jszip": "^3.10.1",
"lunar-typescript": "^1.7.6", "lunar-typescript": "^1.7.6",
"moment": "^2.30.1", "moment": "^2.30.1",
"nanoid": "^5.0.9",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"pinia-plugin-persist": "^1.0.0", "pinia-plugin-persist": "^1.0.0",
"vite-plugin-svg-icons": "^2.0.1", "vite-plugin-svg-icons": "^2.0.1",
@ -31,6 +32,7 @@
}, },
"devDependencies": { "devDependencies": {
"@types/file-saver": "^2.0.7", "@types/file-saver": "^2.0.7",
"@types/nanoid": "^3.0.0",
"@types/node": "^20.14.10", "@types/node": "^20.14.10",
"@vitejs/plugin-vue": "^5.0.5", "@vitejs/plugin-vue": "^5.0.5",
"sass": "^1.77.8", "sass": "^1.77.8",

31
frontend/pnpm-lock.yaml

@ -33,11 +33,14 @@ importers:
specifier: ^3.10.1 specifier: ^3.10.1
version: 3.10.1 version: 3.10.1
lunar-typescript: lunar-typescript:
specifier: ^1.7.5 specifier: ^1.7.6
version: 1.7.5 version: 1.7.6
moment: moment:
specifier: ^2.30.1 specifier: ^2.30.1
version: 2.30.1 version: 2.30.1
nanoid:
specifier: ^5.0.9
version: 5.0.9
pinia: pinia:
specifier: ^2.1.7 specifier: ^2.1.7
version: 2.2.4(typescript@5.6.3)(vue@3.5.12(typescript@5.6.3)) version: 2.2.4(typescript@5.6.3)(vue@3.5.12(typescript@5.6.3))
@ -69,6 +72,9 @@ importers:
'@types/file-saver': '@types/file-saver':
specifier: ^2.0.7 specifier: ^2.0.7
version: 2.0.7 version: 2.0.7
'@types/nanoid':
specifier: ^3.0.0
version: 3.0.0
'@types/node': '@types/node':
specifier: ^20.14.10 specifier: ^20.14.10
version: 20.16.13 version: 20.16.13
@ -534,6 +540,10 @@ packages:
'@types/lodash@4.17.12': '@types/lodash@4.17.12':
resolution: {integrity: sha512-sviUmCE8AYdaF/KIHLDJBQgeYzPBI0vf/17NaYehBJfYD1j6/L95Slh07NlyK2iNyBNaEkb3En2jRt+a8y3xZQ==} resolution: {integrity: sha512-sviUmCE8AYdaF/KIHLDJBQgeYzPBI0vf/17NaYehBJfYD1j6/L95Slh07NlyK2iNyBNaEkb3En2jRt+a8y3xZQ==}
'@types/nanoid@3.0.0':
resolution: {integrity: sha512-UXitWSmXCwhDmAKe7D3hNQtQaHeHt5L8LO1CB8GF8jlYVzOv5cBWDNqiJ+oPEWrWei3i3dkZtHY/bUtd0R/uOQ==}
deprecated: This is a stub types definition. nanoid provides its own type definitions, so you do not need this installed.
'@types/node@20.16.13': '@types/node@20.16.13':
resolution: {integrity: sha512-GjQ7im10B0labo8ZGXDGROUl9k0BNyDgzfGpb4g/cl+4yYDWVKcozANF4FGr4/p0O/rAkQClM6Wiwkije++1Tg==} resolution: {integrity: sha512-GjQ7im10B0labo8ZGXDGROUl9k0BNyDgzfGpb4g/cl+4yYDWVKcozANF4FGr4/p0O/rAkQClM6Wiwkije++1Tg==}
@ -2040,8 +2050,8 @@ packages:
lottie-web@5.12.2: lottie-web@5.12.2:
resolution: {integrity: sha512-uvhvYPC8kGPjXT3MyKMrL3JitEAmDMp30lVkuq/590Mw9ok6pWcFCwXJveo0t5uqYw1UREQHofD+jVpdjBv8wg==} resolution: {integrity: sha512-uvhvYPC8kGPjXT3MyKMrL3JitEAmDMp30lVkuq/590Mw9ok6pWcFCwXJveo0t5uqYw1UREQHofD+jVpdjBv8wg==}
lunar-typescript@1.7.5: lunar-typescript@1.7.6:
resolution: {integrity: sha512-AlOwYrxHRCR9Plba5TlZY0NVv6aFobmR1gxfiAE1KxjDzBXoDtT2KrsBYCVaErGokiL8qLMS1FNwGPiPRX2a4g==} resolution: {integrity: sha512-vrNRgzJ6UgK++P81jaOykV7YBCLemC8l/XDbsXE7MinojXolOKiIHm6sOZg5wdDMbJxCWP1ERAaqcBV9mhw2Bg==}
magic-string@0.30.12: magic-string@0.30.12:
resolution: {integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==} resolution: {integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==}
@ -2145,6 +2155,11 @@ packages:
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true hasBin: true
nanoid@5.0.9:
resolution: {integrity: sha512-Aooyr6MXU6HpvvWXKoVoXwKMs/KyVakWwg7xQfv5/S/RIgJMy0Ifa45H9qqYy7pTCszrHzP21Uk4PZq2HpEM8Q==}
engines: {node: ^18 || >=20}
hasBin: true
nanomatch@1.2.13: nanomatch@1.2.13:
resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==} resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@ -3356,6 +3371,10 @@ snapshots:
'@types/lodash@4.17.12': {} '@types/lodash@4.17.12': {}
'@types/nanoid@3.0.0':
dependencies:
nanoid: 5.0.9
'@types/node@20.16.13': '@types/node@20.16.13':
dependencies: dependencies:
undici-types: 6.19.8 undici-types: 6.19.8
@ -5330,7 +5349,7 @@ snapshots:
lottie-web@5.12.2: {} lottie-web@5.12.2: {}
lunar-typescript@1.7.5: {} lunar-typescript@1.7.6: {}
magic-string@0.30.12: magic-string@0.30.12:
dependencies: dependencies:
@ -5481,6 +5500,8 @@ snapshots:
nanoid@3.3.7: {} nanoid@3.3.7: {}
nanoid@5.0.9: {}
nanomatch@1.2.13(supports-color@3.2.3): nanomatch@1.2.13(supports-color@3.2.3):
dependencies: dependencies:
arr-diff: 4.0.0 arr-diff: 4.0.0

0
frontend/public/image/login/新浪微博.png → frontend/public/image/login/sina.png

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

0
frontend/public/image/login/微信.png → frontend/public/image/login/wechat.png

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
frontend/src/assets/login/GitHub.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
frontend/src/assets/login/QQ.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
frontend/src/assets/login/gitee.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
frontend/src/assets/login/sina.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

BIN
frontend/src/assets/login/wechat.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

97
frontend/src/components/desktop/LockDesktop.vue

@ -48,54 +48,17 @@
</div> </div>
<div class="third-party-login"> <div class="third-party-login">
<img <img
v-for="platform in thirdPartyPlatforms"
:key="platform.name"
:src="platform.icon"
:alt="platform.name"
style=" style="
width: 25px; width: 25px;
height: 25px; height: 25px;
cursor: pointer; cursor: pointer;
color: #409eff; color: #409eff;
" "
src="../../../public/image/login/微信.png" @click="onThirdPartyLogin(platform.name)"
@click="onThirdPartyLogin('wechat')"
/>
<img
style="
width: 25px;
height: 25px;
cursor: pointer;
color: #409eff;
"
src="../../../public/image/login/QQ.png"
@click="onThirdPartyLogin('qq')"
/>
<img
style="
width: 25px;
height: 25px;
cursor: pointer;
color: #409eff;
"
src="../../../public/image/login/新浪微博.png"
@click="onThirdPartyLogin('sina')"
/>
<img
style="
width: 25px;
height: 25px;
cursor: pointer;
color: #409eff;
"
src="../../../public/image/login/GitHub.png"
@click="onThirdPartyLogin('github')"
/>
<img
style="
width: 25px;
height: 25px;
cursor: pointer;
color: #409eff;
"
src="../../../public/image/login/gitee.png"
@click="onThirdPartyLogin('gitee')"
/> />
</div> </div>
<div <div
@ -199,6 +162,30 @@
const config = getSystemConfig(); const config = getSystemConfig();
const lockClassName = ref("screen-show"); const lockClassName = ref("screen-show");
const isRegisterMode = ref(false); const isRegisterMode = ref(false);
const thirdPartyPlatforms = [
{
name: "wechat",
icon: new URL("@/assets/login/wechat.png", import.meta.url).href,
},
{
name: "qq",
icon: new URL("@/assets/login/qq.png", import.meta.url).href,
},
{
name: "sina",
icon: new URL("@/assets/login/sina.png", import.meta.url).href,
},
{
name: "github",
icon: new URL("@/assets/login/github.png", import.meta.url).href,
},
{
name: "gitee",
icon: new URL("@/assets/login/gitee.png", import.meta.url).href,
},
];
function loginSuccess() { function loginSuccess() {
lockClassName.value = "screen-hidean"; lockClassName.value = "screen-hidean";
setTimeout(() => { setTimeout(() => {
@ -219,6 +206,7 @@
} }
}); });
// code
watch( watch(
() => router.currentRoute.value.query.code, () => router.currentRoute.value.query.code,
() => { () => {
@ -249,6 +237,8 @@
const returnedState = router.currentRoute.value.query const returnedState = router.currentRoute.value.query
.state as string; .state as string;
console.log(returnedState, "---", store.State);
if (returnedState !== store.State) { if (returnedState !== store.State) {
notifyError("登录失败,请重试"); notifyError("登录失败,请重试");
return; return;
@ -402,7 +392,7 @@
break; break;
case "gitee": case "gitee":
loginFunction = async function () { loginFunction = async function () {
return await authWithGithub(); return await authWithGitee();
}; };
break; break;
default: default:
@ -423,7 +413,6 @@
const authWithGithub = async (): Promise<boolean> => { const authWithGithub = async (): Promise<boolean> => {
// stateCSRF,使 // stateCSRF,使
const state = Date.now() + Math.random().toString(36).substring(2, 15); const state = Date.now() + Math.random().toString(36).substring(2, 15);
//
store.State = state; store.State = state;
const url = config.userInfo.url + "/github/authorize?state=" + state; const url = config.userInfo.url + "/github/authorize?state=" + state;
const res: any = await fetch(url, { const res: any = await fetch(url, {
@ -452,6 +441,26 @@
const authWithSina = (): boolean | PromiseLike<boolean> => { const authWithSina = (): boolean | PromiseLike<boolean> => {
throw new Error("Function not implemented."); throw new Error("Function not implemented.");
}; };
const authWithGitee = async (): Promise<boolean> => {
// stateCSRF,使
const state = Date.now() + Math.random().toString(36).substring(2, 15);
store.State = state;
const url = config.userInfo.url + "/gitee/authorize?state=" + state;
const res: any = await fetch(url, {
method: "POST",
body: JSON.stringify({
state: state,
}),
});
if (!res.ok) {
return false;
}
const data = await res.json();
// Gitee
window.location.href = data.data.url;
return true;
};
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">

154
frontend/src/components/setting/SetLang.vue

@ -1,88 +1,90 @@
<template> <template>
<div class="container"> <div class="container">
<div class="nav"> <div class="nav">
<ul> <ul>
<li <li
v-for="(item, index) in items" v-for="(item, index) in items"
:key="index" :key="index"
@click="selectItem(index)" @click="selectItem(index)"
:class="{ active: index === activeIndex }" :class="{ active: index === activeIndex }"
> >
{{ item }} {{ item }}
</li> </li>
</ul> </ul>
</div> </div>
<div class="setting"> <div class="setting">
<div v-if="0 === activeIndex"> <div v-if="0 === activeIndex">
<div class="setting-item"> <div class="setting-item">
<h1 class="setting-title">{{ t("language") }}</h1> <h1 class="setting-title">{{ t("language") }}</h1>
</div> </div>
<div class="setting-item"> <div class="setting-item">
<label></label> <label></label>
<el-select v-model="modelvalue"> <el-select v-model="modelvalue">
<el-option <el-option
v-for="(item, key) in langList" v-for="(item, key) in langList"
:key="key" :key="key"
:label="item.label" :label="item.label"
:value="item.value" :value="item.value"
/> />
</el-select> </el-select>
</div> </div>
<div class="setting-item">
<label></label>
<el-button @click="submit" type="primary">
{{ t("confirm") }}
</el-button>
</div>
</div>
</div>
</div>
<div class="setting-item">
<label></label>
<el-button
@click="submit"
type="primary"
>
{{ t("confirm") }}
</el-button>
</div>
</div>
</div>
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref } from "vue"; import { getLang, setLang, t } from "@/i18n";
import { ElMessageBox } from 'element-plus' import { ElMessageBox } from "element-plus";
import { t, getLang, setLang } from "@/i18n"; import { ref } from "vue";
import { useI18n } from 'vue-i18n'; import { useI18n } from "vue-i18n";
const { locale } = useI18n() const { locale } = useI18n();
const showDialog = ref(false); // const showDialog = ref(false);
const langList = [ const langList = [
{ {
label: "中文", label: "中文",
value: "zh-cn", value: "zh-cn",
}, },
{ {
label: "English", label: "English",
value: "en", value: "en",
}, },
]; ];
const items = [t("language")]; const items = [t("language")];
const activeIndex = ref(0); const activeIndex = ref(0);
const currentLang = getLang(); const currentLang = getLang();
const modelvalue = ref(currentLang); const modelvalue = ref(currentLang);
const selectItem = (index: number) => { const selectItem = (index: number) => {
activeIndex.value = index; activeIndex.value = index;
}; };
async function submit() { async function submit() {
setLang(modelvalue.value); setLang(modelvalue.value);
locale.value = modelvalue.value; locale.value = modelvalue.value;
ElMessageBox.alert(t("save.success"), t("language"), { ElMessageBox.alert(t("save.success"), t("language"), {
confirmButtonText: 'OK', confirmButtonText: "OK",
}) });
//showDialog.value = false //showDialog.value = false
// Dialog.showMessageBox({ // Dialog.showMessageBox({
// message: t("save.success"), // message: t("save.success"),
// title: t("language"), // title: t("language"),
// type: "info", // type: "info",
// }); // });
} }
</script> </script>
<style scoped> <style scoped>
@import "./setStyle.css"; @import "./setStyle.css";
</style> </style>

517
frontend/src/components/window/IframeFile.vue

@ -1,269 +1,274 @@
<template> <template>
<iframe class="setiframe" allow="fullscreen" ref="storeRef" :src="src"></iframe> <iframe
class="setiframe"
allow="fullscreen"
ref="storeRef"
:src="src"
></iframe>
</template> </template>
<script lang="ts" setup name="IframeFile"> <script lang="ts" setup name="IframeFile">
//@ts-ignore //@ts-ignore
import { BrowserWindow, Dialog, Notify, System } from "@/system"; import { askAi } from "@/hook/useAi";
import { getSplit, getSystemConfig, setSystemKey } from "@/system/config"; import { useChooseStore } from "@/stores/choose";
import { base64ToBuffer, isBase64 } from "@/util/file"; import { BrowserWindow, Dialog, Notify, System } from "@/system";
import { isShareFile } from "@/util/sharePath.ts"; import { getSplit, getSystemConfig, setSystemKey } from "@/system/config";
import { inject, onMounted, onUnmounted, ref, toRaw } from "vue"; import eventBus from "@/system/event/eventBus";
import { askAi } from "@/hook/useAi"; import { base64ToBuffer, isBase64 } from "@/util/file";
import { useChooseStore } from "@/stores/choose"; import { isShareFile } from "@/util/sharePath.ts";
import { nanoid } from "nanoid"; import { nanoid } from "nanoid";
import eventBus from "@/system/event/eventBus"; import { inject, onMounted, onUnmounted, ref, toRaw } from "vue";
const SP = getSplit(); const SP = getSplit();
const sys: any = inject<System>("system"); const sys: any = inject<System>("system");
const win: any = inject<BrowserWindow>("browserWindow"); const win: any = inject<BrowserWindow>("browserWindow");
const props = defineProps({ const props = defineProps({
src: { src: {
type: String, type: String,
default: "", default: "",
}, },
eventType: { eventType: {
type: String, type: String,
default: "", default: "",
}, },
ext: { ext: {
type: String, type: String,
default: "md", default: "md",
}, },
}); });
const storeRef = ref<HTMLIFrameElement | null>(null); const storeRef = ref<HTMLIFrameElement | null>(null);
let hasInit = false; let hasInit = false;
const choose = useChooseStore(); const choose = useChooseStore();
const componentID = nanoid(); const componentID = nanoid();
// console.log("ID", componentID); // console.log("ID", componentID);
const saveFile = async (e: any) => { const saveFile = async (e: any) => {
if (e.componentID !== componentID) return; if (e.componentID !== componentID) return;
let data = JSON.parse(e.eventData.data); let data = JSON.parse(e.eventData.data);
let ext: any = props.ext; let ext: any = props.ext;
if (ext instanceof Array) { if (ext instanceof Array) {
ext = ext[0]; ext = ext[0];
} }
if (data.ext) { if (data.ext) {
ext = data.ext; ext = data.ext;
} }
let path:string let path: string;
e.filePath !== "" e.filePath !== ""
? (path = `${e.filePath}/${e.fileName}.${ext}`) ? (path = `${e.filePath}/${e.fileName}.${ext}`)
: (path = `${SP}C${SP}Users${SP}Desktop${SP}${e.fileName}.${ext}`); : (path = `${SP}C${SP}Users${SP}Desktop${SP}${e.fileName}.${ext}`);
// console.log('',path); // console.log('',path);
await writeFile(path, data, e.fileName); await writeFile(path, data, e.fileName);
}; };
eventBus.on("saveFile", saveFile); eventBus.on("saveFile", saveFile);
const writeFile = async (path: string, data: any, title: string) => { const writeFile = async (path: string, data: any, title: string) => {
const isShare = ref(false); const isShare = ref(false);
const isWrite = ref(0); const isWrite = ref(0);
if (isShareFile(path)) { if (isShareFile(path)) {
const file = await sys?.fs.getShareInfo(path); const file = await sys?.fs.getShareInfo(path);
isShare.value = true; isShare.value = true;
isWrite.value = isWrite.value =
file.fs.sender === getSystemConfig().userInfo.id file.fs.sender === getSystemConfig().userInfo.id
? 1 ? 1
: file.fs.is_write; : file.fs.is_write;
if ( if (
!isWrite.value && !isWrite.value &&
file.fs.sender !== getSystemConfig().userInfo.id file.fs.sender !== getSystemConfig().userInfo.id
) { ) {
new Notify({ new Notify({
title: "提示", title: "提示",
content: "该文件没有编辑权限", content: "该文件没有编辑权限",
}); });
return; return;
} }
} else if (await sys?.fs.exists(path)) { } else if (await sys?.fs.exists(path)) {
let res = await Dialog.showMessageBox({ let res = await Dialog.showMessageBox({
type: "info", type: "info",
title: "提示", title: "提示",
message: "存在相同的文件名-" + title, message: "存在相同的文件名-" + title,
buttons: ["覆盖文件?", "取消"], buttons: ["覆盖文件?", "取消"],
}); });
//console.log(res) //console.log(res)
if (res.response > 0) { if (res.response > 0) {
return; return;
} }
} }
if (typeof data.content === "string") { if (typeof data.content === "string") {
if (data.content.indexOf(";base64,") > -1) { if (data.content.indexOf(";base64,") > -1) {
const parts = data.content.split(";base64,"); const parts = data.content.split(";base64,");
data.content = parts[1]; data.content = parts[1];
} }
if (isBase64(data.content)) { if (isBase64(data.content)) {
data.content = base64ToBuffer(data.content); data.content = base64ToBuffer(data.content);
//console.log(data.content) //console.log(data.content)
} }
} }
const res = isShare.value const res = isShare.value
? await sys?.fs.writeShareFile(path, data.content, isWrite.value) ? await sys?.fs.writeShareFile(path, data.content, isWrite.value)
: await sys?.fs.writeFile(path, data.content); : await sys?.fs.writeFile(path, data.content);
// console.log("", res, isShare); // console.log("", res, isShare);
new Notify({ new Notify({
title: "提示", title: "提示",
content: res.message, content: res.message,
// content: res.code === 0 ? "" : res.message, // content: res.code === 0 ? "" : res.message,
}); });
sys.refershAppList(); sys.refershAppList();
}; };
const eventHandler = async (e: MessageEvent) => { const eventHandler = async (e: MessageEvent) => {
const eventData = e.data; const eventData = e.data;
// console.log('', componentID == eventData.componentID); // console.log('', componentID == eventData.componentID);
if (eventData.type == props.eventType) { if (eventData.type == props.eventType) {
// if (eventData.componentID !== componentID) return; // if (eventData.componentID !== componentID) return;
let data = JSON.parse(eventData.data); let data = JSON.parse(eventData.data);
let title = data.title; let title = data.title;
let path; let path;
let ext: any = props.ext; let ext: any = props.ext;
if (ext instanceof Array) { if (ext instanceof Array) {
ext = ext[0]; ext = ext[0];
} }
if (data.ext) { if (data.ext) {
ext = data.ext; ext = data.ext;
} }
if (title.indexOf("." + ext) > -1) { if (title.indexOf("." + ext) > -1) {
title = title.replace("." + ext, ""); title = title.replace("." + ext, "");
} }
if (win.config && win.config.path) { if (win.config && win.config.path) {
path = win.config.path; path = win.config.path;
//1 //1
let fileTitleArr = path.split(SP).pop().split("."); let fileTitleArr = path.split(SP).pop().split(".");
let oldExt = fileTitleArr.pop(); let oldExt = fileTitleArr.pop();
let fileTitle = fileTitleArr.join("."); let fileTitle = fileTitleArr.join(".");
if (fileTitle != title) { if (fileTitle != title) {
path = path.replace(fileTitle, title); path = path.replace(fileTitle, title);
} }
if (oldExt != ext) { if (oldExt != ext) {
path = path.replace("." + oldExt, "." + ext); path = path.replace("." + oldExt, "." + ext);
} }
} else { } else {
choose.saveFile("选择地址", "*", componentID, eventData); choose.saveFile("选择地址", "*", componentID, eventData);
return; return;
// path = `${SP}C${SP}Users${SP}Desktop${SP}${title}.${ext}`; // path = `${SP}C${SP}Users${SP}Desktop${SP}${title}.${ext}`;
} }
writeFile(path, data, title); writeFile(path, data, title);
} else if (eventData.type == "initSuccess") { } else if (eventData.type == "initSuccess") {
if (hasInit) { if (hasInit) {
return; return;
} }
hasInit = true; hasInit = true;
let content = win?.config?.content; let content = win?.config?.content;
let title = win.getTitle(); let title = win.getTitle();
// console.log("win.config;", win?.config); // console.log("win.config;", win?.config);
// console.log(title); // console.log(title);
title = title.split(SP).pop(); title = title.split(SP).pop();
// if (!content && win?.config.path) { // if (!content && win?.config.path) {
// const header = { // const header = {
// pwd: '' // pwd: ''
// }; // };
// const filePwd = getSystemConfig().fileInputPwd // const filePwd = getSystemConfig().fileInputPwd
// const pos = filePwd.findIndex((item: any) => item.path == win?.config.path) // const pos = filePwd.findIndex((item: any) => item.path == win?.config.path)
// //console.log('', win?.config.path, pos, filePwd); // //console.log('', win?.config.path, pos, filePwd);
// const userType = getSystemConfig().userType // const userType = getSystemConfig().userType
// if (pos !== -1) { // if (pos !== -1) {
// header.pwd = userType == 'person' ? md5(filePwd[pos].pwd) : filePwd[pos].pwd // header.pwd = userType == 'person' ? md5(filePwd[pos].pwd) : filePwd[pos].pwd
// } // }
// content = await sys?.fs.readFile(win?.config.path, header); // content = await sys?.fs.readFile(win?.config.path, header);
// } // }
content = toRaw(content); content = toRaw(content);
if (content && content !== "") { if (content && content !== "") {
storeRef.value?.contentWindow?.postMessage( storeRef.value?.contentWindow?.postMessage(
{ {
type: "init", type: "init",
data: { content, title }, data: { content, title },
componentID, componentID,
}, },
"*" "*"
); );
} else { } else {
storeRef.value?.contentWindow?.postMessage( storeRef.value?.contentWindow?.postMessage(
{ {
type: "start", type: "start",
title, title,
componentID, componentID,
}, },
"*" "*"
); );
} }
} else if (eventData.type == "close") { } else if (eventData.type == "close") {
// console.log(""); // console.log("");
win.close(); win.close();
} else if (eventData.type == "saveMind") { } else if (eventData.type == "saveMind") {
// console.log(""); // console.log("");
const data = eventData.data; const data = eventData.data;
const path = win?.config?.path; const path = win?.config?.path;
//console.log(path,data) //console.log(path,data)
const winMind = new BrowserWindow({ const winMind = new BrowserWindow({
title: data.title, title: data.title,
url: "/mind/index.html", url: "/mind/index.html",
frame: true, frame: true,
config: { config: {
ext: "mind", ext: "mind",
path: path, path: path,
content: data.content, content: data.content,
}, },
icon: "gallery", icon: "gallery",
width: 700, width: 700,
height: 500, height: 500,
x: 100, x: 100,
y: 100, y: 100,
//center: true, //center: true,
minimizable: false, minimizable: false,
resizable: true, resizable: true,
}); });
winMind.show(); winMind.show();
} else if (eventData.type == "aiCreater") { } else if (eventData.type == "aiCreater") {
console.log("传递内容: ", eventData); console.log("传递内容: ", eventData);
let postData: any = {}; let postData: any = {};
if (eventData.data) { if (eventData.data) {
postData.content = eventData.data; postData.content = eventData.data;
} }
if (eventData.title) { if (eventData.title) {
postData.title = eventData.title; postData.title = eventData.title;
} }
if (eventData.category) { if (eventData.category) {
postData.category = eventData.category; postData.category = eventData.category;
} }
//console.log(postData,eventData.action) //console.log(postData,eventData.action)
// AI // AI
const res: any = await askAi(postData, eventData.action); const res: any = await askAi(postData, eventData.action);
storeRef.value?.contentWindow?.postMessage( storeRef.value?.contentWindow?.postMessage(
{ {
type: "aiReciver", type: "aiReciver",
data: res, data: res,
action: eventData.action, action: eventData.action,
}, },
"*" "*"
); );
} }
}; };
// //
const delFileInputPwd = async () => { const delFileInputPwd = async () => {
let fileInputPwd = getSystemConfig().fileInputPwd; let fileInputPwd = getSystemConfig().fileInputPwd;
const currentPath = win.config.path; const currentPath = win.config.path;
const temp = fileInputPwd.filter( const temp = fileInputPwd.filter(
(item: any) => item.path !== currentPath (item: any) => item.path !== currentPath
); );
setSystemKey("fileInputPwd", temp); setSystemKey("fileInputPwd", temp);
}; };
onMounted(() => { onMounted(() => {
window.addEventListener("message", eventHandler); window.addEventListener("message", eventHandler);
}); });
onUnmounted(async () => { onUnmounted(async () => {
await delFileInputPwd(); await delFileInputPwd();
window.removeEventListener("message", eventHandler); window.removeEventListener("message", eventHandler);
}); });
</script> </script>
<style scoped> <style scoped>
.setiframe { .setiframe {
width: 100%; width: 100%;
height: 100%; height: 100%;
border: none; border: none;
} }
</style> </style>

Loading…
Cancel
Save