Commit b341cbe0 authored by Xuguangxing's avatar Xuguangxing

feat: 对接接口并新增选择页面交互

parent bd777a97
...@@ -30,8 +30,17 @@ export default class NavigatorController extends Controller { ...@@ -30,8 +30,17 @@ export default class NavigatorController extends Controller {
// 保存导航配置 // 保存导航配置
public async saveNavigatorConfig(ctx: Context) { public async saveNavigatorConfig(ctx: Context) {
const pageInfo = ctx.request.body; const pageInfo = ctx.request.body;
console.log(pageInfo); if (!pageInfo.id) {
// ctx.body = ctx.helper.ok(result); delete pageInfo.id;
ctx.body = 1; }
try {
await ctx.service.navigator.saveOrUpdate(pageInfo);
ctx.body = ctx.helper.ok({});
} catch (e) {
ctx.logger.info(`保存导航配置异常, ${JSON.stringify(e)}`);
ctx.body = ctx.helper.fail({
message: '保存导航配置失败'
});
}
} }
} }
\ No newline at end of file
...@@ -38,9 +38,29 @@ ...@@ -38,9 +38,29 @@
}) })
author: string; author: string;
@Column({
field: 'bgColor',
type: DataType.STRING(255)
})
bgColor: string;
@Column({
field: 'bgImg',
type: DataType.STRING(255)
})
bgImg: string;
@Column({ @Column({
field: 'navigatorData', field: 'navigatorData',
type: DataType.TEXT type: DataType.TEXT,
get() {
const configData = this.getDataValue('navigatorData');
return configData ? JSON.parse(configData) : null
},
set(value) {
this.setDataValue('navigatorData', JSON.stringify(value))
// return JSON.stringify(value);
}
}) })
navigatorData: string; navigatorData: string;
......
...@@ -42,4 +42,22 @@ export default class ArticeService extends Service { ...@@ -42,4 +42,22 @@ export default class ArticeService extends Service {
}) })
return res; return res;
} }
// 保存或编辑
async saveOrUpdate(data) {
if (data.id) {
// 编辑
const id = data.id;
const saveData = Object.assign({}, data);
delete saveData.id;
const res = await this.context.model.NavigatorConfig.update(saveData, {
where: {
id
}
})
return res;
}
// 保存
const res = await this.context.model.NavigatorConfig.create(data);
return res;
}
} }
...@@ -9,5 +9,8 @@ export default { ...@@ -9,5 +9,8 @@ export default {
}, },
deleteNavigator(params) { deleteNavigator(params) {
return http.post('http://localhost:7002/navigator/delete', params); return http.post('http://localhost:7002/navigator/delete', params);
},
saveNavigator(params) {
return http.post('http://localhost:7002/navigator/save', params);
} }
}; };
\ No newline at end of file
...@@ -15,7 +15,19 @@ export const columns = function(pointer) { ...@@ -15,7 +15,19 @@ export const columns = function(pointer) {
{ {
align: 'center', align: 'center',
title: '所选页面', title: '所选页面',
key: 'pages' render: (h, params) => {
const navigatorData = params.row.navigatorData;
let str = '';
try {
for (let i = 0; i < navigatorData.length; i++) {
str += `${i + 1}-${navigatorData[i].pageName}; `;
}
return h('span', str);
} catch (e) {
console.log(e);
}
return h('span', str);
}
}, },
{ {
align: 'center', align: 'center',
...@@ -99,20 +111,26 @@ export const urlTableColumns = function(pointer) { ...@@ -99,20 +111,26 @@ export const urlTableColumns = function(pointer) {
return [ return [
{ {
align: 'center', align: 'center',
title: 'ID', title: '排序',
key: 'id', key: 'id',
width: 80 width: 80
}, },
{
align: 'center',
title: '导航名称',
key: 'configName',
width: 120
},
{ {
align: 'center', align: 'center',
title: '所选页面', title: '所选页面',
key: 'name', key: 'pageName',
width: 300 width: 120
}, },
{ {
align: 'center', align: 'center',
title: '跳转链接', title: '跳转链接',
key: 'pages' key: 'pageUrl'
}, },
]; ];
}; };
\ No newline at end of file
<template>
<div>
<div class="search-bar">
<Form @submit.native.prevent inline ref="searchForm" :model="searchForm" class="inline">
<Form-item label="名称" prop="name">
<Input v-model="searchForm.pageName" class="comWidth" />
</Form-item>
<Form-item label="描述" prop="pageDescribe">
<Input v-model="searchForm.pageDescribe" class="comWidth" />
</Form-item>
<Form-item label="作者" prop="author">
<Input v-model="searchForm.author" class="comWidth" />
</Form-item>
<FormItem class="btnGroupStyle">
<div>
<Button class="btnStyle" @click="reset()">重置</Button>
<Button type="primary" class="btnStyle" @click="filter">查询</Button>
</div>
</FormItem>
</Form>
</div>
<div class="tableGroupStyle">
<Table
:columns="columns"
:data="tableData"
class="tableStyle"
/>
<Page
:total="total"
v-if="total > 0"
show-elevator
show-sizer
class="pageStyle"
:current="searchForm.pageNo"
:pageSize="searchForm.pageSize"
@on-change="changePageNo"
/>
<!-- @on-change="changePageNo"
@on-page-size-change="changePageSize" -->
</div>
</div>
</template>
<script>
import api from '@api/editor.api'
import config from '@/config/index';
export default {
data() {
return {
total: 0,
searchForm: {
pageName: '',
pageDescribe: '',
author: '',
pageSize: 10,
pageNo: 1
},
columns: [
{
align: 'center',
title: '页面名称',
key: 'pageName',
width: 150,
},
{
align: 'center',
title: '描述',
key: 'pageDescribe',
width: 150,
},
{
align: 'center',
title: '作者',
key: 'author',
width: 100
},
{
align: 'center',
title: '封面',
width: 60,
render: (h, params) => {
return h('div', {
style: {
padding: '5px 0',
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}
}, [
h('Img', {
style: {
width: '35px'
},
attrs: {
src: params.row.coverImage
}
})
])
}
},
{
align: 'center',
title: '链接',
render: (h, params) => {
return h('span', `${config.h5Host}/activity/${params.row.uuid}?tenantId=${params.row.tenantId}&vccToken={token}`)
}
},
{
align: 'center',
title: '操作',
width: 80,
render: (h, params) => {
const row = params.row;
return h('div', [
h('Button', {
props: {
type: 'primary',
size: 'small'
},
on: {
click: () => {
this.select(row);
}
}
}, '选择')
]);
},
}
],
tableData: []
}
},
created() {
this.query()
},
methods: {
filter() {
this.searchForm.pageNo = 1;
this.searchForm.pageSize = 10;
this.query();
},
changePageNo(pageNo) {
this.searchForm.pageNo = pageNo;
this.query();
},
select(row) {
this.$emit('selectActivityPage', {
pageType: 2,
pageUrl: `${config.h5Host}/activity/${row.uuid}?tenantId=${row.tenantId}&vccToken={token}`,
pageName: row.pageName
});
},
async query() {
const res = await api.getPageList(this.searchForm);
this.total = res.total || 0;
this.tableData = res.data || []
},
reset() {
this.searchForm = {
pageName: '',
pageDescribe: '',
author: '',
pageSize: 10,
pageNo: 1
}
},
}
}
</script>
<style scoped lang="less">
.comWidth {
width: 200px;
}
.search-bar{
width: 100%;
height: 50px;
.btnGroupStyle{
button{
margin-right: 6px;
}
}
/deep/ .ivu-form-item{
margin-bottom: 0;
}
/deep/ .ivu-form-item-label {
font-weight: bold;
display: inline-block;
}
/deep/.ivu-form-item-content {
display: inline-block;
}
}
.tableGroupStyle {
background: #fff;
.toolBarStyle {
display: flex;
justify-content: space-between;
align-items: center;
}
.pageStyle {
margin-top: 20px;
width: 100%;
text-align: right;
}
}
</style>
\ No newline at end of file
<template> <template>
<Modal v-model="show" :title="title" width="500" @on-cancel="close"> <Modal v-model="show" :title="title" width="500" @on-cancel="close">
<div class="navigator-info"> <div class="navigator-info">
<div class="navigator-info-name">名称</div> <div class="navigator-info-name"><i>*</i>名称</div>
<div class="navigator-info-input"> <div class="navigator-info-input">
<Input v-model="name" placeholder="仅用于内部运营人员识别使用" style="width: 300px" /> <Input v-model="name" placeholder="仅用于内部运营人员识别使用" style="width: 300px" />
</div> </div>
</div> </div>
<div class="navigator-info">
<div class="navigator-info-name">导航背景色</div>
<div class="navigator-info-input color">
<Input class="color-input" v-model="bgColor"/>
<ColorPicker v-model="bgColor" />
</div>
</div>
<div class="navigator-info">
<div class="navigator-info-name">导航背景图</div>
<div class="navigator-info-input">
<uploader v-model="bgImg" class="uploader" />
</div>
</div>
<div class="navigator-list"> <div class="navigator-list">
<div <div
class="navigator-list-item" class="navigator-list-item"
...@@ -17,11 +30,11 @@ ...@@ -17,11 +30,11 @@
<Icon type="close-round" @click="deleteNavigatorConfigItem(index)"></Icon> <Icon type="close-round" @click="deleteNavigatorConfigItem(index)"></Icon>
</div> </div>
<div class="navigator-list-item_content"> <div class="navigator-list-item_content">
<span>导航名称</span> <span><i>*</i>导航名称</span>
<Input v-model="item.name" placeholder="请输入导航名称" /> <Input v-model="item.name" placeholder="请输入导航名称" />
</div> </div>
<div class="navigator-list-item_content"> <div class="navigator-list-item_content">
<span>类型</span> <span><i>*</i>类型</span>
<div class="navigator-list-item_content_list"> <div class="navigator-list-item_content_list">
<RadioGroup v-model="item.type"> <RadioGroup v-model="item.type">
<Radio :label="1"> <Radio :label="1">
...@@ -37,26 +50,26 @@ ...@@ -37,26 +50,26 @@
<span /> <span />
<div class="navigator-list-item_content_settings"> <div class="navigator-list-item_content_settings">
<div class="item"> <div class="item">
<div class="label">选中图标</div> <div class="label"><i>*</i>选中图标</div>
<div class="setting"> <div class="setting">
<uploader v-model="item.selectIcon" class="uploader" /> <uploader v-model="item.selectIcon" class="uploader" />
</div> </div>
</div> </div>
<div class="item"> <div class="item">
<div class="label">未选中图标</div> <div class="label"><i>*</i>未选中图标</div>
<div class="setting"> <div class="setting">
<uploader v-model="item.icon" class="uploader" /> <uploader v-model="item.icon" class="uploader" />
</div> </div>
</div> </div>
<div class="item" v-if="item.type == 1"> <div class="item" v-if="item.type == 1">
<div class="label">选中文案颜色</div> <div class="label"><i>*</i>选中文案颜色</div>
<div class="setting"> <div class="setting">
<Input class="color-input" v-model="item.selectColor"/> <Input class="color-input" v-model="item.selectColor"/>
<ColorPicker v-model="item.selectColor" /> <ColorPicker v-model="item.selectColor" />
</div> </div>
</div> </div>
<div class="item" v-if="item.type == 1"> <div class="item" v-if="item.type == 1">
<div class="label">未选中文案颜色</div> <div class="label"><i>*</i>未选中文案颜色</div>
<div class="setting"> <div class="setting">
<Input class="color-input" v-model="item.color"/> <Input class="color-input" v-model="item.color"/>
<ColorPicker v-model="item.color" /> <ColorPicker v-model="item.color" />
...@@ -64,6 +77,16 @@ ...@@ -64,6 +77,16 @@
</div> </div>
</div> </div>
</div> </div>
<div class="navigator-list-item_content">
<span><i>*</i>选择页面</span>
<Button @click="clickSelectPageButton(index)">选择</Button>
</div>
<div class="navigator-list-item_content">
<span></span>
<span class="select" v-if="item.pageName && item.pageUrl">
{{item.pageName}}<template v-if="item.pageType != 1"> - {{item.pageUrl}}</template>
</span>
</div>
</div> </div>
</div> </div>
<div class="navigator-add"> <div class="navigator-add">
...@@ -73,13 +96,36 @@ ...@@ -73,13 +96,36 @@
<Button type="ghost" @click="close">取消</Button> <Button type="ghost" @click="close">取消</Button>
<Button type="primary" @click="confirm">保存</Button> <Button type="primary" @click="confirm">保存</Button>
</div> </div>
<Modal v-model="showSelectPageModal" id="selectPageModal" title="选择页面" width="1000" :styles="{zIndex: 999999}">
<Tabs :value="pageTabType">
<TabPane label="功能页面" name="1">
<featurePageTable
@selectFeaturePage="selectFeaturePage"
/>
</TabPane>
<TabPane label="活动页面" name="2">
<activityPageTable @selectActivityPage="selectActivityPage" />
</TabPane>
<TabPane label="导航页面" name="3">
<navigatorPageTable @selectNavigatorPage="selectNavigatorPage" />
</TabPane>
</Tabs>
<div slot="footer" />
</Modal>
</Modal> </Modal>
</template> </template>
<script> <script>
import uploader from '../../../component/DynamicForm/component/Upload/index.vue' import uploader from '../../../component/DynamicForm/component/Upload/index.vue';
import featurePageTable from './featurePageTable.vue';
import activityPageTable from './activityPageTable.vue';
import navigatorPageTable from './navigatorPageTable.vue';
import navigatorApi from '@api/navigator.api'
export default { export default {
components: { components: {
uploader uploader,
featurePageTable,
activityPageTable,
navigatorPageTable
}, },
props: { props: {
value: { value: {
...@@ -99,8 +145,23 @@ export default { ...@@ -99,8 +145,23 @@ export default {
const obj = Object.assign({}, val); const obj = Object.assign({}, val);
this.name = val.name; this.name = val.name;
this.id = val.id; this.id = val.id;
this.bgColor = val.bgColor;
this.bgImg = val.bgImg;
this.navigatorData = obj.navigatorData; this.navigatorData = obj.navigatorData;
} else {
this.name = '';
this.id = '';
this.bgColor = '';
this.bgImg = '';
this.navigatorData = [];
}
let author = '';
try {
author = JSON.parse(localStorage.getItem('user')).name;
} catch (e) {
author = '';
} }
this.author = author;
}, },
immediate: true immediate: true
} }
...@@ -114,13 +175,7 @@ export default { ...@@ -114,13 +175,7 @@ export default {
} }
}, },
created() { created() {
let author = '';
try {
author = JSON.parse(localStorage.getItem('user')).name;
} catch (e) {
author = '';
}
this.author = author;
}, },
data() { data() {
return { return {
...@@ -129,6 +184,8 @@ export default { ...@@ -129,6 +184,8 @@ export default {
navigatorData: [], // 导航配置 navigatorData: [], // 导航配置
id: '', id: '',
author: '', author: '',
bgColor: '',
bgImg: '',
standardEditDataModel: { // 新增、编辑时会用到的标准导航数据模型 standardEditDataModel: { // 新增、编辑时会用到的标准导航数据模型
name: '', name: '',
type: 1, type: 1,
...@@ -136,14 +193,39 @@ export default { ...@@ -136,14 +193,39 @@ export default {
selectColor: '', selectColor: '',
icon: '', icon: '',
selectIcon: '', selectIcon: '',
page: { pageType: '',
pageType: '', pageUrl: '',
pageUrl: '' pageName: ''
} },
} selectPageIndex: -1, // 选择页面 config索引
showSelectPageModal: false,
pageTabType: "1", // 标签页默认
} }
}, },
methods: { methods: {
selectNavigatorPage(data) {
// 选择导航页面
},
selectActivityPage(data) {
// 选择活动页面(量子积木页面)
this.navigatorData[this.selectPageIndex].pageType = data.pageType;
this.navigatorData[this.selectPageIndex].pageUrl = data.pageUrl;
this.navigatorData[this.selectPageIndex].pageName = data.pageName;
this.showSelectPageModal = false;
},
selectFeaturePage(data) {
// 选择功能页面
console.log('选择功能页面', data)
this.navigatorData[this.selectPageIndex].pageType = data.pageType;
this.navigatorData[this.selectPageIndex].pageUrl = data.pageUrl; // H5端根据pageUrl进行跳转
this.navigatorData[this.selectPageIndex].pageName = data.pageName;
this.showSelectPageModal = false;
},
clickSelectPageButton(index) {
this.selectPageIndex = index;
this.showSelectPageModal = true;
},
close() { close() {
// 关闭事件 // 关闭事件
this.$emit('close') this.$emit('close')
...@@ -155,6 +237,8 @@ export default { ...@@ -155,6 +237,8 @@ export default {
this.navigatorData = []; this.navigatorData = [];
this.id = ''; this.id = '';
this.author = ''; this.author = '';
this.bgColor = '';
this.bgImg = '';
}, },
addNavigatorConfig() { addNavigatorConfig() {
// 添加导航配置 // 添加导航配置
...@@ -200,6 +284,10 @@ export default { ...@@ -200,6 +284,10 @@ export default {
this.$toast('纯图形式配置缺失,请填写后重试'); this.$toast('纯图形式配置缺失,请填写后重试');
return false; return false;
} }
if(!arr[i].pageName || !arr[i].pageUrl || !arr[i].pageType) {
this.$toast('请选择页面');
return false;
}
} }
if (!navigatorNameExist) { if (!navigatorNameExist) {
this.$toast('导航名称缺失,请填写后重试'); this.$toast('导航名称缺失,请填写后重试');
...@@ -211,29 +299,59 @@ export default { ...@@ -211,29 +299,59 @@ export default {
} }
return true; return true;
}, },
confirm() { async confirm() {
// 提交 // 提交
// 首先要进行校验 // 首先要进行校验
if (!this.validate()) return; if (!this.validate()) return;
console.log(this.navigatorData) const params = {
name: this.name,
navigatorData: this.navigatorData,
author: this.author,
id: this.id,
bgColor: this.bgColor,
bgImg: this.bgImg
};
await navigatorApi.saveNavigator(params);
this.$toast('保存成功');
this.$emit('close', 1);
this.resetData();
} }
}, },
} }
</script> </script>
<style scoped lang="less"> <style scoped lang="less">
#selectPageModal{
z-index: 1009;
/deep/ .ivu-modal-mask, /deep/ .ivu-modal-wrap{
z-index: 1009
}
}
/deep/ .ivu-modal-body{ /deep/ .ivu-modal-body{
max-height: 70vh; max-height: 70vh;
overflow-y: auto; overflow-y: auto;
} }
.navigator-info{ .navigator-info{
width: 100%; width: 100%;
height: 40px; // height: 40px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; margin-bottom: 20px;
&-name{ &-name{
margin-right: 10px; margin-right: 10px;
width: 80px;
text-align: right;
i{
color:#f00;
}
}
&-input{
&.color{
display: flex;
align-items: center;
.color-input{
margin-right: 10px;
}
}
} }
} }
.navigator-list{ .navigator-list{
...@@ -259,6 +377,12 @@ export default { ...@@ -259,6 +377,12 @@ export default {
width: 60px; width: 60px;
flex-shrink: 0; flex-shrink: 0;
margin-right: 10px; margin-right: 10px;
i{
color:#f00;
}
&.select{
display: inline-block; flex: 1;word-break:break-all
}
} }
&_list{ &_list{
display: flex; display: flex;
...@@ -281,6 +405,9 @@ export default { ...@@ -281,6 +405,9 @@ export default {
.label{ .label{
width: 100px; width: 100px;
flex-shrink: 0; flex-shrink: 0;
i{
color:#f00;
}
} }
.setting{ .setting{
display: flex; display: flex;
......
<template>
<div>
<Table
:columns="columns"
:data="tableData"
class="tableStyle"
/>
</div>
</template>
<script>
export default {
data() {
return {
columns: [
{
align: 'center',
title: '页面名称',
key: 'name',
},
{
align: 'center',
title: '操作',
render: (h, params) => {
const row = params.row;
return h('div', [
h('Button', {
props: {
type: 'primary',
size: 'small'
},
on: {
click: () => {
this.select(row);
}
}
}, '选择')
]);
},
}
],
tableData: [
{
name: '首页tab',
url: 'home'
},
{
name: '购物车tab',
url: 'shopcart'
},
{
name: '我的tab',
url: 'user'
}
]
}
},
methods: {
select(row) {
this.$emit('selectFeaturePage', {
pageType: 1,
pageUrl: row.url,
pageName: row.name
});
}
}
}
</script>
\ No newline at end of file
<template>
<div></div>
</template>
\ No newline at end of file
...@@ -16,30 +16,30 @@ ...@@ -16,30 +16,30 @@
</FormItem> </FormItem>
</Form> </Form>
</div> </div>
<div class="tableGroupStyle"> <div class="tableGroupStyle">
<div class="toolBarStyle"> <div class="toolBarStyle">
<h3>查询数据</h3> <h3>查询数据</h3>
<div> <div>
<Button type="primary" class="btnStyle" @click="add">新增</Button> <Button type="primary" class="btnStyle" @click="add">新增</Button>
<slot></slot> <slot></slot>
</div>
</div> </div>
<Table </div>
:columns="columns" <Table
:data="tableData" :columns="columns"
class="tableStyle" :data="tableData"
/> class="tableStyle"
<Page />
:total="total" <Page
v-if="total > 0" :total="total"
show-elevator v-if="total > 0"
show-sizer show-elevator
class="pageStyle" show-sizer
:current="searchForm.pageNo" class="pageStyle"
:pageSize="searchForm.pageSize" :current="searchForm.pageNo"
@on-change="changePageNo" :pageSize="searchForm.pageSize"
@on-page-size-change="changePageSize" @on-change="changePageNo"
/> @on-page-size-change="changePageSize"
/>
</div> </div>
<Modal v-model="showPagesUrl" title="页面地址列表" width="900"> <Modal v-model="showPagesUrl" title="页面地址列表" width="900">
<Table <Table
...@@ -52,7 +52,7 @@ ...@@ -52,7 +52,7 @@
<addOrEditNavigator <addOrEditNavigator
v-model="showAddOrEdit" v-model="showAddOrEdit"
:navigatorConfig="navigatorConfig" :navigatorConfig="navigatorConfig"
@close="showAddOrEdit = false" @close="closeAddOrEdit"
/> />
</div> </div>
</template> </template>
...@@ -96,6 +96,13 @@ export default { ...@@ -96,6 +96,13 @@ export default {
this.tableData = res.data || [] this.tableData = res.data || []
}, },
closeAddOrEdit(refresh){
this.showAddOrEdit = false;
this.navigatorConfig = null;
if (refresh) {
this.query();
}
},
add() { add() {
this.navigatorConfig = null; this.navigatorConfig = null;
this.showAddOrEdit = true; this.showAddOrEdit = true;
...@@ -113,8 +120,18 @@ export default { ...@@ -113,8 +120,18 @@ export default {
}, },
showAddr(row) { showAddr(row) {
// 查看地址列表 // 查看地址列表
let configs = row.navigatorData || [];
let arr = [];
for (let i = 0; i < configs.length; i++) {
let obj = {};
obj.id = i + 1;
obj.configName = configs[i].name;
obj.pageName = configs[i].pageName;
obj.pageUrl = configs[i].pageType == 1 ? '' : configs[i].pageUrl;
arr.push(obj)
}
this.urlTableData = arr;
this.showPagesUrl = true; this.showPagesUrl = true;
console.log(row);
}, },
preview(row) { preview(row) {
// 预览,默认预览第一个导航页面 // 预览,默认预览第一个导航页面
...@@ -122,7 +139,6 @@ export default { ...@@ -122,7 +139,6 @@ export default {
}, },
edit(row) { edit(row) {
// 编辑 // 编辑
console.log(row);
this.navigatorConfig = row; this.navigatorConfig = row;
this.showAddOrEdit = true; this.showAddOrEdit = true;
}, },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment