| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505 |
- <?php
- use common\helpers\ComponentHelper;
- ComponentHelper::loadComponentView('com-attachment');
- ComponentHelper::loadComponentView('com-pick-link');
- ?>
- <template id="diy-img-setting">
- <diy-style-contain class="diy-img-setting" :title="topName" :show-title="showTitle" :contain-style="imgContainStyle" :style="{'border-top': showTitle? '':'none'}">
- <div class="suggest" v-if="suggestSite == 1">{{suggestSizeText}}</div>
- <div class="diy-img-models">
- <div class="diy-img-model" :style="{'margin-bottom': '10px','padding': showHotZone?'0':''}" v-for="(item,index) in newImgInfos" :key="index" @mouseover="overModel(index)" @mouseleave="leaveModel">
- <div flex="cross:center">
- <com-attachment :style="{'width': showHotZone?'100%':''}" display="unset" :multiple="false" :max="1" type="images" @selected="coverPic($event,index)">
- <div class="card-upload img-upload-bor" :style="{width: showHotZone?'':imgPopSize[0] + 'px',height: showHotZone?'':imgPopSize[1] + 'px'}" v-if="!item.imgUrl.length">
- <i class="el-icon-plus icon-plugs-center"></i>
- </div>
- <div class="diy-sty-img" flex="main:center cross:center" :class="{'diy-img-hot-zone':showHotZone}" v-else @mouseover="mouseOverImg($event,index)" @mouseleave="mouseLeaveImg" :style="{width: showHotZone?'':imgPopSize[0] + 'px',height: showHotZone?'':imgPopSize[1] + 'px'}">
- <el-image class="diy-sty-img-u" :src="item.imgUrl"></el-image>
- <div class="diy-upd-img" :class="{'diy-upd-hot': showHotZone}" v-show="showHotZone || index == selImgIndex">替换</div>
- <i class="el-icon-close diy-upd-icon" @click.stop="delImg(index)" v-show="!showHotZone && index == selImgIndex"></i>
- <div v-if="showHotZone" class="img-hot-model" @click.stop="updatedHotZone(index)">
- <div v-for="(hot,hotIndex) in item.hotZone" :key="hotIndex" flex="main:center cross:center" :style="{'height': (hot.heightPer * 100) + '%','width': (hot.widthPer * 100) + '%','left': (hot.leftPer * 100) + '%','top': (hot.topPer * 100) + '%',}" class="img-hot-zone-model">
- {{hot.urlName || '暂无链接'}}
- </div>
- </div>
- </div>
- </com-attachment>
- <diy-url :text="item.urlName" @add="addUrl(index)" style="margin-left: 10px;" v-if="showUrl"></diy-url>
- <div class="diy-img-del-model" v-show="newImgInfos.length > 1&&(selModelIndex == index || item.visible)">
- <el-popover placement="bottom" width="120" v-model="item.visible">
- <p class="diy-del-text">确定删除吗?</p>
- <div flex="cross:center">
- <el-button class="diy-del-btn" size="mini" plain @click="delModel(index)">删除</el-button>
- <el-button size="mini" plain @click="item.visible = false">取消</el-button>
- </div>
- <i class="el-icon-close" slot="reference" style="color:#999;"></i>
- </el-popover>
- </div>
- </div>
- <div class="img_button_text" v-if="suggestSite == 2">{{suggestSizeText}}</div>
- </div>
- <div class="diy-add-img" @click="addModel" v-if="openAddImg">
- +添加 {{maxImgLength >= 999?'':newImgInfos.length + '/' + maxImgLength}}
- </div>
- </div>
- <el-dialog width="50%" title="热区编辑器" append-to-body :visible.sync="hotZonePop">
- <div class="diy-hotzone-pop">
- <HotZone :image="selHotZoneImg.imgUrl" :zones-init="selHotZoneImg.hotZone" @add-url="addHotZoneUrl" @save="getSave"></HotZone>
- </div>
- </el-dialog>
- <com-pick-link @close="updatePop" :pop-boo="urlPop" @selected="selectedUrl" :default-tabs="defaultTabs"></com-pick-link>
- </diy-style-contain>
- </template>
- <script>
- /**
- * 颜色组件
- *
- */
- Vue.component('diy-img-setting', {
- template: '#diy-img-setting',
- name: 'diy-img-setting',
- props: {
- showTitle: { //是否开启标题
- type: Boolean,
- default: true
- },
- imgContainStyle: { //最外层样式
- type: Object,
- default: () => {}
- },
- showHotZone: { //是否有热区:开启需要关闭showUrl
- type: Boolean,
- default: false
- },
- showUrl: { //是否开启链接选择
- type: Boolean,
- default: true
- },
- suggestSite: { //尺寸建议位置 1:在顶部 2:在图片下方
- type: [Number, String],
- default: 1
- },
- suggestSizeText: { //建议尺寸文本
- type: String,
- default: "建议图片宽为750,高度420"
- },
- openAddImg: { //是否开启添加按钮
- type: Boolean,
- default: false
- },
- topName: { //头部标题
- type: String,
- default: "图片设置",
- },
- imgPopSize: { //上传图片框的宽高展示 [宽度,高度]
- type: Array,
- default: () => {
- return ['60', '60']
- }
- },
- defImgUrl: { //全局默认图片
- type: String,
- default: "",
- },
- maxImgLength: { //最多添加图片数量
- type: [String, Number],
- default: 5
- },
- /**
- 是否开启默认创建
- */
- defAddImgBoo: {
- type: Boolean,
- default: false,
- },
- /**
- 默认创建多少个
- 注:defAddImgBoo需要开启
- */
- defImgCount: {
- type: [String, Number],
- default: 1
- },
- /**
- 数据格式
- {
- url: "", //链接路径
- urlName: '', //链接名
- urlType: '', //链接类型
- imgUrl: "" //图片路径
- visible: false, //删除弹窗
- hotZone: [{
- leftPer: 0,
- topPer: 0,
- widthPer: 0.30,
- heightPer: 0.30,
- url: '', //链接路径
- urlName: '', //链接名
- urlType: '', //链接类型
- }], //热区数据
- }
- 注:可传一个空数组
- */
- imgInfos: { //图片数据
- type: Array,
- default: () => {
- return []
- }
- },
- defaultTabs: { // 选择需要的tabs栏
- type: Array,
- default () {
- return ["mall", "goods", "addons", "other"]
- },
- },
- },
- data() {
- return {
- newImgInfos: [],
- selModelIndex: -1, //鼠标移入的模块下标
- selImgIndex: -1, //鼠标移入的图片下标
- visible: false,
- hotZonePop: false,
- selHotZoneIndex: -1, //选中图片下标
- selHotZoneImg: [], //选中图片数据热区
- urlPop: false,
- urlIndex: -1,
- hotZoneIndex: -1, //点击热区的下标
- }
- },
- created() {
- },
- watch: {
- imgInfos: {
- deep: true,
- immediate: true,
- handler(val) {
- let that = this;
- this.newImgInfos = [];
- if (val.length == 0) {
- this.addModel();
- } else {
- this.newImgInfos = val;
- }
- }
- }
- },
- methods: {
- // 添加
- addModel() {
- if (this.newImgInfos.length >= this.maxImgLength) {
- this.$notify({
- title: '',
- message: '最多添加' + this.maxImgLength + '个',
- type: 'warning'
- });
- return;
- }
- let obj = {
- url: "", //链接路径
- imgUrl: this.defImgUrl ? this.defImgUrl : "", //图片路径
- visible: false, //删除弹窗
- urlName: '', //链接名
- urlType: '', //链接类型
- hotZone: [{
- leftPer: 0,
- topPer: 0,
- widthPer: 0.30,
- heightPer: 0.30,
- url: '',
- urlName: '',
- urlType: '', //链接类型
- }], //热区数据
- }
- if (this.newImgInfos.length == 0) {
- this.newImgInfos = [];
- for (let i = 0; i < Number(this.defImgCount); i++) {
- this.newImgInfos.push(JSON.parse(JSON.stringify(obj)));
- }
- // 关闭默认创建
- // this.$emit("closeAddImg",false);
- } else {
- this.newImgInfos.push(obj);
- }
- this.changImg();
- },
- // 删除
- delModel(index) {
- if (this.newImgInfos.length == 1) {
- this.newImgInfos[index].visible = false;
- this.$notify({
- title: '',
- message: '最少保留一个',
- type: 'warning'
- });
- return;
- }
- this.newImgInfos.splice(index, 1);
- this.changImg();
- },
- // 添加图片
- coverPic(e, i) {
- console.info(e, i);
- this.newImgInfos[i].imgUrl = e[0].url;
- console.info(this.newImgInfos);
- this.changImg();
- },
- // 删除图片
- delImg(index) {
- this.newImgInfos[index].imgUrl = "";
- this.changImg();
- },
- // 鼠标移入图片
- mouseOverImg(event, index) {
- this.selImgIndex = index;
- },
- // 鼠标移出图片
- mouseLeaveImg() {
- this.selImgIndex = -1;
- },
- // 鼠标移入模块
- overModel(index) {
- this.selModelIndex = index;
- },
- // 鼠标移出模块
- leaveModel() {
- this.selModelIndex = -1;
- },
- // 编辑热区
- updatedHotZone(index) {
- this.hotZonePop = true;
- // this.selHotZoneImg = [];
- this.selHotZoneImg = JSON.parse(JSON.stringify(this.newImgInfos[index]));
- this.urlIndex = index;
- },
- // 获取热区数据
- getSave(val) {
- this.newImgInfos[this.urlIndex].hotZone = val;
- this.hotZonePop = false;
- this.changImg();
- },
- // 图片添加链接
- addUrl(index) {
- this.urlIndex = index;
- this.urlPop = true;
- },
- updatePop(boo) {
- this.urlPop = boo;
- },
- selectedUrl(val) {
- if (!val.length) {
- return false
- }
- let urlInfo = val[0];
- if (this.hotZoneIndex == -1) {
- this.newImgInfos[this.urlIndex].urlName = getOtherUrlName(urlInfo.open_type) || urlInfo.title;
- this.newImgInfos[this.urlIndex].url = urlInfo.params;
- this.newImgInfos[this.urlIndex].urlType = urlInfo.open_type;
- this.urlIndex = -1;
- } else {
- this.selHotZoneImg.hotZone[this.hotZoneIndex].urlName = getOtherUrlName(urlInfo.open_type) || urlInfo.title;
- this.selHotZoneImg.hotZone[this.hotZoneIndex].url = urlInfo.params;
- this.selHotZoneImg.hotZone[this.hotZoneIndex].urlType = urlInfo.open_type;
- // this.newImgInfos[this.urlIndex].hotZone[this.hotZoneIndex].urlName = urlInfo.title;
- // this.newImgInfos[this.urlIndex].hotZone[this.hotZoneIndex].url = urlInfo.route;
- // this.newImgInfos[this.urlIndex].hotZone[this.hotZoneIndex].urlType = urlInfo.open_type;
- }
- this.urlPop = false;
- this.changImg();
- },
- //热区添加链接
- addHotZoneUrl(index) {
- console.log(index);
- this.hotZoneIndex = index;
- this.urlPop = true;
- },
- // 通信
- changImg() {
- this.$emit("change", this.newImgInfos);
- },
- }
- });
- </script>
- <style scoped>
- .suggest {
- margin: 20px 0 12px;
- background: #EAF3FE;
- border: 1px solid #2D8CF0;
- opacity: 1;
- border-radius: 3px;
- padding: 14px 17px 17px;
- font-size: 12px;
- font-weight: bold;
- color: #999999;
- }
- .diy-img-models {
- margin-bottom: 6px;
- }
- .diy-img-model {
- padding: 12px 9px 7px;
- background: #F6F5F8;
- position: relative;
- border-radius: 4px;
- }
- .img-upload-bor {
- position: relative;
- border: 1px dashed #D5D5D5;
- }
- .icon-plugs-center {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- }
- .diy-url {
- height: 39px;
- background: #EDF2FC;
- border-radius: 2px;
- font-size: 11px;
- font-weight: bold;
- line-height: 0px;
- color: #999999;
- flex: 1;
- padding: 9px 15px 14px;
- margin-left: 14px;
- }
- .diy-url-icon {
- font-size: 13px;
- margin-right: 10px;
- }
- .diy-add-img {
- font-size: 14px;
- font-weight: bold;
- color: #999999;
- border: 1px dashed #707070;
- border-radius: 5px;
- padding: 9px 0;
- text-align: center;
- margin-top: 24px;
- }
- .diy-sty-img {
- position: relative;
- background: #FFF;
- }
- .diy-upd-img {
- position: absolute;
- bottom: 0;
- left: 0;
- color: #999999;
- background: rgb(0 0 0 / 50%);
- width: 100%;
- text-align: center;
- min-height: 6%;
- z-index: 101;
- }
- .diy-upd-icon {
- position: absolute;
- top: -6px;
- right: -6px;
- background: rgb(0 0 0 / 50%);
- border-radius: 50%;
- color: #FFF;
- padding: 2px;
- font-size: 12px;
- }
- .diy-upd-img:hover,
- .diy-upd-icon:hover,
- .diy-url:hover,
- .diy-add-img:hover {
- cursor: pointer;
- }
- .diy-img-del-model {
- position: absolute;
- top: 10px;
- right: 9px;
- z-index: 101;
- }
- .diy-del-text {
- text-align: center;
- margin-bottom: 10px;
- }
- .diy-del-btn {
- border: 1px solid #bb3f3f;
- color: #bb3f3f;
- }
- .img_button_text {
- font-size: 12px;
- font-weight: bold;
- color: #999999;
- margin-top: 2px;
- }
- .diy-sty-img-u {
- max-height: 100%;
- width: 100%;
- }
- .diy-img-hot-zone {
- width: 100%;
- min-height: 200px;
- max-height: 950px;
- }
- .diy-upd-hot {
- height: 30px;
- line-height: 30px;
- }
- .img-hot-model {
- position: absolute;
- height: 100%;
- width: 100%;
- top: 0;
- left: 0;
- z-index: 100;
- }
- .img-hot-model:hover,
- .diy-img-del-model:hover {
- cursor: pointer;
- }
- .img-hot-zone-model {
- border: 1px solid red;
- position: absolute;
- background: rgba(233, 243, 253, 0.8);
- color: #3892F1;
- border: 1px solid #3892F1;
- }
- .diy-img-setting .el-dialog__header {
- border-bottom: 1px solid #f2f2f2;
- padding: 12px 22px;
- }
- .diy-img-setting .el-dialog__body {
- padding: 0;
- }
- .diy-hotzone-pop {
- padding: 10px 20px;
- }
- </style>
|