Merge remote-tracking branch 'origin/dev-yxl' into dev-sws

v1.0.0
sws 2024-08-19 18:08:32 +08:00
commit 8f95739901
9 changed files with 206 additions and 72 deletions

View File

@ -1,13 +1,22 @@
import request from '@/utils/request';
class ShopAPI {
/** 分类查询接口*/
/** 分类品牌查询接口*/
static getShop() {
return request({
url: `diyapi/goodsinit`,
method: 'post',
});
}
/** 自动查询商品接口*/
static getShopLists(data: any) {
return request({
url: `diyapi/goodsautodata`,
method: 'post',
data,
});
}
}
export default ShopAPI;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 622 B

After

Width:  |  Height:  |  Size: 380 B

View File

@ -6,6 +6,9 @@
<el-checkbox v-for="item in base_list.list_show_list" :key="item.value" :value="item.value">{{ item.name }}</el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="价格独行">
<el-switch v-model="form.is_price_solo"></el-switch>
</el-form-item>
</card-container>
<card-container>
<div class="mb-12">购物车设置</div>
@ -16,10 +19,10 @@
<div class="flex-row align-c jc-s gap-20 shopping_button_all">
<div v-for="item in base_list.shopping_button_list" :key="item.value" :class="['pa-10 re', { 'br-c br-primary radius-sm': shop_type(item) }]" @click="shopping_button_click(item)">
<template v-if="item.value == '0'">
<div class="pl-13 pr-13 round size-12 bg-primary cr-f shopping_button">{{ item.name }}</div>
<div :class="['pl-13 pr-13 round size-12 bg-primary cr-f shopping_button', {'disabled': ['3','4','5'].includes(form.product_style) }]">{{ item.name }}</div>
</template>
<template v-else-if="item.value == '1'">
<div class="pl-11 pr-11 round size-12 bg-primary cr-f shopping_button">{{ item.name }}</div>
<div :class="['pl-13 pr-13 round size-12 bg-primary cr-f shopping_button', {'disabled': ['3','4','5'].includes(form.product_style) }]">{{ item.name }}</div>
</template>
<template v-else-if="item.value == '2'">
<icon class="shopping_button round pl-6 pr-6 bg-primary " name="add" color="f" size="16"></icon>
@ -93,11 +96,20 @@ const shop_type = computed(() => {
});
const shopping_button_click = (item: { value: string; }) => {
form.value.shop_type = item.value;
if (['3','4','5'].includes(form.value.product_style) && ['0', '1'].includes(item.value)) {
return;
} else {
form.value.shop_type = item.value;
}
};
</script>
<style lang="scss">
<style lang="scss" scoped>
.card, .card.mb-8 {
.el-form-item:last-child {
margin-bottom: 0;
}
}
.card-container-br {
border-bottom: 0.8rem solid #f0f2f5;
}

View File

@ -4,37 +4,64 @@
<div v-for="(item, index) in list" :key="index" class="re" :class="layout_type" :style="layout_style">
<template v-if="product_style == '6'">
<div :class="['flex-row jc-sb ptb-15 mlr-10 gap-20', { 'br-b-e': index != list.length -1 }]">
<div v-if="is_show('0')" :class="text_line" :style="trends_config('title')">{{ item?.title || '耀 ' }}</div>
<div v-if="is_show('2')" class="num" :style="`color: ${ new_style.shop_price_color }`"><span class="identifying">¥</span><span :style="trends_config('price')">{{ item?.price || '41' }}</span></div>
<div v-if="is_show('0')" :class="text_line" :style="trends_config('title')">{{ item.title }}</div>
<div v-if="is_show('2')" class="num" :style="`color: ${ new_style.shop_price_color }`"><span class="identifying">¥</span><span :style="trends_config('price')">{{ item.min_price }}</span></div>
</div>
</template>
<template v-else>
<template v-if="!isEmpty(item)">
<image-empty v-model="item.new_src[0]" :class="`flex-img${product_style} flex align-c jc-c`" :style="content_img_radius"></image-empty>
<template v-if="!isEmpty(item.new_src)">
<image-empty v-model="item.new_src[0]" :class="`flex-img${product_style} flex align-c jc-c`" :style="content_img_radius"></image-empty>
</template>
<template v-else-if="!isEmpty(item.images)">
<el-image :src="item.images" :class="`flex-img${product_style} flex align-c jc-c`" fit="contain" class="img"></el-image>
</template>
<template v-else>
<image-empty :class="`flex-img${product_style} flex align-c jc-c`" :style="content_img_radius"></image-empty>
</template>
</template>
<template v-else>
<image-empty :class="`flex-img${product_style} flex align-c jc-c`" :style="content_img_radius"></image-empty>
</template>
<div class="flex-col flex-1 jc-sb content" :style="content_style">
<div class="flex-col flex-1 jc-sb content gap-10" :style="content_style">
<div class="flex-col gap-10 top-title">
<div v-if="is_show('0')" :class="text_line" :style="trends_config('title')">{{ item?.title || '耀 ' }}</div>
<div v-if="is_show('0')" :class="text_line" :style="trends_config('title')">{{ item.title }}</div>
<div v-if="show_content && is_show('1')" class="flex-row gap-5">
<div class="one1 radius-sm size-9 pl-3 pr-3">{{ item?.price || '满减活动' }}</div>
<div class="one2 radius-sm size-9 pl-3 pr-3">{{ item?.price || '包邮' }}</div>
<div class="one3 radius-sm size-9 pl-3 pr-3">{{ item?.price || '领劵' }}</div>
<div class="one1 radius-sm size-9 pl-3 pr-3">{{ '满减活动' }}</div>
<div class="one2 radius-sm size-9 pl-3 pr-3">{{ '包邮' }}</div>
<div class="one3 radius-sm size-9 pl-3 pr-3">{{ '领劵' }}</div>
</div>
</div>
<div class="flex-row jc-sb align-e">
<div class="flex-col gap-10">
<div class="flex-row align-c">
<div v-if="is_show('2')" class="num" :style="`color: ${ new_style.shop_price_color }`"><span class="identifying">¥</span><span :style="trends_config('price')">{{ item?.price || '41' }}</span></div>
<div v-if="show_content && is_show('5')" class="original-price size-10">{{ item?.price || '51' }}</div>
<div v-if="!['3','4','5'].includes(form.product_style)" class="flex-col gap-5 oh">
<div :class="[form.is_price_solo ? 'flex-row align-c nowrap': 'flex-col gap-5']">
<div v-if="is_show('2')" class="num" :style="`color: ${ new_style.shop_price_color }`"><span class="identifying">{{ item.show_price_symbol }}</span><span :style="trends_config('price')">{{ item.min_price }}</span><span class="identifying">{{ item.show_price_unit }}</span></div>
<div v-if="show_content && is_show('5')" class="size-10 flex"><span class="original-price-left"></span><span class="original-price flex-1 text-line-1">{{ item.show_original_price_symbol }}{{ item.min_original_price }}{{ item.show_original_price_unit }}</span></div>
</div>
<div class="flex-row jc-sb align-e">
<div>
<div v-if="show_content" class="flex-row align-c size-10">
<div v-if="is_show('3')" :class="['pr-5', {'br-r-e': is_show('3') && is_show('4')}]" :style="trends_config('sold_number')">{{ item.sales_count }}</div>
<div v-if="is_show('4')" class="pl-5" :style="trends_config('score')">0</div>
</div>
</div>
<div v-if="show_content" class="flex-row align-c size-10">
<div v-if="is_show('3')" :class="['pr-5', {'br-r-e': is_show('3') && is_show('4')}]" :style="trends_config('sold_number')">0</div>
<div v-if="is_show('4')" class="pl-5" :style="trends_config('score')">0</div>
<div v-if="form.is_shop_show">
<template v-if="form.shop_type == '0'">
<div class="pl-13 pr-13 round cr-f shopping_button" :style="trends_config('button','gradient')">购买</div>
</template>
<template v-else-if="form.shop_type == '1'">
<div class="pl-11 pr-11 round cr-f shopping_button" :style="trends_config('button','gradient')">立即购买</div>
</template>
<template v-else-if="form.shop_type == '2'">
<icon :class="['shopping_button round', {'pl-6 pr-6': shop_icon_size != '8', 'pl-5 pr-5' : shop_icon_size == '8' }] " name="add" color="f" :size="shop_icon_size" :styles="button_gradient()"></icon>
</template>
<template v-else>
<icon :class="['shopping_button round', {'pl-6 pr-6': shop_icon_size != '8', 'pl-5 pr-5' : shop_icon_size == '8' }]" name="cart" color="f" :size="shop_icon_size" :styles="button_gradient()"></icon>
</template>
</div>
</div>
</div>
<div v-else class="flex-row align-c jc-sb">
<div class="flex-row align-c nowrap text-line-1">
<div v-if="is_show('2')" class="num" :style="`color: ${ new_style.shop_price_color }`"><span class="identifying">{{ item.show_price_symbol }}</span><span :style="trends_config('price')">{{ item.min_price }}</span><span class="identifying">{{ item.show_price_unit }}</span></div>
<div v-if="show_content && is_show('5')" class="size-10 flex"><span class="original-price-left"></span><span class="original-price flex-1 text-line-1">{{ item.show_original_price_symbol }}{{ item.min_original_price }}{{ item.show_original_price_unit }}</span></div>
</div>
<div v-if="form.is_shop_show">
<template v-if="form.shop_type == '0'">
<div class="pl-13 pr-13 round cr-f shopping_button" :style="trends_config('button','gradient')">购买</div>
@ -43,16 +70,15 @@
<div class="pl-11 pr-11 round cr-f shopping_button" :style="trends_config('button','gradient')">立即购买</div>
</template>
<template v-else-if="form.shop_type == '2'">
<icon class="shopping_button round pl-6 pr-6" name="add" color="f" :size="shop_icon_size" :styles="button_gradient()"></icon>
<icon :class="['shopping_button round', {'pl-6 pr-6': shop_icon_size != '8', 'pl-5 pr-5' : shop_icon_size == '8' }] " name="add" color="f" :size="shop_icon_size" :styles="button_gradient()"></icon>
</template>
<template v-else>
<icon class="shopping_button round pl-6 pr-6" name="cart" color="f" :size="shop_icon_size" :styles="button_gradient()"></icon>
<icon :class="['shopping_button round', {'pl-6 pr-6': shop_icon_size != '8', 'pl-5 pr-5' : shop_icon_size == '8' }]" name="cart" color="f" :size="shop_icon_size" :styles="button_gradient()"></icon>
</template>
</div>
</div>
</div>
</template>
</div>
</div>
</div>
@ -60,6 +86,7 @@
<script setup lang="ts">
import { common_styles_computer, gradient_handle, padding_computer, radius_computer } from '@/utils';
import { isEmpty } from 'lodash';
import ShopAPI from '@/api/shop';
const props = defineProps({
value: {
@ -82,13 +109,61 @@ const state = reactive({
const { form, new_style } = toRefs(state);
//
const list = computed(() => {
if (!isEmpty(form.value.product_list)) {
return form.value.product_list;
interface product_list {
title: string;
images: string;
new_src: string[];
min_original_price: string;
show_original_price_symbol: string;
show_original_price_unit: string;
min_price: string;
show_price_symbol: string;
show_price_unit: string;
sales_count: string;
}
const default_list = {
title: '华为荣耀畅享平板换屏服务 屏幕换外屏',
min_original_price: '41.2',
show_original_price_symbol: "¥",
min_price: '51',
show_price_symbol: "¥",
show_price_unit: "",
sales_count: "1000",
images: '',
new_src: []
}
const list = ref<product_list[]>([]);
watchEffect(() => {
if (form.value.product_check == '0') {
if (!isEmpty(form.value.product_list)) {
list.value = form.value.product_list;
} else {
list.value = Array(4).fill(default_list);
}
} else {
return Array(4);
get_products();
}
});
const get_products = () => {
const { goods_category_ids, goods_brand_ids, number, sort, sort_rules } = form.value;
const params = {
goods_keywords: '',
goods_category_ids: goods_category_ids,
goods_brand_ids: goods_brand_ids,
goods_order_by_type: sort,
goods_order_by_rule: sort_rules,
goods_number: number
}
//
ShopAPI.getShopLists(params).then((res: any) => {
if (!isEmpty(res.data)) {
list.value = res.data;
} else {
list.value = Array(4).fill(default_list);
}
});
};
//
const content_radius = computed(() => radius_computer(new_style.value.shop_radius));
//
@ -187,21 +262,21 @@ const is_show = (index: string) => {
}
//
const button_size = computed(() => {
let button_size = '27px';
let button_size = '22px';
if (form.value.shop_button_size == '0') {
button_size = '32px';
button_size = '27px';
} else if (form.value.shop_button_size == '2') {
button_size = '22px';
button_size = '18px';
}
return button_size;
})
// icon
const shop_icon_size = computed(() => {
let size = '10';
let size = '8';
if (form.value.shop_button_size == '0') {
size = '20';
size = '15';
} else if (form.value.shop_button_size == '1') {
size = '15';
size = '10';
}
return size;
})
@ -244,11 +319,18 @@ const style_container = computed(() => {
.identifying {
font-size: 0.9rem;
}
.original-price {
.original-price-left {
width: 1rem;
background-image: url('/src/assets/images/components/model-shop-list/price.png');
background-size: 100% 100%;
background-repeat: no-repeat;
padding: 0 1.5rem;
}
.original-price {
background-color: #EDE2C5;
border-radius: 0;
border-bottom-right-radius: 1rem;
border-top-right-radius: 1rem;
padding: 0 1rem 0 0;
}
.shopping_button {
height: v-bind(button_size);
@ -278,7 +360,7 @@ const style_container = computed(() => {
min-width: v-bind(multicolumn_columns);
}
.flex-img0 {
height: 11rem;
height: auto;
width: 11rem;
}
.flex-img1 {
@ -294,7 +376,7 @@ const style_container = computed(() => {
height: 11.4rem;
}
.flex-img4 {
width: 7rem;
width: 100%;
height: 7rem;
}
.flex-img5 {

View File

@ -4,7 +4,7 @@
<card-container class="mb-8">
<div class="mb-12">列表设置</div>
<el-form-item label="选择风格">
<el-radio-group v-model="form.product_style">
<el-radio-group v-model="form.product_style" @change="change_style">
<el-radio v-for="item in base_list.product_style_list" :key="item.value" :value="item.value">{{ item.name }}</el-radio>
</el-radio-group>
</el-form-item>
@ -34,22 +34,22 @@
</div>
</template>
</drag>
<el-button class="mtb-20 w" @click="add">+</el-button>
<el-button class="mt-20 w" @click="add">+</el-button>
</div>
</template>
<template v-else>
<el-form-item label="商品分类">
<el-select v-model="form.product_type" multiple collapse-tags placeholder="请选择文章分类">
<el-option v-for="item in base_list.product_type_list" :key="item.value" :label="item.name" :value="item.value" />
<el-select v-model="form.goods_category_ids" multiple collapse-tags placeholder="请选择商品分类">
<el-option v-for="item in base_list.product_category_list" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="指定品牌">
<el-select v-model="form.product_type" multiple collapse-tags placeholder="请选择文章分类">
<el-option v-for="item in base_list.product_type_list" :key="item.value" :label="item.name" :value="item.value" />
<el-select v-model="form.goods_brand_ids" multiple collapse-tags placeholder="请选择品牌">
<el-option v-for="item in base_list.product_brand_list" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="显示数量">
<el-input v-model="form.number" placeholder="请输入显示数量" clearable />
<el-input-number v-model="form.number" :min="1" :max="100" type="number" placeholder="请输入显示数量" value-on-clear="min" class="w" controls-position="right"></el-input-number>
</el-form-item>
<el-form-item label="排序类型">
<el-radio-group v-model="form.sort">
@ -72,6 +72,13 @@
<script setup lang="ts">
import { get_math } from '@/utils';
import ShopAPI from '@/api/shop';
import { ShopStore } from '@/store';
const shop_store = ShopStore();
interface shop_list {
id: number;
name: string;
};
const props = defineProps({
value: {
type: Object,
@ -97,11 +104,8 @@ const base_list = {
{ name: '指定商品', value: '0' },
{ name: '筛选商品', value: '1' },
],
product_type_list: [
{ name: '样式一', value: '0' },
{ name: '样式二', value: '1' },
{ name: '样式三', value: '2' },
],
product_category_list: [] as shop_list[],
product_brand_list: [] as shop_list[],
sort_list: [
{ name: '综合', value: '0' },
{ name: '销量', value: '1' },
@ -115,9 +119,24 @@ const base_list = {
]
};
// onBeforeMount(() => {
// ShopAPI
// });
onBeforeMount(() => {
if (!shop_store.is_shop_api) {
shop_store.set_is_shop_api(true);
init();
} else {
base_list.product_category_list = shop_store.category_list;
base_list.product_brand_list = shop_store.brand_list;
}
});
const init = () => {
ShopAPI.getShop().then((res) => {
const { goods_category, brand_list } = res.data;
base_list.product_category_list = goods_category;
base_list.product_brand_list = brand_list;
shop_store.set_category_brand(goods_category, brand_list);
});
};
const product_list_remove = (index: number) => {
form.value.product_list.splice(index, 1);
@ -134,6 +153,12 @@ const add = () => {
const product_list_sort = (new_list: any) => {
form.value.product_list = new_list;
}
const change_style = (val: any):void => {
form.value.product_style = val;
if (['3', '4', '5'].includes(val) && ['0', '1'].includes(form.value.shop_type)) {
form.value.shop_type = '2';
}
};
</script>
<style lang="scss" scoped>
.content {
@ -145,7 +170,7 @@ const product_list_sort = (new_list: any) => {
}
}
}
.card {
.card, .card.mb-8 {
.el-form-item:last-child {
margin-bottom: 0;
}

View File

@ -3,8 +3,10 @@ interface DefaultProductList {
content: {
product_style: string;
product_check: string;
product_type: string[];
goods_category_ids: string[];
goods_brand_ids: string[];
product_list: [];
is_price_solo: boolean;
number: number;
sort: string;
sort_rules: string;
@ -45,7 +47,9 @@ const defaultProductList: DefaultProductList = {
product_style: '0',
product_check: '0',
product_list: [],
product_type: [],
goods_category_ids: [],
goods_brand_ids: [],
is_price_solo: true,
number: 4,
sort: '0',
sort_rules: '0',

View File

@ -20,7 +20,7 @@ import defaultImgMagic from './default/img-magic';
import defaultHotZone from './default/hot-zone';
import defaultCustom from './default/custom';
import defaultDataMagic from './default/data-magic';
import { de } from 'element-plus/es/locale';
// 系统设置
interface DefaultSettings {
header_nav: object;

View File

@ -9,5 +9,6 @@ export function setupStore(app: App<Element>) {
}
export * from './modules/footer-nav-content';
export * from './modules/upload';
export * from './modules/shop';
export * from './modules/url-value';
export { store };

View File

@ -2,19 +2,20 @@ import { ref } from 'vue';
import { defineStore } from 'pinia';
export const ShopStore = defineStore('shop', () => {
interface product_list {
id: number;
name: string;
};
// 上传是否需要调接口判断
const is_shop_api = ref(false);
// 上传分类列表
const category = ref<any[]>([]);
// 上传分类列表
const brand = ref<any[]>([]);
const category_list = ref<product_list[]>([]);
// 上传品牌列表
const brand_list = ref<product_list[]>([]);
// 存储上传分类列表
const set_category = (data: any[]) => {
category.value = data;
is_shop_api.value = true;
};
const set_brand = (data: any[]) => {
brand.value = data;
const set_category_brand = (category: product_list[], brand: product_list[]) => {
category_list.value = category;
brand_list.value = brand;
is_shop_api.value = true;
};
// 如果为false 则转为true
@ -23,10 +24,10 @@ export const ShopStore = defineStore('shop', () => {
};
return {
category,
category_list,
brand_list,
is_shop_api,
set_category,
set_brand,
set_category_brand,
set_is_shop_api,
};
});