diff --git a/CHANGELOG.md b/CHANGELOG.md
index 65a1300..a58026a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,8 @@
## 变更记录
+-2024-09-03
+1. 修复文件重命名错误的bug
+2. 修复拖拽上传中断的bug
+3. 新增可手动关闭广告
- 2024-08-27
1. 优化初始化系统,初始化系统时只请求读写一次
2. 去除浏览器存储
@@ -28,6 +32,8 @@ bug梳理:
5. web 的甘特图保存不了
6. 场景适用性:系统默认连接gitee远程软件安装包,缺少默认读取本地安装包路径的json配置文件的打包设置选项(比如在安装时自动读取安装U盘当前目录中/或已直接打包进安装包中的mysql/nginx/php/python本地离线安装包、以及企业自用OA WebApp的本地离线安装包,无需联网,直接同步离线安装)
7. 功能完整性:安装的服务型应用(如mysql/nginx/php/python)没有跟随软件环境启动后自动启动的设置选项,依赖于服务型应用的AI Web UI、php /python应用没有创建桌面快捷方式/菜单快捷方式的入口(即:AI Web UI、php /python应用无法安装和自动开箱即用)。
+8. excel读取原始文件兼容性问题
+9. word读取原始文件兼容性
### 后续开放:
1. 优化内网聊天
diff --git a/frontend/components.d.ts b/frontend/components.d.ts
index afebaeb..39b4653 100644
--- a/frontend/components.d.ts
+++ b/frontend/components.d.ts
@@ -44,9 +44,12 @@ declare module 'vue' {
ElButton: typeof import('element-plus/es')['ElButton']
ElCarousel: typeof import('element-plus/es')['ElCarousel']
ElCarouselItem: typeof import('element-plus/es')['ElCarouselItem']
+ ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
+ ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
ElCol: typeof import('element-plus/es')['ElCol']
+ ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
+ ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
ElDialog: typeof import('element-plus/es')['ElDialog']
- ElDrawer: typeof import('element-plus/es')['ElDrawer']
ElEmpty: typeof import('element-plus/es')['ElEmpty']
ElForm: typeof import('element-plus/es')['ElForm']
ElFormItem: typeof import('element-plus/es')['ElFormItem']
@@ -57,12 +60,16 @@ declare module 'vue' {
ElPagination: typeof import('element-plus/es')['ElPagination']
ElPopover: typeof import('element-plus/es')['ElPopover']
ElProgress: typeof import('element-plus/es')['ElProgress']
+ ElRadio: typeof import('element-plus/es')['ElRadio']
+ ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
ElRow: typeof import('element-plus/es')['ElRow']
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
ElSelect: typeof import('element-plus/es')['ElSelect']
ElSpace: typeof import('element-plus/es')['ElSpace']
+ ElSwitch: typeof import('element-plus/es')['ElSwitch']
ElTable: typeof import('element-plus/es')['ElTable']
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
+ ElTimePicker: typeof import('element-plus/es')['ElTimePicker']
ElTooltip: typeof import('element-plus/es')['ElTooltip']
Error: typeof import('./src/components/taskbar/Error.vue')['default']
FileIcon: typeof import('./src/components/builtin/FileIcon.vue')['default']
@@ -79,8 +86,6 @@ declare module 'vue' {
InstallMember: typeof import('./src/components/install/InstallMember.vue')['default']
InstallPerson: typeof import('./src/components/install/InstallPerson.vue')['default']
LockDesktop: typeof import('./src/components/desktop/LockDesktop.vue')['default']
- LoginDeskop: typeof import('./src/components/desktop/LoginDeskop.vue')['default']
- LoginDesktop: typeof import('./src/components/desktop/LoginDesktop.vue')['default']
Magnet: typeof import('./src/components/taskbar/Magnet.vue')['default']
MarkDown: typeof import('./src/components/builtin/MarkDown.vue')['default']
MenuBar: typeof import('./src/components/window/MenuBar.vue')['default']
@@ -99,6 +104,7 @@ declare module 'vue' {
OsImage: typeof import('./src/components/builtin/OsImage.vue')['default']
PdfViewer: typeof import('./src/components/builtin/PdfViewer.vue')['default']
PictureStore: typeof import('./src/components/builtin/PictureStore.vue')['default']
+ PlanTasks: typeof import('./src/components/oa/PlanTasks.vue')['default']
ProcessManager: typeof import('./src/components/setting/ProcessManager.vue')['default']
QuickLink: typeof import('./src/components/computer/QuickLink.vue')['default']
RectChosen: typeof import('./src/components/builtin/RectChosen.vue')['default']
@@ -114,6 +120,7 @@ declare module 'vue' {
SetSystem: typeof import('./src/components/setting/SetSystem.vue')['default']
Setting: typeof import('./src/components/setting/Setting.vue')['default']
SetUpdate: typeof import('./src/components/setting/SetUpdate.vue')['default']
+ ShowNews: typeof import('./src/components/taskbar/ShowNews.vue')['default']
StartMenu: typeof import('./src/components/taskbar/StartMenu.vue')['default']
StartOption: typeof import('./src/components/taskbar/StartOption.vue')['default']
StateIcon: typeof import('./src/components/taskbar/StateIcon.vue')['default']
diff --git a/frontend/src/components/builtin/EditFileName.vue b/frontend/src/components/builtin/EditFileName.vue
index 0ff203f..07abd7e 100644
--- a/frontend/src/components/builtin/EditFileName.vue
+++ b/frontend/src/components/builtin/EditFileName.vue
@@ -1,17 +1,12 @@
-
+
{{ t("confirm") }}
diff --git a/frontend/src/components/desktop/Notice.vue b/frontend/src/components/desktop/Notice.vue
index ccb28d4..8819461 100644
--- a/frontend/src/components/desktop/Notice.vue
+++ b/frontend/src/components/desktop/Notice.vue
@@ -12,13 +12,15 @@
+
diff --git a/frontend/src/components/oa/PlanTasks.vue b/frontend/src/components/oa/PlanTasks.vue
new file mode 100644
index 0000000..9ee6b52
--- /dev/null
+++ b/frontend/src/components/oa/PlanTasks.vue
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 全选
+
+
+
+
+
+
+
+
+ 创建任务
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/src/components/setting/SetAccount.vue b/frontend/src/components/setting/SetAccount.vue
index f045326..6e5ed07 100644
--- a/frontend/src/components/setting/SetAccount.vue
+++ b/frontend/src/components/setting/SetAccount.vue
@@ -2,12 +2,8 @@
@@ -15,7 +11,7 @@
-
{{ t('account.info') }}
+ 锁屏
{{ t('account') }}
@@ -23,44 +19,51 @@
{{ t('password') }}
-
+
- {{ t('confirm') }}
+ {{ t('confirm') }}
+
+
+
广告与更新提示
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/src/components/taskbar/ShowNews.vue b/frontend/src/components/taskbar/ShowNews.vue
new file mode 100644
index 0000000..b0fdf94
--- /dev/null
+++ b/frontend/src/components/taskbar/ShowNews.vue
@@ -0,0 +1,45 @@
+
+
+
+
+
发布时间: {{ store.newsDetail.showtime }}
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/src/hook/useContextMenu.ts b/frontend/src/hook/useContextMenu.ts
index 9c2957a..ec22b8f 100644
--- a/frontend/src/hook/useContextMenu.ts
+++ b/frontend/src/hook/useContextMenu.ts
@@ -44,9 +44,9 @@ function useContextMenu() {
callback?.();
});
}
-
+
//console.log(path)
- let menuArr = [
+ let menuArr: any = [
{
label: t('refresh'),
click: () => {
@@ -100,29 +100,7 @@ function useContextMenu() {
},
],
},
-
- // {
- // label: '新建报告',
- // submenu: [
- // {
- // label: '日报(Day)',
- // click : () => clickFunc('day', '日报'),
- // },
- // {
- // label: '周报(Week)',
- // click : () => clickFunc('week', '周报'),
- // },
- // {
- // label: '季报(Quarter)',
- // click : () => clickFunc('quarter', '季报'),
- // },
- // {
- // label: '年报(Year)',
- // click: () => clickFunc('year', '年报'),
- // },
- // ],
- // },
{
label: t('paste'),
click: () => {
@@ -139,9 +117,26 @@ function useContextMenu() {
});
},
},
- ...(system._rootState.options.contextMenus || []),
];
-
+ const userInfo: any = system.getConfig('userInfo');
+ if (userInfo.user_auths && userInfo.user_auths.length > 0 && userInfo.user_auths != "") {
+ menuArr.push(
+ {
+ label: '安排任务',
+ click: () => {
+ const win = new BrowserWindow({
+ title: '安排任务',
+ content: "PlanTasks",
+ width: 600,
+ height: 600,
+ center: true,
+ });
+ win.show();
+ }
+ }
+ )
+ }
+ menuArr = [...menuArr, ...(system._rootState.options.contextMenus || [])]
const menu = Menu.buildFromTemplate(
uniqBy(
menuArr,
@@ -162,7 +157,7 @@ function useContextMenu() {
}
newFilePath = fspath.join(path, `${title}(${i})${ext}`);
}
-
+
const content = '';
return await system.fs.writeFile(newFilePath, content);
}
diff --git a/frontend/src/hook/useFileDrag.ts b/frontend/src/hook/useFileDrag.ts
index 7e7ace0..15b5e3b 100644
--- a/frontend/src/hook/useFileDrag.ts
+++ b/frontend/src/hook/useFileDrag.ts
@@ -40,7 +40,7 @@ export function useFileDrag(system: System) {
async function writeFileToInner(
path: string,
name?: string,
- content?: string,
+ content?: any,
process?: (path: string) => void
) {
console.log(content)
@@ -48,15 +48,6 @@ export function useFileDrag(system: System) {
Dialog.showMessageBox({message:"上传失败", type:'error'})
return;
}
- // let fileNameArr = name?.split(".")
- // let ext = fileNameArr?.pop()
- // let title = fileNameArr?.join(".")
- // let save = {
- // title,
- // //blob: content?.replace(/data:.*?;base64,/, '') || ''
- // base64 : content || '',
- // ext
- // }
return await system?.fs
.writeFile(FsPath.join(path, name || 'unkown'), content)
.then(() => {
@@ -65,7 +56,8 @@ export function useFileDrag(system: System) {
}
// 外部文件拖到文件夹放下时
async function outerFileDrop(path: string, list: FileList | undefined, process: (path: string) => void) {
- const len = list?.length || 0;
+ if (!list) return;
+ const len = list.length
const { setProgress } = Dialog.showProcessDialog({
message: '正在写入到文件夹中',
});
@@ -74,35 +66,32 @@ export function useFileDrag(system: System) {
await new Promise((resolve) => {
const item = list?.[i];
console.log(item)
+ if (!item) return;
// let oFile = null;
const reader = new FileReader();
//读取成功
reader.onload = function () {
- console.log(reader);
+ // console.log(reader);
+ //console.log(reader.result)
};
reader.onloadstart = function () {
- console.log('读取开始');
+ //console.log('读取开始');
};
reader.onloadend = async function () {
- //console.log(reader.result)
- await writeFileToInner(path, item?.name, reader.result as string, process);
+ await writeFileToInner(path, item.name, reader.result as any, process);
resolve(true);
};
reader.onabort = function () {
- console.log('中断');
+ //console.log('中断');
};
reader.onerror = function () {
- console.log('读取失败');
+ //console.log('读取失败');
};
reader.onprogress = function (ev) {
const scale = ev.loaded / ev.total;
- if (scale >= 0.5) {
- reader.abort();
- }
+ setProgress(scale);
};
- //reader.readAsDataURL(new Blob([item as BlobPart]));
- //reader.readAsDataURL(item!);
- reader.readAsArrayBuffer(item!);
+ reader.readAsArrayBuffer(item);
});
}
setProgress(101);
diff --git a/frontend/src/stores/notify.ts b/frontend/src/stores/notify.ts
index a1643f5..6360612 100644
--- a/frontend/src/stores/notify.ts
+++ b/frontend/src/stores/notify.ts
@@ -1,40 +1,97 @@
import { defineStore } from "pinia";
import { ref } from "vue";
-import { getSystemConfig,fetchGet } from "@/system/config";
+import { getSystemConfig, fetchGet } from "@/system/config";
+import { useUpgradeStore } from "./upgrade";
export const useNotifyStore = defineStore('notifyStore', () => {
const config = getSystemConfig();
- const notifyList:any = ref([]);
+ const upgradeStore = useUpgradeStore()
+ const notifyList: any = ref([]);
+ const readList: any = ref([])
+ const showNews = ref(false)
+ const newsDetail = ref({})
const page = ref({
current: 1,
size: 10,
total: 0,
pages: 0,
})
- async function getList(){
- if(config.userType == 'person'){
+ async function getList() {
+ if (config.userType == 'person') {
return
- }
- const complition = await fetchGet(config.userInfo.url + '/news/list?page=' + page.value.current + '&limit='+ page.value.size)
- if(!complition.ok){
- return;
- }
- const data = await complition.json();
- if(data.success){
- page.value.total = data.data.total;
- notifyList.value = data.data.list;
- page.value.pages = Math.ceil(page.value.total / page.value.size)
- }
-
+ }
+ const complition = await fetchGet(config.userInfo.url + '/news/list?page=' + page.value.current + '&limit=' + page.value.size)
+ if (!complition.ok) {
+ return;
+ }
+ const data = await complition.json();
+ if (data.success) {
+ page.value.total = data.data.total;
+ notifyList.value = data.data.list;
+ page.value.pages = Math.ceil(page.value.total / page.value.size)
+ checkNotify()
+ }
+
+ }
+ const checkNotify = ()=> {
+ const list = notifyList.value.filter((item: any) => {
+ return readList.value.indexOf(item.id) < 0
+ })
+ if(list.length < 1)return;
+ const centerList = list.filter((item: any) => {
+ return item.position == 'center'
+ })
+ const bottomList = list.filter((item: any) => {
+ return item.position == 'bottom'
+ })
+ if(centerList.length > 0){
+ upgradeStore.hasAd = true
+ upgradeStore.adList = [...centerList, ...upgradeStore.adList]
+ }
+ if(bottomList.length > 0){
+ upgradeStore.hasNotice = true
+ upgradeStore.noticeList = [...bottomList, ...upgradeStore.noticeList]
+ }
+
+ }
+ const addRead = (id: number) => {
+ if (readList.value.indexOf(id) < 0) {
+ readList.value.push(id)
+ }
}
const pageClick = async (pageNum: any) => {
//console.log(pageNum)
page.value.current = pageNum
await getList()
}
+ const viewContent = (item :any) =>{
+ const timestamp = item.add_time * 1000; // 将 10 位时间戳转换为 13 位
+ const date = new Date(timestamp);
+ item.showtime = date.toLocaleString();
+ newsDetail.value = item
+ addRead(item.id)
+ showNews.value = true
+ }
return {
notifyList,
+ showNews,
+ newsDetail,
getList,
+ addRead,
page,
- pageClick
+ pageClick,
+ readList,
+ viewContent
+ }
+}, {
+ persist: {
+ enabled: true,
+ strategies: [
+ {
+ storage: localStorage,
+ paths: [
+ "readList",
+ ]
+ }, // name 字段用localstorage存储
+ ],
}
})
\ No newline at end of file
diff --git a/frontend/src/stores/upgrade.ts b/frontend/src/stores/upgrade.ts
index 280d87d..59d8811 100644
--- a/frontend/src/stores/upgrade.ts
+++ b/frontend/src/stores/upgrade.ts
@@ -36,6 +36,7 @@ export const useUpgradeStore = defineStore('upgradeStore', () => {
}
function systemMessage(){
const config = getSystemConfig();
+
const source = new EventSource(`${config.apiUrl}/system/message`);
source.onmessage = function(event) {
@@ -59,6 +60,7 @@ export const useUpgradeStore = defineStore('upgradeStore', () => {
async function checkUpdate(res:any) {
//console.log(res)
const config = getSystemConfig();
+ if(!config.account.ad)return;
currentVersion.value = config.version;
let bottomList:any = []
let centerList:any = []
@@ -68,13 +70,13 @@ export const useUpgradeStore = defineStore('upgradeStore', () => {
}
if(bottomList && bottomList.length > 0){
hasNotice.value = true
- noticeList.value = changeUrl(bottomList)
+ noticeList.value = [...noticeList.value, ...changeUrl(bottomList)]
}
//console.log(noticeList)
//console.log(centerList)
if(centerList && centerList.length > 0){
hasAd.value = true
- adList.value = changeUrl(centerList)
+ adList.value = [...adList.value, ...changeUrl(centerList)]
}
//console.log(adList.value)
diff --git a/frontend/src/system/config.ts b/frontend/src/system/config.ts
index 6cc66f2..eda6bc7 100644
--- a/frontend/src/system/config.ts
+++ b/frontend/src/system/config.ts
@@ -49,7 +49,9 @@ export const getSystemConfig = (ifset = false) => {
roleName: '',
dept_id: 0,
deptName: '',
- token: ''
+ token: '',
+ user_auths: '',
+ user_shares: ''
};
}
@@ -94,6 +96,7 @@ export const getSystemConfig = (ifset = false) => {
// 初始化账户信息,若本地存储中已存在则不进行覆盖
if (!config.account) {
config.account = {
+ ad: true,
username: '',
password: '',
};
@@ -155,7 +158,7 @@ export function getFileUrl() {
} else {
return config.apiUrl + '/file'
}
- }else{
+ } else {
return config.userInfo.url + '/files'
}
@@ -207,13 +210,7 @@ export function parseJson(str: string) {
};
export function getSplit() {
if (isWindowsOS()) {
- const storeType = getSystemKey('storeType')
- //console.log(storeType)
- if (storeType === 'browser') {
- return "/"
- } else {
- return "\\"
- }
+ return "\\"
} else {
return "/"
}
@@ -242,38 +239,38 @@ export const setSystemConfig = (config: any) => {
};
export const clearSystemConfig = () => {
- const storetype = localStorage.getItem('GodoOS-storeType') || 'browser';
+ const storetype = localStorage.getItem('GodoOS-storeType') || 'local';
localStorage.clear()
localStorage.setItem('GodoOS-storeType', storetype)
//localStorage.removeItem('GodoOS-config');
};
-function bin2hex(s:string) {
+function bin2hex(s: string) {
s = encodeURI(s);//只会有0-127的ascii不转化
- let m:any = s.match(/%[\dA-F]{2}/g), a:any = s.split(/%[\dA-F]{2}/), i, j, n, t;
+ let m: any = s.match(/%[\dA-F]{2}/g), a: any = s.split(/%[\dA-F]{2}/), i, j, n, t;
m.push("")
for (i in a) {
- if (a[i] === "") { a[i] = m[i]; continue }
- n = ""
- for (j in a[i]) {
- t = a[i][j].charCodeAt().toString(16).toUpperCase()
- if (t.length === 1) t = "0" + t
- n += "%" + t
- }
- a[i] = n + m[i]
+ if (a[i] === "") { a[i] = m[i]; continue }
+ n = ""
+ for (j in a[i]) {
+ t = a[i][j].charCodeAt().toString(16).toUpperCase()
+ if (t.length === 1) t = "0" + t
+ n += "%" + t
+ }
+ a[i] = n + m[i]
}
return a.join("").split("%").join("")
- }
- export const getClientId = () => {
- let uuid:any = localStorage.getItem("godoosClientId");
+}
+export const getClientId = () => {
+ let uuid: any = localStorage.getItem("godoosClientId");
if (!uuid) {
- let canvas = document.createElement('canvas');
- let ctx:any = canvas.getContext('2d');
- ctx.fillStyle = '#FF0000';
- ctx.fillRect(0, 0, 8, 10);
- let b64 = canvas.toDataURL().replace("data:image/png;base64,", "");
- let bin = window.atob(b64);
- uuid = bin2hex(bin.slice(-16, -12));
- localStorage.setItem("godoosClientId", uuid);
+ let canvas = document.createElement('canvas');
+ let ctx: any = canvas.getContext('2d');
+ ctx.fillStyle = '#FF0000';
+ ctx.fillRect(0, 0, 8, 10);
+ let b64 = canvas.toDataURL().replace("data:image/png;base64,", "");
+ let bin = window.atob(b64);
+ uuid = bin2hex(bin.slice(-16, -12));
+ localStorage.setItem("godoosClientId", uuid);
}
return uuid;
- }
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/frontend/src/system/index.ts b/frontend/src/system/index.ts
index 4c5f6da..ebc28cb 100644
--- a/frontend/src/system/index.ts
+++ b/frontend/src/system/index.ts
@@ -25,7 +25,7 @@ import { Tray, TrayOptions } from './menu/Tary';
import { getSystemConfig, getSystemKey, setSystemKey, setSystemConfig, clearSystemConfig, getFileUrl, fetchGet, getClientId } from './config'
import { useUpgradeStore } from '@/stores/upgrade';
import { RestartApp } from '@/util/goutil';
-import { notifyError, notifySuccess } from '@/util/msg';
+import { notifyError } from '@/util/msg';
export type OsPlugin = (system: System) => void;
export type FileOpener = {
diff --git a/godo/files/fs.go b/godo/files/fs.go
index 7240bc2..38dd655 100644
--- a/godo/files/fs.go
+++ b/godo/files/fs.go
@@ -228,12 +228,17 @@ func HandleRename(w http.ResponseWriter, r *http.Request) {
libs.HTTPError(w, http.StatusInternalServerError, err.Error())
return
}
+ err = CheckDeleteDesktop(oldPath)
+ if err != nil {
+ log.Printf("Error deleting file from desktop: %s", err.Error())
+ }
err = Rename(basePath, oldPath, newPath)
if err != nil {
log.Printf("Error renaming file: %s", err.Error())
libs.HTTPError(w, http.StatusConflict, err.Error())
return
}
+
err = CheckAddDesktop(newPath)
if err != nil {
log.Printf("Error adding file to desktop: %s", err.Error())