Commit b71eb46b authored by 前端-黄佳鑫's avatar 前端-黄佳鑫
parents a4e9a4a4 5013ea99
......@@ -48,6 +48,14 @@ const router = [
path: '/shop/template/edit',
component: '@/pages/editor/shopEdit',
},
{
path: '/channel/template/preview',
component: '@/pages/preview/shopPreview',
},
{
path: '/shop/template/preview',
component: '@/pages/preview/shopPreview',
},
memberCenterRoute,
shopRoute,
channelRoute,
......
......@@ -13,7 +13,7 @@
"build:yxc": "yarn api && yarn scripts:build-yxc && umi build",
"build:analyze": "ANALYZE=1 umi build",
"build:dev": "pm2 start scripts/devServer.js",
"build:clean": "umi build",
"build:clean": "NODE_OPTIONS=--max_old_space_size=4096 umi build",
"postinstall": "umi generate tmp",
"prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'",
"test": "umi-test",
......
......@@ -24,6 +24,8 @@ export const useAsyncSelect = async (name, service: () => Promise<any[]>, format
label: v[labelString],
value: v[valueString]
}))
} else {
enums = res
}
setFieldState(name, state => {
state.originAsyncData = res
......
......@@ -6,6 +6,7 @@
:global(.anticon) {
margin-right: 8px;
}
:global(.ant-dropdown-menu-item) {
min-width: 160px;
}
......@@ -17,6 +18,8 @@
height: @layout-header-height;
margin-left: auto;
overflow: hidden;
font-size: 12px;
.action {
display: flex;
align-items: center;
......@@ -24,26 +27,32 @@
padding: 0 12px;
cursor: pointer;
transition: all 0.3s;
> span {
>span {
color: @text-color;
vertical-align: middle;
}
&:hover {
background: @pro-header-hover-bg;
}
&:global(.opened) {
background: @pro-header-hover-bg;
}
}
.search {
padding: 0 12px;
&:hover {
background: transparent;
}
}
.account {
.avatar {
margin: ~'calc((@{layout-header-height} - 24px) / 2)' 0;
margin:~'calc((@{layout-header-height} - 24px) / 2)'0;
margin-right: 8px;
color: @primary-color;
vertical-align: top;
......@@ -55,9 +64,11 @@
.dark {
.action {
color: rgba(255, 255, 255, 0.85);
> span {
>span {
color: rgba(255, 255, 255, 0.85);
}
&:hover,
&:global(.opened) {
background: @primary-color;
......@@ -69,12 +80,15 @@
.dark {
.action {
color: @text-color;
> span {
>span {
color: @text-color;
}
&:hover {
color: rgba(255, 255, 255, 0.85);
> span {
>span {
color: rgba(255, 255, 255, 0.85);
}
}
......@@ -86,20 +100,24 @@
:global(.ant-divider-vertical) {
vertical-align: unset;
}
.name {
display: none;
}
.right {
position: absolute;
top: 0;
right: 12px;
.account {
.avatar {
margin-right: 0;
}
}
.search {
display: none;
}
}
}
}
\ No newline at end of file
......@@ -6,7 +6,7 @@ import SettingPanel from '../settingsPanel'
import config from '../configs'
import { LAYOUT_TYPE } from '@/constants'
import { topBarConfig, topAdvertConfig, headerConfig, mainNavConfig, bannerAdvertConfig, CommonTitle1Config, mallLayoutConfig, serviceAdvertConfig, CommonTitle2Config, AboutUsConfig, InformationConfig, FooterConfig } from './defaultData'
import Loading from './loading'
import Loading from '../components/Loading'
import { menuData } from './defaultMenu'
import { PublicApi } from '@/services/api'
import styles from './index.less'
......
.loading_wrap {
width: 100%;
height: 100vh;
justify-content: center;
flex-direction: column;
display: flex;
align-items: center;
.loading_text {
margin-top: 16px;
font-size: 14px;
font-weight: bold;
}
}
\ No newline at end of file
import React from 'react'
import { Spin } from 'antd'
import styles from './index.less'
......
import React from 'react'
import { LingxiPreview } from 'lingxi-design';
// import { useSelector } from 'lingxi-editor-core';
const PreviewPanel = (props) => {
const { theme } = props
return <LingxiPreview theme={theme} />
}
export default PreviewPanel
\ No newline at end of file
......@@ -4,19 +4,28 @@ import { history } from 'umi'
import { Modal } from 'antd'
import styles from './index.less'
const ToolBar: React.FC = () => {
interface ToolBarPropsType {
type?: number;
title?: string
}
const handleGoBack = () => {
Modal.confirm({
content: "是否确认离开模板装修页面?",
okText: "确认",
className: styles.modal_confirm,
cancelText: "取消",
onOk: () => {
history.goBack()
}
})
const ToolBar: React.FC<ToolBarPropsType> = (props) => {
const { type = 1, title = "首页" } = props
const handleGoBack = () => {
if (type === 1) {
Modal.confirm({
content: "是否确认离开模板装修页面?",
okText: "确认",
className: styles.modal_confirm,
cancelText: "取消",
onOk: () => {
history.goBack()
}
})
} else {
history.goBack()
}
}
return (
......@@ -25,8 +34,8 @@ const ToolBar: React.FC = () => {
<ArrowLeftOutlined />
</div>
<div className={styles.toolbar_title}>
<span>正在编辑:</span>
<label>首页</label>
<span>{type === 1 ? '正在编辑:' : '正在预览:'}</span>
<label>{title}</label>
</div>
</div>
)
......
......@@ -7,7 +7,7 @@ import config from '../configs'
import { LAYOUT_TYPE } from '@/constants'
import { topBarConfig, topAdvertConfig, headerConfig, mainNavConfig, bannerAdvertConfig, CommonTitle1Config, mallLayoutConfig, serviceAdvertConfig, CommonTitle2Config, AboutUsConfig, InformationConfig, FooterConfig } from './defaultData'
import { menuData } from './defaultMenu'
import Loading from './loading'
import Loading from '../components/Loading'
import { PublicApi } from '@/services/api'
import { GlobalConfig } from '@/global/config'
import styles from './index.less'
......@@ -84,7 +84,9 @@ const ShopEdit: React.FC<ShopEditPropsType> = (props) => {
const fetchFirstCategory = () => {
return new Promise((resolve) => {
PublicApi.getTemplateShopFindAllFirstCategory().then(res => {
resolve(res.data)
if (res.code === 1000) {
resolve(res.data)
}
})
})
}
......@@ -101,7 +103,9 @@ const ShopEdit: React.FC<ShopEditPropsType> = (props) => {
// @ts-ignore
PublicApi.getTemplateShopFindFirstCategoryDetail(param).then(res => {
resolve(res.data)
if (res.code === 1000) {
resolve(res.data)
}
})
})
}
......@@ -113,7 +117,9 @@ const ShopEdit: React.FC<ShopEditPropsType> = (props) => {
return new Promise((resolve) => {
PublicApi.getTemplateShopFindShop().then(res => {
if (res.code === 1000) {
resolve(res.data)
if (res.code === 1000) {
resolve(res.data)
}
}
})
})
......
import React from 'react'
import { Spin } from 'antd'
import styles from './index.less'
const Loading: React.FC = () => {
return (
<div className={styles.loading_wrap}>
<Spin size="large" />
<p className={styles.loading_text}>正在加载页面数据...</p>
</div>
)
}
export default Loading
......@@ -467,7 +467,7 @@ const CommodityDetail = (props) => {
if (res.data) {
window.location.href = getOrderLink(sessionKey, priceType)
} else {
window.location.href = `/memberCenter/tranactionAbility/purchaseOrder/orderDetail?modelType=5&spam_id=${sessionKey}`
window.location.href = `/memberCenter/tranactionAbility/purchaseOrder/readyAddOrder/add?modelType=5&spam_id=${sessionKey}`
}
})
} else {
......
......@@ -22,13 +22,15 @@ const Header: React.FC<HeaderPropsType> = (props) => {
let handleScroll = () => {
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
const floatSearch = document.getElementById("floatSearch")
if (scrollTop > 500) {
if (!hasClass(floatSearch.classList, 'show')) {
floatSearch.classList.add(styles.show)
}
} else {
if (hasClass(floatSearch.classList, 'show')) {
floatSearch.classList.remove(styles.show)
if (floatSearch) {
if (scrollTop > 500) {
if (!hasClass(floatSearch.classList, 'show')) {
floatSearch.classList.add(styles.show)
}
} else {
if (hasClass(floatSearch.classList, 'show')) {
floatSearch.classList.remove(styles.show)
}
}
}
}
......
......@@ -2,6 +2,7 @@ import React from 'react'
import { EnvironmentOutlined, CaretDownOutlined } from '@ant-design/icons'
import { inject, observer } from 'mobx-react'
import cx from 'classnames'
import { Link } from 'umi'
import ImageBox from '@/components/ImageBox'
import defaultAvatar from './imgs/default_avatar.png'
import AccountSafeIcon from './imgs/account_safe_icon.png'
......@@ -107,7 +108,7 @@ const TopBar: React.FC<TopBarPropsType> = (props) => {
)
}
<li className={styles.topbar_menu_item}>
<a href="/memberCenter/home">会员中心</a>
<Link to="/memberCenter/home">会员中心</Link>
</li>
<li className={styles.topbar_menu_item}>我的消息</li>
<li className={styles.topbar_menu_item}>
......
......@@ -55,9 +55,11 @@ const LXMallLayout: React.FC<LXMallLayoutPropsType> = (props) => {
}
useEffect(() => {
let body = document.getElementsByTagName('body')[0];
if (!isEmpty(mallTemplateInfo)) {
let body = document.getElementsByTagName('body')[0];
body.className = mallTemplateInfo.fileName ? `theme-mall-${mallTemplateInfo.fileName}` : templateName;
} else {
body.className = templateName
}
}, [mallTemplateInfo])
......
......@@ -170,6 +170,11 @@ const PurchaseOnline: React.FC<PurchaseOnlinePropsType> = (props) => {
}
}
const handlePageChange = (page) => {
setCurrent(page)
fetchCommodityList(page)
}
return (
<div className={styles.purchaseOnline}>
<div className={styles.mall_container}>
......@@ -225,7 +230,7 @@ const PurchaseOnline: React.FC<PurchaseOnlinePropsType> = (props) => {
<>
<CommodityList showType={showType} commodityList={commodityList} layoutType={layoutType} />
<div className={styles.pagination_wrap}>
<Pagination showQuickJumper showSizeChanger={false} current={current} total={totalCount} pageSize={pageSize} />
<Pagination showQuickJumper showSizeChanger={false} onChange={handlePageChange} current={current} total={totalCount} pageSize={pageSize} />
</div>
</>
)
......
......@@ -552,7 +552,7 @@ const PurchaseOrder: React.FC<PurchaseOrderPropsType> = (props) => {
if (res.data) {
history.push(`/order?spam_id=${sessionKey}&scence=purchase`)
} else {
history.push(`/memberCenter/tranactionAbility/purchaseOrder/orderDetail?modelType=5&spam_id=${sessionKey}`)
history.push(`/memberCenter/tranactionAbility/purchaseOrder/readyAddOrder/add?modelType=5&spam_id=${sessionKey}`)
}
})
}
......
export const mallLayoutConfig = {
key: "0",
"0": {
"componentName": "MallLayout",
"props": {
"style": {
"width": "100%",
"minHeight": "100%",
"background": "#FFF"
}
},
"childNodes": ["1", "3", "4", "5", "17", "18", "6"]
},
}
export const topBarConfig = {
key: "1",
"1": {
"componentName": "TopBar",
"props": {
linkdisable: true
},
}
}
export const topAdvertConfig = {
key: "2",
"2": {
"componentName": "Advert",
"props": {
"type": "top",
"linkdisable": true,
"advertList": []
},
},
}
export const headerConfig = {
key: "3",
"3": {
"componentName": "ShopHeader",
"props": {
"shopInfo": {},
"logoUrl": ""
},
},
}
export const mainNavConfig = {
key: "4",
"4": {
"componentName": "MainNav",
"props": {},
},
}
export const bannerAdvertConfig = {
key: "5",
"5": {
"componentName": "Advert",
"props": {
"type": "banner",
"linkdisable": true,
"advertList": []
}
},
}
export const CommonTitle1Config = {
key: "6",
"6": {
"componentName": "CommonTitle",
"props": {
"title": "热销商品",
"type": "primary"
},
},
}
export const serviceAdvertConfig = {
key: "16",
"16": {
"componentName": "Advert",
"props": {
"type": "service",
"linkdisable": true,
"advertList": []
}
},
}
export const CommonTitle2Config = {
key: "17",
"17": {
"componentName": "CommonTitle",
"props": {
"title": "关于我们",
"type": "primary"
},
},
}
export const AboutUsConfig = {
key: "18",
"18": {
"componentName": "AboutUs",
"props": {
"shopInfo": {}
},
},
}
export const InformationConfig = {
key: '19',
"19": {
"componentName": "Information",
"props": {},
},
}
export const FooterConfig = {
key: '20',
"20": {
"componentName": "Footer",
"props": {},
},
}
export const menuData = [
{
"path": "/shop",
"name": "首页",
"key": "shopHome",
},
{
"path": "/shop/commodity",
"name": "商品",
"key": "shopCommodity",
},
{
"path": "/shop/pointsMall",
"name": "积分兑换",
"key": "shopPointsMall",
},
{
"path": "/shop/infomation",
"name": "资讯",
"key": "shopInfomation",
},
{
"path": "/shop/about",
"name": "关于我们",
"key": "shopAbout",
},
]
\ No newline at end of file
@content-height: calc(100vh - 120px);
.wrapper {
background: white;
display: flex;
flex-direction: column;
box-shadow: 2px 0 4px 0 rgba(174, 174, 174, 0.50);
transition: all .3s;
}
.content {
display: flex;
flex: 1;
flex-direction: row;
}
.canvas-container {
display: flex;
flex: 1;
justify-content: center;
background-color: #F4F5F7;
height: calc(@content-height + 50px);
overflow: hidden;
}
.loading_wrap {
width: 100%;
height: 100vh;
justify-content: center;
flex-direction: column;
display: flex;
align-items: center;
.loading_text {
margin-top: 16px;
font-size: 14px;
font-weight: bold;
}
}
\ No newline at end of file
import React, { useEffect, useState } from 'react'
import { LegoProvider } from 'lingxi-editor-core'
import ToolBar from '../../editor/components/toolBar'
import PreviewPanel from '../../editor/components/PreviewPanel'
import config from '../../editor/configs'
import { LAYOUT_TYPE } from '@/constants'
import { topBarConfig, topAdvertConfig, headerConfig, mainNavConfig, bannerAdvertConfig, CommonTitle1Config, mallLayoutConfig, serviceAdvertConfig, CommonTitle2Config, AboutUsConfig, InformationConfig, FooterConfig } from './defaultData'
import { menuData } from './defaultMenu'
import Loading from '../../editor/components/Loading'
import { PublicApi } from '@/services/api'
import { GlobalConfig } from '@/global/config'
import styles from './index.less'
interface ShopPreviewPropsType {
location: {
query: {
/**
* 模板id
*/
id: number;
/**
* 模板名称
*/
template: string;
}
}
}
let TemplateList = ['science']
const ShopPreview: React.FC<ShopPreviewPropsType> = (props) => {
const { query: { id, template } } = props.location
const [loading, setLoading] = useState<boolean>(true)
const [theme, setTheme] = useState<string>('theme-shop-science')
const [componentConfigs, setComponentConfigs] = useState({})
useEffect(() => {
if (!TemplateList.includes(template)) {
setTheme(`theme-shop-${TemplateList[0]}`)
} else {
setTheme(`theme-shop-${template}`)
}
getComponentsConfig()
}, [])
const findFirstAdvertsByType = () => {
return new Promise((resolve) => {
let params = {
templateId: id,
type: 1
}
//@ts-ignore
PublicApi.getTemplateShopFindAdvertsByType(params).then(res => {
if (res.code === 1000) {
resolve(res.data)
} else {
resolve([])
}
})
})
}
const findSecondAdvertsByType = () => {
return new Promise((resolve) => {
let params = {
templateId: id,
type: 2
}
//@ts-ignore
PublicApi.getTemplateShopFindAdvertsByType(params).then(res => {
if (res.code === 1000) {
resolve(res.data)
} else {
resolve([])
}
})
})
}
/**
* 获取所有一级品类信息
*/
const fetchFirstCategory = () => {
return new Promise((resolve) => {
console.log(111)
PublicApi.getTemplateShopFindAllFirstCategory().then(res => {
if (res.code === 1000) {
resolve(res.data)
} else {
resolve([])
}
}).catch((err) => {
resolve([])
})
})
}
/**
* 获取一级品类详细信息
*/
const fetchCategoryById = (categoryId) => {
return new Promise((resolve) => {
let param = {
templateId: id,
categoryId
}
// @ts-ignore
PublicApi.getTemplateShopFindFirstCategoryDetail(param).then(res => {
if (res.code === 1000) {
resolve(res.data)
}
})
})
}
/**
* 获取店铺信息
*/
const fetchShopInfo = () => {
return new Promise((resolve) => {
PublicApi.getTemplateShopFindShop().then(res => {
if (res.code === 1000) {
if (res.code === 1000) {
resolve(res.data)
}
}
})
})
}
const getComponentsConfig = async () => {
// 导航栏
mainNavConfig[mainNavConfig.key].props.menuData = menuData
mainNavConfig[mainNavConfig.key].props.type = LAYOUT_TYPE.shop
mainNavConfig[mainNavConfig.key].props.categoryList = []
// 一号位广告
bannerAdvertConfig[bannerAdvertConfig.key].props.advertList = await findFirstAdvertsByType()
// 二号位广告
serviceAdvertConfig[serviceAdvertConfig.key].props.advertList = await findSecondAdvertsByType()
//店铺信息
const shopInfo = await fetchShopInfo()
headerConfig[headerConfig.key].props.shopInfo = shopInfo
const shopList = GlobalConfig.web.shopInfo
let webMallInfo = shopList.filter(item => item.environment === 1 && item.type === 1)[0]
headerConfig[headerConfig.key].props.logoUrl = webMallInfo.logoUrl
topBarConfig[topBarConfig.key].props.shopname = webMallInfo.name
AboutUsConfig[AboutUsConfig.key].props.shopInfo = shopInfo
let initIndex = 100
let floorLineConfig: any = {}
let floorLineKeys: any = []
let firstCategory: any = await fetchFirstCategory()
for (let item of firstCategory) {
let categoryDetail: any = await fetchCategoryById(item.id)
let floorLineConfigItem = {}
floorLineKeys.push(String(initIndex + 1))
let FloorLine = {
[String(initIndex + 1)]: {
"componentName": "ShopFloorLine",
"props": {
title: item.name
},
"childNodes": [String(initIndex + 2), String(initIndex + 3)]
}
}
let Category = {
[String(initIndex + 2)]: {
"componentName": "ShopFloorLine.Category",
"props": {
categoryAdvertPicUrl: categoryDetail.categoryAdvertPicUrl,
categoryid: item.id,
categoryList: categoryDetail.categoryBOList
},
},
}
let Goods = {
[String(initIndex + 3)]: {
"componentName": "ShopFloorLine.Goods",
"props": {
linkdisable: true,
categoryid: item.id,
goodsList: categoryDetail.goodsBOList
},
},
}
floorLineConfigItem = { ...FloorLine, ...Category, ...Goods }
floorLineConfig = { ...floorLineConfig, ...floorLineConfigItem }
initIndex += 100
}
mallLayoutConfig["0"].childNodes = [...mallLayoutConfig["0"].childNodes, ...floorLineKeys, serviceAdvertConfig.key, FooterConfig.key]
let config = {
...mallLayoutConfig,
...topBarConfig,
...topAdvertConfig,
...headerConfig,
...mainNavConfig,
...bannerAdvertConfig,
...CommonTitle2Config,
...AboutUsConfig,
...CommonTitle1Config,
...floorLineConfig,
...serviceAdvertConfig,
...FooterConfig
}
setComponentConfigs(config)
setLoading(false)
}
return !loading ? (
<LegoProvider initState={{ componentConfigs: componentConfigs }} config={config}>
<div className={styles['wrapper']}>
<ToolBar type={2} title="首页" />
<div className={styles['content']}>
<div className={styles['canvas-container']}>
<PreviewPanel theme={theme} />
</div>
</div>
</div>
</LegoProvider>
) : <Loading />
}
export default ShopPreview
\ No newline at end of file
......@@ -60,6 +60,10 @@ const TemplateDetail: React.FC<TemplateDetailPropsType> = (props) => {
// history.push(`/shop/template/edit?id=${detailInfo.id}&template=${detailInfo.fileName}`)
}
const handleLinkPreview = () => {
window.location.href = `/shop/template/preview?id=${detailInfo.id}&template=${detailInfo.fileName}`
}
return (
<DetailPage
title="查看模板"
......@@ -93,7 +97,7 @@ const TemplateDetail: React.FC<TemplateDetailPropsType> = (props) => {
</div>
</div>
</div>
<div className={styles.btn}>
<div className={styles.btn} onClick={() => handleLinkPreview()}>
<EyeOutlined />
<label>预览</label>
</div>
......
......@@ -19,15 +19,15 @@ const ReadyConfirmDelevedOrderDetail: React.FC = () => {
const isHandDeleved = formContext.data && formContext.data.purchaseOrderInteriorState === SaleOrderInsideWorkState.HAND_DELEVED_ORDER
// 所有发货单都是否已经发货了
const isShowBtn = formContext.data?.orderDeliveryDetailsResponses?.some(v => v.interiorState === DeliverySideState.ADD_LOGISTICS_ORDER)
const isShowBtn = isHandDeleved || formContext.data?.orderDeliveryDetailsResponses?.some(v => v.interiorState === DeliverySideState.ADD_LOGISTICS_ORDER)
const approvedRef = useRef<any>({})
const handleClick = useCallback(() => {
if (isHandDeleved) {
approvedRef.current.setVisible(true)
} else {
const deleveBox = document.querySelector('#deleveBox') as any
window.scrollTo(0, deleveBox.offsetTop)
} else {
approvedRef.current.setVisible(true)
}
}, [isHandDeleved])
......
......@@ -13,8 +13,10 @@ const LoginWrap: React.FC = () => {
const { redirect } = history.location.query
const [validFrame, setValidFrame] = useState(false)
const [validButton, setValidButton] = useState(false)
const [loginLoading, setLoginLoading] = useState<boolean>(false)
const finish = (value: any) => {
setLoginLoading(true)
PublicApi.postMemberLogin(value).then(res => {
const { data, code } = res
if (code === 1000) {
......@@ -28,7 +30,11 @@ const LoginWrap: React.FC = () => {
} else {
window.location.replace('/memberCenter/home')
}
} else {
setLoginLoading(false)
}
}).catch(() => {
setLoginLoading(false)
})
}
......@@ -89,7 +95,7 @@ const LoginWrap: React.FC = () => {
</Form.Item>)
}
<Form.Item>
<Button type='primary' size='large' htmlType='submit' block>登录</Button>
<Button type='primary' loading={loginLoading} size='large' htmlType='submit' block>登录</Button>
</Form.Item>
</Form>
}
......
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