Browse Source

Merge branch 'develop'

gaozhan 5 years ago
parent
commit
02c34ee044

+ 113 - 61
src/pages/poster/edit/$id$.js

@@ -14,6 +14,10 @@ import styles from './index.less'
 const { Option } = Select
 const { confirm } = Modal
 
+const unique = (arr) => {
+  return Array.from(new Set(arr))
+}
+
 export default class Edit extends React.PureComponent {
   state={
     name: '',
@@ -69,7 +73,7 @@ export default class Edit extends React.PureComponent {
 
   addShape = (type) => {
     const _ele = this.state.element.slice()
-    const { dx, dy } = _ele[this.state.activeObjectIndex] || { dx: 0, dy: 0 }
+    const { dx, dy } = _ele[this.state.activeObjectIndex] || { dx: 0, dy: 45 }
 
     switch (type) {
       case 'text':
@@ -79,8 +83,8 @@ export default class Edit extends React.PureComponent {
           t: '#text_' + (this.state.element.filter(item => item.type === 'text').length + 1) + '#',
           font: 'pingfang_sc_semibold',
           size: 36,
-          dx: dx + 5,
-          dy: dy + 5,
+          dx: dx + 36,
+          dy: dy + 36,
           width: 490,
           height: 45,
           c: '%23333333'
@@ -93,10 +97,10 @@ export default class Edit extends React.PureComponent {
           content: 'https://cdn01t.weipaitang.com/img/20200407u1hmwwai-75so-tvze-5z15-oynukyk8esad-W1125H1500/w/640',
           w: '100',
           h: '100',
-          dx: dx + 5,
-          dy: dy + 5,
-          round: 'false',
-          align: 'both-align'
+          dx: dx + 15,
+          dy: dy + 15,
+          round: 'false'
+          // align: 'both-align'
         })
         break
       case 'qr':
@@ -104,8 +108,8 @@ export default class Edit extends React.PureComponent {
           content: '我是预览二维码',
           type: 'qr',
           t: '#qr_' + (this.state.element.filter(item => item.type === 'pic').length + 1) + '#',
-          dx: dx + 5,
-          dy: dy + 5,
+          dx: dx + 15,
+          dy: dy + 15,
           size: 140,
           logo: 'true'
         })
@@ -144,6 +148,8 @@ export default class Edit extends React.PureComponent {
   render () {
     const { bg: { w: bgWidth, h: bgHeight, c: bgColor }, activeObjectIndex, element, name, description } = this.state
     const activeObject = element[activeObjectIndex] || {}
+    const group = element.map(item => item.group)
+    const _element = element.map((item, index) => ({ ...item, index: index }))
 
     return (
       <div id="poster" style={{ height: this.state.posterHeight, display: 'flex', flexDirection: 'column' }}>
@@ -162,12 +168,12 @@ export default class Edit extends React.PureComponent {
               <Form layout="vertical">
                 <Form.Item label="宽度" >
                   <Input value={bgWidth} onChange={(e) => {
-                    this.updateBgState({ w: Number.parseFloat(e.target.value) })
+                    this.updateBgState({ w: Number.parseFloat(e.target.value || 0) })
                   }}/>
                 </Form.Item>
                 <Form.Item label="高度">
                   <Input value={bgHeight} onChange={(e) => {
-                    this.updateBgState({ h: Number.parseFloat(e.target.value) })
+                    this.updateBgState({ h: Number.parseFloat(e.target.value || 0) })
                   }}/>
                 </Form.Item>
                 <Form.Item label="背景色">
@@ -194,14 +200,24 @@ export default class Edit extends React.PureComponent {
               <h2>图层列表</h2>
               <ul className={styles.layer}>
                 {
-                  element.map((item, index) => (
-                    <li className={`${activeObjectIndex === index ? styles.selected : ''} ${styles[item.type]}`} onClick={() => this.setState({ activeObjectIndex: index })}>
-                      {(item.type === 'pic' ? item.path : item.t || '').toString().replace(/#/g, '')}
-                      <Popover placement="right" content={<div><p onClick={() => this.setState({ visible: true, editIndex: index, editType: item.type, editName: item.type === 'pic' ? item.path : item.t || '' })}>重命名</p><p onClick={() => this.delElement(index, item.type === 'pic' ? item.path : item.t)}>删除</p></div>}>
-                        <Icon type="setting" theme="filled" />
-                      </Popover>
-                    </li>
-                  ))
+                  unique(group).map((_item) => {
+                    return <React.Fragment>
+                      <div>分组:{_item || '未分组'}</div>
+                      {
+                        _element.filter(item => item.group === _item).map((item, index) => (
+                          <li
+                            className={`${activeObjectIndex === item.index ? styles.selected : ''} ${styles[item.type]}`}
+                            onClick={() => this.setState({ activeObjectIndex: item.index })}>
+                            {(item.type === 'pic' ? item.path : item.t || '').toString().replace(/#/g, '')}
+                            <Popover placement="right" content={<div><p onClick={() => this.setState({ visible: true, editIndex: item.index, editType: item.type, editName: item.type === 'pic' ? item.path : item.t || '' })}>重命名</p><p onClick={() => this.delElement(item.index, item.type === 'pic' ? item.path : item.t)}>删除</p></div>}>
+                              <Icon type="setting" theme="filled" />
+                            </Popover>
+                          </li>
+                        ))
+                      }
+                    </React.Fragment>
+                  })
+
                 }
               </ul>
             </div>
@@ -213,7 +229,8 @@ export default class Edit extends React.PureComponent {
               height: Number(bgHeight),
               lineHeight: 1.3,
               backgroundColor: bgColor,
-              marginBottom: '190px'
+              marginBottom: '190px',
+              margin: '0 auto'
             }}
             >
               {
@@ -237,11 +254,15 @@ export default class Edit extends React.PureComponent {
                           style={{
                             WebkitBoxOrient: 'vertical',
                             WebkitLineClamp: clampLine,
-                            width: Number.parseFloat(item.width) || 'auto',
+                            width: item.float_x === 'center' ? (Number.parseFloat(bgWidth) - Number.parseFloat(item.dx)) + 'px' : (Number.parseFloat(item.width) || 'auto'),
                             height: Number.parseFloat(item.height) || 'auto',
                             fontFamily: item.font,
                             fontSize: item.size,
-                            color: item.c
+                            color: item.c,
+                            opacity: item.opacity,
+                            position: 'relative',
+                            textAlign: item.float_x
+                            // left: (Number.parseFloat(bgWidth) - Number.parseFloat(item.dx) - Number.parseFloat(item.width)) / 2 + 'px'
                           }}>
                           {item.content}
                         </div>
@@ -257,14 +278,24 @@ export default class Edit extends React.PureComponent {
                         onResizeStop={(e, direction, ref, delta, position) => {
                           this.updateElement(index, { w: Number.parseFloat(ref.style.width), h: Number.parseFloat(ref.style.height), ...position })
                         }}
-                        bounds="#canvas"
+                        bounds="parent"
                         className={activeObjectIndex === index ? styles.outline : ''}
 
                       >
-                        <img onClick={() => this.setState({ activeObjectIndex: index })}
-                          src={item.content}
-                          style={{ width: Number.parseFloat(item.w) + 'px', height: Number.parseFloat(item.h) + 'px', borderRadius: (item.round || '').toString() === 'true' ? item.w : 0 }}
-                        />
+                        <div
+                          onClick={() => this.setState({ activeObjectIndex: index })}
+                          style={{
+                            backgroundRepeat: 'no-repeat',
+                            backgroundSize: 'cover',
+                            backgroundImage: `url(${item.content})`,
+                            backgroundPosition: (item.align === 'horizontal-align') ? 'top center' : (item.align === 'vertical-align' ? 'center left' : 'center center'),
+                            width: Number.parseFloat(item.w || 0) + 'px',
+                            height: Number.parseFloat(item.h || 0) + 'px',
+                            borderRadius: ((item.round || '').toString() === 'true') ? '100%' : (`${item.corner || 0}px ${item.corner || 0}px` || 0),
+                            filter: `blur(${(item.gauss || '').split(',')[0] / 2}px)`
+                          }}
+                        >
+                        </div>
                       </Rnd>
                     )
                   }
@@ -277,18 +308,23 @@ export default class Edit extends React.PureComponent {
                         onResizeStop={(e, direction, ref, delta, position) => {
                           this.updateElement(index, { size: Number.parseFloat(ref.style.width), ...position })
                         }}
-                        bounds="#canvas"
+                        bounds="parent"
                         className={activeObjectIndex === index ? styles.outline : ''}
 
                       >
-                        <img
+                        <div
                           onClick={() => this.setState({ activeObjectIndex: index })}
-                          style={{ width: Number.parseFloat(item.size) + 'px', height: Number.parseFloat(item.size) + 'px' }}
-                          src={item.logo === 'wpt' || item.logo === 'youjiang'
-                            ? (item.logo === 'wpt' ? 'https://cdn.weipaitang.com/static/20200413eb9effec-3871-ffec3871-cd41-baed9e98535e-W200H200' : 'https://cdn.weipaitang.com/static/202004141c0b320a-9cdc-320a9cdc-d090-e4b5964fee9d-W200H200')
-                            : 'https://cdn.weipaitang.com/static/20200413d4263aa5-6423-3aa56423-4e8d-a96e1d9d93f3-W200H200'
-                          }
-                        />
+                          style={{
+                            backgroundRepeat: 'no-repeat',
+                            backgroundSize: 'cover',
+                            backgroundImage: `url(${item.logo === 'wpt' || item.logo === 'youjiang'
+                          ? (item.logo === 'wpt' ? 'https://cdn.weipaitang.com/static/20200413eb9effec-3871-ffec3871-cd41-baed9e98535e-W200H200' : 'https://cdn.weipaitang.com/static/202004141c0b320a-9cdc-320a9cdc-d090-e4b5964fee9d-W200H200')
+                          : 'https://cdn.weipaitang.com/static/20200413d4263aa5-6423-3aa56423-4e8d-a96e1d9d93f3-W200H200'})`,
+                            width: Number.parseFloat(item.size || '0') + 'px',
+                            height: Number.parseFloat(item.size || '0') + 'px'
+                          }}
+                        >
+                        </div>
                       </Rnd>
                     )
                   }
@@ -360,6 +396,32 @@ export default class Edit extends React.PureComponent {
                         <InputNumber value={activeObject.height} style={{ width: 60 }} onChange={(value) => this.updateElement(activeObjectIndex, { height: value })}/>
                       </Form.Item>
                     </div>
+                    <div style={{ display: 'flex' }}>
+                      <Form.Item label="X居中" style={{ flex: 1 }}>
+                        <Select value={activeObject.float_x} style={{ width: 80 }} onChange={(value) => this.updateElement(activeObjectIndex, { float_x: value })}>
+                          <Option value="">不居中</Option>
+                          <Option value="center">居中</Option>
+                          {/* <Option value="right">right</Option> */}
+                        </Select>
+                      </Form.Item>
+                      <Form.Item label="文字垂直" style={{ flex: 1 }}>
+                        <Switch
+                          checked={activeObject.vertical}
+                          onChange={(checked) => this.updateElement(activeObjectIndex, { vertical: checked })}
+                          checkedChildren="开"
+                          unCheckedChildren="关"
+                        />
+                      </Form.Item>
+                    </div>
+                    <Form.Item label="不透明">
+                      <Slider
+                        min={0}
+                        max={1}
+                        step="0.1"
+                        onChange={(value) => this.updateElement(activeObjectIndex, { opacity: value })}
+                        value={activeObject.opacity}
+                      />
+                    </Form.Item>
                     <div style={{ display: 'flex' }}>
                       <Form.Item label="固定位置" style={{ flex: 1 }}>
                         <Switch
@@ -382,27 +444,9 @@ export default class Edit extends React.PureComponent {
                       <InputNumber
                         style={{ width: 100 }}
                         value={activeObject.group}
-                        onChange={(value) => this.updateElement(activeObjectIndex, { group: value })}
+                        onChange={(value) => this.updateElement(activeObjectIndex, { group: value || undefined })}
                       />
                     </Form.Item>
-                    {/* <Form.Item label="X居中"> */}
-                    {/* <Select value={this.state.currentOptionArr[1].css.textAlign} style={{ width: 150 }} onChange={(value) => this.handleChange(1, 'textAlign', value)}>
-                        <Option value="left">left</Option>
-                        <Option value="center">center</Option>
-                        <Option value="right">right</Option>
-                      </Select>
-                    </Form.Item>
-                    <Form.Item label="文字垂直">
-                      <Input/>
-                    </Form.Item>
-                    <Form.Item label="不透明">
-                      <Slider
-                        min={1}
-                        max={20}
-                        onChange={(value) => console.log(value)}
-                        value={10}
-                      />
-                    </Form.Item> */}
                   </Form>
                 </div>
               )
@@ -465,7 +509,7 @@ export default class Edit extends React.PureComponent {
                       <InputNumber
                         style={{ width: 100 }}
                         value={activeObject.group}
-                        onChange={(value) => this.updateElement(activeObjectIndex, { group: value })}
+                        onChange={(value) => this.updateElement(activeObjectIndex, { group: value || undefined })}
                       />
                     </Form.Item>
                   </Form>
@@ -501,15 +545,15 @@ export default class Edit extends React.PureComponent {
                       <Form.Item label="圆形" style={{ flex: 1 }}>
                         <Switch checked={(activeObject.round || '').toString() === 'true'} onChange={(checked) => {
                           if (checked) {
-                            this.updateElement(activeObjectIndex, { round: true })
+                            this.updateElement(activeObjectIndex, { round: 'true' })
                           } else {
-                            this.updateElement(activeObjectIndex, { round: false })
+                            this.updateElement(activeObjectIndex, { round: 'false' })
                           }
                         }} checkedChildren="开" unCheckedChildren="关" />
                       </Form.Item>
                       <Form.Item label="圆角" style={{ flex: 1 }}>
                         <Input
-                          placeholder="水平,垂直"
+                          placeholder="圆角半径"
                           style={{ width: 100 }}
                           value={activeObject.corner}
                           onChange={(e) => this.updateElement(activeObjectIndex, { corner: e.target.value })}
@@ -517,10 +561,18 @@ export default class Edit extends React.PureComponent {
                       </Form.Item>
                     </div>
                     <Form.Item label="高斯模糊">
-                      <Input/>
+                      <Input
+                        value={activeObject.gauss}
+                        onChange={(e) => this.updateElement(activeObjectIndex, { gauss: e.target.value })}
+                      />
                     </Form.Item>
                     <Form.Item label="图片裁剪选项">
-                      <Input/>
+                      {activeObject.align}
+                      <Select value={activeObject.align} onChange={(value) => this.updateElement(activeObjectIndex, { align: value })}>
+                        <Option value="vertical-align">垂直居中</Option>
+                        <Option value="horizontal-align">水平居中</Option>
+                        <Option value="both-align">垂直水平居中</Option>
+                      </Select>
                     </Form.Item>
                     <div style={{ display: 'flex' }}>
                       <Form.Item label="固定位置" style={{ flex: 1 }}>
@@ -544,7 +596,7 @@ export default class Edit extends React.PureComponent {
                       <InputNumber
                         style={{ width: 100 }}
                         value={activeObject.group}
-                        onChange={(value) => this.updateElement(activeObjectIndex, { group: value })}
+                        onChange={(value) => this.updateElement(activeObjectIndex, { group: value || undefined })}
                       />
                     </Form.Item>
                   </Form>

+ 1 - 2
src/pages/poster/edit/index copy.js

@@ -56,7 +56,7 @@ export default class Edit extends React.PureComponent {
   async addShape (index, action) {
     const currentOptionArr = this.state.currentOptionArr
     const { type } = currentOptionArr[index]
-    console.log(type, 1234567890)
+
     let Shape
     switch (type) {
       case 'text':
@@ -498,7 +498,6 @@ export default class Edit extends React.PureComponent {
 
   changeActiveObjectValue = () => {
     const type = this.activeObject.mytype
-    console.log(type, '99999999')
     if (!type) return
     // this.setState({
     //   visible: true

+ 20 - 8
src/pages/poster/edit/index.less

@@ -96,11 +96,15 @@
   list-style: none;
   padding:0;
   margin:0;
-  li{
+  div {
+    background-color: #eaeaea;
     padding-left: 5px;
+    font-size: 700;
+  }
+  li{
+    padding-left: 20px;
     cursor: pointer;
-    border-left: 5px solid red;
-
+    // border-left: 5px solid red;
     i{
       float: right;
       margin-top: 9px;
@@ -108,11 +112,18 @@
       margin-right: 5px;
     }
   }
-  li.pic{
-    border-color: blue;
+  li::before{
+    content: "::";
+    color: red;
+    display: inline-block;
+    width: 1em;
+    margin-left: -1em
+  }
+  li.pic::before{
+    color: blue;
   }
-  li.qr{
-    border-color: green;
+  li.qr:before{
+    color: #000;
   }
   li:hover{
     background-color:#1890ff;
@@ -130,11 +141,12 @@
   flex: 1;
   background: #dcdcdc;
   margin: 0px 10px;
-  min-height: 100vh;
+  // min-height: 100vh;
   min-width: 750px;
   overflow: auto;
 }
 .right{
   width:200px;
   float: right;
+  overflow: auto;
 }

+ 0 - 1
src/pages/poster/edit/service.js

@@ -1,7 +1,6 @@
 import { fetchApi, fetchApi_get as fetchApiGet } from '@/apis/'
 import { dc } from '@/conf/config'
 
-console.log(fetchApiGet)
 // 新增海报模版
 export async function create (params) {
   const url = `${dc}/api/poster/create`

+ 33 - 4
src/pages/poster/list/index.js

@@ -1,5 +1,7 @@
+/* eslint-disable no-return-assign */
+/* eslint-disable camelcase */
 import React, { Component, Fragment } from 'react'
-import { Divider } from 'antd'
+import { Divider, Modal, message } from 'antd'
 import { FilterTable, ImagePreview } from 'wptpc-design'
 import { connect } from 'dva'
 import { routerRedux } from 'dva/router'
@@ -8,6 +10,9 @@ import ConfigModal from './components/ConfigModal'
 import CopyTemplateModal from './components/CopyTemplateModal'
 import { dc } from '@/conf/config'
 import { fetchApi_get } from '@/apis/'
+
+import { delTemplateAction } from './services'
+
 // less
 import styles from './index.less'
 
@@ -49,6 +54,27 @@ class Poster extends Component {
     }
   }
 
+  // 删除模版
+  delImg = (data) => {
+    const _this = this
+    Modal.confirm({
+      title: '确定删除模版' + data.name + '?',
+      onOk () {
+        delTemplateAction({
+          id: data.id
+        }).then(res => {
+          if (res.code === 0) {
+            message.success('删除成功~')
+            _this.refresh()
+          }
+        })
+      },
+      onCancel () {
+        console.log('Cancel')
+      }
+    })
+  }
+
   render () {
     // 搜索框配置
     const filterSettingConfig = {
@@ -87,6 +113,10 @@ class Poster extends Component {
       columnConfig: [{
         title: '序号',
         dataIndex: 'id'
+      }, {
+        title: '海报缩略图',
+        dataIndex: 'preview',
+        render: (_, record) => <img src={_} className={styles.previewImg} onClick={this.previewImg.bind(this, record)} />
       }, {
         title: '海报标识',
         dataIndex: 'name'
@@ -101,11 +131,11 @@ class Poster extends Component {
             <Fragment>
               <a href={`/poster/edit/${record.id}`}>编辑</a>
               <Divider type="vertical" />
+              <a onClick={this.delImg.bind(this, record)}>删除</a>
+              <Divider type="vertical" />
               <a onClick={this.handleConfig.bind(this, record)}>查看配置</a>
               <Divider type="vertical" />
               <a onClick={this.handleCopyTemplate.bind(this, record)}>复制模版</a>
-              <Divider type="vertical" />
-              <a onClick={this.previewImg.bind(this, record)}>预览</a>
             </Fragment>
           )
         }
@@ -117,7 +147,6 @@ class Poster extends Component {
         type: 'primary',
         onClick: (e) => {
           this.props.dispatch(routerRedux.push({ pathname: '/poster/edit' }))
-          console.log(this.props.dispatch, '1234567890')
           // TODO:暂时没有创建功能
         }
       }],

+ 5 - 1
src/pages/poster/list/index.less

@@ -1 +1,5 @@
-.poster {}
+.poster {}
+.previewImg{
+  width: 80px;
+  object-fit: cover;
+}

+ 16 - 16
src/pages/poster/list/model.js

@@ -1,38 +1,38 @@
-import { message } from 'antd';
-import { getConfigDetailAction, copyTemplateAction } from './services';
+// import { message } from 'antd'
+import { getConfigDetailAction, copyTemplateAction } from './services'
 
 export default {
   namespace: 'posterList',
 
   state: {
-    configDetail: [],
+    configDetail: []
   },
 
   effects: {
     // 获取海报配置属性信息
-    *getConfigDetail({ payload }, { call, put }) {
-      const res = yield call(getConfigDetailAction, payload);
+    * getConfigDetail ({ payload }, { call, put }) {
+      const res = yield call(getConfigDetailAction, payload)
       if (res) {
-        const { data = [] } = res;
+        const { data = [] } = res
         yield put({
           type: 'updatePosterList',
           payload: {
-            configDetail: data,
-          },
+            configDetail: data
+          }
         })
       }
     },
-    
+
     // 复制新模板
-    *copyTemplate({ payload, cb }, { call }) {
-      const res = yield call(copyTemplateAction, payload);
-      if (res) cb && cb();
+    * copyTemplate ({ payload, cb }, { call }) {
+      const res = yield call(copyTemplateAction, payload)
+      if (res) cb && cb()
     }
   },
 
   reducers: {
-    updatePosterList(state, { payload }) {
-      return { ...state, ...payload };
+    updatePosterList (state, { payload }) {
+      return { ...state, ...payload }
     }
-  },
-}
+  }
+}

+ 16 - 9
src/pages/poster/list/services.js

@@ -1,14 +1,21 @@
-import { request } from '@/apis/base';
-import { dc } from '@/conf/config';
+import { fetchApi, fetchApi_get as fetchApiGet } from '@/apis/'
+import { dc } from '@/conf/config'
 
 // 获取配置属性信息
-export async function getConfigDetailAction(params) {
-  const url = `${dc}/api/poster/property`;
-  return request({ url, params });
+export async function getConfigDetailAction (params) {
+  const url = `${dc}/api/poster/property`
+  return fetchApiGet(url, params)
 }
 
 // 复制模板
-export async function copyTemplateAction(data) {
-  const url = `${dc}/api/poster/copy`;
-  return request({ url, method: 'POST', data });
-}
+export async function copyTemplateAction (data) {
+  const url = `${dc}/api/poster/copy`
+  // return fetchApi({ url, method: 'POST', data })
+  return fetchApi(url, data)
+}
+
+// 删除模版
+export async function delTemplateAction (params) {
+  const url = `${dc}/api/poster/delete`
+  return fetchApiGet(url, params)
+}