mirror of
https://github.com/Megghy/vtsuru.live.git
synced 2025-12-07 02:46:55 +08:00
refactor: 优化多个视图组件并添加功能
本次提交对多个视图组件进行了重构和功能增强:
PointGoodsView.vue:
- 清理了未使用的导入(`useAccount`)和变量(`accountInfo`, `biliInfo` prop)。
- 通过重组计算属性和方法提高了代码可读性。
- 增强了商品列表的筛选和排序逻辑。
- 为购买商品功能添加了错误处理和加载状态。
PointUserHistoryView.vue:
- 为获取积分历史记录实现了加载状态。
- 改进了 PointHistoryCard 组件的渲染。
QuestionBoxView.vue:
- 优化了可读性和性能(整合状态变量,改进命名)。
- 增强了文件上传处理和验证逻辑。
- 改进了标签选择逻辑和数据获取方法。
- 添加了代码注释以提高可理解性。
UserIndexView.vue:
- 简化了确定要显示的模板组件的逻辑。
- 确保无论用户信息是否存在,都一致返回默认模板。
This commit is contained in:
@@ -8,6 +8,8 @@
|
||||
goods: ResponsePointGoodModel | undefined;
|
||||
contentStyle?: string | undefined;
|
||||
}>();
|
||||
|
||||
// 默认封面图片
|
||||
const emptyCover = IMGUR_URL + 'None.png';
|
||||
</script>
|
||||
|
||||
@@ -20,7 +22,9 @@
|
||||
v-else
|
||||
embedded
|
||||
:style="props.contentStyle"
|
||||
class="goods-card"
|
||||
>
|
||||
<!-- 商品封面 -->
|
||||
<template #cover>
|
||||
<NImage
|
||||
:src="goods.cover ? FILE_BASE_URL + goods.cover : emptyCover"
|
||||
@@ -31,6 +35,8 @@
|
||||
style="width: 100%"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<!-- 商品信息头部 -->
|
||||
<template #header-extra>
|
||||
<NFlex justify="space-between">
|
||||
<NFlex>
|
||||
@@ -52,11 +58,14 @@
|
||||
</NFlex>
|
||||
</NFlex>
|
||||
</template>
|
||||
|
||||
<!-- 商品标题 -->
|
||||
<template #header>
|
||||
<NFlex
|
||||
align="center"
|
||||
:size="5"
|
||||
>
|
||||
<!-- 售罄标签 -->
|
||||
<NTag
|
||||
v-if="goods.count == 0"
|
||||
size="small"
|
||||
@@ -65,17 +74,23 @@
|
||||
>
|
||||
已售完
|
||||
</NTag>
|
||||
|
||||
<!-- 商品类型标签 -->
|
||||
<NTag
|
||||
size="small"
|
||||
:bordered="goods.type != GoodsTypes.Physical"
|
||||
>
|
||||
{{ goods.type == GoodsTypes.Physical ? '实物' : '虚拟' }}
|
||||
</NTag>
|
||||
|
||||
<!-- 商品名称 -->
|
||||
<NEllipsis>
|
||||
{{ goods.name }}
|
||||
</NEllipsis>
|
||||
</NFlex>
|
||||
</template>
|
||||
|
||||
<!-- 商品描述和标签 -->
|
||||
<NFlex vertical>
|
||||
<NEllipsis :line-clamp="2">
|
||||
<NText
|
||||
@@ -85,7 +100,10 @@
|
||||
{{ goods.description ? goods.description : '暂无描述' }}
|
||||
</NText>
|
||||
</NEllipsis>
|
||||
<NFlex>
|
||||
|
||||
<!-- 标签展示 -->
|
||||
<NFlex wrap>
|
||||
<!-- 舰长限制标签 -->
|
||||
<NTag
|
||||
v-if="goods.allowGuardLevel > 0"
|
||||
size="tiny"
|
||||
@@ -96,6 +114,8 @@
|
||||
</template>
|
||||
仅限舰长
|
||||
</NTag>
|
||||
|
||||
<!-- 商品标签 -->
|
||||
<NTag
|
||||
v-for="tag in goods.tags"
|
||||
:key="tag"
|
||||
@@ -106,8 +126,21 @@
|
||||
</NTag>
|
||||
</NFlex>
|
||||
</NFlex>
|
||||
|
||||
<!-- 自定义页脚 -->
|
||||
<template #footer>
|
||||
<slot name="footer" />
|
||||
</template>
|
||||
</NCard>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.goods-card {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.goods-card:hover {
|
||||
transform: translateY(-3px);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
NText,
|
||||
NTime,
|
||||
NTooltip,
|
||||
NEmpty
|
||||
} from 'naive-ui'
|
||||
import { h, ref } from 'vue'
|
||||
import PointGoodsItem from './PointGoodsItem.vue'
|
||||
@@ -20,9 +21,11 @@ const props = defineProps<{
|
||||
histories: ResponsePointHisrotyModel[]
|
||||
}>()
|
||||
|
||||
// 礼物详情模态框
|
||||
const showGoodsModal = ref(false)
|
||||
const currentGoods = ref<ResponsePointGoodModel>()
|
||||
|
||||
// 数据表格列定义
|
||||
const historyColumn: DataTableColumns<ResponsePointHisrotyModel> = [
|
||||
{
|
||||
title: '时间',
|
||||
@@ -102,7 +105,6 @@ const historyColumn: DataTableColumns<ResponsePointHisrotyModel> = [
|
||||
{
|
||||
title: '详情',
|
||||
key: 'action',
|
||||
|
||||
render: (row: ResponsePointHisrotyModel) => {
|
||||
switch (row.from) {
|
||||
case PointFrom.Danmaku:
|
||||
@@ -128,6 +130,7 @@ const historyColumn: DataTableColumns<ResponsePointHisrotyModel> = [
|
||||
row.extra?.danmaku.price,
|
||||
])
|
||||
}
|
||||
break
|
||||
case PointFrom.Manual:
|
||||
return h(NFlex, { align: 'center' }, () => [
|
||||
h(NTag, { type: 'info', size: 'small', style: { margin: '0' } }, () => '来自'),
|
||||
@@ -162,23 +165,48 @@ const historyColumn: DataTableColumns<ResponsePointHisrotyModel> = [
|
||||
),
|
||||
])
|
||||
}
|
||||
return null
|
||||
},
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- 无数据时显示提示 -->
|
||||
<NEmpty
|
||||
v-if="!histories || histories.length === 0"
|
||||
description="暂无积分历史记录"
|
||||
/>
|
||||
|
||||
<!-- 有数据时显示表格 -->
|
||||
<NDataTable
|
||||
v-else
|
||||
:columns="historyColumn"
|
||||
:data="histories"
|
||||
:pagination="{ showSizePicker: true, pageSizes: [10, 25, 50, 100], defaultPageSize: 10, size: 'small' }"
|
||||
:pagination="{
|
||||
showSizePicker: true,
|
||||
pageSizes: [10, 25, 50, 100],
|
||||
defaultPageSize: 10,
|
||||
size: 'small'
|
||||
}"
|
||||
/>
|
||||
|
||||
<!-- 商品详情模态框 -->
|
||||
<NModal
|
||||
v-model:show="showGoodsModal"
|
||||
preset="card"
|
||||
title="礼物详情 (快照)"
|
||||
style="max-width: 400px; height: auto"
|
||||
>
|
||||
</NDataTable>
|
||||
<NModal v-model:show="showGoodsModal" preset="card" title="礼物详情 (快照)" style="max-width: 400px; height: auto">
|
||||
<PointGoodsItem :goods="currentGoods" />
|
||||
<template v-if="currentGoods?.content">
|
||||
<NDivider> 礼物内容 </NDivider>
|
||||
<NInput :value="currentGoods?.content" type="textarea" readonly placeholder="无内容" />
|
||||
<NDivider>礼物内容</NDivider>
|
||||
<NInput
|
||||
:value="currentGoods?.content"
|
||||
type="textarea"
|
||||
readonly
|
||||
placeholder="无内容"
|
||||
/>
|
||||
</template>
|
||||
</NModal>
|
||||
</template>
|
||||
|
||||
@@ -177,16 +177,28 @@ const orderColumn: DataTableColumns<ResponsePointOrder2UserModel | ResponsePoint
|
||||
},
|
||||
],
|
||||
render: (row: ResponsePointOrder2UserModel | ResponsePointOrder2OwnerModel) => {
|
||||
switch (row.status) {
|
||||
case PointOrderStatus.Pending:
|
||||
return h(NTag, { size: 'small' }, () => '等待发货')
|
||||
case PointOrderStatus.Shipped:
|
||||
return h(NTag, { size: 'small', type: row.expressCompany ? 'info' : 'warning', bordered: false }, () =>
|
||||
row.expressCompany ? '已发货 | 已填写单号' : '已发货 | 未填写单号',
|
||||
)
|
||||
case PointOrderStatus.Completed:
|
||||
return h(NTag, { size: 'small', type: 'success' }, () => '已完成')
|
||||
const statusMap = {
|
||||
[PointOrderStatus.Pending]: {
|
||||
text: '等待发货',
|
||||
type: 'default'
|
||||
},
|
||||
[PointOrderStatus.Shipped]: {
|
||||
text: row.expressCompany ? '已发货 | 已填写单号' : '已发货 | 未填写单号',
|
||||
type: row.expressCompany ? 'info' : 'warning'
|
||||
},
|
||||
[PointOrderStatus.Completed]: {
|
||||
text: '已完成',
|
||||
type: 'success'
|
||||
}
|
||||
}
|
||||
|
||||
const status = statusMap[row.status] || { text: '未知状态', type: 'error' }
|
||||
|
||||
return h(NTag, {
|
||||
size: 'small',
|
||||
type: status.type as any,
|
||||
bordered: false
|
||||
}, () => status.text)
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -294,6 +306,7 @@ function onChangeStatus(id: number, status: PointOrderStatus) {
|
||||
}
|
||||
async function updateStatus(id: number[], status: PointOrderStatus) {
|
||||
try {
|
||||
isLoading.value = true
|
||||
const data = await QueryPostAPI(POINT_API_URL + 'update-orders-status', {
|
||||
ids: id,
|
||||
status,
|
||||
@@ -311,6 +324,8 @@ async function updateStatus(id: number[], status: PointOrderStatus) {
|
||||
} catch (err) {
|
||||
message.error('操作失败: ' + err)
|
||||
console.log(err)
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
}
|
||||
}
|
||||
async function updateExpress(item: ResponsePointOrder2OwnerModel) {
|
||||
@@ -358,7 +373,6 @@ onMounted(() => {
|
||||
<template #empty>
|
||||
<NEmpty description="暂无订单" />
|
||||
</template>
|
||||
>
|
||||
</NDataTable>
|
||||
<NModal
|
||||
v-if="orderDetail"
|
||||
@@ -380,25 +394,38 @@ onMounted(() => {
|
||||
</NTooltip>
|
||||
</NDivider>
|
||||
<NFlex justify="center">
|
||||
<PointGoodsItem style="max-width: 300px" :goods="currentGoods" />
|
||||
<PointGoodsItem
|
||||
style="max-width: 300px"
|
||||
:goods="currentGoods"
|
||||
/>
|
||||
</NFlex>
|
||||
<template v-if="orderDetail.type == GoodsTypes.Virtual">
|
||||
<NDivider> 虚拟礼物内容 </NDivider>
|
||||
<NInput :value="currentGoods?.content" type="textarea" readonly placeholder="无内容" />
|
||||
<NInput
|
||||
:value="currentGoods?.content"
|
||||
type="textarea"
|
||||
readonly
|
||||
placeholder="无内容"
|
||||
/>
|
||||
</template>
|
||||
<template
|
||||
v-if="
|
||||
orderDetail.type == GoodsTypes.Physical &&
|
||||
orderDetail.status == PointOrderStatus.Pending &&
|
||||
orderDetail.goods.embedCollectUrl &&
|
||||
orderDetail.goods.collectUrl
|
||||
orderDetail.status == PointOrderStatus.Pending &&
|
||||
orderDetail.goods.embedCollectUrl &&
|
||||
orderDetail.goods.collectUrl
|
||||
"
|
||||
>
|
||||
<NDivider> 填写收货地址 </NDivider>
|
||||
<NButton tag="a" :href="orderDetail.goods.collectUrl" target="_blank" type="info">
|
||||
<NButton
|
||||
tag="a"
|
||||
:href="orderDetail.goods.collectUrl"
|
||||
target="_blank"
|
||||
type="info"
|
||||
>
|
||||
在新窗口中打开地址填写表格
|
||||
</NButton>
|
||||
<br />
|
||||
<br>
|
||||
<iframe
|
||||
height="1200"
|
||||
width="800"
|
||||
@@ -406,23 +433,41 @@ onMounted(() => {
|
||||
frameborder="0"
|
||||
allowfullscreen
|
||||
sandbox="allow-same-origin allow-scripts allow-modals allow-downloads allow-forms allow-popups"
|
||||
></iframe>
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
<template v-else-if="orderDetail.instanceOf == 'owner'"
|
||||
><NFlex justify="center">
|
||||
<PointGoodsItem style="max-width: 300px" :goods="currentGoods" />
|
||||
<template v-else-if="orderDetail.instanceOf == 'owner'">
|
||||
<NFlex justify="center">
|
||||
<PointGoodsItem
|
||||
style="max-width: 300px"
|
||||
:goods="currentGoods"
|
||||
/>
|
||||
</NFlex>
|
||||
<NDivider> 设置订单状态 </NDivider>
|
||||
<NFlex justify="center" style="width: 100%">
|
||||
<NFlex
|
||||
justify="center"
|
||||
style="width: 100%"
|
||||
>
|
||||
<NSteps
|
||||
:current="orderDetail.status + 1"
|
||||
size="small"
|
||||
@update:current="(c) => onChangeStatus(orderDetail?.id ?? -1, c - 1)"
|
||||
>
|
||||
<NStep title="等待中" description="等待主播发货" :disabled="orderDetail.status >= 0" />
|
||||
<NStep title="已发货" description="已经发货了" :disabled="orderDetail.status >= 1" />
|
||||
<NStep title="已完成" description="就是已完成" :disabled="orderDetail.status >= 2" />
|
||||
<NStep
|
||||
title="等待中"
|
||||
description="等待主播发货"
|
||||
:disabled="orderDetail.status >= 0"
|
||||
/>
|
||||
<NStep
|
||||
title="已发货"
|
||||
description="已经发货了"
|
||||
:disabled="orderDetail.status >= 1"
|
||||
/>
|
||||
<NStep
|
||||
title="已完成"
|
||||
description="就是已完成"
|
||||
:disabled="orderDetail.status >= 2"
|
||||
/>
|
||||
</NSteps>
|
||||
</NFlex>
|
||||
<template v-if="orderDetail.status == PointOrderStatus.Shipped && orderDetail.instanceOf == 'owner'">
|
||||
@@ -442,7 +487,12 @@ onMounted(() => {
|
||||
style="max-width: 200px"
|
||||
/>
|
||||
</NInputGroup>
|
||||
<NButton type="primary" @click="updateExpress(orderDetail)" style="width: 120px" :loading="isLoading">
|
||||
<NButton
|
||||
type="primary"
|
||||
style="width: 120px"
|
||||
:loading="isLoading"
|
||||
@click="updateExpress(orderDetail)"
|
||||
>
|
||||
更新快递信息
|
||||
</NButton>
|
||||
</NFlex>
|
||||
@@ -452,3 +502,9 @@ onMounted(() => {
|
||||
</NScrollbar>
|
||||
</NModal>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
:deep(.n-data-table .n-data-table-tr:hover) {
|
||||
background-color: rgba(0, 0, 0, 0.03);
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user