Commit 77e092fe authored by Bill's avatar Bill

Merge branch 'dev' of 10.0.0.22:lingxi/lingxi-business-paltform into dev

parents 74f63f36 6e07d806
......@@ -2,8 +2,8 @@ import BASE_CONFIG from '../base.config.json'
import { checkUrl } from '../utils'
const shopInfo = BASE_CONFIG.web.shopInfo
let webChannelInfo = shopInfo.filter(item => item.environment === 1 && item.type === 3)[0] // 渠道商城
let webChannelPointInfo = shopInfo.filter(item => item.environment === 1 && item.type === 5)[0] // 渠道积分商城
const webChannelInfo = shopInfo.filter(item => item.environment === 1 && item.type === 3)[0] // 渠道商城
const webChannelPointInfo = shopInfo.filter(item => item.environment === 1 && item.type === 5)[0] // 渠道积分商城
const defaultChannelRoute = '/channelmall' // 默认渠道商城根路径
const defaultIChannelPointRoute = '/pointsMall' // 默认渠道积分商城路径
......@@ -128,4 +128,4 @@ const ChannelRoute = {
],
}
export default ChannelRoute
\ No newline at end of file
export default ChannelRoute
......@@ -81,13 +81,13 @@ const mallRoute = {
hideHeader: true,
component: '@/pages/lxMall/payResult',
},
{
// 在线求购
path: `/purchaseOnline`,
name: 'purchaseOnline',
key: 'purchaseOnline',
component: '@/pages/lxMall/purchaseOnline',
},
// {
// // 在线求购
// path: `/purchaseOnline`,
// name: 'purchaseOnline',
// key: 'purchaseOnline',
// component: '@/pages/lxMall/purchaseOnline',
// },
{
// 积分商城
path: pointMallRoute,
......
......@@ -93,5 +93,28 @@ module.exports = {
// Passive mode is forced (EPSV command is not sent)
forcePasv: true
})
},
207: {
SITE_ID: '1',
BACK_GATEWAY: 'http://10.0.1.207:8100',
USE_ROUTE_CONFIG: true,
SOCKET_URL: 'ws://10.0.1.207:8100',
ssh: JSON.stringify({
user: "root",
// Password optional, prompted if none given
password: "Shushangyun520",
host: "10.0.1.207",
port: 22,
localRoot: path.resolve('./dist/'),
remoteRoot: "/home/www/lingxi/lingxi-business-platform/dist/",
// include: ["*", "**/*"], // this would upload everything except dot files
include: ["*"],
// e.g. exclude sourcemaps, and ALL files in node_modules (including dot files)
// exclude: ["dist/**/*.map", "node_modules/**", "node_modules/**/.*", ".git/**"],
// delete ALL existing files at destination before uploading, if true
deleteRemote: true,
// Passive mode is forced (EPSV command is not sent)
forcePasv: true
})
}
}
......@@ -5,6 +5,7 @@
"upload:scm": "cross-env local=scm taskName=upload yarn scripts:build",
"upload:10": "cross-env local=10 taskName=upload yarn scripts:build",
"upload:25": "cross-env local=25 taskName=upload yarn scripts:build",
"upload:207": "cross-env local=207 taskName=upload yarn scripts:build",
"api": "god-ytt",
"scripts:build": "node scripts/run",
"scripts:build-yxc": "node scripts/run http://yxc-web-demo.shushangyun.com/api",
......@@ -20,6 +21,7 @@
"build:scm": "cross-env SITE_ID=1 BACK_GATEWAY=http://lingxi-scm.wg.shushangyun.com USE_ROUTE_CONFIG=false SOCKET_URL=ws://lingxi-scm.wg.shushangyun.com yarn build",
"build:all": "cross-env SITE_ID=1 BACK_GATEWAY=http://lingxi-all.wg.shushangyun.com USE_ROUTE_CONFIG=false SOCKET_URL=ws://lingxi-all.wg.shushangyun.com yarn build",
"build:10": "cross-env SITE_ID=1 BACK_GATEWAY=http://10.0.0.10:8100 USE_ROUTE_CONFIG=false SOCKET_URL=ws://10.0.0.10:9400 yarn build",
"build:207": "cross-env SITE_ID=1 BACK_GATEWAY=http://10.0.1.207:8100 USE_ROUTE_CONFIG=false SOCKET_URL=ws://10.0.1.207:9400 yarn build",
"postinstall": "umi generate tmp",
"prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'",
"test": "umi-test",
......@@ -28,6 +30,7 @@
"start:scm": "cross-env SITE_ID=1 BACK_GATEWAY=http://lingxi-scm.wg.shushangyun.com USE_ROUTE_CONFIG=false SOCKET_URL=ws://lingxi-scm.wg.shushangyun.com yarn start",
"start:url": "cross-env SITE_ID=1 BACK_GATEWAY=http://lingxi-all.wg.shushangyun.com USE_ROUTE_CONFIG=true SOCKET_URL=ws://lingxi-all.wg.shushangyun.com yarn start",
"start:10": "cross-env SITE_ID=1 BACK_GATEWAY=http://10.0.0.10:8100 USE_ROUTE_CONFIG=true SOCKET_URL=ws://10.0.0.10:9400 yarn start",
"start:207": "cross-env SITE_ID=1 BACK_GATEWAY=http://10.0.1.207:8100 USE_ROUTE_CONFIG=false SOCKET_URL=ws://10.0.1.207:9400 yarn start",
"start:25": "cross-env SITE_ID=1 BACK_GATEWAY=http://10.0.0.25:8100 USE_ROUTE_CONFIG=true SOCKET_URL=ws://10.0.0.25:9400 yarn start"
},
"lint-staged": {
......
......@@ -79,6 +79,48 @@ const ToolBar: React.FC<ToolBarPropsType> = (props) => {
} else if(layoutType=== LAYOUT_TYPE.channel) {
param.appChannelBO = {}
console.log(componentConfigs, "componentConfigs")
Object.keys(componentConfigs).forEach(key => {
const componentConfigsItem = componentConfigs[key]
if(componentConfigsItem.componentType) {
switch(componentConfigsItem.componentType) {
case PROPS_TYPES.mobileHeaderNav:
param.appChannelBO.topBO = {
status: false,
style: componentConfigsItem.props.styleTheme,
topDetailsBOList: componentConfigsItem.props.dataList || []
}
break
case PROPS_TYPES.mobileBanner:
param.appChannelBO.advertBO = {
status: false,
advertDetailsBOList: componentConfigsItem.props.dataList || []
}
break
case PROPS_TYPES.mobileChannelGoodsCard:
param.appChannelBO.productBO = {
status: false,
productDetailsBOList: componentConfigsItem.props.dataList || []
}
break
case PROPS_TYPES.moibileChannelInformation:
param.appChannelBO.informationBO = {
status: false,
title: componentConfigsItem.props.title,
informationIdList: componentConfigsItem.props.informationIdList || []
}
break
case PROPS_TYPES.mobileBottomNavigation:
param.appChannelBO.bottomBO = {
status: false,
bottomDetailsBOList: componentConfigsItem.props.dataList || []
}
break
default:
break
}
}
})
}
console.log(JSON.stringify(param), "param")
saveAppEnterprise(param)
......
......@@ -14,6 +14,10 @@ const MobileChannelHeaderNav: ComponentConfigTypes = {
label: '编辑',
type: PROPS_TYPES.mobileChannelGoodsCard
},
styleType: {
label: "样式",
type: PROPS_TYPES.objectArray
}
},
};
......
......@@ -17,14 +17,76 @@
&-title {
display: flex;
padding: 10px 12px;
background: linear-gradient(135deg, #F6DDB7 0%, #F6E4CF 100%);
color: #303133;
align-items: center;
&.theme_0 {
color: #303133;
background: linear-gradient(84deg, #F4F5F7 0%, #FFFFFF 100%);
.lingxi-goods-list-item-more {
background-color: rgba(48, 49, 51, 0.1);
}
}
&.theme_1 {
color: #3D4263;
background: linear-gradient(84deg, #C0C3D8 0%, #DDE1F5 100%);
.lingxi-goods-list-item-more {
background-color: rgba(48, 49, 51, 0.1);
}
}
&.theme_2 {
color: #B53838;
background: linear-gradient(84deg, #F3C4C4 0%, #FFEFEF 100%);
.lingxi-goods-list-item-more {
background-color: rgba(48, 49, 51, 0.1);
}
}
&.theme_3 {
color: #C18223;
background: linear-gradient(135deg, #F6DDB7 0%, #F6E4CF 100%);
.lingxi-goods-list-item-more {
background-color: rgba(48, 49, 51, 0.1);
}
}
&.theme_4 {
color: #008F72;
background: linear-gradient(135deg, #ABE4D2 0%, #D7F8EE 100%);
.lingxi-goods-list-item-more {
background-color: rgba(48, 49, 51, 0.1);
}
}
&.theme_5 {
color: #2E77C2;
background: linear-gradient(135deg, #B3D4F6 0%, #DEE7FF 100%);
.lingxi-goods-list-item-more {
background-color: rgba(48, 49, 51, 0.1);
}
}
&.theme_6 {
color: #5243AA;
background: linear-gradient(135deg, #C6C0E9 0%, #ECEAF8 100%);
.lingxi-goods-list-item-more {
background-color: rgba(48, 49, 51, 0.1);
}
}
&-left {
flex: 1;
&-title {
color: #3D4263;
font-size: 16px;
font-weight: 500;
line-height: 18px;
......@@ -32,7 +94,6 @@
&-vicetitle {
display: block;
color: #3D4263;
font-size: 14px;
margin-top: 10px;
line-height: 14px;
......
......@@ -59,7 +59,7 @@ const ChannelGoodsCard: React.FC<ChannelGoodsCardPropsType> = (props) => {
{
dataList && dataList.map((dataItem, dataIndex) => (
<div className={styles["lingxi-goods-list-item"]} key={`goods-list-item-${dataIndex}`}>
<div className={styles["lingxi-goods-list-item-title"]}>
<div className={cx(styles["lingxi-goods-list-item-title"], styles[`theme_${dataItem.style}`])}>
<div className={styles["lingxi-goods-list-item-title-left"]}>
<div className={styles["lingxi-goods-list-item-title-left-title"]}>{dataItem.title}</div>
<label className={styles["lingxi-goods-list-item-title-left-vicetitle"]}>{dataItem.viceTitle}</label>
......
......@@ -23,11 +23,12 @@ export interface InformationItemType {
interface MobileChannelInformationPropsType {
className?: string,
title: string,
dataList: InformationItemType[]
}
const MobileChannelInformation: React.FC<MobileChannelInformationPropsType> = (props) => {
const { className, dataList, ...others} = props
const { className, title, dataList, ...others} = props
const renderChildren = ({ getPrefixCls }: any) => {
const prefixCls = getPrefixCls("channel-information");
......@@ -36,7 +37,7 @@ const MobileChannelInformation: React.FC<MobileChannelInformationPropsType> = (p
return (
<div className={classNameString} {...others}>
<div className={styles["lingxi-channel-information-title"]}>
<span>行业资讯</span>
<span>{title}</span>
</div>
<div className={styles["lingxi-channel-information-scrollview"]}>
<div className={styles["lingxi-channel-information-list"]}>
......
......@@ -19,18 +19,16 @@ export const promptCommodityColumn = [
{
title: "商品名称",
dataIndex: "name",
width: 280,
width: 300,
ellipsis: true,
},
{
title: "品类",
render: (_, record) => record.customerCategory ? record.customerCategory.name : "",
ellipsis: true,
// render: (_, record) => record.customerCategory.name
},
{
title: "品牌",
render: (_, record) => record.brand ? record.brand.name : "",
ellipsis: true,
// render: (_, record) => record.brand.name
},
{
title: "价格",
......@@ -39,4 +37,76 @@ export const promptCommodityColumn = [
},
]
export default promptCommodityColumn
export const integralCommodityColumn = [
{
title: "商品图片",
dataIndex: "mainPic",
render: (mainPic: string) => showMainPic(mainPic)
},
{
title: "商品名称",
dataIndex: "name",
width: 300,
ellipsis: true,
},
{
title: "需要积分",
dataIndex: "min",
render: (_, record) => `${numFormat(record.min)}`
},
]
export const shopColumn = [
{
title: "店铺图片",
dataIndex: "logo",
render: (logo: string) => showMainPic(logo)
},
{
title: "店铺名称",
dataIndex: "memberName",
width: 300,
ellipsis: true,
},
]
export const brandColumn = [
{
title: "品牌logo",
dataIndex: "logoUrl",
render: (imageUrl: string) => showMainPic(imageUrl)
},
{
title: "品牌名称",
dataIndex: "name",
width: 360,
ellipsis: true,
},
]
export const informationColumn = [
{
title: "资讯图片",
dataIndex: "imageUrl",
render: (imageUrl: string) => showMainPic(imageUrl)
},
{
title: "资讯标题",
dataIndex: "title",
width: 360,
ellipsis: true,
},
]
const tableColumn = {
1: promptCommodityColumn,
2: shopColumn,
3: brandColumn,
4: informationColumn
}
export default tableColumn
......@@ -34,9 +34,6 @@ export const formProduct: ISchema = {
"x-component-props": {
placeholder: '请选择品类',
className: 'fixed-ant-selected-down', // 该类强制将显示的下拉框出现在select下, 只有这里出现问题, ??
queryParams: {
storeId: 2,
},
fetchSearch: PublicApi.getProductSelectGetSelectCategory,
style: {
width: 160
......@@ -48,10 +45,7 @@ export const formProduct: ISchema = {
"x-component": 'SearchSelect',
"x-component-props": {
placeholder: '请选择品牌',
queryParams: {
storeId: 2,
},
fetchSearch: PublicApi.getSearchMobileShopStoreGetBrand,
fetchSearch: PublicApi.getProductSelectGetSelectPlatformBrand,
style: {
width: 160
}
......
@import "../../../../../../global//styles/utils.less";
@import "../../../../../../global/styles/utils.less";
@import "../../common.less";
.selectBtn {
......
import React from 'react'
import { numFormat, priceFormat } from '@/utils/numberFomat'
import ImageBox from '@/components/ImageBox'
const showMainPic = (mainPic: string) => <ImageBox width={32} height={32} imgUrl={mainPic} />
const informationColumn = [
{
title: "资讯图片",
dataIndex: "imageUrl",
render: (imageUrl: string) => showMainPic(imageUrl)
},
{
title: "资讯标题",
dataIndex: "title",
width: 360,
ellipsis: true,
},
]
export default informationColumn
import { ISchema } from '@formily/antd'
import { FORM_FILTER_PATH } from '@/formSchema/const'
import { PublicApi } from '@/services/api'
export const formProduct: ISchema = {
type: 'object',
properties: {
name: {
type: 'string',
'x-component': 'ModalSearch',
'x-component-props': {
placeholder: '搜索',
align: 'flex-left',
},
},
[FORM_FILTER_PATH]: {
type: 'object',
'x-component': 'flex-layout',
'x-component-props': {
rowStyle: {
flexWrap: 'nowrap',
style: {
marginRight: 0
}
},
colStyle: {
marginTop: 20,
},
},
properties: {
customerCategoryId: {
type: 'string',
"x-component": 'SearchSelect',
"x-component-props": {
placeholder: '请选择品类',
className: 'fixed-ant-selected-down', // 该类强制将显示的下拉框出现在select下, 只有这里出现问题, ??
queryParams: {
storeId: 2,
},
fetchSearch: PublicApi.getProductSelectGetSelectCategory,
style: {
width: 160
}
}
},
brandId: {
type: 'string',
"x-component": 'SearchSelect',
"x-component-props": {
placeholder: '请选择品牌',
queryParams: {
storeId: 2,
},
fetchSearch: PublicApi.getSearchMobileShopStoreGetBrand,
style: {
width: 160
}
}
},
submit: {
"x-component": 'Submit',
"x-mega-props": {
span: 1
},
"x-component-props": {
children: '查询'
}
}
}
}
}
}
export const basicSchema: ISchema = {
type: 'object',
properties: {
name: {
type: 'string',
'x-component': 'Search',
'x-component-props': {
placeholder: '搜索',
align: 'flex-left',
},
},
}
}
@import "../../../../../../global/styles/utils.less";
@import "../../common.less";
.selectBtn {
display: block;
width: 100%;
background-color: #FAFBFC;
border: 1px dashed #D8DDE6;
}
.uploadPreview {
border: 1px solid #EBECF0;
}
import React, { useState } from 'react'
import { Button, Input, message } from 'antd'
import { PlusOutlined, DeleteOutlined } from '@ant-design/icons'
import { changeProps } from 'lingxi-editor-core'
import ImageBox from '@/components/ImageBox'
import isEmpty from 'lodash/isEmpty'
import ModalTable from '@/components/ModalTable'
import { PublicApi } from '@/services/api'
import { FORM_FILTER_PATH } from '@/formSchema/const'
import cx from 'classnames'
import { useRowSelectionTable } from '@/hooks/useRowSelectionTable'
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch'
import SearchSelect from '@/components/NiceForm/components/SearchSelect'
import Search from '@/components/NiceForm/components/Search'
import Submit from '@/components/NiceForm/components/Submit'
import { basicSchema } from './contant/schema'
import informationColumn from './contant/column'
import arrowRightIcon from '@/assets/icons/arrow_right.png'
import arrowLeftIcon from '@/assets/icons/arrow_left.png'
import styles from './index.less'
interface DataItemType {
sort: number,
id: number,
name: string,
img: string,
type: number,
expand: boolean,
selectInfo?: any
}
interface BannerPropsType {
dataList: DataItemType[],
selectInfo?: any,
informationIdList: number[],
storeId: number,
title: string,
}
const ChannelInformation: React.FC<BannerPropsType> = (props) => {
const { title, informationIdList, dataList } = props
const [expandState, setExpandState] = useState<boolean>(true)
const [modalVisible, setModalVisible] = useState<boolean>(false)
const [recommendTitle, setRecommendTitle] = useState<string>(title)
const [productRowSelection, productRowCtl] = useRowSelectionTable()
/**
* 修改名称
* @param value
* @param id
*/
const handleNameChange = (value: string) => {
setRecommendTitle(value)
changeProps({
props:Object.assign({ ...props }, { title: value })
})
}
const getDataListByList = (list) => {
let result: any = []
if(list) {
list.forEach((listItem) => {
if (listItem.productList && listItem.productList.length > 0) {
result = [...result, ...listItem.productList]
}
})
}
return result
}
/**
* 删除已选商品
*/
const handleDeleteItem = (id: number) => {
let informationIds = [...informationIdList]
informationIds = informationIds.filter(item => item !== id)
const informationList = []
dataList.forEach((listItem: any) => {
if(listItem.id !== id) {
informationList.push(listItem)
}
})
changeProps({
props:Object.assign({ ...props }, {
informationIdList: informationIds,
dataList: informationList,
})
})
}
/**
* 根据类型显示选择的信息
* @param type 1-商品详情 2-积分详情 3-店铺主页 4-资讯详情 5-不跳转
*/
const renderSelectItemByType = (list: any[]) => {
// const selectList = getDataListByList(list)
return (
<div>
{
list && list.map(selectItem => (
<div className={styles.setting_line_addItem_line} key={selectItem.id}>
<div className={styles.setting_line_addItem_line_label}></div>
<div className={styles.setting_line_addItem_line_brief}>
<div className={styles.selectInfoBox}>
<ImageBox direction="column" width={60} height={60} imgUrl={selectItem.imageUrl}/>
<div className={cx(styles.selectInfo, styles.shop)}>
<div className={styles.selectInfo_name}>{selectItem.title}</div>
</div>
<div className={styles.selectInfoBox_delete} onClick={() => handleDeleteItem(selectItem.id)}>
<DeleteOutlined />
</div>
</div>
</div>
</div>
))
}
</div>
)
}
/**
* 打开选择模态框
* @param sort
* @param type
*/
const handleOpenSelectModal = () => {
setModalVisible(true)
}
const fetchCategoryByCommodityId = (idList: number[]) => {
return new Promise((resolve) => {
const param = {
idList
}
PublicApi.postSearchMobileShopStoreGetCategoryByCommodityId(param).then((res) => {
message.destroy()
if (res.code === 1000) {
resolve(changeData(res.data))
} else {
resolve([])
}
}).catch(() => {
resolve([])
})
})
}
const changeData = (dataList) => {
if(dataList) {
return dataList.map((dataItem) => {
return {
categoryId: dataItem.id,
categoryName: dataItem.name,
categoryImage: dataItem.imageUrl || "",
productList: dataItem.commodityResponseList ? dataItem.commodityResponseList.map((commodityItem) => {
return {
id: commodityItem.id,
name: commodityItem.name,
sellPoints: commodityItem.sellingPoint,
min: commodityItem.min,
unitName: commodityItem.unitName,
sold: commodityItem.sold,
mainPic: commodityItem.mainPic,
}
}) : []
}
})
}
return []
}
const handleModalOk = async () => {
let selectedRowKeys = productRowCtl.selectedRowKeys
const selectResult = productRowCtl.selectRow
if (!selectedRowKeys || isEmpty(selectedRowKeys)) {
message.info("请选择")
return null
}
if(informationIdList) {
selectedRowKeys = [...informationIdList, ...selectedRowKeys]
} else {
selectedRowKeys = [...selectedRowKeys]
}
changeProps({
props:Object.assign({ ...props }, {
informationIdList: selectedRowKeys,
dataList: [...dataList, ...selectResult],
})
})
setModalVisible(false)
productRowCtl.setSelectRow([])
productRowCtl.setSelectedRowKeys([])
}
const handleModalCancel = async () => {
setModalVisible(false)
}
/**
* 获取模态框数据
* @param param
*/
const fetchTableList = async (param: any) => {
const params: any = {
...param,
idList: informationIdList,
}
const res = await PublicApi.getManageContentInformationPageByIdNotIn(params, {ctlType: 'none'})
return res.data
}
return (
<div className={styles.setting}>
{/* <div className={styles.hideModule}>
<Checkbox checked={!visible} onChange={handleHideChange}>隐藏整个模块</Checkbox>
</div> */}
<div className={styles.setting_line}>
<div className={styles.setting_line_main}>
<div className={styles.setting_line_name} >
<div style={{ flex: 1 }} onClick={() => setExpandState(!expandState)}>
{
expandState ? <img className={styles.icon} src={arrowLeftIcon} /> : <img className={styles.icon} src={arrowRightIcon} />
}
<span>{title}</span>
</div>
</div>
{
expandState && (
<div className={styles.setting_line_addItem}>
<div className={styles.setting_line_addItem_line}>
<div className={styles.setting_line_addItem_line_label}>标题:</div>
<div className={styles.setting_line_addItem_line_brief}>
<Input value={recommendTitle} onChange={(e) => handleNameChange(e.target.value)} />
</div>
</div>
<div className={styles.setting_line_addItem_line}>
<div className={styles.setting_line_addItem_line_label}>推荐资讯:</div>
<div className={styles.setting_line_addItem_line_brief}>
<Button className={styles.selectBtn} icon={<PlusOutlined />} onClick={() => handleOpenSelectModal()}>选择资讯</Button>
</div>
</div>
{
(dataList && dataList.length > 0) ? renderSelectItemByType(dataList) : null
}
</div>
)
}
</div>
</div>
<ModalTable
modalTitle="选择商品"
width={600}
confirm={handleModalOk}
cancel={handleModalCancel}
scroll={{ y: 400 }}
visible={modalVisible}
columns={informationColumn}
rowSelection={productRowSelection}
fetchTableData={params => fetchTableList(params)}
formilyProps={
{
ctx: {
schema: basicSchema,
components: { ModalSearch: Search, SearchSelect, Submit } ,
effects: ($, actions) => {
actions.reset()
useStateFilterSearchLinkageEffect(
$,
actions,
'name',
FORM_FILTER_PATH,
);
}
}
}
}
resetModal={{
destroyOnClose: true
}}
tableProps={{
rowKey: 'id',
onRow: (record) => ({
onClick: () => {
if(!productRowCtl.selectRow.includes(record)) {
productRowCtl.setSelectRow([...productRowCtl.selectRow, record]);
productRowCtl.setSelectedRowKeys([...productRowCtl.selectRow.map(item => item.id), record.id]);
} else {
productRowCtl.setSelectRow(productRowCtl.selectRow.filter(selectRowItem => selectRowItem.id !== record.id));
productRowCtl.setSelectedRowKeys(productRowCtl.selectedRowKeys.filter(selectedRowKeysItem => selectedRowKeysItem !== record.id))
}
},
})
}}
/>
</div>
)
}
export default ChannelInformation
@import "../../../../../../global//styles/utils.less";
@import "../../../../../../global/styles/utils.less";
@import "../../common.less";
.selectBtn {
......
......@@ -202,6 +202,8 @@ const RecommendCommodity: React.FC<BannerPropsType> = (props) => {
})
})
setModalVisible(false)
productRowCtl.setSelectRow([])
productRowCtl.setSelectedRowKeys([])
}
const handleModalCancel = async () => {
......
import React from 'react'
import { SelectedInfoType, clearSelectedStatus, PROPS_TYPES } from 'lingxi-editor-core';
import { SelectedInfoType, PROPS_TYPES } from 'lingxi-editor-core';
import HeaderNav from './components/headerNav'
import Banner from './components/banner'
import QuickNav from './components/quickNav'
......@@ -7,8 +7,8 @@ import HeadBackground from './components/headBackground'
import RecommendCommodity from './components/recommendCommodity'
import BottomNavigation from './components/bottomNavigation'
import MobileChannelGoods from './components/channelGoods'
import MobileChannelInformation from './components/channelInformation'
import styles from './index.less'
import { ConsoleSqlOutlined } from '@ant-design/icons';
interface PropsSettingsPropsType {
selectedInfo: SelectedInfoType | undefined,
......@@ -35,6 +35,8 @@ const PropsSettings: React.FC<PropsSettingsPropsType> = (props) => {
return <QuickNav {...initProps} />
case PROPS_TYPES.mobileChannelGoodsCard:
return <MobileChannelGoods {...initProps} />
case PROPS_TYPES.moibileChannelInformation:
return <MobileChannelInformation {...initProps} />
case PROPS_TYPES.mobileBottomNavigation:
return <BottomNavigation {...initProps} />
default:
......
import React, { useEffect, useState } from 'react'
import cx from 'classnames'
import { changeProps } from 'lingxi-editor-core'
import styles from './styles.less'
interface DataItemType {
id: number,
title: string,
style: number,
viceTitle: string,
productIdList: number[]
productList?: any[],
expand: boolean,
}
interface GoodsCardTitleStylePropsType {
dataList: DataItemType[]
}
const STYLE_THEME_LIST = [
{
id: 0,
styleName: 'one'
},
{
id: 1,
styleName: 'two'
},
{
id: 2,
styleName: 'three'
},
{
id: 3,
styleName: 'four'
},
{
id: 4,
styleName: 'five'
},
{
id: 5,
styleName: 'six'
},
{
id: 6,
styleName: 'seven'
},
]
const GoodsCardTitleStyle: React.FC<GoodsCardTitleStylePropsType> = (props) => {
const { dataList } = props
const [currentItem, setCurrentItem] = useState<DataItemType | null>(null)
const updateCurrentItem = (list: DataItemType[]) => {
const expandList = list.filter((item) => item.expand)
if (expandList.length > 0) {
setCurrentItem(expandList[0])
} else {
setCurrentItem(null)
}
}
useEffect(() => {
console.log(dataList, "dataList")
updateCurrentItem(dataList)
}, [dataList])
const handleSelectStyle = (id: number) => {
const newList = [...dataList]
for(const item of newList) {
if (item.id === currentItem.id) {
item.style = id
}
}
changeProps({
props:Object.assign({ ...props }, { dataList: newList })
})
}
return currentItem ? (
<div className={styles.goods_card_title_style}>
<div className={styles.style_list}>
{
STYLE_THEME_LIST.map((item) => (
<div
className={cx(styles.style_list_item, item.id === currentItem?.style ? styles.active : null)}
key={`style_list_item_${item.id}`}
onClick={() => handleSelectStyle(item.id)}
>
<div className={cx(styles.card_style, styles[item.styleName])}>
<div className={styles["card_style_left"]}>
<div className={styles["card_style_left_title"]}>标题</div>
<label className={styles["card_style_left_vicetitle"]}>副标题</label>
</div>
<div className={styles["card_style_more"]}>
<span>更多 &gt;</span>
</div>
</div>
</div>
))
}
</div>
</div>
) : null
}
export default GoodsCardTitleStyle
.goods_card_title_style {
width: 100%;
padding: 0 12px;
.style_list {
position: relative;
&_item {
position: relative;
padding: 24px;
border: 1px solid #E4E6EB;
margin-bottom: 24px;
&.active {
border: 1px solid #00B382;
&::after {
content: '';
position: absolute;
width: 0;
height: 0;
border-bottom: 12px solid #00B37A;
border-left: 12px solid transparent;
bottom: 0;
right: 0;
z-index: 5;
}
}
.card_style {
display: flex;
padding: 10px 12px;
align-items: center;
border-radius: 8px 8px 0px 0px;
color: #303133;
&.one {
color: #303133;
background: linear-gradient(84deg, #F4F5F7 0%, #FFFFFF 100%);
.card_style_more {
background-color: rgba(48, 49, 51, 0.1);
}
}
&.two {
color: #3D4263;
background: linear-gradient(84deg, #C0C3D8 0%, #DDE1F5 100%);
.card_style_more {
background-color: rgba(48, 49, 51, 0.1);
}
}
&.three {
color: #B53838;
background: linear-gradient(84deg, #F3C4C4 0%, #FFEFEF 100%);
.card_style_more {
background-color: rgba(48, 49, 51, 0.1);
}
}
&.four {
color: #C18223;
background: linear-gradient(135deg, #F6DDB7 0%, #F6E4CF 100%);
.card_style_more {
background-color: rgba(48, 49, 51, 0.1);
}
}
&.five {
color: #008F72;
background: linear-gradient(135deg, #ABE4D2 0%, #D7F8EE 100%);
.card_style_more {
background-color: rgba(48, 49, 51, 0.1);
}
}
&.six {
color: #2E77C2;
background: linear-gradient(135deg, #B3D4F6 0%, #DEE7FF 100%);
.card_style_more {
background-color: rgba(48, 49, 51, 0.1);
}
}
&.seven {
color: #5243AA;
background: linear-gradient(135deg, #C6C0E9 0%, #ECEAF8 100%);
.card_style_more {
background-color: rgba(48, 49, 51, 0.1);
}
}
&_left {
flex: 1;
&_title {
font-size: 16px;
font-weight: 500;
line-height: 18px;
}
&_vicetitle {
display: block;
font-size: 14px;
margin-top: 10px;
line-height: 14px;
}
}
&_more {
width: 60px;
height: 24px;
background-color: rgba(61, 66, 99, 0.1);
font-size: 12px;
text-align: center;
line-height: 24px;
border-radius: 13px;
}
}
}
}
}
import React, { useState } from 'react'
import cx from 'classnames'
import { SelectedInfoType, changeProps } from 'lingxi-editor-core'
import { SelectedInfoType, changeProps, PROPS_TYPES } from 'lingxi-editor-core'
import GoodsCardTitleStyle from './components/GoodsCardTitleStyle'
import styles from './index.less'
interface StyleSettingsPropsType {
......@@ -24,16 +25,30 @@ const StyleSettings: React.FC<StyleSettingsPropsType> = ({ selectedInfo }) => {
}
}
return (
<div className={styles.styleSettings}>
<div className={styles.styleList}>
{
(selectProps && selectProps.stylesThemeList) && selectProps.stylesThemeList.map(item => (
const renderSettingItem = () => {
const { props: initProps, propsConfig } = selectedInfo || {};
const componentType = propsConfig?.componentType
if (componentType) {
switch (componentType.type) {
case PROPS_TYPES.mobileHeaderNav:
return (selectProps && selectProps.stylesThemeList) && selectProps.stylesThemeList.map(item => (
<div className={cx(styles.styleItem, selectKey === item.key ? styles.active : {})} key={item.key} onClick={() => handleChangeStyleTheme(item.key)}>
<img className={styles.themeImg} src={item.img} title={item.key} />
</div>
))
}
case PROPS_TYPES.mobileChannelGoodsCard:
return <GoodsCardTitleStyle {...initProps} />
default:
return null
}
}
}
return (
<div className={styles.styleSettings}>
<div className={styles.styleList}>
{renderSettingItem()}
</div>
</div>
)
......
......@@ -369,11 +369,15 @@ const CommodityDetail = (props) => {
setSelectCommodityUnitPriceId(item.commodityUnitPriceAndPicId)
setCurrentPriceRange(sortUnitPrice(item.unitPrice))
setAttrAndValList(item)
let productId: number = item.id
if (layoutType === LAYOUT_TYPE.channel || layoutType === LAYOUT_TYPE.ichannel) {
productId = item.commodityUnitPriceAndPicId
}
getStockCountByProductId(productId)
setStockCount(item.stockCount)
// if(getAuth()) {
// let productId: number = item.id
// if (layoutType === LAYOUT_TYPE.channel || layoutType === LAYOUT_TYPE.ichannel) {
// productId = item.commodityUnitPriceAndPicId
// }
// getStockCountByProductId(productId)
// }
}
}
}
......@@ -383,17 +387,17 @@ const CommodityDetail = (props) => {
* 根据商品skuid获取商品库存数量
* @param productId
*/
const getStockCountByProductId = (productId: number) => {
const param: any = {
productId,
shopId: storeId,
}
PublicApi.getWarehouseStockByProductId(param).then((res => {
if (res.code === 1000) {
setStockCount(res.data)
}
}))
}
// const getStockCountByProductId = (productId: number) => {
// const param: any = {
// productId,
// shopId: storeId,
// }
// PublicApi.getWarehouseStockByProductId(param).then((res => {
// if (res.code === 1000) {
// setStockCount(res.data)
// }
// }))
// }
const judgeArrisCommon = (list, otherList) => {
if (list.length === otherList.length) {
......
......@@ -127,6 +127,7 @@
cursor: pointer;
color: #909399;
font-size: 12px;
display: block;
&:hover {
color: var(--mall_main_color);
......@@ -151,6 +152,19 @@
width: 270px;
flex-direction: column;
line-height: 20px;
.delete {
text-decoration: line-through;
}
.tip {
color: #D32F2F;
}
.member_unitprice {
color: #D32F2F;
margin-left: 8px;
}
}
.settlement_box {
......
This diff is collapsed.
......@@ -121,16 +121,16 @@ export const mobileChannelGoodsCard = {
"canHide": false,
"props": {
dataList: [
{
style: 0,
title: "电气电工",
viceTitle: "ELECTRICAL",
},
{
style: 1,
title: "机械设备",
viceTitle: "EQUIPMENT",
}
// {
// style: 0,
// title: "电气电工",
// viceTitle: "ELECTRICAL",
// },
// {
// style: 1,
// title: "机械设备",
// viceTitle: "EQUIPMENT",
// }
]
}
}
......@@ -140,17 +140,17 @@ export const mobileChannelInformation = {
key: "6",
"6": {
"componentName": "MobileChannelInformation",
"componentType": PROPS_TYPES.mobileBanner,
"componentType": PROPS_TYPES.moibileChannelInformation,
"title": "行业资讯",
"canEdit": true,
"canHide": false,
"props": {
title: "行业资讯",
dataList: []
}
}
}
export const mobileBottomNavigation = {
key: "7",
"7": {
......
......@@ -102,41 +102,22 @@ const mobileShopTempleteEdit: React.FC<ShopPreviewPropsType> = (props) => {
* 根据选中的类型和id获取信息
* @param data
*/
const getSelectInfo = (data): Promise<any[] | undefined> => {
const getSelectInfo = (data, channelMemberId): Promise<any[] | undefined> => {
return new Promise((resolve) => {
let getFn: any = null
const param: any = {
current: 1,
pageSize: 100,
idInList: data.productIdList,
priceTypeList: [1],
channelMemberId,
}
switch(data.type) {
case 1:
param.idInList = data.recommend
getFn = PublicApi.postSearchMobileShopEnterpriseGetCommodityList
break
case 2:
param.idList = data.recommend
getFn = PublicApi.getTemplateWebMemberShopWebRecommendList
break
case 3:
param.idList = data.recommend
getFn = PublicApi.postSearchMobileShopEnterpriseGetCategoryBrand
break
case 4:
param.idList = data.recommend
getFn = PublicApi.getManageContentInformationPageByIdIn
break
default:
break
}
getFn ? getFn(param).then(res => {
PublicApi.postSearchMobileShopChannelGetCommodityList(param).then(res => {
message.destroy()
resolve(data.type === 3 ? res.data : res.data.data)
resolve(res.data.data)
}).catch(() => {
resolve(undefined)
}) : resolve(undefined)
})
})
}
......@@ -208,6 +189,34 @@ const mobileShopTempleteEdit: React.FC<ShopPreviewPropsType> = (props) => {
}
const getProductInfo = async (dataList, channelMemberId) => {
const newDataList: any[] = []
for(let index = 0; index < dataList.length; index += 1) {
const item = dataList[index]
if (item.productIdList && item.productIdList.length > 0) {
item.productList = await getSelectInfo(item, channelMemberId)
}
newDataList.push(item)
}
return newDataList
}
const getInformationInfo = async (ids: number[]) => {
if (ids && ids.length > 0) {
const params: any = {
current: 1,
pageSize: 100,
idList: ids,
}
const res = await PublicApi.getManageContentInformationPageByIdIn(params, {ctlType: 'none'})
if(res.code === 1000) {
return res.data.data
}
}
return []
}
const getComponentsConfig = async () => {
try {
const appConfig = await getAppChannelConfig()
......@@ -217,15 +226,30 @@ const mobileShopTempleteEdit: React.FC<ShopPreviewPropsType> = (props) => {
const channelInfo = await fetchChannelInfo()
mobileChannelHeaderNav[mobileChannelHeaderNav.key].props.name = channelInfo.memberName
if(channelInfo.memberId) {
if (channelInfo.memberId) {
const categoryList = await getCustomerCategoryTreeById(channelInfo.memberId)
mobileChannelCategory[mobileChannelCategory.key].props.dataList = categoryList
mobileChannelGoodsCard[mobileChannelGoodsCard.key].props.channelMemberId = channelInfo.memberId
if (appConfig?.productBO) {
mobileChannelGoodsCard[mobileChannelGoodsCard.key].props.dataList = await getProductInfo(appConfig?.productBO.productDetailsBOList, channelInfo.memberId)
}
}
if(appConfig?.advertBO) {
if (appConfig?.advertBO) {
mobileBanner[mobileBanner.key].props.dataList = appConfig?.advertBO.advertDetailsBOList
}
if (appConfig?.informationBO) {
mobileChannelInformation[mobileChannelInformation.key].props.title = appConfig?.informationBO.title
mobileChannelInformation[mobileChannelInformation.key].props.informationIdList = appConfig?.informationBO.informationIdList
mobileChannelInformation[mobileChannelInformation.key].props.dataList = await getInformationInfo(appConfig?.informationBO.informationIdList)
}
if (appConfig?.bottomBO) {
mobileBottomNavigation[mobileBottomNavigation.key].props.dataList = appConfig?.bottomBO.bottomDetailsBOList
}
const config = {
...mallLayoutConfig,
...mobileChannelHeaderNav,
......@@ -247,7 +271,7 @@ const mobileShopTempleteEdit: React.FC<ShopPreviewPropsType> = (props) => {
return !loading ? (
<LegoProvider initState={{ componentConfigs: componentConfigs }} config={config}>
<div className={styles['wrapper']}>
<ToolBar type={1} title="渠道商城-首页" showActions={true} layoutType={LAYOUT_TYPE.shop} templateId={id} />
<ToolBar type={1} title="渠道商城-首页" showActions={true} layoutType={LAYOUT_TYPE.channel} templateId={id} />
<div className={styles['content']}>
<AllComponents />
<div className={styles['app-wrapper']}>
......
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