feat:【antd】【mall】diy-editor 代码风格统一 & 逐个测试 50%

This commit is contained in:
YunaiV
2025-11-11 19:34:42 +08:00
parent 7b0bb55df0
commit 4488425cbf
17 changed files with 696 additions and 443 deletions

View File

@@ -1,23 +1,14 @@
<script setup lang="ts">
import type { NoticeBarProperty } from './config';
import { ref } from 'vue';
import { IconifyIcon } from '@vben/icons';
import { Divider, Image } from 'ant-design-vue';
import { Carousel, Divider, Image } from 'ant-design-vue';
/** 公告栏 */
defineOptions({ name: 'NoticeBar' });
const props = defineProps<{ property: NoticeBarProperty }>();
// 自动轮播
const activeIndex = ref(0);
setInterval(() => {
const contents = props.property.contents || [];
activeIndex.value = (activeIndex.value + 1) % (contents.length || 1);
}, 3000);
defineProps<{ property: NoticeBarProperty }>();
</script>
<template>
@@ -30,11 +21,17 @@ setInterval(() => {
>
<Image :src="property.iconUrl" class="h-[18px]" :preview="false" />
<Divider type="vertical" />
<div class="h-6 flex-1 truncate pr-2 leading-6">
{{ property.contents?.[activeIndex]?.text }}
</div>
<Carousel
:autoplay="true"
:dots="false"
vertical
class="flex-1 pr-2"
style="height: 24px"
>
<div v-for="(item, index) in property.contents" :key="index">
<div class="h-6 truncate leading-6">{{ item.text }}</div>
</div>
</Carousel>
<IconifyIcon icon="lucide:arrow-right" />
</div>
</template>
<style scoped lang="scss"></style>

View File

@@ -7,25 +7,18 @@ import { Form, FormItem, Textarea } from 'ant-design-vue';
import UploadImg from '#/components/upload/image-upload.vue';
import { ColorInput } from '#/views/mall/promotion/components';
// 导航栏属性面板
/** 导航栏属性面板 */
defineOptions({ name: 'PageConfigProperty' });
const props = defineProps<{ modelValue: PageConfigProperty }>();
const emit = defineEmits(['update:modelValue']);
// 表单校验
const rules = {};
const formData = useVModel(props, 'modelValue', emit);
</script>
<template>
<Form
:model="formData"
:rules="rules"
:label-col="{ span: 6 }"
:wrapper-col="{ span: 18 }"
>
<Form :model="formData" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }">
<FormItem label="页面描述" name="description">
<Textarea
v-model:value="formData!.description"
@@ -47,5 +40,3 @@ const formData = useVModel(props, 'modelValue', emit);
</FormItem>
</Form>
</template>
<style scoped lang="scss"></style>

View File

@@ -9,10 +9,10 @@ import { getArticle } from '#/api/mall/promotion/article';
/** 营销文章 */
defineOptions({ name: 'PromotionArticle' });
// 定义属性
const props = defineProps<{ property: PromotionArticleProperty }>();
// 商品列表
const article = ref<MallArticleApi.Article>();
const props = defineProps<{ property: PromotionArticleProperty }>(); // 定义属性
const article = ref<MallArticleApi.Article>(); // 商品列表
watch(
() => props.property.id,

View File

@@ -12,18 +12,18 @@ import { getArticlePage } from '#/api/mall/promotion/article';
import ComponentContainerProperty from '../../component-container-property.vue';
// 营销文章属性面板
/** 营销文章属性面板 */
defineOptions({ name: 'PromotionArticleProperty' });
const props = defineProps<{ modelValue: PromotionArticleProperty }>();
const emit = defineEmits(['update:modelValue']);
const formData = useVModel(props, 'modelValue', emit);
// 文章列表
const articles = ref<MallArticleApi.Article[]>([]);
// 加载中
const loading = ref(false);
// 查询文章列表
const articles = ref<MallArticleApi.Article[]>([]); // 文章列表
const loading = ref(false); // 加载中
/** 查询文章列表 */
const queryArticleList = async (title?: string) => {
loading.value = true;
const { list } = await getArticlePage({
@@ -35,7 +35,7 @@ const queryArticleList = async (title?: string) => {
loading.value = false;
};
// 初始化
/** 初始化 */
onMounted(() => {
queryArticleList();
});

View File

@@ -15,10 +15,10 @@ import { getCombinationActivityListByIds } from '#/api/mall/promotion/combinatio
/** 拼团卡片 */
defineOptions({ name: 'PromotionCombination' });
// 定义属性
const props = defineProps<{ property: PromotionCombinationProperty }>();
// 商品列表
const spuList = ref<MallSpuApi.Spu[]>([]);
const spuList = ref<MallSpuApi.Spu[]>([]); // 商品列表
const spuIdList = ref<number[]>([]);
const combinationActivityList = ref<
MallCombinationActivityApi.CombinationActivity[]
@@ -30,7 +30,7 @@ watch(
try {
// 新添加的拼团组件是没有活动ID的
const activityIds = props.property.activityIds;
// 检查活动ID的有效性
// 检查活动 ID 的有效性
if (Array.isArray(activityIds) && activityIds.length > 0) {
// 获取拼团活动详情列表
combinationActivityList.value =
@@ -68,32 +68,25 @@ watch(
},
);
/**
* 计算商品的间距
* @param index 商品索引
*/
const calculateSpace = (index: number) => {
// 商品的列数
const columns = props.property.layoutType === 'twoCol' ? 2 : 1;
// 第一列没有左边距
const marginLeft = index % columns === 0 ? '0' : `${props.property.space}px`;
// 第一行没有上边距
const marginTop = index < columns ? '0' : `${props.property.space}px`;
/** 计算商品的间距 */
function calculateSpace(index: number) {
const columns = props.property.layoutType === 'twoCol' ? 2 : 1; // 商品的列数
const marginLeft = index % columns === 0 ? '0' : `${props.property.space}px`; // 第一列没有左边距
const marginTop = index < columns ? '0' : `${props.property.space}px`; // 第一行没有上边距
return { marginLeft, marginTop };
};
}
// 容器
const containerRef = ref();
// 计算商品的宽度
const calculateWidth = () => {
const containerRef = ref(); // 容器
/** 计算商品的宽度 */
function calculateWidth() {
let width = '100%';
// 双列时每列的宽度为:(总宽度 - 间距)/ 2
if (props.property.layoutType === 'twoCol') {
// 双列时每列的宽度为:(总宽度 - 间距)/ 2
width = `${(containerRef.value.offsetWidth - props.property.space) / 2}px`;
}
return { width };
};
}
</script>
<template>
<div

View File

@@ -1,11 +1,6 @@
<script setup lang="ts">
import type { PromotionCombinationProperty } from './config';
import type { MallCombinationActivityApi } from '#/api/mall/promotion/combination/combinationActivity';
import { onMounted, ref } from 'vue';
import { CommonStatusEnum } from '@vben/constants';
import { IconifyIcon } from '@vben/icons';
import { useVModel } from '@vueuse/core';
@@ -22,27 +17,20 @@ import {
Tooltip,
} from 'ant-design-vue';
import { getCombinationActivityPage } from '#/api/mall/promotion/combination/combinationActivity';
import UploadImg from '#/components/upload/image-upload.vue';
// import CombinationShowcase from '#/views/mall/promotion/combination/components/combination-showcase.vue';
import { CombinationShowcase } from '#/views/mall/promotion/combination/components';
import { ColorInput } from '#/views/mall/promotion/components';
// 拼团属性面板
import ComponentContainerProperty from '../../component-container-property.vue';
/** 拼团属性面板 */
defineOptions({ name: 'PromotionCombinationProperty' });
const props = defineProps<{ modelValue: PromotionCombinationProperty }>();
const emit = defineEmits(['update:modelValue']);
const formData = useVModel(props, 'modelValue', emit);
// 活动列表
const activityList = ref<MallCombinationActivityApi.CombinationActivity[]>([]);
onMounted(async () => {
const { list } = await getCombinationActivityPage({
pageNo: 1,
pageSize: 10,
status: CommonStatusEnum.ENABLE,
});
activityList.value = list;
});
</script>
<template>
@@ -184,5 +172,3 @@ onMounted(async () => {
</Form>
</ComponentContainerProperty>
</template>
<style scoped lang="scss"></style>

View File

@@ -14,10 +14,10 @@ import { getPointActivityListByIds } from '#/api/mall/promotion/point';
/** 积分商城卡片 */
defineOptions({ name: 'PromotionPoint' });
// 定义属性
const props = defineProps<{ property: PromotionPointProperty }>();
// 商品列表
const spuList = ref<MallPointActivityApi.SpuExtensionWithPoint[]>([]);
const spuList = ref<MallPointActivityApi.SpuExtensionWithPoint[]>([]); // 商品列表
const spuIdList = ref<number[]>([]);
const pointActivityList = ref<MallPointActivityApi.PointActivity[]>([]);
@@ -27,7 +27,7 @@ watch(
try {
// 新添加的积分商城组件是没有活动ID的
const activityIds = props.property.activityIds;
// 检查活动ID的有效性
// 检查活动 ID 的有效性
if (Array.isArray(activityIds) && activityIds.length > 0) {
// 获取积分商城活动详情列表
pointActivityList.value = await getPointActivityListByIds(activityIds);
@@ -65,32 +65,25 @@ watch(
},
);
/**
* 计算商品的间距
* @param index 商品索引
*/
const calculateSpace = (index: number) => {
// 商品的列数
const columns = props.property.layoutType === 'twoCol' ? 2 : 1;
// 第一列没有左边距
const marginLeft = index % columns === 0 ? '0' : `${props.property.space}px`;
// 第一行没有上边距
const marginTop = index < columns ? '0' : `${props.property.space}px`;
/** 计算商品的间距 */
function calculateSpace(index: number) {
const columns = props.property.layoutType === 'twoCol' ? 2 : 1; // 商品的列数
const marginLeft = index % columns === 0 ? '0' : `${props.property.space}px`; // 第一列没有左边距
const marginTop = index < columns ? '0' : `${props.property.space}px`; // 第一行没有上边距
return { marginLeft, marginTop };
};
}
// 容器
const containerRef = ref();
// 计算商品的宽度
const calculateWidth = () => {
const containerRef = ref(); // 容器
/** 计算商品的宽度 */
function calculateWidth() {
let width = '100%';
// 双列时每列的宽度为:(总宽度 - 间距)/ 2
if (props.property.layoutType === 'twoCol') {
// 双列时每列的宽度为:(总宽度 - 间距)/ 2
width = `${(containerRef.value.offsetWidth - props.property.space) / 2}px`;
}
return { width };
};
}
</script>
<template>
<div