diff --git a/src/config.ts b/src/config.ts
index 20c3049..fe9beda 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -2,16 +2,16 @@ export const aIUrl = 'https://metaso.cn/?s=uitab&referrer_s=uitab&q='
export const translateUrl = 'https://fanyi.baidu.com/mtpe-individual/multimodal?lang=zh2en&query='
// oss地址
export const ossBase = import.meta.env.PROD
- ? 'https://oss.goosetab.com'
- : 'https://oss.goosetab.com'
+ ? 'https://newfatfox.oss-cn-beijing.aliyuncs.com'
+ : 'https://newfatfox.oss-cn-beijing.aliyuncs.com'
// 前端地址
-export const frontAddress = import.meta.env.PROD
- ? 'http://goosetab.com'
- : 'http://goosetab.com'
+export const frontAddress = import.meta.env.PROD ? 'http://goosetab.com' : 'http://goosetab.com'
// oss cdn 加速地址
-export const ossCdnBase = import.meta.env.PROD ? ossBase : ossBase
+export const ossCdnBase = import.meta.env.PROD
+ ? 'https://oss.goosetab.com'
+ : 'https://oss.goosetab.com'
// 后端地址
export const apiBase = import.meta.env.PROD
diff --git a/src/layout/grid/DirBlock.tsx b/src/layout/grid/DirBlock.tsx
index e3828c5..27490c0 100644
--- a/src/layout/grid/DirBlock.tsx
+++ b/src/layout/grid/DirBlock.tsx
@@ -40,7 +40,7 @@ export default defineComponent({
'grid-rows-2 grid-cols-2 gap-[8%] p-[10%]': !props.big
})}
onContextmenu={() => {
- menu.open('dock')
+ menu.open(props.block)
}}
>
{selectedDir.value.list
diff --git a/src/layout/grid/DockSetting.tsx b/src/layout/grid/DockSetting.tsx
index 0a94580..a98a482 100644
--- a/src/layout/grid/DockSetting.tsx
+++ b/src/layout/grid/DockSetting.tsx
@@ -25,8 +25,6 @@ export const Letter24 = [
'R'
]
export default defineComponent({
- name: 'SiderSetting',
- props: {},
setup() {
const settings = useSettingsStore()
const layout = useLayoutStore()
@@ -71,7 +69,6 @@ export default defineComponent({
{idx + 1}
diff --git a/src/layout/grid/Feedback.tsx b/src/layout/grid/Feedback.tsx
new file mode 100644
index 0000000..c219b2e
--- /dev/null
+++ b/src/layout/grid/Feedback.tsx
@@ -0,0 +1,169 @@
+import { computed, defineComponent, reactive, toRaw } from 'vue'
+import useLayoutStore from '../useLayoutStore'
+import ImageUploader from '@/utils/ImageUploader'
+
+import { MdInbox } from 'oh-vue-icons/icons'
+import { addIcons, OhVueIcon } from 'oh-vue-icons'
+import { message, Modal, Table } from 'ant-design-vue'
+import request from '@/utils/request'
+import db from '@/db'
+
+addIcons(MdInbox)
+export interface Feedback {
+ description: string
+ qq: string
+ phone: string
+ images: string[]
+ time: number
+}
+const defaultData: Omit
= {
+ description: '',
+ qq: '',
+ phone: '',
+ images: [] as string[]
+}
+export default defineComponent(() => {
+ const data = reactive({ ...defaultData })
+ const layout = useLayoutStore()
+ const isGame = computed(() => {
+ return layout.state.current === 0
+ })
+ const img1 = computed({
+ get: () => data.images[0],
+ set: (val) => (data.images[0] = val)
+ })
+ const img2 = computed({
+ get: () => data.images[1],
+ set: (val) => (data.images[1] = val)
+ })
+ const img3 = computed({
+ get: () => data.images[2],
+ set: (val) => (data.images[2] = val)
+ })
+ return () => (
+
+
+
+ *
+ 问题描述
+
+
{
+ let his = await db.getItem
('feedbacks')
+ if (!his) his = []
+ const ins = Modal.info({
+ title: '历史反馈',
+ width: '1024px',
+ maskClosable: true,
+ content: () => (
+ new Date(record.time).toLocaleString()
+ },
+ {
+ title: '问题描述',
+ customRender: ({ record }) => (
+ {record.description}
+ )
+ },
+ {
+ title: 'QQ',
+ dataIndex: 'qq'
+ },
+ {
+ title: '手机号',
+ dataIndex: 'phone'
+ },
+ {
+ title: '图片',
+ customRender: ({ record }) => (
+
+ {record?.images?.map?.((img: string) => (
+
+ ))}
+
+ )
+ }
+ ]}
+ >
+ ),
+ onOk() {
+ console.log('OK')
+ ins.destroy()
+ },
+ onCancel() {
+ ins.destroy()
+ }
+ })
+ }}
+ >
+
+ 历史反馈
+
+
+
+
联系方式
+
留下您的联系方式,以便必要时我们可以联系到您
+
+
+
+
+
{
+ if (!data.description) {
+ message.error('问题描述不能为空')
+ return
+ }
+ let his = await db.getItem('feedbacks')
+ if (!his) his = []
+ await db.setItem('feedbacks', [...his, { ...toRaw(data), time: Date.now() }])
+ await request('POST', '/api/feedback', {
+ data: {
+ content: data.description,
+ qq: data.qq,
+ phone: data.phone,
+ imgs: data.images
+ },
+ returnType: 'text'
+ })
+ message.success('提交成功')
+ Object.assign(data, { ...defaultData })
+ }}
+ class="mt-4 text-center rounded py-1 cursor-pointer bg-[#ffa93d] text-white"
+ >
+ 提交反馈
+
+
+ )
+})
diff --git a/src/layout/grid/Reset.tsx b/src/layout/grid/Reset.tsx
index b7cf263..ce91683 100644
--- a/src/layout/grid/Reset.tsx
+++ b/src/layout/grid/Reset.tsx
@@ -5,8 +5,6 @@ import clsx from 'clsx'
import { defineComponent } from 'vue'
export default defineComponent({
- name: 'SiderSetting',
- props: {},
setup() {
const settings = useSettingsStore()
return () => (
@@ -18,7 +16,7 @@ export default defineComponent({
>
- 将会把您的历史调整清空,恢复成最初的样式
+ 将会把您的历史调整清空,恢复成最初的样式
)
}
diff --git a/src/layout/grid/SearchSetting.tsx b/src/layout/grid/SearchSetting.tsx
index c5d94bb..db2a8ee 100644
--- a/src/layout/grid/SearchSetting.tsx
+++ b/src/layout/grid/SearchSetting.tsx
@@ -5,8 +5,6 @@ import { defineComponent, ref } from 'vue'
import useSearchConfigStore from '../header/search/useSearchConfigStore'
export default defineComponent({
- name: 'SearchSetting',
- props: {},
setup() {
const settings = useSettingsStore()
const searchStore = useSearchConfigStore()
diff --git a/src/layout/grid/SiderSetting.tsx b/src/layout/grid/SiderSetting.tsx
index 08d708e..c015aa8 100644
--- a/src/layout/grid/SiderSetting.tsx
+++ b/src/layout/grid/SiderSetting.tsx
@@ -6,8 +6,6 @@ import { defineComponent } from 'vue'
import useLayoutStore from '../useLayoutStore'
export default defineComponent({
- name: 'SiderSetting',
- props: {},
setup() {
const settings = useSettingsStore()
const layout = useLayoutStore()
diff --git a/src/layout/grid/TimeSetting.tsx b/src/layout/grid/TimeSetting.tsx
index d5a7af8..fc61a1d 100644
--- a/src/layout/grid/TimeSetting.tsx
+++ b/src/layout/grid/TimeSetting.tsx
@@ -30,8 +30,6 @@ const list: {
}
]
export default defineComponent({
- name: 'SearchSetting',
- props: {},
setup() {
const settings = useSettingsStore()
const searchStore = useSearchConfigStore()
diff --git a/src/layout/useLayoutStore.ts b/src/layout/useLayoutStore.ts
index 3109a6e..a05c391 100644
--- a/src/layout/useLayoutStore.ts
+++ b/src/layout/useLayoutStore.ts
@@ -6,6 +6,8 @@ import useResource from './background/useResource'
import { globalToast } from '@/main'
import jump from '@/utils/jump'
import useSettingsStore from '@/settings/useSettingsStore'
+import useUserStore from '@/user/useUserStore'
+import request from '@/utils/request'
const defaultLayout: Layout = {
content: [
@@ -23,6 +25,7 @@ const defaultLayout: Layout = {
export default defineStore('layout', () => {
const settings = useSettingsStore()
+ const user = useUserStore()
const state = reactive(defaultLayout)
const ready = ref(false)
@@ -125,6 +128,28 @@ export default defineStore('layout', () => {
}
}
})
+
+ let it: any = 0
+ watch(
+ state,
+ (s, _, onCleanUp) => {
+ const id = user.profile.id
+ if (!id) return
+ it = setTimeout(() => {
+ if (!id) return
+ request('PUT', '/api/backup', {
+ data: s,
+ returnType: 'text'
+ })
+ }, 3000)
+ onCleanUp(() => {
+ clearTimeout(it)
+ })
+ },
+ {
+ deep: true
+ }
+ )
return {
state,
ready,
diff --git a/src/main.css b/src/main.css
index 0ac2a4b..b0b10de 100644
--- a/src/main.css
+++ b/src/main.css
@@ -44,6 +44,19 @@
padding-top: 5px !important;
padding-bottom: 5px !important;
}
+
+.no-textarea:focus {
+ outline: none !important;
+ border: none !important;
+}
+.no-textarea:hover {
+ outline: none !important;
+ border: none !important;
+}
+.no-textarea {
+ outline: none !important;
+ border: none !important;
+}
:root {
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
diff --git a/src/settings/SettingsOverlayContent.tsx b/src/settings/SettingsOverlayContent.tsx
index 7ab17c6..2958cb3 100644
--- a/src/settings/SettingsOverlayContent.tsx
+++ b/src/settings/SettingsOverlayContent.tsx
@@ -8,6 +8,7 @@ import SearchSetting from '@/layout/grid/SearchSetting'
import TimeSetting from '@/layout/grid/TimeSetting'
import SiderSetting from '@/layout/grid/SiderSetting'
import DockSetting from '@/layout/grid/DockSetting'
+import Feedback from '@/layout/grid/Feedback'
import Reset from '@/layout/grid/Reset'
export default defineComponent(() => {
@@ -32,6 +33,8 @@ export default defineComponent(() => {
) : router.path === 'settings-reset' ? (
+ ) : router.path === 'settings-fallback' ? (
+
) : null}
diff --git a/src/user/useUserStore.ts b/src/user/useUserStore.ts
index bf95f8b..e632a43 100644
--- a/src/user/useUserStore.ts
+++ b/src/user/useUserStore.ts
@@ -1,3 +1,5 @@
+import type { Block, Layout } from '@/layout/layout.types'
+import useLayoutStore from '@/layout/useLayoutStore'
import request from '@/utils/request'
import { defineStore } from 'pinia'
import { computed, reactive, ref, watch } from 'vue'
@@ -18,29 +20,61 @@ const defaultUserInfo: UserInfo = {
avatar: '',
openId: ''
}
+
+function getLinkList(data: Layout) {
+ const list = [] as Block[]
+ for (const mode of data.content) {
+ for (const page of mode.pages) {
+ for (const item of page.list) {
+ if (!item.link || item.link.startsWith('id:')) break
+ list.push(item)
+ }
+ }
+ }
+ for (const item of data.dock) {
+ if (item) list.push(item)
+ }
+ for (const dirItem of Object.values(data.dir)) {
+ for (const item of dirItem.list) {
+ list.push(item)
+ }
+ }
+ return list
+}
+
export default defineStore('user', () => {
const token = ref(localStorage.getItem('token') || '')
watch(token, (val) => {
localStorage.setItem('token', val)
})
- const profile = reactive({...defaultUserInfo})
+ const profile = reactive({ ...defaultUserInfo })
+ const layout = useLayoutStore()
watch(
token,
- (val) => {
+ async (val) => {
if (!val) return
- request('GET', '/api/profile').then((res) => {
- Object.assign(profile, res)
- })
+ const res = await request('GET', '/api/profile')
+ Object.assign(profile, res)
+ const data = await request('GET', '/api/backup')
+ const remoteList = getLinkList(data)
+ const localList = getLinkList(layout.state)
+ const addList: Block[] = []
+ for (const item of remoteList) {
+ if (!localList.some((el) => el.id !== item.id)) {
+ addList.push(item)
+ }
+ }
+ if (addList.length > 0) {
+ // TODO: 交给张阳
+ }
},
{ immediate: true }
)
const isLogin = computed(() => !!token.value && !!profile.id)
const logout = () => {
token.value = ''
- Object.assign(profile, {...defaultUserInfo})
- // profile.avatar = ''
+ Object.assign(profile, { ...defaultUserInfo })
}
- // 自动备份
return {
token,
profile,