1.文章接口联调

sws 2024-08-21
v1.0.0
sws 2024-08-21 18:28:21 +08:00
parent 151a7799df
commit f549ad2180
12 changed files with 293 additions and 101 deletions

View File

@ -0,0 +1,64 @@
<template>
<div class="flex-col gap-10 w">
<slider v-model="form.margin" @update:model-value="margin_event"></slider>
<div class="flex-row flex-wrap gap-x-20 mt-10">
<div class="flex-width-half pr-10">
<input-number v-model="form.margin_top" icon-name="enter-t" @update:model-value="pt_event"></input-number>
</div>
<div class="flex-width-half pl-10">
<input-number v-model="form.margin_bottom" icon-name="enter-b" @update:model-value="pb_event"></input-number>
</div>
<div class="flex-width-half pr-10">
<input-number v-model="form.margin_left" icon-name="enter-l" @update:model-value="pl_event"></input-number>
</div>
<div class="flex-width-half pl-10">
<input-number v-model="form.margin_right" icon-name="enter-r" @update:model-value="pr_event"></input-number>
</div>
</div>
</div>
</template>
<script setup lang="ts">
const props = defineProps({
value: {
type: Object,
default: () => {},
},
});
//
const state = reactive({
form: props.value || {},
});
// 使toRefs
const { form } = toRefs(state);
const emit = defineEmits(['update:value']);
const margin_event = (val: number | undefined) => {
form.value.margin = Number(val);
form.value.margin_top = Number(val);
form.value.margin_bottom = Number(val);
form.value.margin_left = Number(val);
form.value.margin_right = Number(val);
emit('update:value', form);
};
const pt_event = (val: number | undefined) => {
form.value.margin_top = Number(val);
form.value.margin = 0;
emit('update:value', form);
};
const pb_event = (val: number | undefined) => {
form.value.margin_bottom = Number(val);
form.value.margin = 0;
emit('update:value', form);
};
const pl_event = (val: number | undefined) => {
form.value.margin_left = Number(val);
form.value.margin = 0;
emit('update:value', form);
};
const pr_event = (val: number | undefined) => {
form.value.margin_right = Number(val);
form.value.margin = 0;
emit('update:value', form);
};
</script>

View File

@ -29,23 +29,7 @@
<padding :value="form" @update:value="padding_change"></padding>
</el-form-item>
<el-form-item label="外边距">
<div class="flex-col gap-10 w">
<slider v-model="form.margin" @update:model-value="margin_event"></slider>
<div class="flex-row flex-wrap gap-x-20 mt-10">
<div class="flex-width-half pr-10">
<input-number v-model="form.margin_top" icon-name="out-t" @update:model-value="mt_event"></input-number>
</div>
<div class="flex-width-half pl-10">
<input-number v-model="form.margin_bottom" icon-name="out-b" @update:model-value="mb_event"></input-number>
</div>
<div class="flex-width-half pr-10">
<input-number v-model="form.margin_left" icon-name="out-l" @update:model-value="ml_event"></input-number>
</div>
<div class="flex-width-half pl-10">
<input-number v-model="form.margin_right" icon-name="out-r" @update:model-value="mr_event"></input-number>
</div>
</div>
</div>
<margin :value="form" @update:value="margin_change"></margin>
</el-form-item>
<el-form-item label="圆角">
<radius :value="form" @update:value="radius_change"></radius>
@ -128,39 +112,16 @@ const background_img_url_change = (arry: uploadList[]) => {
form.background_img_url = arry;
emit('update:value', form);
};
const margin_event = (val: number | undefined) => {
form.margin_top = Number(val);
form.margin_bottom = Number(val);
form.margin_left = Number(val);
form.margin_right = Number(val);
emit('update:value', form);
};
const mt_event = (val: number | undefined) => {
form.margin_top = Number(val);
form.margin = 0;
emit('update:value', form);
};
const mb_event = (val: number | undefined) => {
form.margin_bottom = Number(val);
form.margin = 0;
emit('update:value', form);
};
const ml_event = (val: number | undefined) => {
form.margin_left = Number(val);
form.margin = 0;
emit('update:value', form);
};
const mr_event = (val: number | undefined) => {
form.margin_right = Number(val);
form.margin = 0;
emit('update:value', form);
};
const radius_change = (radius: any) => {
form = Object.assign(form, pick(radius, ['radius', 'radius_top_left', 'radius_top_right', 'radius_bottom_left', 'radius_bottom_right']));
emit('update:value', form);
};
const margin_change = (margin: any) => {
form = Object.assign(form, pick(margin, ['margin', 'margin_top', 'margin_bottom', 'margin_left', 'margin_right']));
emit('update:value', form);
};
const padding_change = (padding: any) => {
form = Object.assign(form, pick(padding, ['padding', 'padding_top', 'padding_bottom', 'padding_left', 'padding_right']));
emit('update:value', form);

View File

@ -1,33 +1,30 @@
<template>
<div :style="style_container">
<div class="oh" :style="style_container">
<div class="re" :style="style">
<div class="flex-warp gap-10" :class="article_type == '1' ? 'style1 flex-row' : article_type == '0' ? 'style2 flex-col' : 'style3 flex-col'">
<card-container class="item gap-10" padding="10px" :class="article_type == '0' ? 'flex-row' : 'flex-col'" :style="content_radius">
<img v-if="is_img_show" src="@/assets/images/components/model-video/video.png" />
<div class="flex-col jc-sb gap-8">
<div class="title text-line-2" :style="article_name">华为荣耀畅想平板换屏服务屏幕换外屏幕主板维修华为荣耀畅想平板换屏服务屏幕换外屏幕主板维修华为荣耀畅想平板换屏服务屏幕换外屏幕主板维修华为荣耀畅想平板换屏服务屏幕换外屏幕主板维修华为荣耀畅想平板换屏服务屏幕换外屏幕主板维修</div>
<div class="flex-row jc-sb gap-8">
<div :style="article_date">{{ is_show.includes('0') ? '2020-06-05 15:20' : '' }}</div>
<icon v-show="is_show.includes('1')" name="eye" :style="article_page_view">16</icon>
<div class="flex-warp" :class="article_type_class" :style="article_spacing">
<template v-for="(item, index) in article_list" :key="index">
<div class="item gap-10 bg-f oh" :class="article_type == '0' ? 'flex-row' : 'flex-col'" :style="article_style">
<template v-if="item.new_url.length > 0">
<image-empty v-model="item.new_url[0].url" class="img" :style="img_radius" :error-img-style="error_img"></image-empty>
</template>
<template v-else>
<image-empty v-model="item.link.cover" class="img" :style="img_radius" :error-img-style="error_img"></image-empty>
</template>
<div class="flex-col jc-sb" :style="article_type !== '0' ? content_padding : ''">
<div class="title text-line-2" :style="article_name">{{ item.new_title }}</div>
<div class="flex-row jc-sb gap-8 align-c mt-10">
<div :style="article_date">{{ is_show.includes('0') ? '2020-06-05 15:20' : '' }}</div>
<icon v-show="is_show.includes('1')" name="eye" :style="article_page_view">16</icon>
</div>
</div>
</div>
</card-container>
<card-container class="item gap-10" padding="10px" :class="article_type == '0' ? 'flex-row' : 'flex-col'" :style="content_radius">
<img v-if="is_img_show" src="@/assets/images/components/model-video/video.png" />
<div class="flex-col jc-sb gap-8">
<div class="title text-line-2" :style="article_name">华为荣耀畅想平板换屏服务屏幕换外屏幕主板维修华为荣耀畅想平板换屏服务屏幕换外屏幕主板维修华为荣耀畅想平板换屏服务屏幕换外屏幕主板维修华为荣耀畅想平板换屏服务屏幕换外屏幕主板维修华为荣耀畅想平板换屏服务屏幕换外屏幕主板维修华为荣耀畅想平板换屏服务屏幕换外屏幕主板维修</div>
<div class="flex-row jc-sb gap-8">
<div :style="article_date">{{ is_show.includes('0') ? '2020-06-05 15:20' : '' }}</div>
<icon v-show="is_show.includes('1')" name="eye" :style="article_page_view">16</icon>
</div>
</div>
</card-container>
</template>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { common_styles_computer, radius_computer } from '@/utils';
import { common_styles_computer, gradient_handle, padding_computer, radius_computer } from '@/utils';
const props = defineProps({
value: {
type: Object,
@ -38,8 +35,18 @@ const props = defineProps({
default: true,
},
});
const error_img = ref('width:50px;padding:10px;');
const style = ref('');
const style_container = ref('');
interface ArticleList {
id: number | string;
link: object;
new_title: string;
new_url: uploadList[];
}
const containerRef = ref<HTMLElement | null>(null);
//
const article_list = ref<ArticleList[]>([]);
//
const article_type = ref('0');
//
@ -54,12 +61,26 @@ const article_date = ref('');
const article_page_view = ref('');
//
const content_radius = ref('');
//
const img_radius = ref('');
//
const content_padding = ref('');
//
const content_spacing = ref('');
//
const article_spacing = ref('');
const article_spacing_children = ref('');
const article_item_width = ref('50%');
const article_style = ref({});
watch(
props.value,
(newVal, oldValue) => {
console.log(newVal);
const new_content = newVal?.content;
const new_style = newVal?.style;
//
article_list.value = new_content.article_list;
article_type.value = new_content.article_style;
is_show.value = new_content.is_show;
is_img_show.value = new_content.is_img_show;
@ -67,13 +88,46 @@ watch(
article_name.value = 'font-size:' + new_style.name_size + 'px;' + 'font-weight:' + new_style.name_weight + ';' + 'color:' + new_style.name_color + ';';
article_date.value = 'font-size:' + new_style.time_size + 'px;' + 'font-weight:' + new_style.time_weight + ';' + 'color:' + new_style.time_color + ';';
article_page_view.value = 'font-size:' + new_style.page_view_size + 'px;' + 'font-weight:' + new_style.page_view_weight + ';' + 'color:' + new_style.page_view_color + ';';
content_radius.value = radius_computer(new_style);
content_radius.value = radius_computer(new_style.content_radius);
img_radius.value = radius_computer(new_style.img_radius);
//
content_padding.value = padding_computer(new_style.padding);
//
content_spacing.value = `gap: ${new_style.content_spacing}px;`;
//
article_spacing.value = `gap: ${new_style.article_spacing}px;`;
//
article_style.value = content_radius.value + content_spacing.value;
if (article_type.value == '0') {
article_style.value += content_padding.value;
}
if (article_type.value == '1') {
article_spacing_children.value = `width: calc(50% - ${new_style.article_spacing / 2}px);`;
article_style.value += article_spacing_children.value;
}
if (article_type.value == '3') {
article_item_width.value = `${new_style.article_width}px`;
}
if (new_style.common_style && props.isCommonStyle) {
style_container.value = common_styles_computer(new_style.common_style);
}
},
{ immediate: true, deep: true }
);
const article_type_class = computed(() => {
// article_type == '1' ? '' : article_type == '0' ? '' : ''
switch (article_type.value) {
case '0':
return 'style2 flex-col';
case '1':
return 'style1 flex-row flex-wrap';
case '2':
return 'style3 flex-col';
case '3':
return 'style4 flex-row';
}
return `style${article_type.value}`;
});
</script>
<style lang="scss" scoped>
.style1 {
@ -84,7 +138,7 @@ watch(
.style2 {
.item {
width: 100%;
img {
.img {
width: 11rem;
height: 8.3rem;
}
@ -95,4 +149,9 @@ watch(
width: 100%;
}
}
.style4 {
.item {
min-width: v-bind(article_item_width);
}
}
</style>

View File

@ -13,13 +13,13 @@
<card-container class="card-container-br">
<div class="mb-12">文章设置</div>
<el-form-item label="读取方式">
<el-radio-group v-model="form.article_check">
<el-radio-group v-model="form.article_check" @change="article_check_change">
<el-radio v-for="item in base_list.get_data_method_list" :key="item.value" :value="item.value">{{ item.name }}</el-radio>
</el-radio-group>
</el-form-item>
<template v-if="form.article_check === '0'">
<div class="nav-list">
<drag :data="form.article_list" :space-col="20" @remove="article_list_remove" @on-sort="article_list_sort">
<drag :data="new_auto_article_list" :space-col="20" @remove="article_list_remove" @on-sort="article_list_sort">
<template #default="{ row }">
<upload v-model="row.new_url" :limit="1" size="40" styles="2"></upload>
<el-image :src="row.link.cover" fit="contain" class="img">
@ -29,7 +29,7 @@
</div>
</template>
</el-image>
<div class="flex-1 flex-width text-line-2 size-12 self-s">{{ row.link.title }}</div>
<div class="flex-1 flex-width text-line-2 size-12 self-s">{{ row.new_title }}</div>
</template>
</drag>
<el-button class="mtb-20 w" @click="add">+</el-button>
@ -37,21 +37,21 @@
</template>
<template v-else>
<el-form-item label="文章分类">
<el-select v-model="form.article_category" multiple collapse-tags placeholder="请选择文章分类">
<el-select v-model="form.article_category" multiple collapse-tags placeholder="请选择文章分类" @change="get_pointer_article">
<el-option v-for="item in base_list.article_category_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" type="number" placeholder="请输入显示数量" clearable />
<el-input v-model="form.number" type="number" placeholder="请输入显示数量" clearable @change="get_pointer_article" />
</el-form-item>
<el-form-item label="排序类型">
<el-radio-group v-model="form.sort">
<el-radio v-for="item in base_list.sort_list" :key="item.value" :value="item.value">{{ item.name }}</el-radio>
<el-radio v-for="item in base_list.sort_list" :key="item.value" :value="item.value" @change="get_pointer_article">{{ item.name }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="排序规则">
<el-radio-group v-model="form.sort_rules">
<el-radio v-for="item in base_list.sort_rules_list" :key="item.value" :value="item.value">{{ item.name }}</el-radio>
<el-radio v-for="item in base_list.sort_rules_list" :key="item.value" :value="item.value" @change="get_pointer_article">{{ item.name }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="封面图片">
@ -74,6 +74,7 @@
</template>
<script setup lang="ts">
import { get_math } from '@/utils';
import { isEmpty } from 'lodash';
import ArticleAPI from '@/api/article';
import { articleStore } from '@/store/article';
const article_store = articleStore();
@ -129,12 +130,66 @@ const init = () => {
} else {
base_list.article_category_list = article_store.article;
}
if (isEmpty(new_auto_article_list.value)) {
form.article_list = Array(4).fill(default_article_list);
} else {
form.article_list = new_auto_article_list.value;
}
};
const new_auto_article_list = ref<ArticleList[]>([]);
const article_check_change = (val: any) => {
if (val == '0') {
if (isEmpty(new_auto_article_list.value)) {
form.article_list = Array(4).fill(default_article_list);
} else {
form.article_list = new_auto_article_list.value;
}
} else {
get_pointer_article();
}
};
interface ArticleList {
id: number | string;
link: object;
new_title: string;
new_url: uploadList[];
}
const default_article_list: ArticleList = {
id: 0,
link: {},
new_title: '标题',
new_url: [],
};
const get_pointer_article = () => {
const { article_category, number, sort, sort_rules } = form;
const new_data = {
article_keywords: '',
article_category_ids: article_category.join(','),
article_number: number,
article_order_by_type: sort,
article_order_by_rule: sort_rules,
};
ArticleAPI.getAutoList(new_data).then((res: any) => {
form.article_list = [];
res.data.forEach((child: any) => {
const obj = {
id: get_math(),
new_title: child.title,
new_url: [],
link: child,
};
form.article_list.push(obj);
});
});
};
const article_list_remove = (index: number) => {
new_auto_article_list.value.splice(index, 1);
form.article_list.splice(index, 1);
};
const article_list_sort = (item: any) => {
new_auto_article_list.value = item;
form.article_list = item;
};
const add = () => {
@ -144,13 +199,15 @@ const add = () => {
const url_value_dialog_visible = ref(false);
const url_value_dialog_call_back = (item: any[]) => {
item.forEach((child: any) => {
form.article_list.push({
const obj = {
id: get_math(),
src: '',
new_title: child.title,
new_url: [],
link: child,
});
};
new_auto_article_list.value.push(obj);
});
form.article_list = new_auto_article_list.value;
};
</script>
<style lang="scss" scoped>

View File

@ -4,7 +4,7 @@
<model-article-list-content :value="value.content"></model-article-list-content>
</template>
<template v-else-if="type == '2'">
<model-article-list-styles :value="value.style"></model-article-list-styles>
<model-article-list-styles :value="value.style" :content="value.content"></model-article-list-styles>
</template>
</div>
</template>

View File

@ -37,7 +37,25 @@
<color-picker v-model="form.page_view_color"></color-picker>
</el-form-item>
<el-form-item label="内容圆角">
<radius :value="form"></radius>
<radius :value="form.content_radius"></radius>
</el-form-item>
<el-form-item label="图片圆角">
<radius :value="form.img_radius"></radius>
</el-form-item>
<el-form-item label="内间距">
<padding :value="form.padding"></padding>
</el-form-item>
<el-form-item label="内容间距">
<slider v-model="form.content_spacing"></slider>
</el-form-item>
<el-form-item label="文章间距">
<slider v-model="form.article_spacing"></slider>
</el-form-item>
<el-form-item label="文章间距">
<slider v-model="form.article_spacing"></slider>
</el-form-item>
<el-form-item v-if="article_style == '3'" label="内容宽度">
<slider v-model="form.article_width" :max="1000"></slider>
</el-form-item>
</card-container>
</el-form>
@ -50,14 +68,24 @@ const props = defineProps({
type: Object,
default: () => ({}),
},
content: {
type: Object,
default: () => ({}),
},
});
//
const state = reactive({
form: props.value,
data: props.content,
});
// 使toRefs
const { form, data } = toRefs(state);
const article_style = computed(() => data.value.article_style);
const emit = defineEmits(['update:value']);
const font_weight = reactive([
{ name: '加粗', value: '500' },
{ name: '正常', value: '400' },
]);
//
const form = ref(props.value);
const common_style_update = (value: any) => {
form.value.common_style = value;
};

View File

@ -57,7 +57,7 @@ interface Props {
num: number;
actived: number;
isShow: Array<string>;
chunkPadding: internalStyle;
chunkPadding: paddingStyle;
}
const props = withDefaults(defineProps<Props>(), {

View File

@ -1,9 +1,9 @@
import defaultCommon from './index';
interface ArticleList {
id: number;
url: string;
id: number | string;
link: object;
new_title: string;
new_url: uploadList[];
}
interface DefaultArticleList {
@ -28,11 +28,12 @@ interface DefaultArticleList {
page_view_weight: string;
page_view_size: number;
page_view_color: string;
radius: number;
radius_top_left: number;
radius_top_right: number;
radius_bottom_left: number;
radius_bottom_right: number;
content_radius: radiusStyle;
img_radius: radiusStyle;
padding: paddingStyle;
article_spacing: number;
content_spacing: number;
article_width: number;
common_style: object;
};
}
@ -58,11 +59,33 @@ const defaultArticleList: DefaultArticleList = {
page_view_weight: '400',
page_view_size: 12,
page_view_color: 'rgba(153, 153, 153, 1)',
radius: 8,
radius_top_left: 8,
radius_top_right: 8,
radius_bottom_left: 8,
radius_bottom_right: 8,
// 内容圆角
content_radius: {
radius: 8,
radius_top_left: 8,
radius_top_right: 8,
radius_bottom_left: 8,
radius_bottom_right: 8,
},
// 图片圆角
img_radius: {
radius: 0,
radius_top_left: 0,
radius_top_right: 0,
radius_bottom_left: 0,
radius_bottom_right: 0,
},
// 内间距
padding: {
padding: 10,
padding_top: 10,
padding_bottom: 10,
padding_left: 10,
padding_right: 10,
},
content_spacing: 10, // 内容间距
article_spacing: 10, // 文章间距
article_width: 160, // 文章宽度
common_style: { ...defaultCommon, padding: 10, padding_top: 10, padding_bottom: 10, padding_left: 10, padding_right: 10 },
},
};

View File

@ -17,7 +17,7 @@ interface DefaultProductList {
shop_button_size: string;
};
style: {
shop_padding: internalStyle;
shop_padding: paddingStyle;
shop_img_radius: radiusStyle;
shop_radius: radiusStyle;
content_outer_spacing: number;

View File

@ -34,7 +34,7 @@ interface DefaultProductList {
tabs_weight: string,
tabs_size: number,
tabs_color: string,
shop_padding: internalStyle;
shop_padding: paddingStyle;
shop_img_radius: radiusStyle;
shop_radius: radiusStyle;
content_outer_down_spacing: number;

View File

@ -27,9 +27,9 @@ declare global {
/**
*
*/
type internalKeys = 'padding' | 'padding_bottom' | 'padding_top' | 'padding_left' | 'padding_right';
type internalStyle = {
[key in internalKeys]: number;
type paddingKeys = 'padding' | 'padding_bottom' | 'padding_top' | 'padding_left' | 'padding_right';
type paddingStyle = {
[key in paddingKeys]: number;
};
/**
*

View File

@ -91,7 +91,7 @@ export function gradient_handle(color_list: color_list[], direction: string) {
* @param {string[], string} path
* @returns {string}
*/
export function padding_computer(new_style: internalStyle) {
export function padding_computer(new_style: paddingStyle) {
return `padding: ${new_style.padding_top || 0}px ${new_style.padding_right || 0}px ${new_style.padding_bottom || 0}px ${new_style.padding_left || 0}px;`;
}