Commit 171cb86a authored by GuanHua's avatar GuanHua

fix: 店铺装修火狐浏览器上显示问题

parent f75e0a78
...@@ -100,6 +100,10 @@ export enum LAYOUT_TYPE { ...@@ -100,6 +100,10 @@ export enum LAYOUT_TYPE {
* 企业商城 * 企业商城
*/ */
mall = 'mall', mall = 'mall',
/**
* 自营商城
*/
own = 'own',
/** /**
* 店铺(店铺商城) * 店铺(店铺商城)
*/ */
......
import { ComponentSchemaType, PROPS_TYPES } from '@lingxi-disign/core';
const MallHeader: ComponentSchemaType = {
propsConfig: {
children: {
label: '文本内容',
type: PROPS_TYPES.string,
},
},
};
export default MallHeader;
import { ComponentSchemaType, PROPS_SETTING_TYPES } from '@lingxi-disign/core';
const OwnMainNav: ComponentSchemaType = {
propsConfig: {
componentType: {
label: '广告编辑',
type: PROPS_SETTING_TYPES.advert
},
sliderList: {
label: '广告编辑',
type: PROPS_SETTING_TYPES.carousel,
},
},
};
export default OwnMainNav;
import { ComponentSchemaType, PROPS_SETTING_TYPES } from '@lingxi-disign/core';
const OwnMainNav: ComponentSchemaType = {
propsConfig: {
componentType: {
label: '导航朗编辑',
type: PROPS_SETTING_TYPES.mallNav
},
},
};
export default OwnMainNav;
...@@ -55,6 +55,10 @@ import ChannelHeaderNav from './ChannelHeaderNav' ...@@ -55,6 +55,10 @@ import ChannelHeaderNav from './ChannelHeaderNav'
import InformationCard from './InformationCard' import InformationCard from './InformationCard'
import SuggestProduct from './SuggestProduct' import SuggestProduct from './SuggestProduct'
import OwnBanner from './OwnBanner'
import MallHeader from './MallHeader'
import OwnMainNav from './OwnMainNav'
export default { export default {
View, View,
TopBar, TopBar,
...@@ -103,4 +107,7 @@ export default { ...@@ -103,4 +107,7 @@ export default {
...ChannelHeaderNav, ...ChannelHeaderNav,
InformationCard, InformationCard,
...SuggestProduct, ...SuggestProduct,
OwnBanner,
MallHeader,
OwnMainNav,
} }
.mobileSettingPanel { .mobileSettingPanel {
height: 100%; // height: 100%;
overflow-y: auto; overflow-y: auto;
background-color: #FFF; background-color: #FFF;
transition: width .25s; transition: width .25s;
......
...@@ -7,7 +7,7 @@ export const mallLayoutConfig = { ...@@ -7,7 +7,7 @@ export const mallLayoutConfig = {
"style": { "style": {
"width": "100%", "width": "100%",
"minHeight": "100%", "minHeight": "100%",
"background": "#FFF" "background": "#F5F6F7"
} }
}, },
"childNodes": ["1", "3", "4", "5"] "childNodes": ["1", "3", "4", "5"]
...@@ -39,10 +39,10 @@ export const topAdvertConfig = { ...@@ -39,10 +39,10 @@ export const topAdvertConfig = {
export const headerConfig = { export const headerConfig = {
key: "3", key: "3",
"3": { "3": {
"componentName": "ShopHeader", "componentName": "MallHeader",
"props": { "props": {
"shopInfo": {}, "logoUrl": "",
"logoUrl": "" type: 'own'
}, },
}, },
} }
...@@ -50,61 +50,102 @@ export const headerConfig = { ...@@ -50,61 +50,102 @@ export const headerConfig = {
export const mainNavConfig = { export const mainNavConfig = {
key: "4", key: "4",
"4": { "4": {
"componentName": "MainNav", "componentName": "OwnMainNav",
"props": { "props": {
}, },
}, },
} }
export const bannerAdvertConfig = { export const bannerWrap = {
key: "5", key: "5",
"5": { "5": {
"componentName": "ShopAdvert", "componentName": "View",
"props": {
style: {
display: 'flex',
justifyContent: 'flex-end',
width: '1200px',
margin: '0 auto',
marginTop: 16
}
},
"childNodes": ["6", "7"]
},
}
export const oneBannerConfig = {
key: "6",
"6": {
"componentName": "OwnBanner",
"props": { "props": {
"type": "banner", type: 1,
"linkdisable": true, "linkdisable": true,
"advertList": [] advertList: []
} },
}, },
} }
export const serviceAdvertConfig = { export const bannerColumnWrap = {
key: "16", key: "7",
"16": { "7": {
"componentName": "ShopAdvert", "componentName": "View",
"props": {
style: {
display: 'flex',
flexDirection: 'column',
marginLeft: 16,
}
},
"childNodes": ["8", "9"]
},
}
export const twoBannerConfig = {
key: "8",
"8": {
"componentName": "OwnBanner",
"props": { "props": {
"type": "service", type: 2,
"linkdisable": true, "linkdisable": true,
"advertList": [] advertList: []
} },
}, },
} }
export const CompanyInfoConfig = { export const threeBannerConfig = {
key: "18", key: "9",
"18": { "9": {
"componentName": "CompanyInfo", "componentName": "OwnBanner",
"props": {}, "props": {
type: 3,
"linkdisable": true,
advertList: []
},
}, },
} }
export const AlbumConfig = { export const fourBannerConfig = {
key: "19", key: "16",
"19": { "16": {
"componentName": "Album", "componentName": "OwnBanner",
"props": {}, "props": {
"type": 4,
"linkdisable": true,
"advertList": []
}
}, },
} }
export const HonroPicConfig = { export const InformationConfig = {
key: "20", key: '20',
"20": { "20": {
"componentName": "HonroPic", "componentName": "Information",
"props": {}, "props": {},
}, },
} }
export const FooterConfig = { export const FooterConfig = {
key: '21', key: '21',
"21": { "21": {
......
export const menuData = [ export const menuData = [
{ {
"path": "/shop", "link": "/",
"name": "首页", "name": "首页",
"key": "shopHome", "key": "Home",
type: 1,
status: true,
}, },
{ {
"path": "/shop/commodity", "link": "/commodity",
"name": "现货商品", "name": "现货商品",
"key": "shopCommodity", "key": "commodity",
type: 2,
status: true,
}, },
{ {
"path": "/shop/pointsMall", "link": "/inquery",
"name": "询价商品", "name": "询价商品",
"key": "shopPointsMall", "key": "inquery",
type: 3,
status: true,
}, },
{ {
"path": "/shop/infomation", "link": "/points",
"name": "积分兑换", "name": "积分兑换",
"key": "shopInfomation", "key": "points",
type: 4,
status: true,
}, },
{ {
"path": "/shop/about", "link": "/infomation",
"name": "行情资讯",
"key": "infomation",
type: 6,
status: true,
},
{
"link": "/about",
"name": "关于我们", "name": "关于我们",
"key": "shopAbout", "key": "about",
type: 5,
status: true,
}, },
] ]
...@@ -5,8 +5,23 @@ import ToolBar from '../components/toolBar' ...@@ -5,8 +5,23 @@ import ToolBar from '../components/toolBar'
import DesignPanel from '../components/DesignPanel' import DesignPanel from '../components/DesignPanel'
import SettingPanel from '../settingsPanel' import SettingPanel from '../settingsPanel'
import config from '../configs' import config from '../configs'
import { isEmpty } from 'lodash'
import { LAYOUT_TYPE } from '@/constants' import { LAYOUT_TYPE } from '@/constants'
import { topBarConfig, topAdvertConfig, headerConfig, mainNavConfig, bannerAdvertConfig, mallLayoutConfig, serviceAdvertConfig, CompanyInfoConfig, AlbumConfig, HonroPicConfig, FooterConfig } from './defaultData' import {
topBarConfig,
topAdvertConfig,
headerConfig,
mainNavConfig,
bannerWrap,
oneBannerConfig,
bannerColumnWrap,
twoBannerConfig,
threeBannerConfig,
mallLayoutConfig,
fourBannerConfig,
InformationConfig,
FooterConfig,
} from './defaultData'
import { menuData } from './defaultMenu' import { menuData } from './defaultMenu'
import Loading from '../components/Loading' import Loading from '../components/Loading'
import { PublicApi } from '@/services/api' import { PublicApi } from '@/services/api'
...@@ -35,76 +50,56 @@ const TemplateList = ['science'] ...@@ -35,76 +50,56 @@ const TemplateList = ['science']
const OwnMallEdit: React.FC<ShopEditPropsType> = (props) => { const OwnMallEdit: React.FC<ShopEditPropsType> = (props) => {
const { query: { id, template, shopId } } = props.location const { query: { id, template, shopId } } = props.location
const [loading, setLoading] = useState<boolean>(true) const [loading, setLoading] = useState<boolean>(true)
const [theme, setTheme] = useState<string>('theme-shop-science') const [theme, setTheme] = useState<string>('theme-ownmall-science')
const [componentConfigs, setComponentConfigs] = useState({}) const [componentConfigs, setComponentConfigs] = useState({})
const { memberId, memberRoleId } = getAuth() || {} const { memberId, memberRoleId } = getAuth() || {}
useEffect(() => { useEffect(() => {
if (!TemplateList.includes(template)) { if (!TemplateList.includes(template)) {
setTheme(`theme-shop-${TemplateList[0]}`) setTheme(`theme-ownmall-${TemplateList[0]}`)
} else { } else {
setTheme(`theme-shop-${template}`) setTheme(`theme-ownmall-${template}`)
} }
getComponentsConfig() getComponentsConfig()
}, []) }, [])
const findFirstAdvertsByType = () => { /**
* 获取所有一级品类信息
*/
const fetchFirstCategory = () => {
return new Promise((resolve) => { return new Promise((resolve) => {
const params: any = { const param: any = {
templateId: id,
type: 1,
memberId, memberId,
roleId: memberRoleId roleId: memberRoleId
} }
const headers: any = {
PublicApi.getTemplateAdornWebStoreFindAdvertsByType(params).then(res => { shopId
if (res.code === 1000) {
resolve(res.data)
} else {
resolve([])
}
})
})
}
const findSecondAdvertsByType = () => {
return new Promise((resolve) => {
const params: any = {
templateId: id,
type: 3,
memberId,
roleId: memberRoleId
} }
PublicApi.getTemplateAdornWebSelfFindAllFirstCategory(param, { headers }).then(res => {
PublicApi.getTemplateAdornWebStoreFindAdvertsByType(params).then(res => {
if (res.code === 1000) { if (res.code === 1000) {
resolve(res.data) resolve(res.data)
} else {
resolve([])
} }
}) })
}) })
} }
/** /**
* 获取所有一级品类信息 * 获取导航栏菜单数据
*/ */
const fetchFirstCategory = () => { const getOwnMallNavData = () => {
return new Promise((resolve) => { return new Promise((resolve) => {
const param: any = { const param: any = {
templateId: id,
memberId, memberId,
roleId: memberRoleId roleId: memberRoleId,
} };
const headers: any = { PublicApi.getTemplateAdornWebSelfFindColumn(param).then(res => {
shopId
}
PublicApi.getTemplateAdornWebStoreFindAllFirstCategory(param, { headers }).then(res => {
if (res.code === 1000) { if (res.code === 1000) {
resolve(res.data) resolve(res.data);
} }
}) });
}) });
} };
/** /**
* 获取一级品类详细信息 * 获取一级品类详细信息
...@@ -118,7 +113,7 @@ const OwnMallEdit: React.FC<ShopEditPropsType> = (props) => { ...@@ -118,7 +113,7 @@ const OwnMallEdit: React.FC<ShopEditPropsType> = (props) => {
roleId: memberRoleId roleId: memberRoleId
} }
PublicApi.getTemplateAdornWebStoreMemberCategoryAdorn(param).then(res => { PublicApi.getTemplateAdornWebSelfMemberCategoryAdorn(param).then(res => {
if (res.code === 1000) { if (res.code === 1000) {
resolve(res.data) resolve(res.data)
} }
...@@ -126,47 +121,67 @@ const OwnMallEdit: React.FC<ShopEditPropsType> = (props) => { ...@@ -126,47 +121,67 @@ const OwnMallEdit: React.FC<ShopEditPropsType> = (props) => {
}) })
} }
/** const findAdvertsByType = (type: number) => {
* 获取店铺信息
*/
const fetchShopInfo = (shopId: number) => {
return new Promise((resolve) => { return new Promise((resolve) => {
const param: any = { const params: any = {
templateId: id,
type,
memberId, memberId,
roleId: memberRoleId, roleId: memberRoleId
shopId,
} }
PublicApi.getTemplateWebMemberShopWebMemberShopMain(param).then(res => {
PublicApi.getTemplateAdornWebSelfFindAdvertsByType(params).then(res => {
if (res.code === 1000) { if (res.code === 1000) {
if (res.code === 1000) { resolve(res.data)
resolve(res.data) } else {
} resolve([])
} }
}) })
}) })
} }
// const getCategoryTree = () => {
// return new Promise((resolve) => {
// const param: any = {
// templateId: id,
// categoryId,
// memberId,
// roleId: memberRoleId
// }
// PublicApi.getTemplateAdornWebSelfMemberCategoryAdorn(param).then(res => {
// if (res.code === 1000) {
// resolve(res.data)
// }
// })
// })
// }
const getComponentsConfig = async () => { const getComponentsConfig = async () => {
// 导航栏 // 导航栏
mainNavConfig[mainNavConfig.key].props.menuData = menuData const navData = await getOwnMallNavData();
if(!isEmpty(navData)) {
mainNavConfig[mainNavConfig.key].props.menuData = navData;
} else {
mainNavConfig[mainNavConfig.key].props.menuData = menuData;
}
mainNavConfig[mainNavConfig.key].props.type = LAYOUT_TYPE.shop mainNavConfig[mainNavConfig.key].props.type = LAYOUT_TYPE.shop
mainNavConfig[mainNavConfig.key].props.categoryList = [] mainNavConfig[mainNavConfig.key].props.categoryList = []
// 一号位广告 // 一号位广告
bannerAdvertConfig[bannerAdvertConfig.key].props.advertList = await findFirstAdvertsByType() oneBannerConfig[oneBannerConfig.key].props.advertList = await findAdvertsByType(1)
// 二号位广告 // 二号位广告
serviceAdvertConfig[serviceAdvertConfig.key].props.advertList = await findSecondAdvertsByType() twoBannerConfig[twoBannerConfig.key].props.advertList = await findAdvertsByType(2)
//店铺信息 // 三号位广告
threeBannerConfig[threeBannerConfig.key].props.advertList = await findAdvertsByType(3)
// 四号位广告
fourBannerConfig[fourBannerConfig.key].props.advertList = await findAdvertsByType(4)
//商城信息
const shopList = GlobalConfig.web.shopInfo const shopList = GlobalConfig.web.shopInfo
const webMallInfo = shopList.filter(item => item.environment === 1 && item.type === 1)[0] const webMallInfo = shopList.filter(item => item.id === Number(shopId))[0]
const shopInfo: any = await fetchShopInfo(webMallInfo.id)
headerConfig[headerConfig.key].props.shopInfo = shopInfo
headerConfig[headerConfig.key].props.logoUrl = webMallInfo.logoUrl
topBarConfig[topBarConfig.key].props.shopname = webMallInfo.name topBarConfig[topBarConfig.key].props.shopname = webMallInfo.name
headerConfig[headerConfig.key].props.logoUrl = webMallInfo.logoUrl
CompanyInfoConfig[CompanyInfoConfig.key].props.shopInfo = shopInfo || {}
AlbumConfig[AlbumConfig.key].props.workshopPics = shopInfo.workshopPics || []
HonroPicConfig[HonroPicConfig.key].props.honorPics = shopInfo.honorPics || []
// AboutUsConfig[AboutUsConfig.key].props.shopInfo = shopInfo // AboutUsConfig[AboutUsConfig.key].props.shopInfo = shopInfo
let initIndex = 100 let initIndex = 100
let floorLineConfig: any = {} let floorLineConfig: any = {}
...@@ -221,19 +236,21 @@ const OwnMallEdit: React.FC<ShopEditPropsType> = (props) => { ...@@ -221,19 +236,21 @@ const OwnMallEdit: React.FC<ShopEditPropsType> = (props) => {
} }
mallLayoutConfig["0"].childNodes = [...mallLayoutConfig["0"].childNodes, ...floorLineKeys, serviceAdvertConfig.key, CompanyInfoConfig.key, AlbumConfig.key, HonroPicConfig.key, FooterConfig.key] mallLayoutConfig["0"].childNodes = [...mallLayoutConfig["0"].childNodes, ...floorLineKeys, fourBannerConfig.key, FooterConfig.key]
const config = { const config = {
...mallLayoutConfig, ...mallLayoutConfig,
...topBarConfig, ...topBarConfig,
...topAdvertConfig, ...topAdvertConfig,
...headerConfig, ...headerConfig,
...mainNavConfig, ...mainNavConfig,
...bannerAdvertConfig, ...bannerWrap,
...oneBannerConfig,
...bannerColumnWrap,
...twoBannerConfig,
...threeBannerConfig,
...floorLineConfig, ...floorLineConfig,
...serviceAdvertConfig, ...fourBannerConfig,
...CompanyInfoConfig, // ...InformationConfig,
...AlbumConfig,
...HonroPicConfig,
...FooterConfig ...FooterConfig
} }
setComponentConfigs(config) setComponentConfigs(config)
...@@ -255,7 +272,7 @@ const OwnMallEdit: React.FC<ShopEditPropsType> = (props) => { ...@@ -255,7 +272,7 @@ const OwnMallEdit: React.FC<ShopEditPropsType> = (props) => {
</div> </div>
</div> </div>
</div> </div>
<SettingPanel templateId={id} type="shop" /> <SettingPanel templateId={id} type={LAYOUT_TYPE.own} />
</BrickProvider> </BrickProvider>
) : <Loading /> ) : <Loading />
} }
......
...@@ -6,7 +6,7 @@ import SettingPanel from '../../../../components/SettingPanel' ...@@ -6,7 +6,7 @@ import SettingPanel from '../../../../components/SettingPanel'
import { message, Modal } from 'antd' import { message, Modal } from 'antd'
import { isEmpty } from '@formily/antd/esm/shared' import { isEmpty } from '@formily/antd/esm/shared'
import { PublicApi } from '@/services/api' import { PublicApi } from '@/services/api'
import { clearSelectedStatus, changeProps } from '@lingxi-disign/core'; import { clearSelectedStatus, changeProps, produce } from '@lingxi-disign/core';
import { ArrowUpOutlined, DeleteOutlined, PlusOutlined, ArrowDownOutlined, CaretDownOutlined, CaretUpOutlined } from '@ant-design/icons' import { ArrowUpOutlined, DeleteOutlined, PlusOutlined, ArrowDownOutlined, CaretDownOutlined, CaretUpOutlined } from '@ant-design/icons'
import { addTempalteIdToList } from '../../../../utils' import { addTempalteIdToList } from '../../../../utils'
import styles from './index.less' import styles from './index.less'
...@@ -56,10 +56,10 @@ interface AdvertItemType { ...@@ -56,10 +56,10 @@ interface AdvertItemType {
interface AdvertSettingPropsType { interface AdvertSettingPropsType {
advertList: AdvertItemType[]; advertList: AdvertItemType[];
onChange: Function; onChange: Function;
type: 'top' | 'banner' | 'interact' | 'category' | 'service'; type: 'top' | 'banner' | 'interact' | 'category' | 'service' | number;
templateid: number; templateid: number;
categoryid?: number; categoryid?: number;
templateType: 'channel' | 'shop' templateType: 'channel' | 'shop' | 'own'
} }
const AdvertSetting: React.FC<AdvertSettingPropsType> = forwardRef((props, ref) => { const AdvertSetting: React.FC<AdvertSettingPropsType> = forwardRef((props, ref) => {
...@@ -80,6 +80,14 @@ const AdvertSetting: React.FC<AdvertSettingPropsType> = forwardRef((props, ref) ...@@ -80,6 +80,14 @@ const AdvertSetting: React.FC<AdvertSettingPropsType> = forwardRef((props, ref)
return "500*90" return "500*90"
case 'service': case 'service':
return "580*90" return "580*90"
case 1:
return "496*496"
case 2:
return "480*248"
case 3:
return "232*232"
case 4:
return "592*90"
} }
} }
...@@ -124,7 +132,7 @@ const AdvertSetting: React.FC<AdvertSettingPropsType> = forwardRef((props, ref) ...@@ -124,7 +132,7 @@ const AdvertSetting: React.FC<AdvertSettingPropsType> = forwardRef((props, ref)
const tempItem: any = { const tempItem: any = {
templateId: Number(templateid), templateId: Number(templateid),
type: getAdvertType(type), type: templateType !== 'own' ? getAdvertType(type) : type,
name: '', name: '',
picUrl: '', picUrl: '',
link: '', link: '',
...@@ -196,18 +204,19 @@ const AdvertSetting: React.FC<AdvertSettingPropsType> = forwardRef((props, ref) ...@@ -196,18 +204,19 @@ const AdvertSetting: React.FC<AdvertSettingPropsType> = forwardRef((props, ref)
return return
} }
setConfirmLoading(true) setConfirmLoading(true)
const newParam: any = JSON.parse(JSON.stringify(newProps))
newParam.advertList = newParam.advertList.map((item) => {
console.log(item.link, "item.link")
if (item.link && !item.link.startsWith('http://') && !item.link.startsWith('https://')) {
item.link = `http://${item.link}`
}
return item
})
const newParam: any = produce(newProps, (oldNewProps) => {
oldNewProps.advertList.map((item) => {
if (item.link && !item.link.startsWith('http://') && !item.link.startsWith('https://')) {
item.link = `http://${item.link}`
}
return item
})
return oldNewProps
})
saveAdvert(newParam).then(() => { saveAdvert(newParam).then(() => {
changeProps({ changeProps({
props: newParam props: {...newParam}
}) })
clearSelectedStatus() clearSelectedStatus()
setConfirmLoading(false) setConfirmLoading(false)
...@@ -247,18 +256,21 @@ const AdvertSetting: React.FC<AdvertSettingPropsType> = forwardRef((props, ref) ...@@ -247,18 +256,21 @@ const AdvertSetting: React.FC<AdvertSettingPropsType> = forwardRef((props, ref)
const saveAdvert = (data: any) => { const saveAdvert = (data: any) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const { advertList, type } = data const { advertList, type } = data
if (!checkAdvertList(advertList)) { if (!checkAdvertList(advertList)) {
reject() reject()
return return
} }
const param: any = { const param: any = {
templateId: templateid, templateId: templateid,
type: getAdvertType(type), type: templateType !== 'own' ? getAdvertType(type) : type,
adverts: addTempalteIdToList(advertList, templateid) adverts: addTempalteIdToList(advertList, templateid)
} }
let postFn; let postFn;
if (templateType === 'channel') { if (templateType === 'channel') {
postFn = PublicApi.postTemplateAdornWebChannelSaveAdvert postFn = PublicApi.postTemplateAdornWebChannelSaveAdvert
} else if(templateType === 'own') {
postFn = PublicApi.postTemplateAdornWebSelfSaveAdvert
} else { } else {
postFn = PublicApi.postTemplateAdornWebStoreSaveAdvert postFn = PublicApi.postTemplateAdornWebStoreSaveAdvert
} }
......
.mall_nav {
&_title {
background-color: #F7F8FA;
}
ul {
display: flex;
padding: 0;
margin: 0;
&.hasBorder {
border-bottom: 1px solid #F4F5F7;
&>li {
height: 48px;
line-height: 48px;
}
}
&>li {
list-style: none;
height: 40px;
line-height: 40px;
padding-left: 8px;
font-size: 12px;
color: #909399;
font-weight: 500;
}
}
.mall_nav_list_btn {
margin-left: 16px;
width: 16px;
&_icon {
width: 16px;
height: 16px;
}
}
.width160 {
width: 160px;
}
.width392 {
width: 392px;
}
.width96 {
width: 96px;
}
.width120 {
width: 120px;
}
}
import React, { useState, useCallback , useEffect } from 'react';
import { Modal, Checkbox, Button } from 'antd';
import { clearSelectedStatus, changeProps, produce } from '@lingxi-disign/core';
import { ReactSortable } from "react-sortablejs"
;
import { PublicApi } from '@/services/api';
import isEmpty from 'lodash/isEmpty';
import { LAYOUT_TYPE } from '@/constants';
import cx from 'classnames';
import { cloneDeep, isEqual } from 'lodash';
import upIcon from '@/assets/icons/up_icon.png';
import downIcon from '@/assets/icons/down_icon.png';
import sortIcon from '@/assets/icons/sort_icon.png';
import styles from './index.less';
import SettingPanel from '../../../../components/SettingPanel';
interface MenuItemType {
id: number,
name: string,
link: string,
status: boolean
}
interface MallNavProps {
templateid: number,
menuData: MenuItemType[],
type: LAYOUT_TYPE
}
const MallNav: React.FC<MallNavProps> = (props) => {
const { menuData, templateid, type } = props;
const [list, setList] = useState<MenuItemType[]>([]);
const [confirmLoading, setConfirmLoading] = useState<boolean>(false);
const [newProps, setNewProps] = useState(props);
useEffect(() => {
if (!isEmpty(menuData)) {
const newList: MenuItemType[] = cloneDeep(menuData);
newList.shift();
if (newList) {
setList(newList.map(((item, index) => {
item.id = index;
return item;
})));
}
}
}, [menuData]);
const changeNewProps = (key: string, data: any) => {
const newProps = { ...props };
newProps[key] = data;
setNewProps(newProps);
};
/**
* 保存导航
*/
const saveNav = (data: any) => {
return new Promise((resolve, reject) => {
const { menuData } = data;
const param: any = {
templateId: templateid,
columnBOList: menuData.map((item) => {
return {
name: item.name,
link: item.link,
status: item.status
};
})
};
PublicApi.postTemplateAdornWebSelfSaveColumn(param).then(res => {
if (res.code === 1000) {
resolve(true);
} else {
reject();
}
});
});
};
/**
* 确认
*/
const handleConfirm = (e) => {
e.preventDefault();
if (JSON.stringify(props) === JSON.stringify(newProps)) {
return;
}
setConfirmLoading(true);
if (type === LAYOUT_TYPE.own) {
changeProps({
props: newProps
});
clearSelectedStatus();
} else {
saveNav(newProps).then(() => {
changeProps({
props: newProps
});
clearSelectedStatus();
setConfirmLoading(false);
}).catch(() => {
setConfirmLoading(false);
});
}
};
const sortUp = (index: number, item: MenuItemType) => {
const newList = JSON.parse(JSON.stringify(list));
const tempItem = JSON.parse(JSON.stringify(item));
const temp = newList[index - 1];
newList[index - 1] = item;
newList[index - 1].id = temp.id;
newList[index] = temp;
newList[index].id = tempItem.id;
setList(newList);
changeNewProps('menuData', [menuData[0], ...newList]);
};
const sortDown = (index: number, item: MenuItemType) => {
const newList = JSON.parse(JSON.stringify(list));
const temp = newList[index + 1];
const tempItem = JSON.parse(JSON.stringify(item));
newList[index + 1] = item;
newList[index + 1].id = temp.id;
newList[index] = temp;
newList[index].id = tempItem.id;
setList(newList);
changeNewProps('menuData', [menuData[0], ...newList]);
};
const handleCancel = () => {
if (!isEqual(props, newProps)) {
Modal.confirm({
content: "您还没有保存修改的内容,是否确认关闭?",
okText: "确认",
cancelText: "取消",
onOk: () => {
clearSelectedStatus();
}
});
} else {
clearSelectedStatus();
}
};
const handleStatusChange = (e, item: MenuItemType) => {
const newList = produce(list, (oldList) => {
oldList.map(listItem => {
if (listItem.id === item.id) {
listItem.status = e.target.checked;
}
});
return oldList
})
setList(newList);
changeNewProps('menuData', [menuData[0], ...newList]);
};
return (
<SettingPanel
confirmLoading={confirmLoading}
onCancel={handleCancel}
onOK={handleConfirm}
>
<div className={styles.mall_nav}>
<div className={styles.mall_nav_title}>
<ul>
<li className={styles.width160}>栏目名称</li>
<li className={styles.width392}>链接地址</li>
<li className={styles.width96}>显示在导航上</li>
<li className={styles.width120}>位置排序</li>
</ul>
</div>
<div className={styles.mall_nav_body}>
<div className={styles.mall_nav_list}>
<div>
{
menuData && menuData.map((item, index) => index === 0 && (
<ul key={`menu_item_${index}`} className={styles.hasBorder}>
<li className={styles.width160}>{item.name}</li>
<li className={styles.width392}>{item.link}</li>
<li className={styles.width96}><Checkbox checked={item.status} disabled /></li>
<li className={styles.width120}></li>
</ul>
))
}
</div>
<ReactSortable
list={list}
setList={(newList) => {
setList(newList);
if(!isEmpty(newList)) {
changeProps({
props: Object.assign({ ...props }, { menuData: [menuData[0], ...newList] })
});
}
}}
handle=".draghandle"
>
{
list && list.map((item, index) => (
<ul key={`menu_item_${index}`} className={styles.hasBorder}>
<li className={styles.width160}>{item.name}</li>
<li className={styles.width392}>{item.link}</li>
<li className={styles.width96}><Checkbox checked={item.status} onChange={(e) => handleStatusChange(e, item)} /></li>
<li className={styles.width120}>
<Button type="link" disabled={index === 0} onClick={() => sortUp(index, item)} className={styles.mall_nav_list_btn} icon={<img className={styles.mall_nav_list_btn_icon} src={upIcon} />}></Button>
<Button type="link" disabled={index === list.length - 1} onClick={() => sortDown(index, item)} className={styles.mall_nav_list_btn} icon={<img className={styles.mall_nav_list_btn_icon} src={downIcon} />}></Button>
<Button type="link" className={cx(styles.mall_nav_list_btn, "draghandle")} icon={<img className={styles.mall_nav_list_btn_icon} src={sortIcon} />}></Button>
</li>
</ul>
))
}
</ReactSortable>
</div>
</div>
</div>
</SettingPanel>
);
};
export default MallNav;
...@@ -6,13 +6,13 @@ import GoodsSetting from './components/GoodsSetting' ...@@ -6,13 +6,13 @@ import GoodsSetting from './components/GoodsSetting'
import AdvertSetting from './components/AdvertSetting' import AdvertSetting from './components/AdvertSetting'
import CategoryRecommendSetting from './components/CategoryreCommendSetting' import CategoryRecommendSetting from './components/CategoryreCommendSetting'
import { SelectedInfoType, clearSelectedStatus, PROPS_SETTING_TYPES } from '@lingxi-disign/core'; import { SelectedInfoType, clearSelectedStatus, PROPS_SETTING_TYPES } from '@lingxi-disign/core';
import MallNav from './components/MallNav'
import './index.less' import './index.less'
import { PropTypes } from 'mobx-react'
interface PropsSettingsPropsType { interface PropsSettingsPropsType {
selectedInfo?: SelectedInfoType, selectedInfo?: SelectedInfoType,
templateId: number, templateId: number,
type: 'channel' | 'shop' type: 'channel' | 'shop' | 'own'
} }
const PropsSettings: React.FC<PropsSettingsPropsType> = (props) => { const PropsSettings: React.FC<PropsSettingsPropsType> = (props) => {
...@@ -38,6 +38,8 @@ const PropsSettings: React.FC<PropsSettingsPropsType> = (props) => { ...@@ -38,6 +38,8 @@ const PropsSettings: React.FC<PropsSettingsPropsType> = (props) => {
case PROPS_SETTING_TYPES.categoryBanner: case PROPS_SETTING_TYPES.categoryBanner:
case PROPS_SETTING_TYPES.advert: case PROPS_SETTING_TYPES.advert:
return <AdvertSetting templateid={templateId} {...initProps} templateType={type} /> return <AdvertSetting templateid={templateId} {...initProps} templateType={type} />
case PROPS_SETTING_TYPES.mallNav:
return <MallNav templateid={templateId} {...initProps} />;
} }
} }
return null return null
......
...@@ -8,7 +8,7 @@ import flattenDeep from 'lodash/flattenDeep'; ...@@ -8,7 +8,7 @@ import flattenDeep from 'lodash/flattenDeep';
import map from 'lodash/map'; import map from 'lodash/map';
import isEqual from 'lodash/isEqual'; import isEqual from 'lodash/isEqual';
import keys from 'lodash/keys'; import keys from 'lodash/keys';
import { PROPS_TYPES } from '@lingxi-disign/core'; import { PROPS_TYPES, produce } from '@lingxi-disign/core';
import { CategoryType } from '@lingxi-disign/react-web' import { CategoryType } from '@lingxi-disign/react-web'
export const SPECIAL_STRING_CONSTANTS: any = { export const SPECIAL_STRING_CONSTANTS: any = {
...@@ -154,7 +154,7 @@ export const getAdvertType = (type) => { ...@@ -154,7 +154,7 @@ export const getAdvertType = (type) => {
case 'interact': case 'interact':
return 2 return 2
case 'service': case 'service':
return 3 return 3;
} }
} }
...@@ -163,8 +163,12 @@ export const getAdvertType = (type) => { ...@@ -163,8 +163,12 @@ export const getAdvertType = (type) => {
* @param list * @param list
*/ */
export const addTempalteIdToList = (list, templateId) => { export const addTempalteIdToList = (list, templateId) => {
return list.map(item => { const newList = produce(list, (oldList) => {
item.templateId = templateId oldList.map(item => {
return item item['templateId'] = templateId
return item
})
return oldList
}) })
return newList
} }
...@@ -13,6 +13,19 @@ ...@@ -13,6 +13,19 @@
overflow-x: hidden; overflow-x: hidden;
} }
.theme-ownmall-science {
font-size: 14px;
--mall_main_color: #00A98F;
--mall_main_color_opacity_2: #daf2e7;
--mall_sub_color: #daf2e7;
--mall_main_nav_hover_color: #00A98F;
--category_content_bg: #FFFFFF;
--category_content_title_text: #303133;
--category_content_title_text_hover: #00A98F;
--category_content_sub_title_text: #606266;
}
// 渠道科技类模板 // 渠道科技类模板
.theme-channel-science { .theme-channel-science {
font-size: 14px; font-size: 14px;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment