Browse Source

fix:前端文件bug修复

master
prr 7 months ago
parent
commit
5c7d8dd671
  1. 167
      frontend/src/components/builtin/MarkDown.vue
  2. 134
      frontend/src/components/oa/ShareFiles.vue
  3. 129
      frontend/src/components/setting/SetFilePwd.vue
  4. 5
      frontend/src/components/window/IframeFile.vue
  5. 1
      frontend/src/system/core/FileOs.ts
  6. 2
      godo/cmd/serve.go

167
frontend/src/components/builtin/MarkDown.vue

@ -1,45 +1,48 @@
<script lang="ts" setup>
import { BrowserWindow, System } from "@/system";
import { inject, onMounted, ref, toRaw, onUnmounted } from "vue";
import { notifyError, notifySuccess } from "@/util/msg";
import Vditor from "vditor";
import "vditor/dist/index.css";
import { getMdOption } from "@/util/vditor";
import { isBase64, decodeBase64 } from "@/util/file";
import moment from "moment";
import { useHistoryStore } from "@/stores/history";
import { getSplit } from "@/system/config";
import { saveAs } from "file-saver";
import { useHistoryStore } from "@/stores/history";
import { BrowserWindow, System } from "@/system";
import { getSplit, getSystemConfig } from "@/system/config";
import { decodeBase64, isBase64 } from "@/util/file";
import { notifyError, notifySuccess } from "@/util/msg";
import { getMdOption } from "@/util/vditor";
import { saveAs } from "file-saver";
import moment from "moment";
import Vditor from "vditor";
import "vditor/dist/index.css";
import { inject, onMounted, onUnmounted, ref, toRaw } from "vue";
const historyStore = useHistoryStore();
const historyStore = useHistoryStore();
const drawerBox = ref(false);
const baseTitle = ref("");
const content = ref("");
const sys: any = inject<System>("system");
const win: any = inject<BrowserWindow>("browserWindow");
const isSaveing = ref(false);
const vditor = ref();
const filepath: any = ref("");
const fileInput: any = ref(null);
const SP = getSplit();
console.log(SP);
const drawerBox = ref(false);
const baseTitle = ref("");
const content = ref("");
const sys: any = inject<System>("system");
const win: any = inject<BrowserWindow>("browserWindow");
const isSaveing = ref(false);
const vditor = ref();
const filepath: any = ref("");
const fileInput: any = ref(null);
const SP = getSplit();
console.log(SP);
const debouncedHandleKeyDown = (event: KeyboardEvent) => {
const debouncedHandleKeyDown = (event: KeyboardEvent) => {
//
if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "s") {
if (
(event.metaKey || event.ctrlKey) &&
event.key.toLowerCase() === "s"
) {
event.stopPropagation(); //
event.preventDefault(); //
if (!isSaveing.value) {
saveData();
}
}
};
};
const getDateTime = (t: any) => {
const getDateTime = (t: any) => {
return moment(t).format("MM-DD HH:mm");
};
function getTitle() {
};
function getTitle() {
let title = win.getTitle();
console.log(title);
if (title.indexOf(SP) > -1) {
@ -50,8 +53,8 @@ function getTitle() {
} else {
return "";
}
}
onMounted(async () => {
}
onMounted(async () => {
const editorOptions: any = getMdOption();
editorOptions.input = (val: any) => {
content.value = val;
@ -73,13 +76,13 @@ onMounted(async () => {
}, 1000);
}
document.addEventListener("keydown", debouncedHandleKeyDown);
});
//
onUnmounted(() => {
});
//
onUnmounted(() => {
document.removeEventListener("keydown", debouncedHandleKeyDown);
});
});
async function saveData() {
async function saveData() {
if (isSaveing.value) {
return;
}
@ -100,15 +103,34 @@ async function saveData() {
fileTitleArr.pop();
const oldTitle = fileTitleArr.join(".");
if (oldTitle != baseTitle.value) {
filepath.value = filepath.value.replace(oldTitle, baseTitle.value);
filepath.value = filepath.value.replace(
oldTitle,
baseTitle.value
);
refreshDesktop = true;
}
} else {
refreshDesktop = true;
}
const file = await sys?.fs.getShareInfo(filepath.value);
const isWrite =
file.fs.sender === getSystemConfig().userInfo.id
? 1
: file.fs.is_write;
//console.log(path)
await sys?.fs.writeFile(filepath.value, vditor.value.getValue());
notifySuccess("保存成功!");
const res = file.fi.isShare
? await sys?.fs.writeShareFile(
filepath.value,
vditor.value.getValue(),
isWrite
)
: await sys?.fs.writeFile(filepath.value, vditor.value.getValue());
if (res.success) {
notifySuccess(res.message || "保存成功!");
} else {
notifyError(res.message || "保存失败");
}
isSaveing.value = false;
if (refreshDesktop) {
sys.refershAppList();
@ -118,23 +140,26 @@ async function saveData() {
path: filepath.value,
time: Date.now(),
});
}
function uploadFile(event: any) {
}
function uploadFile(event: any) {
const file = event.target.files[0];
if (!file) {
return;
}
const reader = new FileReader();
reader.onload = (e: any) => {
baseTitle.value = file.name.substring(0, file.name.lastIndexOf("."));
baseTitle.value = file.name.substring(
0,
file.name.lastIndexOf(".")
);
vditor.value.setValue(e.target.result);
};
reader.readAsText(file);
}
function importMd() {
}
function importMd() {
fileInput.value.click();
}
function download() {
}
function download() {
if (baseTitle.value == "") {
notifyError("标题不能为空");
return;
@ -144,9 +169,11 @@ function download() {
notifyError("内容不能为空");
return;
}
let blob = new Blob([contentData], { type: "text/plain;charset=utf-8" });
let blob = new Blob([contentData], {
type: "text/plain;charset=utf-8",
});
saveAs(blob, baseTitle.value + ".md");
}
}
</script>
<template>
<el-drawer
@ -176,12 +203,29 @@ function download() {
</div>
</div>
</el-drawer>
<el-row justify="space-between" :gutter="20" :span="24" style="margin: 10px 20px">
<el-row
justify="space-between"
:gutter="20"
:span="24"
style="margin: 10px 20px"
>
<el-col :span="5">
<el-button @click.stop="drawerBox = !drawerBox" icon="Menu" circle />
<el-button @click.stop="importMd" icon="Upload" circle />
<el-button
@click.stop="drawerBox = !drawerBox"
icon="Menu"
circle
/>
<el-button
@click.stop="importMd"
icon="Upload"
circle
/>
<el-button @click.stop="download" icon="Download" circle />
<el-button
@click.stop="download"
icon="Download"
circle
/>
<input
type="file"
ref="fileInput"
@ -191,14 +235,25 @@ function download() {
/>
</el-col>
<el-col :span="15">
<el-input v-model="baseTitle" placeholder="输入标题" />
<el-input
v-model="baseTitle"
placeholder="输入标题"
/>
</el-col>
<el-col :span="2">
<el-button @click.stop="saveData()" icon="Finished" :loading="isSaveing" circle />
<el-button
@click.stop="saveData()"
icon="Finished"
:loading="isSaveing"
circle
/>
</el-col>
</el-row>
<div id="vditorContainer" style="margin: 10px 20px"></div>
<div
id="vditorContainer"
style="margin: 10px 20px"
></div>
</template>
<style scoped>
@import "@/assets/left.scss";
@import "@/assets/left.scss";
</style>

134
frontend/src/components/oa/ShareFiles.vue

@ -1,82 +1,114 @@
<template>
<el-form :model="form" label-width="auto" style="max-width: 560px;margin-top:20px;padding: 20px;">
<el-form
:model="form"
label-width="auto"
style="max-width: 560px; margin-top: 20px; padding: 20px"
>
<el-form-item label="分享给">
<el-select v-model="form.receverid" filterable multiple clearable collapse-tags placeholder="选择人员"
popper-class="custom-header" :max-collapse-tags="1" value-key="id" style="width: 240px" @change="checkUsers">
<el-select
v-model="form.receverid"
filterable
multiple
clearable
collapse-tags
placeholder="选择人员"
popper-class="custom-header"
:max-collapse-tags="1"
value-key="id"
style="width: 240px"
@change="checkUsers"
>
<template #header>
<el-checkbox v-model="checkAll" @change="handleCheckAll">
<el-checkbox
v-model="checkAll"
@change="handleCheckAll"
>
全选
</el-checkbox>
</template>
<el-option v-for="item in userList" :key="item.id" :label="item.nickname" :value="item.id" />
<el-option
v-for="item in userList"
:key="item.id"
:label="item.nickname"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="编辑权限">
<el-switch v-model="form.iswrite" active-value="1" inactive-value="0" />
<el-switch
v-model="form.iswrite"
active-value="1"
inactive-value="0"
/>
</el-form-item>
<div class="btn-group">
<el-button type="primary" @click="onSubmit">发布分享</el-button>
<el-button
type="primary"
@click="onSubmit"
>发布分享</el-button
>
</div>
</el-form>
</template>
<script lang="ts" setup>
import { ref, inject, onMounted } from 'vue';
import { useSystem, BrowserWindow } from '@/system';
import { getSystemConfig, fetchPost } from "@/system/config";
import { notifySuccess, notifyError } from "@/util/msg";
const window: BrowserWindow | undefined = inject("browserWindow");
const sys = useSystem()
const userInfo: any = sys.getConfig('userInfo')
let userList = ref(userInfo.user_shares)
const checkAll = ref(false)
const form: any = ref({
senderid: '',
import { BrowserWindow, useSystem } from "@/system";
import { fetchPost, getSystemConfig } from "@/system/config";
import { notifyError, notifySuccess } from "@/util/msg";
import { inject, onMounted, ref } from "vue";
const window: BrowserWindow | undefined = inject("browserWindow");
const sys = useSystem();
const userInfo: any = sys.getConfig("userInfo");
let userList = ref(userInfo.user_shares);
const checkAll = ref(false);
const form: any = ref({
senderid: "",
receverid: [],
path: '',
iswrite: '0'
})
const config = ref(getSystemConfig())
path: "",
iswrite: "0",
});
const config = ref(getSystemConfig());
const handleCheckAll = (val: any) => {
const handleCheckAll = (val: any) => {
if (val) {
form.value.receverid = userList.value.map((d: any) => d.value)
form.value.receverid = userList.value.map((d: any) => d.value);
} else {
form.value.receverid.value = []
form.value.receverid.value = [];
}
}
const checkUsers = (val: any) => {
const res:any = []
};
const checkUsers = (val: any) => {
const res: any = [];
val.forEach((item: any) => {
if(item){
res.push(item)
if (item) {
res.push(item);
}
})
form.value.receverid = res
}
const onSubmit = async () => {
const apiUrl = config.value.userInfo.url + '/files/share'
form.value.senderid = config.value.userInfo.id
form.value.path = window?.config.path || ''
const temp = {...form.value}
temp.senderid = temp.senderid.toString()
temp.receverid = temp.receverid.map((item:any) => item.toString())
const res = await fetchPost(apiUrl, new URLSearchParams(temp))
});
form.value.receverid = res;
};
const onSubmit = async () => {
const apiUrl = config.value.userInfo.url + "/files/share";
form.value.senderid = config.value.userInfo.id;
form.value.path = window?.config.path || "";
const temp = { ...form.value };
temp.senderid = temp.senderid.toString();
temp.receverid = temp.receverid.map((item: any) => item.toString());
const res = await fetchPost(apiUrl, new URLSearchParams(temp));
const result = await res.json();
if (res.ok) {
notifySuccess("分享文件成功")
notifySuccess(result.message || "分享文件成功");
} else {
notifyError("分享文件失败")
notifyError(result.message || "分享文件失败");
}
}
onMounted(() => {
userList.value = userList.value.filter((item: any)=> {
return item?.id !== config.value.userInfo.id
})
})
};
onMounted(() => {
userList.value = userList.value.filter((item: any) => {
return item?.id !== config.value.userInfo.id;
});
});
</script>
<style scoped>
.btn-group{
.btn-group {
display: flex;
justify-content: center;
}
}
</style>

129
frontend/src/components/setting/SetFilePwd.vue

@ -1,81 +1,106 @@
<template>
<div class="file-pwd-box">
<div v-if="setPwd">
<div class="setting-item" >
<div class="setting-item">
<label>文件密码</label>
<el-input v-model="filePwd" placeholder="请设置6-10位的密码" type="password" show-password/>
<el-input
v-model="filePwd"
placeholder="请设置6-10位的密码"
type="password"
show-password
/>
</div>
<div class="setting-item">
<label></label>
<el-button @click="toSetFilePwd" type="primary">{{ t("setFilePwd") }}</el-button>
<el-button @click="clearPwd" type="primary">取消文件加密</el-button>
<el-button
@click="toSetFilePwd"
type="primary"
>{{ t("setFilePwd") }}</el-button
>
<el-button
@click="clearPwd"
type="primary"
>取消文件加密</el-button
>
</div>
</div>
<div v-else class="setting-item">
<div
v-else
class="setting-item"
>
<label></label>
<el-button @click="setPwd = true" type="primary">设置文件密码</el-button>
<el-button
@click="setPwd = true"
type="primary"
>设置文件密码</el-button
>
</div>
</div>
</template>
<script lang="ts" setup>
import { md5 } from "js-md5";
import { ref, onMounted } from "vue";
import { t } from "@/system";
import { fetchGet, getApiUrl, setSystemKey, getSystemConfig } from "@/system/config";
import { notifySuccess, notifyError } from "@/util/msg";
const filePwd = ref('')
const setPwd = ref(false)
const config = getSystemConfig()
const params = {
import { t } from "@/system";
import {
fetchGet,
getApiUrl,
getSystemConfig,
setSystemKey,
} from "@/system/config";
import { notifyError, notifySuccess } from "@/util/msg";
import { md5 } from "js-md5";
import { onMounted, ref } from "vue";
const filePwd = ref("");
const setPwd = ref(false);
const config = getSystemConfig();
const params = {
isPwd: 1,
pwd: '',
salt: getSystemConfig().file.salt
}
//
async function toSetFilePwd() {
pwd: "",
salt: getSystemConfig().file.salt,
};
//
async function toSetFilePwd() {
if (filePwd.value.length < 6 || filePwd.value.length > 10) {
notifyError("密码长度应该在6-10位之间")
return
notifyError("密码长度应该在6-10位之间");
return;
}
params.pwd = md5(filePwd.value)
params.isPwd = filePwd.value === '' ? 0 : 1
const url = getApiUrl() + '/file/setfilepwd'
params.pwd = md5(filePwd.value);
params.isPwd = filePwd.value === "" ? 0 : 1;
const url = getApiUrl() + "/file/setfilepwd";
const header = {
'Salt': params.salt ? params.salt : 'vIf_wIUedciAd0nTm6qjJA==',
'FilePwd': params.pwd
}
await fetchGet(`${getApiUrl()}/file/changeispwd?ispwd=${params.isPwd}`)
const res = await fetchGet(url, header)
if (res.ok){
salt: params.salt ? params.salt : "vIf_wIUedciAd0nTm6qjJA==",
pwd: params.pwd,
};
await fetchGet(`${getApiUrl()}/file/changeispwd?ispwd=${params.isPwd}`);
const res = await fetchGet(url, header);
if (res.ok) {
notifySuccess("设置文件密码成功");
} else {
params.isPwd = 0
params.pwd = ''
notifyError("设置文件密码失败")
params.isPwd = 0;
params.pwd = "";
notifyError("设置文件密码失败");
}
setSystemKey("file", params);
}
setSystemKey('file',params)
}
async function clearPwd() {
setPwd.value = false
filePwd.value = ''
params.isPwd = 0
await fetchGet(`${getApiUrl()}/file/changeispwd?ispwd=0`)
setSystemKey('file',params)
}
onMounted(() => {
params.isPwd = config.file.isPwd
setPwd.value = params.isPwd ? true : false
})
async function clearPwd() {
setPwd.value = false;
filePwd.value = "";
params.isPwd = 0;
await fetchGet(`${getApiUrl()}/file/changeispwd?ispwd=0`);
setSystemKey("file", params);
}
onMounted(() => {
params.isPwd = config.file.isPwd;
setPwd.value = params.isPwd ? true : false;
});
</script>
<style scoped>
@import "./setStyle.css";
.file-pwd-box {
@import "./setStyle.css";
.file-pwd-box {
padding-top: 20px;
}
.setting-item {
}
.setting-item {
display: flex;
align-items: center;
}
}
</style>

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

@ -75,7 +75,7 @@
if (isShareFile(path)) {
const file = await sys?.fs.getShareInfo(path);
isShare.value = true;
isWrite.value = file.fs.is_write;
isWrite.value = file.fs.sender === getSystemConfig().userInfo.id ? 1 : file.fs.is_write;
if (
!isWrite.value &&
file.fs.sender !== getSystemConfig().userInfo.id
@ -119,7 +119,8 @@
// console.log("", res, isShare);
new Notify({
title: "提示",
content: res.code === 0 ? "文件已保存" : "文件保存失败",
content: res.message
// content: res.code === 0 ? "" : res.message,
});
sys.refershAppList();
} else if (eventData.type == "initSuccess") {

1
frontend/src/system/core/FileOs.ts

@ -427,7 +427,6 @@ export const useOsFile = () => {
}
}
}
//console.log('创建露肩:', path);
const response = await handleWriteFile(path, content, head);
if (response) {

2
godo/cmd/serve.go

@ -86,7 +86,7 @@ func (l loggingMiddleware) Middleware(next http.Handler) http.Handler {
// CORS 中间件
func corsMiddleware() mux.MiddlewareFunc {
allowHeaders := "Content-Type, Accept, Authorization, Origin,filePwd,salt"
allowHeaders := "Content-Type, Accept, Authorization, Origin,pwd,salt"
allowMethods := "GET, POST, PUT, DELETE, OPTIONS"
return func(next http.Handler) http.Handler {

Loading…
Cancel
Save