feat: 优化页面

pull/155/head
xingyu4j 2025-06-24 15:37:42 +08:00
parent 6a4d0063ff
commit 0b830d634f
15 changed files with 215 additions and 163 deletions

View File

@ -121,7 +121,7 @@ const apiSelectRule = [
field: 'data',
title: '请求参数 JSON 格式',
props: {
autosize: true,
autoSize: true,
type: 'textarea',
placeholder: '{"type": 1}',
},
@ -155,7 +155,7 @@ const apiSelectRule = [
info: `data 为接口返回值,需要写一个匿名函数解析返回值为选择器 options 列表
(data: any)=>{ label: string; value: any }[]`,
props: {
autosize: true,
autoSize: true,
rows: { minRows: 2, maxRows: 6 },
type: 'textarea',
placeholder: `

View File

@ -26,7 +26,7 @@ defineExpose({
>
<Textarea
v-model:value="formData.desc"
:autosize="{ minRows: 6, maxRows: 6 }"
:auto-size="{ minRows: 6, maxRows: 6 }"
:maxlength="1200"
:show-count="true"
placeholder="一首关于糟糕分手的欢快歌曲"

View File

@ -28,7 +28,7 @@ defineExpose({
<Title title="歌词" desc="自己编写歌词或使用Ai生成歌词两节/8行效果最佳">
<Textarea
v-model:value="formData.lyric"
:autosize="{ minRows: 6, maxRows: 6 }"
:auto-size="{ minRows: 6, maxRows: 6 }"
:maxlength="1200"
:show-count="true"
placeholder="请输入您自己的歌词"
@ -60,7 +60,7 @@ defineExpose({
>
<Textarea
v-model="formData.style"
:autosize="{ minRows: 4, maxRows: 4 }"
:auto-size="{ minRows: 4, maxRows: 4 }"
:maxlength="256"
show-count
placeholder="输入音乐风格(英文)"

View File

@ -100,15 +100,6 @@ export function useGridColumns(): VxeTableGridOptions['columns'] {
minWidth: 180,
slots: { default: 'content' },
},
{
field: 'status',
title: '绘画状态',
minWidth: 100,
cellRender: {
name: 'CellDict',
props: { type: DICT_TYPE.AI_IMAGE_STATUS },
},
},
{
field: 'duration',
title: '时长(秒)',
@ -139,9 +130,12 @@ export function useGridColumns(): VxeTableGridOptions['columns'] {
},
},
{
field: 'tags',
title: '风格标签',
minWidth: 180,
slots: { default: 'tags' },
cellRender: {
name: 'CellTags',
},
},
{
minWidth: 100,

View File

@ -7,7 +7,7 @@ import { onMounted, ref } from 'vue';
import { confirm, DocAlert, Page } from '@vben/common-ui';
import { Button, message, Switch, Tag } from 'ant-design-vue';
import { Button, message, Switch } from 'ant-design-vue';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { deleteMusic, getMusicPage, updateMusic } from '#/api/ai/music';
@ -101,9 +101,9 @@ onMounted(async () => {
</template>
<template #userId="{ row }">
<span>{{
userList.find((item) => item.id === row.userId)?.nickname
}}</span>
<span>
{{ userList.find((item) => item.id === row.userId)?.nickname }}
</span>
</template>
<template #content="{ row }">
<Button
@ -141,11 +141,6 @@ onMounted(async () => {
:disabled="row.status !== AiMusicStatusEnum.SUCCESS"
/>
</template>
<template #tags="{ row }">
<Tag v-for="tag in row.tags" :key="tag" class="ml-1">
{{ tag }}
</Tag>
</template>
<template #actions="{ row }">
<TableAction
:actions="[

View File

@ -98,7 +98,7 @@ watch(copied, (val) => {
<Textarea
id="inputId"
v-model:value="compContent"
autosize
auto-size
:bordered="false"
placeholder="生成的内容……"
/>

View File

@ -20,7 +20,13 @@ export function useGridColumns(): VxeTableGridOptions<BpmProcessDefinitionApi.Pr
field: 'icon',
title: '流程图标',
minWidth: 100,
slots: { default: 'icon' },
cellRender: {
name: 'CellImage',
props: {
width: 24,
height: 24,
},
},
},
{
field: 'startUsers',
@ -47,7 +53,9 @@ export function useGridColumns(): VxeTableGridOptions<BpmProcessDefinitionApi.Pr
field: 'version',
title: '流程版本',
minWidth: 80,
slots: { default: 'version' },
cellRender: {
name: 'CellTag',
},
},
{
field: 'deploymentTime',

View File

@ -6,7 +6,7 @@ import { useRoute, useRouter } from 'vue-router';
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
import { Button, Image, Tag, Tooltip } from 'ant-design-vue';
import { Button, Tooltip } from 'ant-design-vue';
import { TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { getProcessDefinitionPage } from '#/api/bpm/definition';
@ -93,16 +93,6 @@ onMounted(() => {
<DocAlert title="工作流手册" url="https://doc.iocoder.cn/bpm/" />
</template>
<Grid table-title="">
<template #icon="{ row }">
<Image
v-if="row.icon"
:src="row.icon"
:width="24"
:height="24"
class="rounded"
/>
<span v-else> </span>
</template>
<template #startUsers="{ row }">
<template v-if="!row.startUsers?.length"></template>
<template v-else-if="row.startUsers.length === 1">
@ -135,9 +125,6 @@ onMounted(() => {
</Button>
<span v-else></span>
</template>
<template #version="{ row }">
<Tag>v{{ row.version }}</Tag>
</template>
<template #actions="{ row }">
<TableAction
:actions="[

View File

@ -4,7 +4,7 @@ import type { DescriptionItemSchema } from '#/components/description';
import { h } from 'vue';
import dayjs from 'dayjs';
import { formatDateTime } from '@vben/utils';
import { DictTag } from '#/components/dict-tag';
import { DICT_TYPE, getDictOptions, getRangePickerDefaultProps } from '#/utils';
@ -186,12 +186,12 @@ export function useDetailFormSchema(): DescriptionItemSchema[] {
{
label: '开始时间',
field: 'startTime',
content: (data) => dayjs(data?.startTime).format('YYYY-MM-DD HH:mm:ss'),
content: (data) => formatDateTime(data?.startTime) as string,
},
{
label: '结束时间',
field: 'endTime',
content: (data) => dayjs(data?.endTime).format('YYYY-MM-DD HH:mm:ss'),
content: (data) => formatDateTime(data?.endTime) as string,
},
{
label: '原因',

View File

@ -54,7 +54,14 @@ export function useGridColumns(): VxeTableGridOptions['columns'] {
field: 'avatar',
title: '头像',
width: 70,
slots: { default: 'avatar' },
cellRender: {
name: 'CellImage',
props: {
width: 24,
height: 24,
shape: 'circle',
},
},
},
{
field: 'nickname',

View File

@ -6,7 +6,7 @@ import { useAccess } from '@vben/access';
import { DocAlert, Page, useVbenModal } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { Avatar, message, Switch } from 'ant-design-vue';
import { message, Switch } from 'ant-design-vue';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import {
@ -167,10 +167,6 @@ const [Grid, gridApi] = useVbenVxeGrid({
/>
</template>
<template #avatar="{ row }">
<Avatar :src="row.avatar" />
</template>
<template #brokerageEnabled="{ row }">
<Switch
v-model:checked="row.brokerageEnabled"

View File

@ -9,8 +9,6 @@ import { ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { fenToYuan } from '@vben/utils';
import { Avatar, Tag } from 'ant-design-vue';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { getBrokerageRecordPage } from '#/api/mall/trade/brokerage/record';
import { DICT_TYPE, getDictOptions, getRangePickerDefaultProps } from '#/utils';
@ -102,7 +100,13 @@ function useColumns(): VxeTableGridOptions['columns'] {
field: 'sourceUserAvatar',
title: '头像',
width: 70,
slots: { default: 'avatar' },
cellRender: {
name: 'CellImage',
props: {
width: 24,
height: 24,
},
},
},
{
field: 'sourceUserNickname',
@ -119,7 +123,10 @@ function useColumns(): VxeTableGridOptions['columns'] {
field: 'status',
title: '状态',
minWidth: 85,
slots: { default: 'status' },
cellRender: {
name: 'CellDict',
props: { type: DICT_TYPE.BROKERAGE_RECORD_STATUS },
},
},
{
field: 'createTime',
@ -173,21 +180,6 @@ const [Grid, gridApi] = useVbenVxeGrid({
<template>
<Modal title="推广订单列表" class="w-3/5">
<Grid table-title="广">
<template #avatar="{ row }">
<Avatar :src="row.sourceUserAvatar" />
</template>
<template #status="{ row }">
<template
v-for="dict in getDictOptions(DICT_TYPE.BROKERAGE_RECORD_STATUS)"
:key="dict.value"
>
<Tag v-if="dict.value === row.status" :color="dict.colorType">
{{ dict.label }}
</Tag>
</template>
</template>
</Grid>
<Grid table-title="广" />
</Modal>
</template>

View File

@ -7,7 +7,7 @@ import { ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { Avatar, Tag } from 'ant-design-vue';
import { Tag } from 'ant-design-vue';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { getBrokerageUserPage } from '#/api/mall/trade/brokerage/user';
@ -76,7 +76,14 @@ function useColumns(): VxeTableGridOptions['columns'] {
field: 'avatar',
title: '头像',
width: 70,
slots: { default: 'avatar' },
cellRender: {
name: 'CellImage',
props: {
width: 24,
height: 24,
shape: 'circle',
},
},
},
{
field: 'nickname',
@ -144,10 +151,6 @@ const [Grid, gridApi] = useVbenVxeGrid({
<template>
<Modal title="推广人列表" class="w-3/5">
<Grid table-title="广">
<template #avatar="{ row }">
<Avatar :src="row.avatar" />
</template>
<template #brokerageEnabled="{ row }">
<Tag v-if="row.brokerageEnabled" color="success"></Tag>
<Tag v-else></Tag>

View File

@ -1,7 +1,15 @@
import type { VbenFormSchema } from '#/adapter/form';
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { DescriptionItemSchema } from '#/components/description';
import { h } from 'vue';
import { fenToYuan, formatDateTime } from '@vben/utils';
import { Tag } from 'ant-design-vue';
import { getAppList } from '#/api/pay/app';
import { DictTag } from '#/components/dict-tag';
import { DICT_TYPE, getDictOptions, getRangePickerDefaultProps } from '#/utils';
/** 列表的搜索表单 */
@ -119,3 +127,128 @@ export function useGridColumns(): VxeTableGridOptions['columns'] {
},
];
}
/** 详情页的字段 */
export function useBaseDetailSchema(): DescriptionItemSchema[] {
return [
{
field: 'merchantRefundId',
label: '商户退款单号',
content: (data) =>
h(Tag, {}, () => {
return data?.merchantRefundId || '-';
}),
},
{
field: 'channelRefundNo',
label: '渠道退款单号',
content: (data) =>
h(Tag, {}, () => {
return data?.channelRefundNo || '-';
}),
},
{
field: 'merchantOrderId',
label: '商户支付单号',
content: (data) =>
h(Tag, {}, () => {
return data?.merchantOrderId || '-';
}),
},
{
field: 'channelOrderNo',
label: '渠道支付单号',
content: (data) =>
h(Tag, {}, () => {
return data?.channelOrderNo || '-';
}),
},
{
field: 'appId',
label: '应用编号',
},
{
field: 'appName',
label: '应用名称',
},
{
field: 'payPrice',
label: '支付金额',
content: (data) =>
h(Tag, { color: 'success' }, () => {
return fenToYuan(data.payPrice || 0);
}),
},
{
field: 'refundPrice',
label: '退款金额',
content: (data) =>
h(Tag, { color: 'red' }, () => {
return fenToYuan(data.refundPrice || 0);
}),
},
{
field: 'status',
label: '退款状态',
content: (data) =>
h(DictTag, {
type: DICT_TYPE.PAY_REFUND_STATUS,
value: data?.status,
}),
},
{
field: 'successTime',
label: '退款时间',
content: (data) => formatDateTime(data.successTime) as string,
},
{
field: 'createTime',
label: '创建时间',
content: (data) => formatDateTime(data.createTime) as string,
},
{
field: 'updateTime',
label: '更新时间',
content: (data) => formatDateTime(data.updateTime) as string,
},
];
}
/** 详情页的字段 */
export function useChannelDetailSchema(): DescriptionItemSchema[] {
return [
{
field: 'channelCode',
label: '退款渠道',
content: (data) =>
h(DictTag, {
type: DICT_TYPE.PAY_CHANNEL_CODE,
value: data?.channelCode,
}),
},
{
field: 'reason',
label: '退款原因',
},
{
field: 'userIp',
label: '退款 IP',
},
{
field: 'notifyUrl',
label: '通知 URL',
},
{
field: 'channelErrorCode',
label: '渠道错误码',
},
{
field: 'channelErrorMsg',
label: '渠道错误码描述',
},
{
field: 'channelNotifyData',
label: '支付通道异步回调内容',
},
];
}

View File

@ -4,16 +4,34 @@ import type { PayRefundApi } from '#/api/pay/refund';
import { ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { formatDateTime } from '@vben/utils';
import { Descriptions, Divider, Tag } from 'ant-design-vue';
import { Divider } from 'ant-design-vue';
import { getRefund } from '#/api/pay/refund';
import { DictTag } from '#/components/dict-tag';
import { DICT_TYPE } from '#/utils';
import { useDescription } from '#/components/description';
import { useBaseDetailSchema, useChannelDetailSchema } from '../data';
const formData = ref<PayRefundApi.Refund>();
const [BaseDescription] = useDescription({
componentProps: {
bordered: false,
column: 2,
class: 'mx-4',
},
schema: useBaseDetailSchema(),
});
const [ChannelDescription] = useDescription({
componentProps: {
bordered: false,
column: 2,
class: 'mx-4',
},
schema: useChannelDetailSchema(),
});
const [Modal, modalApi] = useVbenModal({
async onOpenChange(isOpen: boolean) {
if (!isOpen) {
@ -42,89 +60,8 @@ const [Modal, modalApi] = useVbenModal({
:show-cancel-button="false"
:show-confirm-button="false"
>
<Descriptions bordered :column="2" size="middle" class="mx-4">
<Descriptions.Item label="商户退款单号">
<Tag size="small">{{ formData?.merchantRefundId }}</Tag>
</Descriptions.Item>
<Descriptions.Item label="渠道退款单号">
<Tag type="success" size="small" v-if="formData?.channelRefundNo">
{{ formData?.channelRefundNo }}
</Tag>
</Descriptions.Item>
<Descriptions.Item label="商户支付单号">
<Tag size="small">{{ formData?.merchantOrderId }}</Tag>
</Descriptions.Item>
<Descriptions.Item label="渠道支付单号">
<Tag type="success" size="small">
{{ formData?.channelOrderNo }}
</Tag>
</Descriptions.Item>
<Descriptions.Item label="应用编号">
{{ formData?.appId }}
</Descriptions.Item>
<Descriptions.Item label="应用名称">
{{ formData?.appName }}
</Descriptions.Item>
<Descriptions.Item label="支付金额">
<Tag type="success" size="small">
{{ (formData?.payPrice || 0) / 100.0 }}
</Tag>
</Descriptions.Item>
<Descriptions.Item label="退款金额">
<Tag size="mini" type="danger">
{{ (formData?.refundPrice || 0) / 100.0 }}
</Tag>
</Descriptions.Item>
<Descriptions.Item label="退款状态">
<DictTag
:type="DICT_TYPE.PAY_REFUND_STATUS"
:value="formData?.status"
/>
</Descriptions.Item>
<Descriptions.Item label="退款时间">
{{ formatDateTime(formData?.successTime || '') }}
</Descriptions.Item>
<Descriptions.Item label="创建时间">
{{ formatDateTime(formData?.createTime || '') }}
</Descriptions.Item>
<Descriptions.Item label="更新时间">
{{ formatDateTime(formData?.updateTime || '') }}
</Descriptions.Item>
</Descriptions>
<BaseDescription :data="formData" />
<Divider />
<Descriptions bordered :column="2" size="middle" class="mx-4">
<Descriptions.Item label="退款渠道">
<DictTag
:type="DICT_TYPE.PAY_CHANNEL_CODE"
:value="formData?.channelCode"
/>
</Descriptions.Item>
<Descriptions.Item label="退款原因">
{{ formData?.reason }}
</Descriptions.Item>
<Descriptions.Item label="退款 IP">
{{ formData?.userIp }}
</Descriptions.Item>
<Descriptions.Item label="通知 URL">
{{ formData?.notifyUrl }}
</Descriptions.Item>
</Descriptions>
<Divider />
<Descriptions bordered :column="2" size="middle" class="mx-4">
<Descriptions.Item label="渠道错误码">
{{ formData?.channelErrorCode }}
</Descriptions.Item>
<Descriptions.Item label="渠道错误码描述">
{{ formData?.channelErrorMsg }}
</Descriptions.Item>
</Descriptions>
<Descriptions bordered :column="1" size="middle" class="mx-4">
<Descriptions.Item label="支付通道异步回调内容">
<p class="whitespace-pre-wrap break-words">
{{ formData?.channelNotifyData }}
</p>
</Descriptions.Item>
</Descriptions>
<ChannelDescription :data="formData" />
</Modal>
</template>