1.文章、商品、数据魔方

指定数据 支持单条替换数据
v1.0.0
sws 2024-10-15 17:32:51 +08:00
parent efd3850d73
commit 77d6c4a393
14 changed files with 228 additions and 460 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -5,6 +5,34 @@
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "42124616",
"name": "删除",
"font_class": "delete-o",
"unicode": "e7a3",
"unicode_decimal": 59299
},
{
"icon_id": "42124615",
"name": "更多",
"font_class": "more-o",
"unicode": "e7a4",
"unicode_decimal": 59300
},
{
"icon_id": "42116249",
"name": "标签",
"font_class": "label",
"unicode": "e79f",
"unicode_decimal": 59295
},
{
"icon_id": "42116244",
"name": "热门",
"font_class": "fire",
"unicode": "e7a2",
"unicode_decimal": 59298
},
{
"icon_id": "42105733",
"name": "置顶",
@ -903,43 +931,43 @@
},
{
"icon_id": "37539354",
"name": "bowenxiangqing-dianzan-xuaz",
"font_class": "bowenxiangqing-dianzan-xuaz",
"name": "点赞",
"font_class": "givealike",
"unicode": "e6dd",
"unicode_decimal": 59101
},
{
"icon_id": "37538544",
"name": "bowenxiangqing-fenxiang",
"font_class": "bowenxiangqing-fenxiang",
"name": "分享",
"font_class": "share",
"unicode": "e6dc",
"unicode_decimal": 59100
},
{
"icon_id": "37538541",
"name": "bowenxiangqing-huifu",
"font_class": "bowenxiangqing-huifu",
"name": "消息-方正",
"font_class": "message-square",
"unicode": "e6ce",
"unicode_decimal": 59086
},
{
"icon_id": "37538540",
"name": "bowenxiangqing-dianzan",
"font_class": "bowenxiangqing-dianzan",
"name": "点赞-空心",
"font_class": "givealike-o",
"unicode": "e6da",
"unicode_decimal": 59098
},
{
"icon_id": "37494984",
"name": "wodeqianbao-eyeclo2",
"font_class": "wodeqianbao-eyeclo2",
"name": "眼睛-半个",
"font_class": "eye-half",
"unicode": "e6db",
"unicode_decimal": 59099
},
{
"icon_id": "37482928",
"name": "zuhedap-shoping",
"font_class": "zuhedap-shoping",
"name": "购物车+",
"font_class": "cart-add",
"unicode": "e6d9",
"unicode_decimal": 59097
},

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -4,9 +4,18 @@
<li v-for="(item, index) in from" :key="index" :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="isShowEdit" class="iconfont icon-commodity-edit size-16 cr-primary do-not-trigger two-click" @click.stop="edit(index)" />
<el-icon v-if="type == 'line'" class="iconfont icon-del-o size-16 do-not-trigger" @click.stop="remove(index)" />
<el-icon v-if="type == 'card'" class="iconfont icon-close-o1 size-16 abs cr-c top-de-5 right-de-5" @click.stop="remove(index)" />
<el-icon v-if="type == 'line'" class="iconfont icon-delete-o size-16 do-not-trigger cr-6" @click.stop="remove(index)" />
<!-- <el-icon v-if="isShowEdit" class="iconfont size-16 cr-primary do-not-trigger two-click" @click.stop="edit(index)" /> -->
<el-dropdown v-if="isShowEdit" placement="bottom">
<icon name="more-o" size="16" class="icon-commodity-edit" color="primary"></icon>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click.stop="edit(index)">编辑</el-dropdown-item>
<el-dropdown-item @click.stop="replace(index)">替换</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</li>
</TransitionGroup>
</VueDraggable>
@ -14,7 +23,7 @@
<script setup lang="ts">
import { VueDraggable } from 'vue-draggable-plus';
const emits = defineEmits(['click', 'remove', 'edit', 'onSort']);
const emits = defineEmits(['click', 'remove', 'edit', 'onSort', 'replace']);
interface Props {
data: any; //
@ -55,12 +64,18 @@ const on_click = (item: any, index: number) => {
emits('click', item, index);
};
//
const remove = (index: number) => {
emits('remove', index);
};
//
const edit = (index: number) => {
emits('edit', index);
};
//
const replace = (index: number) => {
emits('replace', index);
};
//
const on_sort = () => {
emits('onSort', from.value);

View File

@ -1,5 +1,5 @@
<template>
<drag :data="drag_list" :space-col="20" :is-show-edit="true" @remove="remove" @on-sort="on_sort" @edit="edit">
<drag :data="drag_list" :space-col="20" :is-show-edit="true" @remove="remove" @on-sort="on_sort" @edit="edit" @replace="replace">
<template #default="{ row, index }">
<upload v-model="row.new_cover" :limit="1" size="40" styles="2"></upload>
<el-image :src="row.data[imgParams]" fit="contain" class="img">
@ -52,7 +52,7 @@ const outerClick = (e: any) => {
edit_index.value = -1;
}
};
const emits = defineEmits(['remove', 'onsort']);
const emits = defineEmits(['remove', 'onsort', 'replace']);
const remove = (index: number) => {
if (edit_index.value === index) {
edit_close_processing(index);
@ -91,6 +91,11 @@ const edit_close_processing = (index: number) => {
list.new_title = '';
}
};
//
const replace = (index: number) => {
emits('replace', index);
};
</script>
<style lang="scss" scoped>
.img {

View File

@ -24,7 +24,7 @@
</el-form-item>
<template v-if="form.data_type === '0'">
<div class="nav-list">
<drag-group :list="form.data_list" img-params="cover" @onsort="data_list_sort" @remove="data_list_remove"></drag-group>
<drag-group :list="form.data_list" img-params="cover" @onsort="data_list_sort" @remove="data_list_remove" @replace="data_list_replace"></drag-group>
<el-button class="mtb-20 w" @click="add">+</el-button>
</div>
</template>
@ -62,7 +62,7 @@
</el-form-item>
</card-container>
</el-form>
<url-value-dialog v-model:dialog-visible="url_value_dialog_visible" :type="['article']" multiple @update:model-value="url_value_dialog_call_back"></url-value-dialog>
<url-value-dialog v-model:dialog-visible="url_value_dialog_visible" :type="['article']" :multiple="url_value_multiple_bool" @update:model-value="url_value_dialog_call_back"></url-value-dialog>
</div>
</template>
<script setup lang="ts">
@ -159,27 +159,43 @@ const theme_change = (val: any) => {
}
}
};
const data_list_remove = (index: number) => {
form.value.data_list.splice(index, 1);
};
const url_value_multiple_bool = ref(true);
const data_list_replace_index = ref(0);
const data_list_replace = (index: number) => {
data_list_replace_index.value = index;
url_value_multiple_bool.value = false;
url_value_dialog_visible.value = true;
};
const data_list_sort = (item: any) => {
form.value.data_list = item;
};
const add = () => {
url_value_multiple_bool.value = true;
url_value_dialog_visible.value = true;
};
//
const url_value_dialog_visible = ref(false);
const url_value_dialog_call_back = (item: any[]) => {
item.forEach((child: any) => {
form.value.data_list.push({
if (url_value_multiple_bool.value) {
item.forEach((child: any) => {
form.value.data_list.push({
id: get_math(),
new_title: '',
new_cover: [],
data: child,
});
});
} else {
form.value.data_list[data_list_replace_index.value] = {
id: get_math(),
new_title: '',
new_cover: [],
data: child,
});
});
data: item[0],
};
}
};
</script>
<style lang="scss" scoped>

View File

@ -48,7 +48,7 @@
</el-form-item>
<template v-if="row.data_type === '0'">
<div class="nav-list">
<drag-group :list="row.data_list" img-params="cover" @onsort="data_list_sort($event, index)" @remove="data_list_remove($event, index)"></drag-group>
<drag-group :list="row.data_list" img-params="cover" @onsort="data_list_sort($event, index)" @remove="data_list_remove($event, index)" @replace="data_list_replace"></drag-group>
<el-button class="mtb-20 w" @click="article_add(index)">+</el-button>
</div>
</template>
@ -92,7 +92,7 @@
</el-form-item>
</card-container>
</el-form>
<url-value-dialog v-model:dialog-visible="url_value_dialog_visible" :type="['article']" multiple @update:model-value="url_value_dialog_call_back"></url-value-dialog>
<url-value-dialog v-model:dialog-visible="url_value_dialog_visible" :type="['article']" :multiple="url_value_multiple_bool" @update:model-value="url_value_dialog_call_back"></url-value-dialog>
</div>
</template>
<script setup lang="ts">
@ -214,6 +214,7 @@ const tabs_list_sort = (item: any) => {
//
form.tabs_list = item;
};
const tabs_add = () => {
form.tabs_list.push({
id: get_math(),
@ -238,21 +239,39 @@ const data_list_sort = (item: any, index: number) => {
form.tabs_list[index].data_list = item;
};
const url_value_multiple_bool = ref(true);
const data_list_replace_index = ref(0);
const data_list_replace = (index: number) => {
data_list_replace_index.value = index;
url_value_multiple_bool.value = false;
url_value_dialog_visible.value = true;
};
const article_index = ref(0);
const article_add = (index: number) => {
url_value_multiple_bool.value = true;
url_value_dialog_visible.value = true;
article_index.value = index;
};
const url_value_dialog_call_back = (item: any[]) => {
// console.log(item);
item.forEach((child: any) => {
form.tabs_list[article_index.value].data_list.push({
if (url_value_multiple_bool.value) {
// console.log(item);
item.forEach((child: any) => {
form.tabs_list[article_index.value].data_list.push({
id: get_math(),
new_title: '',
new_cover: [],
data: child,
});
});
} else {
form.tabs_list[article_index.value].data_list[data_list_replace_index.value] = {
id: get_math(),
new_title: '',
new_cover: [],
data: child,
});
});
data: item[0],
};
}
};
const styles = reactive(props.tabStyle);
@ -264,7 +283,7 @@ watchEffect(() => {
if (is_immersion_model.value) {
form.tabs_top_up = '0';
}
})
});
</script>
<style lang="scss" scoped>
.content {

View File

@ -26,7 +26,7 @@
</card-container>
<template v-if="form.data_type == 'images'">
<div class="bg-f5 divider-line" />
<card-container >
<card-container>
<div class="mb-12">图片设置</div>
<div class="flex-col gap-20">
<div v-for="(item, index) in form.images_list" :key="index" class="card-background box-shadow-sm re">
@ -48,14 +48,14 @@
<div class="bg-f5 divider-line" />
<card-container>
<div class="mb-12">商品设置</div>
<drag-group :list="form.goods_list" img-params="images" @onsort="goods_list_sort" @remove="goods_list_remove"></drag-group>
<drag-group :list="form.goods_list" img-params="images" @onsort="goods_list_sort" @remove="goods_list_remove" @replace="goods_list_replace"></drag-group>
<el-button class="mtb-20 w" @click="goods_list_add">+</el-button>
<el-form-item label="展示信息" label-width="60">
<el-checkbox-group v-model="form.is_show">
<el-checkbox v-for="item in list_show_list" :key="item.value" :value="item.value">{{ item.name }}</el-checkbox>
</el-checkbox-group>
</el-form-item>
<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>
<url-value-dialog v-model:dialog-visible="url_value_dialog_visible" :type="['goods']" :multiple="url_value_multiple_bool" @update:model-value="url_value_dialog_call_back"></url-value-dialog>
</card-container>
</template>
</template>
@ -71,10 +71,14 @@ const props = defineProps({
isShowTitle: {
type: Boolean,
default: true,
}
},
});
const list_show_list = [{ name: '商品名称', value: 'title' }, { name: '商品售价', value: 'price' }, { name: '售价单位', value: 'price_unit' }];
const list_show_list = [
{ name: '商品名称', value: 'title' },
{ name: '商品售价', value: 'price' },
{ name: '售价单位', value: 'price_unit' },
];
const form = ref(props.value);
@ -83,37 +87,54 @@ const img_add = () => {
carousel_img: [],
carousel_link: {},
});
}
};
const img_remove = (index: number) => {
form.value.images_list.splice(index, 1);
}
};
const goods_list_remove = (index: number) => {
form.value.goods_list.splice(index, 1);
};
//
const goods_list_sort = (new_list: any) => {
form.value.goods_list = cloneDeep(new_list);
}
};
const url_value_multiple_bool = ref(true);
const data_list_replace_index = ref(0);
const goods_list_replace = (index: number) => {
data_list_replace_index.value = index;
url_value_multiple_bool.value = false;
url_value_dialog_visible.value = true;
};
watchEffect(() => {
form.value = props.value;
});
const goods_list_add = () => {
url_value_multiple_bool.value = true;
url_value_dialog_visible.value = true;
};
//
const url_value_dialog_visible = ref(false);
//
const url_value_dialog_call_back = (item: any[]) => {
item.forEach((item: any) => {
form.value.goods_list.push({
if (url_value_multiple_bool.value) {
item.forEach((item: any) => {
form.value.goods_list.push({
id: get_math(),
new_cover: [],
new_title: '',
data: item,
});
});
} else {
form.value.goods_list[data_list_replace_index.value] = {
id: get_math(),
new_cover: [],
new_title: '',
data: item,
});
});
data: item[0],
};
}
};
</script>
<style lang="scss" scoped>
@ -133,7 +154,7 @@ const url_value_dialog_call_back = (item: any[]) => {
width: 100%;
height: 12.4rem;
}
:deep(.el-checkbox-group .el-checkbox){
:deep(.el-checkbox-group .el-checkbox) {
margin-right: 2rem;
}
</style>

View File

@ -27,7 +27,7 @@
</el-form-item>
<template v-if="form.data_type === '0'">
<div class="nav-list">
<drag-group :list="form.data_list" img-params="images" @onsort="goods_list_sort" @remove="goods_list_remove"></drag-group>
<drag-group :list="form.data_list" img-params="images" @onsort="goods_list_sort" @remove="goods_list_remove" @replace="data_list_replace"></drag-group>
<el-button class="mt-20 w" @click="add">+</el-button>
</div>
</template>
@ -60,7 +60,7 @@
<div class="divider-line"></div>
<!-- 商品显示的配置信息 -->
<product-show-config :value="form" @change_shop_type="change_shop_type"></product-show-config>
<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>
<url-value-dialog v-model:dialog-visible="url_value_dialog_visible" :type="['goods']" :multiple="url_value_multiple_bool" @update:model-value="url_value_dialog_call_back"></url-value-dialog>
</el-form>
</div>
</template>
@ -139,21 +139,38 @@ onBeforeMount(() => {
const goods_list_remove = (index: number) => {
form.value.data_list.splice(index, 1);
};
const url_value_multiple_bool = ref(true);
const data_list_replace_index = ref(0);
const data_list_replace = (index: number) => {
data_list_replace_index.value = index;
url_value_multiple_bool.value = false;
url_value_dialog_visible.value = true;
};
const add = () => {
url_value_multiple_bool.value = true;
url_value_dialog_visible.value = true;
};
//
const url_value_dialog_visible = ref(false);
//
const url_value_dialog_call_back = (item: any[]) => {
item.forEach((item: any) => {
form.value.data_list.push({
if (url_value_multiple_bool.value) {
item.forEach((item: any) => {
form.value.data_list.push({
id: get_math(),
new_cover: [],
new_title: '',
data: item,
});
});
} else {
form.value.data_list[data_list_replace_index.value] = {
id: get_math(),
new_cover: [],
new_title: '',
data: item,
});
});
data: item[0],
};
}
};
//
const goods_list_sort = (new_list: any) => {

View File

@ -5,7 +5,7 @@
<div class="mb-12">展示设置</div>
<el-form-item label="选项卡置顶">
<div class="flex-row align-c gap-10">
<el-switch v-model="form.tabs_top_up" active-value="1" inactive-value="0" :disabled="is_immersion_model"/>
<el-switch v-model="form.tabs_top_up" active-value="1" inactive-value="0" :disabled="is_immersion_model" />
<el-tooltip effect="dark" :show-after="200" :hide-after="200" content="<span>开启沉浸样式时,选项卡置顶功能禁用</span>" raw-content placement="top">
<icon name="miaosha-hdgz" size="12" color="#999"></icon>
</el-tooltip>
@ -54,7 +54,7 @@
</el-form-item>
<template v-if="row.data_type === '0'">
<div class="nav-list">
<drag-group :list="row.data_list" img-params="images" @onsort="goods_list_sort($event, index)" @remove="goods_list_remove($event, index)"></drag-group>
<drag-group :list="row.data_list" img-params="images" @onsort="goods_list_sort($event, index)" @remove="goods_list_remove($event, index)" @replace="data_list_replace"></drag-group>
<el-button class="mtb-20 w" @click="product_add(index)">+</el-button>
</div>
</template>
@ -93,7 +93,7 @@
<div class="divider-line"></div>
<!-- 商品显示的配置信息 -->
<product-show-config :value="form" @change_shop_type="change_shop_type"></product-show-config>
<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>
<url-value-dialog v-model:dialog-visible="url_value_dialog_visible" :type="['goods']" :multiple="url_value_multiple_bool" @update:model-value="url_value_dialog_call_back"></url-value-dialog>
</el-form>
</div>
</template>
@ -223,8 +223,17 @@ const goods_list_sort = (item: any, index: number) => {
form.value.tabs_list[index].data_list = item;
};
let click_index = 0;
const url_value_multiple_bool = ref(true);
const data_list_replace_index = ref(0);
const data_list_replace = (index: number) => {
data_list_replace_index.value = index;
url_value_multiple_bool.value = false;
url_value_dialog_visible.value = true;
};
const product_add = (index: number) => {
click_index = index;
url_value_multiple_bool.value = true;
url_value_dialog_visible.value = true;
};
@ -232,14 +241,23 @@ const product_add = (index: number) => {
const url_value_dialog_visible = ref(false);
//
const url_value_dialog_call_back = (item: any[]) => {
item.forEach((item: any) => {
form.value.tabs_list[click_index].data_list.push({
if (url_value_multiple_bool.value) {
item.forEach((item: any) => {
form.value.tabs_list[click_index].data_list.push({
id: get_math(),
new_cover: [],
new_title: '',
data: item,
});
});
} else {
form.value.tabs_list[click_index].data_list[data_list_replace_index.value] = {
id: get_math(),
new_cover: [],
new_title: '',
data: item,
});
});
data: item[0],
};
}
};
const tabs_theme_change = (val: string | number | boolean | undefined): void => {
@ -282,7 +300,7 @@ watchEffect(() => {
if (is_immersion_model.value) {
form.value.tabs_top_up = '0';
}
})
});
</script>
<style lang="scss" scoped>
.content {