Commit bea3b9d4 authored by 前端-黄佳鑫's avatar 前端-黄佳鑫

feat: 店铺SEO设置

parent c8bc2aa4
......@@ -10,25 +10,25 @@ import { RouterChild } from '../utils/index';
const ShopRoute: RouterChild = {
path: '/memberCenter/channelAbility',
name: 'channelAbility',
name: '渠道能力',
icon: 'channel',
routes: [
// 创建渠道信息
{
path: '/memberCenter/channelAbility/infoManage',
name: 'shopInfoManage',
name: '创建渠道信息',
component: '@/pages/channel/channelInfo',
},
// 渠道模板列表
{
path: '/memberCenter/channelAbility/template',
name: 'shopTemplate',
name: '渠道模板列表',
component: '@/pages/channel/channelTemplate',
},
// 渠道模板详情
{
path: '/memberCenter/channelAbility/template/detail',
name: 'shopTemplate',
name: '渠道模板详情',
hideInMenu: true,
component: '@/pages/channel/templateDetail',
}
......
......@@ -6,8 +6,8 @@
*/
// import CommodityRoute from './commodityRoute' // 商品能力路由
// import MemberRoute from './memberRoute' // 会员能力路由
// import ShopRoute from './shopRoute' // 店铺能力路由
// import ChannelRoute from './channelRoute' // 渠道能力路由
import ShopRoute from './shopRoute' // 店铺能力路由
import ChannelRoute from './channelRoute' // 渠道能力路由
// import TranactionRoute from './tranactionRoute' // 交易能力路由
// import LogisticsRoute from './logisticsRoutes' // 物流能力路由
// import PayandSettleRoute from './payandSettle' //支付与结算
......@@ -57,6 +57,8 @@ const memberCenterRoute = {
// ShopRoute,
// CommodityRoute,
// srm开发临时使用...
// ChannelRoute,
// ShopRoute,
// ProcurementRoute,
// // 合同能力
// contracRoute,
......
......@@ -26,7 +26,8 @@ export const demandPlanRoute = [
/** 待新增需求计划 */
path: '/memberCenter/procurementAbility/demandPlan/demandPlanAdded/add',
name: '待新增需求计划',
component: '@/pages/transaction/purchaseAbility/demandPlan/demandPlanAdded/add'
component: '@/pages/transaction/purchaseAbility/demandPlan/demandPlanAdded/add',
hideInMenu: true,
},
{
/** 待审核需求计划(一级) */
......
......@@ -10,27 +10,50 @@ import { RouterChild } from '../utils/index';
const ShopRoute: RouterChild = {
path: '/memberCenter/shopAbility',
name: 'shopAbility',
name: '店铺能力',
icon: 'shop',
routes: [
// 创建店铺信息
{
path: '/memberCenter/shopAbility/infoManage',
name: 'shopInfoManage',
name: '创建店铺',
component: '@/pages/shop/shopInfo',
},
// 店铺模板列表
{
path: '/memberCenter/shopAbility/template',
name: 'shopTemplate',
name: '店铺模板列表',
component: '@/pages/shop/shopTemplate',
},
// 店铺模板详情
{
path: '/memberCenter/shopAbility/template/detail',
name: 'shopTemplate',
name: '店铺模板详情',
hideInMenu: true,
component: '@/pages/shop/templateDetail',
},
{
path: '/memberCenter/shopAbility/shopSeo',
name: '店铺SEO设置',
component: '@/pages/shop/shopSeo',
},
{
path: '/memberCenter/shopAbility/shopSeo/add',
name: '新建SEO',
hideInMenu: true,
component: '@/pages/shop/shopSeo/add',
},
{
path: '/memberCenter/shopAbility/shopSeo/edit',
name: '修改SEO',
hideInMenu: true,
component: '@/pages/shop/shopSeo/add',
},
{
path: '/memberCenter/shopAbility/shopSeo/detail',
name: '查看SEO',
hideInMenu: true,
component: '@/pages/shop/shopSeo/add',
}
]
......
......@@ -76,10 +76,10 @@ const CityCascader: React.FC<CitySelectPropsType> = (props) => {
})
if (item.areaResponses) {
const tempCityList = []
// tempCityList.push({
// lable: "所有",
// value: "0"
// })
tempCityList.push({
lable: "所有",
value: "0"
})
for (const cityItem of item.areaResponses) {
tempCityList.push({
lable: cityItem.name,
......
import React from 'react';
import { Form, Input, Tooltip } from 'antd';
import CitySelect from '../CitySelect';
import { QuestionCircleOutlined } from '@ant-design/icons';
import RequireItem from '../RequireItem';
const layout: any = {
colon: false,
labelCol: { style: { width: '174px' } },
wrapperCol: { span: 9 },
labelAlign: "left"
}
const CreatePortal = () => {
const [form] = Form.useForm();
return (
<Form {...layout} form={form}>
{/* 归属地市 */}
<Form.Item label="归属地市">
<Input />
</Form.Item>
{/* 公司LOGO */}
<Form.Item label="公司LOGO">
<Input />
</Form.Item>
{/* 公司简介 */}
<Form.Item label="公司简介">
<Input />
</Form.Item>
{/* 厂房照片 */}
<Form.Item label="厂房照片">
<Input />
</Form.Item>
{/* 厂房照片 */}
<Form.Item label={<RequireItem label="资质荣誉" brief={<Tooltip placement="top" title="如商标注册证书、品牌授权证书等证明材料"><QuestionCircleOutlined /></Tooltip>} />}>
<Input />
</Form.Item>
</Form>
)
}
export default CreatePortal
......@@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react';
import { Modal, Result, Progress, Upload, Button } from 'antd';
import { FileExcelOutlined } from '@ant-design/icons';
import styles from './index.less';
import { UPLOAD_TYPE } from '@/constants'
import { PublicApi } from '@/services/api';
interface Uploader {
......@@ -19,7 +20,7 @@ const UploadModal: React.FC<Uploader> = props => {
const [file, setFile] = useState();
const [fileList, setFileList] = useState([]);
const downLoadTemplate = () => {};
const downLoadTemplate = () => { };
const step0Description = (
<>
......@@ -148,14 +149,19 @@ const UploadModal: React.FC<Uploader> = props => {
const beforeUpload = file => {
let extension = file.name.split('.')[1];
if (['xlsx', 'xls'].includes[extension]) {
if (!['xlsx', 'xls'].includes(extension)) {
setTimeout(() => {
setExceptionCheck(true);
}, 250);
}
return false;
const flag = ['xlsx', 'xls'].includes(extension)
return flag;
};
const handleChange = ({file}) => {
console.log(file)
}
// 上传
const handleUpload = (type: string, file?: any, step: number = 0) => {
let title = '';
......@@ -178,7 +184,7 @@ const UploadModal: React.FC<Uploader> = props => {
if (step === 1) return false;
};
const exportErrorLog = () => {};
const exportErrorLog = () => { };
const handleClose = () => {
setModalStep(0);
......@@ -204,20 +210,19 @@ const UploadModal: React.FC<Uploader> = props => {
icon={<FileExcelOutlined />}
title={step0Description}
extra={
// <Upload
// name="file"
// action=""
// fileList={fileList}
// beforeUpload={file => beforeUpload(file)}
// customRequest={file => console.log(file)}
// >
// <Button type="primary">导入</Button>
// </Upload>
<>
<Button type="primary" onClick={() => handleUpload('upload')}>
导入
</Button>
</>
<Upload
action="/api/purchase/purchase/inquiry/import/excel/check"
showUploadList={false}
beforeUpload={beforeUpload}
onChange={handleChange}
>
<Button type="primary">导入</Button>
</Upload>
// <>
// <Button type="primary" onClick={() => handleUpload('upload')}>
// 导入
// </Button>
// </>
}
/>
</>
......
......@@ -2278,3 +2278,19 @@ export const ExpertRectractStatus = {
4: '已拒绝',
5: '已评标',
}
/** 页面类型 */
export const SELECT_NAME = {
1: '店铺首页',
2: '关于我们'
}
/** 门户类型 */
export enum DOORTYPE {
/** 店铺门户 */
STORE_DOORTYPE = 1,
/** 渠道门户 */
PLACE_DOORTYPE,
/** 采购门户 */
PROCUREMENT_DOORTYPE
}
......@@ -121,3 +121,42 @@
}
}
}
.revise_style {
.upload_data {
width: 575px;
.upload_item {
padding: 5px 8px;
margin-bottom: 16px;
display: flex;
align-items: center;
justify-content: space-between;
background-color: #ecf7ff;
.upload_left {
display: flex;
align-items: center;
color: #303133;
:global {
.anticon-file-word {
color: #4279df;
font-size: 20px;
margin-right: 8px;
}
}
}
.upload_right {
color: #00B37A;
cursor: pointer;
:global {
.anticon-delete {
margin-left: 19px;
color: #C0C4CC;
}
}
}
}
}
}
import React, { useState, useEffect } from 'react'
import { PageHeaderWrapper } from '@ant-design/pro-layout'
import { Form, Input, Button, Tooltip, Select, message } from 'antd'
import { Form, Input, Button, Tooltip, Select, message, Upload } from 'antd'
import { Prompt } from 'umi'
import { inject } from 'mobx-react'
import { QuestionCircleOutlined, DeleteOutlined, CopyOutlined } from '@ant-design/icons'
import { QuestionCircleOutlined, DeleteOutlined, CopyOutlined, UploadOutlined, LinkOutlined } from '@ant-design/icons'
import CitySelect from '@/components/CitySelect'
import RequireItem from '@/components/RequireItem'
import { PublicApi } from '@/services/api'
......@@ -13,6 +13,7 @@ import cx from 'classnames'
import styles from './index.less'
import { getAuth } from '@/utils/auth'
import { isEmpty } from '@formily/antd/esm/shared'
import { UPLOAD_TYPE } from '@/constants'
interface ShopInfoPropsType {
SiteStore: {
......@@ -38,6 +39,34 @@ const ShopInfo: React.FC<ShopInfoPropsType> = (props) => {
const [shopId, setShopId] = useState<number>()
const [confirmLoading, setConfirmLoading] = useState<boolean>(false)
/** 上传公司画册 */
const [file, setFile] = useState<any>({});
const [fileLoading, setFileLoading] = useState<boolean>(false);
const beforeDocUpload = (file: any) => {
const isLt50M = file.size / 1024 / 1024 < 50;
if (!isLt50M) {
message.error('上传文件大小不超过 50M!');
}
return isLt50M;
}
const handleChange = ({ file }) => {
setFileLoading(true);
if (file.response) {
if (file.response.code !== 1000) {
setFileLoading(false);
return
}
setFileLoading(false);
setFile({
albumName: file.name,
albumUrl: file.response.data,
})
}
}
const fileRemove = () => {
setFile({})
}
useEffect(() => {
fetchShopInfo()
fetchAllShop()
......@@ -67,7 +96,7 @@ const ShopInfo: React.FC<ShopInfoPropsType> = (props) => {
}
PublicApi.getTemplateWebMemberShopWebFindCurrMemberShop(param).then(res => {
const data:any = res.data
const data: any = res.data
if (res.code === 1000) {
setShopInfo(data)
setSelectCityData(initMemberShopArea(data.memberShopAreas))
......@@ -155,12 +184,8 @@ const ShopInfo: React.FC<ShopInfoPropsType> = (props) => {
if (!checkMemberShopAreas(value.memberShopAreas)) {
return
}
// if (!shopId) {
// message.error("店铺链接不能为空")
// return
// }
value.storeUrl = storeUrl || `${siteUrl}/shop`
value.shopId = shopId
value.albumName = file.albumName;
value.albumUrl = file.albumUrl;
setConfirmLoading(true)
PublicApi.postTemplateWebMemberShopWebSaveCurrMemberShop(value).then(res => {
if (res.code === 1000) {
......@@ -214,17 +239,6 @@ const ShopInfo: React.FC<ShopInfoPropsType> = (props) => {
}
/**
* 添加推广页
* @param url
*/
const handleAddPromotionPic = (url: string) => {
setPromotionPic(url)
form.setFieldsValue({
promotionPic: url
})
}
/**
* 添加荣誉图片
* @param url
*/
......@@ -236,6 +250,7 @@ const ShopInfo: React.FC<ShopInfoPropsType> = (props) => {
}
const handleMallSelectChange = (mallId: number) => {
setShopId(mallId)
// let selectItem = allMallList.filter(item => item.id === mallId)
setShopId(mallId)
if (!shopInfo) {
......@@ -286,7 +301,7 @@ const ShopInfo: React.FC<ShopInfoPropsType> = (props) => {
if (!shopInfo) {
return null
}
if (shopId && shopInfo.shopId && shopInfo.memberId) {
if (shopId && shopInfo.memberId) {
const resUrl = getMallItemAndSetUrl(shopId)
return resUrl ? (
<div className={styles.shop_url}>
......@@ -401,34 +416,41 @@ const ShopInfo: React.FC<ShopInfoPropsType> = (props) => {
</Form.Item>
<Form.Item
labelAlign="left"
name="promotionPic"
label={<RequireItem label="推广页" />}
name="albumName"
label={<RequireItem label="宣传画册" />}
className={styles.revise_style}
>
<div className={styles.form_item_wrap}>
<div className={styles.img_list}>
{
promotionPic && (
<div className={cx(styles.upload_btn, styles.large, styles.upload)}>
<div className={styles.delete_btn} onClick={() => setPromotionPic("")}><DeleteOutlined /></div>
<img className={styles.upload_img} src={promotionPic} />
</div>
)
}
<UploadImage
imgUrl={""}
large={true}
fileMaxSize={1024}
size="106x107"
onChange={(url) => handleAddPromotionPic(url)}
/>
</div>
<div className={styles.upload_data}>
{Object.keys(file).length > 0 && (
<div className={styles.upload_item}>
<div className={styles.upload_left}>
<LinkOutlined />
<span>{file.albumName}</span>
</div>
<div className={styles.upload_right} onClick={fileRemove}>
<DeleteOutlined />
</div>
</div>
)}
</div>
{Object.keys(file).length === 0 && (
<Upload
action="/api/file/file/upload"
data={{ fileType: UPLOAD_TYPE }}
showUploadList={false}
accept='.pdf'
beforeUpload={beforeDocUpload}
onChange={handleChange}
>
<Button loading={fileLoading} icon={<UploadOutlined />}>上传文件</Button>
<div style={{ marginTop: '8px' }}>一次上传一个文件,每个附件大小不能超过 50M</div>
</Upload>
)}
</Form.Item>
<Form.Item
labelAlign="left"
name="shopId"
label={<RequireItem label="店铺链接" />}
// rules={[{ required: true, message: "请输入客服链接" }]}
>
<Select allowClear value={shopId} className={styles.form_item} onChange={handleMallSelectChange}>
{
......@@ -442,42 +464,6 @@ const ShopInfo: React.FC<ShopInfoPropsType> = (props) => {
}
</Form.Item>
<Form.Item
labelAlign="left"
name="customerUrl"
label={<RequireItem label="客服链接" />}
rules={[{ pattern: /(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-.,@?^=%&:/~+#]*[\w\-@?^=%&/~+#])?/, message: '请输入正确的客服链接' }]}
>
<Input allowClear autoComplete="off" className={styles.form_item} />
</Form.Item>
<Form.Item
labelAlign="left"
name="phone"
label={<RequireItem label="联系电话" />}
>
<Input allowClear autoComplete="off" className={styles.form_item} />
</Form.Item>
<Form.Item
labelAlign="left"
name="address"
label={<RequireItem label="详细地址" />}
>
<Input allowClear autoComplete="off" className={styles.form_item} />
</Form.Item>
<Form.Item
labelAlign="left"
name="lng"
label={<RequireItem label="经度" />}
>
<Input allowClear autoComplete="off" className={styles.form_item} />
</Form.Item>
<Form.Item
labelAlign="left"
name="lat"
label={<RequireItem label="纬度" />}
>
<Input allowClear autoComplete="off" className={styles.form_item} />
</Form.Item>
<Form.Item
label={<RequireItem label="" />}
>
<Button loading={confirmLoading} type="primary" style={{ marginRight: 16 }} onClick={handleSave}>保存</Button>
......
import React, { useEffect, useState } from 'react';
import { history, Prompt } from 'umi';
import { Card, Button, Tabs, Form, Select, Tooltip, Input, Typography } from 'antd';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import ReutrnEle from '@/components/ReturnEle';
import RequireItem from '@/components/RequireItem';
import { QuestionCircleOutlined } from '@ant-design/icons';
import { SELECT_NAME, DOORTYPE } from '@/constants';
import { PublicApi } from '@/services/api';
const { TabPane } = Tabs
const layout: any = {
colon: false,
labelCol: { style: { width: '174px' } },
wrapperCol: { span: 9 },
labelAlign: "left"
}
const ShopSeoAdded = () => {
const { query: { id }, pathname } = history.location;
const link = pathname.split('/')[pathname.split('/').length - 1];
console.log(link)
const [form] = Form.useForm()
const [confirmLoading, setConfirmLoading] = useState<boolean>(false);
const [formIsHalfFilledOut, setFormIsHalfFilledOut] = useState<boolean>(false);
const handleFormValueChange = () => {
setFormIsHalfFilledOut(true)
}
const handleSave = (e: any) => {
e.preventDefault()
const fetch = (link === 'add' ? PublicApi.postTemplateWebSeoWebAdd : PublicApi.postTemplateWebSeoWebUpdate);
form.validateFields().then((value: any) => {
const type: number = value.type;
const params = {
id,
...value,
doorType: DOORTYPE.STORE_DOORTYPE,
name: SELECT_NAME[type]
}
setConfirmLoading(true)
fetch(params).then(res => {
if (res.code !== 1000) {
setConfirmLoading(false);
return
}
setConfirmLoading(false)
setFormIsHalfFilledOut(false)
history.goBack();
}).catch(() => {
setConfirmLoading(false)
})
})
}
useEffect(() => {
if (id) {
PublicApi.getTemplateWebSeoWebGet({ id }).then(res => {
if (res.code !== 1000) {
return
}
form.setFieldsValue({...res.data})
})
}
}, [])
return (
<PageHeaderWrapper
onBack={() => history.goBack()}
backIcon={<ReutrnEle description="返回" />}
extra={
link !== 'detail' && <Button type="primary" loading={confirmLoading} onClick={handleSave}> 保存</Button>
}
>
<Prompt when={formIsHalfFilledOut} message="您还有未保存的内容,是否确定要离开?" />
<Card>
<Tabs
type="card"
>
<TabPane tab='基本信息' key='1'>
<Form
{...layout}
form={form}
hideRequiredMark={true}
onValuesChange={handleFormValueChange}
>
<Form.Item
name='type'
label={<RequireItem label="页面名称" isRequire={true} />}
rules={[{ required: true, message: "请选择页面名称" }]}
>
<Select disabled={link === 'detail'}>
<Select.Option value={1}>店铺首页</Select.Option>
<Select.Option value={2}>关于我们</Select.Option>
</Select>
</Form.Item>
<Form.Item
name='link'
label={<RequireItem label="访问链接" brief={<Tooltip placement="top" title="访问该页面的链接"><QuestionCircleOutlined /></Tooltip>} />}
>
<Input disabled={link === 'detail'} addonBefore={<Typography.Text type='secondary'>http://</Typography.Text>} />
</Form.Item>
<Form.Item
name='title'
label={<RequireItem label="标题" isRequire={true} brief={<Tooltip placement="top" title="用于显示在页面title标签的内容,便于搜索引擎抓取"><QuestionCircleOutlined /></Tooltip>} />}
rules={[{ required: true, message: "请输入标题" }]}
>
<Input disabled={link === 'detail'} placeholder='最长100个字符,50个汉字' />
</Form.Item>
<Form.Item
name='description'
label={<RequireItem label="描述" isRequire={true} brief={<Tooltip placement="top" title="用于显示在页面Description标签的内容,便于搜索引擎抓取"><QuestionCircleOutlined /></Tooltip>} />}
rules={[{ required: true, message: "请输入描述" }]}
>
<Input.TextArea disabled={link === 'detail'} rows={5} placeholder="最长200个字符,100个汉字" maxLength={200} />
</Form.Item>
<Form.Item
name='keywords'
label={<RequireItem label="关键字" isRequire={true} brief={<Tooltip placement="top" title="用于显示在页面Keywords标签的内容,便于搜索引擎通过关键词搜索时抓取页面,多个关键词用豆号分隔"><QuestionCircleOutlined /></Tooltip>} />}
rules={[{ required: true, message: "请输入关键字" }]}
>
<Input.TextArea disabled={link === 'detail'} rows={5} placeholder="最长200个字符,100个汉字" maxLength={200} />
</Form.Item>
</Form>
</TabPane>
</Tabs>
</Card>
</PageHeaderWrapper>
)
}
export default ShopSeoAdded;
import React, { ReactNode, useRef } from 'react';
import { ISchema } from '@formily/antd';
import { history } from 'umi';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { Card, Row, Col, Button, Popconfirm, Typography } from 'antd';
import { StandardTable } from 'god';
import { ColumnType } from 'antd/lib/table/interface';
import { PublicApi } from '@/services/api';
import NiceForm from '@/components/NiceForm';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { createFormActions, FormEffectHooks } from '@formily/antd';
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch';
import { searchSelectGetSelectCategoryOptionEffect } from '@/pages/transaction/effect/index';
import { PauseCircleOutlined, PlayCircleOutlined, PlusOutlined } from '@ant-design/icons';
const ShopSeo = () => {
const ref = useRef<any>({});
const formActions = createFormActions();
/** 修改状态 */
const confirm = (e: any) => {
const status = e.status === 1 ? 0 : 1;
PublicApi.postTemplateWebSeoWebUpdateStatus({ id: e.id, status }).then(res => {
if (res.code !== 1000) {
return
}
ref.current.reload();
})
}
/** 删除 */
const handleDelete = (id: number) => {
PublicApi.postTemplateWebSeoWebDelete({ id }).then(res => {
if (res.code !== 1000) {
return
}
ref.current.reload();
})
}
const columns: ColumnType<any>[] = [
{
title: 'ID',
key: 'id',
dataIndex: 'id',
width: 128,
},
{
title: '页面名称',
key: 'name',
dataIndex: 'name',
render: (text: any,record: any) => <Typography.Link href={`/memberCenter/shopAbility/shopSeo/detail?id=${record.id}`}>{text}</Typography.Link>
},
{
title: '访问链接',
key: 'link',
dataIndex: 'link',
},
{
title: '状态',
key: 'status',
dataIndex: 'status',
width: 256,
render: (text: any, record: any) => {
let component: ReactNode = null
component = (
<Popconfirm
title="确定要执行这个操作?"
onConfirm={() => confirm(record)}
okText="是"
cancelText="否"
>
<Button
type="link"
style={record.status === 1 ? { color: '#00B37A' } : { color: 'red' }}>
{record.status === 1 ? <>有效 <PlayCircleOutlined /></> : <>无效 <PauseCircleOutlined /></>}
</Button>
</Popconfirm>
)
return component
}
},
{
title: '操作',
key: 'action',
dataIndex: 'action',
width: 256,
render: (_text: any, record: any) => (
<>
<Popconfirm
title="确定要执行这个操作?"
onConfirm={() => handleDelete(record.id)}
disabled={record.status === 1}
okText="是"
cancelText="否"
>
<Button disabled={record.status === 1} type='link'>删除</Button>
</Popconfirm>
<Button disabled={record.status === 1} type='link' onClick={() => history.push(`/memberCenter/shopAbility/shopSeo/edit?id=${record.id}`)}>修改</Button>
</>
)
}
]
// 搜索
const search = (values: any) => {
ref.current.reload(values)
}
const fetchData = (params: any) => {
return new Promise(resolve => {
PublicApi.getTemplateWebSeoWebPage({ ...params, doorType: 1 }).then(res => {
resolve(res.data)
})
})
}
const controllerBtns = <Row>
<Col span={6}>
<Button
onClick={() => history.push('/memberCenter/shopAbility/shopSeo/add')}
type="primary"
icon={<PlusOutlined />}
>
新建
</Button>
</Col>
</Row>
const schema: ISchema = {
type: 'object',
properties: {
megalayout: {
type: 'object',
"x-component": 'mega-layout',
"x-component-props": {
grid: true
},
properties: {
ctl: {
type: 'object',
"x-component": "Children",
"x-component-props": {
children: "{{controllerBtns}}"
}
},
name: {
type: 'string',
"x-component": "Search",
"x-mega-props": {
},
"x-component-props": {
placeholder: '页面名称',
advanced: false
}
}
}
}
}
}
return (
<PageHeaderWrapper>
<Card>
<StandardTable
tableProps={{
rowKey: 'id',
}}
columns={columns}
currentRef={ref}
fetchTableData={(params: any) => fetchData(params)}
controlRender={
<NiceForm
actions={formActions}
expressionScope={{ controllerBtns }}
onSubmit={values => search(values)}
effects={($, actions) => {
useStateFilterSearchLinkageEffect($, actions, 'name', FORM_FILTER_PATH)
FormEffectHooks.onFieldChange$('category').subscribe(state => {
searchSelectGetSelectCategoryOptionEffect(actions, 'category')
})
}}
schema={schema}
>
</NiceForm>
}
/>
</Card>
</PageHeaderWrapper >
)
}
export default ShopSeo;
import React from 'react';
import React, { useState } from 'react';
import { Form, Radio, Button, Table } from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import { ColumnType } from 'antd/lib/table/interface';
import SelectProduct from './selectProduct';
const layout: any = {
colon: false,
......@@ -64,6 +65,12 @@ const Material = () => {
dataIndex: 'operate'
}
]
const [visible, setVisible] = useState<boolean>(false);
const handleConfirm = (e: any) => {
console.log(e, 98)
}
return (
<Form {...layout} form={form}>
<Form.Item
......@@ -82,6 +89,7 @@ const Material = () => {
style={{
marginBottom: '24px',
}}
onClick={() => setVisible(true)}
>
<PlusOutlined />
添加
......@@ -90,6 +98,12 @@ const Material = () => {
columns={columns}
dataSource={[]}
/>
{/* 选择货品 */}
<SelectProduct
visible={visible}
onclose={() => setVisible(false)}
confirm={handleConfirm}
/>
</Form>
)
}
......
import React, { useRef } from 'react';
import {
Drawer,
Button
} from 'antd';
import { StandardTable } from 'god';
import { ColumnType } from 'antd/lib/table/interface';
import { PublicApi } from '@/services/api';
import NiceForm from '@/components/NiceForm';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { createFormActions, FormEffectHooks } from '@formily/antd';
import { useRowSelectionTable } from '@/hooks/useRowSelectionTable';
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch';
import { searchSelectGetSelectCategoryOptionEffect } from '@/pages/transaction/effect/index';
import {
SelectProductSchema,
} from '../../../schema';
const formActions = createFormActions();
interface Iprops {
visible: boolean,
onclose?(),
confirm?(e:any),
}
const SelectProduct: React.FC<Iprops> = (props: any) => {
const ref = useRef({});
const { visible, onclose, confirm } = props;
const [rowSelection, RowCtl] = useRowSelectionTable({ customKey: 'id' });
const columns: ColumnType<any>[] = [
{
title: '货号',
key: 'code',
dataIndex: 'code'
},
{
title: '货品名称',
key: 'name',
dataIndex: 'name'
},
{
title: '规格型号',
key: 'type',
dataIndex: 'type'
},
{
title: '品类',
key: 'customerCategory',
dataIndex: 'customerCategory',
render: (text: any) => <span>{(text && Object.keys(text).length > 0) && text.name}</span>
},
{
title: '品牌',
key: 'brand',
dataIndex: 'brand',
render: (text: any) => <span>{(text && Object.keys(text).length > 0) && text.name}</span>
},
{
title: '单位',
key: 'unitName',
dataIndex: 'unitName'
},
]
const fetchGoodsData = (params: any) => {
return new Promise(resolve => {
PublicApi.getProductGoodsGetGoodsList(params).then(res => {
const { data } = res
resolve(data)
})
})
}
return (
<Drawer
visible={visible}
onClose={onclose}
title='选择货品'
width={900}
footer={
<div
style={{
textAlign: 'right',
}}
>
<Button onClick={onclose} style={{ marginRight: 8 }}>
取消
</Button>
<Button onClick={() => confirm(RowCtl)} type="primary">
确定
</Button>
</div>
}
>
<StandardTable
currentRef={ref}
columns={columns}
tableProps={{ rowKew: 'id' }}
rowSelection={rowSelection}
fetchTableData={(params) => fetchGoodsData(params)}
controlRender={
<NiceForm
actions={formActions}
effects={($, actions) => {
useStateFilterSearchLinkageEffect($, actions, 'name', FORM_FILTER_PATH)
FormEffectHooks.onFieldChange$('category').subscribe(state => {
searchSelectGetSelectCategoryOptionEffect(actions, 'category')
})
}}
schema={SelectProductSchema}
>
</NiceForm>
}
/>
</Drawer>
)
}
export default SelectProduct
......@@ -15,6 +15,7 @@ import style from './index.less';
import DrawerWrite from '../modal/drawerWrite';
import Import from '../modal/import';
import { PublicApi } from '@/services/api';
import UploadModal from '@/components/UploadModal';
const layout: any = {
colon: false,
......@@ -295,10 +296,15 @@ const Material: React.FC<Iprops> = (props: any) => {
)}
{materielMode === 2
&& (
<Import
flag={flag}
onClose={() => setFlag(false)}
<UploadModal
visibleModal={flag}
fileText='货品资料'
onCancel={() => setFlag(false)}
/>
// <Import
// flag={flag}
// onClose={() => setFlag(false)}
// />
)}
</Form>
</>
......
......@@ -5,7 +5,8 @@ import {
Col,
Image,
Progress,
Button
Button,
Upload
} from 'antd';
import style from './index.less';
import excelIcon from '@/assets/imgs/excel.png';
......@@ -18,7 +19,7 @@ interface Iprops {
const Import: React.FC<Iprops> = (props: any) => {
const { flag, onClose } = props;
const [next, setNext] = useState<number>(2);
const [next, setNext] = useState<number>(1);
return (
<Modal
width={400}
......@@ -26,7 +27,11 @@ const Import: React.FC<Iprops> = (props: any) => {
visible={flag}
onCancel={onClose}
footer={
next !== 1 ? null : <Button type='primary'>导入</Button>
next !== 1 ? null :
<Upload>
<Button type='primary'>导入</Button>
</Upload>
}
>
{ next === 1 &&
......
......@@ -20,6 +20,7 @@ import * as ContractV2Api from './ContractV2Api';
import * as OrderV2Api from './OrderV2Api';
import * as PlatformApi from './PlatformApi';
import * as ProductV2Api from './ProductV2Api';
import * as TemplateV2Api from './TemplateV2Api';
/**
* 可在这里写入自定义的接口
......@@ -52,4 +53,5 @@ export const PublicApi = {
...OrderV2Api,
...PlatformApi,
...ProductV2Api,
...TemplateV2Api,
}
......@@ -21,7 +21,8 @@ const tokenList = [
{ name: 'ContractV2', token: 'bbf1f327cfe7c59d1e7fd9c5d25119829dd79d238b1f1c79ed97331e220721a4', categoryIds: [0] }, // 合同能力V2
{ name: 'OrderV2', token: '033f83bd5f519506f65f46d1513b1f8028a1dc1b5238d22edd0a2feb53cd3a19', categoryIds: [0], }, //订单服务V2
{ name: 'Platform', token: 'cadc3b13452c3ec67b5ef0c57063f12142e857a9eaa64669e80165adf42f5861', categoryIds: [0] }, // 平台后台v2
{ name: 'ProductV2', token: 'b915026587fa1f6edf056f3335817fe2d4b350b0aa84da456786e15e83d45827', categoryIds: [0], } // 商品服务V2
{ name: 'ProductV2', token: 'b915026587fa1f6edf056f3335817fe2d4b350b0aa84da456786e15e83d45827', categoryIds: [0], }, // 商品服务V2
{ name: 'TemplateV2', token: 'f0187aed046ac19accbed5c780cade01cf11b50a37099dab9d456195a4abd0d3', categoryIds: [0], }, // 页面模板服务V2
]
const getConfigMap = (tokens) => tokens.map(v => ({
......
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