初始上传

This commit is contained in:
2026-04-04 17:27:12 +08:00
parent 4d80d28eb4
commit b7e11774ee
11191 changed files with 1588469 additions and 0 deletions

View File

@@ -0,0 +1,31 @@
.float-btn .comp-title {display: none;}
.float-btn .float-btn-box {display: flex;flex-direction: column;align-items: flex-end;justify-content: center;text-align: center;border: 1px dashed;}
.float-btn .float-btn-item:nth-last-child(1) {margin-bottom: 0;}
.float-btn .float-btn-item {display: flex;justify-content: center;align-items: center;flex-direction: column;margin-bottom: 10px;overflow: hidden;}
.float-btn .float-btn-item .img-box, .float-btn .float-btn-item .icon-box {overflow: hidden;display: flex;justify-content: center;align-items: center;}
.float-btn .float-btn-item .img-box img {max-width: 100%;max-height: 100%;}
.float-btn .float-btn-item span {margin-top: 5px;color: #333;font-size: 12px;}
.float-btn .float-btn-list li, .float-btn .float-btn-list .add-item {display: flex;align-items: end;border: 1px dashed #e5e5e5;padding: 10px;}
.float-btn .float-btn-list li + li {margin: 10px 0;}
.float-btn .float-btn-list .right-wrap {display: flex;flex-direction: column;flex: 1;width: 0;}
.float-btn-list .right-wrap .action-box {display: flex;margin-bottom: 4px;}
.float-btn-list .action {margin-right: 10px;width: 42px;height: 28px;line-height: 28px;text-align: center;border: 1px solid #EEEEEE;cursor: pointer;}
.float-btn-list .action .iconfont {font-size: 20px;}
.float-btn-list .action:hover {border-color: var(--base-color);color: var(--base-color);}
.float-btn .right-wrap .layui-form-item {margin-bottom: 0;}
.float-btn .right-wrap .layui-form-label {text-align: left;}
.float-btn .float-btn-list .add-item {justify-content: center;align-items: center;margin: 10px 0;cursor: pointer;}
.float-btn .float-btn-list .add-item i {font-weight: bold;display: inline-block;height: 24px;line-height: 24px;font-size: 18px;margin-right: 10px;}
.float-btn .float-btn-list .add-item span {display: inline-block;height: 24px;line-height: 24px;}
.float-btn .float-btn-list li {position: relative;}
.float-btn .float-btn-list li:hover .del {display: block;}
.float-btn {position: absolute;}
.float-btn .preview-draggable {padding: 0;}
.float-btn.left {background: rgba(255, 255, 255, 0.45);margin-left: 10px;top: 130px;}
.float-btn.left .edit-attribute {right: -980px;top: -100px;}
.float-btn.right_bottom {margin-left: 10px;bottom: 130px;left: 642px;}
.float-btn-list {margin-left: 20px;}
.float-btn-list .hint {margin: 10px 0 10px 0;color: #909399;font-size: 12px;}
.float-btn .tab-wrap {display: none !important;}
.float-btn .icon-radio .icon-wrap i {color: #303133;}
.float-btn .preview-draggable .del {right: -20px;}

View File

@@ -0,0 +1,48 @@
<nc-component :data="data[index]" class="float-btn" data-disabled="1">
<!-- 预览 -->
<template slot="preview">
<template v-if="nc.lazyLoad">
<div class="float-btn-box border-color" data-disabled="1">
<div v-for="(item,previewIndex) in nc.list" :key="previewIndex" :index="previewIndex" class="float-btn-item" data-disabled="1">
<div class="img-box" data-disabled="1" v-if="!item.iconType || item.iconType == 'img'" :style="{ width : nc.imageSize + 'px',height : nc.imageSize + 'px' }">
<img :src="changeImgUrl(item.imageUrl)" data-disabled="1">
</div>
<div class="icon-box" data-disabled="1" v-if="item.iconType && item.iconType == 'icon'" :style="{ width : nc.imageSize + 'px',height : nc.imageSize + 'px',fontSize : nc.imageSize + 'px' }">
<iconfont :icon="item.icon" v-if="item.icon" :value="item.style ? item.style : ''"></iconfont>
</div>
</div>
</div>
</template>
</template>
<!-- 内容编辑 -->
<template slot="edit-content">
<template v-if="nc.lazyLoad">
<div class="template-edit-title">
<h3>按钮位置</h3>
<btn-position></btn-position>
<slide :data="{ field : 'btnBottom', label : '上下偏移' }"></slide>
</div>
<div class="template-edit-title">
<h3>图片设置</h3>
<slide :data="{ field : 'imageSize', label : '图片大小', min: 40, max : 100 }"></slide>
<float-btn-list></float-btn-list>
</div>
</template>
</template>
<!-- 样式编辑 -->
<template slot="edit-style"></template>
<!-- 资源 -->
<template slot="resource">
<js>
var floatBtnResourcePath = "{$resource_path}"; // http路径
var floatBtnRelativePath = "{$relative_path}"; // 相对路径
</js>
<css src="{$resource_path}/css/design.css"></css>
<js src="{$resource_path}/js/design.js"></js>
</template>
</nc-component>

View File

@@ -0,0 +1,309 @@
var floatBtnListHtml = '<div class="float-btn-list">';
floatBtnListHtml += '<p class="hint" style="font-size: 12px; margin: 5px 0 8px;">建议上传正方形图片</p>';
floatBtnListHtml += '<ul>';
floatBtnListHtml += '<li v-for="(item,index) in list" :key="item.id">';
floatBtnListHtml += '<img-icon-upload :data="{data : item}"></img-icon-upload>';
floatBtnListHtml += '<div class="right-wrap">';
floatBtnListHtml += '<div class="action-box" v-show="item.iconType == \'icon\'">';
floatBtnListHtml += '<div class="action" @click="iconStyle($event, index)"><i class="iconfont iconpifu"></i></div>';
floatBtnListHtml += '<div class="action" :id="\'float-btn-color-\' + index"><i class="iconfont iconyanse"></i></div>';
floatBtnListHtml += '</div>';
floatBtnListHtml += '<nc-link :data="{field: $parent.data.list[index].link}"></nc-link>';
floatBtnListHtml += '</div>';
floatBtnListHtml += '<i class="del" @click="del(index)" data-disabled="1">x</i>';
floatBtnListHtml += '<div class="error-msg"></div>';
floatBtnListHtml += '</li>';
floatBtnListHtml += '</ul>';
floatBtnListHtml += '<div class="add-item text-color" v-if="showAddItem" @click="add">';
floatBtnListHtml += '<i>+</i>';
floatBtnListHtml += '<span>添加一个浮动按钮</span>';
floatBtnListHtml += '</div>';
floatBtnListHtml += '</div>';
Vue.component("float-btn-list",{
data: function () {
return {
list: this.$parent.data.list,
maxTip : 3,//最大上传数量提示
showAddItem : true,
screenWidth:0,
colorPicker:{}
};
},
created : function(){
if(!this.$parent.data.verify) this.$parent.data.verify = [];
this.$parent.data.verify.push(this.verify);//加载验证方法
this.$parent.data.ignore = ['textColor','pageBgColor','componentBgColor','elementBgColor','marginTop','marginBottom','marginBoth','componentAngle','elementAngle'];//加载忽略内容 -- 其他设置中的属性设置
this.$parent.data.ignoreLoad = true; // 等待忽略数组赋值后加载
getElementPosition(this.$parent);
window.onresize = () => {
return (() => {
window.screenWidth = document.body.clientWidth;
this.screenWidth = window.screenWidth
})()
};
this.changeShowAddItem();//获取默认值
this.list.forEach(function (item) {
if (!item.id) item.id = ns.gen_non_duplicate(10)
})
},
watch : {
list : function(){
this.changeShowAddItem();
getElementPosition(this.$parent)
},
screenWidth(val){
// 为了避免频繁触发resize函数导致页面卡顿使用定时器
getElementPosition(this.$parent);
},
"$parent.data.btnBottom": function () {
getElementPosition(this.$parent);
}
},
mounted(){
this.fetchAllMenuIconColor();
},
methods: {
verify :function () {
var res = { code: true, message: "" };
if(this.list.length >0){
for(var i=0;i < this.list.length;i++){
if(this.$parent.data.list[i].imageUrl == "" && this.$parent.data.list[i].icon == ""){
res.code = false;
res.message = "请添加图片";
break;
}
}
}else{
res.code = false;
res.message = "请添加一个浮动按钮";
}
return res;
},
//改变添加浮动按钮
changeShowAddItem(){
if(this.list.length >= this.maxTip) this.showAddItem = false;
else this.showAddItem = true;
},
/**
* 选择图标风格
* @param event
* @param index
*/
iconStyle(event, index){
var self = this;
selectIconStyle({
elem: event.currentTarget,
icon: self.list[index].icon,
callback: function (data) {
if (data) {
self.list[index].style = data;
} else {
iconStyleSet({
style: JSON.stringify(self.list[index].style),
query: {
icon: self.list[index].icon
}
}, function(style){
self.list[index].style = style;
})
}
}
})
},
/**
* 渲染颜色组件
* @param id
* @param color
* @param callback
*/
colorRender(id, color, callback){
var self = this;
if (this.colorPicker[id]) return;
setTimeout(function () {
self.colorPicker[id] = Colorpicker.create({
el: id,
color: color,
change: function (elem, hex) {
callback(elem, hex)
}
});
})
},
/**
* 渲染全部菜单颜色选择器
*/
fetchAllMenuIconColor(){
var self = this;
this.list.forEach(function (item, index) {
self.colorRender('float-btn-color-' + index, '', function (elem, color) {
index = $(elem).parents('li').index();
if (self.list[index].style.iconBgColor.length || self.list[index].style.iconBgImg) {
self.list[index].style.iconBgColor = [color];
} else {
self.list[index].style.iconColor = [color];
}
self.$forceUpdate();
})
})
},
add(){
var self = this;
this.list.push({ imageUrl : '', title : '', link : {name: ''}, iconType: 'img', icon: '', style: {fontSize: 60, iconBgColor: [], iconBgColorDeg: 0,iconBgImg: '',bgRadius: 0,iconColor: ['#000'],iconColorDeg: 0}})
this.colorRender('float-btn-color-' + (this.list.length - 1), '', function (elem, color) {
var index = $(elem).parents('li').index();
if (self.list[index].style.iconBgColor.length || self.list[index].style.iconBgImg) {
self.list[index].style.iconBgColor = [color];
} else {
self.list[index].style.iconColor = [color];
}
self.$forceUpdate();
})
},
del(index){
this.list.splice(index, 1);
delete this.colorPicker['float-btn-color-' + index];
}
},
template: floatBtnListHtml
});
/**
* 按钮位置
*/
var btnPosition = '<div class="layui-form-item icon-radio">';
btnPosition += '<label class="layui-form-label sm">{{data.label}}</label>';
btnPosition += '<div class="layui-input-block">';
btnPosition += '<template v-for="(item,index) in list">';
btnPosition += '<span :class="[parent[data.field] == item.value ? \'\' : \'layui-hide\']">{{item.label}}</span>';
btnPosition += '</template>';
btnPosition += '<ul class="icon-wrap">';
btnPosition += '<template v-for="(item,index) in list">';
btnPosition += '<li @click="changePosition(item.value)" :class="{\'border-color\':parent[data.field] == item.value}">';
btnPosition += '<i class="iconfont" :class="[item.icon_img,parent[data.field] == item.value ? \'text-color\' : \'\']"></i>';
btnPosition += '</li>';
btnPosition += '</template>';
btnPosition += '</ul>';
btnPosition += '</div>';
btnPosition += '</div>';
Vue.component("btn-position", {
props: {
data: {
type: Object,
default: function () {
return {
field: "bottomPosition",
label: "按钮位置"
};
}
}
},
data: function () {
return {
list: [
{
label: "左上",
value: "1",
icon_img: "iconzuoshangjiao",
},
{
label: "右上",
value: "2",
icon_img: "iconyoushangjiao",
},
{
label: "左下",
value: "3",
icon_img: "iconzuoxiajiao",
},
{
label: "右下",
value: "4",
icon_img: "iconyouxiajiao",
},
],
parent: this.$parent.data,
imageSize: this.$parent.data.imageSize,
};
},
created: function () {
$('.float-btn').parent('.draggable-element').css({"border": "none"});// 将边框进行隐藏掉
},
watch: {
"$parent.data.imageSize": function () {
getElementPosition(this.$parent);
}
},
methods: {
changePosition:function(val){
this.parent.bottomPosition = val;
getElementPosition(this.$parent)
}
},
template: btnPosition
});
function getElementPosition(params) {
var type = parseInt(params.data.bottomPosition), //布局类型1为第一种2为第二种依次类推
bottomNumber = parseInt(params.data.btnBottom); //上下偏移的变量
/**
* #diyView .diy-view-wrap .preview-block =》 显示框【定位的参照对象是body】#diyView =》 外边框【定位的参照对象是body】
* 1、弹窗按钮是根据“外边框”进行定位的,但弹窗按钮是需要在“显示框”中展示
* 2、弹窗按钮与显示框的上下间距定义为50px,左右为30px这个是常量
* 3、计算弹窗按钮的四个位置都是根据 topleft进行计算的
* */
var box = document.querySelector("#diyView .diy-view-wrap .preview-block").getBoundingClientRect();
var box1 = document.querySelector("#diyView").getBoundingClientRect();
var topVal = 0; //弹窗按钮的top
var leftVal = 0; //弹窗按钮的left
var leftOffSet = 30; //弹窗按钮左右的偏移量
if (type == 1) {
// topVal = 显示框的top - 外边框的top + 距离显示框下边距的50px + 偏移量
// leftVal = 显示框的left - 外边框的left + 距离显示框右边距的30px
topVal = 100 + bottomNumber + "px";
leftVal = box.left - box1.left + leftOffSet + "px";
} else if (type == 2) {
// topVal = 显示框的top - 外边框的top + 距离显示框下边距的50px + 偏移量
// leftVal = 显示框的left - 外边框的left + 显示框的width82 - 弹窗按钮的width - 距离显示框右边距的30px
topVal = 100 + bottomNumber + "px";
leftVal = box.left - box1.left + box.width - params.data.imageSize - 2 - leftOffSet + "px";
} else if (type == 3) {
// topVal = 显示框的top - 外边框的上边距(20) - 防止贴边(20) - 弹出按钮高度 - 弹出按钮的下外边距 - 偏移量
// leftVal = 显示框的left - 外边框的left + 距离显示框左边距的30px
// topVal = box.top - box1.top + box.height - 82 - topOff - bottomNumber + "px";
topVal = $("#diyView .preview-wrap .div-wrap").height() - 20 - 20 - (params.data.list.length * params.data.imageSize) - ((params.data.list.length - 1) * 10) - bottomNumber + 'px';
leftVal = box.left - box1.left + leftOffSet + "px";
} else if (type == 4) {
// topVal = 显示框的top - 外边框的上边距(20) - 防止贴边(20) - 弹出按钮高度 - 弹出按钮的下外边距 - 偏移量
// leftVal = 显示框的left - 外边框的left + 显示框的width - 弹窗按钮的width - 边框width - 距离显示框右边距的30px
topVal = $("#diyView .preview-wrap .div-wrap").height() - 20 - 20 - (params.data.list.length * params.data.imageSize) - ((params.data.list.length - 1) * 10) - bottomNumber + 'px';
leftVal = box.left - box1.left + box.width - params.data.imageSize - 2 - leftOffSet + "px";
}
$(".draggable-element .float-btn").css({
left: leftVal,
top: topVal,
'z-index': 999
});
$(".draggable-element .float-btn .edit-attribute").css({
position: 'fixed',
right: '15px',
top: Math.abs(box1.top)
})
}