Compare commits

..

7 Commits

Author SHA1 Message Date
shenhan000 16f4689ab3 update 2025-04-29 14:57:10 +08:00
shenhan000 a040a82fd8 update 2025-04-29 10:27:49 +08:00
shenhan000 9ae2729807 update 2025-04-28 17:11:58 +08:00
shenhan000 448895a1e6 update 2025-04-26 17:01:40 +08:00
shenhan000 c3841d66e9 Merge branch 'planet' 2025-04-26 17:01:17 +08:00
shenhan 836ce7c4da update 2025-04-26 14:06:29 +08:00
shenhan 99c2350a7b update 2025-04-26 14:02:52 +08:00
23 changed files with 4779 additions and 2407 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 845 B

3
app/components.d.ts vendored
View File

@ -16,12 +16,15 @@ declare module 'vue' {
NCheckbox: typeof import('naive-ui')['NCheckbox'] NCheckbox: typeof import('naive-ui')['NCheckbox']
NConfigProvider: typeof import('naive-ui')['NConfigProvider'] NConfigProvider: typeof import('naive-ui')['NConfigProvider']
NDatePicker: typeof import('naive-ui')['NDatePicker'] NDatePicker: typeof import('naive-ui')['NDatePicker']
NDivider: typeof import('naive-ui')['NDivider']
NDropdown: typeof import('naive-ui')['NDropdown'] NDropdown: typeof import('naive-ui')['NDropdown']
NEllipsis: typeof import('naive-ui')['NEllipsis'] NEllipsis: typeof import('naive-ui')['NEllipsis']
NEmpty: typeof import('naive-ui')['NEmpty'] NEmpty: typeof import('naive-ui')['NEmpty']
NForm: typeof import('naive-ui')['NForm'] NForm: typeof import('naive-ui')['NForm']
NFormItem: typeof import('naive-ui')['NFormItem'] NFormItem: typeof import('naive-ui')['NFormItem']
NIcon: typeof import('naive-ui')['NIcon'] NIcon: typeof import('naive-ui')['NIcon']
NImage: typeof import('naive-ui')['NImage']
NImageGroup: typeof import('naive-ui')['NImageGroup']
NInfiniteScroll: typeof import('naive-ui')['NInfiniteScroll'] NInfiniteScroll: typeof import('naive-ui')['NInfiniteScroll']
NInput: typeof import('naive-ui')['NInput'] NInput: typeof import('naive-ui')['NInput']
NInputGroup: typeof import('naive-ui')['NInputGroup'] NInputGroup: typeof import('naive-ui')['NInputGroup']

View File

@ -249,7 +249,7 @@ async function handlePictureChange(event: Event) {
placeholder="请输入加入费用" placeholder="请输入加入费用"
> >
<template #suffix> <template #suffix>
积分 金币
</template> </template>
</NInputNumber> </NInputNumber>
</NFormItem> </NFormItem>

View File

@ -78,8 +78,8 @@ async function getCommunityDetail() {
formValue.value = { formValue.value = {
imageUrl, imageUrl,
communityName, communityName,
communityTag: communityTag.toString(), communityTag: communityTag?.toString() || '',
type: type.toString(), type: type?.toString() || '',
price, price,
id, id,
validityDay, validityDay,
@ -274,7 +274,7 @@ async function handlePictureChange(event: Event) {
placeholder="请输入加入费用" placeholder="请输入加入费用"
> >
<template #suffix> <template #suffix>
积分 金币
</template> </template>
</NInputNumber> </NInputNumber>
</NFormItem> </NFormItem>

View File

@ -82,7 +82,7 @@ async function getQrCode() {
} }
} }
// //
const isVisible = ref(true) const isVisible = ref(true)
// //

View File

@ -126,8 +126,6 @@ async function handleUserSelect(key: string) {
} }
// //
async function handlePublishSelect(key: string) { async function handlePublishSelect(key: string) {
if (!userStore?.userInfo.name)
return
if (!userStore.isLoggedIn) { if (!userStore.isLoggedIn) {
modalStore.showLoginModal() modalStore.showLoginModal()
} }
@ -140,7 +138,6 @@ async function handlePublishSelect(key: string) {
} }
else { else {
const baseUrl = window.location.origin const baseUrl = window.location.origin
debugger
window.open(`${baseUrl}/${key}?type=add`, '_blank', 'noopener,noreferrer') window.open(`${baseUrl}/${key}?type=add`, '_blank', 'noopener,noreferrer')
// router.push({ // router.push({
// path: `/${key}`, // path: `/${key}`,

View File

@ -14,12 +14,13 @@ defineExpose({
const regex = /^1[3-9]\d{9}$/ const regex = /^1[3-9]\d{9}$/
const rules: FormRules = { const rules: FormRules = {
phone: [ phone: [
{ required: true, message: '请输入手机号', trigger: 'blur' }, // , trigger: 'blur'
{ pattern: regex, message: '手机号格式不正确', trigger: 'blur' }, { required: true, message: '请输入手机号' },
{ pattern: regex, message: '手机号格式不正确' },
], ],
code: [ code: [
{ required: true, message: '请输入验证码', trigger: 'blur' }, { required: true, message: '请输入验证码' },
{ len: 6, message: '验证码长度为6位', trigger: 'blur' }, { len: 6, message: '验证码长度为6位' },
], ],
} }
// //

View File

@ -122,7 +122,7 @@ watchEffect(() => {
<template> <template>
<div class="bg-white rounded-lg w-[290px] p-4 h-fit"> <div class="bg-white rounded-lg w-[290px] p-4 h-fit">
<div class="flex flex-col gap-4"> <div class="flex flex-col">
<!-- 左侧图片 --> <!-- 左侧图片 -->
<div class="w-[258px] h-[258px] rounded-lg relative bg-[#f2f3f5] overflow-hidden"> <div class="w-[258px] h-[258px] rounded-lg relative bg-[#f2f3f5] overflow-hidden">
<img <img
@ -150,7 +150,7 @@ watchEffect(() => {
</div> </div>
</div> </div>
</div> </div>
<n-divider />
<!-- 右侧信息 --> <!-- 右侧信息 -->
<div class="flex flex-col justify-between flex-1"> <div class="flex flex-col justify-between flex-1">
<div class="space-y-2"> <div class="space-y-2">
@ -158,23 +158,24 @@ watchEffect(() => {
{{ planetInfo.communityName }} {{ planetInfo.communityName }}
</h1> </h1>
</div> </div>
<div class="flex items-center gap-8 text-xs text-[#878d95] mt-1 mb-4"> <div class="flex items-center gap-8 text-xs text-[#878d95] mt-1">
<div>创建{{ planetInfo.validityDay }}</div> <div>创建{{ planetInfo.validityDay }}</div>
</div> </div>
<div class="text-sm text-[#4a5563] line-clamp-3"> <!-- line-clamp-3 -->
<div class="text-sm text-[#4a5563] py-3">
{{ planetInfo.description }} {{ planetInfo.description }}
</div> </div>
</div> </div>
</div> </div>
<div <div
class="flex items-center bg-[#F4F9FF] px-2 py-3 rounded-lg mt-4 text-sm text-gray-800 cursor-pointer" class="flex items-center bg-[#F4F9FF] px-2 py-3 rounded-lg text-sm text-gray-800 cursor-pointer"
@click="toFileList" @click="toFileList"
> >
<FileChartColumnIncreasing class="w-4 h-4 mr-2" /> <FileChartColumnIncreasing class="w-4 h-4 mr-2" />
全部文件 全部文件
</div> </div>
<!-- 在线咨询 --> <!-- 在线咨询 -->
<div class="mt-6"> <div class="">
<button <button
class="w-full bg-[#1e80ff] hover:bg-[#3b8fff] text-white rounded-lg py-3 mt-4" class="w-full bg-[#1e80ff] hover:bg-[#3b8fff] text-white rounded-lg py-3 mt-4"
@click="handleShowQuestion" @click="handleShowQuestion"

View File

@ -1,7 +1,10 @@
<script setup lang="ts"> <script setup lang="ts">
import { commonApi } from '@/api/common'
// import { NConfigProvider, NInfiniteScroll, NInput } from 'naive-ui' // import { NConfigProvider, NInfiniteScroll, NInput } from 'naive-ui'
import { import {
EllipsisVertical, EllipsisVertical,
FileChartColumn,
Star, Star,
ThumbsUp, ThumbsUp,
} from 'lucide-vue-next' } from 'lucide-vue-next'
@ -33,7 +36,6 @@ const props = defineProps({
default: () => ({}), default: () => ({}),
}, },
}) })
// const $props = defineProps(['headUrl', 'dataList', 'height']) // const $props = defineProps(['headUrl', 'dataList', 'height'])
const userStore = useUserStore() const userStore = useUserStore()
@ -256,6 +258,7 @@ async function handleDel(type: string, item: any) {
if (type === 'parent') { if (type === 'parent') {
params.publishId = item.item.id params.publishId = item.item.id
params.communityId = item.item.communityId params.communityId = item.item.communityId
params.tenantId = item.item.tenantId
} }
else { else {
const { id, communityId, tenantId } = item.sub const { id, communityId, tenantId } = item.sub
@ -277,11 +280,14 @@ async function handleDel(type: string, item: any) {
} }
} }
//
const isVisibleReport = ref(false)
async function handleSelect(event: any, type: string, item: any) { async function handleSelect(event: any, type: string, item: any) {
event.stopPropagation() // event.stopPropagation() //
if (type === 'choiceness') { if (type === 'choiceness') {
try { try {
const res = await request.get(`publish/elite?publishId=${item.id}&communityId=${item.communityId}`) const res = await request.get(`publish/elite?publishId=${item.id}&communityId=${item.communityId}&tenantId=${item.tenantId}`)
if (res.code === 200) { if (res.code === 200) {
message.success(item.isElite === 1 ? '取消精选成功!' : '精选成功!') message.success(item.isElite === 1 ? '取消精选成功!' : '精选成功!')
getCommentList() getCommentList()
@ -292,20 +298,30 @@ async function handleSelect(event: any, type: string, item: any) {
} }
} }
else if (type === 'complaint') { else if (type === 'complaint') {
console.log('投诉') isVisibleReport.value = true
} }
else if (type === 'delete') { else if (type === 'delete') {
console.log('删除') console.log('删除')
} }
} }
//
function handleDownload(url: string) {
const a = document.createElement('a')
a.href = url
a.download = url.split('/').pop() || 'downloaded_file'
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
}
</script> </script>
<template> <template>
<div class="bg-white py-4 rounded min-h-[320px]"> <div class="min-h-[320px]">
<div <div
v-for="(item, index) in commentList" v-for="(item, index) in commentList"
:key="index" :key="index"
class="px-4" class="p-4 mb-2 rounded bg-white"
> >
<div class="nav-wrap"> <div class="nav-wrap">
<div class="left-img"> <div class="left-img">
@ -313,7 +329,7 @@ async function handleSelect(event: any, type: string, item: any) {
</div> </div>
<div class="right"> <div class="right">
<div class="name flex justify-between items-center relative"> <div class="name flex justify-between items-center relative">
<span>{{ item.userName }}</span> <span class="text-[#4a5563] text-sm">{{ item.userName }}</span>
<img <img
v-if="item.isElite === 1" v-if="item.isElite === 1"
class="cursor-pointer absolute right-0 top-[4px] w-10 h-10" class="cursor-pointer absolute right-0 top-[4px] w-10 h-10"
@ -354,11 +370,11 @@ async function handleSelect(event: any, type: string, item: any) {
</div> </div>
</div> </div>
</div> </div>
<div class="des"> <div class="text-gray-500 text-xs">
{{ item.content }} {{ item. createTime }}
</div> </div>
<div class="star-wrap"> <div class="star-wrap">
<span class="time">{{ item.createTime }}</span> <span class="text-[#192029] text-sm">{{ item.content }}</span>
<div class="star-operator"> <div class="star-operator">
<div class="icon-wrap"> <div class="icon-wrap">
<ThumbsUp size="16" class="mr-1" :color="item.isLike !== 0 ? '#ff0000' : '#000000'" @click="handleFocus('parent', { item })" /> <ThumbsUp size="16" class="mr-1" :color="item.isLike !== 0 ? '#ff0000' : '#000000'" @click="handleFocus('parent', { item })" />
@ -370,7 +386,51 @@ async function handleSelect(event: any, type: string, item: any) {
<span class="cursor-pointer m-r16" @click="handleMessage(item)"></span> <span class="cursor-pointer m-r16" @click="handleMessage(item)"></span>
<span class="cursor-pointer" @click="handleDel('parent', { item })">删除</span> <span v-if="item.userId === userStore?.userInfo?.userId || userStore?.userInfo?.userId === Number(props.publishListParams.tenantId)" class="cursor-pointer" @click="handleDel('parent', { item })"></span>
</div>
</div>
<div>
<div v-if="item.fileName" class="my-2">
<!-- <n-image-group>
<n-space>
<n-image
v-for="(subItem, subIndex) in item.fileName.split(',')"
:key="subIndex"
width="100"
:src="subItem"
/>
</n-space>
</n-image-group> -->
<div
v-for="(subItem, subIndex) in item.fileName.split(',')"
:key="subIndex"
title="点击下载"
class="text-[#4a5563] text-sm cursor-pointer flex items-center hover:text-[#4a5563]/80"
@click="handleDownload(subItem)"
>
<FileChartColumn size="16" class="mr-1" />
{{ subItem }}
</div>
</div>
<div v-if="item.imageUrl" class="flex items-center my-1 gap-2">
<n-image-group>
<n-space>
<n-image
v-for="(subItem, subIndex) in item.imageUrl.split(',')"
:key="subIndex"
width="80"
height="70"
:src="subItem"
/>
</n-space>
</n-image-group>
<!-- <img
v-for="(subItem, subIndex) in item.imageUrl.split(',')"
:key="subIndex"
class="w-14 h-14 rounded-lg"
:src="subItem"
alt=""
> -->
</div> </div>
</div> </div>
<!-- 父项评论回复操作 --> <!-- 父项评论回复操作 -->
@ -392,7 +452,7 @@ async function handleSelect(event: any, type: string, item: any) {
</div> </div>
</div> </div>
</div> </div>
<div class="child-wrap"> <div v-if="item.commentList.length > 0" class="child-wrap bg-[#f9fbff] ml-12 p-2 rounded">
<div v-for="(ele, subIndex) in item.commentList" :key="subIndex" class="child-wrap-item"> <div v-for="(ele, subIndex) in item.commentList" :key="subIndex" class="child-wrap-item">
<div class="left-img"> <div class="left-img">
<img :src="ele.userAvatar"> <img :src="ele.userAvatar">
@ -419,7 +479,7 @@ async function handleSelect(event: any, type: string, item: any) {
<span style="vertical-align: middle">{{ ele.likeNum }}</span> <span style="vertical-align: middle">{{ ele.likeNum }}</span>
</div> </div>
<span class="cursor-pointer m-r16" @click="handleMessage(ele)"></span> <span class="cursor-pointer m-r16" @click="handleMessage(ele)"></span>
<span v-if="item.userId === userStore?.userInfo?.userId" class="cursor-pointer" @click="handleDel('sub', { item, sub: ele })"></span> <span v-if="item.userId === userStore?.userInfo?.userId || userStore?.userInfo?.userId === Number(props.publishListParams.tenantId)" class="cursor-pointer" @click="handleDel('sub', { item, sub: ele })"></span>
</div> </div>
</div> </div>
<!-- 子项评论回复操作 --> <!-- 子项评论回复操作 -->
@ -443,6 +503,67 @@ async function handleSelect(event: any, type: string, item: any) {
</div> </div>
</div> </div>
</div> </div>
<div>
<PlanetReport
v-model="isVisibleReport"
:publish-list-params="props.publishListParams"
/>
</div>
<!-- <n-modal
v-model:show="isVisibleReport"
:preset="null"
:mask-closable="false"
transform-origin="center"
class="custom-modal"
>
<div class="bg-white rounded-xl p-4">
<div class="flex items-center justify-between">
<div class="text-xl">
举报
</div>
<div>
<n-icon size="20" class="mr-2 cursor-pointer" @click="closeReport">
<Close />
</n-icon>
</div>
</div>
<div class="flex flex-col p-4">
<n-radio
v-for="(item, index) in reportList"
:key="index"
class="m-4 text-[#fff000]"
size="large"
:checked="reportType === item.dictValue"
value="Definitely Maybe"
name="basic-demo"
@change="handleChange(item)"
>
{{ item.dictLabel }}
</n-radio>
<n-input
v-if="
reportType !== undefined && reportType === '6'
"
v-model:value="reportTypeText"
placeholder="点击输入"
type="textarea"
:autosize="{
minRows: 5,
maxRows: 10,
}"
/>
<div
class="mt-4 w-[100%] h-10 flex rounded-lg text-white items-center justify-center cursor-pointer"
:class="[
reportType !== undefined ? 'bg-[#4c79ee]' : 'bg-[#cccccc]',
]"
@click="onReport"
>
确认
</div>
</div>
</div>
</n-modal> -->
<div class="no-more"> <div class="no-more">
暂时没有更多评论 暂时没有更多评论
</div> </div>
@ -576,7 +697,6 @@ async function handleSelect(event: any, type: string, item: any) {
} }
.child-wrap { .child-wrap {
padding-left: 52px;
.child-wrap-item { .child-wrap-item {
display: flex; display: flex;
font-size: 14px; font-size: 14px;

View File

@ -109,7 +109,7 @@ function handleShowMessage() {
<!-- 右侧功能区 --> <!-- 右侧功能区 -->
<div class="flex items-center ml-auto space-x-4"> <div class="flex items-center ml-auto space-x-4">
<!-- 搜索框 --> <!-- 搜索框 -->
<div class="relative flex items-center w-[360px]"> <!-- <div class="relative flex items-center w-[360px]">
<input <input
v-model="searchQuery" v-model="searchQuery"
type="text" type="text"
@ -122,7 +122,7 @@ function handleShowMessage() {
</svg> </svg>
<span class="text-sm font-bold">搜索</span> <span class="text-sm font-bold">搜索</span>
</button> </button>
</div> </div> -->
<!-- 通知铃铛 --> <!-- 通知铃铛 -->
<button class="relative p-2 hover:bg-gray-50 rounded-lg" @click="handleShowMessage"> <button class="relative p-2 hover:bg-gray-50 rounded-lg" @click="handleShowMessage">

View File

@ -1,5 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { import {
CalendarCheck,
ThumbsUp, ThumbsUp,
} from 'lucide-vue-next' } from 'lucide-vue-next'
import { watch } from 'vue' import { watch } from 'vue'
@ -217,38 +218,38 @@ async function handleFocus(type: string, item: any) {
} }
// //
function handleMessage(item: any) { // function handleMessage(item: any) {
if (!item.isShowInput) { // if (!item.isShowInput) {
item.word = '' // item.word = ''
} // }
item.isShowInput = !item.isShowInput // item.isShowInput = !item.isShowInput
} // }
// //
async function handleDel(type: string, item: any) { // async function handleDel(type: string, item: any) {
const params = {} // const params = {}
if (type === 'parent') { // if (type === 'parent') {
params.publishId = item.item.id // params.publishId = item.item.id
params.communityId = item.item.communityId // params.communityId = item.item.communityId
} // }
else { // else {
const { id, communityId, tenantId } = item.sub // const { id, communityId, tenantId } = item.sub
params.id = id // params.id = id
params.communityId = communityId // params.communityId = communityId
params.tenantId = tenantId // params.tenantId = tenantId
params.publishId = item.item.id // params.publishId = item.item.id
} // }
try { // try {
const url = type === 'sub' ? '/publishComment/delete' : '/publish/remove' // const url = type === 'sub' ? '/publishComment/delete' : '/publish/remove'
const res = await request.post(url, params) // const res = await request.post(url, params)
if (res.code === 200) { // if (res.code === 200) {
message.success('删除成功!') // message.success('')
getCommentList() // getCommentList()
} // }
} // }
catch (error) { // catch (error) {
console.log(error) // console.log(error)
} // }
} // }
// //
async function handlePublish() { async function handlePublish() {
@ -271,6 +272,26 @@ async function handlePublish() {
console.log(error) console.log(error)
} }
} }
//
async function handleAccept(item: any, ele: any) {
const params = {
commentId: ele.id,
tenantId: props.publishListParams.tenantId,
communityId: props.publishListParams.communityId,
questionId: item.id,
}
try {
const res = await request.post('questionComment/adopt', params)
if (res.code === 200) {
message.success('采纳成功!')
getCommentList()
}
}
catch (error) {
console.log(error)
}
}
</script> </script>
<template> <template>
@ -346,7 +367,7 @@ async function handlePublish() {
</div> --> </div> -->
</div> </div>
<div v-if="item.questionUrl" class="flex flex-wrap gap-2"> <div v-if="item.questionUrl" class="flex flex-wrap gap-2">
<img v-for="(ele, index) in item.questionUrl.split(',')" :key="index" class="w-16 h-16 rounded-md" :src="ele"> <img v-for="(ele, subIndex) in item.questionUrl.split(',')" :key="subIndex" class="w-16 h-16 rounded-md" :src="ele">
</div> </div>
<!-- 父项评论回复操作 --> <!-- 父项评论回复操作 -->
<!-- <div v-if="item.isShowInput" class="input-wrap" style="margin-top: 10px;"> <!-- <div v-if="item.isShowInput" class="input-wrap" style="margin-top: 10px;">
@ -388,6 +409,13 @@ async function handlePublish() {
</div> </div>
<div class="star-wrap"> <div class="star-wrap">
<span class="time">{{ ele.createTime }}</span> <span class="time">{{ ele.createTime }}</span>
<div v-if="ele.isAccept === 0 && item.status === 0 && userStore?.userInfo?.userId === Number(props.publishListParams.tenantId) && ele.userId !== userStore?.userInfo?.userId" class="cursor-pointer m-r16 text-xs flex items-center text-[#3f7ef7] bg-[#ecf1fc] rounded-lg px-2 py-1" @click="handleAccept(item, ele)">
<CalendarCheck size="16" fill="currentColor" color="#fff" class="mr-1" />
<span>采纳</span>
</div>
<div v-if="ele.isAccept === 1" class="text-xs flex items-center text-[#3f7ef7] bg-[#ecf1fc] rounded-lg px-2 py-1">
<span>已采纳</span>
</div>
<!-- <div class="star-operator"> <!-- <div class="star-operator">
<div class="icon-wrap"> <div class="icon-wrap">
<ThumbsUp size="16" class="mr-1" :color="ele.isLike !== 0 ? '#ff0000' : '#000000'" @click="handleFocus('sub', { sub: ele, item })" /> <ThumbsUp size="16" class="mr-1" :color="ele.isLike !== 0 ? '#ff0000' : '#000000'" @click="handleFocus('sub', { sub: ele, item })" />

View File

@ -0,0 +1,134 @@
<script setup lang="ts">
//
import { commonApi } from '@/api/common'
import { Close } from '@vicons/ionicons5'
import {
EllipsisVertical,
FileChartColumn,
Star,
ThumbsUp,
} from 'lucide-vue-next'
interface PublishListParams {
communityId: string | number
tenantId: string | number
publishId: string | number
[key: string]: any
}
const props = defineProps<{
publishListParams: PublishListParams
modelValue: boolean
}>()
const emit = defineEmits<{
(e: 'update:modelValue', value: boolean): void
}>()
const message = useMessage()
const reportTypeText = ref('')
const reportType = ref('')
const reportList = ref([])
async function getDictType() {
try {
const res = await commonApi.dictType({ type: 'community_report' })
if (res.code === 200) {
reportList.value = res.data
}
}
catch (error) {
console.error(error)
}
}
getDictType()
function handleChange(item: any) {
reportType.value = item.dictValue
if (item.dictValue !== '6') {
reportTypeText.value = ''
}
}
async function onReport() {
if (reportType.value !== undefined) {
const params = {
communityId: props.publishListParams.communityId,
content: reportTypeText.value,
reportType: reportType.value,
publishId: props.publishListParams.publishId,
tenantId: props.publishListParams.tenantId,
}
const res = await request.post('/report/addReport', params)
if (res.code === 200) {
message.success('举报成功!')
emit('update:modelValue', false)
}
}
}
function closeReport() {
emit('update:modelValue', false)
}
</script>
<template>
<div>
<n-modal
:show="modelValue"
:preset="null"
:mask-closable="false"
transform-origin="center"
class="custom-modal"
@update:show="(value) => emit('update:modelValue', value)"
>
<div class="bg-white rounded-xl p-4">
<div class="flex items-center justify-between">
<div class="text-xl">
举报
</div>
<div>
<n-icon size="20" class="mr-2 cursor-pointer" @click="closeReport">
<Close />
</n-icon>
</div>
</div>
<div class="flex flex-col p-4">
<n-radio
v-for="(item, index) in reportList"
:key="index"
class="m-4 text-[#fff000]"
size="large"
:checked="reportType === item.dictValue"
value="Definitely Maybe"
name="basic-demo"
@change="handleChange(item)"
>
{{ item.dictLabel }}
</n-radio>
<n-input
v-if="reportType !== undefined && reportType === '6'"
v-model:value="reportTypeText"
placeholder="点击输入"
type="textarea"
:autosize="{
minRows: 5,
maxRows: 10,
}"
/>
<div
class="mt-4 w-[100%] h-10 flex rounded-lg text-white items-center justify-center cursor-pointer"
:class="[
reportType !== undefined ? 'bg-[#4c79ee]' : 'bg-[#cccccc]',
]"
@click="onReport"
>
确认
</div>
</div>
</div>
</n-modal>
</div>
</template>

View File

@ -170,7 +170,7 @@ async function handlePictureChange(event: Event) {
class="w-[125px] h-[125px] rounded" class="w-[125px] h-[125px] rounded"
> >
<n-icon color="#fff" class="absolute top-1 right-1 p-1 z-40 cursor-pointer w-6 h-6"> <n-icon color="#fff" class="absolute top-1 right-1 p-1 z-40 cursor-pointer w-6 h-6">
<CloseOutline class="text-[20px]" size="20" @click="questionUrlList.splice(index, 1)" /> <CloseOutline class="text-[20px]" size="20" @click="imageUrl.splice(index, 1)" />
</n-icon> </n-icon>
</div> </div>
</div> </div>

View File

@ -23,7 +23,7 @@ const formData = ref({
type: 0, // 01 type: 0, // 01
amount: 10, // amount: 10, //
content: '', // content: '', //
isAnonymous: 0, // 1 0 // isAnonymous: 0, // 1 0
questionUrl: '', // questionUrl: '', //
}) })
@ -72,7 +72,7 @@ async function handlePublish() {
type: 0, type: 0,
amount: undefined, amount: undefined,
content: '', content: '',
isAnonymous: 0, // isAnonymous: 0,
questionUrl: '', questionUrl: '',
} }
fileList.value = [] fileList.value = []
@ -180,9 +180,9 @@ async function handlePictureChange(event: Event) {
</n-radio> </n-radio>
</n-radio-group> </n-radio-group>
<n-checkbox v-model:checked="formData.isAnonymous" unchecked-value="0" checked-value="1"> <!-- <n-checkbox v-model:checked="formData.isAnonymous" unchecked-value="0" checked-value="1">
匿名提问 匿名提问
</n-checkbox> </n-checkbox> -->
<n-button <n-button
type="primary" type="primary"

View File

@ -1,106 +1,114 @@
<template>
<n-modal
v-model:show="isVisibleReport"
:preset="null"
:mask-closable="false"
transform-origin="center"
class="custom-modal"
>
<div class="bg-white rounded-xl p-4">
<div class="flex items-center justify-between">
<div class="text-xl">举报</div>
<div>
<n-icon size="20" class="mr-2 cursor-pointer" @click="closeReport">
<Close />
</n-icon>
</div>
</div>
<div class="flex flex-col">
<n-radio
class="m-4 text-[#fff000]"
size="large"
v-for="(item, index) in reportList"
:key="index"
:checked="reportParams.reportId === item.dictValue"
value="Definitely Maybe"
name="basic-demo"
@change="handleChange(item)"
>
{{ item.dictLabel }}
</n-radio>
<n-input
v-if="reportParams.reportId !== undefined && reportParams.reportId === '5'"
v-model:value="reportParams.text"
placeholder="点击输入"
type="textarea"
:autosize="{
minRows: 5,
maxRows: 10,
}"
/>
<div
@click="onReport"
class="mt-4 w-[100%] h-10 flex rounded-lg text-white items-center justify-center cursor-pointer"
:class="[
reportParams.reportId !== undefined
? 'bg-[#4c79ee]'
: 'bg-[#cccccc]',
]"
>
确认
</div>
</div>
</div>
</n-modal>
</template>
<script setup lang="ts"> <script setup lang="ts">
import { commonApi } from "@/api/common"; import { commonApi } from '@/api/common'
import { Close } from "@vicons/ionicons5"; import { Close } from '@vicons/ionicons5'
const message = useMessage()
// //
const isVisibleReport = ref(true); const isVisibleReport = ref(true)
const reportParams = ref({ const reportParams = ref({
reportId: undefined, reportId: undefined,
text: "", text: '',
type:1 type: 1,
}); })
const reportList = ref([]); const reportList = ref([])
async function getDictType() { async function getDictType() {
try { try {
const res = await commonApi.dictType({ type: "report_type" }); const res = await commonApi.dictType({ type: 'report_type' })
if (res.code === 200) { if (res.code === 200) {
reportList.value = res.data; reportList.value = res.data
} }
} catch (error) { }
console.log(error); catch (error) {
console.log(error)
} }
} }
getDictType(); getDictType()
function handleChange(item: any) { function handleChange(item: any) {
reportParams.value.reportId = item.dictValue; reportParams.value.reportId = item.dictValue
if (item.dictValue !== "5") { if (item.dictValue !== '5') {
reportParams.value.text = ""; reportParams.value.text = ''
} }
console.log("object", reportParams.value); console.log('object', reportParams.value)
} }
function closeReport() { function closeReport() {
isVisibleReport.value = false; isVisibleReport.value = false
} }
async function onReport(){ async function onReport() {
if( reportParams.value.reportId !== undefined){ if (reportParams.value.reportId !== undefined) {
reportParams.value.productId = detailsInfo.value.id reportParams.value.productId = detailsInfo.value.id
const res = await request.post('/report/addReport', reportParams.value) const res = await request.post('/report/addReport', reportParams.value)
if (res.code === 200) {
isVisibleReport.value = false
message.success('举报成功')
}
} }
} }
</script> </script>
<template>
<n-modal
v-model:show="isVisibleReport"
:preset="null"
:mask-closable="false"
transform-origin="center"
class="custom-modal"
>
<div class="bg-white rounded-xl p-4">
<div class="flex items-center justify-between">
<div class="text-xl">
举报
</div>
<div>
<n-icon size="20" class="mr-2 cursor-pointer" @click="closeReport">
<Close />
</n-icon>
</div>
</div>
<div class="flex flex-col">
<n-radio
v-for="(item, index) in reportList"
:key="index"
class="m-4 text-[#fff000]"
size="large"
:checked="reportParams.reportId === item.dictValue"
value="Definitely Maybe"
name="basic-demo"
@change="handleChange(item)"
>
{{ item.dictLabel }}
</n-radio>
<n-input
v-if="reportParams.reportId !== undefined && reportParams.reportId === '5'"
v-model:value="reportParams.text"
placeholder="点击输入"
type="textarea"
:autosize="{
minRows: 5,
maxRows: 10,
}"
/>
<div
class="mt-4 w-[100%] h-10 flex rounded-lg text-white items-center justify-center cursor-pointer"
:class="[
reportParams.reportId !== undefined
? 'bg-[#4c79ee]'
: 'bg-[#cccccc]',
]"
@click="onReport"
>
确认
</div>
</div>
</div>
</n-modal>
</template>
<style scoped> <style scoped>
.container{ .container {
/* position: fixed; /* position: fixed;
top: 0; top: 0;
left: 0; left: 0;
width: 100vw; width: 100vw;
@ -108,4 +116,4 @@ async function onReport(){
opacity: 0.4; opacity: 0.4;
background: #000; */ background: #000; */
} }
</style> </style>

View File

@ -36,14 +36,14 @@ const showEditPlanet = ref(false)
const menuItems = computed(() => { const menuItems = computed(() => {
const items = [ const items = [
{ // {
label: '分享星球', // label: '',
action: () => { // action: () => {
const url = window.location.href // const url = window.location.href
navigator.clipboard.writeText(url) // navigator.clipboard.writeText(url)
message.success('链接已复制到剪贴板') // message.success('')
}, // },
}, // },
{ {
label: '退出星球', label: '退出星球',
action: async () => { action: async () => {
@ -109,18 +109,29 @@ function handleSuccess() {
} }
function goDetail(item: any) { function goDetail(item: any) {
const params = {
communityId: item.id,
tenantId: item.tenantId,
id: item.id,
userId: item.userId,
}
if (item.isJoin === 0) { if (item.isJoin === 0) {
router.push({ router.push({
path: '/public-planet-detail', path: '/public-planet-detail',
state: { state: params,
communityId: item.id,
tenantId: item.tenantId,
userId: item.userId,
},
}) })
} }
else { else {
router.push(`/planet-detail?communityId=${item.id}&tenantId=${item.tenantId}`) router.push({
path: '/planet-detail',
state: {
communityId: item.id,
tenantId: item.tenantId,
publishId: item.id,
userId: item.userId,
},
})
// router.push(`/planet-detail?communityId=${item.id}&tenantId=${item.tenantId}&publishId=${item.id}&userId=${item.userId}`)
} }
} }
</script> </script>
@ -130,7 +141,7 @@ function goDetail(item: any) {
<div class="bg-white rounded-lg shadow-sm flex p-4 cursor-pointer hover:shadow-[0_4px_14px_0_rgba(0,0,0,0.1)]" @click="goDetail(item)"> <div class="bg-white rounded-lg shadow-sm flex p-4 cursor-pointer hover:shadow-[0_4px_14px_0_rgba(0,0,0,0.1)]" @click="goDetail(item)">
<div class="w-[161px] h-[161px] relative rounded-lg"> <div class="w-[161px] h-[161px] relative rounded-lg">
<img class="w-full h-full object-cover rounded-lg" :src="item.imageUrl" alt=""> <img class="w-full h-full object-cover rounded-lg" :src="item.imageUrl" alt="">
<span class="absolute bottom-2 left-2 text-white text-xs">{{ item.publishNum || 0 }}人已经加入</span> <span class="absolute bottom-2 left-2 text-white text-xs">{{ item.joinNum || 0 }}人已经加入</span>
</div> </div>
<div class="flex flex-col gap-2 px-4 flex-1 justify-between"> <div class="flex flex-col gap-2 px-4 flex-1 justify-between">
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
@ -154,12 +165,12 @@ function goDetail(item: any) {
@mouseleave="hideMenu" @mouseleave="hideMenu"
> >
<div <div
v-for="item in menuItems" v-for="subItem in menuItems"
:key="item.label" :key="subItem.label"
class="px-4 py-2 text-sm hover:bg-gray-100 cursor-pointer" class="px-4 py-2 text-sm hover:bg-gray-100 cursor-pointer"
@click="item.action" @click="subItem.action"
> >
{{ item.label }} {{ subItem.label }}
</div> </div>
</div> </div>
</div> </div>
@ -221,7 +232,7 @@ function goDetail(item: any) {
:mask-closable="false" :mask-closable="false"
preset="dialog" preset="dialog"
title="提示!" title="提示!"
content="退出后将无法查看/操作该星球的内容,是否确认退出该星球" :content="props.item.joinNum === 1 ? '退出后该星球的内容将会被删除,若你是最后一个成员,退出后星球将被解散,是否确认退出该星球' : '退出后将无法查看/操作该星球的内容,是否确认退出该星球'"
negative-text="取消" negative-text="取消"
positive-text="确认退出" positive-text="确认退出"
@negative-click="isDelete = false" @negative-click="isDelete = false"

View File

@ -140,6 +140,9 @@ onMounted(() => {
<div class="w-[200px]"> <div class="w-[200px]">
消费金币值 消费金币值
</div> </div>
<div class="w-[200px]">
金币余额
</div>
</div> </div>
<n-infinite-scroll <n-infinite-scroll
style="height: calc(100vh - 300px);" style="height: calc(100vh - 300px);"
@ -148,7 +151,7 @@ onMounted(() => {
> >
<div v-for="item in walletRecordList" :key="item" class="mc-table flex w-full"> <div v-for="item in walletRecordList" :key="item" class="mc-table flex w-full">
<div class="w-[250px]"> <div class="w-[250px]">
{{ item.consumeDate }} {{ item.createTime }}
</div> </div>
<div class="w-[250px]"> <div class="w-[250px]">
{{ item.productName }} {{ item.productName }}
@ -156,8 +159,11 @@ onMounted(() => {
<div class="flex-1"> <div class="flex-1">
- -
</div> </div>
<div class="w-[200px]" :class="{ 'text-[#FFD700]': item.amount > 0 }">
{{ item.amount > 0 ? `+${item.amount}` : item.amount }}
</div>
<div class="w-[200px]"> <div class="w-[200px]">
{{ item.amount }} {{ item.wallet }}
</div> </div>
</div> </div>
</n-infinite-scroll> </n-infinite-scroll>

View File

@ -133,7 +133,7 @@ function handleCreateSuccess() {
</div> </div>
</div> </div>
</div> </div>
<div v-else-if="dataList.length > 0" class="grid grid-cols-3 gap-2"> <div class="grid grid-cols-3 gap-2">
<div v-if="communityTag === 'myCreate'" class="bg-black rounded-lg flex flex-col justify-center items-center p-4 hover:shadow-[0_4px_14px_0_rgba(0,0,0,0.1)] transition-all duration-300 cursor-pointer" @click="showCreateModal"> <div v-if="communityTag === 'myCreate'" class="bg-black rounded-lg flex flex-col justify-center items-center p-4 hover:shadow-[0_4px_14px_0_rgba(0,0,0,0.1)] transition-all duration-300 cursor-pointer" @click="showCreateModal">
<div class="text-white text-xl"> <div class="text-white text-xl">
魔创星球 魔创星球
@ -145,9 +145,11 @@ function handleCreateSuccess() {
创建星球 创建星球
</div> </div>
</div> </div>
<PlanetItem v-for="(item, index) in dataList" :key="index" :item="item" :type="communityTag" @refresh="refresh" /> <template v-if="dataList.length > 0">
<PlanetItem v-for="(item, index) in dataList" :key="index" :item="item" :type="communityTag" @refresh="refresh" />
</template>
</div> </div>
<div v-if="dataList.length === 0 && listFinish" class="flex flex-col items-center justify-center py-12"> <div v-if="dataList.length === 0 && listFinish && communityTag === 'myJoin'" class="flex flex-col items-center justify-center py-12">
<div class="w-48 h-48 mb-4 flex items-center justify-center"> <div class="w-48 h-48 mb-4 flex items-center justify-center">
<div class="relative"> <div class="relative">
<div class="w-32 h-32 rounded-full border-4 border-gray-200" /> <div class="w-32 h-32 rounded-full border-4 border-gray-200" />

View File

@ -6,7 +6,6 @@ import { NConfigProvider, NImage, NMessageProvider } from 'naive-ui'
import { onMounted, ref } from 'vue' import { onMounted, ref } from 'vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
const message = useMessage()
definePageMeta({ definePageMeta({
layout: 'planet', layout: 'planet',
}) })
@ -29,11 +28,13 @@ const typeList = ref([
value: 999, value: 999,
}, },
]) ])
const showPublishModal = ref(false) const showPublishModal = ref(false)
const publishListParams = ref({ const publishListParams = ref({
communityId: route.query.communityId, communityId: route.query.communityId,
tenantId: route.query.tenantId, tenantId: route.query.tenantId,
publishId: route.query.id,
type: null, type: null,
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
@ -45,28 +46,67 @@ const questionParams = ref({
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
}) })
const questionList = ref([]) // const questionList = ref([])
const isShow = ref('publish') const isShow = ref('publish')
async function handleTypeChange(type: number | null) { async function handleTypeChange(type: number | null) {
publishListParams.value.type = type publishListParams.value.type = type
questionParams.value.pageNum = 1 questionParams.value.pageNum = 1
if (type === 999) { // if (type === 999) { //
isShow.value = 'question' isShow.value = 'question'
try { // try {
const res = await request.post('/question/list', questionParams.value) // const res = await request.post('/question/list', questionParams.value)
if (res.code === 200) { // if (res.code === 200) {
questionList.value = res.rows // questionList.value = res.rows
} // }
} // }
catch (error) { // catch (error) {
console.error(error) // console.error(error)
} // }
} }
else { else {
publishListParams.value.pageNum = 1 publishListParams.value.pageNum = 1
isShow.value = 'publish' isShow.value = 'publish'
} }
} }
const PublishComponentKey = ref(0)
function closePublishModal() {
showPublishModal.value = false
nextTick(() => {
PublishComponentKey.value++
})
}
onMounted(() => {
const state = history.state
if (state && state.communityId && state.tenantId) {
publishListParams.value = {
communityId: state.communityId,
tenantId: state.tenantId,
publishId: state.id,
type: null,
pageNum: 1,
pageSize: 10,
}
questionParams.value = {
communityId: state.communityId,
tenantId: state.tenantId,
pageNum: 1,
pageSize: 10,
}
}
else {
// state退 URL
publishListParams.value = {
communityId: route.query.communityId as string,
tenantId: route.query.tenantId as string,
publishId: route.query.id as string,
type: null,
pageNum: 1,
pageSize: 10,
}
}
})
</script> </script>
<template> <template>
@ -114,6 +154,7 @@ async function handleTypeChange(type: number | null) {
<NConfigProvider> <NConfigProvider>
<NMessageProvider> <NMessageProvider>
<PlanetComment <PlanetComment
:key="PublishComponentKey"
:publish-list-params="publishListParams" :publish-list-params="publishListParams"
/> />
</NMessageProvider> </NMessageProvider>
@ -123,6 +164,7 @@ async function handleTypeChange(type: number | null) {
<NConfigProvider> <NConfigProvider>
<NMessageProvider> <NMessageProvider>
<PlanetQuestionComment <PlanetQuestionComment
:key="PublishComponentKey"
:publish-list-params="questionParams" :publish-list-params="questionParams"
/> />
</NMessageProvider> </NMessageProvider>
@ -130,7 +172,7 @@ async function handleTypeChange(type: number | null) {
</div> </div>
</div> </div>
<div class="w-[300px]"> <div class="w-[300px]">
<PlanetBaseInfo :community-id="route.query.communityId" :tenant-id="route.query.tenantId" /> <PlanetBaseInfo v-if="publishListParams.communityId && publishListParams.tenantId" :community-id="publishListParams.communityId" :tenant-id="publishListParams.tenantId" />
</div> </div>
<n-modal <n-modal
v-model:show="showPublishModal" v-model:show="showPublishModal"
@ -140,9 +182,10 @@ async function handleTypeChange(type: number | null) {
class="rounded-lg" class="rounded-lg"
> >
<PublishContent <PublishContent
:community-id="route.query.communityId" v-if="publishListParams.communityId && publishListParams.tenantId"
:tenant-id="route.query.tenantId" :community-id="publishListParams.communityId"
@success="showPublishModal = false" :tenant-id="publishListParams.tenantId"
@success="closePublishModal"
/> />
</n-modal> </n-modal>
</div> </div>

View File

@ -210,9 +210,9 @@ function copyToClipboard(text: string) {
<div class="min-h-screen bg-[#F7F8FA] px-10 py-6 flex gap-4"> <div class="min-h-screen bg-[#F7F8FA] px-10 py-6 flex gap-4">
<div class="bg-white rounded-lg flex-1"> <div class="bg-white rounded-lg flex-1">
<div class="flex justify-between items-center m-3 text-sm"> <div class="flex justify-between items-center m-3 text-sm">
<div class="bg-[#328afe] text-white px-3 py-1 rounded-sm cursor-pointer"> <!-- <div class="bg-[#328afe] text-white px-3 py-1 rounded-sm cursor-pointer">
分享星球 分享星球
</div> </div> -->
<div class="relative flex items-center w-[300px]"> <div class="relative flex items-center w-[300px]">
<input <input
v-model="params.searchContent" v-model="params.searchContent"

View File

@ -1,5 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import planetBg from '@/assets/img/planetBg.png' import planetBg from '@/assets/img/planetBg.png'
import { X } from 'lucide-vue-next'
import { NConfigProvider, NImage, NMessageProvider } from 'naive-ui' import { NConfigProvider, NImage, NMessageProvider } from 'naive-ui'
import { onMounted, ref, watch } from 'vue' import { onMounted, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router' import { useRoute, useRouter } from 'vue-router'
@ -14,6 +15,7 @@ const params = ref({
tenantId: '', tenantId: '',
userId: '', userId: '',
}) })
// const goldPaymentRef = ref(null)
onMounted(() => { onMounted(() => {
const state = history.state const state = history.state
@ -84,8 +86,37 @@ async function getAttention() {
console.log(err) console.log(err)
} }
} }
// const isShowGoldPayment = ref(false)
const paymentModal = ref(false)
//
const showConfirmModal = ref(false)
function onPositiveClick() {
showConfirmModal.value = false
paymentModal.value = true
getQrCode()
}
function onNegativeClick() {
showConfirmModal.value = false
}
const formRef = ref(null)
const paymentParams = ref({
amount: 10,
type: 'wallet',
})
const amount = ref(10)
const qrUrl = ref('')
//
const paymentStatus = ref(1)
const isJoinModal = ref(false)
async function handleJoin() { async function handleJoin() {
isJoinModal.value = true
}
async function onPositiveJoinClick() {
try { try {
const data = { const data = {
communityId: params.value.communityId, communityId: params.value.communityId,
@ -93,16 +124,90 @@ async function handleJoin() {
} }
const res = await request.post(`/community/join`, data) const res = await request.post(`/community/join`, data)
if (res.code === 200) { if (res.code === 200) {
isJoinModal.value = false
message.success('加入成功') message.success('加入成功')
setTimeout(() => { setTimeout(() => {
router.push(`/planet-detail?communityId=${params.value.communityId}&tenantId=${params.value.tenantId}`) router.push(`/planet-detail?communityId=${params.value.communityId}&tenantId=${params.value.tenantId}`)
}, 1000) }, 1000)
} }
} }
catch (err: any) {
if (err.code === 12202 && err.msg === '钱包余额不足,请充值') {
showConfirmModal.value = true
}
}
}
function onNegativeJoinClick() {
isJoinModal.value = false
}
function closePayment() {
paymentModal.value = false
}
let pollingTimer: ReturnType<typeof setInterval> | undefined
async function getQrCode() {
try {
paymentParams.value.amount = amount.value
const res = await request.post(`/ali/pay/doPay`, paymentParams.value)
if (res.code === 200) {
paymentStatus.value = 1
qrUrl.value = res.data.url
pollingTimer && clearTimeout(pollingTimer)
pollingTimer = setInterval(async () => {
try {
const res2 = await request.get(`/order/queryTradeStatus?outTradeNo=${res.data.orderNo}`)
if (res2.data === 2) { // 1 2 4
paymentStatus.value = 2
clearTimeout(pollingTimer)
paymentModal.value = false
message.success('支付成功!')
}
else if (res2.data === 4) {
paymentStatus.value = 4
clearTimeout(pollingTimer)
}
}
catch (err) {
console.log('object', err)
}
}, 2000)
}
}
catch (err) { catch (err) {
console.log(err) console.log(err)
} }
} }
//
// function paymentSuccess() {
// // getIsMember();
// if (import.meta.client) {
// window.location.reload()
// }
// }
// function closeGoldPayment() {
// isShowGoldPayment.value = false
// if (goldPaymentRef.value) {
// goldPaymentRef.value.isVisible = false
// }
// }
// //
// const isMember = ref(false)
// async function getIsMember() {
// try {
// const res = await request.get('/member/isMember')
// if (res.code === 200) {
// isMember.value = res.data
// }
// }
// catch (err) {
// console.log(err)
// }
// }
// getIsMember()
// //
// async function getAttention() { // async function getAttention() {
// try { // try {
@ -159,7 +264,7 @@ async function handleJoin() {
<div class="flex justify-between p-2 rounded bg-white items-center"> <div class="flex justify-between p-2 rounded bg-white items-center">
<div class="flex items-center gap-2 text-[#fc4141]"> <div class="flex items-center gap-2 text-[#fc4141]">
<span class="font-bold text-[28px]">{{ communityDetail.price ? communityDetail.price : '免费' }}</span> <span v-if="communityDetail.price" class="text-[16px]"></span> <span class="font-bold text-[28px]">{{ communityDetail.price ? communityDetail.price : '免费' }}</span> <span v-if="communityDetail.price" class="text-[16px]"></span>
</div> </div>
<div <div
class="text-white text-[14px] flex items-center justify-center cursor-pointer w-[128px] h-[40px] bg-[linear-gradient(207deg,#3BEDFF_0%,#328AFE_100%)] rounded-lg" class="text-white text-[14px] flex items-center justify-center cursor-pointer w-[128px] h-[40px] bg-[linear-gradient(207deg,#3BEDFF_0%,#328AFE_100%)] rounded-lg"
@ -177,7 +282,7 @@ async function handleJoin() {
</div> </div>
<div class="flex gap-4 bg-[#F9FBFF] rounded-lg p-2"> <div class="flex gap-4 bg-[#F9FBFF] rounded-lg p-2">
<div class="w-[80px] h-[80px] rounded"> <div class="w-[80px] h-[80px] rounded">
<img class="rounded-full" :src="userInfo.avatar" alt="星球概况"> <img class="rounded-full w-full h-full object-cover" :src="userInfo.avatar" alt="星球概况">
</div> </div>
<div class="flex flex-col justify-between py-2"> <div class="flex flex-col justify-between py-2">
<div class="flex gap-4"> <div class="flex gap-4">
@ -211,5 +316,113 @@ async function handleJoin() {
</div> </div>
</div> </div>
</div> </div>
<!-- <NConfigProvider>
<NMessageProvider>
<GoldPayment
v-if="isShowGoldPayment"
ref="goldPaymentRef"
:is-member="isMember"
@payment-success="paymentSuccess"
@close-payment="closeGoldPayment"
/>
</NMessageProvider>
</NConfigProvider> -->
<n-modal
v-model:show="showConfirmModal"
:mask-closable="false"
preset="dialog"
title="确认"
content="余额不足,是否确认充值?"
positive-text="确认"
negative-text="算了"
@positive-click="onPositiveClick"
@negative-click="onNegativeClick"
/>
<n-modal
v-model:show="paymentModal"
:preset="null"
:mask-closable="false"
transform-origin="center"
class="custom-modal"
>
<div class="bg-white rounded-xl w-200 p-4">
<X class="absolute top-1 right-1 cursor-pointer" @click="closePayment" />
<div class="mb-4 mt-6 flex">
<n-form
ref="formRef"
:label-width="80"
:model="paymentParams"
size="large"
label-placement="left"
style="width: 240px"
>
<n-form-item label="输入金币" path="modelProduct.modelName">
<n-input v-model:value="amount" type="number" placeholder="输入积分" />
</n-form-item>
</n-form>
<n-button type="primary" class="mt-1 ml-2" @click="getQrCode">
确定
</n-button>
</div>
<div class="flex justify-center items-center my-4">
<div class="w-30 h-30 flex justify-center items-center relative">
<n-qr-code :value="qrUrl" :size="90" style="padding: 0;" />
<div v-if="paymentStatus === 4" class="absolute top-0 left-0 w-full h-full flex cursor-pointer flex-col justify-center items-center bg-opacity-50 bg-black text-white" @click="getQrCode">
请点击刷新<RotateCcw />
</div>
</div>
<div class="flex justify-center ml-2 flex-col pb-[14px]">
<div class="flex items-baseline">
<div class="text-[#222] font-medium mr-1">
支付
</div>
<div class="text-[#814600] mr-1">
<span class="text-[16px] mr-1">¥</span>
<span class="text-[40px]">{{ paymentParams.amount }}</span>
</div>
</div>
<div class="flex items-center mb-1">
<img src="@/assets/img/alipay.png" class="mr-1"> 请扫码完成支付
</div>
<div class="text-[12px]">
<span class="text-[#999]">
开通即代表同意
</span>
<span class="text-[#814600]">
魔创未来会员协议
</span>
</div>
</div>
</div>
</div>
</n-modal>
<!-- 是否加入弹框 -->
<n-modal
v-model:show="isJoinModal"
:mask-closable="false"
preset="dialog"
title="确认"
content="是否确认加入星球?"
positive-text="确认"
negative-text="算了"
@positive-click="onPositiveJoinClick"
@negative-click="onNegativeJoinClick"
/>
</div> </div>
</template> </template>
<style lang="scss" scoped>
.member-item {
display: flex;
justify-content: center;
align-items: center;
width: 16.66%;
height: 40px;
border: 1px solid #f0f0f0;
font-size: 12px;
font-weight: 400;
margin-right: -1px;
margin-bottom: -1px;
}
</style>

View File

@ -58,9 +58,10 @@ export default defineNuxtConfig({
}, },
build: { build: {
transpile: import.meta.env.NODE_ENV === 'production' transpile: import.meta.env.NODE_ENV === 'production'
? ['naive-ui', 'vueuc', '@css-render/vue3-ssr', '@juggle/resize-observer'] ? ['naive-ui', 'vueuc', '@css-render/vue3-ssr', '@juggle/resize-observer']
: ['@juggle/resize-observer'], : ['@juggle/resize-observer', 'naive-ui', 'vueuc'],
}, },
routeRules: { routeRules: {

File diff suppressed because it is too large Load Diff