完成问题反馈
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='
|
||||
// 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
|
||||
|
|
|
@ -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({
|
|||
<span class={'w-[20px]'}>{idx + 1}</span>
|
||||
<div
|
||||
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]'
|
||||
)}
|
||||
>
|
||||
|
|
|
@ -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'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'SiderSetting',
|
||||
props: {},
|
||||
setup() {
|
||||
const settings = useSettingsStore()
|
||||
return () => (
|
||||
|
@ -18,7 +16,7 @@ export default defineComponent({
|
|||
>
|
||||
<Button type="primary">立即重置</Button>
|
||||
</SettingItem>
|
||||
<p class={"text-[#666] text-[12px]"}>将会把您的历史调整清空,恢复成最初的样式</p>
|
||||
<p class={'text-[#666] text-[12px]'}>将会把您的历史调整清空,恢复成最初的样式</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -30,8 +30,6 @@ const list: {
|
|||
}
|
||||
]
|
||||
export default defineComponent({
|
||||
name: 'SearchSetting',
|
||||
props: {},
|
||||
setup() {
|
||||
const settings = useSettingsStore()
|
||||
const searchStore = useSearchConfigStore()
|
||||
|
|
13
src/main.css
13
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;
|
||||
|
|
|
@ -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(() => {
|
|||
<DockSetting />
|
||||
) : router.path === 'settings-reset' ? (
|
||||
<Reset />
|
||||
) : router.path === 'settings-fallback' ? (
|
||||
<Feedback />
|
||||
) : null}
|
||||
</ThemeProvider>
|
||||
</div>
|
||||
|
|
|
@ -23,7 +23,7 @@ export default defineStore('user', () => {
|
|||
watch(token, (val) => {
|
||||
localStorage.setItem('token', val)
|
||||
})
|
||||
const profile = reactive({...defaultUserInfo})
|
||||
const profile = reactive({ ...defaultUserInfo })
|
||||
watch(
|
||||
token,
|
||||
(val) => {
|
||||
|
@ -37,7 +37,7 @@ export default defineStore('user', () => {
|
|||
const isLogin = computed(() => !!token.value && !!profile.id)
|
||||
const logout = () => {
|
||||
token.value = ''
|
||||
Object.assign(profile, {...defaultUserInfo})
|
||||
Object.assign(profile, { ...defaultUserInfo })
|
||||
// profile.avatar = ''
|
||||
}
|
||||
// 自动备份
|
||||
|
|
Loading…
Reference in New Issue