商品添加封装成组件
parent
151a7799df
commit
9f0b2e28bf
|
|
@ -4,7 +4,8 @@
|
|||
<li v-for="(item, index) in from" :key="item.id" :class="className" class="flex gap-y-16 re" @click="on_click(item, index)">
|
||||
<el-icon class="iconfont icon-drag size-16 cursor-move" />
|
||||
<slot :row="item" :index="index" />
|
||||
<el-icon v-if="type == 'line'" class="iconfont icon-del-o size-16" @click="remove(index)" />
|
||||
<el-icon v-if="isShowEdit" class="iconfont icon-commodity-edit size-16 cr-primary do-not-trigger two-click" @click="edit(index)" />
|
||||
<el-icon v-if="type == 'line'" class="iconfont icon-del-o size-16 do-not-trigger" @click="remove(index)" />
|
||||
<el-icon v-if="type == 'card'" class="iconfont icon-close-o size-16 abs cr-c top-de-5 right-de-5" @click="remove(index)" />
|
||||
</li>
|
||||
</TransitionGroup>
|
||||
|
|
@ -13,16 +14,18 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import { VueDraggable } from 'vue-draggable-plus';
|
||||
const emits = defineEmits(['click', 'remove', 'onSort']);
|
||||
const emits = defineEmits(['click', 'remove', 'edit', 'onSort']);
|
||||
|
||||
interface Props {
|
||||
data: any; // 拖拽列表数据
|
||||
type?: string; // card: 卡片区域 line: 一行
|
||||
spaceCol?: number; // 上下间距
|
||||
iconPosition?: string; // top/bottom/center
|
||||
isShowEdit?: boolean;
|
||||
}
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
type: () => 'line',
|
||||
isShowEdit: false,
|
||||
spaceCol: () => 5,
|
||||
iconPosition: 'center',
|
||||
});
|
||||
|
|
@ -42,7 +45,6 @@ if (props.type == 'card') {
|
|||
}
|
||||
|
||||
const from = ref(props.data);
|
||||
|
||||
const on_click = (item: any, index: number) => {
|
||||
emits('click', item, index);
|
||||
};
|
||||
|
|
@ -50,6 +52,9 @@ const on_click = (item: any, index: number) => {
|
|||
const remove = (index: number) => {
|
||||
emits('remove', index);
|
||||
};
|
||||
const edit = (index: number) => {
|
||||
emits('edit', index);
|
||||
};
|
||||
// 拖拽更新之后用户更新数据
|
||||
const on_sort = () => {
|
||||
emits('onSort', from);
|
||||
|
|
@ -64,7 +69,7 @@ const on_sort = () => {
|
|||
.size-16 {
|
||||
font-size: 1.6rem !important;
|
||||
}
|
||||
.icon-del-o {
|
||||
.icon-del-o, .icon-commodity-edit {
|
||||
cursor: pointer;
|
||||
}
|
||||
.cursor-move {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
<template>
|
||||
<drag :data="drag_list" :space-col="20" :is-show-edit="true" @remove="remove" @on-sort="on_sort" @edit="edit">
|
||||
<template #default="{ row, index }">
|
||||
<upload v-model="row.new_url" :limit="1" size="40" styles="2"></upload>
|
||||
<el-image :src="row.link[imgParams]" fit="contain" class="img">
|
||||
<template #error>
|
||||
<div class="bg-f5 flex-row jc-c align-c radius h w">
|
||||
<icon name="error-img" size="16" color="9"></icon>
|
||||
</div>
|
||||
</template>
|
||||
</el-image>
|
||||
<template v-if="index === edit_index">
|
||||
<el-input v-model="row.new_title" placeholder="请输入链接" type="textarea" class="flex-1 do-not-trigger" :rows="2"></el-input>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="flex-1 flex-width text-line-2 size-12 self-s">{{ row.new_title }}</div>
|
||||
</template>
|
||||
</template>
|
||||
</drag>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
interface Props {
|
||||
list: any[];
|
||||
imgParams: string;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
imgParams: 'cover',
|
||||
isouterClick: false,
|
||||
});
|
||||
|
||||
const drag_list = ref(props.list);
|
||||
watchEffect(() => {
|
||||
drag_list.value = props.list;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
// 监听点击事件
|
||||
document.addEventListener('click', outerClick);
|
||||
});
|
||||
onUnmounted(() => {
|
||||
// 移除监听事件
|
||||
document.removeEventListener('click', outerClick);
|
||||
});
|
||||
const edit_index = ref(-1);
|
||||
// 判断点击的是否是可以点击的区域,其他区域隐藏掉编辑属性
|
||||
const outerClick = (e: any) => {
|
||||
if (!e.target.className.includes('do-not-trigger') && !e.target.parentNode.className.includes('do-not-trigger')) {
|
||||
edit_index.value = -1;
|
||||
}
|
||||
};
|
||||
const emits = defineEmits(['remove', 'onsort']);
|
||||
const remove = (index: number) => {
|
||||
if (edit_index.value === index) {
|
||||
edit_index.value = -1;
|
||||
}
|
||||
emits('remove', index);
|
||||
}
|
||||
const on_sort = (item: any) => {
|
||||
emits('onsort', item);
|
||||
}
|
||||
const edit = (index: number) => {
|
||||
if (edit_index.value === index) {
|
||||
edit_index.value = -1;
|
||||
} else {
|
||||
edit_index.value = index;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.img {
|
||||
width: 4rem;
|
||||
height: 4rem;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -14,27 +14,35 @@
|
|||
</el-menu>
|
||||
</div>
|
||||
<div class="right-content flex-1">
|
||||
<!-- 商城链接/插件 -->
|
||||
<template v-if="link_select == 'shop' || link_select == 'plugins'">
|
||||
<link-list :key="link_select" v-model="link_value" :type="link_select" :reset="reset_compontent"></link-list>
|
||||
</template>
|
||||
<!-- 商品分类 -->
|
||||
<template v-else-if="link_select == 'goods-category'">
|
||||
<link-goods-category v-model="link_value" :reset="reset_compontent"></link-goods-category>
|
||||
</template>
|
||||
<!-- 商品搜索 -->
|
||||
<template v-else-if="link_select == 'goods-search'">
|
||||
<link-goods-search :reset="reset_compontent" :status="component_status" @update:link="goods_category_link" @type="goods_category_type_change"></link-goods-search>
|
||||
</template>
|
||||
<!-- 商品页面 -->
|
||||
<template v-else-if="link_select == 'goods'">
|
||||
<link-goods v-model="link_value" :multiple="multiple" :reset="reset_compontent"></link-goods>
|
||||
</template>
|
||||
<!-- 文章页面 -->
|
||||
<template v-else-if="link_select == 'article'">
|
||||
<link-articles v-model="link_value" :multiple="multiple" :reset="reset_compontent"></link-articles>
|
||||
</template>
|
||||
<!-- diy页面/页面设计/自定义页面 -->
|
||||
<template v-else-if="link_select == 'diy' || link_select == 'design' || link_select == 'custom-view'">
|
||||
<link-table :key="link_select" v-model="link_value" :multiple="multiple" :type="link_select" :reset="reset_compontent"></link-table>
|
||||
</template>
|
||||
<!-- 品牌 -->
|
||||
<template v-else-if="link_select == 'brand'">
|
||||
<link-brand v-model="link_value" :multiple="multiple" :reset="reset_compontent"></link-brand>
|
||||
</template>
|
||||
<!-- 自定义链接 -->
|
||||
<template v-else-if="link_select == 'custom-url'">
|
||||
<link-custom :reset="reset_compontent" :status="component_status" @update:link="custom_link"></link-custom>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
</template>
|
||||
<template v-else>
|
||||
<template v-if="!isEmpty(item)">
|
||||
<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 v-if="!isEmpty(item.new_url)">
|
||||
<image-empty v-model="item.new_url[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>
|
||||
|
|
@ -85,7 +85,7 @@
|
|||
</template>
|
||||
<script setup lang="ts">
|
||||
import { common_styles_computer, gradient_handle, padding_computer, radius_computer } from '@/utils';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { isEmpty, cloneDeep } from 'lodash';
|
||||
import ShopAPI from '@/api/shop';
|
||||
|
||||
const props = defineProps({
|
||||
|
|
@ -112,7 +112,7 @@ const { form, new_style } = toRefs(state);
|
|||
interface product_list {
|
||||
title: string;
|
||||
images: string;
|
||||
new_src: string[];
|
||||
new_url: string[];
|
||||
min_original_price: string;
|
||||
show_original_price_symbol: string;
|
||||
show_original_price_unit: string;
|
||||
|
|
@ -130,7 +130,7 @@ const default_list = {
|
|||
show_price_unit: "",
|
||||
sales_count: "1000",
|
||||
images: '',
|
||||
new_src: []
|
||||
new_url: []
|
||||
}
|
||||
const list = ref<product_list[]>([]);
|
||||
const get_products = () => {
|
||||
|
|
@ -155,7 +155,11 @@ const get_products = () => {
|
|||
watchEffect(() => {
|
||||
if (form.value.product_check == '0') {
|
||||
if (!isEmpty(form.value.product_list)) {
|
||||
list.value = form.value.product_list;
|
||||
list.value = cloneDeep(form.value.product_list).map((item: any) => ({
|
||||
...item.link,
|
||||
title: item.new_title,
|
||||
new_url: item.new_url,
|
||||
}));
|
||||
} else {
|
||||
list.value = Array(4).fill(default_list);
|
||||
}
|
||||
|
|
@ -356,6 +360,7 @@ const style_container = computed(() => {
|
|||
}
|
||||
.flex-img0 {
|
||||
height: auto;
|
||||
max-height: 12rem;
|
||||
width: 11rem;
|
||||
}
|
||||
.flex-img1 {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
</el-form-item>
|
||||
</card-container>
|
||||
<div class="content-height bg-f">
|
||||
<card-container class="card-container-br">
|
||||
<card-container class="card-container-br" @click="card_click">
|
||||
<div class="mb-12">商品设置</div>
|
||||
<el-form-item label="添加商品">
|
||||
<el-radio-group v-model="form.product_check">
|
||||
|
|
@ -19,21 +19,7 @@
|
|||
</el-form-item>
|
||||
<template v-if="form.product_check === '0'">
|
||||
<div class="nav-list">
|
||||
<drag :data="form.product_list" :space-col="20" @remove="product_list_remove" @on-sort="product_list_sort">
|
||||
<template #default="{ row }">
|
||||
<upload v-model="row.new_src" :limit="1" size="40" styles="2"></upload>
|
||||
<el-image :src="row.url" fit="contain" class="img">
|
||||
<template #error>
|
||||
<div class="bg-f5 flex-row jc-c align-c radius h w">
|
||||
<icon name="error-img" size="16" color="9"></icon>
|
||||
</div>
|
||||
</template>
|
||||
</el-image>
|
||||
<div class="flex-1 flex-width">
|
||||
<url-value v-model="row.href"></url-value>
|
||||
</div>
|
||||
</template>
|
||||
</drag>
|
||||
<dragGroup :list="form.product_list" img-params="images" @onsort="product_list_sort" @remove="product_list_remove"></dragGroup>
|
||||
<el-button class="mt-20 w" @click="add">+添加</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -67,6 +53,7 @@
|
|||
<product-show-config :value="form"></product-show-config>
|
||||
</div>
|
||||
</el-form>
|
||||
<url-value-dialog v-model:dialog-visible="url_value_dialog_visible" :type="['goods']" multiple @update:model-value="url_value_dialog_call_back"></url-value-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
|
|
@ -138,27 +125,38 @@ onBeforeMount(() => {
|
|||
init();
|
||||
});
|
||||
|
||||
const product_list_remove = (index: number) => {
|
||||
form.value.product_list.splice(index, 1);
|
||||
};
|
||||
const add = () => {
|
||||
form.value.product_list.push({
|
||||
id: get_math(),
|
||||
src: 'carousel',
|
||||
new_src: [],
|
||||
href: {},
|
||||
});
|
||||
url_value_dialog_visible.value = true;
|
||||
};
|
||||
// 拖拽更新之后,更新数据
|
||||
const product_list_sort = (new_list: any) => {
|
||||
form.value.product_list = new_list;
|
||||
};
|
||||
// 删除显示
|
||||
const product_list_remove = (index: number) => {
|
||||
form.value.product_list.splice(index, 1);
|
||||
};
|
||||
|
||||
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';
|
||||
}
|
||||
};
|
||||
// 打开弹出框
|
||||
const url_value_dialog_visible = ref(false);
|
||||
// 弹出框选择的内容
|
||||
const url_value_dialog_call_back = (item: any[]) => {
|
||||
item.forEach((item: any) => {
|
||||
form.value.product_list.push({
|
||||
id: get_math(),
|
||||
new_url: [],
|
||||
is_edit: false,
|
||||
new_title: item.title,
|
||||
link: item,
|
||||
});
|
||||
});
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.content {
|
||||
|
|
|
|||
|
|
@ -3,24 +3,6 @@
|
|||
<el-form :model="form" label-width="70">
|
||||
<card-container class="mb-8">
|
||||
<div class="mb-12">商品样式</div>
|
||||
<el-form-item label="内容圆角">
|
||||
<radius :value="form.shop_radius" @update:value="shop_radius_change"></radius>
|
||||
</el-form-item>
|
||||
<el-form-item label="图片圆角">
|
||||
<radius :value="form.shop_img_radius" @update:value="img_radius_change"></radius>
|
||||
</el-form-item>
|
||||
<el-form-item label="内间距">
|
||||
<padding :value="form.shop_padding" @update:value="shop_padding_change"></padding>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="['0', '4'].includes(product_style)" label="内容间距">
|
||||
<slider v-model="form.content_spacing" :max="100"></slider>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品间距">
|
||||
<slider v-model="form.content_outer_spacing" :max="100"></slider>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="product_style == '5'" label="内容宽度">
|
||||
<slider v-model="form.content_outer_width" :max="1000"></slider>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品名称">
|
||||
<text-size-type v-model:typeface="form.shop_title_typeface" v-model:size="form.shop_title_size"></text-size-type>
|
||||
</el-form-item>
|
||||
|
|
@ -45,6 +27,24 @@
|
|||
<el-form-item label="评分颜色">
|
||||
<color-picker v-model="form.shop_score_color" default-color="#000000"></color-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="内容圆角">
|
||||
<radius :value="form.shop_radius" @update:value="shop_radius_change"></radius>
|
||||
</el-form-item>
|
||||
<el-form-item label="图片圆角">
|
||||
<radius :value="form.shop_img_radius" @update:value="img_radius_change"></radius>
|
||||
</el-form-item>
|
||||
<el-form-item label="内间距">
|
||||
<padding :value="form.shop_padding" @update:value="shop_padding_change"></padding>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="['0', '4'].includes(product_style)" label="内容间距">
|
||||
<slider v-model="form.content_spacing" :max="100"></slider>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品间距">
|
||||
<slider v-model="form.content_outer_spacing" :max="100"></slider>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="product_style == '5'" label="内容宽度">
|
||||
<slider v-model="form.content_outer_width" :max="1000"></slider>
|
||||
</el-form-item>
|
||||
</card-container>
|
||||
<card-container class="mb-8">
|
||||
<div class="mb-12">购物车按钮</div>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ interface DefaultProductList {
|
|||
product_check: string;
|
||||
goods_category_ids: string[];
|
||||
goods_brand_ids: string[];
|
||||
product_list: [];
|
||||
product_list: string[];
|
||||
is_price_solo: boolean;
|
||||
number: number;
|
||||
sort: string;
|
||||
|
|
|
|||
|
|
@ -311,5 +311,8 @@ $line: 5;
|
|||
-webkit-line-clamp: #{$i};
|
||||
line-clamp: #{$i}; // 添加标准属性以增加兼容性
|
||||
-webkit-box-orient: vertical;
|
||||
word-break: break-word;
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue