Authored by htoooth

add banner comp

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<title>iView project</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0">
<link rel="stylesheet" href="/dist/vendors.css">
<link rel="stylesheet" href="/dist/app-home.css">
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="/dist/vendors.js"></script>
<script type="text/javascript" src="/dist/app-home.js"></script>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<title>iView project</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0">
<link rel="stylesheet" href="/dist/vendors.css">
<link rel="stylesheet" href="/dist/app-sort.css">
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="/dist/vendors.js"></script>
<script type="text/javascript" src="/dist/app-sort.js"></script>
</body>
</html>
\ No newline at end of file
... ... @@ -9,7 +9,7 @@ class Api {
if (!PRODUCTION) {
data = Object.assign({}, data, {
debug: 'XYZ'
}).catch(this.catch);
});
}
return util.ajax.get(url, data).then(result => result.data);
... ...
... ... @@ -2,59 +2,21 @@
<div>
<table class="banner-table">
<tbody>
<tr v-for="(i,index) in value_" :key="i.imgId">
<tr v-for="(i,index) in value_" :key="i">
<th>{{+index + 1}}</th>
<th>
<file-upload></file-upload>
<file-upload
:default-file="i.src | removeImageParams"
:id="index"
@success="onUploadSuccess"
@remove="onUploadRemove"
>
</file-upload>
</th>
<th>
<Form>
<FormItem>
<Select v-model="i.url.action">
<Option value="go.h5">H5网页</Option>
<Option value="go.ufo">商品列表页</Option>
<Option value="go.pool">商品池</Option>
</Select>
</FormItem>
<template v-if="i.url.action === 'go.h5'">
<FormItem>
<Input v-model="i.url.title" placeholder="参数"/>
</FormItem>
<FormItem>
<Input v-model="i.url.url" placeholder="参数"/>
</FormItem>
</template>
<template v-if="i.url.action === 'go.ufo'">
<FormItem>
<Input v-model="i.url.productListTitle" placeholder="参数"/>
</FormItem>
<FormItem>
<Input v-model="i.url.productPool" placeholder="参数"/>
</FormItem>
<FormItem>
<Input v-model="i.url.url" placeholder="参数"/>
</FormItem>
</template>
<template v-if="i.url.action === 'go.pool'">
<FormItem>
<Input v-model="i.url.productId" placeholder="参数"/>
</FormItem>
<FormItem>
<Input v-model="i.url.url" placeholder="参数"/>
</FormItem>
</template>
</Form>
<banner-params v-model="i.url"></banner-params>
</th>
<th>
... ... @@ -73,29 +35,52 @@
<script>
import fileUpload from './drag-file-upload';
import bannerParams from './banner-params';
import util from '@/libs/util';
export default {
props: {
value: {
type: Object,
default: {}
props: ['value'],
filters: {
removeImageParams(url) {
if (!url) {
return
}
return url.split('?')[0]
}
},
data() {
return {
value_: this.handleData(this.value)
value_: this.handleData(util.clone(this.value))
}
},
methods: {
onDeleteBtnClick(i, index) {
this.value_.splice(index, 1);
this.$emit('input', this.value_);
this.$emit('input', this.handleSaveData(this.value_));
},
onAddBtnClick() {
this.value_.push({
alt: "",
bgColor: "",
imgId: "0",
isFocusRec: "0",
src: "",
url: {
action: 'go.h5',
url: ''
}
});
this.$emit('input', this.value_);
this.$emit('input', this.handleSaveData(this.value_));
},
onUploadSuccess(id, {url}) {
this.value_[id].src = url + '?imageView2/{mode}/w/{width}/h/{height}';
this.$emit('input', this.handleSaveData(this.value_));
},
onUploadRemove(id) {
this.value_[id].src = '';
this.$emit('input', this.handleSaveData(this.value_));
},
handleData(m) {
let keys = Object.keys(m);
... ... @@ -119,34 +104,46 @@ export default {
for (const i of keys) {
let a = m[i];
let url = new URL(a.url.url);
let params = new URLSearchParams(url.search);
a.url.url = `${url.origin}${url.pathname}`
if (a.url.action === 'go.ufo' && params.get('pagename') === 'productDetail') {
if (a.url.action === 'go.ufo' && util.getUrlQueryString(a.url.url, 'pagename') === 'productDetail') {
a.url.action = 'go.pool'
}
for (let p of params) {
a.url[p[0]] = p[1]
}
result.push(a)
}
console.log(result);
return result;
},
handleSaveData(m) {
let temp = util.clone(m)
for (const i of Object.keys(temp)) {
if (temp[i].url.action === 'go.pool') {
temp[i].url.action = 'go.ufo';
}
}
// array to object
const result = {}
for (const i of Object.keys(temp)) {
result[i] = temp[i]
}
return result;
},
getValue(){
return this.handleSaveData(this.value_);
}
},
watch: {
value(newVal) {
this.value_ = newVal
this.value_ = this.handleData(util.clone(newVal));
}
},
components: {
fileUpload
fileUpload,
bannerParams
}
}
</script>
... ...
<template>
<div>
<Input :value="title" @input="onUpdateTitle" placeholder="标题"/>
<Input :value="link" @input="onUpdateLink" placeholder="链接"/>
</div>
</template>
<script>
import util from '@/libs/util'
export default {
props: ['value'],
data() {
return {
title: util.getUrlQueryString(this.value, 'title'),
link: util.getLink(this.value)
}
},
watch: {
value(newVal) {
this.title = util.getUrlQueryString(newVal, 'title');
this.link = util.getLink(newVal);
}
},
methods: {
onUpdateTitle(val) {
this.title = val;
this.$emit('input', this.getUrl());
},
onUpdateLink(val) {
this.link = val;
this.$emit('input', this.getUrl());
},
getUrl() {
return `${this.link}?title=${this.title}`
}
}
}
</script>
<style>
</style>
... ...
<template>
<div>
<Form>
<FormItem>
<Select v-model="action_">
<Option value="go.h5">H5网页</Option>
<Option value="go.ufo">商品列表页</Option>
<Option value="go.pool">商品池</Option>
</Select>
</FormItem>
<FormItem>
<h5-url v-if="action_ === 'go.h5'" v-model="url_"></h5-url>
<ufo-url v-else-if="action_ === 'go.ufo'" v-model="url_"></ufo-url>
<pool-url v-else-if="action_ === 'go.pool'" v-model="url_"></pool-url>
</FormItem>
</Form>
</div>
</template>
<script>
import h5 from './banner-h5'
import ufo from './banner-ufo'
import pool from './banner-pool'
export default {
props: ['value'],
data() {
return {
url_: this.value.url,
action_: this.value.action
}
},
methods: {
},
watch: {
url_(newVal) {
this.$emit('input', {url: this.url_, action: this.action_})
},
action_(newVal) {
if (newVal === 'go.pool') {
this.url_ = 'https://m.yohobuy.com/?pagename=productDetail'
} else if (newVal === 'go.ufo') {
this.url_ = 'https://m.yohobuy.com/?pagename=productList'
} else if (newVal === 'go.h5' ){
this.url_ = ''
}
this.$emit('input', {url: this.url_, action: this.action_})
}
},
components: {
h5Url: h5,
ufoUrl: ufo,
poolUrl: pool
}
}
</script>
<style>
</style>
... ...
<template>
<div>
<Input :value="productId" @input="onUpdateProductId" placeholder="商品ID"/>
</div>
</template>
<script>
import util from '@/libs/util'
export default {
props: ['value'],
data() {
return {
pagename: util.getUrlQueryString(this.value, 'pagename') || 'productDetail',
productId: util.getUrlQueryString(this.value, 'productId'),
link: util.getLink(this.value) || 'https://m.yohobuy.com/',
}
},
watch: {
value(newVal) {
this.pagename = util.getUrlQueryString(this.value, 'pagename') || 'productDetail';
this.productId = util.getUrlQueryString(this.value, 'productId');
this.link = util.getLink(this.value) || 'https://m.yohobuy.com/';
}
},
methods: {
onUpdateProductId(val) {
this.productId = val;
this.$emit('input', this.getUrl());
},
getUrl() {
let params = new URLSearchParams();
params.append('pagename', this.pagename);
params.append('productId', this.productId);
return `${this.link}?${params}`
}
}
}
</script>
<style>
</style>
\ No newline at end of file
... ...
<template>
<div>
<Input :value="productListTitle" @input="onUpdateTitle" placeholder="标题"/>
<Input :value="productPool" @input="onUpdatePool" placeholder="商品池ID"/>
</div>
</template>
<script>
import util from '@/libs/util'
export default {
props: ['value'],
data() {
return {
pagename: util.getUrlQueryString(this.value, 'pagename') || 'productList',
productListTitle: util.getUrlQueryString(this.value, 'productListTitle'),
productPool: util.getUrlQueryString(this.value, 'productPool'),
link: util.getLink(this.value) || 'https://m.yohobuy.com/',
}
},
watch: {
value(newVal) {
this.pagename = util.getUrlQueryString(this.value, 'pagename') || 'productList';
this.productListTitle = util.getUrlQueryString(this.value, 'productListTitle');
this.productPool = util.getUrlQueryString(this.value, 'productPool');
this.link = util.getLink(this.value) || 'https://m.yohobuy.com/';
}
},
methods: {
onUpdateTitle(val) {
this.productListTitle = val;
this.$emit('input', this.getUrl());
},
onUpdatePool(val) {
this.productPool = val;
this.$emit('input', this.getUrl());
},
getUrl() {
let params = new URLSearchParams();
params.append('pagename', this.pagename);
params.append('productListTitle', this.productListTitle);
params.append('productPool', this.productPool);
return `${this.link}?${params}`
}
}
}
</script>
<style>
</style>
... ...
... ... @@ -6,9 +6,11 @@
<Modal
v-model="show"
@on-ok="onOk"
@on-cancel="onCancel"
title="轮播图资源位"
>
<banner-editor v-model="list"></banner-editor>
<banner-editor ref="editor" v-model="list"></banner-editor>
</Modal>
</div>
</template>
... ... @@ -17,6 +19,8 @@
import selectComp from './select-comp';
import bannerEditor from './banner-editor';
import ResourceService from '@/service/resource-service';
export default {
props: ['data', 'resContentDataId'],
data() {
... ... @@ -24,12 +28,33 @@ export default {
return {
imgUrl: require('assets/banner-img.png'),
show: false,
list: allData.data
list: allData.data,
allData
}
},
mounted() {
this.resourceService = new ResourceService();
},
methods: {
onClick() {
this.show = true;
},
onOk() {
this.allData.data = this.$refs.editor.getValue();
this.resourceService.editResource({
id: this.resContentDataId,
contentData: JSON.stringify(this.allData)
}).then(() => {
this.$bus.$emit('updated');
}).catch(() => {
this.$bus.$emit('updated');
})
},
onCancel() {
this.allData = JSON.parse(this.data);
this.list = this.allData.data;
this.$bus.$emit('updated');
}
},
components: {
... ...
... ... @@ -33,6 +33,9 @@ import imagePurview from './image-purview'
export default {
name: 'drag-file-upload',
props: {
id: {
type: Number
},
defaultFile: {
type: String
},
... ... @@ -69,7 +72,7 @@ export default {
},
handleSuccess(response, file, files) {
if (response.data) {
file.url = response.data.imagesList[0];
file.url = response.data
}
this.uploadList = files;
... ... @@ -91,11 +94,6 @@ export default {
desc: '文件 ' + file.name + ' 太大,不能超过 2M。'
});
},
selected(url) {
this.uploadList = this.defaultList = [{url}];
this.$emit('success', this.id, {url});
},
},
mounted() {
this.uploadList = this.$refs.upload.fileList;
... ...
... ... @@ -22,7 +22,6 @@ import selectComp from './select-comp';
import hotEditor from './hot-editor';
import ResourceService from '@/service/resource-service';
export default {
name: 'hot',
props: ['data', 'resContentDataId'],
... ... @@ -57,6 +56,9 @@ export default {
})
},
onCancel() {
this.name = this.allData.template_intro;
this.list = this.allData.data.split(',');
this.$bus.$emit('updated');
}
},
... ...
... ... @@ -10,10 +10,14 @@
<template v-else>
<Progress v-if="progress" :percent="percentage" hide-info></Progress>
</template>
<modal-purview v-model="showModal" :url="url"></modal-purview>
</div>
</template>
<script>
import modalPurview from './modal-purview'
export default {
name: 'image-purview',
props: {
... ... @@ -50,6 +54,9 @@ export default {
this.$emit('remove-image', this.url);
}
},
components: {
modalPurview
}
};
</script>
... ...
<template>
<Modal title="查看图片" :value="model" @input="input">
<img :src="url" v-if="model" style="width: 100%">
<div slot="footer"></div>
</Modal>
</template>
<script>
export default {
name: 'modal-purview',
props: ['value', 'url'],
data() {
return {
model: this.value
};
},
methods: {
input(val) {
this.model = val;
this.$emit('input', val);
}
},
watch: {
value(val) {
this.model = val;
}
}
};
</script>
... ...
<template>
<Form :model="formItem" :label-width="60">
<FormItem label="标题">
<Input :value="formItem.category_name" @input="onChangeCate" placeholder="标题"/>
</FormItem>
<FormItem label="more">
<Input :value="formItem.productListTitle" @input="onChangeTitle" placeholder="跳转列表标题"/>
</FormItem>
<FormItem >
<Select :value="formItem.type" @input="onChangeSelect">
<Option value="sort">分类</Option>
<Option value="series">系列</Option>
</Select>
</FormItem>
<FormItem >
<Input :value="formItem.type_id" placeholder="分类代码" @input="onChangeType" />
</FormItem>
<FormItem label="商品编码">
<Input :value="formItem.product_ids" type="textarea" @input="onChangeIds" :rows="4" placeholder="多个商品以英文逗号分隔"/>
</FormItem>
<Button @click="onDelete">删除</Button>
</Form>
</template>
<script>
export default {
props: ["value"],
data() {
let type = 'sort' in this.value.more_url.params.listparams ? 'sort' : 'series';
let type_id = this.value.more_url.params.listparams[type] || 0
let productListTitle = this.value.more_url.params.productListTitle || '';
return {
formItem: {
category_name: this.value.category_name,
product_ids: this.value.product_ids,
productListTitle,
type,
type_id,
}
};
},
methods: {
print() {
console.log(this.getValue());
},
onDelete() {
this.$emit('on-remove');
},
getValue() {
let vm = this;
return {
category_name: vm.formItem.category_name,
product_ids: vm.formItem.product_ids,
more_url: {
action: "go.ufo",
params: {
pagename: "productList",
productListTitle: vm.formItem.productListTitle,
listparams: { [vm.formItem.type]: vm.formItem.type_id }
}
}
};
},
onChangeCate(v) {
this.formItem.category_name = v;
this.$emit('on-change', this.getValue());
},
onChangeTitle(v) {
this.formItem.productListTitle = v;
this.$emit('on-change', this.getValue());
},
onChangeSelect(v) {
this.formItem.type = v;
this.$emit('on-change', this.getValue());
},
onChangeType(v) {
this.formItem.type_id = v;
this.$emit('on-change', this.getValue());
},
onChangeIds(v) {
this.formItem.product_ids = v;
this.$emit('on-change', this.getValue());
},
}
};
</script>
<style>
</style>
... ...
<template>
<div>
<div class="item">
<Form :model="formItem" :label-width="60">
<FormItem label="标题">
<Input v-model="formItem.input1" placeholder="标题"/>
</FormItem>
<FormItem label="more">
<Input v-model="formItem.input2" placeholder="跳转列表标题"/>
</FormItem>
<FormItem >
<Input v-model="formItem.input3" placeholder="请选择跳转列表"/>
</FormItem>
<FormItem >
<Input v-model="formItem.input4" placeholder="url"/>
</FormItem>
<FormItem label="商品编码">
<Input v-model="formItem.ids" type="textarea" :rows="4" placeholder="多个商品以英文逗号分隔"/>
</FormItem>
<Button >删除</Button>
</Form>
<div class="item" v-for="(i,index) in list" :key="i.id" draggable="true">
<sort-tab-item :value="i" @on-remove="onDeleteBtn(index)" @on-change="(v) => (onChange(index, v))"></sort-tab-item>
</div>
<Button style="margin-top:20px">添加一组</Button>
<Button style="margin-top:20px" @click="onAddBtn">添加一组</Button>
</div>
</template>
<script>
import sortTabItem from './sortTab-editor-item'
import util from '@/libs/util'
export default {
props: ["value"],
data() {
return {
formItem: {
input1: '',
input2: '',
input3: '',
input4: '',
ids: ''
},
list: [{
list: util.clone(this.value)
};
},
methods: {
onAddBtn() {
this.list.push({
category_name: '',
product_ids: '',
more_url: {
action: '',
action: "go.ufo",
params: {
pagename: "productList",
productListTitle: '',
listparams: { sort: 0}
}
}
}],
}
},
methods: {
onAddBtn() {
})
},
onDeleteBtn() {
onDeleteBtn(i, index) {
this.list.splice(index, 1);
},
getValue() {
return this.list;
},
onChange(i, v) {
this.$set(this.list, i, v);
}
},
components: {
sortTabItem
}
}
};
</script>
<style>
... ... @@ -67,7 +56,8 @@ export default {
padding-top: 30px;
padding-left: 20px;
padding-right: 20px;
margin-bottom: 20px;
padding-bottom: 20px;
cursor: move;
}
.item:hover {
... ...
<template>
<div>
<select-comp :cb="onClick">
<img src="~assets/sort_item.png" alt="" srcset="" width="100%">
<img src="~assets/sort_item.png" alt="" srcset="" width="100%">
</select-comp>
<Modal v-model="show" title="品类资源位">
<sort-tab-editor></sort-tab-editor>
<Modal v-model="show" title="品类资源位" @on-ok="onOk" @on-cancel="onCancel">
<sort-tab-editor ref="editor" :value="list"></sort-tab-editor>
</Modal>
</div>
</template>
... ... @@ -13,16 +13,52 @@
<script>
import selectComp from './select-comp';
import sortTabEditor from './sortTab-editor'
import ResourceService from '@/service/resource-service';
let idStart = 1;
export default {
props: ['data', 'resContentDataId'],
data() {
let allData = JSON.parse(this.data);
let vm = this;
return {
show: false
show: false,
idStart: 1,
list: vm.addId(allData.data),
allData,
}
},
mounted() {
this.resourceService = new ResourceService();
},
methods: {
onClick() {
this.show = true;
},
addId(m) {
m.forEach(i => {
i.id = Date.now() + idStart++;
})
return m;
},
onOk() {
this.allData.data = this.$refs.editor.getValue();
this.resourceService.editResource({
id: this.resContentDataId,
contentData: JSON.stringify(this.allData)
}).then(() => {
this.$bus.$emit('updated');
}).catch(() => {
this.$bus.$emit('updated');
})
},
onCancel() {
this.list = this.allData.data;
this.$bus.$emit('updated');
}
},
components: {
... ...
<template>
<div>
<Form :label-width="100">
<FormItem :label="i.poolName" v-for="i in formItem" :key="i.id">
<FormItem :label="i.poolName" v-for="i in list" :key="i.id">
<Input :value="i.poolId" @input="(v) => {onUpdate(v, i)}"/>
</FormItem>
</Form>
... ... @@ -19,14 +19,12 @@ export default {
}
},
data() {
return {
formItem: this.list
}
return {}
},
methods: {
onUpdate(v, i) {
i.poolId = v
this.$emit('update:list', this.formItem)
this.$emit('update:list', this.list)
}
},
mounted() {
... ...
... ... @@ -10,7 +10,7 @@
@on-ok="onOk"
@on-cancel="onCancel"
>
<tab-editor :list.sync="data"></tab-editor>
<tab-editor :list.sync="list"></tab-editor>
</Modal>
</div>
</template>
... ... @@ -19,13 +19,15 @@
import selectComp from './select-comp';
import tabEditor from './tab-editor';
import ResourceService from '@/service/resource-service';
import util from '@/libs/util';
export default {
name: 'tab',
props: ['data'],
data() {
return {
show: false
show: false,
list: util.clone(this.data)
}
},
mounted() {
... ... @@ -36,7 +38,7 @@ export default {
this.show = true;
},
onOk() {
const updateVal = this.data.map((i) => {
const updateVal = this.list.map((i) => {
return {
id: i.id,
poolId: i.poolId
... ... @@ -47,9 +49,9 @@ export default {
this.$bus.$emit('updated');
},
onCancel() {
this.list = util.clone(this.data)
this.$bus.$emit('updated');
},
},
components: {
selectComp,
... ...
... ... @@ -28,4 +28,43 @@ function getQueryString(name) {
util.getQueryString = getQueryString
function getUrlQueryString(url, name) {
if (!url) {
return ''
}
console.log(url);
let searchParams = url.split('?')[1]
let urlParams = new URLSearchParams(searchParams);
return urlParams.get(name) || ''
}
function getLink(url) {
if (!url) {
return ''
}
let urlObj = url.split('?')[0];
return `${urlObj}`;
}
util.getUrlQueryString = getUrlQueryString;
util.getLink = getLink;
function clone(aObject) {
if (!aObject) {
return aObject;
}
let bObject, v, k;
bObject = Array.isArray(aObject) ? [] : {};
for (k in aObject) {
v = aObject[k];
bObject[k] = (typeof v === "object") ? clone(v) : v;
}
return bObject;
}
util.clone = clone;
export default util;
\ No newline at end of file
... ...
... ... @@ -27,10 +27,12 @@ class ResourceService extends Service {
return 0;
});
resContentInfos.push({
type: 'resGoodsPoools',
data: resGoodsPools
});
if (resGoodsPools) {
resContentInfos.push({
type: 'resGoodsPoools',
data: resGoodsPools
});
}
return resContentInfos;
});
... ...
... ... @@ -41,6 +41,7 @@
this.init();
this.$bus.$on('updated', () => {
console.log('updated');
this.init();
})
},
... ...
This diff could not be displayed because it is too large.