| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619 |
- import React, {Component} from 'react'
- import './index.css'
- import {
- Picker,
- NavBar,
- Accordion,
- List,
- InputItem,
- ImagePicker,
- Button,
- ActivityIndicator,
- Stepper,
- Modal
- } from 'antd-mobile'
- import {Switch, Row, Col, Icon} from 'antd'
- import {withRouter} from 'react-router-dom'
- import {
- create_product,
- update_product,
- category_by_props,
- productbyprops,
- update_category,
- delete_category,
- create_category
- } from "../../../../utils/gql"
- import {Query, Mutation} from "react-apollo"
- import gql from "graphql-tag"
- import {idGen} from "../../../../utils/func"
- import moment from 'moment'
- import {storeFile} from "../../../../configs/url"
- import axios from 'axios'
- import classNames from 'classnames'
- const Item = List.Item
- const categoryFilterRefetch = {
- "status": "1",
- "limit": 7,
- "sort_by": {"order": "asc"}
- }
- const categoryFilter = {
- "sort_by": {"order": "asc"}
- }
- class Goods extends Component {
- constructor(props) {
- super(props)
- this.state = {
- accordionKey: undefined
- }
- }
- render() {
- let {accordionKey} = this.state
- return (
- <div className='goods-wrap'>
- <NavBar
- className='navbar'
- mode="light"
- icon={<Icon type="left"/>}
- onLeftClick={() => {
- this.props.history.go(-2)
- }}
- >商品管理</NavBar>
- <div className='content-wrap'>
- <div className='my-list-subtitle' style={{color: 'grey'}}><Icon type="bulb" style={{marginRight: 10}}/>{accordionKey? '折叠单项以展开更多分类':'请选择需要打开的分类'}</div>
- <Accordion className="my-accordion" onChange={(key) => {
- this.setState({
- accordionKey: key[0]
- })
- }}>
- <Accordion.Panel header="全部分类"
- className={classNames({'hidden': accordionKey === '1' || accordionKey === '2'})}>
- <AllCategory/>
- </Accordion.Panel>
- <Accordion.Panel header="全部商品"
- className={classNames({'hidden': accordionKey === '0' || accordionKey === '2'})}>
- <AllGoods/>
- </Accordion.Panel>
- <Accordion.Panel header="添加商品"
- className={classNames({'hidden': accordionKey === '0' || accordionKey === '1'})}>
- <AddGoods/>
- </Accordion.Panel>
- </Accordion>
- </div>
- </div>
- )
- }
- }
- class AddGoods extends Component {
- constructor(props) {
- super(props)
- let state = {
- files: [],
- imgDatas: [],
- }
- if (props.good === undefined) {
- this.state = {
- ...state,
- name: '',
- price: 0,
- intro: '',
- stock: 20,
- category: '',
- category_id: '',
- newGood: true
- }
- } else {
- // console.log(props.good)
- let {name, price, intro, stock, id} = props.good
- this.state = {
- ...state,
- id,
- name,
- price,
- intro,
- stock,
- category: props.good.category_id.name,
- category_id: [props.good.category_id.id],
- newGood: false
- }
- }
- }
- onChange = (id) => (files, operationType) => {
- let imgDatas = []
- files.forEach((file, index) => {
- let base64Cont = files[index].url.split(',')[1]
- let imgType = files[index].file.type.split('/')[1]
- let imgNewName = `good_id_${id}.${imgType}`
- const imgData = {
- 'file-name': `e-commerce/images/${imgNewName}`,
- 'bucket': 'case',
- 'cont': base64Cont,
- 'public': true,
- 'format': 'base64'
- }
- imgDatas.push(imgData)
- })
- this.setState({
- imgDatas,
- files
- })
- }
- uploadImg = () => {
- let {imgDatas} = this.state
- return imgDatas.map((imgData) => (
- axios({
- url: storeFile,
- method: 'post',
- data: imgData
- })
- ))
- }
- render() {
- let {files, imgDatas, name, intro, stock, price, category_id, newGood} = this.state
- let id = newGood ? idGen('goods') : this.state.id
- return (
- <List className="my-add-goods-list">
- <InputItem onChange={(e) => {
- this.setState({name: e})
- }} value={name} placeholder="请输入名称">名称</InputItem>
- <Query query={gql(category_by_props)} variables={categoryFilter}>
- {
- ({loading, error, data}) => {
- if (loading) {
- return (
- <div className="loading-center">
- <ActivityIndicator text="Loading..." size="large"/>
- </div>
- )
- }
- if (error) {
- return 'error!'
- }
- let categoryList = data.categorybyprops.map(category => {
- category.value = category.id
- category.label = category.text
- return category
- })
- return (
- <Picker data={categoryList}
- cols={1}
- value={this.state.category_id}
- onChange={v => {
- this.setState({category_id: v})
- }}
- >
- <List.Item arrow="horizontal">选择种类</List.Item>
- </Picker>
- )
- }
- }
- </Query>
- <InputItem onChange={(e) => {
- this.setState({intro: e})
- }} value={intro} placeholder="请输入简介">简介</InputItem>
- <InputItem onChange={(e) => {
- this.setState({price: e})
- }} value={price} placeholder="请输入价格">价格</InputItem>
- <Item extra={<Stepper onChange={(e) => {
- this.setState({stock: e})
- }} value={stock} style={{width: '100%', minWidth: '100px'}} showNumber size="small"/>}>库存</Item>
- <div className='list-others'>
- <div className='list-others-subtitle'>商品图片</div>
- <ImagePicker
- files={files}
- onChange={this.onChange(id)}
- onImageClick={(index, fs) => console.log(index, fs)}
- selectable={true}
- multiple={false}
- />
- {
- newGood ?
- <Mutation mutation={gql(create_product)} refetchQueries={[
- {query: gql(productbyprops), variables: {}},
- {query: gql(productbyprops), variables: {status: '1', recommend: 1}}
- ]}>
- {(createproduct, {loading, error}) => {
- if (loading)
- return (
- <div className="loading">
- <div className="align">
- <ActivityIndicator text="Loading..." size="large"/>
- </div>
- </div>
- )
- if (error)
- return 'error'
- let varObj = {
- id,
- unit: '1件',
- status: '1',
- recommend: 0,
- category_id: category_id[0],
- name,
- stock,
- intro,
- price,
- createdAt: moment().format('YYYY-MM-DD HH:mm:ss'),
- updatedAt: ''
- }
- return (
- <Button type="primary" size="small" inline onClick={() => {
- Promise.all(this.uploadImg()).then(res => {
- let prefix = 'https://case-1254337200.cos.ap-beijing.myqcloud.com/'
- let img = imgDatas.length === 1 ? prefix + imgDatas[0]['file-name'] : imgDatas.map((imgData, index) => (
- prefix + imgDatas[index]['file-name']
- ))
- let variables = {...varObj}
- if (imgDatas.length !== 0) {
- variables.img = img
- }
- createproduct({variables})
- })
- }}>创建</Button>
- )
- }}
- </Mutation>
- :
- <Mutation mutation={gql(update_product)} refetchQueries={[
- {query: gql(productbyprops), variables: {}},
- {query: gql(productbyprops), variables: {status: '1', recommend: 1}}
- ]}>
- {(updateproduct, {loading, error}) => {
- if (loading)
- return (
- <div className="loading">
- <div className="align">
- <ActivityIndicator text="Loading..." size="large"/>
- </div>
- </div>
- )
- if (error)
- return 'error'
- let varObj = {
- id,
- unit: '1件',
- status: '1',
- recommend: 0,
- category_id: category_id[0],
- name,
- stock,
- intro,
- price,
- updatedAt: moment().format('YYYY-MM-DD HH:mm:ss')
- }
- return (
- <Button type="primary" size="small" inline onClick={() => {
- Promise.all(this.uploadImg()).then(res => {
- let prefix = 'https://case-1254337200.cos.ap-beijing.myqcloud.com/'
- let img = imgDatas.length === 1 ? prefix + imgDatas[0]['file-name'] : imgDatas.map((imgData, index) => (
- prefix + imgDatas[index]['file-name']
- ))
- let variables = {...varObj}
- if (imgDatas.length !== 0) {
- variables.img = img
- }
- updateproduct({variables})
- })
- }}>更新</Button>
- )
- }}
- </Mutation>
- }
- </div>
- </List>
- )
- }
- }
- class AllGoods extends Component {
- constructor(props) {
- super(props)
- this.state = {
- modal: false,
- product: {}
- }
- }
- controlModal = (bool) => () => {
- this.setState({
- modal: bool
- })
- if (!bool) {
- this.setState({
- product: {}
- })
- }
- }
- render() {
- let {modal, product} = this.state
- return (
- <Query query={gql(productbyprops)} variables={{}}>
- {
- ({loading, error, data}) => {
- if (loading) {
- return (
- <div className="loading-center">
- <ActivityIndicator text="Loading..." size="large"/>
- </div>
- )
- }
- if (error) {
- return 'error!'
- }
- let products = data.productbyprops
- return (
- <div>
- <div className='all-goods'>
- {
- products.map(product => {
- return (
- <Row className='good-block' key={product.id}>
- <Col span={6}>
- <div className='good-image'
- style={{backgroundImage: `url(${product.img})`}}/>
- </Col>
- <Col span={11} offset={1}>{product.name}</Col>
- <Col span={5} style={{display: 'flex', justifyContent: 'space-around'}}>
- <Mutation mutation={gql(update_product)} refetchQueries={[
- {query: gql(productbyprops), variables: {}},
- {query: gql(productbyprops), variables: {status: '1', recommend: 1}}
- ]}>
- {(updateproduct, {loading, error}) => {
- if (loading)
- return (
- <div className="loading">
- <div className="align">
- <ActivityIndicator text="Loading..." size="large"/>
- </div>
- </div>
- )
- if (error)
- return 'error'
- let {id, recommend} = product
- let variables = {
- id,
- recommend: Number(!recommend),
- updatedAt: moment().format('YYYY-MM-DD HH:mm:ss')
- }
- return (
- <Icon type="like" className={classNames('not-like', {'like': recommend===1})} onClick={() => {
- updateproduct({variables})
- }}/>
- )
- }}
- </Mutation>
- <Icon type="form" onClick={() => {
- this.setState({modal: true, product})
- }}/>
- </Col>
- </Row>
- )
- })
- }
- </div>
- <Modal
- popup
- visible={modal}
- onClose={this.controlModal(false)}
- animationType="slide-up"
- className='modify-goods-modal'
- >
- <div className='close-popup' onClick={this.controlModal(false)}>X</div>
- <div style={{paddingTop: 52}}>
- <AddGoods good={product}/>
- </div>
- </Modal>
- </div>
- )
- }
- }
- </Query>
- )
- }
- }
- class AllCategory extends Component {
- constructor(props) {
- super(props)
- this.state = {}
- }
- render() {
- return (
- <div>
- <Query query={gql(category_by_props)} variables={categoryFilter}>
- {
- ({loading, error, data}) => {
- if (loading) {
- return (
- <div className="loading-center">
- <ActivityIndicator text="Loading..." size="large"/>
- </div>
- )
- }
- if (error) {
- return 'error!'
- }
- let categoryList = data.categorybyprops
- return (
- <div>
- <List>
- {
- categoryList.map(category => {
- return (
- <Item key={category.id} extra={
- <div className='list-extra'>
- <AllCategorySwitch category={category}/>
- <AllCategoryButton category={category}/>
- </div>
- }>
- {category.text}
- </Item>
- )
- })
- }
- </List>
- <AllCategoryInput order={categoryList.length + 1}/>
- </div>
- )
- }
- }
- </Query>
- </div>
- )
- }
- }
- class AllCategorySwitch extends Component {
- constructor(props) {
- super(props)
- this.state = {
- checked: props.category.status === '1'
- }
- }
- render() {
- let {category} = this.props
- let {checked} = this.state
- return (
- <Mutation mutation={gql(update_category)} refetchQueries={[
- {query: gql(category_by_props), variables: categoryFilter},
- {query: gql(category_by_props), variables: categoryFilterRefetch}
- ]}>
- {(updatecategory, {loading, error}) => {
- if (loading)
- return (
- <div className="loading">
- <div className="align">
- <ActivityIndicator text="Loading..." size="large"/>
- </div>
- </div>
- )
- if (error)
- return 'error'
- let obj = {
- id: category.id,
- updatedAt: moment().format('YYYY-MM-DD HH:mm:ss')
- }
- return (
- <Switch checked={checked} onChange={(bool) => {
- this.setState({checked: bool})
- updatecategory({variables: {...obj, status: bool ? '1' : '0'}})
- }}/>
- )
- }}
- </Mutation>
- )
- }
- }
- class AllCategoryButton extends Component {
- constructor(props) {
- super(props)
- this.state = {}
- }
- render() {
- let {category} = this.props
- return (
- <Mutation mutation={gql(delete_category)} refetchQueries={[
- {query: gql(category_by_props), variables: categoryFilter},
- {query: gql(category_by_props), variables: categoryFilterRefetch}
- ]}>
- {(deletecategory, {loading, error}) => {
- if (loading)
- return (
- <div className="loading">
- <div className="align">
- <ActivityIndicator text="Loading..." size="large"/>
- </div>
- </div>
- )
- if (error)
- return 'error'
- return (
- <Button type='warning' inline size="small" onClick={() => {
- deletecategory({variables: {id: category.id}})
- }}>删除</Button>
- )
- }}
- </Mutation>
- )
- }
- }
- class AllCategoryInput extends Component {
- constructor(props) {
- super(props)
- this.state = {
- newCategory: ''
- }
- }
- render() {
- let {order} = this.props
- let {newCategory} = this.state
- return (
- <Mutation mutation={gql(create_category)} refetchQueries={[
- {query: gql(category_by_props), variables: categoryFilter},
- {query: gql(category_by_props), variables: categoryFilterRefetch}
- ]}>
- {(createcategory, {loading, error}) => {
- if (loading)
- return (
- <div className="loading">
- <div className="align">
- <ActivityIndicator text="Loading..." size="large"/>
- </div>
- </div>
- )
- if (error)
- return 'error'
- let obj = {
- id: idGen('category'),
- name: newCategory,
- img: '',
- order,
- status: '1',
- createdAt: moment().format('YYYY-MM-DD HH:mm:ss'),
- updatedAt: ''
- }
- return (
- <InputItem
- onChange={(e) => {
- this.setState({newCategory: e})
- }}
- value={newCategory}
- placeholder="请输入分类名称"
- extra={
- <Button type='primary' inline size="small"
- onClick={() => {
- createcategory({variables: obj})
- }}>添加</Button>
- }>
- 新的分类
- </InputItem>
- )
- }}
- </Mutation>
- )
- }
- }
- export default withRouter(Goods)
|