完成问题反馈
This commit is contained in:
parent
b65584e4af
commit
3d7eec25b2
|
@ -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='
|
export const translateUrl = 'https://fanyi.baidu.com/mtpe-individual/multimodal?lang=zh2en&query='
|
||||||
// oss地址
|
// oss地址
|
||||||
export const ossBase = import.meta.env.PROD
|
export const ossBase = import.meta.env.PROD
|
||||||
? 'https://oss.goosetab.com'
|
? 'https://newfatfox.oss-cn-beijing.aliyuncs.com'
|
||||||
: 'https://oss.goosetab.com'
|
: 'https://newfatfox.oss-cn-beijing.aliyuncs.com'
|
||||||
|
|
||||||
// 前端地址
|
// 前端地址
|
||||||
export const frontAddress = import.meta.env.PROD
|
export const frontAddress = import.meta.env.PROD ? 'http://goosetab.com' : 'http://goosetab.com'
|
||||||
? 'http://goosetab.com'
|
|
||||||
: 'http://goosetab.com'
|
|
||||||
|
|
||||||
// oss cdn 加速地址
|
// 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
|
export const apiBase = import.meta.env.PROD
|
||||||
|
|
|
@ -25,8 +25,6 @@ export const Letter24 = [
|
||||||
'R'
|
'R'
|
||||||
]
|
]
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'SiderSetting',
|
|
||||||
props: {},
|
|
||||||
setup() {
|
setup() {
|
||||||
const settings = useSettingsStore()
|
const settings = useSettingsStore()
|
||||||
const layout = useLayoutStore()
|
const layout = useLayoutStore()
|
||||||
|
@ -71,7 +69,6 @@ export default defineComponent({
|
||||||
<span class={'w-[20px]'}>{idx + 1}</span>
|
<span class={'w-[20px]'}>{idx + 1}</span>
|
||||||
<div
|
<div
|
||||||
class={clsx(
|
class={clsx(
|
||||||
|
|
||||||
'flex-1 bg-black/[0.05] border-[1px] py-1 rounded-lg relative flex items-center pl-4 border-transparent hover:border-[#ffa94d]'
|
'flex-1 bg-black/[0.05] border-[1px] py-1 rounded-lg relative flex items-center pl-4 border-transparent hover:border-[#ffa94d]'
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|
|
@ -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<Feedback, 'time'> = {
|
||||||
|
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 () => (
|
||||||
|
<div class={'p-4 ' + (isGame.value ? 'text-white' : 'text-black/60')}>
|
||||||
|
<div class="flex justify-between items-center">
|
||||||
|
<div>
|
||||||
|
<span class="text-red-500">*</span>
|
||||||
|
问题描述
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="cursor-pointer"
|
||||||
|
onClick={async () => {
|
||||||
|
let his = await db.getItem<Feedback[]>('feedbacks')
|
||||||
|
if (!his) his = []
|
||||||
|
const ins = Modal.info({
|
||||||
|
title: '历史反馈',
|
||||||
|
width: '1024px',
|
||||||
|
maskClosable: true,
|
||||||
|
content: () => (
|
||||||
|
<Table
|
||||||
|
class="max-h-[50vh] overflow-y-auto"
|
||||||
|
dataSource={his.reverse()}
|
||||||
|
rowKey="time"
|
||||||
|
pagination={false}
|
||||||
|
columns={[
|
||||||
|
{
|
||||||
|
title: '时间',
|
||||||
|
customRender: ({ record }) => new Date(record.time).toLocaleString()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '问题描述',
|
||||||
|
customRender: ({ record }) => (
|
||||||
|
<div class="w-[200px] break-all">{record.description}</div>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'QQ',
|
||||||
|
dataIndex: 'qq'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '手机号',
|
||||||
|
dataIndex: 'phone'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '图片',
|
||||||
|
customRender: ({ record }) => (
|
||||||
|
<div class="flex gap-2">
|
||||||
|
{record?.images?.map?.((img: string) => (
|
||||||
|
<img src={img} class="w-16 object-cover" />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
></Table>
|
||||||
|
),
|
||||||
|
onOk() {
|
||||||
|
console.log('OK')
|
||||||
|
ins.destroy()
|
||||||
|
},
|
||||||
|
onCancel() {
|
||||||
|
ins.destroy()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<OhVueIcon
|
||||||
|
name="md-inbox"
|
||||||
|
fill={isGame.value ? 'rgba(255,255,255,.8)' : 'rgba(0,0,0,.8)'}
|
||||||
|
/>
|
||||||
|
历史反馈
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class={'mt-2 ' + (isGame.value ? 'bg-white/10 text-white' : 'bg-black/5 text-black/60')}>
|
||||||
|
<textarea
|
||||||
|
v-model={data.description}
|
||||||
|
class="bg-transparent no-textarea w-full p-2"
|
||||||
|
style={{
|
||||||
|
color: isGame.value ? 'white' : 'black'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div class="p-2 flex gap-2">
|
||||||
|
<ImageUploader width={42} v-model:value={img1.value} />
|
||||||
|
<ImageUploader width={42} v-model:value={img2.value} />
|
||||||
|
<ImageUploader width={42} v-model:value={img3.value} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mt-4">联系方式</div>
|
||||||
|
<div class="text-sm">留下您的联系方式,以便必要时我们可以联系到您</div>
|
||||||
|
<div class="grid grid-cols-2 gap-2 text-sm mt-2">
|
||||||
|
<input
|
||||||
|
v-model={data.qq}
|
||||||
|
placeholder="QQ号"
|
||||||
|
class={'p-2 rounded-lg ' + (isGame.value ? 'bg-white/10' : 'bg-black/5')}
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
v-model={data.phone}
|
||||||
|
placeholder="手机号"
|
||||||
|
class={'p-2 rounded-lg ' + (isGame.value ? 'bg-white/10' : 'bg-black/5')}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
onClick={async () => {
|
||||||
|
if (!data.description) {
|
||||||
|
message.error('问题描述不能为空')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let his = await db.getItem<Feedback[]>('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"
|
||||||
|
>
|
||||||
|
提交反馈
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})
|
|
@ -5,8 +5,6 @@ import clsx from 'clsx'
|
||||||
import { defineComponent } from 'vue'
|
import { defineComponent } from 'vue'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'SiderSetting',
|
|
||||||
props: {},
|
|
||||||
setup() {
|
setup() {
|
||||||
const settings = useSettingsStore()
|
const settings = useSettingsStore()
|
||||||
return () => (
|
return () => (
|
||||||
|
@ -18,7 +16,7 @@ export default defineComponent({
|
||||||
>
|
>
|
||||||
<Button type="primary">立即重置</Button>
|
<Button type="primary">立即重置</Button>
|
||||||
</SettingItem>
|
</SettingItem>
|
||||||
<p class={"text-[#666] text-[12px]"}>将会把您的历史调整清空,恢复成最初的样式</p>
|
<p class={'text-[#666] text-[12px]'}>将会把您的历史调整清空,恢复成最初的样式</p>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,6 @@ import { defineComponent, ref } from 'vue'
|
||||||
import useSearchConfigStore from '../header/search/useSearchConfigStore'
|
import useSearchConfigStore from '../header/search/useSearchConfigStore'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'SearchSetting',
|
|
||||||
props: {},
|
|
||||||
setup() {
|
setup() {
|
||||||
const settings = useSettingsStore()
|
const settings = useSettingsStore()
|
||||||
const searchStore = useSearchConfigStore()
|
const searchStore = useSearchConfigStore()
|
||||||
|
|
|
@ -6,8 +6,6 @@ import { defineComponent } from 'vue'
|
||||||
import useLayoutStore from '../useLayoutStore'
|
import useLayoutStore from '../useLayoutStore'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'SiderSetting',
|
|
||||||
props: {},
|
|
||||||
setup() {
|
setup() {
|
||||||
const settings = useSettingsStore()
|
const settings = useSettingsStore()
|
||||||
const layout = useLayoutStore()
|
const layout = useLayoutStore()
|
||||||
|
|
|
@ -30,8 +30,6 @@ const list: {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'SearchSetting',
|
|
||||||
props: {},
|
|
||||||
setup() {
|
setup() {
|
||||||
const settings = useSettingsStore()
|
const settings = useSettingsStore()
|
||||||
const searchStore = useSearchConfigStore()
|
const searchStore = useSearchConfigStore()
|
||||||
|
|
13
src/main.css
13
src/main.css
|
@ -44,6 +44,19 @@
|
||||||
padding-top: 5px !important;
|
padding-top: 5px !important;
|
||||||
padding-bottom: 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 {
|
:root {
|
||||||
text-rendering: optimizeLegibility;
|
text-rendering: optimizeLegibility;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
|
|
|
@ -8,6 +8,7 @@ import SearchSetting from '@/layout/grid/SearchSetting'
|
||||||
import TimeSetting from '@/layout/grid/TimeSetting'
|
import TimeSetting from '@/layout/grid/TimeSetting'
|
||||||
import SiderSetting from '@/layout/grid/SiderSetting'
|
import SiderSetting from '@/layout/grid/SiderSetting'
|
||||||
import DockSetting from '@/layout/grid/DockSetting'
|
import DockSetting from '@/layout/grid/DockSetting'
|
||||||
|
import Feedback from '@/layout/grid/Feedback'
|
||||||
import Reset from '@/layout/grid/Reset'
|
import Reset from '@/layout/grid/Reset'
|
||||||
|
|
||||||
export default defineComponent(() => {
|
export default defineComponent(() => {
|
||||||
|
@ -32,6 +33,8 @@ export default defineComponent(() => {
|
||||||
<DockSetting />
|
<DockSetting />
|
||||||
) : router.path === 'settings-reset' ? (
|
) : router.path === 'settings-reset' ? (
|
||||||
<Reset />
|
<Reset />
|
||||||
|
) : router.path === 'settings-fallback' ? (
|
||||||
|
<Feedback />
|
||||||
) : null}
|
) : null}
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -23,7 +23,7 @@ export default defineStore('user', () => {
|
||||||
watch(token, (val) => {
|
watch(token, (val) => {
|
||||||
localStorage.setItem('token', val)
|
localStorage.setItem('token', val)
|
||||||
})
|
})
|
||||||
const profile = reactive({...defaultUserInfo})
|
const profile = reactive({ ...defaultUserInfo })
|
||||||
watch(
|
watch(
|
||||||
token,
|
token,
|
||||||
(val) => {
|
(val) => {
|
||||||
|
@ -37,7 +37,7 @@ export default defineStore('user', () => {
|
||||||
const isLogin = computed(() => !!token.value && !!profile.id)
|
const isLogin = computed(() => !!token.value && !!profile.id)
|
||||||
const logout = () => {
|
const logout = () => {
|
||||||
token.value = ''
|
token.value = ''
|
||||||
Object.assign(profile, {...defaultUserInfo})
|
Object.assign(profile, { ...defaultUserInfo })
|
||||||
// profile.avatar = ''
|
// profile.avatar = ''
|
||||||
}
|
}
|
||||||
// 自动备份
|
// 自动备份
|
||||||
|
|
Loading…
Reference in New Issue