Browse Source

fix:文件分享bug修复

master
prr 7 months ago
parent
commit
b3951968ac
  1. 17
      frontend/src/components/builtin/EditFileName.vue
  2. 2
      frontend/src/components/builtin/FileIcon.vue
  3. 25
      frontend/src/components/builtin/FileList.vue
  4. 16
      frontend/src/components/builtin/FileProps.vue
  5. 226
      frontend/src/components/chat/ChatUserSetting.vue
  6. 1
      frontend/src/components/desktop/ScreenContent.vue
  7. 1
      frontend/src/components/window/IframeFile.vue
  8. 1
      frontend/src/hook/useContextMenu.ts
  9. 18
      frontend/src/system/core/FileOs.ts

17
frontend/src/components/builtin/EditFileName.vue

@ -17,6 +17,7 @@ import {
useSystem, useSystem,
OsFileWithoutContent, OsFileWithoutContent,
} from "@/system"; } from "@/system";
import { notifyError } from "@/util/msg";
const browserWindow: BrowserWindow = inject("browserWindow")!; const browserWindow: BrowserWindow = inject("browserWindow")!;
const name = ref(basename((browserWindow.config.content as OsFileWithoutContent).path)); const name = ref(basename((browserWindow.config.content as OsFileWithoutContent).path));
@ -29,10 +30,22 @@ function confirm() {
}); });
return; return;
} }
const newPath = join(browserWindow.config.content.path, name.value); let oldPath = ''
if(browserWindow.config.content?.isShare) {
oldPath = browserWindow.config.content.parentPath
} else {
const temp = browserWindow.config.content.path.split('/')
temp.pop()
oldPath = temp.join('/')
}
const newPath = join(oldPath, name.value);
useSystem() useSystem()
?.fs.rename(browserWindow.config.content.path, newPath) ?.fs.rename(browserWindow.config.content.path, newPath)
.then(() => { .then((res: any) => {
if(!res || res.code === -1) {
notifyError(res.message || '改名失败')
return
}
emitEvent("file.props.edit"); emitEvent("file.props.edit");
browserWindow.emit("file.props.edit", newPath); browserWindow.emit("file.props.edit", newPath);
browserWindow.close(); browserWindow.close();

2
frontend/src/components/builtin/FileIcon.vue

@ -7,7 +7,7 @@
<div v-if="extname(file?.path || '') === '.ln' || file?.isShare === true" class="ln-img"> <div v-if="extname(file?.path || '') === '.ln' || file?.isShare === true" class="ln-img">
<img :src="lnicon" alt="ln" /> <img :src="lnicon" alt="ln" />
</div> </div>
<div v-if="extname(file?.path || '') === '.ln' || file?.isPwd === true" class="lock-img"> <div v-if="file?.isPwd === true" class="lock-img">
<img :src="lockImg" alt="ln" /> <img :src="lockImg" alt="ln" />
</div> </div>
</div> </div>

25
frontend/src/components/builtin/FileList.vue

@ -161,7 +161,7 @@ function doubleTouch(e: TouchEvent, item: OsFileWithoutContent) {
const editIndex = ref<number>(-1); const editIndex = ref<number>(-1);
const editName = ref<string>(''); const editName = ref<string>('');
function onEditNameEnd() { async function onEditNameEnd() {
const editEndName = editName.value.trim(); const editEndName = editName.value.trim();
if (editEndName && editIndex.value >= 0) { if (editEndName && editIndex.value >= 0) {
const editpath: any = props.fileList[editIndex.value].path.toString() const editpath: any = props.fileList[editIndex.value].path.toString()
@ -174,7 +174,7 @@ function onEditNameEnd() {
newPath.pop() newPath.pop()
newPath.push(editEndName) newPath.push(editEndName)
newPath = newPath.join(sp) newPath = newPath.join(sp)
sys?.fs.rename( await sys?.fs.rename(
editpath, editpath,
newPath newPath
); );
@ -384,6 +384,17 @@ function handleRightClick(mouse: MouseEvent, item: OsFileWithoutContent, index:
}, },
}) })
} }
if (!item.isShare) {
fileMenus.push({
label: t('create.shortcut'),
click: () => {
createLink(item.path)?.then(() => {
chosenIndexs.value = [];
props.onRefresh();
});
},
},)
}
const userType = sys.getConfig('userType'); const userType = sys.getConfig('userType');
if (userType == 'member' && !item.isShare && !item.isDirectory) { if (userType == 'member' && !item.isShare && !item.isDirectory) {
@ -428,16 +439,6 @@ function handleRightClick(mouse: MouseEvent, item: OsFileWithoutContent, index:
menuArr.push.apply(menuArr, fileMenus) menuArr.push.apply(menuArr, fileMenus)
} }
const sysEndMenu = [ const sysEndMenu = [
{
label: t('create.shortcut'),
click: () => {
createLink(item.path)?.then(() => {
chosenIndexs.value = [];
props.onRefresh();
});
},
},
{ {
label: t('props'), label: t('props'),
click: () => { click: () => {

16
frontend/src/components/builtin/FileProps.vue

@ -85,8 +85,8 @@ if(path.indexOf('/F') === 0) {
} }
// file.value = await useSystem()?.fs.stat(window?.config.content); // file.value = await useSystem()?.fs.stat(window?.config.content);
function localName<T>(currentPath:T){ function localName<T>(currentPath:T){
if(isShareFile(path)) { if(isShareFile(path) && file.value && file.value.path) {
const arr = path.split('/') const arr = file?.value.path.split('/')
const url = '/' + arr[1] + '/' + arr[2] + '/' + arr[arr.length-1] const url = '/' + arr[1] + '/' + arr[2] + '/' + arr[arr.length-1]
return arr.length >3 ? url : currentPath return arr.length >3 ? url : currentPath
} }
@ -109,7 +109,17 @@ function editFileName() {
resizable: false, resizable: false,
}); });
win.on("file.props.edit", async (_: string, data: string) => { win.on("file.props.edit", async (_: string, data: string) => {
file.value = await useSystem()?.fs.stat(data); //console.log('', file.value, data);
if(data.indexOf('data/userData') === 0) {
const newPathArr = data.split('/')
const pathArr = file.value?.path.split('/') || []
pathArr.pop()
pathArr.push(newPathArr.pop() || '')
const shareInfo = await useSystem()?.fs.getShareInfo(pathArr.join('/'))
file.value = shareInfo?.fi
} else {
file.value = await useSystem()?.fs.stat(data);
}
}); });
win.show(); win.show();

226
frontend/src/components/chat/ChatUserSetting.vue

@ -1,29 +1,34 @@
<script setup> <script lang="ts" setup>
import { t } from '@/i18n'; import { t } from '@/i18n';
import { ref, onMounted } from "vue"; import { ref, reactive, onMounted } from "vue";
import { useChatStore } from "@/stores/chat"; import { useChatStore } from "@/stores/chat";
import { notifyError, notifySuccess } from "@/util/msg"; import { notifyError, notifySuccess } from "@/util/msg";
import { fetchGet, getSystemConfig, setSystemKey } from "@/system/config"; import { fetchGet, fetchPost, getSystemConfig, setSystemKey } from "@/system/config";
const store = useChatStore() const store = useChatStore()
const form = ref({ const form = ref({
nickname: '', nickname: '',
}) })
interface ImgItem {
url: string;
name: string;
}
const editType = ref(0)
const userInfo = getSystemConfig().userInfo const userInfo = getSystemConfig().userInfo
const dialogShow = ref(false) const dialogShow = ref(false)
let imgList = reactive([]) let imgList = reactive<ImgItem[]>([])
let pos = ref(0) let pos = ref(0)
const showChange = (val) =>{
const showChange = (val: boolean) =>{
dialogShow.value = val dialogShow.value = val
} }
const toChangeHead = async ()=>{ const toChangeHead = async ()=>{
let res = await fetchGet(`${userInfo.url}/files/saveavatar?id=${userInfo.id}&name=${imgList[pos.value].name}`) let res = await fetchGet(`${userInfo.url}/files/saveavatar?id=${userInfo.id}&name=${imgList[pos.value]?.name}`)
console.log('submit!:',res)
if (!res.ok) { if (!res.ok) {
notifyError("头像换取失败") notifyError("头像换取失败")
} else { } else {
res = await res.json() const response = await res.json()
notifySuccess(res.message) notifySuccess(response?.message || '头像换取成功')
userInfo.avatar = imgList[pos.value].name userInfo.avatar = imgList[pos.value]?.name
store.userInfo.avatar = userInfo.url + '/upload/avatar/' + userInfo.avatar store.userInfo.avatar = userInfo.url + '/upload/avatar/' + userInfo.avatar
setSystemKey('userInfo', userInfo) setSystemKey('userInfo', userInfo)
} }
@ -35,8 +40,8 @@ const getHeadList = async () => {
// const apiUrl = getSystemConfig().apiUrl + '/upload/avatar/'; // const apiUrl = getSystemConfig().apiUrl + '/upload/avatar/';
const apiUrl = userInfo.url + '/upload/avatar/'; const apiUrl = userInfo.url + '/upload/avatar/';
if (res.ok) { if (res.ok) {
res = await res.json() const response = await res.json()
for (const item of res.data) { for (const item of response?.data) {
imgList.push({ imgList.push({
url: apiUrl + item, url: apiUrl + item,
name: item name: item
@ -45,67 +50,143 @@ const getHeadList = async () => {
} }
} }
// //
const chooseImg = (index) => { const chooseImg = (index: number) => {
pos.value = index pos.value = index
} }
const onSubmit = async () => { const onSubmit = async () => {
console.log('提交'); console.log('提交');
} }
//
const passwordForm = reactive({
oldPassword: '',
newPassword: '',
confirmPassword: ''
})
const passwordRef:any = ref(null)
const rules = {
oldPassword: [
{ required: true, message: '密码不能为空', trigger: 'blur' }
],
newPassword: [
{ required: true, message: '密码不能为空', trigger: 'blur' },
{ min: 6, message: '密码长度不能小于6位', trigger: 'blur' }
],
confirmPassword: [
{ required: true, message: '请再次输入密码', trigger: 'blur' },
{ validator: (value:any, callback:any) => {
if (value === '') {
callback(new Error('请再次输入密码'));
} else if (value !== passwordForm.newPassword) {
callback(new Error('两次输入的密码不一致'));
} else {
callback();
}
}, trigger: 'blur' }
],
}
const toChangePwd = async () => {
try {
await passwordRef.value.validate()
const formData = new FormData()
formData.append('oldpassword', passwordForm.oldPassword)
formData.append('newpassword', passwordForm.newPassword)
let res = await fetchPost(`${userInfo.url}/member/savepwd`, formData)
const response = await res.json()
if (response && response?.success) {
notifySuccess(response?.message)
} else {
notifyError(response?.message)
}
} catch (e) {
console.log(e)
}
}
onMounted(()=>{ onMounted(()=>{
getHeadList() getHeadList()
store.userInfo.avatar = userInfo.url + '/upload/avatar/' + userInfo.avatar store.userInfo.avatar = userInfo.url + '/upload/avatar/' + userInfo.avatar
}) })
</script> </script>
<template> <template>
<div> <el-container>
<el-form :model="form" label-width="160px" style="padding: 30px;"> <el-aside>
<el-form-item label="头像"> <div @click="editType = 0" :class="{'is-active': editType == 0}">修改资料</div>
<el-avatar :size="90" :src="store.userInfo.avatar" @click="showChange(true)"/> <div @click="editType = 1" :class="{'is-active': editType == 1}">修改密码</div>
</el-form-item> </el-aside>
<el-form-item label="昵称"> <el-main>
<el-input v-model="store.userInfo.nickname" /> <el-form v-if="editType == 0" :model="form" label-width="150px" style="padding: 30px;">
</el-form-item> <el-form-item label="头像">
<el-form-item label="手机号"> <el-avatar :size="90" :src="store.userInfo.avatar" @click="showChange(true)"/>
<el-input v-model="store.userInfo.phone" /> </el-form-item>
</el-form-item> <el-form-item label="昵称">
<el-form-item label="工号"> <el-input v-model="store.userInfo.nickname" />
<el-input v-model="store.userInfo.job_number" /> </el-form-item>
</el-form-item> <el-form-item label="手机号">
<el-form-item label="自我介绍"> <el-input v-model="store.userInfo.phone" />
<el-input v-model="store.userInfo.desc" /> </el-form-item>
</el-form-item> <el-form-item label="工号">
<el-form-item> <el-input v-model="store.userInfo.job_number" />
<el-button type="primary" @click="onSubmit">保存</el-button> </el-form-item>
</el-form-item> <el-form-item label="自我介绍">
</el-form> <el-input v-model="store.userInfo.desc" />
<el-dialog v-model="dialogShow" title="修改头像" width="500px" draggable> </el-form-item>
<div> <el-form-item>
<span <el-button type="primary" @click="onSubmit">保存</el-button>
v-for="(item, index) in imgList" </el-form-item>
:key="item.name" </el-form>
class="img-box" <el-form v-else :model="passwordForm" :rules="rules" ref="passwordRef" label-width="120px" style="padding: 30px;">
> <el-form-item label="旧密码" prop="oldPassword">
<el-avatar <el-input
:size="80" v-model="passwordForm.oldPassword"
:src="item.url" type="password"
@click="chooseImg(index)" show-password
:class="{'is-active': pos == index}" />
</el-form-item>
<el-form-item label="新密码" prop="newPassword">
<el-input
v-model="passwordForm.newPassword"
type="password"
show-password
/>
</el-form-item>
<el-form-item label="再次输入密码" prop="confirmPassword">
<el-input
v-model="passwordForm.confirmPassword"
type="password"
show-password
/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="toChangePwd">保存</el-button>
</el-form-item>
</el-form>
</el-main>
<el-dialog v-model="dialogShow" title="修改头像" width="400px" draggable>
<div>
<span
v-for="(item, index) in imgList"
:key="item.name"
class="img-box"
> >
</el-avatar> <el-avatar
<el-icon v-show="pos == index"><Select /></el-icon> :size="80"
</span> :src="item.url"
</div> @click="chooseImg(index)"
<template #footer> :class="{'is-active': pos == index}"
<div class="dialog-footer"> >
<el-button @click="showChange(false)">{{ t("cancel") }}</el-button> </el-avatar>
<el-button type="primary" @click="toChangeHead"> <el-icon v-show="pos == index"><Select /></el-icon>
{{ t("confirm") }} </span>
</el-button> </div>
</div> <template #footer>
</template> <div class="dialog-footer">
</el-dialog> <el-button @click="showChange(false)">{{ t("cancel") }}</el-button>
<el-button type="primary" @click="toChangeHead">
</div> {{ t("confirm") }}
</el-button>
</div>
</template>
</el-dialog>
</el-container>
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">
@ -132,5 +213,28 @@ onMounted(()=>{
transform: translate(-50%,0) transform: translate(-50%,0)
} }
} }
.el-container {
.el-aside {
width: 20%;
padding: 20px;
background-color: #f9f9f9;
box-sizing: border-box;
div {
width: 100%;
min-width: 38px;
height: 40px;
font-size: 14px;
}
.is-active,
div:hover {
font-weight: bold;
color: #16b777;
}
.el-input {
width: 200px;
}
}
}
</style> </style>

1
frontend/src/components/desktop/ScreenContent.vue

@ -31,6 +31,7 @@ defineProps<{
rootState: RootState; rootState: RootState;
}>(); }>();
onMounted(() => { onMounted(() => {
//console.log('rootState:', RootState.state);
useSystem().rootRef = screenref.value; useSystem().rootRef = screenref.value;
}); });
</script> </script>

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

@ -67,7 +67,6 @@ const eventHandler = async (e: MessageEvent) => {
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)
console.log('文件信息:',file);
isShare.value = true isShare.value = true
isWrite.value = file.fs.is_write isWrite.value = file.fs.is_write
if (!isWrite.value) { if (!isWrite.value) {

1
frontend/src/hook/useContextMenu.ts

@ -215,6 +215,7 @@ function useContextMenu() {
newPath = fspath.join(parentPath, `${file.title}(${i}).${file.ext}`) newPath = fspath.join(parentPath, `${file.title}(${i}).${file.ext}`)
} }
} }
//console.log(newPath) //console.log(newPath)
return system?.fs.rename(file.path, newPath) return system?.fs.rename(file.path, newPath)

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

@ -2,7 +2,7 @@ import { getFileUrl,fetchGet,fetchPost } from "../config.ts";
const API_BASE_URL = getFileUrl() const API_BASE_URL = getFileUrl()
import { OsFileMode } from '../core/FileMode'; import { OsFileMode } from '../core/FileMode';
import { getSystemConfig } from "@/system/config"; import { getSystemConfig } from "@/system/config";
import { turnServePath, turnLocalPath, isRootShare } from "@/util/sharePath.ts"; import { turnServePath, turnLocalPath, isRootShare, isShareFile } from "@/util/sharePath.ts";
import { OsFile } from "./FileSystem.ts"; import { OsFile } from "./FileSystem.ts";
// import { notifyError } from "@/util/msg"; // import { notifyError } from "@/util/msg";
export async function handleReadDir(path: any): Promise<any> { export async function handleReadDir(path: any): Promise<any> {
@ -137,7 +137,17 @@ export async function handleClear(): Promise<any> {
} }
export async function handleRename(oldPath: string, newPath: string): Promise<any> { export async function handleRename(oldPath: string, newPath: string): Promise<any> {
const res = await fetchGet(`${API_BASE_URL}/rename?oldPath=${encodeURIComponent(oldPath)}&newPath=${encodeURIComponent(newPath)}`); const url = isShareFile(oldPath) ? 'sharerename' : 'rename'
let params = ''
if (isShareFile(oldPath)) {
const optionID = oldPath.indexOf('/F/myshare') === 0 ? 0 : 1
oldPath = turnServePath(oldPath)
newPath = turnServePath(newPath)
params = `oldpath=${encodeURIComponent(oldPath)}&newpath=${encodeURIComponent(newPath)}&userID=${getSystemConfig()?.userInfo.id}&optionID=${optionID}`
} else {
params = `oldPath=${encodeURIComponent(oldPath)}&newPath=${encodeURIComponent(newPath)}`
}
const res = await fetchGet(`${API_BASE_URL}/${url}?${params}`);
if (!res.ok) { if (!res.ok) {
return false; return false;
} }
@ -298,6 +308,8 @@ export const useOsFile = () => {
async getShareInfo(path: string) { async getShareInfo(path: string) {
const response = await handleShareDetail(path, getSystemConfig().userInfo.id); const response = await handleShareDetail(path, getSystemConfig().userInfo.id);
if (response && response.data) { if (response && response.data) {
response.data.fi.isShare = true
response.data.fi.path = turnLocalPath(response.data.fi.path, path, 1)
return response.data; return response.data;
} }
return []; return [];
@ -357,7 +369,7 @@ export const useOsFile = () => {
return false; return false;
}, },
async rename(oldPath: string, newPath: string) { async rename(oldPath: string, newPath: string) {
const response = await handleRename(turnServePath(oldPath), turnServePath(newPath)); const response = await handleRename(oldPath, newPath);
if (response) { if (response) {
return response; return response;
} }

Loading…
Cancel
Save