源文件

This commit is contained in:
gyq
2025-04-25 09:49:53 +08:00
commit 791d82b9e3
640 changed files with 130029 additions and 0 deletions

View File

@@ -0,0 +1,290 @@
<template>
<view :class="'wh-auto pr allSignList-' + propIndex + propKey" :style="'height:' + propDataHeight * propScale + 'px;'">
<view v-for="(item, index) in new_list" :key="index" :data-id="item.id" :data-location-x="item.location.x" :data-location-y="item.location.y" :class="'sign-' + propIndex + propKey + ' main-content ' + get_animation_class(item.com_data)" :style="'left:' + get_percentage_count(item.location.x, item.com_data.data_follow, 'left') + ';top:' + get_percentage_count(item.location.y, item.com_data.data_follow, 'top') + ';width:' + get_percentage_count(item.com_data.com_width, item.com_data.data_follow, 'width', item.com_data.is_width_auto, item.com_data.max_width, item.key) + ';height:' + get_percentage_count(item.com_data.com_height, item.com_data.data_follow, 'height', item.com_data.is_height_auto, item.com_data.max_height, item.key) + ';z-index:' + (new_list.length - 1 > 0 ? (new_list.length - 1) - index : 0)">
<template v-if="item.key == 'text'">
<model-text :propKey="propKey + item.id" :propValue="item.com_data" :propScale="propScale" :propFieldList="propFieldList" :propSourceList="propSourceList" :propConfigLoop="propConfigLoop" :propIsCustom="propIsCustom" :propIsCustomGroup="propIsCustomGroup" :propCustomGroupFieldId="propCustomGroupFieldId" :propTitleParams="propShowData.data_name" @url_event="url_event"></model-text>
</template>
<template v-else-if="item.key == 'img'">
<model-image :propKey="propKey + item.id" :propValue="item.com_data" :propScale="propScale" :propFieldList="propFieldList" :propSourceList="propSourceList" :propConfigLoop="propConfigLoop" :propIsCustom="propIsCustom" :propIsCustomGroup="propIsCustomGroup" :propCustomGroupFieldId="propCustomGroupFieldId" :propImgParams="propShowData.data_logo" @url_event="url_event"></model-image>
</template>
<template v-else-if="item.key == 'auxiliary-line'">
<model-lines :propKey="propKey + item.id" :propValue="item.com_data" :propScale="propScale" :propFieldList="propFieldList" :propSourceList="propSourceList" :propConfigLoop="propConfigLoop" :propIsCustom="propIsCustom" :propIsCustomGroup="propIsCustomGroup" :propCustomGroupFieldId="propCustomGroupFieldId"></model-lines>
</template>
<template v-else-if="item.key == 'icon'">
<model-icon :propKey="propKey + item.id" :propValue="item.com_data" :propScale="propScale" :propFieldList="propFieldList" :propSourceList="propSourceList" :propConfigLoop="propConfigLoop" :propIsCustom="propIsCustom" :propIsCustomGroup="propIsCustomGroup" :propCustomGroupFieldId="propCustomGroupFieldId" @url_event="url_event"></model-icon>
</template>
<template v-else-if="item.key == 'panel'">
<model-panel :propKey="propKey + item.id" :propValue="item.com_data" :propScale="propScale" :propFieldList="propFieldList" :propSourceList="propSourceList" :propConfigLoop="propConfigLoop" :propIsCustom="propIsCustom" :propIsCustomGroup="propIsCustomGroup" :propCustomGroupFieldId="propCustomGroupFieldId" @url_event="url_event"></model-panel>
</template>
<template v-else-if="item.key == 'custom-group'">
<model-custom-group :propKey="propKey + item.id" :propValue="item.com_data" :propScale="propScale" :propFieldList="propFieldList" :propConfigLoop="propConfigLoop" :propDataWidth="item.com_data.com_width" :propDataHeight="item.com_data.custom_height" :propSourceList="propSourceList" :propGroupSourceList="propGroupSourceList" :propIsCustom="propIsCustom" :propShowData="propShowData"></model-custom-group>
</template>
</view>
</view>
</template>
<script>
import modelText from '@/components/diy/modules/custom/model-text.vue';
import modelLines from '@/components/diy/modules/custom/model-lines.vue';
import modelImage from '@/components/diy/modules/custom/model-image.vue';
import modelIcon from '@/components/diy/modules/custom/model-icon.vue';
import modelPanel from '@/components/diy/modules/custom/model-panel.vue';
import modelCustomGroup from '@/components/diy/modules/custom/model-custom-group.vue';
import { location_compute, isEmpty } from '@/common/js/common/common.js';
export default {
components: {
modelText,
modelLines,
modelImage,
modelIcon,
modelPanel,
modelCustomGroup
},
props: {
propCustomList: {
type: Array,
default: () => {
return [];
},
required: true,
},
propIndex: {
type: Number,
default: 0,
},
propSourceList: {
type: Object,
default: () => {
return {};
}
},
propGroupSourceList: {
type: Array,
default: () => {
return [];
}
},
propDataHeight: {
type: Number,
default: 0,
},
propScale: {
type: Number,
default: 1,
},
propDataIndex: {
type: Number,
default: 1,
},
propDataSplitIndex: {
type: Number,
default: 1,
},
propIsCustom: {
type: Boolean,
default: false,
},
propIsCustomGroup: {
type: Boolean,
default: false
},
propShowData: {
type: Object,
default: () => ({
data_key: 'id',
data_name: 'name'
}),
},
propKey: {
type: [String, Number],
default: '',
},
propCustomGroupFieldId: {
type: String,
default: ''
},
propFieldList: {
type: Array,
default: () => {
return [];
}
},
propConfigLoop: {
type: String,
default: "1"
}
},
data() {
return {
new_list: [],
custom_width: 0,
};
},
watch: {
propKey(val) {
// 初始化
this.init(this.propCustomList);
},
propCustomList(val) {
this.init(val);
}
},
computed: {
get_percentage_count() {
return (num, data_follow, type, is_auto = '0', max_size = 0, key = '') => {
// 检查类型是否为'left'或'top',如果是,则根据跟随数据计算样式
if (['left', 'top'].includes(type)) {
const { id = '', type: follow_type = 'left' } = data_follow || { id: '', type: 'left' };
// 如果id不为空且follow_type与type匹配则返回原始值的字符串表示
if (id !== '' && follow_type === type) {
return `${num}px`;
}
// 如果条件不满足则根据比例缩放num并返回
return `${num * this.propScale}px`;
} else {
// 如果is_auto设置为'1'则根据type和max_size计算自动样式
if (is_auto === '1') {
if (type === 'width' || type === 'height') {
if (typeof max_size === 'number' && max_size >= 0) {
const scaledMaxSize = max_size * this.propScale;
const autoStyle = 'auto;';
const maxSizeStyle = scaledMaxSize > 0 ? ` max-${type}: ${scaledMaxSize}px;` : '';
const whiteSpaceStyle = type === 'width' && scaledMaxSize <= 0 ? ' white-space:nowrap;' : '';
return `${ autoStyle }${ maxSizeStyle }${ whiteSpaceStyle }`;
} else {
return 'auto;';
}
}
} else {
// 微信小程序图片等比缩放对小数点后的内容支持的不是特别的好,需要取向上取整数
if (key == 'img' && ['width', 'height'].includes(type)) {
// 如果is_auto未设置或条件不满足则根据比例缩放num并返回
return `${ Math.round(num * this.propScale) }px`;
} else {
// 如果is_auto未设置或条件不满足则根据比例缩放num并返回
return `${num * this.propScale}px`;
}
}
}
};
},
get_animation_class() {
return (data) => {
const { type = 'none', number = 'infinite' } = data?.animation_style || {};
if (type != 'none') {
return type + (number == 'infinite' ? `-${number}` : '');
} else {
return '';
}
};
}
},
mounted() {
this.init(this.propCustomList);
},
methods: {
async init(val) {
// 如果为空就不进行渲染
if (isEmpty(val)) {
return;
}
await this.get_custom_width();
this.set_new_list(val);
},
get_custom_width() {
// 获取当前容器的宽度
const query = uni.createSelectorQuery().in(this);
query.select('.allSignList-' + this.propIndex + this.propKey)
.boundingClientRect((res) => {
if (res) {
this.setData({
custom_width: res.width,
});
}
})
.exec();
},
async set_new_list(val) {
// 第一次渲染先渲染全部数据
this.setData({
new_list: val
});
// 判断是否有跟随的数据
const follow_list = val.filter(item => item.com_data.data_follow && item.com_data?.data_follow?.id !== '');
if (follow_list.length > 0) {
await this.$nextTick();
// 第二次如果有跟随数据,更新对应数据的内容, 如果有超出容器范围的数据,限制其超出容器范围
const query = uni.createSelectorQuery().in(this);
query.selectAll('.sign-' + this.propIndex + this.propKey)
.boundingClientRect((rect) => {
if (rect) {
// 将返回的内容转成map对象方便快速查找节省性能
const idMap = new Map(rect.map(item => [item.dataset.id, item]));
// 历史数据拷贝,方便后续操作避免每次都更新数据,统一重新渲染
const val = JSON.parse(JSON.stringify(this.new_list));
val.forEach((item1) => {
const { data_follow } = item1.com_data;
const targetItem = idMap.get(data_follow?.id);
if (targetItem) {
const text_item = item1.key == 'text' ? idMap.get((item1?.id || '')+ '') : undefined;
if (data_follow?.type === 'left') {
// 更新位置信息
const location_x = this.updateLocation(targetItem, data_follow, this.propScale, true);
// 获取组件的宽度,如果是宽度自适应,则需要重新计算位置
let item_width = item1.com_data.com_width;
// 如果是宽度自适应,需要重新判断一下处理逻辑
if (item1.com_data.is_width_auto === '1' && text_item) {
item_width = text_item.width;
}
// 根据容器信息更新位置信息
item1.location.x = location_compute(item_width, location_x, this.custom_width);
} else if (data_follow?.type === 'top') {
// 更新位置信息
const location_y = this.updateLocation(targetItem, data_follow, this.propScale, false);
// 获取组件的宽度,如果是宽度自适应,则需要重新计算位置
let item_height = item1.com_data.com_height;
// 如果是高度自适应,需要重新判断一下处理逻辑
if (item1.com_data?.is_height_auto === '1' && text_item) {
item_height = text_item.height;
}
// 根据容器信息更新位置信息
item1.location.y = location_compute(item_height, location_y, this.propDataHeight * this.propScale);
}
}
});
this.setData({
new_list: val
});
}
})
.exec();
}
},
updateLocation(targetItem, data_follow, scale, isX) {
try {
const locationValueStr = targetItem.dataset[`location${isX ? 'X' : 'Y'}`];
if (locationValueStr == null) {
return;
}
const locationValue = parseFloat(locationValueStr);
if (isNaN(locationValue) || scale <= 0 || (isX ? targetItem.width < 0 : targetItem.height < 0)) return;
const computedValue = ((locationValue + (data_follow?.spacing || 0)) * scale) + (isX ? targetItem.width : targetItem.height);
return computedValue;
} catch (error) {
console.error(`Error updating location ${isX ? 'X' : 'Y'}:`, error);
}
},
url_event(e) {
this.$emit('url_event', e, this.propDataIndex, this.propDataSplitIndex);
}
},
};
</script>
<style lang="scss" scoped>
.main-content {
position: absolute;
overflow: hidden;
}
</style>