diff --git a/src/api/mall/promotion/seckill/seckillActivity.ts b/src/api/mall/promotion/seckill/seckillActivity.ts index 4bb0e8b1..dc5a350a 100644 --- a/src/api/mall/promotion/seckill/seckillActivity.ts +++ b/src/api/mall/promotion/seckill/seckillActivity.ts @@ -18,6 +18,7 @@ export interface SeckillActivityVO { singleLimitCount?: number stock?: number totalStock?: number + seckillPrice?: number products?: SeckillProductVO[] } @@ -43,6 +44,11 @@ export const getSeckillActivityPage = async (params) => { return await request.get({ url: '/promotion/seckill-activity/page', params }) } +// 查询秒杀活动列表,基于活动编号数组 +export const getSeckillActivityListByIds = (ids: number[]) => { + return request.get({ url: `/promotion/seckill-activity/list-by-ids?ids=${ids}` }) +} + // 查询秒杀活动详情 export const getSeckillActivity = async (id: number) => { return await request.get({ url: '/promotion/seckill-activity/get?id=' + id }) diff --git a/src/components/DiyEditor/components/mobile/FloatingActionButton/index.vue b/src/components/DiyEditor/components/mobile/FloatingActionButton/index.vue index 19e42cb6..c2b99263 100644 --- a/src/components/DiyEditor/components/mobile/FloatingActionButton/index.vue +++ b/src/components/DiyEditor/components/mobile/FloatingActionButton/index.vue @@ -44,7 +44,7 @@ defineOptions({ name: 'FloatingActionButton' }) defineProps<{ property: FloatingActionButtonProperty }>() // 是否展开 -const expanded = ref(true) +const expanded = ref(false) // 处理展开/折叠 const handleToggleFab = () => { expanded.value = !expanded.value diff --git a/src/components/DiyEditor/components/mobile/PromotionSeckill/config.ts b/src/components/DiyEditor/components/mobile/PromotionSeckill/config.ts index 800398be..022be92c 100644 --- a/src/components/DiyEditor/components/mobile/PromotionSeckill/config.ts +++ b/src/components/DiyEditor/components/mobile/PromotionSeckill/config.ts @@ -3,13 +3,21 @@ import { ComponentStyle, DiyComponent } from '@/components/DiyEditor/util' /** 秒杀属性 */ export interface PromotionSeckillProperty { // 布局类型:单列 | 三列 - layoutType: 'oneCol' | 'threeCol' + layoutType: 'oneColBigImg' | 'oneColSmallImg' | 'twoCol' // 商品字段 fields: { // 商品名称 name: PromotionSeckillFieldProperty + // 商品简介 + introduction: PromotionSeckillFieldProperty // 商品价格 price: PromotionSeckillFieldProperty + // 市场价 + marketPrice: PromotionSeckillFieldProperty + // 商品销量 + salesCount: PromotionSeckillFieldProperty + // 商品库存 + stock: PromotionSeckillFieldProperty } // 角标 badge: { @@ -18,6 +26,19 @@ export interface PromotionSeckillProperty { // 角标图片 imgUrl: string } + // 按钮 + btnBuy: { + // 类型:文字 | 图片 + type: 'text' | 'img' + // 文字 + text: string + // 文字按钮:背景渐变起始颜色 + bgBeginColor: string + // 文字按钮:背景渐变结束颜色 + bgEndColor: string + // 图片按钮:图片地址 + imgUrl: string + } // 上圆角 borderRadiusTop: number // 下圆角 @@ -25,10 +46,11 @@ export interface PromotionSeckillProperty { // 间距 space: number // 秒杀活动编号 - activityId: number + activityIds: number[] // 组件样式 style: ComponentStyle } + // 商品字段 export interface PromotionSeckillFieldProperty { // 是否显示 @@ -43,13 +65,23 @@ export const component = { name: '秒杀', icon: 'mdi:calendar-time', property: { - activityId: undefined, - layoutType: 'oneCol', + layoutType: 'oneColBigImg', fields: { name: { show: true, color: '#000' }, - price: { show: true, color: '#ff3000' } + introduction: { show: true, color: '#999' }, + price: { show: true, color: '#ff3000' }, + marketPrice: { show: true, color: '#c4c4c4' }, + salesCount: { show: true, color: '#c4c4c4' }, + stock: { show: false, color: '#c4c4c4' } }, badge: { show: false, imgUrl: '' }, + btnBuy: { + type: 'text', + text: '立即秒杀', + bgBeginColor: '#FF6000', + bgEndColor: '#FE832A', + imgUrl: '' + }, borderRadiusTop: 8, borderRadiusBottom: 8, space: 8, diff --git a/src/components/DiyEditor/components/mobile/PromotionSeckill/index.vue b/src/components/DiyEditor/components/mobile/PromotionSeckill/index.vue index fe092a03..3d34a3d4 100644 --- a/src/components/DiyEditor/components/mobile/PromotionSeckill/index.vue +++ b/src/components/DiyEditor/components/mobile/PromotionSeckill/index.vue @@ -1,135 +1,201 @@ - - + diff --git a/src/components/DiyEditor/components/mobile/PromotionSeckill/property.vue b/src/components/DiyEditor/components/mobile/PromotionSeckill/property.vue index 306ec9b9..61287590 100644 --- a/src/components/DiyEditor/components/mobile/PromotionSeckill/property.vue +++ b/src/components/DiyEditor/components/mobile/PromotionSeckill/property.vue @@ -2,30 +2,31 @@ - - - - - + - - + + - + + + + + + + + + + + @@ -34,12 +35,36 @@ + +
+ + +
+
+ +
+ + +
+
+ +
+ + +
+
+ +
+ + +
+
@@ -47,10 +72,36 @@ - + + + + + 文字 + 图片 + + + + + () const emit = defineEmits(['update:modelValue']) const { formData } = usePropertyForm(props.modelValue, emit) // 活动列表 -const activityList = ref([]) +const activityList = ref([]) onMounted(async () => { const { list } = await SeckillActivityApi.getSeckillActivityPage({ status: CommonStatusEnum.ENABLE diff --git a/src/components/FormCreate/src/config/useDictSelectRule.ts b/src/components/FormCreate/src/config/useDictSelectRule.ts index 5c5e8cad..f232f486 100644 --- a/src/components/FormCreate/src/config/useDictSelectRule.ts +++ b/src/components/FormCreate/src/config/useDictSelectRule.ts @@ -48,7 +48,7 @@ export const useDictSelectRule = () => { }, { type: 'select', - field: 'dictValueType', + field: 'valueType', title: '字典值类型', value: 'str', options: [ diff --git a/src/router/index.ts b/src/router/index.ts index 8f66ca31..b818421c 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -5,7 +5,7 @@ import remainingRouter from './modules/remaining' // 创建路由实例 const router = createRouter({ - history: createWebHistory(), // createWebHashHistory URL带#,createWebHistory URL不带# + history: createWebHistory(import.meta.env.VITE_BASE_PATH), // createWebHashHistory URL带#,createWebHistory URL不带# strict: true, routes: remainingRouter as RouteRecordRaw[], scrollBehavior: () => ({ left: 0, top: 0 }) diff --git a/src/utils/routerHelper.ts b/src/utils/routerHelper.ts index f292751a..83aa39ef 100644 --- a/src/utils/routerHelper.ts +++ b/src/utils/routerHelper.ts @@ -88,7 +88,8 @@ export const generateRoute = (routes: AppCustomRouteRecordRaw[]): AppRouteRecord // 2. 生成 data(AppRouteRecordRaw) // 路由地址转首字母大写驼峰,作为路由名称,适配keepAlive let data: AppRouteRecordRaw = { - path: route.path.indexOf('?') > -1 ? route.path.split('?')[0] : route.path, + path: + route.path.indexOf('?') > -1 && !isUrl(route.path) ? route.path.split('?')[0] : route.path, // 注意,需要排除 http 这种 url,避免它带 ? 参数被截取掉 name: route.componentName && route.componentName.length > 0 ? route.componentName diff --git a/src/views/crm/contract/detail/index.vue b/src/views/crm/contract/detail/index.vue index 1369a355..9d5e14ca 100644 --- a/src/views/crm/contract/detail/index.vue +++ b/src/views/crm/contract/detail/index.vue @@ -36,7 +36,7 @@ ref="permissionListRef" :biz-id="contract.id!" :biz-type="BizTypeEnum.CRM_CONTRACT" - :show-action="!permissionListRef?.isPool || false" + :show-action="true" @quit-team="close" /> diff --git a/src/views/mall/promotion/kefu/components/KeFuMessageList.vue b/src/views/mall/promotion/kefu/components/KeFuMessageList.vue index bd1b9ce0..483fdc24 100644 --- a/src/views/mall/promotion/kefu/components/KeFuMessageList.vue +++ b/src/views/mall/promotion/kefu/components/KeFuMessageList.vue @@ -86,7 +86,7 @@ @@ -423,9 +423,9 @@ const showTime = computed(() => (item: KeFuMessageRespVO, index: number) => { // 消息气泡 .kefu-message { - color: #A9A9A9; + color: #a9a9a9; border-radius: 5px; - box-shadow: 3px 3px 5px rgba(220,220,220, 0.1); + box-shadow: 3px 3px 5px rgba(220, 220, 220, 0.1); padding: 5px 10px; width: auto; max-width: 50%; diff --git a/src/views/mall/promotion/kefu/components/tools/emoji.ts b/src/views/mall/promotion/kefu/components/tools/emoji.ts index ff7a12e7..0cbf95af 100644 --- a/src/views/mall/promotion/kefu/components/tools/emoji.ts +++ b/src/views/mall/promotion/kefu/components/tools/emoji.ts @@ -66,7 +66,7 @@ export const useEmoji = () => { ) for (const path in pathList) { const imageModule: any = await pathList[path]() - emojiPathList.value.push(imageModule.default) + emojiPathList.value.push({ path: path, src: imageModule.default }) } } @@ -116,7 +116,10 @@ export const useEmoji = () => { function getEmojiFileByName(name: string) { for (const emoji of emojiList) { if (emoji.name === name) { - return emojiPathList.value.find((item: string) => item.indexOf(emoji.file) > -1) + const emojiPath = emojiPathList.value.find( + (item: { path: string; src: string }) => item.path.indexOf(emoji.file) > -1 + ) + return emojiPath ? emojiPath.src : undefined } } return false diff --git a/src/views/mall/promotion/seckill/components/SeckillShowcase.vue b/src/views/mall/promotion/seckill/components/SeckillShowcase.vue new file mode 100644 index 00000000..a924e8ca --- /dev/null +++ b/src/views/mall/promotion/seckill/components/SeckillShowcase.vue @@ -0,0 +1,156 @@ + + + + diff --git a/src/views/mall/promotion/seckill/components/SeckillTableSelect.vue b/src/views/mall/promotion/seckill/components/SeckillTableSelect.vue new file mode 100644 index 00000000..3e4e67e9 --- /dev/null +++ b/src/views/mall/promotion/seckill/components/SeckillTableSelect.vue @@ -0,0 +1,343 @@ + + +