This commit is contained in:
chc
2022-10-21 11:22:56 +08:00
138 changed files with 14354 additions and 2038 deletions

View File

@@ -5,8 +5,10 @@
</template>
<script>
export default {
};
</script>

View File

@@ -6,7 +6,8 @@ import {
deleteRequest,
importRequest,
getRequestWithNoToken,
commonUrl
commonUrl,
postRequestWithNoForm
} from "@/libs/axios";
// 获取数据字典
export const getDictData = "/dictData/getByType/";
@@ -355,3 +356,13 @@ export const refundStatistics = params => {
export const refundPriceStatistics = params => {
return getRequest(`/statistics/refund/order/getPrice`, params);
};
//下载结算单
export const downLoadGoods = () => {
return getRequest(`/goods/import/downLoad/`, {}, 'blob')
}
// 上传待发货的订单列表
export const uploadGoodsExcel = params => {
return postRequestWithNoForm(`/goods/import/import`, params );
};

View File

@@ -6,6 +6,9 @@ import {
deleteRequest,
getRequestWithNoToken,
postRequestWithNoTokenData,
putRequestWithNoForm,
postRequestWithNoToken,
postRequestWithNoForm,
commonUrl,
} from "@/libs/axios";
@@ -14,13 +17,15 @@ export const getAllCity = (params) => {
return getRequest(commonUrl+'/common/common/region/allCity', params)
}
// 获取全部权限数据
export const getCurrentPermissionList = (params) => {
return getRequest("/menu/memberMenu", params);
};
// 登陆
export const getHomeNotice = params => {
return getRequest("/other/article/getByPage?type=STORE_ARTICLE&pageSize=15");
};
// 登陆
export const getSellerHomeData = params => {
return getRequest("/statistics/index", params);
@@ -122,10 +127,9 @@ export const unRelate = params => {
export const getRelatedListData = params => {
return getRequest("/relate/findByCondition", params);
};
// 获取用户数据 多条件
export const getUserListData = params => {
return getRequest("/user/getByCondition", params);
return getRequest("/clerk", params);
};
// 通过用户名搜索
export const searchUserByName = (username, params) => {
@@ -138,7 +142,7 @@ export const getAllUserData = params => {
// 添加用户
export const addUser = params => {
return postRequest("/user/admin/add", params);
return postRequest("/clerk", params);
};
// 编辑用户
export const editUser = params => {
@@ -213,25 +217,25 @@ export const deleteMessageSend = (ids, params) => {
// 分页获取文件数据
export const getFileListData = params => {
return getRequest("/file", params);
return getRequest(`${commonUrl}/common/common/file`, params);
};
// 复制文件
export const copyFile = params => {
return postRequest("/file/copy", params);
return postRequest(`${commonUrl}/common/common/file/copy`, params);
};
// 重命名文件
export const renameFile = params => {
return postRequest("/file/rename", params);
return postRequest(`${commonUrl}/common/common/file/rename`, params);
};
// 删除文件
export const deleteFile = (ids, params) => {
return deleteRequest(`/file/delete/${ids}`, params);
return deleteRequest(`${commonUrl}/common/common/file/delete/${ids}`, params);
};
// 下载文件
export const aliDownloadFile = (fKey, params) => {
return getRequest(`/file/ali/download/${fKey}`, params);
return getRequest(`${commonUrl}/common/common/file/ali/download/${fKey}`, params);
};
@@ -265,4 +269,100 @@ export const handleRefreshToken = (token) => {
return getRequestWithNoToken(`/passport/login/refresh/${token}`);
};
// 获取一级部门
export const initDepartment = (params) => {
return getRequest("/department", params);
};
// 添加部门
export const addDepartment = (params) => {
return postRequest("/department", params);
};
// 删除部门
export const deleteDepartment = (ids, params) => {
return deleteRequest(`/department/${ids}`, params);
};
// 编辑部门
export const editDepartment = (ids, params) => {
return putRequest(`/department/${ids} `, params);
};
// 加载部门子级数据
export const loadDepartment = (id) => {
return getRequest(`/department/${id}`);
};
// 通过部门获取全部角色数据
export const getUserByDepartmentId = (id, params) => {
return getRequest(`/departmentRole/${id}`, params);
};
// 分页获取角色数据
export const getRoleList = (params) => {
return getRequest("/role", params);
};
// 通过部门修改绑定角色
export const updateDepartmentRole = (id, params) => {
return putRequestWithNoForm(`/departmentRole/${id}`, params);
};
// 获取全部权限数据
export const getAllPermissionList = (params) => {
return getRequest("/menu/tree", params);
};
// 添加角色
export const addRole = (params) => {
return postRequest("/role", params);
};
// 删除角色
export const deleteRole = (ids, params) => {
return deleteRequest(`/role/${ids}`, params);
};
// 编辑角色
export const editRole = (params) => {
return putRequest(`/role/${params.roleId}`, params);
};
// 分配角色权限
export const editRolePerm = (params) => {
return postRequest("/role/editRolePerm", params);
};
// 查看某角色拥有的菜单
export const selectRoleMenu = (params) => {
return getRequest(`/roleMenu/${params}`);
};
// 保存角色菜单
export const saveRoleMenu = (id, params) => {
return postRequestWithNoForm(`/roleMenu/${id}`, params);
};
// 获取全部角色数据
export const getAllRoleList = (params) => {
return getRequest("/role", params);
};
export const checkClerk = (mobile) => {
return postRequest(`/clerk/${mobile}/check`);
};
// 重置用户密码
export const resetPassword = (params) => {
return postRequest(`/clerk/resetPassword/${params}`);
};
// 删除用户
export const deleteClerk = (ids) => {
return deleteRequest(`/clerk/delByIds/${ids}`);
};
// 禁 启用用户
export const enableClerk = (id, params) => {
return putRequest(`/clerk/enable/${id}`, params);
};
// 获取店员详细
export const getClerk = (id) => {
return getRequest(`/clerk/${id}`);
};
export const editOtherUser = (id, params) => {
return putRequest(`/clerk/${id}`,params);
};

View File

@@ -31,4 +31,8 @@ export const updateLogistics = (id,params) => {
return putRequest(`/other/logistics/${id}`,params);
};
export const getCheckedOn = params =>{
return getRequest(`/other/logistics/getCheckedFaceSheet`,params);
}

View File

@@ -17,6 +17,10 @@ export const queryExportOrder = params => {
return getRequest(`/order/order/queryExportOrder`, params);
};
//获取电子面单
export const getOrderFaceSheet= (orderSn,params) =>{
return postRequest(`/order/order/${orderSn}/createElectronicsFaceSheet`,params)
}
// 上传待发货的订单列表
export const uploadDeliverExcel = params => {

View File

@@ -4,10 +4,6 @@ import {
postRequest,
putRequest,
deleteRequest,
importRequest,
getRequestWithNoToken,
putRequestWithNoForm,
postRequestWithNoForm,
} from "@/libs/axios";
/**
@@ -15,8 +11,7 @@ import {
*
*/
export const setHomeSetup = params => {
return postRequest("/other/pageData/add", params);
return postRequest("/settings/pageData/save", params);
};
/**
@@ -25,7 +20,7 @@ export const setHomeSetup = params => {
*/
export const getHomeData = params => {
return getRequest(`/other/pageData/${params}`);
return getRequest(`/settings/pageData/${params}`);
};
@@ -34,8 +29,8 @@ export const getHomeData = params => {
*
*/
export const getHomeList = params => {
return getRequest(`/settings/pageData/${params.pageClientType}/pageDataList`, params);
return getRequest("/pageData/pageDataList", params);
};
@@ -43,9 +38,8 @@ export const getHomeList = params => {
* 修改楼层装修
*
*/
export const updateHome = (id,params) => {
return putRequest(`/pageData/update/${id}`, params);
export const updateHome = (id, params) => {
return putRequest(`/settings/pageData/update/${id}`, params);
};
/**
@@ -53,8 +47,7 @@ export const updateHome = (id,params) => {
*
*/
export const removePageHome = (id) => {
return deleteRequest(`/pageData/removePageData/${id}`);
return deleteRequest(`/settings/pageData/removePageData/${id}`);
};
@@ -63,7 +56,6 @@ export const removePageHome = (id) => {
*
*/
export const releasePageHome = (id) => {
return putRequest(`/pageData/releasePageData`,id);
return putRequest(`/settings/pageData/release/${id}`);
};

View File

@@ -41,10 +41,24 @@ export const getBillDetail = (id, params) => {
export const getLogistics = (id, params) => {
return getRequest(`/other/logistics`, params)
}
//返回信息
export const getIsCheck =(logisticsId) =>{
return getRequest(`other/logistics/${logisticsId}/getStoreLogistics`)
}
// 开启物流公司
export const logisticsChecked = (id, params) => {
return postRequest(`/other/logistics/${id}`, params)
return postRequest(`/other/logistics/${id}`, params, {
"Content-type": "application/json"
})
}
//获取发货地址
export const getDeliverAddress = () =>{
return getRequest(`/settings/storeSettings/storeDeliverGoodsAddress`)
}
//修改发货地址
export const editDeliverAddress = (params) =>{
return putRequest(`/settings/storeSettings/storeDeliverGoodsAddress`,params)
}
// 关闭开启物流公司
@@ -117,4 +131,9 @@ export const editShipTemplate = (id, params, headers) => {
return putRequest(`/setting/freightTemplate/${id}`, params, headers)
}
//修改电子面单等信息
export const editChecked = (logisticsId,params) => {
return putRequest(`/other/logistics/${logisticsId}/updateStoreLogistics`,params)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 KiB

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 202 KiB

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

BIN
seller/src/assets/play.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -388,6 +388,42 @@ export const result = [{
component: "sys/user-manage/userManage",
children: []
},
{
name: "clerk",
level: 1,
type: 0,
title: "店员设置",
path: "",
component: "Main",
children: [
{
name: "clerkManage",
level: 2,
type: 0,
title: "店员管理",
path: "clerkManage",
component: "shop/system/clerk/clerkManage",
children: null
},{
name: "storeDepartmentManage",
level: 2,
type: 0,
title: "部门管理",
path: "storeDepartmentManage",
component: "shop/system/department/storeDepartmentManage",
children: null
},
{
name: "storeRole",
level: 2,
type: 0,
title: "角色权限",
path: "storeRole",
component: "shop/system/role/storeRoleManage",
children: null
}
]
},
{
name: "ship",
level: 1,
@@ -415,6 +451,7 @@ export const result = [{
}
]
},
{
name: "shop",
level: 1,
@@ -423,7 +460,8 @@ export const result = [{
path: "/shop",
component: "Main",
description: "",
children: [{
children: [
{
name: "shopSetting",
level: 2,
type: 0,
@@ -432,6 +470,35 @@ export const result = [{
component: "shop/shopSetting",
children: null,
},
{
name: "wapList",
level: 2,
type: 0,
title: "移动楼层",
path: "wapList",
component: "shop/wap/wapList",
children: null
},
{
name: "pcList",
level: 2,
type: 0,
title: "PC楼层",
path: "pcList",
component: "shop/floorList",
children: null
},
// {
// name: "shopAddress",
// level: 2,
// type: 0,
// title: "自提管理",
// path: "shopAddress",
// component: "shop/shopAddress",
// children: null,
// }
// {
// name: "shopAddress",
// level: 2,
@@ -469,5 +536,6 @@ export const result = [{
children: null
}]
}]
}
},
];

View File

@@ -1,6 +1,8 @@
import lazyLoading from './lazyLoading.js';
import Cookies from "js-cookie";
import { result } from './routerJson.js';
import { getCurrentPermissionList } from "@/api/index";
const config = require('@/config/index')
@@ -9,451 +11,447 @@ let util = {
};
util.title = function (title) {
title = title || `${config.title} 商家后台`;
window.document.title = title;
title = title || `${config.title} 商家后台`;
window.document.title = title;
};
util.millsToTime = function (mills) {
if (!mills) {
return "";
}
let s = mills / 1000;
if (s < 60) {
return s.toFixed(0) + " 秒"
}
let m = s / 60;
if (m < 60) {
return m.toFixed(0) + " 分钟"
}
let h = m / 60;
if (h < 24) {
return h.toFixed(0) + " 小时"
}
let d = h / 24;
if (d < 30) {
return d.toFixed(0) + " 天"
}
let month = d / 30
if (month < 12) {
return month.toFixed(0) + " 个月"
}
let year = month / 12
return year.toFixed(0) + " 年"
if (!mills) {
return "";
}
let s = mills / 1000;
if (s < 60) {
return s.toFixed(0) + " 秒"
}
let m = s / 60;
if (m < 60) {
return m.toFixed(0) + " 分钟"
}
let h = m / 60;
if (h < 24) {
return h.toFixed(0) + " 小时"
}
let d = h / 24;
if (d < 30) {
return d.toFixed(0) + " 天"
}
let month = d / 30
if (month < 12) {
return month.toFixed(0) + " 个月"
}
let year = month / 12
return year.toFixed(0) + " 年"
};
util.inOf = function (arr, targetArr) {
let res = true;
arr.forEach(item => {
if (targetArr.indexOf(item) < 0) {
res = false;
}
});
return res;
let res = true;
arr.forEach(item => {
if (targetArr.indexOf(item) < 0) {
res = false;
}
});
return res;
};
util.oneOf = function (ele, targetArr) {
if (targetArr.indexOf(ele) >= 0) {
return true;
} else {
return false;
}
if (targetArr.indexOf(ele) >= 0) {
return true;
} else {
return false;
}
};
util.getRouterObjByName = function (routers, name) {
if (!name || !routers || !routers.length) {
return null;
}
let routerObj = null;
for (let item of routers) {
if (item.name == name) {
return item;
}
routerObj = util.getRouterObjByName(item.children, name);
if (routerObj) {
return routerObj;
}
}
if (!name || !routers || !routers.length) {
return null;
}
let routerObj = null;
for (let item of routers) {
if (item.name == name) {
return item;
}
routerObj = util.getRouterObjByName(item.children, name);
if (routerObj) {
return routerObj;
}
}
return null;
};
util.handleTitle = function (vm, item) {
if (typeof item.title == 'object') {
return item.title;
} else {
return item.title;
}
if (typeof item.title == 'object') {
return item.title;
} else {
return item.title;
}
};
util.setCurrentPath = function (vm, name) {
let title = '';
let isOtherRouter = false;
vm.$store.state.app.routers.forEach(item => {
if (item.children.length == 1) {
if (item.children[0].name == name) {
title = util.handleTitle(vm, item);
if (item.name == 'otherRouter') {
isOtherRouter = true;
}
}
} else {
item.children.forEach(child => {
if (child.name == name) {
title = util.handleTitle(vm, child);
if (item.name == 'otherRouter') {
isOtherRouter = true;
}
}
});
let title = '';
let isOtherRouter = false;
vm.$store.state.app.routers.forEach(item => {
if (item.children.length == 1) {
if (item.children[0].name == name) {
title = util.handleTitle(vm, item);
if (item.name == 'otherRouter') {
isOtherRouter = true;
}
});
let currentPathArr = [];
if (name == 'home_index') {
currentPathArr = [
{
title: util.handleTitle(vm, util.getRouterObjByName(vm.$store.state.app.routers, 'home_index')),
path: '',
name: 'home_index'
}
];
} else if ((name.indexOf('_index') >= 0 || isOtherRouter) && name !== 'home_index') {
currentPathArr = [
{
title: util.handleTitle(vm, util.getRouterObjByName(vm.$store.state.app.routers, 'home_index')),
path: '/home',
name: 'home_index'
},
{
title: title,
path: '',
name: name
}
];
}
} else {
let currentPathObj = vm.$store.state.app.routers.filter(item => {
if (item.children.length <= 1) {
return item.children[0].name == name;
} else {
let i = 0;
let childArr = item.children;
let len = childArr.length;
while (i < len) {
if (childArr[i].name == name) {
return true;
}
i++;
}
return false;
}
})[0];
if (currentPathObj.children.length <= 1 && currentPathObj.name == 'home') {
currentPathArr = [
{
title: '首页',
path: '',
name: 'home_index'
}
];
} else if (currentPathObj.children.length <= 1 && currentPathObj.name !== 'home') {
currentPathArr = [
{
title: '首页',
path: '/home',
name: 'home_index'
},
{
title: currentPathObj.title,
path: '',
name: name
}
];
} else {
let childObj = currentPathObj.children.filter((child) => {
return child.name == name;
})[0];
currentPathArr = [
{
title: '首页',
path: '/home',
name: 'home_index'
},
{
title: currentPathObj.title,
path: '',
name: currentPathObj.name
},
{
title: childObj.title,
path: currentPathObj.path + '/' + childObj.path,
name: name
}
];
item.children.forEach(child => {
if (child.name == name) {
title = util.handleTitle(vm, child);
if (item.name == 'otherRouter') {
isOtherRouter = true;
}
}
});
}
vm.$store.commit('setCurrentPath', currentPathArr);
});
let currentPathArr = [];
if (name == 'home_index') {
currentPathArr = [
{
title: util.handleTitle(vm, util.getRouterObjByName(vm.$store.state.app.routers, 'home_index')),
path: '',
name: 'home_index'
}
];
} else if ((name.indexOf('_index') >= 0 || isOtherRouter) && name !== 'home_index') {
currentPathArr = [
{
title: util.handleTitle(vm, util.getRouterObjByName(vm.$store.state.app.routers, 'home_index')),
path: '/home',
name: 'home_index'
},
{
title: title,
path: '',
name: name
}
];
} else {
let currentPathObj = vm.$store.state.app.routers.filter(item => {
if (item.children.length <= 1) {
return item.children[0].name == name;
} else {
let i = 0;
let childArr = item.children;
let len = childArr.length;
while (i < len) {
if (childArr[i].name == name) {
return true;
}
i++;
}
return false;
}
})[0];
if (currentPathObj.children.length <= 1 && currentPathObj.name == 'home') {
currentPathArr = [
{
title: '首页',
path: '',
name: 'home_index'
}
];
} else if (currentPathObj.children.length <= 1 && currentPathObj.name !== 'home') {
currentPathArr = [
{
title: '首页',
path: '/home',
name: 'home_index'
},
{
title: currentPathObj.title,
path: '',
name: name
}
];
} else {
let childObj = currentPathObj.children.filter((child) => {
return child.name == name;
})[0];
currentPathArr = [
{
title: '首页',
path: '/home',
name: 'home_index'
},
{
title: currentPathObj.title,
path: '',
name: currentPathObj.name
},
{
title: childObj.title,
path: currentPathObj.path + '/' + childObj.path,
name: name
}
];
}
}
vm.$store.commit('setCurrentPath', currentPathArr);
return currentPathArr;
return currentPathArr;
};
util.openNewPage = function (vm, name, argu, query) {
if (!vm.$store) {
return;
if (!vm.$store) {
return;
}
let storeOpenedList = vm.$store.state.app.storeOpenedList;
let openedPageLen = storeOpenedList.length;
let i = 0;
let tagHasOpened = false;
while (i < openedPageLen) {
if (name == storeOpenedList[i].name) { // 页面已经打开
vm.$store.commit('storeOpenedList', {
index: i,
argu: argu,
query: query
});
tagHasOpened = true;
break;
}
let storeOpenedList = vm.$store.state.app.storeOpenedList;
let openedPageLen = storeOpenedList.length;
let i = 0;
let tagHasOpened = false;
while (i < openedPageLen) {
if (name == storeOpenedList[i].name) { // 页面已经打开
vm.$store.commit('storeOpenedList', {
index: i,
argu: argu,
query: query
});
tagHasOpened = true;
break;
}
i++;
i++;
}
if (!tagHasOpened) {
let tag = vm.$store.state.app.tagsList.filter((item) => {
if (item.children) {
return name == item.children[0].name;
} else {
return name == item.name;
}
});
tag = tag[0];
if (tag) {
tag = tag.children ? tag.children[0] : tag;
if (argu) {
tag.argu = argu;
}
if (query) {
tag.query = query;
}
vm.$store.commit('increateTag', tag);
}
if (!tagHasOpened) {
let tag = vm.$store.state.app.tagsList.filter((item) => {
if (item.children) {
return name == item.children[0].name;
} else {
return name == item.name;
}
});
tag = tag[0];
if (tag) {
tag = tag.children ? tag.children[0] : tag;
if (argu) {
tag.argu = argu;
}
if (query) {
tag.query = query;
}
vm.$store.commit('increateTag', tag);
}
}
vm.$store.commit('setCurrentPageName', name);
}
vm.$store.commit('setCurrentPageName', name);
};
util.toDefaultPage = function (routers, name, route, next) {
let len = routers.length;
let i = 0;
let notHandle = true;
while (i < len) {
if (routers[i].name == name && routers[i].children && routers[i].redirect == undefined) {
route.replace({
name: routers[i].children[0].name
});
notHandle = false;
next();
break;
}
i++;
}
if (notHandle) {
next();
let len = routers.length;
let i = 0;
let notHandle = true;
while (i < len) {
if (routers[i].name == name && routers[i].children && routers[i].redirect == undefined) {
route.replace({
name: routers[i].children[0].name
});
notHandle = false;
next();
break;
}
i++;
}
if (notHandle) {
next();
}
};
// 将Csv文件解析为二维数组
export const getArrayFromFile = (file) => {
let nameSplit = file.name.split('.')
let format = nameSplit[nameSplit.length - 1]
return new Promise((resolve, reject) => {
let reader = new FileReader()
reader.readAsText(file) // 以文本格式读取
let arr = []
reader.onload = function (evt) {
let data = evt.target.result // 读到的数据
let pasteData = data.trim()
arr = pasteData.split((/[\n\u0085\u2028\u2029]|\r\n?/g)).map(row => {
return row.split('\t')
}).map(item => {
return item[0].split(',')
})
if (format == 'csv') resolve(arr)
else reject(new Error('[Format Error]:不是Csv文件'))
}
})
let nameSplit = file.name.split('.')
let format = nameSplit[nameSplit.length - 1]
return new Promise((resolve, reject) => {
let reader = new FileReader()
reader.readAsText(file) // 以文本格式读取
let arr = []
reader.onload = function (evt) {
let data = evt.target.result // 读到的数据
let pasteData = data.trim()
arr = pasteData.split((/[\n\u0085\u2028\u2029]|\r\n?/g)).map(row => {
return row.split('\t')
}).map(item => {
return item[0].split(',')
})
if (format == 'csv') resolve(arr)
else reject(new Error('[Format Error]:不是Csv文件'))
}
})
}
// 将二维数组转为表格数据
export const getTableDataFromArray = (array) => {
let columns = []
let tableData = []
if (array.length > 1) {
let titles = array.shift()
columns = titles.map(item => {
return {
title: item,
key: item
}
})
tableData = array.map(item => {
let res = {}
item.forEach((col, i) => {
res[titles[i]] = col
})
return res
})
}
return {
columns,
tableData
}
let columns = []
let tableData = []
if (array.length > 1) {
let titles = array.shift()
columns = titles.map(item => {
return {
title: item,
key: item
}
})
tableData = array.map(item => {
let res = {}
item.forEach((col, i) => {
res[titles[i]] = col
})
return res
})
}
return {
columns,
tableData
}
}
util.initRouter = function (vm) { // 初始化路由
const constRoutes = [];
const otherRoutes = [];
const constRoutes = [];
const otherRoutes = [];
// 404路由需要和动态路由一起加载
const otherRouter = [{
path: '/*',
name: 'error-404',
meta: {
title: '404-页面不存在'
},
component: 'error-page/404'
}];
// 判断用户是否登录
let userInfo = Cookies.get('userInfoSeller')
if (!userInfo) {
// 未登录
return;
}
// 404路由需要和动态路由一起加载
const otherRouter = [{
path: '/*',
name: 'error-404',
meta: {
title: '404-页面不存在'
},
component: 'error-page/404'
}];
// 判断用户是否登录
let userInfo = Cookies.get('userInfoSeller')
if (!userInfo) {
// 未登录
return;
}
if (!vm.$store.state.app.added) {
// 加载菜单
let menuData = result;
// 格式化数据,设置 空children 为 null
for(let i =0;i<menuData.length;i++){
let t = menuData[i].children
for(let k = 0;k<t.length;k++){
let tt = t[k].children;
for(let z = 0;z<tt.length;z++){
tt[z].children = null
// 给所有三级路由添加字段显示一级菜单name方便点击页签时的选中筛选
tt[z].firstRouterName = menuData[i].name
}
}
// 加载菜单
getCurrentPermissionList().then(res => {
if (!res.success) return false;
let menuData = res.result;
// 格式化数据,设置 空children 为 null
for (let i = 0; i < menuData.length; i++) {
let t = menuData[i].children
for (let k = 0; k < t.length; k++) {
let tt = t[k].children;
for (let z = 0; z < tt.length; z++) {
tt[z].children = null
// 给所有三级路由添加字段显示一级菜单name方便点击页签时的选中筛选
tt[z].firstRouterName = menuData[i].name
}
util.initAllMenuData(constRoutes, menuData);
util.initRouterNode(otherRoutes, otherRouter);
// 添加所有主界面路由
vm.$store.commit('updateAppRouter', constRoutes.filter(item => item.children.length > 0));
// 添加全局路由
vm.$store.commit('updateDefaultRouter', otherRoutes);
// 添加菜单路由
util.initMenuData(vm, menuData);
// 缓存数据 修改加载标识
window.localStorage.setItem('menuData', JSON.stringify(menuData));
vm.$store.commit('setAdded', true);
} else {
// 读取缓存数据
let data = window.localStorage.getItem('menuData');
if (!data) {
vm.$store.commit('setAdded', false);
return;
}
let menuData = JSON.parse(data);
// 添加菜单路由
util.initMenuData(vm, menuData);
}
}
if (!menuData) {
return;
}
util.initAllMenuData(constRoutes, menuData);
util.initRouterNode(otherRoutes, otherRouter);
// 添加所有主界面路由
vm.$store.commit('updateAppRouter', constRoutes.filter(item => item.children.length > 0));
// 添加全局路由
vm.$store.commit('updateDefaultRouter', otherRoutes);
// 添加菜单路由
util.initMenuData(vm, menuData);
// 缓存数据 修改加载标识
window.localStorage.setItem('menuData', JSON.stringify(menuData));
vm.$store.commit('setAdded', true);
})
};
// 添加所有顶部导航栏下的菜单路由
util.initAllMenuData = function (constRoutes, data) {
let allMenuData = [];
data.forEach(e => {
if (e.type == -1) {
e.children.forEach(item => {
allMenuData.push(item);
})
}
})
util.initRouterNode(constRoutes, allMenuData);
let allMenuData = [];
data.forEach(e => {
if (e.level == 0) {
e.children.forEach(item => {
allMenuData.push(item);
})
}
})
util.initRouterNode(constRoutes, allMenuData);
}
// 生成菜单格式数据
util.initMenuData = function (vm, data) {
const menuRoutes = [];
let menuData = data;
// 顶部菜单
let navList = [];
menuData.forEach(e => {
let nav = {
name: e.name,
title: e.title,
}
navList.push(nav);
})
if (navList.length < 1) {
return;
const menuRoutes = [];
let menuData = data;
// 顶部菜单
let navList = [];
menuData.forEach(e => {
let nav = {
name: e.name,
title: e.title,
}
// 存入vuex
vm.$store.commit('setNavList', navList);
let currNav = window.localStorage.getItem('currNav')
if (currNav) {
// 读取缓存title
for (var item of navList) {
if (item.name == currNav) {
vm.$store.commit('setCurrNavTitle', item.title);
break;
}
}
} else {
// 默认第一个
currNav = navList[0].name;
vm.$store.commit('setCurrNavTitle', navList[0].title);
navList.push(nav);
})
if (navList.length < 1) {
return;
}
// 存入vuex
vm.$store.commit('setNavList', navList);
let currNav = window.localStorage.getItem('currNav')
if (currNav) {
// 读取缓存title
for (var item of navList) {
if (item.name == currNav) {
vm.$store.commit('setCurrNavTitle', item.title);
break;
}
}
vm.$store.commit('setCurrNav', currNav);
for (var item of menuData) {
if (item.name == currNav) {
// 过滤
menuData = item.children;
break;
}
} else {
// 默认第一个
currNav = navList[0].name;
vm.$store.commit('setCurrNavTitle', navList[0].title);
}
vm.$store.commit('setCurrNav', currNav);
for (var item of menuData) {
if (item.name == currNav) {
// 过滤
menuData = item.children;
break;
}
util.initRouterNode(menuRoutes, menuData);
// 刷新界面菜单
vm.$store.commit('updateMenulist', menuRoutes.filter(item => item.children.length > 0));
}
util.initRouterNode(menuRoutes, menuData);
// 刷新界面菜单
vm.$store.commit('updateMenulist', menuRoutes.filter(item => item.children.length > 0));
let tagsList = [];
vm.$store.state.app.routers.map((item) => {
if (item.children.length <= 1) {
tagsList.push(item.children[0]);
} else {
tagsList.push(...item.children);
}
});
vm.$store.commit('setTagsList', tagsList);
let tagsList = [];
vm.$store.state.app.routers.map((item) => {
if (item.children.length <= 1) {
tagsList.push(item.children[0]);
} else {
tagsList.push(...item.children);
}
});
vm.$store.commit('setTagsList', tagsList);
};
// 生成路由节点
util.initRouterNode = function (routers, data) { // data为所有子菜单数据
for (var item of data) {
let menu = Object.assign({}, item);
menu.component = lazyLoading(menu.component);
if (item.children && item.children.length > 0) {
menu.children = [];
util.initRouterNode(menu.children, item.children);
}
let meta = {};
// 给页面添加标题
meta.title = menu.title ? menu.title + " - "+config.title+"商家后台" : null;
meta.firstRouterName = menu.firstRouterName
meta.keepAlive = menu.keepAlive ? true : false
menu.meta = meta;
routers.push(menu);
for (var item of data) {
let menu = Object.assign({}, item);
menu.component = lazyLoading(menu.frontRoute);
if (item.children && item.children.length > 0) {
menu.children = [];
util.initRouterNode(menu.children, item.children);
}
let meta = {};
// 给页面添加标题
meta.title = menu.title ? menu.title + " - " + config.title + "商家后台" : null;
meta.firstRouterName = item.firstRouterName
meta.keepAlive = menu.keepAlive ? true : false
menu.meta = meta;
routers.push(menu);
}
};
export default util;

View File

@@ -5,6 +5,7 @@ import "./styles/theme.less";
import "core-js/stable";
import vueQr from "vue-qr";
import liliDialog from '@/views/lili-dialog'
import App from "./App";
import { router } from "./router/index";
import store from "./store";
@@ -21,7 +22,6 @@ import { setStore, getStore, removeStore } from "@/libs/storage";
import i18nBox from '@/views/lili-components/i18n-translate'
import util from "@/libs/util";
import VueLazyload from "vue-lazyload";
import * as filters from "@/utils/filters"; // global filter
@@ -45,7 +45,9 @@ Vue.use(VueLazyload, {
});
Vue.use(ViewUI);
Vue.component('liliDialog',liliDialog)
Vue.component('i18nBox',i18nBox)
Vue.component('liliDialog',liliDialog)
Vue.component("vue-qr", vueQr); //此处将vue-qr添加为全局组件
// 挂载全局使用的方法

View File

@@ -102,6 +102,18 @@ export const otherRouter = {
name: "order-detail",
component: () => import("@/views/order/order/orderDetail.vue")
},
{
path: "/floorList/main",
title: "编辑模板",
name: "main",
component: () => import("@/views/shop/wap/main.vue")
},
{
path: "/pcFloorList/main",
title: "编辑模板",
name: "renovation",
component: () => import("@/views/shop/renovation.vue")
},
{
path: "order-complaint-detail",
title: "投诉详情",
@@ -127,7 +139,25 @@ export const otherRouter = {
title: "发货",
name: "export-order-deliver",
component: () => import("@/views/order/order/exportOrderDeliver.vue")
}
},
{
path: "order-detail",
title: "订单详情",
name: "order-detail",
component: () => import("@/views/order/order/orderDetail.vue")
},
{
path: "/floorList/main",
title: "编辑模板",
name: "main",
component: () => import("@/views/shop/wap/main.vue")
},
{
path: "/pcFloorList/main",
title: "编辑模板",
name: "renovation",
component: () => import("@/views/shop/renovation.vue")
},
// {
// path: "/*",
// name: "error-404",

View File

@@ -15,7 +15,7 @@ export function unitPrice(val, unit, location) {
}
return (unit || "") + price;
}
// 转义
// 转义
export function enCode(v1) {
var entry = {
"&#39;": "'",
@@ -162,3 +162,60 @@ export function formatDate(date, fmt) {
}
return fmt;
}
// 楼层装修,选择链接处理跳转方式
export function formatLinkType (item) {
const types = ['goods', 'category', 'shops', 'marketing', 'pages', 'other'] // 所有跳转的分类 依次为 商品、分类、店铺、活动、页面、其他
let url = '';
switch (item.___type) {
case 'goods':
url = `/goodsDetail?skuId=${item.id}&goodsId=${item.goodsId}`;
break;
case 'category':
url = `/goodsList?categoryId=${item.allId}`;
break;
case 'shops':
url = `/merchant?id=${item.id}`;
break;
case 'marketing': // 暂无数据,需要后续修改
url = `/seckill?id=${item.id}`;
break;
case 'pages': // 暂无数据,需要后续修改
url = `/article?id=${item.id}`;
break;
case 'other':
switch (item.title) {
case '首页':
url = '/';
break;
case '购物车':
url = '/cart';
break;
case '我的订单':
url = '/home/MyOrder';
break;
case '收藏商品':
url = '/home/Favorites';
break;
case '个人中心':
url = '/home';
break;
case '外部链接':
url = item.url;
break;
case '秒杀频道':
url = '/seckill';
break;
case '领券中心':
url = '/coupon';
break;
}
break;
}
return url;
}

View File

@@ -1,6 +1,7 @@
<template>
<div class="search">
<Card>
<Row @keydown.enter.native="handleSearch">
<Form
ref="searchForm"
@@ -66,6 +67,7 @@
</Row>
<Row class="operation padding-row">
<Button @click="addGoods" type="primary">添加商品</Button>
<Button @click="openImportGoods" type="primary">导入商品</Button>
<Dropdown @on-click="handleDropdown">
<Button type="default">
批量操作
@@ -189,6 +191,21 @@
<Button type="primary" @click="saveShipTemplate">更新</Button>
</div>
</Modal>
<Modal title="导入商品信息" v-model="importModal" :mask-closable="false">
<div style="text-align: center">
<Upload :before-upload="handleUpload" name="files" accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
multiple type="drag" :action="action" :headers="accessToken">
<div style="padding: 50px 0">
<Icon type="ios-cloud-upload" size="102" style="color: #3399ff"></Icon>
<h2>选择或拖拽文件上传</h2>
</div>
</Upload>
<Button @click="exportGoods" type="text" style="color: red">下载导入模板</Button>
</div>
<div slot="footer">
<Button type="text" @click="importModal = false">确定</Button>
</div>
</Modal>
</div>
</template>
@@ -201,13 +218,20 @@ import {
lowGoods,
deleteGoods,
batchShipTemplate,
downLoadGoods
} from "@/api/goods";
import { baseUrl } from "@/libs/axios.js";
import * as API_Shop from "@/api/shops";
import Cookies from "js-cookie";
import {uploadGoodsExcel} from "../../../api/goods";
export default {
name: "goods",
data() {
return {
accessToken: {}, // 验证token
importModal: false,
action: baseUrl + "/goods/import/import", // 上传接口
id: "", //要操作的id
loading: true, // 表单加载状态
shipTemplateForm: {}, // 物流模板
@@ -510,6 +534,59 @@ export default {
}
});
},
// 上传数据
handleUpload(file) {
this.file = file;
this.upload();
return false;
},
/**
* 上传文件
*/
async upload() {
let fd = new FormData();
fd.append("files", this.file);
let res = await uploadGoodsExcel(fd);
if (res.success) {
this.stepList.map((item) => {
item.checked = false;
this.$Message.success("导入成功")
this.importModal = false
});
this.stepList[2].checked = true;
}
},
openImportGoods(){
this.importModal = true
},
async exportGoods(){
downLoadGoods()
.then((res) => {
console.log(res)
const blob = new Blob([res], {
type: "application/vnd.ms-excel;charset=utf-8",
});
//对于<a>标签,只有 Firefox 和 Chrome内核 支持 download 属性
//IE10以上支持blob但是依然不支持download
if ("download" in document.createElement("a")) {
//支持a标签download的浏览器
const link = document.createElement("a"); //创建a标签
link.download = "商品批量导入模板.xls"; //a标签添加属性
link.style.display = "none";
link.href = URL.createObjectURL(blob);
document.body.appendChild(link);
link.click(); //执行下载
URL.revokeObjectURL(link.href); //释放url
document.body.removeChild(link); //释放标签
} else {
navigator.msSaveBlob(blob, fileName);
}
})
.catch((err) => {
console.log(err);
});
},
// 更新库存
updateStock() {
let updateStockList = this.stockList.map((i) => {
@@ -751,9 +828,7 @@ export default {
},
mounted() {
this.init();
},
mounted() {
this.init();
this.accessToken.accessToken = this.getStore("accessToken");
},
};
</script>

2
seller/src/views/lili-dialog/goods-dialog.vue Normal file → Executable file
View File

@@ -14,7 +14,7 @@
<Button type="primary" @click="goodsData=[]; getQueryGoodsList();" icon="ios-search">搜索</Button>
</div>
</div>
<div style="positon:retavle;">
<div >
<Scroll class="wap-content-list" :on-reach-bottom="handleReachBottom" :distance-to-edge="[3,3]">
<div class="wap-content-item" :class="{ active: item.selected }" @click="checkedGoods(item, index)" v-for="(item, index) in goodsData" :key="index">

0
seller/src/views/lili-dialog/index.vue Normal file → Executable file
View File

85
seller/src/views/lili-dialog/link-dialog.vue Normal file → Executable file
View File

@@ -1,85 +1,55 @@
<template>
<div class="wrapper">
<div class="wap-list">
<div
class="wap-item"
@click="clickTag(item, i)"
v-for="(item, i) in wap"
:key="i"
:class="{ active: selected == i }"
>
{{ item.title }}
</div>
</div>
<div class="wap-content"></div>
<!-- 弹出选择商品的modal -->
<Modal
title="选择"
:styles="{ top: '120px' }"
width="750"
@on-cancel="clickClose"
@on-ok="clickClose"
v-model="flag"
:mask-closable="false"
scrollable
>
<goodsDialog
@selected="
<Tabs :value="wap[0].title" class="tabs">
<TabPane :label="item.title" :name="item.title" @click="clickTag(item, i)" v-for="(item, i) in wap" :key="i">
<component ref="lili-component" :is="templateWay[item.name]" @selected="
(val) => {
goodsData = val;
changed = val;
}
"
ref="goodsDialog"
/>
</Modal>
" />
</TabPane>
</Tabs>
</div>
</template>
<script>
import wap from "./wap.js";
import goodsDialog from "./goods-dialog";
import templateWay from "./template/index";
export default {
components: {
goodsDialog,
},
data() {
return {
goodsData: "", // 商品列表
flag: false, // 控制商品模块显隐
selected: 0, // 已选模块
templateWay, // 模板数据
changed: "", // 变更模板
selected: 0, // 已选数据
selectedLink: "", //选中的链接
wap, // tab标签栏数据
wap // tab标签
};
},
watch: {
selectedLink(val) {
this.$emit("selectedLink", val);
changed: {
handler(val) {
this.$emit("selectedLink", val[0]); //因为是单选,所以直接返回第一个
},
deep: true,
},
},
mounted() {
this.$nextTick(() => {
console.log( this.$refs["lili-component"])
this.$refs["lili-component"][0].type = "single"; //商品页面设置成为单选
});
this.wap.forEach((item) => {
item.selected = false;
});
},
methods: {
clickClose() {
this.flag = false;
},
// 点击链接
clickTag(val, i) {
this.selected = i;
if (!val.openGoods) {
this.selectedLink = val;
}
// 打开选择商品
else {
this.$refs.goodsDialog.selectedWay = [];
this.$refs.goodsDialog.type = "single";
this.flag = true;
}
},
},
methods: {},
};
</script>
<style scoped lang="scss">
@@ -91,6 +61,9 @@ export default {
.wap-flex {
margin: 2px;
}
.tabs {
width: 100%;
}
/deep/ .ivu-modal {
overflow: hidden;
@@ -101,4 +74,4 @@ export default {
height: 500px;
overflow: hidden;
}
</style>
</style>

0
seller/src/views/lili-dialog/style.scss Normal file → Executable file
View File

View File

@@ -0,0 +1,121 @@
<template>
<div class="wrapper">
<!-- 一级分类 -->
<div class="list">
<div class="list-item" :class="{active:parentIndex === cateIndex}" @click="handleClickChild(cate,cateIndex)" v-for="(cate,cateIndex) in categoryList" :key="cateIndex">
{{cate.name}}
</div>
</div>
<!-- 二级分类 -->
<div class="list">
<div class="list-item" :class="{active:secondIndex === secondI}" @click="handleClickSecondChild(second,secondI)" v-if="secondLevel.length != 0" v-for="(second,secondI) in secondLevel"
:key="secondI">
{{second.name}}
</div>
</div>
<!--三级分类 -->
<div class="list">
<div class="list-item" :class="{active:thirdIndex === thirdI}" @click="handleClickthirdChild(third,thirdI)" v-if="thirdLevel.length != 0" v-for="(third,thirdI) in thirdLevel" :key="thirdI">
{{third.name}}
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
parentIndex: '', // 分类父级下标
secondIndex: '', // 分类二级下标
thirdIndex: '', // 分类三级下标
categoryList: [], // 分类列表一级数据
secondLevel: [], // 分类列表二级数据
thirdLevel: [], // 分类列表三级数据
selectedData: "", // 已选分类数据
};
},
mounted() {
this.init();
},
methods: {
// 点击一级
handleClickChild(item, index) {
this.parentIndex = index;
this.secondLevel = item.children;
item.___type = "category";
item.allId = item.id;
this.secondIndex = '';
this.thirdIndex = '';
this.thirdLevel = []
this.$emit("selected", [item]);
// 点击第一级的时候默认显示第二级第一个
// this.handleClickSecondChild(item.children, 0);
},
// 点击二级
handleClickSecondChild(second, index) {
second.___type = "category";
second.allId = `${second.parentId},${second.id}`
this.secondIndex = index;
this.thirdLevel = second.children;
this.thirdIndex = '';
this.$emit("selected", [second]);
// this.handleClickthirdChild(second.children[0], 0);
},
// 点击三级
handleClickthirdChild(item, index) {
item.___type = "category";
item.allId = `${this.categoryList[this.parentIndex].id},${item.parentId},${item.id}`
this.$emit("selected", [item]);
this.thirdIndex = index;
},
init() {
let category = JSON.parse(localStorage.getItem('category'))
if (category) {
category.forEach((item) => {
item.___type = "category";
});
this.categoryList = category;
// this.handleClickChild(category[0], 0);
} else {
setTimeout(() => {
category = JSON.parse(localStorage.getItem('category'))
category.forEach((item) => {
item.___type = "category";
});
this.categoryList = category;
// this.handleClickChild(category[0], 0);
},3000)
}
},
},
};
</script>
<style lang="scss" scoped>
.list {
width: 30%;
margin: 0 1.5%;
height: 400px;
overflow: auto;
> .list-item {
padding: 10px;
transition: 0.35s;
cursor: pointer;
}
.list-item:hover {
background: #ededed;
}
}
.active {
background: #ededed;
}
.wrapper {
overflow: hidden;
}
</style>

View File

@@ -0,0 +1,15 @@
import category from './category.vue'
import shops from './shops.vue'
import pages from './pages.vue'
import goods from '../goods-dialog.vue'
import other from './other.vue'
export default {
// pages,
// shops,
category,
goods,
other,
}

View File

@@ -0,0 +1,141 @@
<template>
<div>
<Row :gutter="30">
<Col span="6" v-for="(item,index) in linkList" :key="index" v-if="(item.title !== '拼团频道' && item.title !== '签到') || $route.name !== 'renovation'">
<div class="card" :class="{'active':selectedIndex == index}" @click="handleLink(item,index)">
<Icon size="24" :type="item.icon" />
<p>{{item.title}}</p>
</div>
</Col>
<!-- 外部链接只有pc端跳转 -->
<Col span="6" v-if="$route.name === 'renovation'">
<div class="card" :class="{'active':selectedIndex == linkList.length}" @click="handleLink(linkItem,linkList.length)">
<Poptip v-model="linkVisible">
<Icon size="24" :type="linkItem.icon" />
<p>{{linkItem.title}}</p>
<div slot="title">链接地址</div>
<div slot="content">
<Input type="text" @keyup="handleLink(linkItem,linkList.length)" v-model="linkItem.url" placeholder="https://"></Input>
</div>
</Poptip>
</div>
</Col>
</Row>
</div>
</template>
<script>
export default {
data() {
return {
linkList: [ // 链接列表
{
title: "首页",
icon: "md-home",
___type: "home",
},
{
title: "购物车",
icon: "md-cart",
___type: "cart",
},
{
title: "收藏商品",
icon: "md-heart",
___type: "collection",
},
{
title: "我的订单",
icon: "md-document",
___type: "order",
},
{
title: "个人中心",
icon: "md-person",
___type: "user",
},
{
title: "拼团频道",
icon: "md-flame",
___type: "group",
},
{
title: "秒杀频道",
icon: "md-flame",
___type: "seckill",
},
{
title: "领券中心",
icon: "md-pricetag",
___type: "coupon",
},
{
title: "签到",
icon: "md-happy",
___type: "sign",
},
// {
// title: "小程序直播",
// icon: "ios-videocam",
// ___type: "live",
// },
{
title: "砍价",
icon: "md-share-alt",
___type: "kanjia",
},
{
title: "积分商城",
icon: "ios-basket",
___type: "point",
},
],
linkItem: {
title: "外部链接",
icon: "ios-link",
___type: "link",
url: ''
},
linkVisible: false, // 是否显示外部链接
selectedIndex: 9999999, // 已选index
};
},
methods: {
handleLink(val, index) {
val = {...val,___type:'other'}
this.selectedIndex = index;
if (index === this.linkList.length) {
this.linkVisible = true
} else {
this.linkVisible = false
}
this.$emit("selected",[val])
},
},
};
</script>
<style lang="scss" scoped>
@import "../style.scss";
.card {
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
padding: 20px 0;
margin: 10px 0;
text-align: center;
transition: 0.35s;
cursor: pointer;
/deep/ p {
margin: 10px 0;
}
border: 1px solid #ededed;
}
.card:hover{
background: #ededed;
}
.active {
background: #ededed;
}
</style>

View File

@@ -0,0 +1,80 @@
<template>
<div class="wrapper">
<!-- TODO 目前数据少暂且不用 -->
<!-- <div class="list">
<div class="list-item active">
文章页
</div>
</div> -->
<div class="content">
<!-- <Article @callbacked="callbackArticle" :selected="true" /> -->
</div>
</div>
</template>
<script>
// import Article from "@/views/page/article-manage/articleList.vue";
export default {
components: {
// Article,
},
data() {
return {};
},
methods: {
callbackArticle(val) {
val.___type = "pages";
val.___path = "/pages/passport/article";
this.$emit("selected", [val]);
},
},
};
</script>
<style lang="scss" scoped>
/deep/ .ivu-card-body {
height: 414px;
overflow: auto;
}
.ivu-table-wrapper ivu-table-wrapper-with-border {
height: 300px !important;
}
.list {
margin: 0 1.5%;
height: 400px;
overflow: auto;
> .list-item {
padding: 10px;
transition: 0.35s;
cursor: pointer;
}
.list-item:hover {
background: #ededed;
}
}
.list {
flex: 2;
width: auto;
}
.content {
overflow: hidden;
flex: 8;
height: 431px;
}
.active {
background: #ededed;
}
.wrapper {
height: 416px;
overflow: hidden;
}
/deep/ .ivu-table {
height: 300px !important;
overflow: auto;
}
/deep/ .ivu-card-body {
padding: 0;
height: auto;
}
</style>

View File

@@ -0,0 +1,110 @@
<template>
<div class="shop">
<div class="wap-content">
<div class="query-wrapper">
<div class="query-item">
<div>店铺名称</div>
<Input placeholder="请输入店铺名称" @on-clear="shopsData=[]; params.storeName=''; params.pageNumber =1; init()" @on-enter="()=>{shopsData=[]; params.pageNumber =1; init();}" icon="ios-search" clearable style="width: 150px"
v-model="params.storeName" />
</div>
<div class="query-item">
<Button type="primary" @click="shopsData=[];params.pageNumber =1; init();" icon="ios-search">搜索</Button>
</div>
</div>
<div>
<Scroll class="wap-content-list" :on-reach-bottom="handleReachBottom" :distance-to-edge="23">
<div class="wap-content-item" @click="clickShop(item,index)" :class="{ active:selected == index }" v-for="(item, index) in shopsData" :key="index">
<div>
<img class="shop-logo" :src="item.storeLogo" alt="" />
</div>
<div class="wap-content-desc">
<div class="wap-content-desc-title">{{ item.storeName }}</div>
<div class="self-operated" :class="{'theme_color':item.selfOperated }">{{ item.selfOperated ? '自营' : '非自营' }}</div>
<div class="wap-sku" :class="{'theme_color':(item.storeDisable === 'OPEN' ? true : false) }">{{ item.storeDisable === 'OPEN' ? '开启中' : '未开启' }}</div>
</div>
</div>
<Spin size="large" fix v-if="loading"></Spin>
</Scroll>
</div>
</div>
</div>
</template>
<script>
import { getShopListData } from "@/api/shops.js";
export default {
data() {
return {
loading: false, // 加载状态
total: "", // 总数
params: { // 请求参数
pageNumber: 1,
pageSize: 10,
storeDisable: "OPEN",
storeName: "",
},
shopsData: [], // 店铺数据
selected: 9999999999, //设置一个不可能选中的index
};
},
watch: {},
created() {
this.init();
},
methods: {
handleReachBottom() {
setTimeout(() => {
if (this.params.pageNumber * this.params.pageSize <= this.total) {
this.params.pageNumber++;
this.init();
}
}, 1500);
},
init() {
this.loading = true;
getShopListData(this.params).then((res) => {
if (res.success) {
/**
* 解决数据请求中,滚动栏会一直上下跳动
*/
this.total = res.result.total;
this.shopsData.push(...res.result.records);
this.loading = false;
}
});
},
clickShop(val, i) {
this.selected = i;
val = { ...val, ___type: "shops" };
this.$emit("selected", [val]);
},
},
};
</script>
<style lang="scss" scoped>
@import "../style.scss";
.shop {
display: flex;
}
.self-operated {
font-size: 12px;
color: #999;
}
.wap-content-list {
flex-wrap: wrap;
}
.shop-logo {
object-fit: cover;
}
.wap-content-item {
}
.active {
background: url("../../../assets/selected.png") no-repeat;
background-position: right;
background-size: 10%;
}
</style>

View File

@@ -1,25 +1,40 @@
export default [
{
title:"商品",
url:"0",
openGoods:true
},
{
title:"分类",
url:"1"
},
{
title:"店铺",
url:"2"
},
{
title:"活动",
url:"3",
},
{
title:"其他",
url:"4"
}
{
title: "商品",
url: "0",
openGoods: true,
name: "goods"
},
// {
// title: "分类",
// url: "1",
// name: "category"
// },
// {
// title: "活动",
// url: "3",
// name: "marketing"
// },
// {
// title: "页面",
// url: "3",
// name: "pages"
// },
// {
// title: "活动",
// url: "3",
// name: "marketing"
// },
// {
// title: "页面",
// url: "3",
// name: "pages"
// },
{
title: "其他",
url: "3",
name: "other"
}
];

View File

@@ -2,38 +2,66 @@
<div class="login" @click="$refs.verify.show = false">
<Row type="flex" @keydown.enter.native="submitLogin">
<Col style="width: 368px">
<Header />
<Row style="flex-direction: column;">
<Form ref="usernameLoginForm" :model="form" :rules="rules" class="form">
<FormItem prop="username">
<Input v-model="form.username" prefix="ios-contact" size="large" clearable placeholder="请输入用户名"
autocomplete="off" />
</FormItem>
<FormItem prop="password">
<Input type="password" v-model="form.password" prefix="ios-lock" size="large" password placeholder="请输入密码"
autocomplete="off" />
</FormItem>
</Form>
<Header />
<Row style="flex-direction: column">
<Form
ref="usernameLoginForm"
:model="form"
:rules="rules"
class="form"
>
<FormItem prop="username">
<Input
v-model="form.username"
prefix="ios-contact"
size="large"
clearable
placeholder="请输入用户名"
autocomplete="off"
/>
</FormItem>
<FormItem prop="password">
<Input
type="password"
v-model="form.password"
prefix="ios-lock"
size="large"
password
placeholder="请输入密码"
autocomplete="off"
/>
</FormItem>
</Form>
<Row>
<div class="login-btn" type="primary" size="large" :loading="loading" @click="submitLogin" long>
<span v-if="!loading">登录</span>
<span v-else>登录中</span>
</div>
<Row>
<div
class="login-btn"
type="primary"
size="large"
:loading="loading"
@click="submitLogin"
long
>
<span v-if="!loading">登录</span>
<span v-else>登录中</span>
</div>
</Row>
</Row>
</Row>
<Footer />
<!-- 拼图验证码 -->
<verify ref="verify" class="verify-con" verifyType="LOGIN" @change="verifyChange"></verify>
<Footer />
<!-- 拼图验证码 -->
<verify
ref="verify"
class="verify-con"
verifyType="LOGIN"
@change="verifyChange"
></verify>
</Col>
</Row>
</div>
</template>
<script>
import { getCurrentPermissionList } from "@/api/index";
import { login, userMsg } from "@/api/index";
import Cookies from "js-cookie";
import Header from "@/views/main-components/header";
@@ -76,6 +104,10 @@ export default {
},
};
},
created() {
window.localStorage.setItem("menuData", "");
},
methods: {
afterLogin(res) {
let accessToken = res.result.accessToken;
@@ -85,6 +117,10 @@ export default {
// 获取用户信息
userMsg().then((res) => {
if (res.success) {
// location.reload();
// this.$router.go(0);
console.log("Huoqu ");
this.setStore("saveLogin", this.saveLogin);
if (this.saveLogin) {
// 保存7天
@@ -94,9 +130,10 @@ export default {
} else {
Cookies.set("userInfoSeller", JSON.stringify(res.result));
}
util.initRouter(this);
this.$store.commit("setAvatarPath", res.result.storeLogo);
// 加载菜单
util.initRouter(this);
this.$router.push({
name: "home_index",
});
@@ -120,8 +157,8 @@ export default {
this.loading = true;
let fd = new FormData();
fd.append('username',this.form.username)
fd.append('password',this.md5(this.form.password))
fd.append("username", this.form.username);
fd.append("password", this.md5(this.form.password));
login(fd)
.then((res) => {
this.loading = false;
@@ -138,7 +175,6 @@ export default {
};
</script>
<style lang="scss" scoped>
.login {
height: 100%;
background: url("../assets/background.png") no-repeat;
@@ -148,8 +184,6 @@ export default {
display: flex;
align-items: center;
justify-content: center;
.verify-con {
position: absolute;
top: 126px;
@@ -175,9 +209,8 @@ export default {
transition: 0.35s;
}
.login-btn:hover {
opacity: .9;
opacity: 0.9;
border-radius: 10px;
}
}
</style>

View File

@@ -0,0 +1,72 @@
<template>
<div>
<Cascader
v-model="selectDep"
:data="department"
@on-change="handleChangeDep"
change-on-select
filterable
clearable
placeholder="请选择"
></Cascader>
</div>
</template>
<script>
import { initDepartment } from "@/api/index";
export default {
name: "departmentChoose",
props: {
},
data() {
return {
selectDep: [], // 已选数据
department: [] // 列表
};
},
methods: {
// 获取部门数据
initDepartmentData() {
initDepartment().then(res => {
if (res.success) {
const arr = res.result;
this.filterData(arr)
this.department = arr
}
});
},
handleChangeDep(value, selectedData) {
let departmentId = "";
// 获取最后一个值
if (value && value.length > 0) {
departmentId = value[value.length - 1];
}
this.$emit("on-change", departmentId);
},
// 清空已选列表
clearSelect() {
this.selectDep = [];
},
// 处理部门数据
filterData (data) {
data.forEach(e => {
e.value = e.id;
e.label = e.title;
if (e.children) {
this.filterData(e.children)
} else {
return
}
})
}
},
created() {
this.initDepartmentData();
}
};
</script>
<style lang="scss">
</style>

View File

@@ -0,0 +1,159 @@
<template>
<div>
<div style="display:flex;">
<Input
v-model="departmentTitle"
readonly
style="margin-right:10px;"
:placeholder="placeholder"
:clearable="clearable"
@on-clear="clearSelect"
/>
<Poptip transfer trigger="click" placement="right" title="选择部门" width="250">
<Button icon="md-list">选择部门</Button>
<div slot="content">
<Input
v-model="searchKey"
suffix="ios-search"
@on-change="searchDep"
placeholder="输入部门名搜索"
clearable
/>
<div class="dep-tree-bar">
<Tree
:data="dataDep"
@on-select-change="selectTree"
></Tree>
<Spin size="large" fix v-if="depLoading"></Spin>
</div>
</div>
</Poptip>
</div>
</div>
</template>
<script>
import {initDepartment, searchDepartment} from "@/api/index";
export default {
name: "departmentTreeChoose",
props: {
multiple: {
type: Boolean,
default: false
},
clearable: {
type: Boolean,
default: true
},
placeholder: {
type: String,
default: "点击选择部门"
}
},
data() {
return {
depLoading: false, // 加载状态
departmentTitle: "", // modal标题
searchKey: "", // 搜索关键词
dataDep: [], // 部门列表
selectDep: [], // 已选部门
departmentId: [] // 部门id
};
},
methods: {
// 获取部门数据
initDepartmentData() {
initDepartment().then(res => {
if (res.success) {
this.dataDep = res.result;
}
});
},
searchDep() {
// 搜索部门
if (this.searchKey) {
this.depLoading = true;
searchDepartment({title: this.searchKey}).then(res => {
this.depLoading = false;
if (res.success) {
res.result.forEach(function (e) {
if (e.status == -1) {
e.title = "[已禁用] " + e.title;
e.disabled = true;
}
});
this.dataDep = res.result;
}
});
} else {
this.initDepartmentData();
}
},
// 选择回调
selectTree(v) {
if (v.length === 0) {
this.$emit("on-change", null);
this.departmentId = "";
this.departmentTitle = "";
return
}
this.departmentId = v[0].id;
this.departmentTitle = v[0].title;
let department = {
departmentId: this.departmentId,
departmentTitle: this.departmentTitle
}
this.$emit("on-change", department);
},
// 清除选中方法
clearSelect() {
this.departmentId = [];
this.departmentTitle = "";
this.initDepartmentData();
if (this.multiple) {
this.$emit("on-change", []);
} else {
this.$emit("on-change", "");
}
this.$emit("on-clear");
},
// 设置数据 回显用
setData(ids, title) {
this.departmentTitle = title;
if (this.multiple) {
this.departmentId = ids;
} else {
this.departmentId = [];
this.departmentId.push(ids);
}
}
},
created() {
this.initDepartmentData();
}
};
</script>
<style lang="scss" scoped>
.dep-tree-bar {
position: relative;
min-height: 80px;
max-height: 500px;
overflow: auto;
margin-top: 5px;
}
.dep-tree-bar::-webkit-scrollbar {
width: 6px;
height: 6px;
}
.dep-tree-bar::-webkit-scrollbar-thumb {
border-radius: 4px;
-webkit-box-shadow: inset 0 0 2px #d1d1d1;
background: #e4e4e4;
}
</style>

View File

@@ -263,7 +263,6 @@
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
});

View File

@@ -28,6 +28,7 @@
<Button v-if="allowOperation.ship" @click="orderDeliver" type="primary"
>发货</Button
>
<Button @click="Toprint" type="primary" ghost v-if="allowOperation.ship">打印电子面单</Button>
</div>
</Card>
@@ -440,13 +441,31 @@
<span>订单发货</span>
</p>
<div>
<Form :model="faceSheetForm" ref="faceSheetForm" v-if="facesheetFlag" :rules="faceSheetFormValidate">
<FormItem label="物流公司" prop="logisticsId" style="position: relative" :label-width="90">
<Select
v-model="faceSheetForm.logisticsId"
placeholder="请选择"
style="width: 250px"
>
<Option
v-for="(item, i) in checkedLogistics"
:key="i"
:value="item.logisticsId"
>{{ item.name }}
</Option>
</Select>
</FormItem>
</Form>
<Form
v-else
ref="orderDeliveryForm"
:model="orderDeliveryForm"
:label-width="90"
:rules="orderDeliverFormValidate"
style="position: relative"
>
<FormItem label="物流公司" prop="logisticsId">
<Select
v-model="orderDeliveryForm.logisticsId"
@@ -456,12 +475,13 @@
<Option
v-for="(item, i) in checkedLogistics"
:key="i"
:value="item.id"
>{{ item.name }}
:value="item.logisticsId"
>{{ item.name }}
</Option>
</Select>
</FormItem>
<FormItem label="物流单号" prop="logisticsNo">
<!-- v-if="showOrder" -->
<FormItem label="物流单号" prop="logisticsNo" >
<Input
v-model="orderDeliveryForm.logisticsNo"
style="width: 250px"
@@ -535,6 +555,7 @@
<script>
import * as API_Order from "@/api/order";
import * as API_Logistics from "@/api/logistics";
import liliMap from "@/views/my-components/map/index";
import * as RegExp from "@/libs/RegExp.js";
import region from "@/views/lili-components/region";
@@ -557,6 +578,16 @@ export default {
region: [], //地区
regionId: [], //地区id
showRegion: false,
someJSONdata: '',
faceSheetForm: {
logisticsId: '',
},
faceSheetFormValidate: {
logisticsId: [
{ required: true, message: "请选择物流公司"},
],
},
facesheetFlag: false, //电子面单标识
orderLogModal: false, //弹出调整价格框
logisticsModal: false, //弹出查询物流框
orderDeliverModal: false, //订单发货弹出框
@@ -786,6 +817,15 @@ export default {
}
});
},
Toprint(){
this.facesheetFlag = true;
API_Logistics.getCheckedOn().then(res => {
if (res.success) {
this.checkedLogistics = res.result;
this.orderDeliverModal = true;
}
});
},
// 修改订单金额
modifyPrice() {
//默认要修改的金额为订单总金额
@@ -824,6 +864,7 @@ export default {
},
//订单发货
orderDeliver() {
this.facesheetFlag = false
API_Order.getLogisticsChecked().then((res) => {
if (res.success) {
this.checkedLogistics = res.result;
@@ -831,21 +872,39 @@ export default {
}
});
},
Toprints(){
if(this.form.logisticsId != null && this.form.logisticsId != ''){
this.orderDeliverModal = false;
}
},
//订单发货提交
orderDeliverySubmit() {
this.$refs.orderDeliveryForm.validate((valid) => {
if (valid) {
API_Order.orderDelivery(this.sn, this.orderDeliveryForm).then(
(res) => {
if(this.facesheetFlag){
this.$refs['faceSheetForm'].validate((valid) => {
if (valid) {
API_Order.getOrderFaceSheet(this.sn, this.faceSheetForm).then(res => {
if (res.success) {
this.$Message.success("订单发货成功");
this.orderDeliverModal = false;
this.getDataDetail();
this.someJSONdata = res.result;
this.Toprints();
}
}
);
}
});
})
}
})
}else{
this.$refs['orderDeliveryForm'].validate((valid) => {
if (valid) {
API_Order.orderDelivery(this.sn,this.orderDeliveryForm).then(
(res) => {
if (res.success) {
this.$Message.success("订单发货成功");
this.orderDeliverModal = false;
this.getDataDetail();
}
}
);
}
});
}
},
//弹出修改收货地址框
editAddress() {

View File

@@ -0,0 +1,286 @@
<template>
<div class="wrapper">
<!-- <Card class="category">
<div
:class="{ active: i == selectedIndex }"
class="category-item"
v-for="(typeItem, i) in pageTypes"
:key="typeItem.type"
>
<div @click="clickType(typeItem.type, i)">{{ typeItem.title }}</div>
</div>
</Card> -->
<Card class="content">
<Button type="primary" @click="createTemp">添加页面</Button>
<div class="list">
<Spin size="large" fix v-if="loading"></Spin>
<div class="item item-title">
<div>页面名称</div>
<div class="item-config">
<div>状态</div>
<div>操作</div>
</div>
</div>
<div class="item" v-for="(item, index) in list" :key="index">
<div>{{ item.name || "暂无模板昵称" }}</div>
<div class="item-config">
<i-switch v-model="item.pageShow" @on-change="releaseTemplate(item.id)">
<span slot="open"></span>
<span slot="close"></span>
</i-switch>
<Button type="info" placement="right" @click="Template(item)" size="small"
>编辑</Button
>
<Button type="success" placement="right" @click="decorate(item)" size="small"
>装修</Button
>
<Poptip confirm title="删除此模板?" @on-ok="delTemplate(item.id)">
<Button type="error" size="small">删除</Button>
</Poptip>
</div>
</div>
<div class="no-more" v-if="list.length == 0">暂无更多模板</div>
</div>
<Page show-total :total="total" show-sizer :page-size-opts="[10, 20, 50]" show-elevator style="float:right;overflow:hidden;" @on-change="changePageNum" @on-page-size-change="changePageSize" :page-size="searchForm.pageSize"/>
</Card>
<Modal
v-model="showModal"
title="模板设置"
draggable
width="600"
:z-index="100"
:loading="loading"
:mask-closable="false"
@on-ok="newTemplate"
@on-cancel="showModal = false"
>
<Form ref="form" :model="formData" :label-width="80">
<FormItem label="模板名称" prop="name">
<Input v-model="formData.name" placeholder="请输入模板名称" />
</FormItem>
</Form>
</Modal>
</div>
</template>
<script>
import * as API_floor from "@/api/other.js";
export default {
name: "floorList",
data() {
return {
showModal: false, // 添加modal的显示
selectedIndex: 0, // 首页还是专题选择的index
total:0,
formData: {
// 新建模态框的数据
status: false, // 模板是否开启
name: "", // 模板名称
},
searchForm:{
pageNumber:1,
pageSize:10,
sort: 'createTime',
order: 'desc',
pageClientType:'PC'
},
columns: [
// 列表展示的column
{
title: "页面名称",
key: "name",
},
{
title: "状态",
},
{
title: "操作",
key: "action",
},
],
loading: false, // 加载状态
pageTypes: [
// 那种类别的模板
{
type: "INDEX",
title: "首页",
},
// {
// type: "SPECIAL",
// title: "专题",
// },
],
list: [], // 模板列表
};
},
mounted() {
this.getTemplateList();
},
methods: {
newTemplate() {
// 添加,编辑模板
this.$refs.form.validate((valid) => {
if (valid) {
const data = this.formData;
data.status ? (data.pageShow = "OPEN") : (data.pageShow = "CLOSE");
delete data.status;
(data.pageType = "STORE"), (data.pageClientType = "PC");
if (data.id) {
API_floor.updateHome(data.id, data).then((res) => {
this.$Message.success("编辑模板成功");
this.showModal = false;
this.getTemplateList();
});
} else {
API_floor.setHomeSetup(data).then((res) => {
this.$Message.success("新建模板成功");
this.showModal = false;
this.getTemplateList();
});
}
} else {
this.loading = false;
}
});
},
createTemp() {
// 新建表单
this.$refs.form.resetFields();
this.showModal = true;
},
Template(item) {
// 编辑表单
item.status = item.pageShow;
this.formData = item;
this.showModal = true;
},
decorate(val) {
// 装修
this.$router.push({
name: "renovation",
query: { id: val.id, pageShow: val.pageShow },
});
},
// 分页 修改页码
changePageNum (val) {
this.searchForm.pageNumber = val;
this.getTemplateList();
},
// 分页 修改页数
changePageSize (val) {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = val;
this.getTemplateList();
},
getTemplateList() {
//模板列表
// let params = {
// pageNumber: 1,
// pageSize: 999,
// pageType: "INDEX",
// pageClientType: "PC",
// };
API_floor.getHomeList(this.searchForm).then((res) => {
if (res.success) {
// this.total
this.total = res.result.total
this.list = res.result.records;
this.list.forEach((e) => {
if (e.pageShow === "OPEN") {
e.pageShow = true;
} else {
e.pageShow = false;
}
});
}
});
},
releaseTemplate(id) {
//发布模板
API_floor.releasePageHome(id).then((res) => {
if (res.success) {
this.$Message.success("发布模板成功");
this.getTemplateList();
}
});
},
// 删除模板
delTemplate(id) {
API_floor.removePageHome(id).then((res) => {
if (res.success) {
this.$Message.success("删除模板成功");
this.getTemplateList();
}
});
},
},
};
</script>
<style lang="scss" scoped>
.category-item {
cursor: pointer;
padding: 4px;
}
.active {
background: #ededed;
}
.item-title {
background: #d7e7f5 !important;
height: 54px;
}
.no-more {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.wrapper {
background: #fff;
padding: 20px;
display: flex;
}
.category {
flex: 2;
}
.content {
flex: 8;
}
* {
margin: 5px;
}
.list {
min-height: 600px;
position: relative;
}
.item:nth-of-type(2) {
margin: 0 5px;
}
.item {
width: 100% !important;
padding: 0 4px;
display: flex;
align-items: center;
justify-content: space-between;
> .item-config {
width: 250px;
display: flex;
justify-content: space-between;
align-items: center;
div:nth-child(2) {
margin-right: 80px;
}
}
}
.item:nth-of-type(2n + 1) {
background: #f5f7fa;
}
</style>

View File

@@ -0,0 +1,862 @@
export const modelData = [
{
type: 'hotAdvert',
name: '热门广告',
icon: 'md-image',
showName: '',
options: {
list: [{
img: require('@/assets/nav/decorate1.png'),
url: '',
size: '1200*自定义'
},
{
img: require('@/assets/nav/1.jpg'),
url: '',
size: '230*190'
},
{
img: require('@/assets/nav/1.jpg'),
url: '',
size: '230*190'
},
{
img: require('@/assets/nav/1.jpg'),
url: '',
size: '230*190'
},
{
img: require('@/assets/nav/1.jpg'),
url: '',
size: '230*190'
},
{
img: require('@/assets/nav/1.jpg'),
url: '',
size: '230*190'
}
],
},
},
{
type: 'seckill',
name: '促销活动',
icon: 'md-image',
showName: '',
options: {
list: [{
time: 6,
goodsList: [{
img: require('@/assets/nav/1.jpg'),
price: 20,
originalPrice: 30,
name: '阿迪达斯三叶草asdasdafads123213a',
url: ''
},
{
img: require('@/assets/nav/2.jpg'),
price: 20,
originalPrice: 30,
name: '阿迪达斯三叶草asdasdafadsa',
url: ''
},
{
img: require('@/assets/nav/3.jpg'),
price: 20,
originalPrice: 30,
name: '阿迪达斯三叶草asdasdafadsa',
url: ''
},
{
img: require('@/assets/nav/4.jpg'),
price: 20,
originalPrice: 30,
name: '阿迪达斯三叶草asdasdafadsa',
url: ''
},
{
img: require('@/assets/nav/5.jpg'),
price: 20,
originalPrice: 30,
name: '阿迪达斯三叶草asdasdafadsa',
url: ''
},
{
img: require('@/assets/nav/1.jpg'),
price: 20,
originalPrice: 30,
name: '阿迪达斯三叶草asdasdafadsa',
url: ''
},
{
img: require('@/assets/nav/2.jpg'),
price: 20,
originalPrice: 30,
name: '阿迪达斯三叶草asdasdafadsa',
url: ''
},
{
img: require('@/assets/nav/3.jpg'),
price: 20,
originalPrice: 30,
name: '阿迪达斯三叶草asdasdafadsa',
url: ''
},
{
img: require('@/assets/nav/4.jpg'),
price: 20,
originalPrice: 30,
name: '阿迪达斯三叶草asdasdafadsa',
url: ''
},
{
img: require('@/assets/nav/5.jpg'),
price: 20,
originalPrice: 30,
name: '阿迪达斯三叶草asdasdafadsa',
url: ''
},
]
},
{
time: 8,
goodsList: [{
img: require('@/assets/nav/1.jpg'),
url: ''
},
{
img: require('@/assets/nav/2.jpg'),
url: ''
},
{
img: require('@/assets/nav/3.jpg'),
url: ''
},
{
img: require('@/assets/nav/4.jpg'),
url: ''
},
{
img: require('@/assets/nav/5.jpg'),
url: ''
},
]
},
{
time: 10,
goodsList: [{
img: require('@/assets/nav/1.jpg'),
url: ''
},
{
img: require('@/assets/nav/2.jpg'),
url: ''
},
{
img: require('@/assets/nav/3.jpg'),
url: ''
},
{
img: require('@/assets/nav/4.jpg'),
url: ''
},
{
img: require('@/assets/nav/5.jpg'),
url: ''
},
]
},
{
time: 12,
goodsList: [{
img: require('@/assets/nav/1.jpg'),
url: ''
},
{
img: require('@/assets/nav/2.jpg'),
url: ''
},
{
img: require('@/assets/nav/3.jpg'),
url: ''
},
{
img: require('@/assets/nav/4.jpg'),
url: ''
},
{
img: require('@/assets/nav/5.jpg'),
url: ''
},
]
},
{
time: 14,
goodsList: []
},
{
time: 16,
goodsList: []
},
{
time: 18,
goodsList: []
}
]
},
},
{
type: 'discountAdvert',
name: '折扣广告',
icon: 'md-image',
options: {
bgImg: {
img: require('@/assets/nav/decorate.png'),
url: '',
size: "1300*586"
},
classification: [{
img: require('@/assets/nav/decorate2.jpeg'),
url: '',
size: '190*210'
}, {
img: require('@/assets/nav/decorate2.jpeg'),
url: '',
size: '190*210'
}, {
img: require('@/assets/nav/decorate2.jpeg'),
url: '',
size: '190*210'
}, {
img: require('@/assets/nav/decorate2.jpeg'),
url: '',
size: '190*210'
}, {
img: require('@/assets/nav/decorate2.jpeg'),
url: '',
size: '190*210'
}, {
img: require('@/assets/nav/decorate2.jpeg'),
url: '',
size: '190*210'
}, {
img: require('@/assets/nav/decorate2.jpeg'),
url: '',
size: '190*210'
}, {
img: require('@/assets/nav/decorate2.jpeg'),
url: '',
size: '190*210'
}, {
img: require('@/assets/nav/decorate2.jpeg'),
url: '',
size: '190*210'
}, {
img: require('@/assets/nav/decorate2.jpeg'),
url: '',
size: '190*210'
}, ],
brandList: [{
img: require('@/assets/nav/decorate11.jpeg'),
url: '',
size: '240*105'
}, {
img: require('@/assets/nav/decorate11.jpeg'),
url: '',
size: '240*105'
}, {
img: require('@/assets/nav/decorate11.jpeg'),
url: '',
size: '240*105'
}, {
img: require('@/assets/nav/decorate11.jpeg'),
url: '',
size: '240*105'
}, ]
},
},
{
type: 'recommend',
name: '好货推荐',
icon: 'md-image',
options: {
contentLeft: {
title: '发现好货',
secondTitle: '更多好货',
bgColor: '#449dae',
url: '',
list: [{
img: require('@/assets/nav/decorate3.jpeg'),
name: '阿迪达斯三叶草',
describe: '也许是每一款经典系列都应该有一个独特的故事吧',
url: '',
size: '160*160'
},
{
img: require('@/assets/nav/decorate4.jpeg'),
name: '360行车记录',
describe: '夜行 监控 电子狗 蓝牙',
url: '',
size: '80*80'
},
{
img: require('@/assets/nav/decorate4.jpeg'),
name: '360行车记录',
describe: '夜行 监控 电子狗 蓝牙',
url: '',
size: '80*80'
},
{
img: require('@/assets/nav/decorate4.jpeg'),
name: '360行车记录',
describe: '夜行 监控 电子狗 蓝牙',
url: '',
size: '80*80'
},
{
img: require('@/assets/nav/decorate4.jpeg'),
name: '360行车记录',
describe: '夜行 监控 电子狗 蓝牙',
url: '',
size: '80*80'
},
{
img: require('@/assets/nav/decorate4.jpeg'),
name: '360行车记录',
describe: '夜行 监控 电子狗 蓝牙',
url: '',
size: '80*80'
},
{
img: require('@/assets/nav/decorate4.jpeg'),
name: '360行车记录',
describe: '夜行 监控 电子狗 蓝牙',
url: '',
size: '80*80'
},
]
},
contentRight: {
title: '特色推荐',
secondTitle: '更多特色推荐',
bgColor: '#a25684',
url: '',
list: [{
img: require('@/assets/nav/decorate5.jpeg'),
name: '好心情喝出来',
describe: '遇见懂你的饮品',
url: '',
size: '100*100'
},
{
img: require('@/assets/nav/decorate5.jpeg'),
name: '好心情喝出来',
describe: '遇见懂你的饮品',
url: '',
size: '100*100'
},
{
img: require('@/assets/nav/decorate5.jpeg'),
name: '好心情喝出来',
describe: '遇见懂你的饮品',
url: '',
size: '100*100'
},
{
img: require('@/assets/nav/decorate5.jpeg'),
name: '好心情喝出来',
describe: '遇见懂你的饮品',
url: '',
size: '100*100'
},
]
}
},
},
{
type: 'newGoodsSort',
name: '新品排行',
icon: 'md-image',
options: {
left: {
title: '特卖',
secondTitle: "更多特卖",
bgColor: '#c43d7e',
url: '',
list: [{
name: '新年心愿单',
describe: '满269减50,满999减100',
img: require('@/assets/nav/decorate6.jpeg'),
url: '',
size: "160*160"
},
{
name: 'Ms.Maggie 冬季时尚',
describe: '满269减50',
img: require('@/assets/nav/decorate6.jpeg'),
url: '',
size: "90*90"
},
{
name: 'Ms.Maggie 冬季时尚',
describe: '满269减50',
img: require('@/assets/nav/decorate6.jpeg'),
url: '',
size: "90*90"
},
{
name: 'Ms.Maggie 冬季时尚',
describe: '满269减50',
img: require('@/assets/nav/decorate6.jpeg'),
url: '',
size: "90*90"
},
{
name: '阿迪达斯 领跑时尚',
describe: '满269减50',
img: require('@/assets/nav/decorate6.jpeg'),
url: '',
size: "90*90"
},
],
},
middle: {
title: '新品',
secondTitle: "更多新品",
bgColor: '#e66a07',
url: '',
list: [{
name: '阿迪达斯 领跑时尚',
describe: '满269减50',
img: require('@/assets/nav/decorate6.jpeg'),
url: '',
size: "90*90"
},
{
name: '阿迪达斯 领跑时尚',
describe: '满269减50',
img: require('@/assets/nav/decorate6.jpeg'),
url: '',
size: "90*90"
},
{
name: '阿迪达斯 领跑时尚',
describe: '满269减50',
img: require('@/assets/nav/decorate6.jpeg'),
url: '',
size: "90*90"
},
{
name: '阿迪达斯 领跑时尚',
describe: '满269减50',
img: require('@/assets/nav/decorate6.jpeg'),
url: '',
size: "90*90"
},
{
name: '阿迪达斯 领跑时尚',
describe: '满269减50',
img: require('@/assets/nav/decorate6.jpeg'),
url: '',
size: "90*90"
},
{
name: '阿迪达斯 领跑时尚',
describe: '满269减50',
img: require('@/assets/nav/decorate6.jpeg'),
url: '',
size: "90*90"
},
]
},
right: {
title: '排行榜',
secondTitle: "精品风向标",
bgColor: '#b62323',
url: '',
list: [{
name: '小米红米3s手机壳保护套红米3高配版指纹男女款潮版磨砂硬壳防摔 收藏截图 送大礼包',
price: 14.9,
img: require('@/assets/nav/decorate7.jpeg'),
url: ''
},
{
name: '小米红米3s手机壳保护套红米3高配版指纹男女款潮版磨砂硬壳防摔 收藏截图 送大礼包',
price: 14.9,
img: require('@/assets/nav/decorate7.jpeg'),
url: ''
},
{
name: '小米红米3s手机壳保护套红米3高配版指纹男女款潮版磨砂硬壳防摔 收藏截图 送大礼包',
price: 14.9,
img: require('@/assets/nav/decorate7.jpeg'),
url: ''
},
{
name: '小米红米3s手机壳保护套红米3高配版指纹男女款潮版磨砂硬壳防摔 收藏截图 送大礼包',
price: 14.9,
img: require('@/assets/nav/decorate7.jpeg'),
url: ''
},
{
name: '小米红米3s手机壳保护套红米3高配版指纹男女款潮版磨砂硬壳防摔 收藏截图 送大礼包',
price: 14.9,
img: require('@/assets/nav/decorate7.jpeg'),
url: ''
},
{
name: '小米红米3s手机壳保护套红米3高配版指纹男女款潮版磨砂硬壳防摔 收藏截图 送大礼包',
price: 14.9,
img: require('@/assets/nav/decorate7.jpeg'),
url: ''
},
]
}
},
},
{
type: 'firstAdvert',
name: '首页广告',
icon: 'md-image',
options: {
list: [{
name: '生鲜',
describe: "年货带回家 满199减60",
img: require('@/assets/nav/decorate8.png'),
url: '',
fromColor: '#e89621',
toColor: "#f5c568",
size: '170*170'
},
{
name: '众筹',
describe: "年货带回家",
img: require('@/assets/nav/decorate9.png'),
url: '',
fromColor: "#325bb4",
toColor: '#4c9afe',
size: '170*170'
},
{
name: '生鲜',
describe: "年货带回家 满199减60",
img: require('@/assets/nav/decorate8.png'),
url: '',
fromColor: "#1c9daf",
toColor: '#40cda7',
size: '170*170'
},
{
name: '众筹',
describe: "备孕有孕检测仪",
img: require('@/assets/nav/decorate9.png'),
url: '',
fromColor: "#d13837",
toColor: '#df6d4f',
size: '170*170'
},
{
name: '生鲜',
describe: "年货带回家 满199减60",
img: require('@/assets/nav/decorate8.png'),
url: '',
fromColor: "#ca4283",
toColor: '#eb75cf',
size: '170*170'
},
{
name: '众筹',
describe: "备孕有孕检测仪",
img: require('@/assets/nav/decorate9.png'),
url: '',
fromColor: "#5d40c1",
toColor: '#8c5fdb',
size: '170*170'
},
],
},
},
{
type: 'bannerAdvert',
name: '横幅广告',
icon: 'md-image',
options: {
img: '',
url: '',
size: '1200*自定义'
},
},
{
type: 'notEnough',
name: '还没逛够',
icon: 'md-image',
options: {
list: [
[{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
],
[{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
],
[{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
],
[{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
{
img: require('@/assets/nav/decorate10.jpeg'),
name: 'Apple/苹果 13 英寸MacBook Pro Multi-Touch Bar 和 Touch ID 2.9GHz 处理器 512GB 存储容量',
price: 6666,
url: ''
},
],
],
navList: [{
title: '精选',
desc: '猜你喜欢'
},
{
title: '智能先锋',
desc: '大电器城'
},
{
title: '居家优品',
desc: '品质生活'
},
{
title: '超市百货',
desc: '百货生鲜'
},
]
},
},
]

View File

@@ -0,0 +1,385 @@
<template>
<div class="model-form">
<div class="model-content">
<!-- 头部广告登录信息不需要拖拽 -->
<div class="top-fixed-advert" :style="{backgroundColor:topAdvert.bgColor}">
<img :src="topAdvert.img" width="1200" height="80" alt="">
<div class="setup-box">
<Button size="small" @click.stop="handleModel('topAdvert')">编辑</Button>
</div>
</div>
<div class="header-con">
<div></div>
<ul class="detail">
<li>立即注册</li>
<li>请登录</li>
<li>我的订单</li>
<li>我的足迹</li>
<li><Icon size="18" type="ios-cart-outline" ></Icon>购物车</li>
<li>店铺入驻</li>
</ul>
</div>
<div class="search-con">
<img :src="require('@/assets/logo.png')" class="logo" alt="">
<div class="search">
<i-input size="large" placeholder="输入你想查找的商品">
<Button slot="append">搜索</Button>
</i-input>
</div>
</div>
<div class="nav-con">
<div class="all-categories">全部商品分类</div>
<ul class="nav-item">
<li v-for="(item,index) in navList.list" :key="index">
<a href="#">{{item.name}}</a>
</li>
</ul>
<div class="setup-box">
<Button size="small" @click.stop="handleModel('quickNav')">编辑</Button>
</div>
</div>
<!-- 装修主体 -->
<div>
<draggable class="model-form-list"
v-model="data.list"
v-bind="{group:'model', ghostClass: 'ghost'}"
@end="handleMoveEnd"
@add="handleModelAdd"
>
<template v-for="(element, index) in data.list">
<model-form-item v-if="element && element.key" :key="element.key" :element="element" :index="index" :data="data"></model-form-item>
</template>
</draggable>
</div>
</div>
<Modal
v-model="showModal"
title="顶部广告"
draggable
width="800"
:z-index="100"
:mask-closable="false"
>
<!-- 顶部广告 -->
<div class="modal-top-advert">
<div>
<img class="show-image" width="600" height="40" :src="topAdvert.img" alt />
</div>
<div class="tips">
建议尺寸<span>{{ topAdvert.size }}</span>
</div>
<div>
图片链接<span>{{ topAdvert.url }}</span><Button size="small" type="primary" @click="handleSelectLink">选择链接</Button>
</div>
<div>
选择图片<Button size="small" type="primary" @click="handleSelectImg">选择图片</Button>&nbsp;
</div>
<div>
选择背景色<ColorPicker v-model="topAdvert.bgColor" />
</div>
</div>
</Modal>
<Modal
v-model="showModalNav"
title="快捷导航"
draggable
width="800"
:z-index="100"
:mask-closable="false"
>
<!-- 分类tab栏 -->
<div class="modal-tab-bar">
<Button type="primary" size='small' @click="handleAddNav">添加分类</Button>
<table cellspacing="0">
<thead>
<tr>
<th width="250">分类名称</th>
<th width="250">链接地址</th>
<!-- <th width="150">排序</th> -->
<th width="250">操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in navList.list" :key="index">
<td><Input v-model="item.name" /></td>
<td><Input v-model="item.url" disabled /></td>
<!-- <td><Input v-model="item.sort"/></td> -->
<td>
<Button type="primary" size="small" @click="handleSelectLink(item,index)">选择链接</Button>&nbsp;
<Button type="error" size="small" @click="handleDelNav(index)">删除</Button>
</td>
</tr>
</tbody>
</table>
</div>
</Modal>
<!-- 选择商品链接 -->
<liliDialog
ref="liliDialog"
@selectedLink="selectedLink"
></liliDialog>
<!-- 选择图片 -->
<Modal width="1200px" v-model="picModelFlag" footer-hide>
<ossManage @callback="callbackSelected" :isComponent="true" ref="ossManage" />
</Modal>
</div>
</template>
<script>
import Draggable from 'vuedraggable'
import ModelFormItem from './modelFormItem.vue'
import ossManage from "@/views/sys/oss-manage/ossManage";
export default {
name:'modelForm',
components:{
Draggable,
ModelFormItem,
ossManage
},
props:['data'],
data(){
return{
picModelFlag: false, // 选择图片模态框
showModal: false, // 顶部广告模态框
showModalNav: false, // 分类nav模态框
selectedNav:null, //当前已选nav
// 模拟搜索框下方数据
promotionTags: [ "买2免1", "领200神券", "199减100", "母婴5折抢", "充100送20"], // 热词数据
topAdvert:{ // 头部广告图数据
type:'topAdvert',
img:'',
url:'',
bgColor:'#de000d',
size:'1200*80'
},
navList:{ // 分类nav数据
type:'navBar',
list:[
{name:'秒杀', url:''}, {name:'闪购', url:''}, {name:'优惠券', url:''}, {name:'拍卖', url:''}, {name:'服装城', url:''},
]
}
}
},
mounted(){
document.body.ondrop = function (event) {
let isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1
if (isFirefox) {
event.preventDefault()
event.stopPropagation()
}
}
},
methods:{
handleSelectLink(item,index) { // 调起选择链接弹窗
if(item) this.selectedNav = item;
this.$refs.liliDialog.open('link')
},
// 已选链接
selectedLink(val) {
console.log(val);
if(this.showModalNav){
this.selectedNav.url = this.$options.filters.formatLinkType(val);
}else {
this.topAdvert.url = this.$options.filters.formatLinkType(val);
}
},
handleDelNav(index){ // 删除导航
this.navList.list.splice(index,1)
},
handleAddNav(){ // 添加导航
this.navList.list.push(
{name:'',url:''}
)
console.log(this.navList.list)
},
// 拖动结束回调
handleMoveEnd ({newIndex, oldIndex}) {
console.log('index', newIndex, oldIndex)
},
// 修改顶部广告
handleModel (type) {
if(type == 'topAdvert'){
this.showModal = true;
} else {
this.showModalNav = true;
}
},
// 选择图片
handleSelectImg() {
this.$refs.ossManage.selectImage = true;
this.picModelFlag = true;
},
callbackSelected (item) { // 选择图片回调
this.picModelFlag = false;
this.topAdvert.img = item.url;
},
handleModelAdd (evt) { // 拖拽,添加模块
const newIndex = evt.newIndex
// 为拖拽到容器的元素添加唯一 key
this.data.list[newIndex] = JSON.parse(JSON.stringify(this.data.list[newIndex]))
const key = Date.parse(new Date()) + '_' + Math.ceil(Math.random() * 99999)
this.$set(this.data.list, newIndex, {
...this.data.list[newIndex],
options: {
...this.data.list[newIndex].options,
},
key,
// 绑定键值
model: this.data.list[newIndex].type + '_' + key
})
},
}
}
</script>
<style lang="scss" scoped>
@import './modelList/setup-box.scss';
.model-form {
width: 1500px;
}
.model-content {
width: 1200px;
margin: 0 auto;
background: #fff;
min-height: 1200px;
}
.model-form-list{
min-height: 500px;
}
/** 顶部广告,头部,搜索框 start */
.top-fixed-advert{
display: flex;
width:1500px;
margin-left: -150px;
background: $theme_color;
justify-content: center;
}
.header-con {
display: flex;
justify-content: space-between;
height: 35px;
padding: 0 15px;
line-height: 35px;
color: #999;
font-weight: bold;
div,li{
&:hover{
color: $theme_color;
cursor: pointer;
}
}
.detail{
display: flex;
>li{
margin-left: 10px;
&::after{
content: "|";
padding-left: 10px;
}
&:last-child::after{
content:'';
padding-left: 0;
}
&:hover::after{
color: #999;
}
}
}
}
/** 搜索框 */
.search-con {
padding-top: 15px;
margin: 0px auto;
margin-bottom: 10px;
width: 1200px;
position: relative;
.logo{
position: absolute;
top: 10px;
left: 10px;
width: 150px;
height: 50px;
}
.search {
width: 460px;
margin: 0 auto;
/deep/ .ivu-input.ivu-input-large {
border: 2px solid $theme_color;
font-size: 12px;
height: 34px;
&:focus {
box-shadow: none;
}
}
/deep/ .ivu-input-group-append {
border: 1px solid $theme_color;
border-left: none;
height: 30px;
background-color: $theme_color;
color: #ffffff;
button {
font-size: 14px;
font-weight: 600;
line-height: 1;
}
}
}
}
/** 商品分类 */
.nav-con{
width:1200px;
height: 40px;
background: #eee;
display: flex;
.all-categories{
width: 200px;
line-height: 40px;
color: #fff;
background-color: $theme_color;
text-align: center;
font-size: 16px;
}
.nav-item {
width: 1000px;
height: 40px;
line-height: 40px;
overflow: hidden;
list-style: none;
background-color: #eee;
display: flex;
li{
font-size: 16px;
font-weight: bold;
margin-left: 20px;
a{
color:rgb(89, 88, 88);
font-size: 15px;
&:hover{color:$theme_color}
}
}
}
}
/** 顶部广告,头部,搜索框 end */
.top-fixed-advert, .nav-con{
position: relative;
&:hover{
.setup-box{
display: block;
}
}
}
/** 装修模态框 内部样式start */
.modal-top-advert{
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
>*{
margin-bottom: 10px;
}
}
</style>

View File

@@ -0,0 +1,491 @@
<template>
<div class="model-item" v-if="element && element.key">
<!-- 轮播图模块包括个人信息快捷导航模块 -->
<template v-if="element.type == 'carousel'">
<model-carousel :data="element"></model-carousel>
</template>
<!-- 轮播图模块100%宽度无个人信息栏 -->
<template v-if="element.type == 'carousel1'">
<model-carousel1 class="mb_20" :data="element"></model-carousel1>
</template>
<!-- 轮播图模块包括个人信息两个轮播模块 -->
<template v-if="element.type == 'carousel2'">
<model-carousel2 class="mb_20" :data="element"></model-carousel2>
</template>
<!-- 热门广告 -->
<template v-if="element.type == 'hotAdvert'">
<div class="setup-content">
<img
style="display: block"
:src="element.options.list[0].img"
@click="$router.push(element.options.list[0].url)"
width="1200"
alt=""
/>
<div class="setup-box">
<div>
<Button
size="small"
@click.stop="handleSelectModel(element.options.list[0])"
>编辑</Button
>
</div>
</div>
</div>
<ul class="advert-list">
<template v-for="(item, index) in element.options.list">
<li
v-if="index !== 0"
@click="$router.push(item.url)"
class="setup-content"
:key="index"
>
<img :src="item.img" width="230" height="190" alt="" />
<div class="setup-box">
<div>
<Button size="small" @click.stop="handleSelectModel(item)"
>编辑</Button
>
</div>
</div>
</li>
</template>
</ul>
</template>
<!-- 限时秒杀 待完善 -->
<template v-if="element.type == 'seckill'">
<seckill :data="element"></seckill>
</template>
<!-- 折扣广告 -->
<template v-if="element.type == 'discountAdvert'">
<div
class="discountAdvert"
:style="{
'background-image':
'url(' + require('@/assets/nav/decorate.png') + ')',
}"
>
<div>
<div
v-for="(item, index) in element.options.classification"
:key="index"
class="setup-content"
>
<img :src="item.img" width="190" height="210" alt="" />
<div class="setup-box">
<div>
<Button size="small" @click.stop="handleSelectModel(item)"
>编辑</Button
>
</div>
</div>
</div>
</div>
<div>
<div
v-for="(item, index) in element.options.brandList"
:key="index"
class="setup-content"
>
<img :src="item.img" width="240" height="105" alt="" />
<div class="setup-box">
<div>
<Button size="small" @click.stop="handleSelectModel(item)"
>编辑</Button
>
</div>
</div>
</div>
</div>
</div>
</template>
<!-- 好货推荐 -->
<template v-if="element.type == 'recommend'">
<recommend :data="element"></recommend>
</template>
<!-- 新品排行 -->
<template v-if="element.type == 'newGoodsSort'">
<new-goods-sort :data="element"></new-goods-sort>
</template>
<!-- 首页广告 -->
<template v-if="element.type == 'firstAdvert'">
<first-page-advert :data="element"></first-page-advert>
</template>
<!-- 横幅广告 -->
<template v-if="element.type == 'bannerAdvert'">
<div class="horizontal-advert setup-content">
<img
v-if="element.options.img"
width="1200"
:src="element.options.img"
alt=""
/>
<div v-else class="default-con">
<p>广告图片</p>
<p>1200*自定义</p>
</div>
<div class="setup-box">
<div>
<Button
size="small"
@click.stop="handleSelectModel(element.options)"
>编辑</Button
>
</div>
</div>
</div>
</template>
<template v-if="element.type == 'notEnough'">
<not-enough :data="element"></not-enough>
</template>
<div class="del-btn">
<Button size="small" type="error" @click="handleModelDelete">删除</Button>
</div>
<Modal
v-model="showModal"
title="装修"
draggable
width="800"
:z-index="100"
:mask-closable="false"
>
<div class="modal-top-advert">
<div>
<!-- 热门广告两种图片尺寸 -->
<img
class="show-image"
width="600"
height="40"
v-if="selected.size && selected.size.indexOf('1200') >= 0"
:src="selected.img"
alt
/>
<img
class="show-image"
width="230"
height="190"
v-if="selected.size && selected.size.indexOf('230*190') >= 0"
:src="selected.img"
alt
/>
<!-- 折扣广告三种图片尺寸 -->
<img
class="show-image"
width="600"
height="300"
v-if="selected.size && selected.size.indexOf('1300') >= 0"
:src="selected.img"
alt
/>
<img
class="show-image"
width="190"
height="210"
v-if="selected.size && selected.size.indexOf('190*210') >= 0"
:src="selected.img"
alt
/>
<img
class="show-image"
width="240"
height="105"
v-if="selected.size && selected.size.indexOf('240*105') >= 0"
:src="selected.img"
alt
/>
</div>
<div class="tips">
建议尺寸<span>{{ selected.size }}</span>
</div>
<div>
图片链接<span>{{ selected.url }}</span>
<Button size="small" type="primary" @click="handleSelectLink"
>选择链接</Button
>
</div>
<div>
选择图片<Button size="small" type="primary" @click="handleSelectImg"
>选择图片</Button
>&nbsp;
</div>
</div>
</Modal>
<!-- 选择商品链接 -->
<liliDialog
ref="liliDialog"
@selectedLink="selectedLink"
></liliDialog>
<!-- 选择图片 -->
<Modal width="1200px" v-model="picModelFlag" footer-hide>
<ossManage
@callback="callbackSelected"
:isComponent="true"
ref="ossManage"
/>
</Modal>
</div>
</template>
<script>
import ModelCarousel from "./modelList/carousel.vue";
import ModelCarousel1 from './modelList/carousel1.vue';
import ModelCarousel2 from './modelList/carousel2.vue';
import FirstPageAdvert from "./modelList/firstPageAdvert.vue";
import NewGoodsSort from "./modelList/newGoodsSort.vue";
import Recommend from "./modelList/recommend.vue";
import NotEnough from "./modelList/notEnough.vue";
import Seckill from "./modelList/seckill.vue";
import ossManage from "@/views/sys/oss-manage/ossManage";
export default {
name: "modelFormItem",
props: ["element", "select", "index", "data"],
components: {
ModelCarousel,
ModelCarousel1,
ModelCarousel2,
Recommend,
NewGoodsSort,
FirstPageAdvert,
NotEnough,
Seckill,
ossManage,
},
data() {
return {
showModal: false, // modal显隐
selected: {}, // 已选数据
picModelFlag: false, // 图片选择器
};
},
methods: {
// 编辑模块
handleSelectModel(item) {
this.selected = item;
this.showModal = true;
},
// 删除模块
handleModelDelete() {
this.$Modal.confirm({
title: "提示",
content: "<p>确定删除当前模块吗?</p>",
onOk: () => {
this.$nextTick(() => {
this.data.list.splice(this.index, 1);
});
},
});
},
handleSelectLink(item, index) {
// 调起选择链接弹窗
this.$refs.liliDialog.open("link");
},
// 确定选择链接
selectedLink(val) {
this.selected.url = this.$options.filters.formatLinkType(val);
},
handleSelectImg() {
// 选择图片
this.$refs.ossManage.selectImage = true;
this.picModelFlag = true;
},
// 回显图片
callbackSelected(val) {
this.picModelFlag = false;
this.selected.img = val.url;
},
},
};
</script>
<style lang="scss" scoped>
@import "./modelList/setup-box.scss";
.model-item {
position: relative;
margin-bottom: 20px;
&:hover {
.del-btn {
display: block;
}
}
}
.del-btn {
width: 100px;
height: 100px;
display: none;
position: absolute;
right: -100px;
top: 0;
&:hover {
display: block;
}
}
/** 横幅广告 */
.horizontal-advert {
width: 1200px;
height: auto;
.default-con {
height: 100px;
padding-top: 30px;
text-align: center;
background: #ddd;
}
}
/** 热门广告 */
.advert-list {
background: $theme_color;
height: 200px;
display: flex;
justify-content: space-around;
padding: 3px 10px;
> li {
img {
cursor: pointer;
border-radius: 10px;
transition: all 150ms ease-in-out;
&:hover {
transform: translateY(-3px);
box-shadow: rgba(0, 0, 0, 0.4) 0px 5px 20px 0px;
}
}
}
}
/** 限时秒杀 */
.limit-img {
display: flex;
flex-direction: row;
img {
width: 300px;
height: 100px;
}
}
/** 折扣广告 */
.discountAdvert {
height: 566px;
background-repeat: no-repeat;
margin-left: -97px;
position: relative;
> div {
padding-left: 295px;
display: flex;
flex-wrap: wrap;
&:nth-child(1) img {
margin: 10px 10px 0 0;
}
&:nth-child(2) img {
margin: 0 10px 0 0;
}
}
}
/** 首页品牌 */
.brand {
.brand-view {
display: flex;
margin-top: 10px;
.brand-view-content {
width: 470px;
margin-left: 10px;
img {
width: 100%;
height: 316px;
}
.brand-view-title {
height: 50px;
padding: 0 5px;
display: flex;
align-items: center;
justify-content: space-between;
}
}
.brand-view-content:first-child {
width: 240px;
margin-left: 0;
}
}
.brand-list {
margin-top: 10px;
display: flex;
align-items: center;
flex-wrap: wrap;
li {
width: 121px;
height: 112px;
position: relative;
overflow: hidden;
border: 1px solid #f5f5f5;
margin: -1px -1px 0 0;
&:hover {
.brand-mash {
display: flex;
}
}
.brand-img {
text-align: center;
margin-top: 30px;
img {
width: 100px;
height: auto;
}
}
.brand-mash {
display: none;
position: absolute;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.5);
width: inherit;
height: inherit;
font-size: 12px;
font-weight: bold;
.ivu-icon {
position: absolute;
right: 10px;
top: 10px;
font-size: 15px;
}
align-items: center;
justify-content: center;
flex-direction: column;
color: #fff;
cursor: pointer;
div:last-child {
background-color: $theme_color;
border-radius: 9px;
padding: 0 10px;
margin-top: 5px;
}
}
}
.refresh {
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
.ivu-icon {
font-size: 18px;
transition: all 0.3s ease-out;
}
&:hover {
background-color: $theme_color;
color: #fff;
.ivu-icon {
transform: rotateZ(360deg);
}
}
}
}
}
/** 装修模态框 内部样式start */
.modal-top-advert {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
> * {
margin-bottom: 10px;
}
}
</style>

View File

@@ -0,0 +1,290 @@
<template>
<div class="model-carousel">
<div class="nav-body clearfix">
<!-- 侧边导航 -->
<div class="nav-side">分类占位区</div>
<div class="nav-content setup-content">
<!-- 轮播图 -->
<Carousel autoplay>
<CarouselItem v-for="(item, index) in data.options.list" :key="index">
<div style="overflow: hidden">
<img :src="item.img" width="790" height="340" />
</div>
</CarouselItem>
</Carousel>
<div class="setup-box">
<div>
<Button size="small" @click.stop="handleSelectModel">编辑</Button>
</div>
</div>
</div>
<div class="nav-right">
<div class="person-msg">
<img :src="userInfo.face" v-if="userInfo.face" alt />
<Avatar icon="ios-person" class="mb_10" v-else size="80" />
<div>Hi{{ userInfo.nickName || "欢迎来到管理后台" | secrecyMobile }}</div>
<div v-if="userInfo.id">
<Button type="error" shape="circle">会员中心</Button>
</div>
<div v-else>
<Button type="error" shape="circle">请登录</Button>
</div>
</div>
<div class="shop-msg">
<div>
<span>常见问题</span>
<ul class="article-list">
<li class="ellipsis" :alt="article.title" v-for="(article, index) in articleList" :key="index" @click="goArticle(article.id)">
{{article.title}}
</li>
</ul>
</div>
</div>
</div>
</div>
<Modal
v-model="showModal"
title="快捷导航"
draggable
width="800"
:z-index="100"
:mask-closable="false"
>
<div class="modal-tab-bar">
<Button type="primary" size="small" @click="handleAdd">添加轮播</Button>
&nbsp;
<span class="ml_10">图片尺寸:{{ data.size }}</span>
<div style="color: #999" class="fz_12">点击缩略图替换图片</div>
<table cellspacing="0">
<thead>
<tr>
<th width="250">所选图片</th>
<th width="250">链接地址</th>
<!-- <th width="150">排序</th> -->
<th width="250">操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in data.options.list" :key="index">
<td>
<img
style="cursor: pointer"
:src="item.img"
@click="handleSelectImg(item)"
width="200"
height="100"
alt=""
/>
</td>
<td><Input v-model="item.url" disabled /></td>
<!-- <td><Input v-model="item.sort"/></td> -->
<td>
<Button
type="primary"
size="small"
@click="handleSelectImg(item)"
>选择图片</Button
>&nbsp;
<Button
type="info"
size="small"
@click="handleSelectLink(item)"
>选择链接</Button
>&nbsp;
<Button
type="error"
ghost
size="small"
@click="handleDel(index)"
>删除</Button
>
</td>
</tr>
</tbody>
</table>
</div>
</Modal>
<!-- 选择商品链接 -->
<liliDialog
ref="liliDialog"
@selectedLink="selectedLink"
></liliDialog>
<!-- 选择图片 -->
<Modal width="1200px" v-model="picModelFlag" footer-hide>
<ossManage @callback="callbackSelected" :isComponent="true" ref="ossManage" />
</Modal>
</div>
</template>
<script>
import ossManage from "@/views/sys/oss-manage/ossManage";
export default {
name: "modelCarousel",
props: ["data"],
components: {
ossManage
},
data() {
return {
showModal: false, // modal显隐
selected: null, // 已选数据
picModelFlag: false, // 选择图片modal
userInfo:{},
articleList:[
{title:'促销计算规则'},
{title:'商家申请开店'},
{title:'商家账号注册'},
{title:'促销计算规则'}
]
};
},
methods: {
handleSelectModel () {
// 编辑模块
this.showModal = true;
},
// 添加轮播图
handleAdd () {
this.data.options.list.push({ img: "", url: "" });
this.$forceUpdate();
},
handleSelectLink (item) {
// 选择链接
this.$refs.liliDialog.open('link')
this.selected = item;
},
callbackSelected (item) { // 选择图片回调
this.picModelFlag = false;
this.selected.img = item.url;
},
handleDel(index) {
// 删除图片
this.data.options.list.splice(index, 1);
},
selectedLink(val) { // 选择链接回调
console.log(val);
this.selected.url = this.$options.filters.formatLinkType(val);
console.log(this.selected.url);
},
// 选择图片
handleSelectImg(item) {
this.selected = item;
this.$refs.ossManage.selectImage = true;
this.picModelFlag = true;
},
},
};
</script>
<style scoped lang="scss">
@import "./setup-box.scss";
.model-carousel {
width: 1200px;
height: 340px;
overflow: hidden;
}
.nav-item li {
float: left;
font-size: 16px;
font-weight: bold;
margin-left: 30px;
}
.nav-item a {
text-decoration: none;
color: #555555;
}
.nav-item a:hover {
color: $theme_color;
}
/*大的导航信息,包含导航,幻灯片等*/
.nav-body {
width: 1200px;
height: 340px;
margin: 0px auto;
}
.nav-side {
height: 100%;
width: 200px;
padding: 0px;
color: #fff;
float: left;
background-color: #6e6568;
line-height: 340px;
text-align: center;
}
/*导航内容*/
.nav-content {
width: 800px;
height: 340px;
overflow: hidden;
float: left;
position: relative;
}
.nav-right {
float: left;
width: 200px;
.person-msg {
display: flex;
align-items: center;
flex-direction: column;
margin: 20px auto;
button {
height: 25px !important;
margin-top: 10px;
}
.ivu-btn-default {
color: $theme_color;
border-color: $theme_color;
}
img {
margin-bottom: 10px;
width: 80px;
height: 80px;
border-radius: 50%;
}
}
.shop-msg {
div {
width: 100%;
margin: 10px 27px;
span {
cursor: pointer;
text-align: center;
font-weight: bold;
margin-left: 5px;
}
span:nth-child(1) {
color: $theme_color;
margin-left: 0;
}
span:nth-child(2) {
font-weight: normal;
}
span:nth-child(3):hover {
color: $theme_color;
}
}
ul {
margin: 0 30px;
li {
cursor: pointer;
margin: 5px 0;
color: #999395;
&:hover {
color: $theme_color;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,188 @@
<template>
<div class="model-carousel1" :style="{background: bgColor}">
<div class="nav-body clearfix">
<!-- 侧边导航 -->
<div class="nav-side">分类占位区</div>
<div class="nav-content setup-content">
<!-- 轮播图 -->
<Carousel autoplay @on-change="autoChange">
<CarouselItem v-for="(item, index) in data.options.list" :key="index" >
<div style="overflow: hidden">
<img :src="item.img" width="1200" height="470" />
</div>
</CarouselItem>
</Carousel>
<div class="setup-box">
<div>
<Button size="small" @click.stop="handleSelectModel">编辑</Button>
</div>
</div>
</div>
</div>
<Modal
v-model="showModal"
title="快捷导航"
draggable
width="800"
:z-index="100"
:mask-closable="false"
>
<div class="modal-tab-bar">
<Button type="primary" size="small" @click="handleAdd">添加轮播</Button>
&nbsp;
<span class="ml_10">图片尺寸:{{ data.size }}</span>
<span style="color: red" class="fz_12 ml_10">点击缩略图替换图片点击颜色选择器选择背景色</span>
<table cellspacing="0">
<thead>
<tr>
<th width="250">所选图片</th>
<th width="250">链接地址</th>
<th width="250">操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in data.options.list" :key="index">
<td>
<img
style="cursor: pointer"
:src="item.img"
@click="handleSelectImg(item)"
width="200"
height="100"
alt=""
/>
</td>
<td><Input v-model="item.url" disabled /></td>
<td>
<Button
type="info"
size="small"
@click="handleSelectLink(item)"
>选择链接</Button
>&nbsp;
<ColorPicker size="small" v-model="item.bgColor" />
&nbsp;
<Button
type="error"
ghost
size="small"
@click="handleDel(index)"
>删除</Button
>
</td>
</tr>
</tbody>
</table>
</div>
</Modal>
<!-- 选择商品链接 -->
<liliDialog
ref="liliDialog"
@selectedLink="selectedLink"
></liliDialog>
<!-- 选择图片 -->
<Modal width="1200px" v-model="picModelFlag" footer-hide>
<ossManage @callback="callbackSelected" ref="ossManage" />
</Modal>
</div>
</template>
<script>
import ossManage from "@/views/sys/oss-manage/ossManage";
export default {
name: "modelCarousel",
props: ["data"],
components: {
ossManage
},
data() {
return {
showModal: false, // modal显隐
selected: null, // 已选数据
picModelFlag: false, // 选择图片modal
bgColor:'#fff' // 轮播背景色
};
},
mounted () {
this.bgColor = this.data.options.list[0].bgColor
},
methods: {
handleSelectModel () {
// 编辑模块
this.showModal = true;
},
// 自动切换时改变背景色
autoChange (oVal,val) {
this.bgColor = this.data.options.list[val].bgColor
},
// 添加轮播图片和链接
handleAdd () {
this.data.options.list.push({ img: "", url: "", bgColor: '#fff' });
this.$forceUpdate();
},
// 打开选择链接modal
handleSelectLink (item) {
this.$refs.liliDialog.open('link')
this.selected = item;
},
callbackSelected (item) { // 选择图片回调
this.picModelFlag = false;
this.selected.img = item.url;
},
// 删除图片
handleDel(index) {
this.data.options.list.splice(index, 1);
},
selectedLink(val) { // 选择链接回调
this.selected.url = this.$options.filters.formatLinkType(val);
},
// 打开选择图片modal
handleSelectImg(item) {
this.selected = item;
this.$refs.ossManage.selectImage = true;
this.picModelFlag = true;
}
},
};
</script>
<style scoped lang="scss">
@import "./setup-box.scss";
.model-carousel1 {
width: 1500px;
height: 470px;
margin-left: -150px;
background: #fff;
}
/*大的导航信息,包含导航,幻灯片等*/
.nav-body {
width: 1200px;
height: 470px;
margin: 0px auto;
}
.nav-side {
height: 100%;
width: 200px;
padding: 0px;
color: #fff;
background-color:rgba(0,0,0,.5);
line-height: 470px;
text-align: center;
position: absolute;
z-index: 1;
}
/*导航内容*/
.nav-content {
width: 1200px;
height: 470px;
overflow: hidden;
float: left;
position: relative;
}
</style>

View File

@@ -0,0 +1,368 @@
<template>
<div class="model-carousel2">
<div class="nav-body clearfix">
<!-- 侧边导航 -->
<div class="nav-side">分类占位区</div>
<div class="nav-content setup-content">
<!-- 轮播图 -->
<Carousel autoplay>
<CarouselItem v-for="(item, index) in data.options.list" :key="index">
<div style="overflow: hidden">
<img :src="item.img" width="590" height="470" />
</div>
</CarouselItem>
</Carousel>
<div class="setup-box">
<div>
<Button size="small" @click.stop="handleSelectModel">编辑</Button>
</div>
</div>
</div>
<div class="nav-content1 setup-content">
<!-- 轮播图 -->
<Carousel autoplay :autoplay-speed="5000">
<CarouselItem v-for="(item, index) in data.options.listRight" :key="index">
<div class="mb_10">
<img :src="item[0].img" width="190" height="150" />
</div>
<div class="mb_10">
<img :src="item[1].img" width="190" height="150" />
</div>
<div>
<img :src="item[2].img" width="190" height="150" />
</div>
</CarouselItem>
</Carousel>
<div class="setup-box">
<div>
<Button size="small" @click.stop="handleSelectModel">编辑</Button>
</div>
</div>
</div>
<div class="nav-right">
<div class="person-msg">
<img :src="userInfo.face" v-if="userInfo.face" alt />
<Avatar icon="ios-person" class="mb_10" v-else size="80" />
<div>Hi{{ userInfo.nickName || "欢迎来到管理后台" | secrecyMobile }}</div>
<div v-if="userInfo.id">
<Button type="error" shape="circle">会员中心</Button>
</div>
<div v-else>
<Button type="error" shape="circle">请登录</Button>
</div>
</div>
<div class="shop-msg">
<div>
<span>常见问题</span>
<ul class="article-list">
<li class="ellipsis" :alt="article.title" v-for="(article, index) in articleList" :key="index" @click="goArticle(article.id)">
{{article.title}}
</li>
</ul>
</div>
</div>
</div>)
</div>
<!-- 左侧轮播装修 -->
<Modal
v-model="showModal"
title="快捷导航"
draggable
width="800"
:z-index="100"
:mask-closable="false"
>
<div class="modal-tab-bar">
<Button type="primary" size="small" @click="handleAdd">添加轮播</Button>
&nbsp;
<span class="ml_10">图片尺寸:{{ data.size }}</span>
<span style="color: red" class="fz_12 ml_10">点击缩略图替换图片</span>
<table cellspacing="0">
<thead>
<tr>
<th width="250">所选图片</th>
<th width="250">链接地址</th>
<th width="250">操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in data.options.list" :key="index">
<td>
<img
style="cursor: pointer"
:src="item.img"
@click="handleSelectImg(item)"
width="200"
height="100"
alt=""
/>
</td>
<td><Input v-model="item.url" disabled /></td>
<td>
<Button
type="info"
size="small"
@click="handleSelectLink(item)"
>选择链接</Button>&nbsp;
<Button
type="error"
ghost
size="small"
@click="handleDel(index)"
>删除</Button
>
</td>
</tr>
</tbody>
</table>
</div>
</Modal>
<!-- 右侧轮播装修 -->
<Modal
v-model="showModal"
title="右侧装修"
draggable
width="800"
:z-index="100"
:mask-closable="false"
>
<div class="modal-tab-bar">
<Button type="primary" size="small" @click="handleAddGroup">添加组</Button>
&nbsp;
<span class="ml_10">图片尺寸:{{ data.size }}</span>
<span style="color: red" class="fz_12 ml_10">点击缩略图替换图片</span>
<Tabs type="card" closable @on-tab-remove="handleTabRemove" class="mt_10">
<TabPane :label="'图片组'+(gIndex+1)" v-for="(group, gIndex) in data.options.listRight" :key="gIndex">
<table cellspacing="0">
<thead>
<tr>
<th width="250">所选图片</th>
<th width="250">链接地址</th>
<th width="250">操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in group" :key="index">
<td>
<img
style="cursor: pointer"
:src="item.img"
@click="handleSelectImg(item)"
width="200"
height="100"
alt=""
/>
</td>
<td><Input v-model="item.url" disabled /></td>
<td>
<Button
type="info"
size="small"
@click="handleSelectLink(item)"
>选择链接</Button>
</td>
</tr>
</tbody>
</table>
</TabPane>
</Tabs>
</div>
</Modal>
<!-- 选择商品链接 -->
<liliDialog
ref="liliDialog"
@selectedLink="selectedLink"
></liliDialog>
<!-- 选择图片 -->
<Modal width="1200px" v-model="picModelFlag" footer-hide>
<ossManage @callback="callbackSelected" ref="ossManage" />
</Modal>
</div>
</template>
<script>
import ossManage from "@/views/sys/oss-manage/ossManage";
export default {
name: "modelCarousel",
props: ["data"],
components: {
ossManage
},
data() {
return {
showModal: false, // modal显隐
selected: null, // 已选数据
picModelFlag: false, // 选择图片modal
userInfo:{},
articleList:[
{title:'促销计算规则'},
{title:'商家申请开店'},
{title:'商家账号注册'},
{title:'促销计算规则'}
]
};
},
methods: {
handleSelectModel () {
// 编辑模块
this.showModal = true;
},
// 添加轮播
handleAdd () {
this.data.options.list.push({ img: "", url: "" });
this.$forceUpdate();
},
// 添加图片组
handleAddGroup () {
this.data.options.listRight.push([
{img:'',url:''},
{img:'',url:''},
{img:'',url:''}
])
},
// 删除图片组
handleTabRemove (index) {
this.data.options.listRight.splice(index, 1)
},
// 打开图片链接
handleSelectLink (item) {
this.$refs.liliDialog.open('link')
this.selected = item;
},
callbackSelected (item) { // 选择图片回调
this.picModelFlag = false;
this.selected.img = item.url;
},
// 删除图片
handleDel(index) {
this.data.options.list.splice(index, 1);
},
selectedLink(val) { // 选择链接回调
console.log(val);
this.selected.url = this.$options.filters.formatLinkType(val);
console.log(this.selected.url);
},
// 打开选择图片modal
handleSelectImg(item) {
this.selected = item;
this.$refs.ossManage.selectImage = true;
this.picModelFlag = true;
},
},
};
</script>
<style scoped lang="scss">
@import "./setup-box.scss";
.model-carousel2 {
width: 1200px;
height: 470px;
overflow: hidden;
}
.nav-item li {
float: left;
font-size: 16px;
font-weight: bold;
margin-left: 30px;
}
.nav-item a {
text-decoration: none;
color: #555555;
}
.nav-item a:hover {
color: $theme_color;
}
/*大的导航信息,包含导航,幻灯片等*/
.nav-body {
width: 1200px;
height: 470px;
margin: 0px auto;
}
.nav-side {
height: 100%;
width: 200px;
padding: 0px;
color: #fff;
float: left;
background-color: #6e6568;
line-height: 470px;
text-align: center;
}
/*导航内容*/
.nav-content,.nav-content1 {
width: 590px;
height: 470px;
overflow: hidden;
float: left;
position: relative;
margin-left: 10px;
}
.nav-content1{
width: 190px;
}
.nav-right {
float: left;
width: 190px;
margin-left: 10px;
.person-msg {
display: flex;
align-items: center;
flex-direction: column;
margin: 20px auto;
button {
height: 25px !important;
margin-top: 10px;
}
.ivu-btn-default {
color: $theme_color;
border-color: $theme_color;
}
img {
margin-bottom: 10px;
width: 80px;
height: 80px;
border-radius: 50%;
}
}
.shop-msg {
div {
width: 100%;
margin: 10px 27px;
span {
cursor: pointer;
text-align: center;
font-weight: bold;
margin-left: 5px;
}
span:nth-child(1) {
color: $theme_color;
margin-left: 0;
}
span:nth-child(2) {
font-weight: normal;
}
span:nth-child(3):hover {
color: $theme_color;
}
}
ul {
li {
cursor: pointer;
margin: 5px 0;
color: #999395;
width: 150px;
font-size: 12px;
&:hover {
color: $theme_color;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,162 @@
<template>
<div class="first-page-advert">
<div class="item setup-content" :style="{backgroundImage:`linear-gradient(to right, ${item.fromColor}, ${item.toColor})`}" v-for="(item, index) in options.list" :key="index">
<div>
<span class="line top-line"></span>
<p>{{item.name}}</p>
<span class="line btm-line"></span>
<p>{{item.describe}}</p>
</div>
<img :src="item.img" width="170" height="170" alt="">
<div class="setup-box">
<div><Button size="small" @click.stop="handleSelectModel(item)">编辑</Button></div>
</div>
</div>
<Modal
v-model="showModal"
title="装修"
draggable
width="800"
:z-index="100"
:mask-closable="false"
>
<div class="modal-top-advert">
<div>
<img class="show-image" width="170" height="170" :src="selected.img" alt />
</div>
<div>
<span>图片主标题</span><Input v-model="selected.name" />
</div>
<div>
<span>图片描述</span><Input v-model="selected.describe" />
</div>
<div class="tips">
建议尺寸<span>{{ selected.size }}</span>
</div>
<div>
图片链接<span>{{ selected.url }}</span> <Button size="small" type="primary" @click="handleSelectLink">选择链接</Button>
</div>
<div>
<span>渐变背景色</span><Input v-model="selected.fromColor" /> <ColorPicker v-if="selected.fromColor" v-model="selected.fromColor" />
</div>
<div>
<span>渐变背景色</span><Input v-model="selected.toColor" /> <ColorPicker v-if="selected.toColor" v-model="selected.toColor" />
</div>
<div :style="{backgroundImage:`linear-gradient(to right, ${selected.fromColor}, ${selected.toColor})`}" class="exhibition"></div>
<div>
选择图片<Button size="small" type="primary" @click="handleSelectImg">选择图片</Button>&nbsp;
</div>
</div>
</Modal>
<!-- 选择商品链接 -->
<liliDialog
ref="liliDialog"
@selectedLink="selectedLink"
></liliDialog>
<!-- 选择图片 -->
<Modal width="1200px" v-model="picModelFlag" footer-hide>
<ossManage @callback="callbackSelected" :isComponent="true" ref="ossManage" />
</Modal>
</div>
</template>
<script>
import ossManage from "@/views/sys/oss-manage/ossManage";
export default {
props:{
data: {
type: Object,
default: null
}
},
components: {ossManage},
data() {
return {
options: this.data.options, // 当前类型数据
showModal: false, // modal显隐
selected: {}, // 已选数据
picModelFlag: false // 图片选择器
}
},
methods:{
// 打开装修modal
handleSelectModel (item,type) {
this.selected = item;
this.showModal = true
},
handleSelectLink(item,index) { // 调起选择链接弹窗
this.$refs.liliDialog.open('link')
},
// 选择链接回调
selectedLink(val) {
this.selected.url = this.$options.filters.formatLinkType(val);;
},
handleSelectImg(){ // 选择图片
this.$refs.ossManage.selectImage = true;
this.picModelFlag = true;
},
// 选择图片回调
callbackSelected (val) {
this.picModelFlag = false;
this.selected.img = val.url;
}
}
}
</script>
<style lang="scss" scoped>
@import './setup-box.scss';
.first-page-advert{
display: flex;
flex-wrap: wrap;
justify-content: space-between;
// margin-top: -10px;
.item{
width: 393px;
height: 170px;
margin-top: 10px;
display: flex;
align-items: center;
justify-content: center;
img{margin-left: 20px;}
&:nth-of-type(1),&:nth-of-type(2),&:nth-of-type(3){margin-top: 0;}
p:nth-of-type(1){
margin: 3px 0;
font-size: 18px;
color: #fff;
}
p:nth-of-type(2){
margin-top: 3px;
color: #fff;
}
}
.line{
position: relative;
display: block;
height: 2px;
background: url('../../../assets/festival_icon.png');
z-index: 1;
}
.top-line{
width: 78px;
background-position: -1px -3px;
}
.btm-line{
background-position: 0 -11px;
width: 154px;
}
}
.modal-top-advert{
align-items: start;
padding: 0 30px;
.exhibition{
width: 300px;
height: 50px;
}
}
</style>

View File

@@ -0,0 +1,339 @@
<template>
<div class="new-goods">
<div class="left">
<div class="top-header setup-content" :style="{background:options.left.bgColor}">
<span>{{options.left.title}}</span>
<span>{{options.left.secondTitle}} &gt;</span>
<div class="setup-box">
<div><Button size="small" @click.stop="handleSelectModel(options.left,true)">编辑</Button></div>
</div>
</div>
<div class="content">
<div class="con-item setup-content" v-for="(item, index) in options.left.list" :key="index">
<div>
<p>{{item.name}}</p>
<p class="describe">{{item.describe}}</p>
</div>
<img :src="item.img" alt="">
<div class="setup-box">
<div><Button size="small" @click.stop="handleSelectModel(item)">编辑</Button></div>
</div>
</div>
</div>
</div>
<div class="middle">
<div class="top-header setup-content" :style="{background:options.middle.bgColor}">
<span>{{options.middle.title}}</span>
<span>{{options.middle.secondTitle}} &gt;</span>
<div class="setup-box">
<div><Button size="small" @click.stop="handleSelectModel(options.middle,true)">编辑</Button></div>
</div>
</div>
<div class="content">
<div class="con-item setup-content" v-for="(item, index) in options.middle.list" :key="index">
<div>
<p>{{item.name}}</p>
<p class="describe">{{item.describe}}</p>
</div>
<img :src="item.img" alt="">
<div class="setup-box">
<div><Button size="small" @click.stop="handleSelectModel(item)">编辑</Button></div>
</div>
</div>
</div>
</div>
<div class="right">
<div class="top-header setup-content" :style="{background:options.right.bgColor}">
<span>{{options.right.title}}</span>
<span>{{options.right.secondTitle}} &gt;</span>
<div class="setup-box">
<div><Button size="small" @click.stop="handleSelectModel(options.right,true)">编辑</Button></div>
</div>
</div>
<div class="content">
<div class="setup-content" v-for="(item, index) in options.right.list" :key="index">
<img :src="item.img" alt="">
<p>{{item.name}}</p>
<p>{{item.price | unitPrice('¥')}}</p>
<div class="jiaobiao" :class="'jiaobiao'+(index+1)">{{index+1}}</div>
<div class="setup-box">
<div><Button size="small" @click.stop="handleSelectGoods(item)">编辑</Button></div>
</div>
</div>
</div>
</div>
<!-- 装修内容 -->
<Modal
v-model="showModal"
title="装修"
draggable
width="800"
:z-index="100"
:mask-closable="false"
>
<div class="modal-top-advert">
<div>
<img class="show-image" width="160" height="160" v-if="selected.size && selected.size.indexOf('160*160')>=0" :src="selected.img" alt />
<img class="show-image" width="80" height="80" v-if="selected.size && selected.size.indexOf('90*90')>=0" :src="selected.img" alt />
</div>
<div>
<span>图片主标题</span><Input v-model="selected.name" />
</div>
<div>
<span>图片描述</span><Input v-model="selected.describe" />
</div>
<div class="tips">
建议尺寸<span>{{ selected.size }}</span>
</div>
<div>
图片链接<span>{{ selected.url }}</span> <Button size="small" type="primary" @click="handleSelectLink">选择链接</Button>
</div>
<div>
<Button size="small" type="primary" @click="handleSelectImg">选择图片</Button>&nbsp;
<Button size="small" type="primary" @click="handleSelectGoods('')">选择商品</Button>
</div>
</div>
</Modal>
<!-- 装修标题 -->
<Modal
v-model="showModal1"
title="装修"
draggable
width="800"
:z-index="100"
:mask-closable="false"
>
<div class="modal-top-advert">
<div>
<span>主标题</span><Input v-model="selected.title" />
</div>
<div>
<span>副标题</span><Input v-model="selected.secondTitle" />
</div>
<div>
<span>副标题链接{{selected.url}}</span><Button size="small" class="ml_10" type="primary" @click="handleSelectLink">选择链接</Button>
</div>
<div>
<span>背景色</span><ColorPicker v-if="selected.bgColor" v-model="selected.bgColor" />
</div>
</div>
</Modal>
<!-- 选择商品链接 -->
<liliDialog
ref="liliDialog"
@selectedLink="selectedLink"
@selectedGoodsData="selectedGoodsData"
></liliDialog>
<!-- 选择图片 -->
<Modal width="1200px" v-model="picModelFlag" footer-hide>
<ossManage @callback="callbackSelected" :isComponent="true" ref="ossManage" />
</Modal>
</div>
</template>
<script>
import ossManage from "@/views/sys/oss-manage/ossManage";
export default {
props:{
data:{
type:Object,
default:null
}
},
components:{
ossManage
},
data() {
return {
options:this.data.options, // 当前数据
showModal:false, // modal显隐
showModal1:false, // modal显隐
selected: {}, // 已选数据
picModelFlag: false // 选择图片modal
}
},
methods:{
// 装修modal
handleSelectModel (item, type) {
this.selected = item;
console.warn(item);
if(type){
this.showModal1 = true
} else {
this.showModal = true
}
},
handleSelectLink() { // 调起选择链接弹窗
this.$refs.liliDialog.open('link')
},
handleSelectGoods(item) { // 调起选择商品
console.warn(item);
if (item) this.selected = item;
this.$refs.liliDialog.open('goods', 'single')
setTimeout(() => {
this.$refs.liliDialog.goodsData = [this.selected]
}, 500);
},
// 选择链接回调
selectedLink (val) {
this.selected.url = this.$options.filters.formatLinkType(val);
},
// 选择商品回调
selectedGoodsData (val) {
console.log(val);
let goods = val[0]
console.log(this.selected);
this.selected.img = goods.thumbnail
this.selected.price = goods.price
this.selected.name = goods.goodsName
this.selected.url = `/goodsDetail?skuId=${goods.id}&goodsId=${goods.goodsId}`
},
handleSelectImg(){ // 选择图片
this.$refs.ossManage.selectImage = true;
this.picModelFlag = true;
},
// 选择图片回显
callbackSelected (val) {
this.picModelFlag = false;
this.selected.img = val.url;
}
}
}
</script>
<style lang="scss" scoped>
@import './setup-box.scss';
.new-goods{
display: flex;
justify-content: space-between;
>div{
width: 393px;
height: 440px;
}
.left>.content{
>div:nth-child(1){
height: 240px;
flex-direction: column;
border: 1px solid #eee;
border-top: none;
border-left: none;
justify-content: space-between;
img{
width: 160px;
height: 160px;
}
.describe{margin-top: 10px;}
}
>div:nth-child(2){border-right: 1px solid #eee;}
>div:nth-child(3),>div:nth-child(4){border-bottom: 1px solid #eee;}
}
.middle>.content{
>div{
border-style:solid;
border-color: #eee;
border-width: 0;
border-bottom-width: 1px;
}
>div:nth-child(1),>div:nth-child(2),>div:nth-child(3){border-right-width: 1px;}
>div:nth-child(6), >div:nth-child(3){border-bottom-width: 0;}
}
.right>.content{
display: flex;
flex-wrap: wrap;
flex-direction: row;
font-size: 12px;
>div{
position: relative;
width: 120px;
padding: 5px 10px 0 10px;
img{
width: 100px;
height: 100px;
}
border-bottom: 1px solid #eee;
:nth-child(2){
height: 38px;
overflow: hidden;
}
:nth-child(3){
color: $theme_color;
margin-top: 5px;
}
.jiaobiao{
position: absolute;
width: 23px;
height: 23px;
top: 10px;
right: 16px;
background: url('../../../assets/festival_icon.png');
color: #FFF;
text-align: center;
}
.jiaobiao1,.jiaobiao4{
background-position: -2px -30px;
}
.jiaobiao2,.jiaobiao5{
background-position: -31px -30px;
}
.jiaobiao3,.jiaobiao6{
background-position: -60px -30px;
}
}
>div:nth-child(4),>div:nth-child(5),>div:nth-child(6){border: none;}
}
.top-header{
display: flex;
align-items: center;
justify-content: space-between;
height: 50px;
padding: 0 10px;
background: #c43d7e;
color: #fff;
span:nth-child(1){
font-size: 20px;
}
span:nth-child(2){
font-size: 12px;
}
}
.content{
padding: 10px 12px 0;
display: flex;
flex-wrap: wrap;
flex-direction: column;
height: 370px;
}
.con-item{
width: 185px;
height: 120px;
display: flex;
padding-left: 10px;
padding-top: 10px;
img{
width: 90px;
height: 90px;
margin-top: 10px;
}
}
.describe{
color: #999;
font-size: 12px;
margin-top: 15px;
}
}
.modal-top-advert{
align-items: start;
padding: 0 30px;
}
</style>

View File

@@ -0,0 +1,226 @@
<template>
<div class="not-enough">
<ul class="nav-bar setup-content">
<li v-for="(item, index) in conData.options.navList" :class="currentIndex===index?'curr':''" @click="changeCurr(index)" :key="index">
<p>{{item.title}}</p>
<p>{{item.desc}}</p>
</li>
<div class="setup-box" style="width:100px;left:1100px;">
<div>
<Button size="small" @click.stop="handleSelectModel">编辑</Button>
</div>
</div>
</ul>
<div class="content" v-if="showContent">
<div v-for="(item, index) in conData.options.list[currentIndex]" :key="index" class="setup-content">
<img :src="item.img" width="210" height="210" :alt="item.name">
<p>{{item.name}}</p>
<p>
<span>{{item.price | unitPrice('¥')}}</span>
<!-- <span>{{item.price | unitPrice('¥')}}</span> -->
</p>
<div class="setup-box">
<div>
<Button size="small" @click.stop="handleSelectGoods(item)">编辑</Button>
</div>
</div>
</div>
</div>
<Modal
v-model="showModal"
title="装修"
draggable
width="800"
:z-index="100"
:mask-closable="false"
>
<div class="modal-tab-bar">
<Button type="primary" size='small' @click="handleAddNav">添加分类</Button>
<table cellspacing="0">
<thead>
<tr>
<th width="250">主标题</th>
<th width="250">描述</th>
<th width="250">操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in conData.options.navList" :key="index">
<td><Input v-model="item.title" /></td>
<td><Input v-model="item.desc" /></td>
<td v-if="index!=0">
<Button type="error" size="small" @click="handleDelNav(index)">删除</Button>
</td>
</tr>
</tbody>
</table>
</div>
</Modal>
<!-- 选择商品链接 -->
<liliDialog
ref="liliDialog"
@selectedGoodsData="selectedGoodsData"
></liliDialog>
</div>
</template>
<script>
export default {
props:{
data:{
type: Object,
default: null
}
},
data() {
return {
currentIndex:0, // 当前商品index
conData:this.data, // 当前数据
selected:{}, // 已选数据
showModal:false, // modal显隐
showContent:true, // 选择后刷新数据用
}
},
watch:{
data:function(val){
this.conData = val
},
conData:function(val){
this.$emit('content',val)
}
},
methods:{
// tab点击切换
changeCurr(index){
this.currentIndex = index;
},
// 编辑
handleSelectModel (item,type) {
this.selected = item;
this.showModal = true
},
handleSelectGoods(item) { // 调起选择商品弹窗
if(item) this.selected = item;
this.$refs.liliDialog.open('goods', 'single')
setTimeout(() => {
this.$refs.liliDialog.goodsData = [this.selected]
}, 500);
},
// 选择商品回调
selectedGoodsData(val){
console.log(val)
let goods = val[0]
this.selected.img = goods.thumbnail
this.selected.price = goods.price
this.selected.name = goods.goodsName
this.selected.url = `/goodsDetail?skuId=${goods.id}&goodsId=${goods.goodsId}`
},
handleDelNav(index){ // 删除导航
this.conData.options.navList.splice(index,1)
this.conData.options.list.splice(index,1)
},
handleAddNav(){ // 添加导航
this.conData.options.navList.push(
{title:'',desc:''}
)
this.conData.options.list.push(
[{ img:'', name:'', price:0, url:'' },
{ img:'', name:'', price:0, url:'' },
{ img:'', name:'', price:0, url:'' },
{ img:'', name:'', price:0, url:'' },
{ img:'', name:'', price:0, url:'' },
{ img:'', name:'', price:0, url:'' },
{ img:'', name:'', price:0, url:'' },
{ img:'', name:'', price:0, url:'' },
{ img:'', name:'', price:0, url:'' },
{ img:'', name:'', price:0, url:'' },
],
)
this.showContent = false
this.$nextTick(()=>{
this.showContent = true;
})
},
}
}
</script>
<style lang="scss" scoped>
@import './setup-box.scss';
.nav-bar{
display: flex;
justify-content: center;
width: 100%;
margin-bottom: 10px;
background-color: rgb(218, 217, 217);
height: 60px;
align-items: center;
position: relative;
li{
padding: 0 30px;
text-align: center;
p:nth-child(1){
font-size: 16px;
border-radius: 50px;
padding: 0 7px;
}
p:nth-child(2){
font-size: 14px;
color: #999;
}
&:hover{
p{
color: $theme_color;
}
cursor: pointer;
}
border-right: 1px solid #eee;
}
li:last-of-type{
border: none;
}
.curr{
p:nth-child(1){
background-color: $theme_color;
color: #fff;
}
p:nth-child(2){
color: $theme_color;
}
}
}
.content{
display: flex;
flex-wrap: wrap;
justify-content: space-between;
>div{
padding: 10px;
box-sizing: border-box;
border: 1px solid #eee;
margin-bottom: 10px;
p:nth-of-type(1){
overflow: hidden;
width: 210px;
white-space: nowrap;
text-overflow:ellipsis;
margin: 10px 0 5px 0;
}
p:nth-of-type(2){
color: $theme_color;
font-size: 16px;
display: flex;
justify-content: space-between;
align-items: center;
span:nth-child(2){
text-decoration: line-through;
font-size: 12px;
color: #999;
}
}
}
}
</style>

View File

@@ -0,0 +1,418 @@
<template>
<div class="recommend">
<div class="recommend-left">
<div
class="head-recommend setup-content"
:style="{ background: msgLeft.bgColor }"
>
<span>{{ msgLeft.title }}</span>
<span>{{ msgLeft.secondTitle }}&gt;</span>
<div class="setup-box">
<div>
<Button size="small" @click.stop="handleSelectModel(msgLeft, true)"
>编辑</Button
>
</div>
</div>
</div>
<div class="content-left">
<div class="setup-content">
<img :src="msgLeft.list[0].img" width="160" height="160" alt="" />
<div class="margin-left">{{ msgLeft.list[0].name }}</div>
<div class="margin-left">{{ msgLeft.list[0].describe }}</div>
<Button
size="small"
:style="{ background: msgLeft.bgColor }"
class="fz_12 view-btn"
>点击查看</Button
>
<div class="setup-box">
<div>
<Button
size="small"
@click.stop="handleSelectModel(msgLeft.list[0])"
>编辑</Button
>
</div>
</div>
</div>
<div>
<template v-for="(item, index) in msgLeft.list">
<div v-if="index != 0" :key="index" class="setup-content">
<img :src="item.img" width="80" height="80" alt="" />
<div>
<div>{{ item.name }}</div>
<div>{{ item.describe }}</div>
</div>
<div class="setup-box">
<div>
<Button size="small" @click.stop="handleSelectModel(item)"
>编辑</Button
>
</div>
</div>
</div>
</template>
</div>
</div>
</div>
<div class="recommend-right">
<div
class="head-recommend setup-content"
:style="{ background: msgRight.bgColor }"
>
<span>{{ msgRight.title }}</span>
<span>{{ msgRight.secondTitle }}&gt;</span>
<div class="setup-box">
<div>
<Button size="small" @click.stop="handleSelectModel(msgRight, true)"
>编辑</Button
>
</div>
</div>
</div>
<div class="content-right">
<div
v-for="(item, index) in msgRight.list"
:key="index"
class="setup-content"
>
<div
class="right-item"
:style="{ border: index === 2 || index === 3 ? 'none' : '' }"
>
<div>
<span :style="{ background: msgRight.bgColor }">{{
item.name
}}</span>
<span>{{ item.describe }}</span>
</div>
<div class="right-img">
<img :src="item.img" alt="" />
</div>
</div>
<div class="setup-box">
<div>
<Button size="small" @click.stop="handleSelectModel(item)"
>编辑</Button
>
</div>
</div>
</div>
</div>
</div>
<Modal
v-model="showModal"
title="装修"
draggable
width="800"
:z-index="100"
:mask-closable="false"
>
<div class="modal-top-advert">
<div>
<img
class="show-image"
width="160"
height="160"
v-if="selected.size && selected.size.indexOf('160*160') >= 0"
:src="selected.img"
alt
/>
<img
class="show-image"
width="80"
height="80"
v-if="selected.size && selected.size.indexOf('80*80') >= 0"
:src="selected.img"
alt
/>
<img
class="show-image"
width="100"
height="100"
v-if="selected.size && selected.size.indexOf('100*100') >= 0"
:src="selected.img"
alt
/>
</div>
<div><span>图片主标题</span><Input v-model="selected.name" /></div>
<div><span>图片描述</span><Input v-model="selected.describe" /></div>
<div class="tips">
建议尺寸<span>{{ selected.size }}</span>
</div>
<div>
图片链接<span>{{ selected.url }}</span>
<Button
size="small"
class="ml_10"
type="primary"
@click="handleSelectLink"
>选择链接</Button
>
</div>
<div>
<Button size="small" type="primary" @click="handleSelectImg"
>选择图片</Button
>&nbsp;
<Button size="small" type="primary" @click="handleSelectGoods"
>选择商品</Button
>
</div>
</div>
</Modal>
<Modal
v-model="showModal1"
title="装修"
draggable
width="800"
:z-index="100"
:mask-closable="false"
>
<div class="modal-top-advert">
<div><span>主标题</span><Input v-model="selected.title" /></div>
<div><span>副标题</span><Input v-model="selected.secondTitle" /></div>
<div>
<span>副标题链接{{ selected.url }}</span
><Button
size="small"
class="ml_10"
type="primary"
@click="handleSelectLink"
>选择链接</Button
>
</div>
<div>
<span>背景色</span><Input v-model="selected.bgColor" />
<ColorPicker v-if="selected.bgColor" v-model="selected.bgColor" />
</div>
</div>
</Modal>
<!-- 选择商品链接 -->
<liliDialog
ref="liliDialog"
@selectedLink="selectedLink"
@selectedGoodsData="selectedGoodsData"
></liliDialog>
<!-- 选择图片 -->
<Modal width="1200px" v-model="picModelFlag" footer-hide>
<ossManage @callback="callbackSelected" :isComponent="true" ref="ossManage" />
</Modal>
</div>
</template>
<script>
import ossManage from "@/views/sys/oss-manage/ossManage";
export default {
props: {
data: {
type: Object,
default: {},
},
},
components: {
ossManage,
},
data() {
return {
msgLeft: this.data.options.contentLeft, // 左侧数据
msgRight: this.data.options.contentRight, // 右侧数据
showModal: false, // modal显隐
showModal1: false, // modal显隐
selected: {}, // 已选数据
picModelFlag: false, // 图片选择
};
},
methods: {
// 编辑
handleSelectModel(item, type) {
this.selected = item;
if (type) {
this.showModal1 = true;
} else {
this.showModal = true;
}
},
handleSelectLink(item, index) {
// 调起选择链接弹窗
this.$refs.liliDialog.open("link");
},
handleSelectGoods(item) {
// 调起选择商品
this.$refs.liliDialog.open('goods', 'single')
},
// 选择链接回调
selectedLink(val) {
this.selected.url = this.$options.filters.formatLinkType(val);
},
// 选择商品回调
selectedGoodsData(val) {
console.log(val);
let goods = val[0];
this.selected.img = goods.thumbnail;
this.selected.price = goods.price;
this.selected.name = goods.goodsName;
this.selected.url = `/goodsDetail?skuId=${goods.id}&goodsId=${goods.goodsId}`;
},
handleSelectImg() {
// 选择图片
this.$refs.ossManage.selectImage = true;
this.picModelFlag = true;
},
// 选择图片回调
callbackSelected(val) {
this.picModelFlag = false;
this.selected.img = val.url;
},
},
};
</script>
<style lang="scss" scoped>
@import "./setup-box.scss";
.recommend {
display: flex;
justify-content: space-between;
.recommend-left {
width: 595px;
.content-left {
display: flex;
padding-top: 10px;
font-size: 12px;
> div:nth-child(1) {
width: 189px;
border-right: 1px solid #eee;
height: 360px;
img {
margin: 40px 0 0 15px;
}
.margin-left {
margin-left: 15px;
width: 145px;
}
div:nth-of-type(1) {
font-weight: bold;
border-top: 1px solid #eee;
padding-top: 10px;
padding-bottom: 10px;
}
div:nth-of-type(2) {
color: #999;
}
.view-btn {
margin-left: 15px;
margin-top: 10px;
color: #fff;
}
}
> div:nth-child(2) {
width: 405px;
display: flex;
flex-wrap: wrap;
> div {
display: flex;
align-items: center;
width: 200px;
height: 120px;
img {
margin: 0 10px;
}
> div:nth-child(2) {
// margin: 0 10px;
:nth-child(2) {
color: #449dae;
}
}
}
}
}
}
.recommend-right {
width: 595px;
height: 360px;
.head-recommend {
background: #a25684;
}
.content-right {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
padding-top: 10px;
> div {
width: 50%;
text-align: center;
height: 180px;
padding-top: 10px;
.right-item {
border-bottom: 1px solid #eee;
display: flex;
margin-top: 30px;
margin-left: 5px;
margin-right: 5px;
height: 150px;
padding: 0 10px;
font-size: 12px;
> div:nth-child(1) {
width: 130px;
margin-top: 30px;
span:nth-child(1) {
color: #fff;
border-radius: 10px;
padding: 0 5px;
background-color: #a25684;
display: block;
width: 120px;
overflow: hidden;
white-space: nowrap;
margin: 0 10px 10px 0;
}
span:nth-child(2) {
font-size: 12px;
color: #666;
display: block;
}
}
.right-img {
width: 100;
height: 100px;
text-align: center;
margin: 0 auto;
img {
max-height: 100px;
max-width: 100px;
}
}
}
}
> div:nth-child(n + 1) {
border-right: 1px solid #eee;
}
}
}
.head-recommend {
display: flex;
align-items: center;
justify-content: space-between;
height: 50px;
padding: 0 10px;
background: #449dae;
color: #fff;
span:nth-child(1) {
font-size: 20px;
}
span:nth-child(2) {
font-size: 12px;
}
}
}
.modal-top-advert {
align-items: start;
padding: 0 30px;
}
</style>

View File

@@ -0,0 +1,291 @@
<template>
<div class="seckill">
<div class="desc">秒杀商品需要在促销活动中添加商品有商品时才会在首页展示</div>
<div class="aside">
<div class="title">{{ actName }}</div>
<div class="hour">
<span>{{ currHour }}:00</span>点场 倒计时
</div>
<div class="count-down" v-if="actStatus === 1">
<span>{{ hours }}</span
><span>{{ minutes }}</span
><span>{{ seconds }}</span>
</div>
<div class="act-status" v-else>
{{ actStatus == 0 ? "未开始" : "已结束" }}
</div>
</div>
<div class="section">
<swiper ref="mySwiper" :options="swiperOptions">
<swiper-slide
v-for="(item, index) in options.list[0].goodsList"
:key="index"
>
<div class="content">
<img :src="item.img" width="140" height="140" :alt="item.name" />
<div class="ellipsis">{{ item.name }}</div>
<div>
<span>{{ item.price | unitPrice("¥") }}</span>
<span>{{ item.originalPrice | unitPrice("¥") }}</span>
</div>
</div>
</swiper-slide>
</swiper>
</div>
</div>
</template>
<script>
import { Swiper, SwiperSlide, directive } from "vue-awesome-swiper";
import "swiper/swiper-bundle.css";
export default {
components: {
Swiper,
SwiperSlide,
},
directives: {
swiper: directive,
},
props: {
data: {
type: Object,
default: null,
},
},
data() {
return {
options: this.data.options, // 当前数据
actStatus: 0, // 0 未开始 1 进行中 2 已结束
actName: "限时秒杀",
currHour: "00", // 当前秒杀场
diffSeconds: 0, // 倒地时
hours: "00", // 小时
minutes: "00", // 分钟
seconds: "00", // 秒
interval: undefined, // 定时器
swiperOptions: {
// 轮播图参数
slidesPerView: 5,
autoplay: true,
loop: true,
},
};
},
watch: {
diffSeconds(val) {
const hours = Math.floor(val / 3600);
// 当前秒数 / 60向下取整
// 获取到所有分钟数 3600 / 60 = 60分钟
// 对60取模超过小时数的分钟数
const minutes = Math.floor(val / 60) % 60;
// 当前的秒数 % 60获取到 超过小时数、分钟数的秒数(秒数)
const seconds = val % 60;
this.hours = hours < 10 ? "0" + hours : hours;
this.minutes = minutes < 10 ? "0" + minutes : minutes;
this.seconds = seconds < 10 ? "0" + seconds : seconds;
if (val === 0) {
clearInterval(this.interval);
this.hours = 0;
this.minutes = 0;
this.seconds = 0;
this.countDown(this.options.list);
}
},
},
mounted() {
this.countDown(this.options.list);
},
beforeDestroy() {
clearInterval(this.interval);
},
methods: {
// 倒计时
countDown(list) {
/**
* 默认倒计时两小时
* 如果没有开始,则显示未开始
* 进行中显示倒计时
* 今天的秒杀结束则显示已结束
*/
let nowHour = new Date().getHours();
if (nowHour < Number(list[0].time)) {
// 活动未开始
this.currHour = list[0].time;
this.actStatus = 0;
} else if (nowHour >= Number(list[list.length - 1].time + 2)) {
// 活动已结束
this.actStatus = 2;
this.currHour = list[list.length - 1].time;
} else {
// 活动进行中
this.actStatus = 1;
for (let i = 0; i < list.length; i++) {
if (nowHour == Number(list[i].time)) {
this.currHour = list[i].time;
}
if (
nowHour > Number(list[i].time) &&
nowHour < Number(list[i].time + 2)
) {
this.currHour = list[i].time;
}
}
// 当前0点时间戳
let zeroTime = new Date(new Date().toLocaleDateString()).getTime();
// 活动倒计时
this.diffSeconds = Math.floor(
(zeroTime +
3600 * 1000 * (this.currHour + 2) -
new Date().getTime()) /
1000
);
const that = this;
this.interval = setInterval(() => {
this.diffSeconds--;
}, 1000);
}
},
},
};
</script>
<style lang="scss" scoped>
.seckill {
width: 100%;
height: 260px;
display: flex;
position: relative;
.desc{
position: absolute;
color: $theme_color;
left: 200px;
top: 5px;
}
.aside {
overflow: hidden;
width: 190px;
height: 100%;
color: #fff;
background-image: url("../../../assets/seckillBg.png");
.title {
width: 100%;
text-align: center;
font-size: 28px;
margin-top: 31px;
}
.hour {
margin-top: 90px;
text-align: center;
span {
font-size: 18px;
}
}
.count-down {
margin: 10px 0 0 30px;
> span {
position: relative;
float: left;
width: 30px;
height: 30px;
text-align: center;
background-color: #2f3430;
margin-right: 20px;
color: white;
font-size: 20px;
&::after {
content: ":";
display: block;
position: absolute;
right: -20px;
font-weight: bolder;
font-size: 18px;
width: 20px;
height: 100%;
top: 0;
}
}
> span:last-child::after {
content: "";
}
}
.act-status {
margin: 10px 0 0 65px;
font-size: 20px;
}
}
.section {
width: 1000px;
// background: #efefef;
.swiper-slide {
height: 260px;
.content {
width: 200px;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
position: relative;
&::after {
content: "";
display: block;
position: absolute;
top: 50%;
right: 0;
width: 1px;
height: 200px;
transform: translateY(-50%);
background: linear-gradient(180deg, white, #eeeeee, white);
}
img {
margin-top: 30px;
}
> div {
width: 160px;
margin-top: 10px;
font-size: 12px;
position: relative;
}
> div:nth-of-type(1):hover {
color: $theme_color;
cursor: pointer;
}
> div:nth-of-type(2) {
border: 1px solid $theme_color;
line-height: 24px;
display: flex;
text-align: center;
span:nth-child(1) {
color: #fff;
font-size: 16px;
width: 92px;
background-color: $theme_color;
position: relative;
&::before {
content: " ";
width: 0;
height: 0;
border-color: transparent white transparent transparent;
border-style: solid;
border-width: 24px 8px 0 0;
position: absolute;
top: 0;
left: 84px;
}
}
span:nth-child(2) {
color: #999;
width: 66px;
text-decoration: line-through;
}
}
}
}
}
}
</style>

View File

@@ -0,0 +1,62 @@
.setup-content{
position: relative;
&:hover{
.setup-box{
display: block;
}
}
}
.setup-box{
display: none;
position: absolute;
top: 0;
left: 0;
background: rgba(0, 0, 0, .2);
z-index: 99;
width: 100%;
height: 100%;
.ivu-btn{
float: right;
margin-right: 5px;
margin-top: 5px;
}
}
.modal-tab-bar{
margin-left: 20px;
table{
margin-top: 10px;
display:inline-block;
border: 1px solid #ddd;
border-radius: 5px;
max-height: 400px !important;
overflow: hidden auto;
}
thead{
background-color: #eee;
th{
padding: 5px 0;
}
}
td{
padding: 10px;
text-align: center;
}
tbody>tr:hover{
background-color: aliceblue;
}
}
.modal-top-advert{
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
>*{
margin-bottom: 10px;
}
.ivu-input-wrapper{
width: 200px;
}
}

View File

@@ -0,0 +1,20 @@
### 楼层装修页面
#### floorList.vue 楼层列表
#### renovation.vue 楼层装修主页面
#### singleConfig.vue 右侧配置项
#### modelForm.vue 中间展示所选模块
#### modelFormItem.vue 单个模块样式
#### modelConfig.js 模块数据
#### modelList文件夹为添加的模块
### wap文件夹为移动端楼层装修
### draggable中文文档 (http://www.itxst.com/vue-draggable/tutorial.html)

View File

@@ -0,0 +1,175 @@
<template>
<div class="renovation">
<!-- 左侧模块列表 -->
<div class="model-list">
<div class="classification-title">基础模块</div>
<draggable tag="ul" :list="modelData" v-bind="{group:{ name:'model', pull:'clone',put:false},sort:false, ghostClass: 'ghost'}" >
<li v-for="(model, index) in modelData" :key="index" class="model-item">
<Icon :type="model.icon" />
<span>{{model.name}}</span>
</li>
</draggable>
</div>
<!-- 中间展示模块 -->
<div class="show-content">
<model-form ref="modelForm" :data="modelForm"></model-form>
</div>
<!-- 操作按钮 -->
<div class="btn-bar">
<Button type="primary" :loading="submitLoading" @click="saveTemplate">保存模板</Button>
<Button class="ml_10" @click="resetTemplate">还原模板</Button>
</div>
</div>
</template>
<script>
import { modelData } from "./modelConfig";
import Draggable from "vuedraggable";
import ModelForm from "./modelForm.vue";
import * as API_floor from "@/api/other.js";
export default {
components: {
Draggable,
ModelForm,
},
mounted() {
this.getTemplateItem(this.$route.query.id);
},
data() {
return {
modelData, // 可选模块数据
modelForm: { list: [] }, // 模板数据
submitLoading: false, // 提交加载状态
};
},
methods: {
saveTemplate() {
// 保存模板
this.submitTemplate(this.$route.query.pageShow ? 'OPEN' : 'CLOSE')
},
// 提交模板
submitTemplate(pageShow) {
this.submitLoading = true
const modelForm = JSON.parse(JSON.stringify(this.modelForm))
modelForm.list.unshift(this.$refs.modelForm.navList);
modelForm.list.unshift(this.$refs.modelForm.topAdvert);
const data = {
id: this.$route.query.id,
pageData: JSON.stringify(modelForm),
pageShow
};
API_floor.updateHome(this.$route.query.id, data).then((res) => {
this.submitLoading = false
if (res.success) {
this.$Message.success("保存模板成功");
}
});
},
resetTemplate() {
// 还原模板
this.getTemplateItem(this.$route.query.id);
},
getTemplateItem(id) {
// 获取模板数据
API_floor.getHomeData(id).then((res) => {
if (res.success) {
let pageData = res.result.pageData;
if (pageData) {
pageData = JSON.parse(pageData);
if (pageData.list[0].type === "topAdvert") {
// topAdvert 为顶部广告 navList为导航栏
this.$refs.modelForm.topAdvert = pageData.list[0];
this.$refs.modelForm.navList = pageData.list[1];
pageData.list.splice(0, 2);
this.modelForm = pageData;
} else {
this.modelForm = { list: [] };
}
} else {
this.modelForm = { list: [] };
}
}
});
},
},
watch: {
modelForm: {
deep: true,
handler: function (val) {
console.log(val);
},
},
},
};
</script>
<style lang="scss" scoped>
.renovation {
position: relative;
display: flex;
}
.model-list {
width: 120px;
height: auto;
padding: 10px;
background: #fff;
margin-top: 60px;
position: fixed;
z-index: 100;
box-shadow: 1px 1px 10px #999;
.classification-title {
width: 100%;
height: 30px;
line-height: 30px;
}
.model-item {
width: 100px;
height: 30px;
background: #eee;
margin-top: 10px;
line-height: 30px;
text-align: center;
color: #999;
&:hover {
border: 1px dashed #409eff;
color: #409eff;
cursor: move;
}
}
.ghost::after {
border: none;
height: 0;
content: "";
}
}
.show-content {
margin-left: 150px;
margin-top: 60px;
}
.ghost {
background: #fff;
height: 30px;
position: relative;
&::after {
content: "松开鼠标添加模块";
position: absolute;
background: #fff;
border: 1px dashed #409eff;
color: #409eff;
top: 0;
left: 0;
width: 100%;
height: 50px;
text-align: center;
line-height: 50px;
}
}
.btn-bar {
position: fixed;
width: 100%;
background: #fff;
height: 50px;
padding: 10px;
box-shadow: 1px 1px 10px #999;
z-index: 99;
top: 100px;
}
</style>

View File

@@ -9,154 +9,341 @@
ref="table"
></Table>
</Card>
<Modal v-model="openModal" :title="openModalTitle" @on-ok="submit">
<h3 style="color: #ff3c2a; margin-bottom: 10px">是否需要电子面单</h3>
<RadioGroup
v-model="faceSheetForm.faceSheetFlag"
style="margin-bottom: 20px"
@on-change="getfaceSheetFlag($event)"
>
<Radio :label="true">
<span>需要</span>
</Radio>
<Radio :label="false">
<span>不需要</span>
</Radio>
</RadioGroup>
<Card v-if="onpenText" class="modalStyle">
<h3 style="color: #ff3c2a; margin-bottom: 10px">请输入详细信息</h3>
<Form ref="formValidate" :label-width="150" label-position="right" :model="faceSheetForm" :rules="ruleValidate">
<FormItem label="customerName" prop="customerName">
<Input
v-model="faceSheetForm.customerName"
type="text"
class="faceSheetInput"
></Input
></FormItem>
<FormItem label="customerPwd" prop="customerPwd">
<Input
v-model="faceSheetForm.customerPwd"
type="text"
class="faceSheetInput"
></Input>
</FormItem>
<FormItem label="customerPwd" prop="monthCode">
<Input
v-model="faceSheetForm.monthCode"
type="text"
class="faceSheetInput"
></Input
></FormItem>
<FormItem label="customerPwd" prop="sendSite">
<Input
v-model="faceSheetForm.sendSite"
type="text"
class="faceSheetInput"
></Input
></FormItem>
<FormItem label="customerPwd" prop="sendStaff">
<Input
v-model="faceSheetForm.sendStaff"
type="text"
class="faceSheetInput"
></Input
></FormItem>
<FormItem label="支付方式" prop="payType">
<Select
v-model="faceSheetForm.payType"
class="faceSheetInput">
<Option value="1">现付</Option>
<Option value="2">到付</Option>
<Option value="3">月结</Option>
<Option value="4">第三方支付(仅SF支持)</Option>
</Select
></FormItem>
<FormItem label="快递类型" prop="expType">
<Input
v-model="faceSheetForm.expType"
type="text"
class="faceSheetInput"/>
</FormItem>
<div style="width:100%;text-align:center;">
<a style="padding-right: 20px" @click="frontDownload('use')">使用说明</a>
<a @click="frontDownload('type')">快递类型</a>
</div>
</Form>
</Card>
<br/>
</Modal>
</div>
</template>
<script>
import * as API_Shop from "@/api/shops";
import * as API_Shop from "@/api/shops";
export default {
name: "logistics",
data() {
return {
loading: true, // 表单加载状态
searchForm: {
// 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小
sort: "createTime", // 默认排序字段
order: "desc", // 默认排序方式
export default {
name: "logistics",
data() {
return {
row: {},
openModal: false,
loading: true, // 表单加载状态
searchForm: {
// 搜索框初始化对象
pageNumber: 1, // 当前页数
pageSize: 10, // 页面大小
sort: "createTime", // 默认排序字段
order: "desc", // 默认排序方式
},
openModalTitle: '开启信息',
ruleValidate: {
customerName: [{ required: true, message: "请填写必填项" ,trigger: "blur" }],
payType: [{ required: true, message: "请填写必填项" ,trigger: "change" }],
expType: [{ required: true, message: "请填写必填项" ,trigger: "blur" }],
customerPwd: [{ required: true, message: "请填写必填项" ,trigger: "blur" }],
monthCode: [{ required: true, message: "请填写必填项" ,trigger: "blur" }],
sendSite: [{ required: true, message: "请填写必填项" ,trigger: "blur" }],
sendStaff: [{ required: true, message: "请填写必填项" ,trigger: "blur" }],
},
faceSheetForm: {
faceSheetFlag: false,
customerName: "",
payType: '1',
expType: '1',
customerPwd: "",
monthCode: "",
sendSite: "",
sendStaff: "",
},
columns: [
{
title: "物流公司",
key: "name",
minWidth: 120,
sortable: false,
},
columns: [
{
title: "物流公司",
key: "name",
minWidth: 120,
sortable: false,
},
{
title: "状态",
key: "selected",
minWidth: 120,
sortable: true,
render: (h, params) => {
if(params.row.selected === null || params.row.selected === ""){
return h("div", [h("tag", {props: {color: "volcano"}}, "关闭")]);
}else{
return h("div", [h("tag", {props: {color: "green"}}, "开启")]);
}
{
title: "状态",
key: "selected",
minWidth: 120,
sortable: true,
render: (h, params) => {
if (params.row.selected === null || params.row.selected === "") {
return h("div", [h("tag", {props: {color: "volcano"}}, "关闭")]);
} else {
return h("div", [h("tag", {props: {color: "green"}}, "开启")]);
}
},
{
title: "操作",
key: "action",
align: "center",
width: 200,
render: (h, params) => {
if(params.row.selected === null){
return h("div", [
h(
"Button",
{
props: {
type: "success",
size: "small",
},
style: {
marginRight: "5px",
},
on: {
click: () => {
this.open(params.row);
},
}
},
{
title: "操作",
key: "action",
align: "center",
width: 200,
render: (h, params) => {
if (params.row.selected === null) {
return h("div", [
h(
"Button",
{
props: {
type: "success",
size: "small",
},
style: {
marginRight: "5px",
},
on: {
click: () => {
this.open(params.row);
},
},
"开启"
),
]);
}else{
return h("div", [
h(
"Button",
{
props: {
type: "error",
size: "small",
},
style: {
marginRight: "5px",
},
on: {
click: () => {
this.close(params.row);
},
},
"开启"
),
]);
} else {
return h("div", [
h(
"Button",
{
props: {
type: "error",
size: "small",
},
style: {
marginRight: "5px",
},
on: {
click: () => {
this.close(params.row);
},
},
"关闭"
),
]);
}
},
"关闭"
),
h(
"Button",
{
props: {
type: "info",
size: "small",
},
on: {
click: () => {
this.getFaceSheetInfo(params.row);
},
},
},
"修改"
),
]);
}
},
},
],
data: [], // 表单数据
};
},
],
data: [], // 表单数据
onpenText: false,
};
},
methods: {
//获取状态
getfaceSheetFlag(e) {
console.log(e);
if (e === true) {
console.log("打开");
this.onpenText = true;
} else {
console.log("关闭");
this.onpenText = false;
}
},
methods: {
// 初始化数据
init() {
this.getDataList();
},
// 获取数据
getDataList() {
this.loading = true;
API_Shop.getLogistics().then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result;
}
});
// 初始化数据
init() {
this.getDataList();
},
// 获取数据
getDataList() {
this.loading = true;
API_Shop.getLogistics().then((res) => {
this.loading = false;
},
// 开启
open(v) {
this.$Modal.confirm({
title: "确认开启",
// 记得确认修改此处
content: "您确认开启此物流公司?",
loading: true,
onOk: () => {
API_Shop.logisticsChecked(v.id).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("物流公司开启成功");
this.init();
}
});
if (res.success) {
this.data = res.result;
}
});
this.loading = false;
},
// 开启
open(v) {
this.row = v;
this.openModal = true;
this.searchForm.faceSheetFlag = "false"; //开弹框 等于v
if (this.searchForm.faceSheetFlag == "true") {
this.onpenText = true;
} else {
this.onpenText = false;
}
},
//修改
getFaceSheetInfo(v) {
this.row = v;
this.logisticsId = v.logisticsId;
this.openModalTitle = '修改信息';
API_Shop.getIsCheck(this.logisticsId).then((res) => {
if (res.success) {
// this.searchForm = res.result.recordes;
this.faceSheetForm.faceSheetFlag = res.result.faceSheetFlag; //开弹框 等于v
if (this.faceSheetForm.faceSheetFlag === true) {
this.onpenText = true;
} else {
this.faceSheetForm.faceSheetFlag = false
this.onpenText = false;
}
this.faceSheetForm.customerName = res.result.customerName;
this.faceSheetForm.customerPwd = res.result.customerPwd;
this.faceSheetForm.monthCode = res.result.monthCode;
this.faceSheetForm.sendSite = res.result.sendSite;
this.faceSheetForm.sendStaff = res.result.sendStaff;
}
});
this.openModal = true;
},
frontDownload(val) {
var a = document.createElement("a"); //创建一个<a></a>标签
//根据点击按钮来下载不同文件
if (val === 'use') {
a.href = "static/open.xlsx"; // 给a标签的href属性值加上地址注意这里是绝对路径不用加 点.
a.download = "使用说明.xlsx"; //设置下载文件文件名,这里加上.xlsx指定文件类型pdf文件就指定.fpd即可
} else if (val === 'type') {
a.href = "static/logisticsType.xlsx"; // 给a标签的href属性值加上地址注意这里是绝对路径不用加 点.
a.download = "快递类型.xlsx"; //设置下载文件文件名,这里加上.xlsx指定文件类型pdf文件就指定.fpd即可
}
a.style.display = "none"; // 障眼法藏起来a标签
document.body.appendChild(a); // 将a标签追加到文档对象中
a.click(); // 模拟点击了a标签会触发a标签的href的读取浏览器就会自动下载了
a.remove(); // 一次性的用完就删除a标签
},
submit() {
if ( this.row.selected === null || this.row.selected === "") {
API_Shop.logisticsChecked(
this.row.logisticsId,
this.faceSheetForm
).then((res) => {
this.openModal = false;
this.$Modal.remove();
if (res.success) {
this.$Message.success("物流公司开启成功");
this.init();
}
});
},
// 关闭
close(v){
this.$Modal.confirm({
title: "确认关闭",
content: "您确认关闭此物流公司?",
loading: true,
onOk: () => {
API_Shop.logisticsUnChecked(v.selected).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("物流公司关闭成功");
this.init();
}
});
} else {
API_Shop.editChecked(this.logisticsId, this.faceSheetForm).then((res) => {
if (res.success) {
this.$Message.success("修改成功");
this.init();
}
});
}
},
mounted() {
this.init();
},
};
// 关闭
close(v) {
this.$Modal.confirm({
title: "确认关闭",
content: "您确认关闭此物流公司?",
loading: true,
onOk: () => {
API_Shop.logisticsUnChecked(v.selected).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("物流公司关闭成功");
this.init();
}
});
}
});
}
},
mounted() {
this.init();
},
};
</script>
<style lang="scss" scoped>
.faceSheetInput{
width: 300px;
}
</style>

View File

@@ -47,6 +47,9 @@
style="width: 30%"
></Input>
</FormItem>
<FormItem label="店铺楼层" prop="content" class="wangEditor">
<i-switch v-model="form.pageShow" @on-change="pageShow"></i-switch>
</FormItem>
<Form-item>
<Button
@click="handleSubmit"
@@ -58,6 +61,77 @@
</Form-item>
</Form>
</TabPane>
<TabPane label="发货地址">
<Form
ref="addressGoods"
:model="addressGoods"
:label-width="100"
:rules="addressGoodsValidate"
>
<FormItem label="发货人姓名" prop="salesConsignorName">
<Input
v-model="addressGoods.salesConsignorName"
maxlength="11"
clearable
style="width: 20%"
>
</Input>
</FormItem>
<FormItem label="发货人手机号" prop="salesConsignorMobile">
<Input
v-model="addressGoods.salesConsignorMobile"
maxlength="11"
clearable
style="width: 20%"
>
</Input>
</FormItem>
<FormItem label="地址" prop="salesConsignorAddressId">
<Input
v-model="regionGoods"
clearable
disabled
style="width: 20%"
v-if="showRegion == false"
>
</Input>
<regionMap
style="width: 20%"
@selected="selectedRegionGoods"
v-if="showRegion == true"
/>
<Button
v-if="showRegion == false"
@click="regionClicks"
type="primary"
style="margin-left: 8px"
>修改
</Button>
</FormItem>
<!-- <FormItem label="地址名称" prop="salesConsignorAddressPath">
<Input
v-model="addressGoods.salesConsignorAddressPath"
clearable
style="width: 20%"
>
</Input>
</FormItem> -->
<FormItem label="详细地址" prop="salesConsignorDetail">
<Input
v-model="addressGoods.salesConsignorDetail"
clearable
style="width: 20%"
>
</Input>
</FormItem>
<Button
@click="SetAddressGoods"
type="primary"
style="margin-left: 8px"
>确认
</Button>
</Form>
</TabPane>
<TabPane label="退货地址" name="REFUND_GOODS_ADDRESS">
<Form
ref="addressForm"
@@ -191,6 +265,7 @@ import liliMap from "@/views/my-components/map/index";
import regionMap from "@/views/lili-components/region";
import * as RegExp from "@/libs/RegExp.js";
import Cookies from "js-cookie";
import {editDeliverAddress, getDeliverAddress} from "../../api/shops";
export default {
name: "shopSetting",
@@ -257,6 +332,7 @@ export default {
storeAddressDetail: "", //详细地址
storeAddressIdPath: "", //地址
storeDesc: "", // 店铺描述
pageShow:false,
},
// 表单验证规则
@@ -302,12 +378,64 @@ export default {
],
},
submitLoading: false, // 添加或编辑提交状态
//发货地址
addressGoods: {
salesConsignorName:" ",
salesConsignorMobile:" ",
salesConsignorAddressId: " ",
salesConsignorAddressPath: " ",
salesConsignorDetail: " ",
},
regionGoods:"",//发货地址
addressGoodsValidate: {
salesConsignorName: [
{ required: true, message: "请输入发货人姓名", trigger: "blur" },
],
salesConsignorMobile: [
{ required: true, message: "手机号不能为空", trigger: "blur" },
{
pattern: RegExp.mobile,
trigger: "blur",
message: "请输入正确的手机号",
},
],
salesConsignorDetail: [
{ required: true, message: "请输入详细地址", trigger: "blur" },
],
},
};
},
methods: {
// 初始化数据
init() {
this.getShopInfo();
this.getDeliverAddress()
},
selectedRegionGoods(val){
this.regionGoods = val[1];
this.regionIdS = val[0];
},
regionClicks(){
this.showRegion = true;
this.regionIdS = "";
},
SetAddressGoods(){
console.log(this.$refs.addressGoods)
if (this.regionIdS == "") {
this.$Message.error("请选择地址");
return;
}
this.$refs.addressGoods.validate((valid) => {
if (valid) {
this.addressGoods.salesConsignorAddressPath = this.regionGoods;
this.addressGoods.salesConsignorAddressId = this.regionIdS;
API_Shop.editDeliverAddress(this.addressGoods).then(res=>{
if(res.success){
this.$Message.success("修改成功")
}
})
}
});
},
//获取店铺信息
getShopInfo() {
@@ -331,6 +459,21 @@ export default {
}
});
},
pageShow(type) {
this.form.pageShow = type
},
getDeliverAddress(){
API_Shop.getDeliverAddress().then(res=>{
if(res.success){
if(res.result!= '' && res.result != null){
console.log(89898999998)
this.addressGoods = res.result;
this.regionGoods = res.result.salesConsignorAddressPath;
this.regionIdS = res.result.salesConsignorAddressId;
}
}
})
},
//修改售后地址
regionClick() {
this.showRegion = true;

View File

@@ -0,0 +1,782 @@
<template>
<div class="search">
<Card>
<Form ref="searchForm" :model="searchForm" inline :label-width="70" class="search-form">
<Form-item label="店员名称">
<Input
type="text"
v-model="searchForm.clerkName"
placeholder="请输入店员名称"
clearable
style="width: 200px"
/>
</Form-item>
<Form-item label="联系方式">
<Input
type="text"
v-model="searchForm.mobile"
placeholder="请输入联系方式"
clearable
style="width: 200px"
/>
</Form-item>
<Form-item label="部门">
<department-choose @on-change="handleSelectDep" style="width: 150px;" ref="dep"></department-choose>
</Form-item>
<Button @click="handleSearch" type="primary" icon="ios-search" class="search-btn">搜索</Button>
</Form>
<Row class="operation padding-row">
<Button @click="add" type="primary">添加</Button>
<Button @click="delAll">批量删除</Button>
<Button @click="resetPass">重置密码</Button>
</Row>
<br>
<Table
:loading="loading"
border
:columns="columns"
:data="data"
sortable="custom"
@on-sort-change="changeSort"
@on-selection-change="showSelect"
ref="table"
></Table>
<Row type="flex" justify="end" class="mt_10">
<Page
:current="searchForm.pageNumber"
:total="total"
:page-size="searchForm.pageSize"
@on-change="changePage"
@on-page-size-change="changePageSize"
:page-size-opts="[10,20,50]"
size="small"
show-total
show-elevator
show-sizer
></Page>
</Row>
</Card>
<Modal
:title="modalTitle"
v-model="userEditModalVisible"
:mask-closable="false"
:width="500"
:styles="{top: '30px'}"
>
<Form ref="form" :model="editForm" :label-width="80" :rules="formValidate">
<FormItem label="手机号">
<Input v-model="mobile" disabled/>
</FormItem>
<FormItem label="店员名称">
<Input v-model="clerkName" disabled/>
</FormItem>
<FormItem label="超级管理员" prop="isSuper">
<RadioGroup type="button" button-style="solid" v-model="editForm.isSuper">
<Radio :label="1">
<span></span>
</Radio>
<Radio :label="0">
<span></span>
</Radio>
</RadioGroup>
</FormItem>
<FormItem label="角色" prop="roles" v-if="editForm.isSuper == 0">
<Select v-model="editForm.roles" multiple>
<Option v-for="item in roleList" :value="item.id" :key="item.id" :label="item.name">
</Option>
</Select>
</FormItem>
<Form-item label="所属部门">
<department-tree-choose @on-change="handleEditSelectDepTree" ref="depTree"></department-tree-choose>
</Form-item>
</Form>
<div slot="footer">
<Button type="text" @click="userEditModalVisible = false">取消</Button>
<Button type="primary" :loading="submitLoading" @click="updateSubmit">提交</Button>
</div>
</Modal>
<Modal
:title="modalTitle"
v-model="userModalVisible"
:mask-closable="false"
:width="500"
:styles="{top: '30px'}"
>
<Form ref="form" :model="form" :label-width="80" :rules="formValidate">
<FormItem label="手机号" prop="mobile">
<Input placeholder="请输入要添加的会员手机号码" maxlength="11" style="width: 75%" v-model="form.mobile"
autocomplete="off" @on-change="checkClerks"/>
&nbsp;<Button v-if="!memberCheck" @click="checkClerk">校验</Button>
<Button v-if="memberCheck" @click="checkAgainClerk">重新校验</Button>
</FormItem>
<FormItem v-if="newMember" label="用户名" prop="username">
<Input v-model="form.username" autocomplete="off"/>
</FormItem>
<FormItem v-if="oldMember" label="用户名" prop="username">
<Input v-model="form.username" autocomplete="off" disabled/>
</FormItem>
<FormItem label="密码" prop="password" v-if="newMember" :error="errorPass">
<Input type="password" password v-model="form.password" autocomplete="off"/>
</FormItem>
<FormItem label="超级管理员" prop="isSuper" v-if="newMember || oldMember">
<RadioGroup type="button" button-style="solid" v-model="form.isSuper">
<Radio :label="1">
<span></span>
</Radio>
<Radio :label="0">
<span></span>
</Radio>
</RadioGroup>
</FormItem>
<FormItem label="角色" prop="roles" v-if="(oldMember || newMember) && form.isSuper == 0">
<Select v-model="form.roles" multiple>
<Option v-for="item in roleList" :value="item.id" :key="item.id" :label="item.name">
</Option>
</Select>
</FormItem>
<Form-item label="所属部门" v-if="oldMember || newMember">
<department-tree-choose @on-change="handleSelectDepTree" ref="depTree"></department-tree-choose>
</Form-item>
</Form>
<div slot="footer">
<Button type="text" @click="userModalVisible = false">取消</Button>
<Button type="primary" :loading="submitLoading" @click="submitUser">提交</Button>
</div>
</Modal>
</div>
</template>
<script>
import {
checkClerk,
getUserListData,
getAllRoleList,
addUser,
editOtherUser,
enableClerk,
deleteClerk,
resetPassword,
getClerk
} from "@/api/index";
import {validateMobile} from "@/libs/validate";
import departmentChoose from "@/views/my-components/lili/department-choose";
import departmentTreeChoose from "@/views/my-components/lili/department-tree-choose";
import uploadPicInput from "@/views/my-components/lili/upload-pic-input";
export default {
name: "clerk-manage",
components: {
departmentChoose,
departmentTreeChoose,
uploadPicInput,
},
data() {
return {
open:0,
loading: true, // 加载状态
selectCount: 0, // 已选数量
selectList: [], // 已选数据列表
searchForm: { // 请求参数
clerkName: "",
departmentId: "",
pageNumber: 1,
pageSize: 10,
sort: "createTime",
order: "desc"
},
modalType: 0, // 新增编辑标识
userModalVisible: false, // 用户modal显隐
userEditModalVisible:false,
modalTitle: "", // modal标题
form: { // 表单
username: "",
mobile: 0,
sex: "",
isSuper: 0,
roles: [],
departmentId: "",
departmentTitle: ""
},
editForm: { // 表单
isSuper: 0,
roles: [],
departmentId: "",
departmentTitle: ""
},
mobile: "",
clerkName: "",
newMember: false,
oldMember: false,
memberCheck: false,
roleList: [], // 角色列表
errorPass: "", // 错误提示
formValidate: { // 验证规则
username: [
{required: true, message: "用户名不能为空", trigger: "blur"}
],
password: [
{required: true, message: "密码不能为空", trigger: "blur"}
],
mobile: [
{required: true, message: "手机号不能为空", trigger: "blur"},
{validator: validateMobile, trigger: "blur"}
]
},
submitLoading: false, // 提交状态
columns: [ // 表头
{
type: "selection",
width: 60,
align: "center",
fixed: "left"
},
{
title: "店员名称",
key: "clerkName",
minWidth: 100,
sortable: true,
fixed: "left"
},
{
title: "手机号码",
key: "mobile",
minWidth: 100,
fixed: "left"
},
{
title: "店主",
key: "status",
align: "center",
width: 130,
render: (h, params) => {
if (params.row.shopkeeper == true) {
return h("div", [
h("Badge", {
props: {
status: "success",
text: "是"
}
})
]);
} else if (params.row.shopkeeper == false) {
return h("div", [
h("Badge", {
props: {
status: "error",
text: "否"
}
})
]);
}
},
},
{
title: "超级管理员",
key: "status",
align: "center",
width: 130,
render: (h, params) => {
if (params.row.isSuper == true) {
return h("div", [
h("Badge", {
props: {
status: "success",
text: "是"
}
})
]);
} else if (params.row.isSuper == false) {
return h("div", [
h("Badge", {
props: {
status: "error",
text: "否"
}
})
]);
}
},
},
{
title: "状态",
key: "status",
align: "center",
width: 130,
render: (h, params) => {
if (params.row.status == true) {
return h("div", [
h("Badge", {
props: {
status: "success",
text: "启用"
}
})
]);
} else if (params.row.status == false) {
return h("div", [
h("Badge", {
props: {
status: "error",
text: "禁用"
}
})
]);
}
},
filters: [
{
label: "启用",
value: true
},
{
label: "禁用",
value: false
}
],
filterMultiple: false,
filterMethod(value, row) {
return row.status == value;
}
},
{
title: "创建时间",
key: "createTime",
sortable: true,
sortType: "desc",
width: 180
},
{
title: "操作",
key: "action",
width: 200,
align: "center",
fixed: "right",
render: (h, params) => {
let enableOrDisable = "";
if (params.row.status == true) {
enableOrDisable = h(
"Button",
{
props: {
size: "small"
},
style: {
marginRight: "5px"
},
on: {
click: () => {
this.disable(params.row);
}
}
},
"禁用"
);
} else {
enableOrDisable = h(
"Button",
{
props: {
type: "success",
size: "small"
},
style: {
marginRight: "5px"
},
on: {
click: () => {
this.enable(params.row);
}
}
},
"启用"
);
}
return h("div", [
h(
"Button",
{
props: {
type: "info",
size: "small"
},
style: {
marginRight: "5px"
},
on: {
click: () => {
this.edit(params.row);
}
}
},
"编辑"
),
enableOrDisable,
h(
"Button",
{
props: {
type: "error",
size: "small"
},
on: {
click: () => {
this.remove(params.row);
}
}
},
"删除"
)
]);
}
}
],
data: [], // 用户数据
total: 0, // 总数
};
},
methods: {
// 初始化数据
init() {
this.getUserList();
},
checkClerks() {
this.open = this.form.mobile.length;
console.log(this.open)
if(this.open == 11 ){
this.checkClerk();
}
if(this.open < 11){
this.checkAgainClerk()
}
},
// 选择部门回调
handleSelectDepTree(v) {
if (v) {
this.form.departmentId = v.departmentId;
this.form.departmentTitle = v.departmentTitle;
} else {
this.form.departmentId = "";
this.form.departmentTitle = "";
}
},
// 选择部门回调
handleEditSelectDepTree(v) {
if (v) {
this.editForm.departmentId = v.departmentId;
this.editForm.departmentTitle = v.departmentTitle;
} else {
this.editForm.departmentId = "";
this.editForm.departmentTitle = "";
}
},
//重新校验会员
checkAgainClerk() {
this.memberCheck = false
this.newMember = false
this.oldMember = false
},
//检测当前店员
checkClerk() {
if (this.form.mobile) {
this.newMember = false
this.oldMember = false
checkClerk(this.form.mobile).then(res => {
if (!res.result.id) {
this.newMember = true
} else {
this.oldMember = true
this.form.username = res.result.username
this.form.password = res.result.password
}
this.form.isSuper = 1
this.memberCheck = true;
});
}
},
// 搜索项部门选择
handleSelectDep(v) {
this.searchForm.departmentId = v;
},
// 分页 修改页码
changePage(v) {
this.searchForm.pageNumber = v;
this.getUserList();
this.clearSelectAll();
},
// 分页 修改页数
changePageSize(v) {
this.searchForm.pageSize = v;
this.searchForm.pageNumber = 1;
this.getUserList();
},
getUserList() {
// 多条件搜索用户列表
this.loading = true;
getUserListData(this.searchForm).then(res => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
});
},
// 搜索
handleSearch() {
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
this.getUserList();
},
// 排序
changeSort(e) {
this.searchForm.sort = e.key;
this.searchForm.order = e.order;
if (e.order == "normal") {
this.searchForm.order = "";
}
this.getUserList();
},
// 获取角色列表
getRoleList() {
let params = {
pageSize: 100
}
getAllRoleList(params).then(res => {
if (res.success) {
this.roleList = res.result.records;
}
});
},
// 重置密码
resetPass() {
if (this.selectCount == 0) {
this.$Message.warning('请选中数据后重试!');
return
}
this.$Modal.confirm({
title: "确认重置",
content:
"您确认要重置所选的 " +
this.selectCount +
" 条用户数据密码为【123456】?",
loading: true,
onOk: () => {
let ids = "";
this.selectList.forEach(function (e) {
ids += e.id + ",";
});
ids = ids.substring(0, ids.length - 1);
console.warn(ids)
resetPassword(ids).then(res => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("操作成功");
this.clearSelectAll();
this.getUserList();
}
});
}
});
},
updateSubmit(){
this.submitLoading = true;
console.warn(this.editForm)
editOtherUser(this.editForm.id,this.editForm).then(res => {
this.submitLoading = false;
if (res.success) {
this.$Message.success("操作成功");
this.getUserList();
this.userEditModalVisible = false;
}
});
},
// 确认提交
submitUser() {
this.$refs.form.validate(valid => {
if (valid) {
// 添加用户 避免编辑后传入id
const params = JSON.parse(JSON.stringify(this.form))
console.warn(params)
delete params.id;
delete params.status;
if (this.newMember) {
if (params.password == "" || params.password == undefined) {
this.errorPass = "密码不能为空";
return;
}
if (params.password.length < 6) {
this.errorPass = "密码长度不得少于6位";
return;
}
//todo
params.password = this.md5(params.password)
} else {
params.password = this.form.password
}
this.submitLoading = true;
addUser(params).then(res => {
this.submitLoading = false;
if (res.success) {
this.$Message.success("操作成功");
this.getUserList();
this.userModalVisible = false;
}
});
}
});
},
// 添加用户
add() {
// this.checkClerks();
this.modalType = 0;
this.modalTitle = "添加店员";
this.$refs.form.resetFields();
this.form = { // 表单
username: "",
mobile: "",
isSuper: 0,
roles: [],
departmentId: "",
departmentTitle: ""
},
this.oldMember = false
this.newMember = false
this.userModalVisible = true;
},
// 编辑用户
edit(v) {
console.warn(v)
getClerk(v.id).then(res => {
console.warn(res)
this.mobile = res.result.mobile
this.clerkName = res.result.clerkName
this.editForm.isSuper = 0
this.editForm.id = res.result.id
if(res.result.isSuper){
this.editForm.isSuper = 1
}
this.editForm.departmentId = res.result.departmentId
this.$refs.depTree.setData(res.result.departmentId, res.result.departmentTitle);
let selectRolesId = [];
if (res.result.roles) {
res.result.roles.forEach(function (e) {
selectRolesId.push(e.id);
});
}
this.editForm.roles = selectRolesId;
this.modalTitle = "修改店员";
this.userEditModalVisible = true;
})
},
// 启用
enable(v) {
let params = {
status: true
}
this.$Modal.confirm({
title: "确认启用",
content: "您确认要启用用户 " + v.clerkName + " ?",
loading: true,
onOk: () => {
enableClerk(v.id, params).then(res => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("操作成功");
this.getUserList();
}
});
}
});
},
// 禁用
disable(v) {
let params = {
status: false
}
this.$Modal.confirm({
title: "确认禁用",
content: "您确认要禁用用户 " + v.clerkName + " ?",
loading: true,
onOk: () => {
enableClerk(v.id, params).then(res => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("操作成功");
this.getUserList();
}
});
}
});
},
// 删除用户
remove(v) {
this.$Modal.confirm({
title: "确认删除",
content: "您确认要删除用户 " + v.clerkName + " ?",
loading: true,
onOk: () => {
deleteClerk(v.id).then(res => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("删除成功");
this.getUserList();
}
});
}
});
},
// 选中状态
showSelect(e) {
this.selectList = e;
this.selectCount = e.length;
},
// 清除选中状态
clearSelectAll() {
this.$refs.table.selectAll(false);
},
// 批量删除
delAll() {
if (this.selectCount <= 0) {
this.$Message.warning("您还未选择要删除的数据");
return;
}
this.$Modal.confirm({
title: "确认删除",
content: "您确认要删除所选的 " + this.selectCount + " 条店员?",
loading: true,
onOk: () => {
let ids = "";
this.selectList.forEach(function (e) {
ids += e.id + ",";
});
ids = ids.substring(0, ids.length - 1);
deleteClerk(ids).then(res => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("删除成功");
this.clearSelectAll();
this.getUserList();
}
});
}
});
}
},
mounted() {
this.init();
this.getRoleList();
}
};
</script>

View File

@@ -0,0 +1,408 @@
<template>
<div class="search">
<Card>
<Row class="operation">
<i-switch v-model="strict" size="large" style="margin-right: 5px">
<span slot="open">级联</span>
<span slot="close">单选</span>
</i-switch>
<Button @click="addRoot">添加部门</Button>
<Button @click="add" type="primary">添加子部门</Button>
<Button @click="delAll">批量删除</Button>
<Button @click="getParentList">刷新</Button>
</Row>
<Row type="flex" justify="start">
<Col :md="8" :lg="8" :xl="6">
<Alert show-icon>
当前选择编辑
<span class="select-title">{{ editTitle }}</span>
<a class="select-clear" v-if="form.id" @click="cancelSelect"
>取消选择</a
>
</Alert>
<div class="tree-bar" :style="{ maxHeight: maxHeight }">
<Tree
ref="tree"
:data="data"
:load-data="loadData"
show-checkbox
@on-check-change="changeSelect"
@on-select-change="selectTree"
:check-strictly="!strict"
></Tree>
<Spin size="large" fix v-if="loading"></Spin>
</div>
</Col>
<Col :md="15" :lg="13" :xl="9" style="margin-left: 10px">
<Form
ref="form"
:model="form"
:label-width="100"
:rules="formValidate"
>
<FormItem label="部门名称" prop="title">
<Input v-model="form.title" />
</FormItem>
<FormItem label="选择角色">
<Select
:loading="userLoading"
not-found-text="暂无角色"
v-model="selectedRole"
multiple
>
<Option v-for="item in users" :value="item.id" :key="item.id">{{
item.name
}}</Option>
</Select>
</FormItem>
<FormItem label="排序值" prop="sortOrder">
<Tooltip
trigger="hover"
placement="right"
content="值越小越靠前,支持小数"
>
<InputNumber
:max="1000"
:min="0"
v-model="form.sortOrder"
></InputNumber>
</Tooltip>
</FormItem>
<Form-item>
<Button
style="margin-right: 5px"
@click="submitEdit"
:loading="submitLoading"
type="primary"
>修改并保存</Button
>
<Button @click="handleReset">重置</Button>
</Form-item>
</Form>
</Col>
</Row>
</Card>
<Modal
:title="modalTitle"
v-model="modalVisible"
:mask-closable="false"
:width="500"
>
<Form
ref="formAdd"
:model="formAdd"
:label-width="85"
:rules="formValidate"
>
<div v-if="showParent">
<FormItem label="上级部门:">{{ form.title }}</FormItem>
</div>
<FormItem label="部门名称" prop="title">
<Input v-model="formAdd.title" />
</FormItem>
<FormItem label="排序值" prop="sortOrder">
<Tooltip
trigger="hover"
placement="right"
content="值越小越靠前,支持小数"
>
<InputNumber
:max="1000"
:min="0"
v-model="formAdd.sortOrder"
></InputNumber>
</Tooltip>
</FormItem>
</Form>
<div slot="footer">
<Button type="text" @click="cancelAdd">取消</Button>
<Button type="primary" :loading="submitLoading" @click="submitAdd"
>提交</Button
>
</div>
</Modal>
</div>
</template>
<script>
import {
initDepartment,
loadDepartment,
addDepartment,
editDepartment,
deleteDepartment,
getUserByDepartmentId,
getRoleList,
updateDepartmentRole,
} from "@/api/index";
export default {
name: "store-department-manage",
data() {
return {
loading: true, // 加载状态
maxHeight: "500px", // 最大高度
strict: true, // 级联还是单选
userLoading: false, // 选择角色加载状态
loadingEdit: false, // 编辑加载状态
modalVisible: false, // modal显隐
selectList: [], // 已选列表
selectCount: 0, // 已选总数
showParent: false, // 展示父级
modalTitle: "", // modal标题
editTitle: "", // 编辑标题
selectedRole: [], //选择的角色
searchKey: "", // 搜索关键字
form: { // 提交表单
id: "",
title: "",
parentId: "",
parentTitle: "",
sortOrder: 0,
status: 0,
},
formAdd: {}, // 新增表单
formValidate: { // 验证规则
title: [{ required: true, message: "名称不能为空", trigger: "blur" }],
sortOrder: [
{
required: true,
type: "number",
message: "排序值不能为空",
trigger: "blur",
},
],
},
submitLoading: false, // 提交loading
data: [], // 部门数据
dataEdit: [], // 编辑时部门数据
users: [], // 用户
};
},
methods: {
init() {
this.getParentList();
},
// 获取部门数据
getParentList() {
this.loading = true;
initDepartment().then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result;
}
});
},
// 动态加载二级数据
loadData(item, callback) {
loadDepartment(item.id).then((res) => {
this.loadingEdit = false;
if (res.success) {
console.log(res.result);
callback(res.result);
}
});
},
// 点击树
selectTree(v) {
if (v.length > 0) {
// 转换null为""
for (let attr in v[0]) {
if (v[0][attr] == null) {
v[0][attr] = "";
}
}
let str = JSON.stringify(v[0]);
let data = JSON.parse(str);
this.editTitle = data.title;
// 加载部门用户数据
this.userLoading = true;
getUserByDepartmentId(data.id).then((res) => {
let way =[]
res.result && res.result.forEach((item) => {
way.push(item.roleId)
})
this.$set(this,'selectedRole',way)
});
getRoleList({
pageNumber: 1,
pageSize: 10000,
}).then((res) => {
this.userLoading = false;
if (res.success) {
this.users = res.result.records;
// 回显
this.form = data;
}
});
} else {
this.cancelSelect();
}
},
// 取消选择
cancelSelect() {
let data = this.$refs.tree.getSelectedNodes()[0];
if (data) {
data.selected = false;
}
this.$refs.form.resetFields();
delete this.form.id;
this.editTitle = "";
},
// 选择上级部门
selectTreeEdit(v) {
if (v.length > 0) {
// 转换null为""
for (let attr in v[0]) {
if (v[0][attr] == null) {
v[0][attr] = "";
}
}
let str = JSON.stringify(v[0]);
let data = JSON.parse(str);
this.form.parentId = data.id;
this.form.parentTitle = data.title;
}
},
// 取消添加部门
cancelAdd() {
this.modalVisible = false;
},
// 重置表单
handleReset() {
this.$refs.form.resetFields();
this.form.status = 0;
},
// 提交表单
submitEdit() {
this.$refs.form.validate((valid) => {
if (valid) {
if (!this.form.id) {
this.$Message.warning("请先点击选择要修改的部门");
return;
}
let roleWay = [];
this.selectedRole.forEach((item) => {
let role = {
departmentId: this.form.id,
roleId: item,
};
roleWay.push(role);
});
Promise.all([
editDepartment(this.form.id, this.form),
updateDepartmentRole(this.form.id, roleWay)
]).then((res) => {
console.warn(res)
this.submitLoading = false;
if (res[0].success) {
this.$Message.success("编辑成功");
this.init();
this.modalVisible = false;
}
});
}
});
},
// 确认添加部门
submitAdd() {
this.$refs.formAdd.validate((valid) => {
if (valid) {
this.submitLoading = true;
addDepartment(this.formAdd).then((res) => {
this.submitLoading = false;
if (res.success) {
this.$Message.success("添加成功");
this.init();
this.modalVisible = false;
}
});
}
});
},
// 添加子部门
add() {
if (this.form.id == "" || this.form.id == null) {
this.$Message.warning("请先点击选择一个部门");
return;
}
this.modalTitle = "添加子部门";
this.showParent = true;
this.formAdd = {
parentId: this.form.id,
sortOrder: 0,
status: 0,
};
this.modalVisible = true;
},
// 添加一级部门
addRoot() {
this.modalTitle = "添加一级部门";
this.showParent = false;
this.formAdd = {
parentId: 0,
sortOrder: 0,
status: 0,
};
this.modalVisible = true;
},
// 选中回调
changeSelect(v) {
console.log(v);
this.selectCount = v.length;
this.selectList = v;
},
// 批量删除部门
delAll() {
if (this.selectCount <= 0) {
this.$Message.warning("您还未勾选要删除的数据");
return;
}
this.$Modal.confirm({
title: "确认删除",
content:
"您确认要删除所选的 " + this.selectCount + " 条数据及其下级所有数据?",
loading: true,
onOk: () => {
let ids = "";
this.selectList.forEach(function (e) {
ids += e.id + ",";
});
ids = ids.substring(0, ids.length - 1);
deleteDepartment(ids).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("删除成功");
this.selectList = [];
this.selectCount = 0;
this.cancelSelect();
this.init();
}
});
},
});
},
},
mounted() {
// 计算高度
let height = document.documentElement.clientHeight;
this.maxHeight = Number(height - 287) + "px";
this.init();
},
};
</script>
<style lang="scss" scoped>
@import "@/styles/tree-common.scss";
</style>

View File

@@ -0,0 +1,768 @@
<template>
<div class="search">
<Card>
<Row class="operation">
<Button @click="addRole" type="primary">添加角色</Button>
<Button @click="delAll">批量删除</Button>
</Row>
<br>
<Table :loading="loading" border :columns="columns" :data="data" ref="table" sortable="custom" @on-sort-change="changeSort" @on-selection-change="changeSelect"></Table>
<Row type="flex" justify="end" class="mt_10">
<Page :current="pageNumber" :total="total" :page-size="pageSize" @on-change="changePage" @on-page-size-change="changePageSize" :page-size-opts="[10, 20, 50]" size="small" show-total
show-elevator show-sizer></Page>
</Row>
</Card>
<!-- 编辑 -->
<Modal :title="modalTitle" v-model="roleModalVisible" :mask-closable="false" :width="500">
<Form ref="roleForm" :model="roleForm" :label-width="80" :rules="roleFormValidate">
<FormItem label="角色名称" prop="name">
<Input v-model="roleForm.name" />
</FormItem>
<FormItem label="备注" prop="description">
<Input v-model="roleForm.description" />
</FormItem>
</Form>
<div slot="footer">
<Button type="text" @click="roleModalVisible = false">取消</Button>
<Button type="primary" :loading="submitLoading" @click="submitRole">提交
</Button>
</div>
</Modal>
<!-- 菜单权限 -->
<Modal :title="modalTitle" v-model="permModalVisible" :mask-closable="false" :width="500" :styles="{ top: '30px' }" class="permModal">
<div style="position: relative">
<Tree ref="tree" :data="permData" show-checkbox :render="renderContent">
</Tree>
<Spin size="large" fix v-if="treeLoading"></Spin>
</div>
<div slot="footer">
<Button type="text" @click="permModalVisible = false">取消</Button>
<Select v-model="openLevel" @on-change="changeOpen" style="width: 110px; text-align: left; margin-right: 10px">
<Option value="0">展开所有</Option>
<Option value="1">收合所有</Option>
<Option value="2">仅展开一级</Option>
<Option value="3">仅展开两级</Option>
</Select>
<Button type="primary" :loading="submitPermLoading" @click="submitPermEdit()">编辑
</Button>
</div>
</Modal>
<!-- 保存权限弹出选择权限 -->
<Modal width="800" v-model="selectIsSuperModel" title="选择菜单权限" :loading="superModelLoading" @on-ok="saveRole">
<div class="btns">
<Button type="primary" @click="setRole()" class="btn-item">一键选中·数据权限</Button>
<Button class="btn-item" @click="setRole('onlyView')">一键选中·查看权限</Button>
</div>
<div class="role-list">
<div class="role-item" v-for="(item, index) in saveRoleWay" :key="index">
<div class="title">{{ item.title }}</div>
<div class="content">
<RadioGroup type="button" button-style="solid" v-model="item.isSuper">
<Radio :label="1">
<span>操作数据权限</span>
</Radio>
<Radio :label="0">
<span>查看权限</span>
</Radio>
</RadioGroup>
</div>
</div>
</div>
</Modal>
</div>
</template>
<script>
import {
getRoleList,
getAllPermissionList,
addRole,
editRole,
deleteRole,
loadDepartment,
selectRoleMenu,
saveRoleMenu,
} from "@/api/index";
import util from "@/libs/util.js";
export default {
name: "role-manage",
data() {
return {
superModelLoading: false, //保存权限弹出选择权限保存
selectIsSuperModel: false, //保存权限弹出选择权限
rolePermsWay: [], //查询角色权限集合
openLevel: "0", // 展开的级别
loading: true, // 加载状态
treeLoading: true, // 树加载
depTreeLoading: true, // 部门树加载
submitPermLoading: false, // 权限提交加载
submitDepLoading: false, // 部门提交加载
sortColumn: "", // 排序
sortType: "desc", // 排序类型
modalType: 0, // 0 添加 1 编辑
roleModalVisible: false, // 角色modal
permModalVisible: false, // 菜单权限modal
depModalVisible: false, // 部门modal
modalTitle: "", // modal标题
roleForm: {
// 角色表单
name: "",
description: "",
},
roleFormValidate: {
// 验证规则
name: [
{ required: true, message: "角色名称不能为空", trigger: "blur" },
],
},
submitLoading: false, // 提交loading
selectList: [], // 已选列表
selectCount: 0, // 已选总数
columns: [
// 表头
{
type: "selection",
width: 60,
align: "center",
},
{
title: "角色名称",
key: "name",
minWidth: 150,
},
{
title: "备注",
key: "description",
minWidth: 150,
tooltip: true,
},
{
title: "创建时间",
key: "createTime",
width: 170,
sortable: true,
sortType: "desc",
},
{
title: "更新时间",
key: "updateTime",
width: 170,
sortable: true,
},
{
title: "最后操作人",
key: "createBy",
width: 150,
},
{
title: "操作",
key: "action",
align: "center",
fixed: "right",
width: 230,
render: (h, params) => {
return h("div", [
h(
"Button",
{
props: {
type: "warning",
size: "small",
},
style: {
marginRight: "5px",
},
on: {
click: () => {
this.editPerm(params.row);
},
},
},
"菜单权限"
),
h(
"Button",
{
props: {
size: "small",
type: "info",
},
style: {
marginRight: "5px",
},
on: {
click: () => {
this.edit(params.row);
},
},
},
"编辑"
),
h(
"Button",
{
props: {
type: "error",
size: "small",
},
on: {
click: () => {
this.remove(params.row);
},
},
},
"删除"
),
]);
},
},
],
data: [], // 角色数据
pageNumber: 1, // 页数
pageSize: 10, // 每页数量
total: 0, // 总数
permData: [], // 菜单权限数据
editRolePermId: "", // 编辑权限id
selectAllFlag: false, // 全选标识
depData: [], // 部门数据
dataType: 0, // 数据类型
editDepartments: [], // 编辑部门
saveRoleWay: [], //用户保存用户点击的菜单
};
},
methods: {
// 初始化数据
init() {
this.getRoleList();
// 获取所有菜单权限树
this.getPermList();
},
// 渲染部门前icon
renderContent(h, { root, node, data }) {
let icon = "";
if (data.level == 0) {
icon = "ios-navigate";
} else if (data.level == 1) {
icon = "md-list-box";
} else if (data.level == 2) {
icon = "md-list";
} else if (data.level == 3) {
icon = "md-radio-button-on";
} else {
icon = "md-radio-button-off";
}
return h(
"span",
{
style: {
display: "inline-block",
cursor: "pointer",
},
},
[
h("span", [
h("Icon", {
props: {
type: icon,
size: "16",
},
style: {
"margin-right": "8px",
"margin-bottom": "3px",
},
}),
h("span", data.title),
h(
"Tag",
{
props: {
color:
data.isSuper == 1
? "red"
: data.isSuper == 0
? "default"
: "default",
},
style: {
"margin-left": "10px",
display:
data.isSuper == 1 || data.isSuper == 0
? "inline-block"
: "none",
},
},
data.isSuper == 1
? "操作权限"
: data.isSuper == 0
? "查看权限"
: ""
),
]),
]
);
},
// 分页 修改页码
changePage(v) {
this.pageNumber = v;
this.getRoleList();
this.clearSelectAll();
},
// 分页 修改页数
changePageSize(v) {
this.pageNumber = 1;
this.pageSize = v;
this.getRoleList();
},
// 变更排序方式
changeSort(e) {
this.sortColumn = e.key;
this.sortType = e.order;
if (e.order == "normal") {
this.sortType = "";
}
this.getRoleList();
},
/**
* 设置权限
*/
setRole(val) {
let enable;
val == "onlyView" ? (enable = 0) : (enable = 1);
this.saveRoleWay.map((item) => {
item.isSuper = enable;
});
},
/**
* 查询所有角色
*/
getRoleList() {
this.loading = true;
let params = {
pageNumber: this.pageNumber,
pageSize: this.pageSize,
sort: this.sortColumn,
order: this.sort,
};
getRoleList(params).then((res) => {
this.loading = false;
if (res.success) {
this.data = res.result.records;
this.total = res.result.total;
}
});
},
/**
* 查询菜单
*/
getPermList() {
this.treeLoading = true;
getAllPermissionList().then((res) => {
if (res.success) {
this.deleteDisableNode(res.result);
this.permData = res.result;
this.treeLoading = false;
}
this.treeLoading = false;
});
},
// 递归标记禁用节点
deleteDisableNode(permData) {
let that = this;
permData.forEach(function (e) {
if (e.status == -1) {
e.title = "[已禁用] " + e.title;
e.disabled = true;
}
if (e.children && e.children.length > 0) {
that.deleteDisableNode(e.children);
}
});
},
// 提交
submitRole() {
this.$refs.roleForm.validate((valid) => {
if (valid) {
if (this.modalType == 0) {
// 添加
this.submitLoading = true;
addRole(this.roleForm).then((res) => {
this.submitLoading = false;
if (res.success) {
this.$Message.success("操作成功");
this.getRoleList();
this.roleModalVisible = false;
}
});
} else {
this.submitLoading = true;
this.roleForm.roleId = this.roleForm.id;
editRole(this.roleForm).then((res) => {
this.submitLoading = false;
if (res.success) {
this.$Message.success("操作成功");
this.getRoleList();
this.roleModalVisible = false;
}
});
}
}
});
},
/**
* 点击添加按钮
*/
addRole() {
this.modalType = 0;
this.modalTitle = "添加角色";
this.$refs.roleForm.resetFields();
delete this.roleForm.id;
this.roleModalVisible = true;
},
// 编辑
edit(v) {
this.modalType = 1;
this.modalTitle = "编辑角色";
this.$refs.roleForm.resetFields();
// 转换null为""
for (let attr in v) {
if (v[attr] == null) {
v[attr] = "";
}
}
let str = JSON.stringify(v);
let roleInfo = JSON.parse(str);
this.roleForm = roleInfo;
this.roleModalVisible = true;
},
// 删除
remove(v) {
this.$Modal.confirm({
title: "确认删除",
content: "您确认要删除角色 " + v.name + " ?",
loading: true,
onOk: () => {
deleteRole(v.id).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("删除成功");
this.getRoleList();
}
});
},
});
},
// 清除选中
clearSelectAll() {
this.$refs.table.selectAll(false);
},
// 选中回调
changeSelect(e) {
this.selectList = e;
this.selectCount = e.length;
},
// 批量删除
delAll() {
if (this.selectCount <= 0) {
this.$Message.warning("您还未选择要删除的数据");
return;
}
this.$Modal.confirm({
title: "确认删除",
content: "您确认要删除所选的 " + this.selectCount + " 条数据?",
loading: true,
onOk: () => {
let ids = "";
this.selectList.forEach(function (e) {
ids += e.id + ",";
});
ids = ids.substring(0, ids.length - 1);
deleteRole(ids).then((res) => {
this.$Modal.remove();
if (res.success) {
this.$Message.success("删除成功");
this.clearSelectAll();
this.getRoleList();
}
});
},
});
},
// 菜单权限
async editPerm(v) {
/**
* 点击菜单权限每次将赋值的isSuper数据给清空掉
*/
this.permData.map((item) => {
item.children.length != 0
? item.children.map((child) => {
child.children.length != 0
? child.children.map((kid) => {
delete kid.isSuper;
})
: "";
delete child.isSuper;
})
: "";
delete item.isSuper;
});
if (this.treeLoading) {
this.$Message.warning("菜单权限数据加载中,请稍后点击查看");
return;
}
this.editRolePermId = v.id;
this.modalTitle = "分配 " + v.name + " 的菜单权限";
// 匹配勾选
let rolePerms;
// 当前角色的菜单权限
let res = await selectRoleMenu(v.id);
if (res.result) {
rolePerms = res.result;
this.rolePermsWay = res.result;
}
// 递归判断子节点是否可以选中
this.checkPermTree(this.permData, rolePerms);
this.permModalVisible = true;
},
// 递归判断子节点
checkPermTree(permData, rolePerms) {
let that = this;
permData.forEach((p) => {
if (that.hasPerm(p, rolePerms) && p.status != -1) {
if (p.children && p.children.length === 0) {
this.$set(p, "checked", true);
}
} else {
this.$set(p, "checked", false);
}
if (p.children && p.children.length > 0) {
that.checkPermTree(p.children, rolePerms);
}
});
},
// 判断角色拥有的权限节点勾选
hasPerm(p, rolePerms) {
if (!rolePerms) return false;
let flag = false;
for (let i = 0; i < rolePerms.length; i++) {
if (p.id == rolePerms[i].menuId) {
this.$set(p, "isSuper", rolePerms[i].isSuper);
flag = true;
break;
}
}
if (flag) {
return true;
}
return false;
},
// 递归全选节点
selectedTreeAll(permData, select) {
let that = this;
permData.forEach(function (e) {
e.checked = select;
if (e.children && e.children.length > 0) {
that.selectedTreeAll(e.children, select);
}
});
},
/**分配菜单权限 */
submitPermEdit() {
this.saveRoleWay = [];
this.selectIsSuperModel = true; //打开选择权限
let selectedNodes = this.$refs.tree.getCheckedAndIndeterminateNodes();
let way = [];
selectedNodes.forEach((e) => {
console.log(e)
let perm = {
title: e.title,
isSuper: e.isSuper ? e.isSuper = 1 : e.isSuper = 0 || 0,
menuId: e.id,
roleId: this.editRolePermId,
};
way.push(perm);
this.$set(this,'saveRoleWay',way)
});
console.log(this.saveRoleWay)
},
/**保存权限 */
saveRole() {
this.superModelLoading = true;
saveRoleMenu(this.editRolePermId, this.saveRoleWay).then((res) => {
this.superModelLoading = false;
if (res.success) {
this.$Message.success("操作成功");
// 标记重新获取菜单数据
this.$store.commit("setAdded", false);
util.initRouter(this);
this.getRoleList();
this.permModalVisible = false;
}
});
},
// 加载数据
loadData(item, callback) {
loadDepartment(item.id, { openDataFilter: false }).then((res) => {
if (res.success) {
res.result.forEach(function (e) {
e.checked = false;
if (e.isParent) {
e.loading = false;
e.children = [];
}
if (e.status == -1) {
e.title = "[已禁用] " + e.title;
e.disabled = true;
}
});
callback(res.result);
}
});
},
// 判断展开子节点
expandCheckDep(v) {
this.checkDepTree(v.children, this.editDepartments);
},
// 判断子节点
checkDepTree(depData, roleDepIds) {
let that = this;
depData.forEach(function (p) {
if (that.hasDepPerm(p, roleDepIds)) {
p.checked = true;
} else {
p.checked = false;
}
});
},
// 树结构展开层级
changeOpen(v) {
if (v == "0") {
this.permData.forEach((e) => {
e.expand = true;
if (e.children && e.children.length > 0) {
e.children.forEach((c) => {
c.expand = true;
if (c.children && c.children.length > 0) {
c.children.forEach(function (b) {
b.expand = true;
});
}
});
}
});
} else if (v == "1") {
this.permData.forEach((e) => {
e.expand = false;
if (e.children && e.children.length > 0) {
e.children.forEach((c) => {
c.expand = false;
if (c.children && c.children.length > 0) {
c.children.forEach(function (b) {
b.expand = false;
});
}
});
}
});
} else if (v == "2") {
this.permData.forEach((e) => {
e.expand = true;
if (e.children && e.children.length > 0) {
e.children.forEach((c) => {
c.expand = false;
if (c.children && c.children.length > 0) {
c.children.forEach(function (b) {
b.expand = false;
});
}
});
}
});
} else if (v == "3") {
this.permData.forEach((e) => {
e.expand = true;
if (e.children && e.children.length > 0) {
e.children.forEach((c) => {
c.expand = true;
if (c.children && c.children.length > 0) {
c.children.forEach(function (b) {
b.expand = false;
});
}
});
}
});
}
},
},
mounted() {
this.init();
},
};
</script>
<style lang="scss" scoped>
.role-list {
height: 500px;
overflow-y: auto;
display: flex;
flex-wrap: wrap;
}
.role-item {
width: 50%;
display: flex;
padding: 20px 0;
align-items: center;
> .title {
flex: 2;
text-align: right;
}
> .content {
flex: 10;
}
}
.btns {
display: flex;
align-items: center;
justify-content: center;
}
.btn-item {
margin-right: 20px;
}
.permModal {
.ivu-modal-body {
max-height: 560px;
overflow: auto;
}
}
.depModal {
.ivu-modal-body {
max-height: 500px;
overflow: auto;
}
}
.tips {
font-size: 12px;
color: #999;
margin-left: 8px;
}
.title {
font-weight: bold;
margin-right: 20px;
}
</style>

View File

@@ -0,0 +1,164 @@
<template>
<div class="model-view">
<div class="model-view-content">
<div class="content">
<div class="wap-title">首页</div>
<div class="draggable">
<!-- 全屏 -->
<div class="full-shadow" v-if="type == 'full'">
<img :src="advertising[0].img" alt="" />
</div>
</div>
</div>
</div>
<div class="model-config">
<div class="decorate">
<div class="decorate-title">全屏广告</div>
<div class="decorate-list">
<div
class="decorate-item"
v-for="(item, index) in advertising"
:key="index"
>
<div class="decorate-item-title">
<div>设置</div>
</div>
<div class="decorate-item-box">
<!-- 选择照片 -->
<div class="decorate-view">
<div class="decorate-view-title">选择图片</div>
<div>
<img class="show-image" :src="item.img" alt />
<input
type="file"
class="hidden-input"
@change="changeFile(item, index)"
ref="files"
:id="'files' + index"
/>
<div class="tips">
建议尺寸
<span>{{ item.size }}</span>
</div>
</div>
<div class="selectBtn">
<Button
size="small"
@click="handleClickFile(item, index)"
ghost
type="primary"
>选择照片</Button
>
</div>
</div>
<!-- 选择连接 -->
<div class="decorate-view">
<div class="decorate-view-title">选择图片</div>
<div>
<Button
ghost
type="primary"
size="small"
@click="clickLink(item)"
>选择链接</Button
>
</div>
</div>
</div>
</div>
</div>
<!-- <Button type="primary" @click="addDecorate()" ghost>添加</Button> -->
<liliDialog ref="liliDialog" :types="linkType"></liliDialog>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
type: "full", // 是否全屏
//全屏广告
advertising: [
{
img:
"https://st-gdx.dancf.com/gaodingx/0/uxms/design/20200903-182035-5e87.png?x-oss-process=image/resize,w_932/interlace,1,image/format,webp",
size: "750*1624",
},
],
linkType: "", // 选择类型
};
},
methods: {
// 点击链接
clickLink(item) {
this.$refs.liliDialog.open('link')
},
//点击图片解析成base64
changeFile(item, index) {
const file = document.getElementById("files" + index).files[0];
if (file == void 0) return false;
const reader = new FileReader();
reader.readAsDataURL(file);
this.$nextTick((res) => {
reader.onload = (e) => {
item.img = e.target.result;
};
});
},
// 点击选择照片
handleClickFile(item, index) {
document.getElementById("files" + index).click();
},
},
};
</script>
<style scoped lang="scss">
@import "./style.scss";
@import "./decorate.scss";
.decorate-radio {
margin: 10px 0;
}
.window-shadow,
.full-shadow {
display: flex;
position: absolute;
top: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.2);
left: 0;
align-items: center;
justify-content: center;
}
.window-shadow {
> img {
width: 306px;
height: 418px;
}
}
.full-shadow {
> img {
width: 100%;
height: 100%;
}
}
.draggable {
position: relative;
}
.btn-item {
> img {
margin: 4px 0;
border-radius: 50%;
width: 30px;
height: 30px;
}
}
</style>

View File

@@ -0,0 +1,159 @@
<template>
<div class="model-view">
<div class="model-view-content">
<div class="content">
<div class="wap-title">首页</div>
<div class="draggable">
<!-- 弹窗广告 -->
<div class="window-shadow">
<img :src="advertising[0].img" alt="" />
</div>
</div>
</div>
</div>
<div class="model-config">
<div class="decorate">
<div class="decorate-title">弹窗广告</div>
<div class="decorate-list">
<div
class="decorate-item"
v-for="(item, index) in advertising"
:key="index"
>
<div class="decorate-item-title">
<div>设置</div>
</div>
<div class="decorate-item-box">
<!-- 选择照片 -->
<div class="decorate-view">
<div class="decorate-view-title">选择图片</div>
<div>
<img class="show-image" :src="item.img" alt />
<input
type="file"
class="hidden-input"
@change="changeFile(item, index)"
ref="files"
:id="'files' + index"
/>
<div class="tips">
建议尺寸
<span>{{ item.size }}</span>
</div>
</div>
<div class="selectBtn">
<Button
size="small"
@click="handleClickFile(item, index)"
ghost
type="primary"
>选择照片</Button
>
</div>
</div>
<!-- 选择连接 -->
<div class="decorate-view">
<div class="decorate-view-title">选择图片</div>
<div>
<Button
ghost
type="primary"
size="small"
@click="clickLink(item)"
>选择链接</Button
>
</div>
</div>
</div>
</div>
</div>
<liliDialog ref="liliDialog" :types="linkType"></liliDialog>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
type: "full", // 展示方式
//全屏广告
advertising: [
{
img:
"https://shopro-1253949872.file.myqcloud.com/uploads/20200704/9136ecddcddf6607184fab689207e7e3.png",
size: "612*836",
},
],
linkType: "", // 选择类型
};
},
methods: {
// 点击链接
clickLink(item) {
this.$refs.liliDialog.open('link')
},
//点击图片解析成base64
changeFile(item, index) {
const file = document.getElementById("files" + index).files[0];
if (file == void 0) return false;
const reader = new FileReader();
reader.readAsDataURL(file);
this.$nextTick((res) => {
reader.onload = (e) => {
item.img = e.target.result;
};
});
},
// 点击选择照片
handleClickFile(item, index) {
document.getElementById("files" + index).click();
},
},
};
</script>
<style scoped lang="scss">
@import "./style.scss";
@import "./decorate.scss";
.decorate-radio {
margin: 10px 0;
}
.window-shadow,
.full-shadow {
display: flex;
position: absolute;
top: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.2);
left: 0;
align-items: center;
justify-content: center;
}
.window-shadow {
> img {
width: 306px;
height: 418px;
}
}
.full-shadow {
> img {
width: 100%;
height: 100%;
}
}
.draggable {
position: relative;
}
.btn-item {
> img {
margin: 4px 0;
border-radius: 50%;
width: 30px;
height: 30px;
}
}
</style>

View File

@@ -0,0 +1,570 @@
import * as API_Other from "@/api/other";
// 获取楼层装修信息
export function initData(id) {
API_Other.getHomeData(id).then(res => {
homeData = res;
});
}
export let homeData = {};
/**
* drawer:true 广告右侧打开抽屉中显示
* ad_drawer:true 活动魔方右侧显示
* notAdd: true 没有添加按钮
* notLink: true 没有连接功能
* notImg: true 没有选择图片功能
* close:true 右侧关闭按钮
*/
export const modelData = [
{
type: "carousel",
name: "图片轮播",
img: "md-image",
notTitle: false,
close: true,
options: {
list: [
{
img: "https://i.loli.net/2020/12/05/fKH4CwImpbuD5Xj.png",
url: "",
link: "",
size: "750*350"
},
{
img: "https://i.loli.net/2020/12/05/12kleCgrSLfKoQs.png",
url: "",
link: "",
size: "750*350"
},
{
img: "https://i.loli.net/2021/05/14/ZlzcCdnpejtN9gL.png",
url: "",
link: "",
size: "750*350"
}
]
}
},
{
type: "leftOneRightTwo",
name: "左一右二",
notAdd: true,
drawer: true,
view: "tpl_ad_list",
img: "md-image",
options: {
list: [
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "335*335"
},
{
img: "https://i.loli.net/2021/05/14/kdB3AE9ay4c1SnN.png",
url: "",
link: "",
size: "335*177"
},
{
img: "https://i.loli.net/2021/05/14/FmDr9ksiXeEqYLU.png",
url: "",
link: "",
size: "335*177"
}
]
}
},
{
type: "title",
name: "标题栏",
img: "md-image",
notAdd: true,
notLink: true,
notImg: true,
options: {
list: [
{
title: "标题",
color: "#000000"
}
]
}
},
{
type: "leftTwoRightOne",
name: "左二右一",
notAdd: true,
drawer: true,
img: "md-image",
options: {
list: [
{
img: "https://i.loli.net/2021/05/14/kdB3AE9ay4c1SnN.png",
url: "",
link: "",
size: "335*177"
},
{
img: "https://i.loli.net/2021/05/14/FmDr9ksiXeEqYLU.png",
url: "",
link: "",
size: "335*177"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "335*335"
}
]
}
},
{
type: "flexThree",
name: "三列单行",
drawer: true,
notAdd: true,
img: "md-image",
options: {
list: [
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "226*226 (1:1)"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "226*226 (1:1)"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "226*226 (1:1)"
}
]
}
},
{
type: "flexOne",
name: "一张大图",
drawer: true,
notAdd: true,
img: "md-image",
options: {
list: [
{
img: "https://i.loli.net/2020/12/05/8wSNWbnqujDh6HL.png",
url: "",
link: "",
size: "750*280"
}
]
}
},
{
type: "flexTwo",
name: "两张横图",
drawer: true,
notAdd: true,
img: "md-image",
options: {
list: [
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "335*220"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "335*220"
}
]
}
},
{
type: "topOneBottomTwo",
name: "上一下二",
drawer: true,
notAdd: true,
img: "md-image",
options: {
list: [
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "710*170"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "335*170"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "335*170"
}
]
}
},
{
type: "topTwoBottomOne",
name: "上二下一",
drawer: true,
notAdd: true,
img: "md-image",
options: {
list: [
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "335*170"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "335*170"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "710*170"
}
]
}
},
{
type: "flexFive",
name: "五列单行",
drawer: true,
notAdd: true,
img: "md-image",
options: {
list: [
{
img: "https://picsum.photos/id/127/200/200",
url: "",
link: "",
size: "75*751:1"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "75*751:1"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "75*751:1"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "75*751:1"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "75*751:1"
}
]
}
},
{
type: "flexFour",
name: "四列单行",
drawer: true,
notAdd: true,
img: "md-image",
options: {
list: [
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "88*881:1"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "88*881:1"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "88*881:1"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
size: "88*881:1"
}
]
}
},
{
type: "textPicture",
name: "文字图片",
drawer: true,
notAdd: true,
img: "md-image",
options: {
list: [
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
title: "文字",
size: "88*881:1"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
title: "文字",
size: "88*881:1"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
title: "文字",
size: "88*881:1"
},
{
img: "https://i.loli.net/2021/05/14/dtNvI5UxchXn8gz.png",
url: "",
link: "",
title: "文字",
size: "88*881:1"
}
]
}
},
{
type: "tpl_ad_list",
name: "广告魔方",
img: "md-image",
options: {
list: [
{
bg_img: "",
name: "",
url: ""
}
]
}
},
{
type: "menu",
name: "宫格导航",
img: "md-image",
close: true,
options: {
list: [
{
img: "https://i.loli.net/2020/12/05/SoGAv7gYybuWzED.png",
url: "",
link: "",
title: "标题",
size: "88*88 (1:1)"
},
{
img: "https://i.loli.net/2020/12/05/JXR5K3sbIeENjqH.png",
url: "",
link: "",
title: "标题",
size: "88*88 (1:1)"
},
{
img: "https://i.loli.net/2020/12/05/KlZfnCFIdEV231Y.png",
url: "",
link: "",
title: "标题",
size: "88*88 (1:1)"
},
{
img: "https://i.loli.net/2020/12/05/GfmMyN2wrUVIlci.png",
url: "",
link: "",
title: "标题",
size: "88*88 (1:1)"
},
{
img: "https://i.loli.net/2020/12/05/eznDa3iNby5FkYL.png",
url: "",
link: "",
title: "标题",
size: "88*88 (1:1)"
}
]
}
},
{
type: "search",
name: "搜索",
img: "md-image",
notAdd: true,
notLink: true,
notImg: true,
options: {
list: [
{
title: "搜索"
}
]
}
},
{
type: "goods",
name: "商品分类",
img: "md-image",
notAdd: true,
notLink: true,
notImg: true,
options: {
list: [
{
/**
* 2021/12/9
* 新增索引index判断商品归属分类
* 之前代码没有配置index也不会收到印象
* 新建的楼层将采用索引判断分类
*/
titleWay: [
{
title: "精选",
desc: "电子推荐",
___index:0,
},
{
title: "实惠",
desc: "便宜好货",
___index:1,
},
{
title: "进口",
desc: "国际自营",
___index:2,
},
{
title: "推荐",
desc: "喂奶推荐",
___index:3,
}
],
listWay: [
{
img: "https://i.loli.net/2021/05/14/KTLSrOVJmEdX12A.png",
price: "120",
title:
" 微软 (Microsoft) Xbox 无线控制器/手柄 湛蓝色 | 3.5mm耳机接口蓝牙连接 Xbox主机电脑平板通用",
type: "精选",
___index:0
},
{
img: "https://i.loli.net/2020/12/05/c9mptI5Pg8qJ6ny.png",
title:
"宏碁(acer) DP高清线1.2版 2K*4KDisplayPort公对公接线笔记本电脑显卡连接显示器视频线1.5米",
price: "190",
type: "精选",
___index:0
},
]
}
]
}
}
// TODO 第一版本隐藏暂无此功能
// {
// notAdd: true,
// notImg: true,
// type: "joinGroup",
// name: "拼团活动",
// img: "md-image",
// options: {
// list: [
// {
// title: "测试拼团"
// }
// ]
// }
// },
// {
// notAdd: true,
// notImg: true,
// type: "integral",
// name: "积分活动",
// img: "md-image",
// options: {
// list: [
// {
// title: "测试积分"
// }
// ]
// }
// },
// {
// notAdd: true,
// notImg: true,
// type: "spike",
// name: "秒杀活动",
// img: "md-image",
// options: {
// list: [
// {
// title: "测试秒杀"
// }
// ]
// }
// },
// {
// notAdd: true,
// notImg: true,
// type: "group",
// name: "团购活动",
// img: "md-image",
// options: {
// list: [
// {
// title: "测试团购"
// }
// ]
// }
// }
];

View File

@@ -0,0 +1,117 @@
/deep/ .ivu-modal-mask,.ivu-modal-wrap{
z-index: 800;
}
.decorate-view-link{
font-size: 12px;
margin: 0 4px;
color: #999;
}
.decorate-view-style {
border: 1px solid #ededed;
background: #f7f7fa;
text-align: center;
width: 100%;
padding: 30px 0 0 0;
margin-bottom: 20px;
cursor: pointer;
> .select-style {
background: #ededed;
padding: 15px 0;
font-size: 15px;
}
}
.decorate-border {
border: 1px solid #ededed;
margin: 10px 0;
padding: 0 10px;
}
.drawer {
width: 100%;
display: flex;
flex-wrap: wrap;
> .drawer-item {
cursor: pointer;
border: 1px solid #ededed;
background: #f9f0ff;
width: 170px;
margin-right: 14px;
color: #9254de;
margin-bottom: 14px;
border-radius: 0.8em;
height: 60px;
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
}
}
.hidden-input {
display: none;
}
.decorate {
padding: 0 20px;
height: calc(100vh - 120px);
overflow-y: auto;
padding-bottom: 120px;
}
.decorate-title {
height: 50px;
line-height: 50px;
font-weight: bold;
}
.decorate-list {
overflow: hidden;
}
.decorate-view {
display: flex;
margin: 20px 0;
align-items: center;
}
.decorate-item-box {
background: #fff;
padding: 10px;
border: 1px solid #ededed;
}
.decorate-item-title {
height: 40px;
display: flex;
align-items: center;
justify-content: space-between;
line-height: 40px;
padding: 0 10px;
}
.decorate-view-title {
margin-right: 10px;
}
.decorate-item {
background: #ededed;
border-top-left-radius: 0.4em;
margin-bottom: 20px;
border-top-right-radius: 0.4em;
}
.show-image {
max-width: 50px;
}
.tips {
font-size: 12px;
color: #999;
> span {
color: $theme_color;
}
}
.selectBtn {
margin-left: 10px;
}
.bing-goods-list {
display: flex;
> .bing-goods-item {
width: 50px;
height: 50px;
> img {
width: 100%;
height: 100%;
display: block;
}
}
}

View File

@@ -0,0 +1,304 @@
<template>
<div class="decorate">
<div class="decorate-title">
{{ res.name }}
<Button
style="margin-left: 20px"
size="small"
ghost
v-if="res.type == 'tpl_ad_list' || res.type == 'tpl_activity_list' || res.drawer"
type="primary"
@click="selectStyle()"
>选择风格</Button
>
</div>
<!-- 右侧显示抽屉 -->
<Drawer title="选择风格" :closable="false" width="400" v-model="styleFlag">
<div class="drawer">
<div
class="drawer-item"
@click="clickDrawer(item, index)"
v-for="(item, index) in modelData"
:key="index"
v-if="item.drawer"
>
<img src alt />
<span>{{ item.name }}</span>
</div>
</div>
</Drawer>
<!-- 卡片集合 -->
<div
class="decorate-list"
v-if="(res.type != 'tpl_ad_list' && res.type != 'tpl_activity_list') || res.drawer"
>
<div class="decorate-item" v-for="(item, index) in res.options.list" :key="index">
<div class="decorate-item-title">
<div>卡片</div>
<Icon
@click="closeDecorate(index)"
v-if="res.close"
size="20"
color="#e1251b"
type="md-close-circle"
/>
</div>
<div class="decorate-item-box">
<div
class="decorate-border"
v-if="item.titleWay"
v-for="(title_item, title_index) in item.titleWay"
:key="title_index"
>
<div class="decorate-view">
<div class="decorate-view-title">标题{{ title_index + 1 }}</div>
<div>
<Input v-model="title_item.title" />
</div>
</div>
<div class="decorate-view">
<div class="decorate-view-title">描述</div>
<div>
<Input v-model="title_item.desc" />
</div>
</div>
<div class="decorate-view">
<div class="decorate-view-title">绑定商品</div>
<div
class="decorate-view-link"
v-if="res.options.list[0].listWay.length != 0"
>
<!-- 绑定商品选择器回调已选择的商品 -->
<div
v-if="
title_item.___index == bindGoods.___index ||
title_item.title == bindGoods.type
"
v-for="(bindGoods, bindGoodsIndex) in res.options.list[0].listWay"
:key="bindGoodsIndex"
>
{{ bindGoods.title }},
</div>
</div>
<div>
<Button @click="bindGoodsId(title_item)" size="small" ghost type="primary"
>选择商品</Button
>
</div>
</div>
</div>
<!-- 选择照片 -->
<div class="decorate-view" v-if="!res.notImg">
<div class="decorate-view-title">选择照片</div>
<div>
<img class="show-image" :src="item.img" alt />
<div class="tips">
建议尺寸
<span>{{ item.size }}</span>
</div>
</div>
<div class="selectBtn">
<Button
size="small"
@click="handleClickFile(item, index)"
ghost
type="primary"
>选择照片</Button
>
</div>
</div>
<!-- 填写标题 -->
<div class="decorate-view" v-if="item.title != void 0 && !res.notTitle">
<div class="decorate-view-title">菜单标题</div>
<div>
<Input v-model="item.title" style="width: 200px" />
</div>
</div>
<!-- 填写链接 -->
<div class="decorate-view" v-if="!res.notLink">
<div class="decorate-view-title">选择链接</div>
<div v-if="item.url.length != 0" class="decorate-view-link">
已选链接:
<span>
{{
ways.find((e) => {
return item.url.___type == e.name;
}).title
}}
-
<!-- 当选择完链接之后的商品名称 -->
<span v-if="item.url.___type == 'goods'"> {{ item.url.goodsName }}</span>
<!-- 当选择完链接之后的分类回调 -->
<span v-if="item.url.___type == 'category'"> {{ item.url.name }}</span>
<!-- 当选择完链接之后的店铺回调 -->
<span v-if="item.url.___type == 'shops'"> {{ item.url.memberName }}</span>
<!-- 当选择完链接之后的其他回调 -->
<span v-if="item.url.___type == 'other'"> {{ item.url.title }}</span>
<!-- 当选择完活动之后的其他回调 -->
<span v-if="item.url.___type == 'marketing'">
<span v-if="item.url.___promotion == 'SECKILL'"> 秒杀 </span>
<span v-if="item.url.___promotion == 'FULL_DISCOUNT'"> 满减 </span>
<span v-if="item.url.___promotion == 'PINTUAN'"> 拼团 </span>
{{ item.url.title || item.url.goodsName }}
</span>
<!-- 当选择完活动之后的其他回调 -->
<span v-if="item.url.___type == 'pages'"> {{ item.url.title }}</span>
</span>
</div>
<div>
<Button ghost size="small" type="primary" @click="clickLink(item, index)"
>选择链接</Button
>
</div>
</div>
</div>
</div>
</div>
<Button
v-if="res.type != 'tpl_ad_list' && res.type != 'tpl_activity_list' && !res.notAdd"
type="primary"
@click="addDecorate()"
ghost
>添加</Button
>
<liliDialog
ref="liliDialog"
@selectedLink="selectedLink"
@selectedGoodsData="selectedGoodsData"
></liliDialog>
<Modal width="1200px" v-model="picModelFlag">
<ossManage @callback="callbackSelected" ref="ossManage" />
</Modal>
</div>
</template>
<script>
import ossManage from "@/views/sys/oss-manage/ossManage";
import { modelData } from "./config";
import ways from "@/views/lili-dialog/wap.js"; // 选择链接的类型
export default {
components: {
ossManage,
},
data() {
return {
ways, // 选择链接的类型
picModelFlag: false, //图片选择器
linkType: "goods", // dialog弹窗口类型
styleFlag: false, //广告魔方开关
selectedLinkIndex: "", //选择链接的索引
modelData, // 装修数据
selectedGoods: "", // 已选商品
selectedLinks: "", // 已选链接
modelList: "", // 装修列表
};
},
watch: {
res: {
handler: (val) => {},
deep: true,
},
},
props: ["res"],
methods: {
// 选择风格
selectStyle() {
this.styleFlag = !this.styleFlag;
},
// 回调选择的链接
selectedLink(val) {
this.selectedLinks.url = val;
},
// 回调的商品信息
selectedGoodsData(val) {
if (!val) return false;
let data = val.map((item) => {
delete item.selected;
delete item.intro;
delete item.mobileIntro;
return {
img: item.thumbnail,
title: item.goodsName,
type: this.selectedGoods.title,
___index: this.selectedGoods.___index,
...item,
};
});
this.res.options.list[0].listWay.push(...data);
this.linkType = "";
},
// 绑定商品
bindGoodsId(val) {
this.selectedGoods = val;
this.liliDialogFlag(true);
},
// 点击抽屉
clickDrawer(item, index) {
this.$emit("handleDrawer", item);
this.styleFlag = false;
},
// 打开图片选择器
liliDialogFlag(flag) {
this.$refs.liliDialog.goodsFlag = flag;
this.$refs.liliDialog.flag = true;
},
// 点击链接赋值一个唯一值,并将当前选择的模块赋值
clickLink(val, index) {
this.selectedLinks = val;
this.liliDialogFlag(false);
},
//点击图片解析成base64
changeFile(item, index) {
const file = document.getElementById("files" + index).files[0];
if (file == void 0) return false;
const reader = new FileReader();
reader.readAsDataURL(file);
this.$nextTick((res) => {
reader.onload = (e) => {
item.img = e.target.result;
};
});
},
//添加设置
addDecorate() {
let way = {
img: "https://picsum.photos/id/264/200/200",
title: "标题",
link: "",
url: "",
size: this.res.options.list[0]?.size,
};
this.res.options.list.push(way);
},
// 图片选择器回显
callbackSelected(val) {
this.picModelFlag = false;
this.selectedGoods.img = val.url;
},
// 点击选择图片
handleClickFile(item, index) {
// this.$refs.ossManage.selectImage = true;
this.selectedGoods = item;
this.picModelFlag = true;
},
// 关闭
closeDecorate(index) {
this.$nextTick(() => {
this.res.options.list.splice(index, 1);
});
},
},
};
</script>
<style scoped lang="scss">
@import "./decorate.scss";
</style>

View File

@@ -0,0 +1,17 @@
import index from './index.vue' //首页
import advertising from './advertising.vue' //全屏活动
import alertAdvertising from './alertAdvertising.vue' //弹窗活动
const templates = {
index,
advertising,
alertAdvertising
}
export default templates

View File

@@ -0,0 +1,213 @@
<template>
<div class="wrapper">
<!-- 拖拽栏 展示栏 -->
<div class="model-view">
<div class="model-view-menu">
<draggable
class="model-view-menu-item"
:list="modelData"
:move="handleMove"
v-bind="{
group: { name: 'model', pull: 'clone', put: false, animation: 150 },
sort: false,
ghostClass: 'ghost',
}"
>
<li
v-for="(model, index) in modelData"
v-if="!model.drawer"
:key="index"
class="model-item"
>
<img src alt />
<span>{{ model.name }}</span>
</li>
</draggable>
</div>
<div class="model-view-content">
<div class="content">
<div class="wap-title">首页</div>
<draggable
class="draggable"
group="model"
ghostClass="ghost"
@add="handleContentlAdd"
@end="handleContentlEnd"
v-model="contentData.list"
>
<div
class="list"
v-for="(element, index) in contentData.list"
:key="element.key"
>
<component
class="component"
:class="{ active: selected == index }"
@click.native="handleComponent(element, index)"
:is="templates[element.type]"
:res="element.options"
></component>
<Icon
v-if="selected == index"
@click="closeComponent(index)"
color="#e1251b"
size="25"
class="close"
type="ios-close-circle"
/>
</div>
</draggable>
</div>
</div>
<!-- 右侧栏 -->
<div class="model-config">
<decorate
@handleDrawer="handleDrawer"
v-if="decorateData"
:res="decorateData"
></decorate>
</div>
</div>
</div>
</template>
<script>
import templates from "./template/index";
import Draggable from "vuedraggable";
import { modelData } from "./config";
import decorate from "./decorate";
import * as API_Other from '@/api/other'
export default {
components: {
Draggable,
decorate,
},
data() {
return {
templates, // 模板类型
modelData, // 装修模型
qrcode: "", // 二维码
selected: 0, // 已选下标
contentData: { // 总数据
list: [],
},
decorateData: "", // 装修数据
};
},
watch: {
contentData: {
handler(val) {
this.$store.state.styleStore = val;
},
deep: true,
},
},
mounted() {
this.init();
},
methods: {
enableBindGoodsShow(){
},
// 初始化数据
init() {
if (!this.$route.query.id) return false;
API_Other.getHomeData(this.$route.query.id).then(res=>{
this.contentData = JSON.parse(res.result.pageData)
this.handleComponent( this.contentData.list[0], 0)
})
},
// 中间组件拖动,右侧数据绑定不变
handleContentlEnd(evt) {
const { newIndex } = evt;
this.handleComponent(this.contentData.list[newIndex], newIndex);
},
// 关闭楼层装修
closeComponent(index) {
this.$nextTick(() => {
this.decorateData = "";
console.log(this.contentData.list.length);
// 如果当前楼层不为一
if (this.contentData.list.length > 1) {
// 如果当前最底层 给下一层赋值
if (index - 1 == -1) {
this.handleComponent(this.contentData.list[index], index);
} else {
// 如果不是最底层给上一层赋值
this.handleComponent(this.contentData.list[index - 1], index - 1);
}
this.contentData.list.splice(index, 1);
} else {
this.contentData.list.splice(index, 1);
}
});
},
// 点击楼层装修
handleComponent(val, index) {
console.warn(val)
this.selected = index;
this.$set(this, "decorateData", val);
},
// 右侧栏回调
handleDrawer(val) {
let newIndex = this.selected;
this.decorateData = "";
this.$set(this.contentData.list, newIndex, {
...val,
options: {
...val.options,
},
// 绑定键值
model: val.type,
});
this.contentData.list = JSON.parse(JSON.stringify(this.contentData.list));
this.$set(this, "decorateData", this.contentData.list[newIndex]);
},
// 封装拖拽参数
package(val, newIndex) {
this.contentData.list[newIndex] = "";
val = JSON.parse(JSON.stringify(val));
this.$set(this.contentData.list, newIndex, {
...val,
options: {
...val.options,
},
// 绑定键值
model: val.type,
});
},
// 拖动
handleContentlAdd(evt) {
const { newIndex } = evt;
this.package(this.contentData.list[newIndex], newIndex);
this.handleComponent(this.contentData.list[newIndex], newIndex);
},
handleMove() {
return true;
},
},
};
</script>
<style scoped lang="scss">
@import "./style.scss";
</style>

View File

@@ -0,0 +1,39 @@
<template>
<div class="box">
<!-- 顶部栏 -->
<navbar @selected="selected" />
<component :is="layout[name]"></component>
</div>
</template>
<script>
import layout from "./index";
import navbar from "./navbar";
export default {
components: {
navbar,
},
data() {
return {
layout, // 装修模块
name: "index", // 装修的页面
};
},
methods: {
selected(val) { // 顶部栏点击切换
this.name = val;
}
}
};
</script>
<style scoped lang="scss">
.box {
height: calc(100vh - 120px);
width: 98%;
margin: 0 auto;
padding: 0 20px;
background: #fff;
border-radius: 0.4em;
overflow: hidden;
}
</style>

View File

@@ -0,0 +1,214 @@
<template>
<!-- 预览保存 -->
<div class="model-title">
<div>店铺装修</div>
<div class="btns">
<Button
@click="clickBtn(item)"
size="small"
v-for="(item, index) in way"
:key="index"
:type="item.selected ? 'primary' : ''"
>
{{ item.title }}
</Button>
</div>
<div class="model-title-view-btn">
<!-- TODO 后期会补全 目前版本暂无 -->
<!-- <Poptip placement="bottom" width="100">
<Button size="default" @click="creatQrCode">预览模板</Button>
<div slot="content" class="default-view-content">
<div>临时预览</div>
<div ref="qrCodeUrl"></div>
</div>
</Poptip> -->
<Button size="default" type="primary" @click="handleSpinShow">保存模板</Button>
<Modal
title="保存中"
v-model="saveDialog"
:closable="true"
:mask-closable="false"
:footer-hide="true"
>
<div v-if="progress">
<div class="model-item">
模板名称 <Input style="width: 200px" v-model="submitWay.name" />
</div>
<div class="model-item">
是否立即发布
<i-switch v-model="submitWay.pageShow">
<span slot="open"></span>
<span slot="close"></span>
</i-switch>
</div>
<Button type="primary" @click="save()">保存</Button>
</div>
<Progress v-else :percent="num" status="active" />
</Modal>
</div>
</div>
</template>
<script>
import * as API_Other from "@/api/other.js";
export default {
data() {
return {
progress: true, // 展示进度
num: 20, // 提交进度
saveDialog: false, // 加载状态
way: [
// 装修tab栏切换
{
title: "首页",
name: "index",
selected: true,
},
// {
// title: "全屏广告",
// name: "advertising",
// selected: false,
// },
// {
// title: "弹窗广告",
// name: "alertAdvertising",
// selected: false,
// },
],
submitWay: {
// 表单信息
pageShow: this.$route.query.type || false,
name: this.$route.query.name || "模板名称",
pageClientType: "H5",
},
};
},
watch: {},
mounted() {},
methods: {
clickBtn(val) {
this.way.forEach((item, index) => {
item.selected = false;
});
val.selected = true;
this.$emit("selected", val.name);
},
/**
* 加载,并保存模板
*/
handleSpinShow() {
this.saveDialog = true;
},
// 填写是否发布,模板名称之后保存
save() {
if (this.$store.state.styleStore == void 0) {
this.$Message.error("请装修楼层");
return false;
}
this.submitWay?.pageShow === true
? (this.submitWay.pageShow = "OPEN")
: (this.submitWay.pageShow = "CLOSE");
this.submitWay.pageData = JSON.stringify(this.$store.state.styleStore);
this.submitWay.pageType = "STORE";
this.$route.query.id ? this.update() : this.submit(this.submitWay);
},
// 更新
update() {
this.progress = false;
API_Other.updateHome(this.$route.query.id, {
pageData: JSON.stringify(this.$store.state.styleStore),
name: this.submitWay.name,
pageShow: this.submitWay.pageShow,
pageType: "STORE",
pageClientType: "H5",
})
.then((res) => {
this.num = 50;
if (res.success) {
this.num = 80;
/**制作保存成功动画¸ */
setTimeout(() => {
this.saveDialog = false;
this.$Message.success("修改成功");
this.goback();
}, 1000);
} else {
this.saveDialog = false;
this.$Message.error("修改失败,请稍后重试");
}
console.log(res);
})
.catch((error) => {});
},
// 返回查询数据页面
goback() {
this.$router.push({
path: "/shop/wapList",
});
},
// 保存
submit(submitWay) {
this.progress = false;
API_Other.setHomeSetup(submitWay)
.then((res) => {
this.num = 50;
if (res.success) {
this.num = 80;
/**制作保存成功动画¸ */
setTimeout(() => {
this.saveDialog = false;
this.$Message.success("保存成功");
this.goback();
}, 1000);
} else {
this.progress = true;
this.saveDialog = false;
this.$Message.error("保存失败,请稍后重试");
}
console.log(res);
})
.catch((error) => {});
},
},
};
</script>
<style scoped lang="scss">
.model-item {
width: 100%;
padding: 10px 0;
display: flex;
align-items: center;
> * {
margin: 0 8px;
}
}
.model-title {
height: 70px;
display: flex;
justify-content: space-between;
align-items: center;
color: #333;
font-size: 14px;
> .model-title-view-btn {
> * {
margin: 0 10px;
}
}
}
.btns {
* {
margin: 0 4px;
}
}
</style>

View File

@@ -0,0 +1,98 @@
.model-view {
display: flex;
.model-view-menu {
flex: 1.5;
min-width: 250px;
> .model-view-menu-item {
display: flex;
align-items: center;
flex-wrap: wrap;
}
}
.model-config {
flex: 2.5;
}
.model-view-content {
flex: 6;
}
.model-item {
line-height: 1.75;
font-size: 13px;
margin: 0 5px 10px 5px;
border: 1px solid #ededed;
background: #f6f6f9;
width: 70px;
height: 70px;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
}
.model-view-content {
background: #f6f6f9;
border-radius: 0.8em;
display: flex;
justify-content: flex-start;
align-items: center;
flex-direction: column;
}
.wap-title {
line-height: 44px;
text-align: center;
height: 44px;
border-bottom: 1px solid #ededed;
}
.content {
margin: 20px 0;
padding: 50px 13px;
width: 360px;
background: url("../../../assets/iPhoneX_model.png") no-repeat;
height: 780px;
background-size: 360px;
overflow: hidden;
> .component,
.draggable {
height: 590px;
overflow-y: auto;
background: #ebebeb;
}
> .draggable {
padding-bottom: 100px;
}
}
.list {
position: relative;
}
.close {
position: absolute;
right: 5px;
top: 10px;
z-index: 99;
}
.model-btn {
> * {
margin: 0 4px;
}
}
.qrCode {
width: 100px;
height: 100px;
}
.default-view-content {
text-align: center;
font-weight: bold;
line-height: 2;
/deep/ img {
margin: 0 auto;
}
}
.model-config {
overflow-y: auto;
}
.active {
box-sizing: border-box;
border: 1px solid $theme_color;
}

View File

@@ -0,0 +1,57 @@
.position-box{
position: absolute;
right: 0;
bottom: 0;
}
.join-box {
display: flex;
}
.item-price {
> span {
font-size: 15px;
font-weight: 500;
color: #e1212b;
}
}
.join-item {
flex: 1;
}
.item-img {
width: 75px;
height: 75px;
margin: 0 auto;
display: block;
}
.item-img-box {
position: relative;
}
.item-line-through {
> span {
font-size: 10px;
font-weight: 400;
text-decoration: line-through;
color: #999;
}
}
.item-position-tips {
position: absolute;
right: 0;
color: #fff;
font-size: 12px;
bottom: 0;
}
.join-title {
display: flex;
justify-content: space-between;
align-items: center;
background: #fff;
height: 50px;
> div:nth-of-type(1) {
font-size: 16px;
font-weight: bold;
}
> div:nth-of-type(2) {
font-size: 12px;
color: #999;
}
}

View File

@@ -0,0 +1,44 @@
import tpl_banner from "./tpl_banner";
import tpl_title from "./tpl_title";
import tpl_left_one_right_two from "./tpl_left_one_right_two";
import tpl_left_two_right_one from "./tpl_left_two_right_one";
import tpl_top_one_bottom_two from "./tpl_top_one_bottom_two";
import tpl_top_two_bottom_one from "./tpl_top_two_bottom_one";
import tpl_flex_one from "./tpl_flex_one";
import tpl_flex_two from "./tpl_flex_two";
import tpl_flex_three from "./tpl_flex_three";
import tpl_flex_five from "./tpl_flex_five";
import tpl_flex_four from "./tpl_flex_four";
import tpl_text_picture from "./tpl_text_picture";
import tpl_menu from "./tpl_menu";
import tpl_search from "./tpl_search";
import tpl_join_group from "./tpl_join_group";
import tpl_integral from "./tpl_integral";
import tpl_spike from "./tpl_spike";
import tpl_group from "./tpl_group";
import tpl_ad_list from "./tpl_view_list";
import tpl_activity_list from './tpl_view_list'
import tpl_goods from "./tpl_goods";
export default {
carousel: tpl_banner,
title: tpl_title,
leftOneRightTwo: tpl_left_one_right_two,
leftTwoRightOne: tpl_left_two_right_one,
topOneBottomTwo:tpl_top_one_bottom_two,
topTwoBottomOne:tpl_top_two_bottom_one,
flexThree: tpl_flex_three,
flexFive: tpl_flex_five,
flexFour: tpl_flex_four,
flexTwo: tpl_flex_two,
textPicture: tpl_text_picture,
menu: tpl_menu,
search: tpl_search,
joinGroup: tpl_join_group,
flexOne: tpl_flex_one,
goods: tpl_goods,
integral:tpl_integral,
spike:tpl_spike,
group:tpl_group,
tpl_ad_list,
tpl_activity_list
};

View File

@@ -0,0 +1,31 @@
.image-mode {
width: 100%;
height: 100%;
display: block;
padding: 1px;
}
.layout {
padding: 8px;
margin: 4px 0;
background: #fff;
}
.layout,
.view-height-75,
.view-height-150 {
overflow: hidden;
}
.view-width-100{
width: 100%;
}
.view-height-75 {
height: 75px;
}
.view-height-150 {
height: 150px;
flex: 1;
}
.view-height-85 {
height: 85px;
flex: 1;
}

View File

@@ -0,0 +1,32 @@
<template>
<div class="layout">
<Carousel class="carousel" v-if="res" autoplay :autoplay-speed="5000">
<CarouselItem v-for="(item, index) in res.list" :key="index">
<div>
<img class="image-mode" :src="item.img" />
</div>
</CarouselItem>
</Carousel>
</div>
</template>
<script>
export default {
title: "导航栏",
props: ["res"],
watch: {
res: {
handler(newValue, oldValue) {
this.$set(this,'res',newValue);
},
deep: true
}
}
};
</script>
<style lang="scss" scoped>
@import "./tpl.scss";
.carousel,
.image-mode {
height: 150px;
}
</style>

View File

@@ -0,0 +1,30 @@
<template>
<div class="layout">
<img class="image-mode" :src="res.list[0].img" alt="">
<img class="image-mode" :src="res.list[1].img" alt="">
<img class="image-mode" :src="res.list[2].img" alt="">
<img class="image-mode" :src="res.list[3].img" alt="">
<img class="image-mode" :src="res.list[4].img" alt="">
</div>
</template>
<script>
export default {
title: "五列单行图片模块",
props: ["res"],
};
</script>
<style lang="scss" scoped>
@import "./tpl.scss";
.layout {
background: #e8e8e8;
display: flex;
align-items: center;
justify-content: center;
background-size: cover;
}
img {
width: 67px !important;
}
</style>

View File

@@ -0,0 +1,33 @@
<template>
<div class="layout">
<img class="image-mode" :src="res.list[0].img" alt="">
<img class="image-mode" :src="res.list[1].img" alt="">
<img class="image-mode" :src="res.list[2].img" alt="">
<img class="image-mode" :src="res.list[3].img" alt="">
</div>
</template>
<script>
export default {
title: "四列单行图片模块",
props: ["res"],
};
</script>
<style lang="scss" scoped>
@import "./tpl.scss";
.layout {
// background: #e8e8e8;
// height: 84px;
display: flex;
padding: 0 8px;
align-items: center;
justify-content: center;
background-size: cover;
}
img{
width: 84px !important;
}
</style>

View File

@@ -0,0 +1,25 @@
<template>
<div class="layout">
<div class="flex-one">
<img :src="res.list[0].img" alt="">
</div>
</div>
</template>
<script>
export default {
props: ['res']
}
</script>
<style lang="scss" scoped>
@import './tpl.scss';
.flex-one{
width: 100%;
display: block;
height: 110px;
overflow: hidden;
>img{
width: 100%;
height: 100%;
}
}
</style>

View File

@@ -0,0 +1,29 @@
<template>
<div class="layout">
<img class="image-mode" :src="res.list[0].img" alt="">
<img class="image-mode" :src="res.list[1].img" alt="">
<img class="image-mode" :src="res.list[2].img" alt="">
</div>
</template>
<script>
export default {
title: "三列单行图片模块",
props: ["res"],
};
</script>
<style lang="scss" scoped>
@import "./tpl.scss";
.layout {
background: #e8e8e8;
height: 110px;
display: flex;
align-items: center;
justify-content: center;
background-size: cover;
}
img{
width: 111px !important;
}
</style>

Some files were not shown because too many files have changed in this diff Show More