Browse Source

调整代码结构

zhanghe 7 years ago
parent
commit
402ec06dde
83 changed files with 1037 additions and 1854 deletions
  1. 1 1
      src/common/menu.js
  2. 14 10
      src/common/router.js
  3. 6 1
      src/components/RBItem/PictureItem.js
  4. 1 1
      src/components/RBItem/PictureItem.less
  5. 3 3
      src/components/RBTableSelector/Selector.js
  6. 33 21
      src/components/RBUpload/index.js
  7. 28 0
      src/index.less
  8. 11 3
      src/layouts/UserLayout.less
  9. 0 2
      src/models/courseware.js
  10. 0 2
      src/models/lesson.js
  11. 0 4
      src/models/product.js
  12. 24 7
      src/models/resource.js
  13. 0 4
      src/models/shelves.js
  14. 0 2
      src/models/tag.js
  15. 0 2
      src/models/tagGroup.js
  16. 0 3
      src/models/terminal.js
  17. 9 24
      src/routes/Campus/CampusList.js
  18. 0 16
      src/routes/Campus/CampusList.less
  19. 3 11
      src/routes/Frontend/Tag/TagList.js
  20. 3 19
      src/routes/Frontend/TagGroup/TagGroupList.js
  21. 0 16
      src/routes/Frontend/TagGroup/TagGroupList.less
  22. 1 1
      src/routes/Merchant/MerchantCreate.js
  23. 4 20
      src/routes/Merchant/MerchantList.js
  24. 0 23
      src/routes/Merchant/MerchantList.less
  25. 2 2
      src/routes/Product/Course/CourseCreate.js
  26. 11 23
      src/routes/Product/Course/CourseList.js
  27. 0 16
      src/routes/Product/Course/CourseList.less
  28. 3 3
      src/routes/Product/Courseware/CoursewareCreate.js
  29. 3 19
      src/routes/Product/Courseware/CoursewareList.js
  30. 0 16
      src/routes/Product/Courseware/CoursewareList.less
  31. 3 19
      src/routes/Product/Lesson/LessonList.js
  32. 0 16
      src/routes/Product/Lesson/LessonList.less
  33. 3 19
      src/routes/Product/Package/PackageList.js
  34. 0 16
      src/routes/Product/Package/PackageList.less
  35. 1 1
      src/routes/Product/Support/SupportCreate.js
  36. 5 21
      src/routes/Product/Support/SupportList.js
  37. 0 16
      src/routes/Product/Support/SupportList.less
  38. 4 3
      src/routes/Resource/PictureCardList.js
  39. 173 0
      src/routes/Resource/Picture/PictureEdit.js
  40. 36 31
      src/routes/Resource/PictureList.js
  41. 3 3
      src/routes/Resource/PictureCreateMultiple.js
  42. 1 1
      src/routes/Resource/PictureCreateMultiple.less
  43. 25 22
      src/routes/Resource/PictureCreateSingle.js
  44. 20 11
      src/routes/Resource/PictureTableList.js
  45. 34 0
      src/routes/Resource/Picture/PictureTableList.less
  46. 35 0
      src/routes/Resource/Picture/PictureUpload.js
  47. 97 0
      src/routes/Resource/Picture/PictureUploadResult.js
  48. 0 59
      src/routes/Resource/PictureCreate.js
  49. 0 22
      src/routes/Resource/PictureTableList.less
  50. 36 32
      src/routes/Resource/VideoList.js
  51. 1 1
      src/routes/Resource/VideoPlayList.js
  52. 1 1
      src/routes/Resource/VideoPlayList.less
  53. 8 9
      src/routes/Resource/VideoTableList.js
  54. 60 10
      src/routes/Shelves/Course/CourseEdit.js
  55. 0 9
      src/routes/Shelves/Course/CourseEdit.less
  56. 7 19
      src/routes/Shelves/Course/CourseList.js
  57. 0 16
      src/routes/Shelves/Course/CourseList.less
  58. 137 9
      src/routes/Shelves/Package/PackageEdit.js
  59. 0 0
      src/routes/Shelves/Package/PackageEdit.less
  60. 9 21
      src/routes/Shelves/Package/PackageList.js
  61. 0 16
      src/routes/Shelves/Package/PackageList.less
  62. 0 315
      src/routes/Shelves/Record/ShelvesCreate.js
  63. 0 29
      src/routes/Shelves/Record/ShelvesCreate.less
  64. 0 80
      src/routes/Shelves/Record/ShelvesEdit.js
  65. 0 0
      src/routes/Shelves/Record/ShelvesEdit.less
  66. 0 214
      src/routes/Shelves/Record/ShelvesList.js
  67. 0 16
      src/routes/Shelves/Record/ShelvesList.less
  68. 0 333
      src/routes/Shelves/Record/TableForm.js
  69. 0 8
      src/routes/Shelves/Record/TableForm.less
  70. 0 32
      src/routes/Shelves/Record/index.js
  71. 140 11
      src/routes/Shelves/Support/SupportEdit.js
  72. 0 0
      src/routes/Shelves/Support/SupportEdit.less
  73. 7 19
      src/routes/Shelves/Support/SupportList.js
  74. 0 16
      src/routes/Shelves/Support/SupportList.less
  75. 11 47
      src/routes/Shelves/Support/TableForm.js
  76. 5 0
      src/routes/Shelves/Support/TableForm.less
  77. 6 22
      src/routes/Terminal/User/TerminalList.js
  78. 0 28
      src/routes/Terminal/User/TerminalList.less
  79. 3 3
      src/routes/Terminal/WhiteList/WhiteList.js
  80. 1 1
      src/routes/Trade/Order/SubOrderDetail.js
  81. 1 0
      src/routes/Trade/ShopCart/ShopCartList.js
  82. 0 0
      src/routes/Trade/ShopCart/ShopCartList.less
  83. 4 2
      src/utils/config.js

+ 1 - 1
src/common/menu.js

@@ -28,7 +28,7 @@ const menuData = () => {
       path: 'resource',
       children: [{
         name: '图库管理',
-        path: 'image',
+        path: 'picture',
         icon: 'file-jpg',
       }, {
         name: '视频管理',

+ 14 - 10
src/common/router.js

@@ -104,22 +104,26 @@ export const getRouterData = (app) => {
       name: '编辑校区',
     },
     // 资源管理相关路由注册
-    '/resource/image': {
-      component: dynamicWrapper(app, ['resource'], () => import('../routes/Resource/PictureList')),
+    '/resource/picture': {
+      component: dynamicWrapper(app, ['resource'], () => import('../routes/Resource/Picture/PictureList')),
     },
-    '/resource/imageCreate': {
-      component: dynamicWrapper(app, [], () => import('../routes/Resource/PictureCreate')),
+    '/resource/picture-upload': {
+      component: dynamicWrapper(app, ['resource'], () => import('../routes/Resource/Picture/PictureUpload')),
     },
-    '/resource/imageCreate/single': {
-      component: dynamicWrapper(app, ['resource'], () => import('../routes/Resource/PictureCreateSingle')),
+    '/resource/picture-upload/single': {
+      component: dynamicWrapper(app, ['resource'], () => import('../routes/Resource/Picture/PictureSingleUpload')),
       name: '单图上传',
     },
-    '/resource/imageCreate/multiple': {
-      component: dynamicWrapper(app, [], () => import('../routes/Resource/PictureCreateMultiple')),
-      name: '多图上传',
+    '/resource/picture-upload/result': {
+      component: dynamicWrapper(app, ['resource'], () => import('../routes/Resource/Picture/PictureUploadResult')),
+      name: '上传结果',
+    },
+    '/resource/picture-edit/:id': {
+      component: dynamicWrapper(app, ['resource'], () => import('../routes/Resource/Picture/PictureEdit')),
+      name: '编辑图片',
     },
     '/resource/video': {
-      component: dynamicWrapper(app, ['resource'], () => import('../routes/Resource/VideoList')),
+      component: dynamicWrapper(app, ['resource'], () => import('../routes/Resource/Video/VideoList')),
     },
     // 系统管理相关路由注册
     '/system/cms-user': {

+ 6 - 1
src/components/RBItem/PictureItem.js

@@ -12,6 +12,10 @@ class PictureItem extends Component {
     const { id, onDelete } = this.props;
     onDelete({ id });
   }
+  handleItemEdit = () => {
+    const { id, onEdit } = this.props;
+    onEdit({ id });
+  }
   render() {
     const { picPath, picCode, selected } = this.props;
     return (
@@ -41,7 +45,8 @@ class PictureItem extends Component {
             size="small"
             type="primary"
             icon="edit"
-            style={{ marginRight: 20 }}
+            style={{ marginRight: 5 }}
+            onClick={this.handleItemEdit}
           >编辑
           </Button>
           <Button

+ 1 - 1
src/components/RBItem/PictureItem.less

@@ -28,7 +28,7 @@
   top: 5px;
   right: 5px;
   font-size: 16px;
-  font-weight: 600px;
+  font-weight: 600;
   color: @primary-9;
   &:hover {
     color: red;

+ 3 - 3
src/components/RBTableSelector/Selector.js

@@ -77,7 +77,7 @@ export default class Selector extends PureComponent {
    * @params rows
    */
   handleMultipleTransfer = (rows) => {
-    const { selectedRowKeys, selectedRows } = this.state;
+    const { selectedRowKeys } = this.state;
     const newSelectedRowKeys = [];
     const newSelectedRows = rows.filter((item) => {
       if (selectedRowKeys.indexOf(item.key) === -1) {
@@ -87,8 +87,8 @@ export default class Selector extends PureComponent {
       return false;
     });
     this.setState({
-      selectedRows: [...selectedRows, ...newSelectedRows],
-      selectedRowKeys: [...selectedRowKeys, ...newSelectedRowKeys],
+      selectedRows: [...newSelectedRows],
+      selectedRowKeys: [...newSelectedRowKeys],
     });
   }
   /**

+ 33 - 21
src/components/RBUpload/index.js

@@ -1,7 +1,8 @@
+/* eslint-disable prefer-template,no-param-reassign */
 import React, { Component } from 'react';
 import { Upload, Icon, message, Modal } from 'antd';
 import { queryOssSignature } from '../../services/resource';
-import { fileMaxSize } from '../../utils/config';
+import { FILE_MAX_SIZE } from '../../utils/config';
 import { setSignature } from '../../utils/signature';
 import styles from './index.less';
 
@@ -23,14 +24,28 @@ const renderAccept = (accept) => {
 
 // 检查文件大小
 const checkFileSize = (fileName, fileSize) => {
-  if (fileSize > fileMaxSize * 1000 * 1000) {
-    Message.error(`${fileName}文件大小超过${fileSize}M!`);
+  if (fileSize > FILE_MAX_SIZE * 1000 * 1000) {
+    Message.error(`${fileName}文件大小超过${FILE_MAX_SIZE}M!`);
     return false;
   }
   return true;
 };
 
 /**
+ * 使用时间戳生成随机的文件名
+ * @param fileName
+ * @param fileCode
+ * @returns {string}
+ */
+const getRandomFileName = (fileName, fileCode) => {
+  const relativePath = fileCode ? fileCode.replace(/-/g, '/') + '/' : '';
+  const separatorIndex = fileName.lastIndexOf('.');
+  const suffix = fileName.substring(separatorIndex + 1, fileName.length);
+  const randomFileName = (new Date()).getTime().toString() + Math.floor(Math.random() * 10000) + '.' + suffix;
+  return `${relativePath}${randomFileName}`;
+};
+
+/**
  * 将传入文件对象处理成upload组件格式
  * @param {Object/Array}
  * @return {Array} [{}]
@@ -62,10 +77,11 @@ class Uploader extends Component {
       fileList: renderFileList(this.props.fileList), // 文件对象列表
       curFileName: '',
       previewImg: '',
-      previewVisiable: false,
+      previewVisible: false,
     };
   }
   handleBeforeUpload = (file) => {
+    console.log('call beforeUpload func:', new Date().getTime())
     const { fileCode } = this.props;
     if (!checkFileSize(file.name, file.size)) {
       return false;
@@ -74,9 +90,7 @@ class Uploader extends Component {
       .then((res) => {
         this.setState({
           ossSign: res.data || res,
-          curFileName: fileCode ?
-            fileCode.replace(/-/g, '/') :
-            file.name.replace(/-/g, '/'), // 处理图片文件名
+          curFileName: getRandomFileName(file.name, fileCode),
         });
         if (res.data) {
           setSignature(res.data); // 保存签名到本地
@@ -84,30 +98,28 @@ class Uploader extends Component {
       });
   }
   handleOnChange = ({ fileList }) => {
-    const { ossSign, fileCode } = this.state;
+    console.log('call onChange func:', new Date().getTime())
+    const { ossSign, curFileName } = this.state;
     const { onUpload, totalLimit } = this.props;
     const { dir, host } = ossSign;
-    fileList = fileList.filter((file) => {
+    const newFileList = fileList.filter((file) => {
       if (file.status === 'error') {
         Message.error(`${file.name}上传失败!`); // 上传失败给出提示并去掉
         return false;
       }
       if (file.status === 'done' && !file.processed) {
         Message.success('上传成功');
-        const fileName = fileCode ?
-          fileCode.replace(/-/g, '/') :
-          file.name.replace(/-/g, '/');
-        file.url = `${host}/${dir}${fileName}`;
-        file.path = `${dir}${fileName}`;
+        file.url = `${host}/${dir}${curFileName}`;
+        file.path = `${dir}${curFileName}`;
         file.thumbUrl = file.url;
         file.processed = true;
       }
       return true;
     });
     this.setState({
-      fileList: renderFileList(fileList),
+      fileList: renderFileList(newFileList),
     });
-    const uploaded = fileList.filter((file) => {
+    const uploaded = newFileList.filter((file) => {
       if (file.status === 'done' && file.processed) {
         return true;
       }
@@ -133,17 +145,17 @@ class Uploader extends Component {
   handleOnPreview = (file) => {
     this.setState({
       previewImg: file.url || file.thumbUrl,
-      previewVisiable: true,
+      previewVisible: true,
     });
   }
   handleCancelPreview = () => {
     this.setState({
-      previewVisiable: false,
+      previewVisible: false,
     });
   }
   render() {
     const { multiple, accept, totalLimit, forbidden } = this.props;
-    const { ossSign, fileList, curFileName, previewImg, previewVisiable } = this.state;
+    const { ossSign, fileList, curFileName, previewImg, previewVisible } = this.state;
     const { host, policy, accessid, signature, dir } = ossSign;
 
     const uploadProps = {
@@ -176,10 +188,10 @@ class Uploader extends Component {
             <Icon type="inbox" />
           </p>
           <p className={styles.dragText}>点击或者拖拽图片到此区域进行上传</p>
-          <p className={styles.dragHint}>支持jpg/png图片格式,大小需小于2M</p>
+          <p className={styles.dragHint}>{`支持jpg/png图片格式,大小需小于${FILE_MAX_SIZE}M`}</p>
         </Upload.Dragger>
         <Modal
-          visible={previewVisiable}
+          visible={previewVisible}
           footer={null}
           onCancel={this.handleCancelPreview}
           width={650}

+ 28 - 0
src/index.less

@@ -1,3 +1,5 @@
+@import "~antd/lib/style/themes/default.less";
+
 html,
 body,
 :global(#root) {
@@ -46,4 +48,30 @@ body {
   .ant-table-tbody > tr.ant-table-row-selected td {
     background: #ffffb8 !important;
   }
+  .ant-tag {
+    width: 137px;
+    text-align: center;
+    margin-top: 5px;
+    height: 25px;
+    line-height: 25px;
+  }
+}
+
+// 自定义全局样式
+:global(.editBtn) {
+  margin-right: 10px;
+  background: @primary-color !important;
+  color: #fff !important;
+  font-weight: 500 !important;
+}
+:global(.delBtn) {
+  background: #f5222d !important;
+  color: #fff !important;
+  font-weight: 500 !important;
+}
+:global(.depositBtn) {
+  margin-right: 10px;
+  background: #a0d911 !important;
+  color: #fff !important;
+  font-weight: 500 !important;
 }

+ 11 - 3
src/layouts/UserLayout.less

@@ -15,9 +15,6 @@
 @media (min-width: @screen-md-min) {
   .container {
     background: #fff;
-    // background-image: url('https://gw.alipayobjects.com/zos/rmsportal/TVYTbAXWheQpRcWDaDMu.svg');
-    background-repeat: no-repeat;
-    background-position: center 110px;
     background-size: 100%;
   }
 
@@ -26,6 +23,17 @@
   }
 }
 
+@media (min-width: @screen-xxl-min) {
+  .container {
+    background: #fff;
+    background-size: 100%;
+  }
+
+  .content {
+    padding: 250px 0 24px 0;
+  }
+}
+
 .top {
   text-align: center;
 }

+ 0 - 2
src/models/courseware.js

@@ -23,7 +23,6 @@ export default {
     *fetchCoursewareList({ payload }, { call, put }) {
       const response = yield call(queryCoursewareList, payload);
       if (response.success) {
-        message.success('加载课件列表成功');
         yield put({
           type: 'querySuccess',
           payload: {
@@ -38,7 +37,6 @@ export default {
     *fetchCoursewareItem({ payload }, { call, put }) {
       const response = yield call(queryCoursewareItem, payload);
       if (response.success) {
-        message.success('加载课件详情成功');
         yield put({
           type: 'querySuccess',
           payload: {

+ 0 - 2
src/models/lesson.js

@@ -23,7 +23,6 @@ export default {
     *fetchLessonList({ payload }, { call, put }) {
       const response = yield call(queryLessonList, payload);
       if (response.success) {
-        message.success('加载课列表成功');
         yield put({
           type: 'querySuccess',
           payload: {
@@ -38,7 +37,6 @@ export default {
     *fetchLessonItem({ payload }, { call, put }) {
       const response = yield call(queryLessonItem, payload);
       if (response.success) {
-        message.success('加载课详情成功');
         yield put({
           type: 'querySuccess',
           payload: {

+ 0 - 4
src/models/product.js

@@ -28,7 +28,6 @@ export default {
     *fetchCourseList({ payload }, { call, put }) {
       const response = yield call(queryProductList, {type: PRODUCT_COURSE, ...payload});
       if (response.success) {
-        message.success('加载课程列表成功');
         yield put({
           type: 'querySuccess',
           payload: {
@@ -43,7 +42,6 @@ export default {
     *fetchSupportList({ payload }, { call, put }) {
       const response = yield call(queryProductList, {type: PRODUCT_SUPPORT, ...payload});
       if (response.success) {
-        message.success('加载配套列表成功');
         yield put({
           type: 'querySuccess',
           payload: {
@@ -58,7 +56,6 @@ export default {
     *fetchPackageList({ payload }, { call, put }) {
       const response = yield call(queryProductList, {type: PRODUCT_PACKAGE, ...payload});
       if (response.success) {
-        message.success('加载套餐包列表成功');
         yield put({
           type: 'querySuccess',
           payload: {
@@ -73,7 +70,6 @@ export default {
     *fetchProductItem({ payload }, { call, put }) {
       const response = yield call(queryProductItem, payload);
       if (response.success) {
-        message.success('加载详情成功');
         yield put({
           type: 'querySuccess',
           payload: {

+ 24 - 7
src/models/resource.js

@@ -3,6 +3,7 @@ import { message } from 'antd';
 import {
   createImage,
   deleteImage,
+  updateImage,
   queryImageResource,
   queryVideoResource,
 } from '../services/resource';
@@ -21,7 +22,6 @@ export default {
     *fetchImageList({ payload }, { call, put }) {
       const response = yield call(queryImageResource, payload);
       if (response.success) {
-        message.success('加载图片列表成功');
         yield put({
           type: 'querySuccess',
           payload: {
@@ -36,7 +36,6 @@ export default {
     *fetchVideoList({ payload }, { call, put }) {
       const response = yield call(queryVideoResource, payload);
       if (response.success) {
-        message.success('加载视频列表成功');
         yield put({
           type: 'querySuccess',
           payload: {
@@ -50,15 +49,33 @@ export default {
     },
     *createImage({ payload }, { call, put }) {
       const response = yield call(createImage, payload);
-      if (response.success) {
-        message.success('创建成功');
-        yield put(routerRedux.goBack());
+      if (response && response.success) {
+        yield put(
+          routerRedux.push({
+            pathname: '/resource/picture-upload/result',
+            state: response.data,
+          })
+        );
       }
     },
-    *deleteImage({ payload }, { call, put }) {
+    *updateImage({ payload, states }, { call, put }) {
+      const response = yield call(updateImage, payload);
+      if (response && response.success) {
+        message.success('修改图片成功');
+        yield put(routerRedux.push({
+          pathname: '/resource/picture',
+          state: states,
+        }));
+      }
+    },
+    *deleteImage({ payload, states }, { call, put }) {
       const response = yield call(deleteImage, payload);
       if (response && response.success) {
-        message.success('删除成功');
+        message.success('删除图片成功');
+        yield put({
+          type: 'fetchImageList',
+          payload: states,
+        });
       }
     },
   },

+ 0 - 4
src/models/shelves.js

@@ -32,7 +32,6 @@ export default {
     *fetchItemList({ payload }, { call, put }) {
       const response = yield call(queryItemList, payload);
       if (response.success) {
-        message.success('加载商品列表成功');
         yield put({
           type: 'querySuccess',
           payload: {
@@ -47,7 +46,6 @@ export default {
     *fetchCourseItemList({ payload }, { call, put }) {
       const response = yield call(queryItemList, { type: PRODUCT_COURSE, ...payload });
       if (response.success) {
-        message.success('加载课程商品列表成功');
         yield put({
           type: 'querySuccess',
           payload: {
@@ -62,7 +60,6 @@ export default {
     *fetchSupportItemList({ payload }, { call, put }) {
       const response = yield call(queryItemList, { type: PRODUCT_SUPPORT, ...payload });
       if (response.success) {
-        message.success('加载配套商品列表成功');
         yield put({
           type: 'querySuccess',
           payload: {
@@ -77,7 +74,6 @@ export default {
     *fetchPackageItemList({ payload }, { call, put }) {
       const response = yield call(queryItemList, { type: PRODUCT_PACKAGE, ...payload });
       if (response.success) {
-        message.success('加载套餐包商品列表成功');
         yield put({
           type: 'querySuccess',
           payload: {

+ 0 - 2
src/models/tag.js

@@ -23,7 +23,6 @@ export default {
     *fetchTagList({ payload }, { call, put }) {
       const response = yield call(queryTagList, payload);
       if (response.success) {
-        message.success('加载标签表成功');
         yield put({
           type: 'querySuccess',
           payload: {
@@ -38,7 +37,6 @@ export default {
     *fetchTagItem({ payload }, { call, put }) {
       const response = yield call(queryTagItem, payload);
       if (response.success) {
-        message.success('加载标签详情成功');
         yield put({
           type: 'querySuccess',
           payload: {

+ 0 - 2
src/models/tagGroup.js

@@ -23,7 +23,6 @@ export default {
     *fetchTagGroupList({ payload }, { call, put }) {
       const response = yield call(queryTagGroupList, payload);
       if (response.success) {
-        message.success('加载标签组表成功');
         yield put({
           type: 'querySuccess',
           payload: {
@@ -38,7 +37,6 @@ export default {
     *fetchTagGroupItem({ payload }, { call, put }) {
       const response = yield call(queryTagGroupItem, payload);
       if (response.success) {
-        message.success('加载标签组详情成功');
         yield put({
           type: 'querySuccess',
           payload: {

+ 0 - 3
src/models/terminal.js

@@ -28,7 +28,6 @@ export default {
     *fetchTerminalList({ payload }, { call, put }) {
       const response = yield call(queryTerminalList, payload);
       if (response.success) {
-        message.success('加载终端列表成功');
         yield put({
           type: 'querySuccess',
           payload: {
@@ -83,7 +82,6 @@ export default {
     *fetchSpecialTerminalList({ payload }, { call, put }) {
       const response = yield call(querySpecialTerminalList, payload);
       if (response.success) {
-        message.success('加载白名单列表成功');
         yield put({
           type: 'querySuccess',
           payload: {
@@ -98,7 +96,6 @@ export default {
     *fetchSpecialTerminalItem({ payload }, { call, put }) {
       const response = yield call(querySpecialTerminalItem, payload);
       if (response.success) {
-        message.success('加载白名单用户详情成功');
         yield put({
           type: 'querySuccess',
           payload: {

+ 9 - 24
src/routes/Campus/CampusList.js

@@ -4,10 +4,10 @@ import { connect } from 'dva';
 import { routerRedux } from 'dva/router';
 import { Card, Modal, Form, Button, message } from 'antd';
 import { StandardTableList } from '../../components/RBList';
+import Ellipsis from '../../components/Ellipsis';
 import RBRemoteSelect from '../../components/RBRemoteSelect';
 import PageHeaderLayout from '../../layouts/PageHeaderLayout';
 import { addRowKey } from '../../utils/utils';
-import styles from './CampusList.less';
 
 const Message = message;
 
@@ -117,7 +117,7 @@ export default class CampusListPage extends Component {
         <div>
           <Button
             size="small"
-            className={styles.editBtn}
+            type="primary"
             onClick={() => this.handleEditOperation(item)}
           >编辑
           </Button>
@@ -125,11 +125,8 @@ export default class CampusListPage extends Component {
       );
     };
     const batchActions = [{
-      key: 'delete',
-      name: '批量删除',
-    }, {
-      key: 'recovery',
-      name: '批量恢复',
+      key: 'edit',
+      name: '批量编辑',
     }];
     const basicSearch = {
       keys: [{
@@ -149,28 +146,15 @@ export default class CampusListPage extends Component {
       title: '校区编号',
       key: 1,
       dataIndex: 'code',
-      render: (text, record) => (
-        <a
-          className={styles.link}
-          onClick={() => this.handleEditOperation(record)}
-        >
-          {text}
-        </a>
-      ),
-      width: '12%',
+      width: '15%',
     }, {
       title: '校区名称',
       key: 2,
       dataIndex: 'name',
-      render: (text, record) => (
-        <a
-          className={styles.link}
-          onClick={() => this.handleEditOperation(record)}
-        >
-          {text}
-        </a>
+      width: '31%',
+      render: text => (
+        <Ellipsis tooltip lines={1}>{text}</Ellipsis>
       ),
-      width: '34%',
     }, {
       title: '所属渠道',
       key: 3,
@@ -198,6 +182,7 @@ export default class CampusListPage extends Component {
       dataIndex: 'operation',
       render: (_, record) => renderOperation(record),
       width: '6%',
+      align: 'right',
     }];
     return (
       <PageHeaderLayout>

+ 0 - 16
src/routes/Campus/CampusList.less

@@ -1,16 +0,0 @@
-@import "../../../node_modules/antd/lib/style/themes/default.less";
-
-.link {
-  font-weight: 500;
-}
-.editBtn {
-  margin-right: 10px;
-  background: @primary-5;
-  color: #fff;
-  font-weight: 500;
-}
-.deleteBtn {
-  background: #f5222d;
-  color: #fff;
-  font-weight: 500;
-}

+ 3 - 11
src/routes/Frontend/Tag/TagList.js

@@ -5,7 +5,6 @@ import { routerRedux } from 'dva/router';
 import { Card, Modal, Button, message } from 'antd';
 import { StandardTableList } from '../../../components/RBList/index';
 import { renderStatus, addRowKey } from '../../../utils/utils';
-import styles from './TagList.less';
 
 const Message = message;
 
@@ -77,13 +76,13 @@ export default class TagListPage extends Component {
         <div>
           <Button
             size="small"
-            className={styles.editBtn}
+            className="editBtn"
             onClick={() => this.handleEditOperation(item)}
           >编辑
           </Button>
           <Button
             size="small"
-            className={styles.delBtn}
+            className="delBtn"
             onClick={() => this.handleDeleteOperation(item)}
           >删除
           </Button>
@@ -113,14 +112,6 @@ export default class TagListPage extends Component {
       title: '标签名称',
       key: 1,
       dataIndex: 'name',
-      render: (text, record) => (
-        <a
-          className={styles.link}
-          onClick={() => this.handleEditOperation(record)}
-        >
-          {text}
-        </a>
-      ),
       width: '20%',
     }, {
       title: '所属标签组',
@@ -149,6 +140,7 @@ export default class TagListPage extends Component {
       key: 6,
       render: (_, record) => renderOperation(record),
       width: '13%',
+      align: 'right',
     }];
     return (
       <Card>

+ 3 - 19
src/routes/Frontend/TagGroup/TagGroupList.js

@@ -5,7 +5,6 @@ import { routerRedux } from 'dva/router';
 import { Card, Modal, Button, message } from 'antd';
 import { StandardTableList } from '../../../components/RBList/index';
 import { renderStatus, addRowKey } from '../../../utils/utils';
-import styles from './TagGroupList.less';
 
 const Message = message;
 
@@ -77,13 +76,13 @@ export default class TagGroupListPage extends Component {
         <div>
           <Button
             size="small"
-            className={styles.editBtn}
+            className="editBtn"
             onClick={() => this.handleEditOperation(item)}
           >编辑
           </Button>
           <Button
             size="small"
-            className={styles.delBtn}
+            className="delBtn"
             onClick={() => this.handleDeleteOperation(item)}
           >删除
           </Button>
@@ -116,27 +115,11 @@ export default class TagGroupListPage extends Component {
       title: '标签组编号',
       key: 1,
       dataIndex: 'code',
-      render: (text, record) => (
-        <a
-          className={styles.link}
-          onClick={() => this.handleEditOperation(record)}
-        >
-          {text}
-        </a>
-      ),
       width: '20%',
     }, {
       title: '标签组名称',
       key: 2,
       dataIndex: 'name',
-      render: (text, record) => (
-        <a
-          className={styles.link}
-          onClick={() => this.handleEditOperation(record)}
-        >
-          {text}
-        </a>
-      ),
       width: '20%',
     }, {
       title: '所属渠道',
@@ -160,6 +143,7 @@ export default class TagGroupListPage extends Component {
       key: 6,
       render: (_, record) => renderOperation(record),
       width: '13%',
+      align: 'right',
     }];
     return (
       <Card>

+ 0 - 16
src/routes/Frontend/TagGroup/TagGroupList.less

@@ -1,16 +0,0 @@
-@import "../../../../node_modules/antd/lib/style/themes/default.less";
-
-.link {
-  font-weight: 500;
-}
-.editBtn {
-  margin-right: 10px;
-  background: @primary-5;
-  color: #fff;
-  font-weight: 500;
-}
-.delBtn {
-  background: #f5222d;
-  color: #fff;
-  font-weight: 500;
-}

+ 1 - 1
src/routes/Merchant/MerchantCreate.js

@@ -134,7 +134,7 @@ export default class MerchantCreatePage extends PureComponent {
 
     return (
       <PageHeaderLayout>
-        <Card>
+        <Card style={{ marginBottom: 70 }}>
           <Form>
             <Form.Item label={fieldLabels.type} {...formItemLayout}>
               {getFieldDecorator('domain', {

+ 4 - 20
src/routes/Merchant/MerchantList.js

@@ -7,7 +7,6 @@ import { StandardTableList } from '../../components/RBList';
 import PageHeaderLayout from '../../layouts/PageHeaderLayout';
 import Authorized from '../../utils/Authorized';
 import { renderStatus, renderCategory, addRowKey } from '../../utils/utils';
-import styles from './MerchantList.less';
 
 const Message = message;
 
@@ -86,20 +85,20 @@ export default class MerchantListPage extends Component {
           <Authorized authority="root" noMatch={null}>
             <Button
               size="small"
-              className={styles.depositBtn}
+              className="depositBtn"
               onClick={() => this.handleDepositOperation(item)}
             >充值
             </Button>
           </Authorized>
           <Button
             size="small"
-            className={styles.editBtn}
+            className="editBtn"
             onClick={() => this.handleEditOperation(item)}
           >编辑
           </Button>
           <Button
             size="small"
-            className={styles.deleteBtn}
+            className="delBtn"
             onClick={() => this.handleDeleteOperation(item)}
           >删除
           </Button>
@@ -132,27 +131,11 @@ export default class MerchantListPage extends Component {
       title: '商户编号',
       key: 1,
       dataIndex: 'code',
-      render: (text, record) => (
-        <a
-          className={styles.link}
-          onClick={() => this.handleEditOperation(record)}
-        >
-          {text}
-        </a>
-      ),
       width: '12%',
     }, {
       title: '商户名称',
       key: 2,
       dataIndex: 'name',
-      render: (text, record) => (
-        <a
-          className={styles.link}
-          onClick={() => this.handleEditOperation(record)}
-        >
-          {text}
-        </a>
-      ),
       width: '16%',
     }, {
       title: '商户类型',
@@ -183,6 +166,7 @@ export default class MerchantListPage extends Component {
       dataIndex: 'operation',
       render: (_, record) => renderOperation(record),
       width: '18%',
+      align: 'right',
     }];
     return (
       <PageHeaderLayout>

+ 0 - 23
src/routes/Merchant/MerchantList.less

@@ -1,23 +0,0 @@
-@import "~antd/lib/style/themes/default.less";
-
-.link {
-  // text-decoration: underline;
-  font-weight: 500;
-}
-.editBtn {
-  margin-right: 10px;
-  background: @primary-5;
-  color: #fff;
-  font-weight: 500;
-}
-.depositBtn {
-  margin-right: 10px;
-  background: #a0d911;
-  color: #fff;
-  font-weight: 500;
-}
-.deleteBtn {
-  background: #f5222d;
-  color: #fff;
-  font-weight: 500;
-}

+ 2 - 2
src/routes/Product/Course/CourseCreate.js

@@ -9,9 +9,9 @@ import {
   renderStatus, statusToBool, boolToStatus, genAbsolutePicUrl,
 } from '../../../utils/utils';
 import { PRODUCT_LESSON } from '../../../utils/config';
-import RBDragSortTable from '../../../components/RBDragSortTable/index';
+import RBDragSortTable from '../../../components/RBDragSortTable';
 import Selector from '../../../components/RBTableSelector/Selector';
-import FooterToolbar from '../../../components/FooterToolbar/index';
+import FooterToolbar from '../../../components/FooterToolbar';
 import styles from './CourseCreate.less';
 
 const fieldLabels = {

+ 11 - 23
src/routes/Product/Course/CourseList.js

@@ -3,9 +3,9 @@ import moment from 'moment';
 import { connect } from 'dva';
 import { routerRedux } from 'dva/router';
 import { Card, Modal, Button, message } from 'antd';
-import { StandardTableList } from '../../../components/RBList/index';
+import { StandardTableList } from '../../../components/RBList';
+import Ellipsis from '../../../components/Ellipsis';
 import { renderStatus, addRowKey } from '../../../utils/utils';
-import styles from './CourseList.less';
 
 const Message = message;
 
@@ -78,13 +78,13 @@ export default class CourseListPage extends Component {
         <div>
           <Button
             size="small"
-            className={styles.editBtn}
+            className="editBtn"
             onClick={() => this.handleEditOperation(item)}
           >编辑
           </Button>
           <Button
             size="small"
-            className={styles.delBtn}
+            className="delBtn"
             onClick={() => this.handleDeleteOperation(item)}
           >删除
           </Button>
@@ -117,34 +117,21 @@ export default class CourseListPage extends Component {
       title: '课程编号',
       key: 1,
       dataIndex: 'code',
-      render: (text, record) => (
-        <a
-          className={styles.link}
-          onClick={() => this.handleEditOperation(record)}
-        >
-          {text}
-        </a>
-      ),
-      width: '25%',
+      width: '20%',
     }, {
       title: '课程名称',
       key: 2,
       dataIndex: 'name',
-      render: (text, record) => (
-        <a
-          className={styles.link}
-          onClick={() => this.handleEditOperation(record)}
-        >
-          {text}
-        </a>
-      ),
       width: '30%',
+      render: text => (
+        <Ellipsis tooltip lines={1}>{text}</Ellipsis>
+      ),
     }, {
       title: '课程状态',
       key: 3,
       dataIndex: 'status',
       render: text => renderStatus(text),
-      width: '12%',
+      width: '15%',
     }, {
       title: '更新时间',
       key: 4,
@@ -156,7 +143,8 @@ export default class CourseListPage extends Component {
       key: 5,
       dataIndex: 'operation',
       render: (_, record) => renderOperation(record),
-      width: '13%',
+      width: '15%',
+      align: 'right',
     }];
     return (
       <Card>

+ 0 - 16
src/routes/Product/Course/CourseList.less

@@ -1,16 +0,0 @@
-@import "../../../../node_modules/antd/lib/style/themes/default.less";
-
-.link {
-  font-weight: 500;
-}
-.editBtn {
-  margin-right: 10px;
-  background: @primary-5;
-  color: #fff;
-  font-weight: 500;
-}
-.delBtn {
-  background: #f5222d;
-  color: #fff;
-  font-weight: 500;
-}

+ 3 - 3
src/routes/Product/Courseware/CoursewareCreate.js

@@ -46,7 +46,7 @@ const formItemLayout = {
 export default class CoursewareCreatePage extends Component {
   state = {
     modalSelectorDestroy: true,
-    resourceType: 'Picture',
+    resourceType: 'Index',
   };
   componentWillMount() {
     // 进入页面前清空下model中state内容,防止上次内容造成干扰
@@ -81,7 +81,7 @@ export default class CoursewareCreatePage extends Component {
   }
   selectorDataFetcher = (params) => {
     const { resourceType } = this.state;
-    if (resourceType === 'Picture') {
+    if (resourceType === 'Index') {
       this.props.dispatch({
         type: 'resource/fetchImageList',
         payload: params,
@@ -331,7 +331,7 @@ export default class CoursewareCreatePage extends Component {
               onCancel={this.handleSelectorCancel}
             >
               <Selector
-                multiple={resourceType === 'Picture'}
+                multiple={resourceType === 'Index'}
                 loading={loading}
                 selectorName={resourceType}
                 list={resource.list}

+ 3 - 19
src/routes/Product/Courseware/CoursewareList.js

@@ -5,7 +5,6 @@ import { routerRedux } from 'dva/router';
 import { Card, Modal, Button, message } from 'antd';
 import { StandardTableList } from '../../../components/RBList/index';
 import { renderStatus, addRowKey } from '../../../utils/utils';
-import styles from './CoursewareList.less';
 
 const Message = message;
 
@@ -78,13 +77,13 @@ export default class CoursewareListPage extends Component {
         <div>
           <Button
             size="small"
-            className={styles.editBtn}
+            className="editBtn"
             onClick={() => this.handleEditOperation(item)}
           >编辑
           </Button>
           <Button
             size="small"
-            className={styles.delBtn}
+            className="delBtn"
             onClick={() => this.handleDeleteOperation(item)}
           >删除
           </Button>
@@ -117,27 +116,11 @@ export default class CoursewareListPage extends Component {
       title: '课件编号',
       key: 1,
       dataIndex: 'code',
-      render: (text, record) => (
-        <a
-          className={styles.link}
-          onClick={() => this.handleEditOperation(record)}
-        >
-          {text}
-        </a>
-      ),
       width: '25%',
     }, {
       title: '课件名称',
       key: 2,
       dataIndex: 'title',
-      render: (text, record) => (
-        <a
-          className={styles.link}
-          onClick={() => this.handleEditOperation(record)}
-        >
-          {text}
-        </a>
-      ),
       width: '30%',
     }, {
       title: '课件状态',
@@ -157,6 +140,7 @@ export default class CoursewareListPage extends Component {
       dataIndex: 'operation',
       render: (_, record) => renderOperation(record),
       width: '13%',
+      align: 'right',
     }];
     return (
       <Card>

+ 0 - 16
src/routes/Product/Courseware/CoursewareList.less

@@ -1,16 +0,0 @@
-@import "../../../../node_modules/antd/lib/style/themes/default.less";
-
-.link {
-  font-weight: 500;
-}
-.editBtn {
-  margin-right: 10px;
-  background: @primary-5;
-  color: #fff;
-  font-weight: 500;
-}
-.delBtn {
-  background: #f5222d;
-  color: #fff;
-  font-weight: 500;
-}

+ 3 - 19
src/routes/Product/Lesson/LessonList.js

@@ -5,7 +5,6 @@ import { routerRedux } from 'dva/router';
 import { Card, Modal, Button, message } from 'antd';
 import { StandardTableList } from '../../../components/RBList/index';
 import { renderStatus, addRowKey } from '../../../utils/utils';
-import styles from './LessonList.less';
 
 const Message = message;
 
@@ -78,13 +77,13 @@ export default class LessonListPage extends Component {
         <div>
           <Button
             size="small"
-            className={styles.editBtn}
+            className="editBtn"
             onClick={() => this.handleEditOperation(item)}
           >编辑
           </Button>
           <Button
             size="small"
-            className={styles.delBtn}
+            className="delBtn"
             onClick={() => this.handleDeleteOperation(item)}
           >删除
           </Button>
@@ -117,27 +116,11 @@ export default class LessonListPage extends Component {
       title: '课编号',
       key: 1,
       dataIndex: 'code',
-      render: (text, record) => (
-        <a
-          className={styles.link}
-          onClick={() => this.handleEditOperation(record)}
-        >
-          {text}
-        </a>
-      ),
       width: '25%',
     }, {
       title: '课名称',
       key: 2,
       dataIndex: 'title',
-      render: (text, record) => (
-        <a
-          className={styles.link}
-          onClick={() => this.handleEditOperation(record)}
-        >
-          {text}
-        </a>
-      ),
       width: '30%',
     }, {
       title: '课状态',
@@ -157,6 +140,7 @@ export default class LessonListPage extends Component {
       dataIndex: 'operation',
       render: (_, record) => renderOperation(record),
       width: '13%',
+      align: 'right',
     }];
     return (
       <Card>

+ 0 - 16
src/routes/Product/Lesson/LessonList.less

@@ -1,16 +0,0 @@
-@import "../../../../node_modules/antd/lib/style/themes/default.less";
-
-.link {
-  font-weight: 500;
-}
-.editBtn {
-  margin-right: 10px;
-  background: @primary-5;
-  color: #fff;
-  font-weight: 500;
-}
-.delBtn {
-  background: #f5222d;
-  color: #fff;
-  font-weight: 500;
-}

+ 3 - 19
src/routes/Product/Package/PackageList.js

@@ -5,7 +5,6 @@ import { routerRedux } from 'dva/router';
 import { Card, Modal, Button, message } from 'antd';
 import { StandardTableList } from '../../../components/RBList/index';
 import { renderStatus, addRowKey } from '../../../utils/utils';
-import styles from './PackageList.less';
 
 const Message = message;
 
@@ -77,13 +76,13 @@ export default class PackageListPage extends Component {
         <div>
           <Button
             size="small"
-            className={styles.editBtn}
+            className="editBtn"
             onClick={() => this.handleEditOperation(item)}
           >编辑
           </Button>
           <Button
             size="small"
-            className={styles.delBtn}
+            className="delBtn"
             onClick={() => this.handleDeleteOperation(item)}
           >删除
           </Button>
@@ -116,27 +115,11 @@ export default class PackageListPage extends Component {
       title: '套餐包编号',
       key: 1,
       dataIndex: 'code',
-      render: (text, record) => (
-        <a
-          className={styles.link}
-          onClick={() => this.handleEditOperation(record)}
-        >
-          {text}
-        </a>
-      ),
       width: '25%',
     }, {
       title: '套餐包名称',
       key: 2,
       dataIndex: 'name',
-      render: (text, record) => (
-        <a
-          className={styles.link}
-          onClick={() => this.handleEditOperation(record)}
-        >
-          {text}
-        </a>
-      ),
       width: '30%',
     }, {
       title: '套餐包状态',
@@ -156,6 +139,7 @@ export default class PackageListPage extends Component {
       dataIndex: 'operation',
       render: (_, record) => renderOperation(record),
       width: '13%',
+      align: 'right',
     }];
     return (
       <Card>

+ 0 - 16
src/routes/Product/Package/PackageList.less

@@ -1,16 +0,0 @@
-@import "../../../../node_modules/antd/lib/style/themes/default.less";
-
-.link {
-  font-weight: 500;
-}
-.editBtn {
-  margin-right: 10px;
-  background: @primary-5;
-  color: #fff;
-  font-weight: 500;
-}
-.delBtn {
-  background: #f5222d;
-  color: #fff;
-  font-weight: 500;
-}

+ 1 - 1
src/routes/Product/Support/SupportCreate.js

@@ -284,7 +284,7 @@ export default class SupportCreatePage extends Component {
             pageSize={resource.pageSize}
             totalSize={resource.totalSize}
             multiple={isCover ? false : true}
-            selectorName={isCover ? 'PictureSingle' : 'Picture'}
+            selectorName={isCover ? 'PictureSingle' : 'Index'}
             onCancel={() => this.handleSelectorCancel(isCover ? 'cover' : 'carousel')}
             onChange={(data) => this.handleSelectorChange(isCover ? 'cover' : 'carousel', data)}
             onFinish={(rows) => this.handleSelectorFinish(isCover ? 'cover' : 'carousel', rows)}

+ 5 - 21
src/routes/Product/Support/SupportList.js

@@ -5,7 +5,6 @@ import { routerRedux } from 'dva/router';
 import { Card, Modal, Button, message } from 'antd';
 import { StandardTableList } from '../../../components/RBList/index';
 import { renderStatus, addRowKey } from '../../../utils/utils';
-import styles from './SupportList.less';
 
 const Message = message;
 
@@ -78,13 +77,13 @@ export default class SupportListPage extends Component {
         <div>
           <Button
             size="small"
-            className={styles.editBtn}
+            className="editBtn"
             onClick={() => this.handleEditOperation(item)}
           >编辑
           </Button>
           <Button
             size="small"
-            className={styles.delBtn}
+            className="delBtn"
             onClick={() => this.handleDeleteOperation(item)}
           >删除
           </Button>
@@ -117,28 +116,12 @@ export default class SupportListPage extends Component {
       title: '配套编号',
       key: 1,
       dataIndex: 'code',
-      render: (text, record) => (
-        <a
-          className={styles.link}
-          onClick={() => this.handleEditOperation(record)}
-        >
-          {text}
-        </a>
-      ),
-      width: '25%',
+      width: '20%',
     }, {
       title: '配套名称',
       key: 2,
       dataIndex: 'name',
-      render: (text, record) => (
-        <a
-          className={styles.link}
-          onClick={() => this.handleEditOperation(record)}
-        >
-          {text}
-        </a>
-      ),
-      width: '30%',
+      width: '35%',
     }, {
       title: '配套状态',
       key: 3,
@@ -157,6 +140,7 @@ export default class SupportListPage extends Component {
       dataIndex: 'operation',
       render: (_, record) => renderOperation(record),
       width: '13%',
+      align: 'right',
     }];
     return (
       <Card>

+ 0 - 16
src/routes/Product/Support/SupportList.less

@@ -1,16 +0,0 @@
-@import "../../../../node_modules/antd/lib/style/themes/default.less";
-
-.link {
-  font-weight: 500;
-}
-.editBtn {
-  margin-right: 10px;
-  background: @primary-5;
-  color: #fff;
-  font-weight: 500;
-}
-.delBtn {
-  background: #f5222d;
-  color: #fff;
-  font-weight: 500;
-}

+ 4 - 3
src/routes/Resource/PictureCardList.js

@@ -1,6 +1,6 @@
 import React from 'react';
-import { PictureItem } from '../../components/RBItem';
-import { StandardCardList } from '../../components/RBList';
+import { PictureItem } from '../../../components/RBItem';
+import { StandardCardList } from '../../../components/RBList';
 
 function pictureItemFormatter(originData) {
   return originData.map((item) => {
@@ -15,7 +15,7 @@ function pictureItemFormatter(originData) {
 
 function PictureCardList({
   UIParams, dataSource, loading, totalSize, pageSize, pageNo,
-  onFilterClick, onCreateClick, onBatchClick, onDeleteClick,
+  onFilterClick, onCreateClick, onBatchClick, onDeleteClick, onEditClick,
 }) {
   const batchActions = [{
     key: 'delete',
@@ -48,6 +48,7 @@ function PictureCardList({
       footer={{ pagination, batchActions, onBatchClick }}
       grid={{ gutter: 16, xxl: 12, xl: 6, lg: 4, md: 3, sm: 2, xs: 1 }}
       onDelete={onDeleteClick}
+      onEdit={onEditClick}
     />
   );
 }

+ 173 - 0
src/routes/Resource/Picture/PictureEdit.js

@@ -0,0 +1,173 @@
+import React, { PureComponent } from 'react';
+import { Card, Form, Input, Button, Switch } from 'antd';
+import { connect } from 'dva';
+import { routerRedux } from 'dva/router';
+import Uploader from '../../../components/RBUpload';
+import PageHeaderLayout from '../../../layouts/PageHeaderLayout';
+import { boolToStatus, statusToBool } from '../../../utils/utils';
+
+const formItemLayout = {
+  labelCol: {
+    xs: { span: 24 },
+    sm: { span: 6 },
+  },
+  wrapperCol: {
+    xs: { span: 24 },
+    sm: { span: 14 },
+    md: { span: 10 },
+  },
+};
+const submitFormLayout = {
+  wrapperCol: {
+    xs: { span: 24, offset: 0 },
+    sm: { span: 10, offset: 6 },
+  },
+};
+
+function getFileObject(params) {
+  if (!params) { return; }
+  const { format, url, path, name, size } = params;
+  return { url, path, name, size, type: `image/${format}` };
+}
+
+@Form.create()
+@connect(({ loading }) => ({
+  submitting: loading.models.resource,
+}))
+export default class PictureSingleUpload extends PureComponent {
+  constructor(props) {
+    super(props);
+    const { location } = props;
+    const { state } = location;
+    this.state = {
+      fileList: [getFileObject(state)],
+      code: state.code || '',
+      name: state.name || '',
+    };
+  }
+  handleNameInputChange = (e) => {
+    this.setState({ name: e.target.value });
+  }
+  handleOnChangeEvent = (fileList) => {
+    this.setState({ fileList });
+    return fileList;
+  }
+  handlePageBack = () => {
+    const { UIParams, Queryers } = this.props.location.state || {};
+    this.props.dispatch(
+      routerRedux.push({
+        pathname: '/resource/picture',
+        state: { UIParams, Queryers },
+      })
+    );
+  }
+  handlePageSubmit = (e) => {
+    e.preventDefault();
+    this.props.form.validateFieldsAndScroll((err, values) => {
+      if (!err) {
+        const { id, type, UIParams, Queryers } = this.props.location.state || {};
+        const { fileList, status, ...params } = values;
+        if (Array.isArray(fileList) && fileList.length) {
+          params.url = fileList[0].url;
+        }
+        params.id = id;
+        params.type = type;
+        params.status = boolToStatus(status);
+        this.props.dispatch({
+          type: 'resource/updateImage',
+          payload: params,
+          states: { UIParams, Queryers },
+        });
+      }
+    });
+  }
+  render() {
+    const { form, submitting } = this.props;
+    const { getFieldDecorator } = form;
+    const { fileList, code, name } = this.state;
+    const firstPicture = fileList[0] || {};
+    const { type, size, path } = firstPicture;
+
+    return (
+      <PageHeaderLayout>
+        <Card>
+          <Form onSubmit={this.handlePageSubmit}>
+            <Form.Item label="图片编号" {...formItemLayout}>
+              {getFieldDecorator('code', {
+                initialValue: code,
+              })(
+                <Input disabled />
+              )}
+            </Form.Item>
+            <Form.Item label="图片名称" {...formItemLayout}>
+              {getFieldDecorator('name', {
+                rules: [{ required: true, message: '图片名称不能为空' }],
+                initialValue: name,
+              })(
+                <Input onChange={this.handleNameInputChange} />
+              )}
+            </Form.Item>
+            <Form.Item label="图片上传" {...formItemLayout}>
+              {getFieldDecorator('fileList', {
+                getValueFromEvent: this.handleOnChangeEvent,
+              })(
+                <Uploader
+                  forbidden={
+                    !((code && /^[a-zA-Z0-9|-]+$/ig.test(code) && name))
+                  }
+                  fileCode={code}
+                  fileList={fileList}
+                  accept="image"
+                  multiple={false}
+                  totalLimit={1}
+                />
+              )}
+            </Form.Item>
+            <Form.Item label="图片路径" {...formItemLayout}>
+              {getFieldDecorator('path', {
+                initialValue: path,
+              })(
+                <Input disabled />
+              )}
+            </Form.Item>
+            <Form.Item label="图片格式" {...formItemLayout}>
+              {getFieldDecorator('format', {
+                initialValue: type ? type.split('/')[1] : '',
+              })(
+                <Input disabled />
+              )}
+            </Form.Item>
+            <Form.Item label="图片大小" {...formItemLayout}>
+              {getFieldDecorator('size', {
+                initialValue: size,
+              })(
+                <Input disabled />
+              )}
+            </Form.Item>
+            <Form.Item label="图片状态" {...formItemLayout}>
+              {getFieldDecorator('status', {
+                valuePropName: 'checked',
+                initialValue: statusToBool(status),
+              })(
+                <Switch
+                  checkedChildren="启用"
+                  unCheckedChildren="不启用"
+                />
+              )}
+            </Form.Item>
+            <Form.Item {...submitFormLayout} style={{ marginTop: 32 }}>
+              <Button onClick={this.handlePageBack}>取消</Button>
+              <Button
+                type="primary"
+                htmlType="submit"
+                loading={submitting}
+                style={{ marginLeft: 8 }}
+              >提交
+              </Button>
+            </Form.Item>
+          </Form>
+        </Card>
+      </PageHeaderLayout>
+    );
+  }
+}

+ 36 - 31
src/routes/Resource/PictureList.js

@@ -4,6 +4,7 @@ import { routerRedux } from 'dva/router';
 import { Card, Modal, Button, message } from 'antd';
 import PictureCardList from './PictureCardList';
 import PictureTableList from './PictureTableList';
+import PageHeaderLayout from '../../../layouts/PageHeaderLayout';
 
 const Message = message;
 
@@ -32,15 +33,10 @@ export default class PictureListPage extends Component {
   }
   // 增加
   handleCreateOperation = () => {
-    // 页面跳转把这些参数传递过去,返回的时候再传回来,来保证组件等状态不变
-    const { Queryers, UIParams } = this.state;
     this.props.dispatch(
       routerRedux.push({
-        pathname: '/resource/imageCreate/single',
-        state: {
-          Queryers,
-          UIParams,
-        },
+        pathname: '/resource/picture-upload/single',
+        state: this.state,
       })
     );
   }
@@ -49,8 +45,7 @@ export default class PictureListPage extends Component {
     Modal.confirm({
       okText: '确定',
       cancelText: '取消',
-      title: '你确定要删除这张图片吗?',
-      content: '删除后所有与之关联的课件将不再显示该图片',
+      title: '您确定要删除这张图片吗?',
       onOk: () => {
         this.props.dispatch({
           type: 'resource/deleteImage',
@@ -60,8 +55,16 @@ export default class PictureListPage extends Component {
     });
   }
   // 修改
-  handleEditOperation = () => {
-
+  handleEditOperation = (data) => {
+    this.props.dispatch(
+      routerRedux.push({
+        pathname: `/resource/picture-edit/${data.id}`,
+        state: {
+          ...this.state,
+          ...data,
+        },
+      })
+    );
   }
   // 查询
   handleFilterOperation = (params, states) => {
@@ -95,26 +98,28 @@ export default class PictureListPage extends Component {
       onBatchClick: this.handleBatchOperation,
     };
     return (
-      <Card bordered={false}>
-        <Button.Group style={{ marginBottom: 16 }}>
-          <Button
-            style={{ width: 50 }}
-            onClick={this.handleShowTypeChange}
-            icon="appstore-o"
-            type={this.state.isCard ? 'primary' : null}
-          />
-          <Button
-            style={{ width: 50 }}
-            onClick={this.handleShowTypeChange}
-            icon="table"
-            type={this.state.isCard ? null : 'primary'}
-          />
-        </Button.Group>
-        {this.state.isCard ?
-          <PictureCardList {...publicProps} /> :
-          <PictureTableList {...publicProps} />
-        }
-      </Card>
+      <PageHeaderLayout>
+        <Card>
+          <Button.Group style={{ marginBottom: 16 }}>
+            <Button
+              style={{ width: 50 }}
+              onClick={this.handleShowTypeChange}
+              icon="appstore-o"
+              type={this.state.isCard ? 'primary' : null}
+            />
+            <Button
+              style={{ width: 50 }}
+              onClick={this.handleShowTypeChange}
+              icon="table"
+              type={this.state.isCard ? null : 'primary'}
+            />
+          </Button.Group>
+          {this.state.isCard ?
+            <PictureCardList {...publicProps} /> :
+            <PictureTableList {...publicProps} />
+          }
+        </Card>
+      </PageHeaderLayout>
     );
   }
 }

+ 3 - 3
src/routes/Resource/PictureCreateMultiple.js

@@ -2,15 +2,15 @@ import React, { PureComponent } from 'react';
 import { connect } from 'dva';
 import { routerRedux } from 'dva/router';
 import { Input, Button, message } from 'antd';
-import Uploader from '../../components/RBUpload';
-import styles from './PictureCreateMultiple.less';
+import Uploader from '../../../components/RBUpload/index';
+import styles from './PictureMultipleUpload.less';
 
 const Message = message;
 
 @connect(({ loading }) => ({
   submitting: loading.models.resource,
 }))
-export default class CreateMultiplePicture extends PureComponent {
+export default class PictureMultipleUpload extends PureComponent {
   state = {
     fileList: [],
   }

+ 1 - 1
src/routes/Resource/PictureCreateMultiple.less

@@ -1,4 +1,4 @@
-@import "~antd/lib/style/themes/default.less";
+@import "../../../../node_modules/antd/lib/style/themes/default.less";
 
 .content {
   width: 100%;

+ 25 - 22
src/routes/Resource/PictureCreateSingle.js

@@ -2,14 +2,33 @@ import React, { PureComponent, Fragment } from 'react';
 import { Form, Input, Button, Switch, Alert } from 'antd';
 import { connect } from 'dva';
 import { routerRedux } from 'dva/router';
-import Uploader from '../../components/RBUpload';
-import { STATUS_DELETE, STATUS_NORMAL } from '../../utils/config';
+import Uploader from '../../../components/RBUpload';
+import { boolToStatus } from '../../../utils/utils';
+import { RESOURCE_IMAGE } from '../../../utils/config';
+
+const formItemLayout = {
+  labelCol: {
+    xs: { span: 24 },
+    sm: { span: 6 },
+  },
+  wrapperCol: {
+    xs: { span: 24 },
+    sm: { span: 14 },
+    md: { span: 10 },
+  },
+};
+const submitFormLayout = {
+  wrapperCol: {
+    xs: { span: 24, offset: 0 },
+    sm: { span: 10, offset: 6 },
+  },
+};
 
 @Form.create()
 @connect(({ loading }) => ({
   submitting: loading.models.resource,
 }))
-export default class CreateOnePicture extends PureComponent {
+export default class PictureSingleUpload extends PureComponent {
   state = {
     fileList: [],
     code: null,
@@ -29,7 +48,7 @@ export default class CreateOnePicture extends PureComponent {
     const { UIParams, Queryers } = this.props.location.state || {};
     this.props.dispatch(
       routerRedux.push({
-        pathname: '/resource/image',
+        pathname: '/resource/picture',
         state: {
           UIParams,
           Queryers,
@@ -45,7 +64,8 @@ export default class CreateOnePicture extends PureComponent {
         if (Array.isArray(fileList) && fileList.length) {
           params.url = fileList[0].url;
         }
-        params.status = status ? STATUS_NORMAL : STATUS_DELETE;
+        params.status = boolToStatus(status);
+        params.type = RESOURCE_IMAGE;
         this.props.dispatch({
           type: 'resource/createImage',
           payload: params,
@@ -60,23 +80,6 @@ export default class CreateOnePicture extends PureComponent {
     const firstPicture = fileList[0] || {};
     const { type, size, path } = firstPicture;
 
-    const formItemLayout = {
-      labelCol: {
-        xs: { span: 24 },
-        sm: { span: 6 },
-      },
-      wrapperCol: {
-        xs: { span: 24 },
-        sm: { span: 14 },
-        md: { span: 12 },
-      },
-    };
-    const submitFormLayout = {
-      wrapperCol: {
-        xs: { span: 24, offset: 0 },
-        sm: { span: 12, offset: 6 },
-      },
-    };
     return (
       <Form onSubmit={this.handlePageSubmit}>
         <Form.Item {...submitFormLayout}>

+ 20 - 11
src/routes/Resource/PictureTableList.js

@@ -1,14 +1,14 @@
 import React from 'react';
 import moment from 'moment';
-import { Divider } from 'antd';
-import { ossHost } from '../../utils/config';
-import { renderStatus, addRowKey } from '../../utils/utils';
-import { StandardTableList } from '../../components/RBList';
+import { Button } from 'antd';
+import { ossHost } from '../../../utils/config';
+import { renderStatus, addRowKey } from '../../../utils/utils';
+import { StandardTableList } from '../../../components/RBList/index';
 import styles from './PictureTableList.less';
 
 function PictureTableList({
   UIParams, dataSource, loading, totalSize, pageSize, pageNo,
-  onFilterClick, onCreateClick, onBatchClick, onDeleteClick,
+  onFilterClick, onCreateClick, onBatchClick, onDeleteClick, onEditClick,
 }) {
   const batchActions = [{
     key: 'delete',
@@ -46,14 +46,22 @@ function PictureTableList({
       </div>
     );
   };
-  const renderActions = () => {
+  const renderActions = (item) => {
     return (
       <div>
-        <a>查看</a>
-        <Divider type="vertical" />
-        <a>编辑</a>
-        <Divider type="vertical" />
-        <a onClick={onDeleteClick}>删除</a>
+        <Button
+          size="small"
+          type="primary"
+          className={styles.editBtn}
+          onClick={() => onEditClick(item)}
+        >编辑
+        </Button>
+        <Button
+          size="small"
+          className={styles.delBtn}
+          onClick={() => onDeleteClick(item)}
+        >删除
+        </Button>
       </div>
     );
   };
@@ -97,6 +105,7 @@ function PictureTableList({
     dataIndex: 'action',
     render: (_, record) => renderActions(record),
     width: '15%',
+    align: 'right',
   }];
 
   return (

+ 34 - 0
src/routes/Resource/Picture/PictureTableList.less

@@ -0,0 +1,34 @@
+@import "../../../../node_modules/antd/lib/style/themes/default.less";
+
+.thumbPic {
+  position: relative;
+  vertical-align: middle;
+  text-align: center;
+  width: 90px;
+  height: 128px;
+  line-height: 128px;
+  img {
+    max-height: 100%;
+    max-width: 100%;
+    vertical-align: middle;
+    height: auto;
+  }
+}
+
+.meta {
+  p {
+    font-weight: 500;
+  }
+}
+
+.editBtn {
+  margin-right: 10px;
+  background: @primary-5;
+  color: #fff;
+  font-weight: 500;
+}
+.delBtn {
+  background: #f5222d;
+  color: #fff;
+  font-weight: 500;
+}

+ 35 - 0
src/routes/Resource/Picture/PictureUpload.js

@@ -0,0 +1,35 @@
+import React, { Component } from 'react';
+import { Route, Switch } from 'dva/router';
+import { connect } from 'dva';
+import { Card } from 'antd';
+import { getRoutes } from '../../../utils/utils';
+import PageHeaderLayout from '../../../layouts/PageHeaderLayout';
+
+@connect()
+export default class PictureUpload extends Component {
+  render() {
+    const { match, routerData } = this.props;
+    const routes = getRoutes(match.path, routerData);
+
+    return (
+      <PageHeaderLayout>
+        <Card>
+          <Switch>
+            {
+              routes.map(item =>
+                (
+                  <Route
+                    key={item.key}
+                    path={item.path}
+                    component={item.component}
+                    exact={item.exact}
+                  />
+                )
+              )
+            }
+          </Switch>
+        </Card>
+      </PageHeaderLayout>
+    );
+  }
+}

+ 97 - 0
src/routes/Resource/Picture/PictureUploadResult.js

@@ -0,0 +1,97 @@
+import React, { Component } from 'react';
+import { connect } from 'dva';
+import { routerRedux } from 'dva/router';
+import { Button, Icon, Card } from 'antd';
+import Result from '../../../components/Result';
+import { genAbsolutePicUrl } from '../../../utils/utils';
+
+class PictureUploadSuccessResult extends Component {
+  jumpToPictureListPage = () => {
+    this.props.dispatch(
+      routerRedux.push({
+        pathname: '/resource/picture',
+      })
+    );
+  }
+  jumpToPictureDetailPage = (params) => {
+    this.props.dispatch(
+      routerRedux.push({
+        pathname: `/resource/picture-edit/:${params.id}`,
+        state: params,
+      })
+    );
+  }
+  jumpToPictureSingleUpload = () => {
+    this.props.dispatch(
+      routerRedux.push({
+        pathname: '/resource/picture-upload/single',
+      })
+    );
+  }
+  render() {
+    const { location } = this.props;
+    const { state = {} } = location;
+    const { path, code, format, name, size } = state;
+    const description = '图片上传成功,请核对以下图片信息,如果有误请编辑图片进行修改';
+    const extra = (
+      <div>
+        <div style={{ fontSize: 16, color: 'rgba(0, 0, 0, 0.85)', fontWeight: 500, marginBottom: 16 }}>
+          您提交的图片信息如下:
+        </div>
+        <div style={{ marginBottom: 16 }}>
+          <Icon style={{ color: '#52c41a', marginRight: 8 }} type="check-circle-o" />图片名称:
+          <span style={{ marginLeft: 16 }}>{name || ''}</span>
+        </div>
+        <div style={{ marginBottom: 16 }}>
+          <Icon style={{ color: '#52c41a', marginRight: 8 }} type="check-circle-o" />图片编号:
+          <span style={{ marginLeft: 16 }}>{code || ''}</span>
+        </div>
+        <div style={{ marginBottom: 16 }}>
+          <Icon style={{ color: '#52c41a', marginRight: 8 }} type="check-circle-o" />图片格式:
+          <span style={{ marginLeft: 16 }}>{format || ''}</span>
+        </div>
+        <div style={{ marginBottom: 16 }}>
+          <Icon style={{ color: '#52c41a', marginRight: 8 }} type="check-circle-o" />图片大小:
+          <span style={{ marginLeft: 16 }}>{`${size || ''}字节`}</span>
+        </div>
+        <div style={{ marginBottom: 16 }}>
+          <Icon style={{ color: '#52c41a', marginRight: 8 }} type="check-circle-o" />图片地址:
+          <span style={{ marginLeft: 16 }}>{path ? genAbsolutePicUrl(path) : ''}</span>
+        </div>
+      </div>
+    );
+    const actions = (
+      <div>
+        <Button
+          onClick={this.jumpToPictureListPage}
+        >返回列表
+        </Button>
+        <Button
+          type="primary"
+          style={{ marginLeft: 10 }}
+          onClick={this.jumpToPictureSingleUpload}
+        >再传一个
+        </Button>
+        <Button
+          type="primary"
+          style={{ marginLeft: 10 }}
+          onClick={() => this.jumpToPictureDetailPage(state)}
+        >修改图片
+        </Button>
+      </div>
+    );
+    return (
+      <Card>
+        <Result
+          type="success"
+          title="上传成功"
+          description={description}
+          extra={extra}
+          actions={actions}
+        />
+      </Card>
+    );
+  }
+}
+
+export default connect()(PictureUploadSuccessResult);

+ 0 - 59
src/routes/Resource/PictureCreate.js

@@ -1,59 +0,0 @@
-import React, { Component } from 'react';
-import { routerRedux, Route, Switch } from 'dva/router';
-import { connect } from 'dva';
-import PageHeaderLayout from '../../layouts/PageHeaderLayout';
-import { getRoutes } from '../../utils/utils';
-
-@connect()
-export default class PictureCreate extends Component {
-  handleTabChange = (key) => {
-    const { dispatch, match } = this.props;
-    switch (key) {
-      case 'single':
-        dispatch(routerRedux.push(`${match.url}/single`));
-        break;
-      case 'multiple':
-        dispatch(routerRedux.push(`${match.url}/multiple`));
-        break;
-      default:
-        break;
-    }
-  }
-
-  render() {
-    // tab面板列表
-    const tabList = [{
-      key: 'single',
-      tab: '单图上传',
-    }, {
-      key: 'multiple',
-      tab: '多图上传',
-    }];
-
-    const { match, routerData, location } = this.props;
-    const routes = getRoutes(match.path, routerData);
-
-    return (
-      <PageHeaderLayout
-        tabList={tabList}
-        tabActiveKey={location.pathname.replace(`${match.path}/`, '')}
-        onTabChange={this.handleTabChange}
-      >
-        <Switch>
-          {
-            routes.map(item =>
-              (
-                <Route
-                  key={item.key}
-                  path={item.path}
-                  component={item.component}
-                  exact={item.exact}
-                />
-              )
-            )
-          }
-        </Switch>
-      </PageHeaderLayout>
-    );
-  }
-}

+ 0 - 22
src/routes/Resource/PictureTableList.less

@@ -1,22 +0,0 @@
-@import "~antd/lib/style/themes/default.less";
-
-.thumbPic {
-  position: relative;
-  vertical-align: middle;
-  text-align: center;
-  width: 90px;
-  height: 128px;
-  line-height: 128px;
-  img {
-    max-height: 100%;
-    max-width: 100%;
-    vertical-align: middle;
-    height: auto;
-  }
-}
-
-.meta {
-  p {
-    font-weight: 500;
-  }
-}

+ 36 - 32
src/routes/Resource/VideoList.js

@@ -1,9 +1,11 @@
+/* eslint-disable no-prototype-builtins */
 import React, { Component } from 'react';
 import { connect } from 'dva';
 import { Card, Button, message } from 'antd';
 import VideoPlayList from './VideoPlayList';
 import VideoTableList from './VideoTableList';
-import { addRowKey } from '../../utils/utils';
+import PageHeaderLayout from '../../../layouts/PageHeaderLayout';
+import { addRowKey } from '../../../utils/utils';
 
 const Message = message;
 
@@ -29,7 +31,7 @@ export default class VideoListPage extends Component {
     super(props);
     this.state = {
       isCard: true,
-      destory: true,
+      destroy: true,
       current: {},
     };
   }
@@ -52,11 +54,11 @@ export default class VideoListPage extends Component {
   handleBatchOperation = () => {
     Message.info('暂不支持批量操作!');
   }
-  handleModalDestory = () => {
-    this.setState({ destory: true });
+  handleModalDestroy = () => {
+    this.setState({ destroy: true });
   }
   handleModalCreate = (item) => {
-    this.setState({ destory: false, current: item });
+    this.setState({ destroy: false, current: item });
   }
 
   render() {
@@ -71,34 +73,36 @@ export default class VideoListPage extends Component {
       onFilterClick: this.handleFilterOperation,
     };
     return (
-      <Card bordered={false}>
-        <Button.Group style={{ marginBottom: 16 }}>
-          <Button
-            style={{ width: 50 }}
-            onClick={this.handleShowTypeChange}
-            icon="appstore-o"
-            type={this.state.isCard ? 'primary' : null}
-          />
-          <Button
-            style={{ width: 50 }}
-            onClick={this.handleShowTypeChange}
-            icon="table"
-            type={this.state.isCard ? null : 'primary'}
-          />
-        </Button.Group>
-        {this.state.isCard ?
-          <VideoPlayList {...publicProps} /> : (
-            <VideoTableList
-              {...publicProps}
-              currentItem={this.state.current}
-              modalDestory={this.state.destory}
-              onModalDestory={this.handleModalDestory}
-              onModalCreate={this.handleModalCreate}
-              onBatchClick={this.handleBatchOperation}
+      <PageHeaderLayout>
+        <Card bordered={false}>
+          <Button.Group style={{ marginBottom: 16 }}>
+            <Button
+              style={{ width: 50 }}
+              onClick={this.handleShowTypeChange}
+              icon="appstore-o"
+              type={this.state.isCard ? 'primary' : null}
             />
-          )
-        }
-      </Card>
+            <Button
+              style={{ width: 50 }}
+              onClick={this.handleShowTypeChange}
+              icon="table"
+              type={this.state.isCard ? null : 'primary'}
+            />
+          </Button.Group>
+          {this.state.isCard ?
+            <VideoPlayList {...publicProps} /> : (
+              <VideoTableList
+                {...publicProps}
+                currentItem={this.state.current}
+                modalDestroy={this.state.destroy}
+                onModalDestroy={this.handleModalDestroy}
+                onModalCreate={this.handleModalCreate}
+                onBatchClick={this.handleBatchOperation}
+              />
+            )
+          }
+        </Card>
+      </PageHeaderLayout>
     );
   }
 }

+ 1 - 1
src/routes/Resource/VideoPlayList.js

@@ -1,7 +1,7 @@
 import React, { PureComponent } from 'react';
 import moment from 'moment';
 import { Table, Pagination, Select, Input } from 'antd';
-import RBVideoPlayer from '../../components/RBVideoPlayer';
+import RBVideoPlayer from '../../../components/RBVideoPlayer/index';
 import styles from './VideoPlayList.less';
 
 export default class VideoPlayList extends PureComponent {

+ 1 - 1
src/routes/Resource/VideoPlayList.less

@@ -1,4 +1,4 @@
-@import "~antd/lib/style/themes/default.less";
+@import "../../../../node_modules/antd/lib/style/themes/default.less";
 
 .table {
   font-size: 16px;

+ 8 - 9
src/routes/Resource/VideoTableList.js

@@ -1,14 +1,13 @@
 import React from 'react';
 import moment from 'moment';
-import { Card, Badge, Modal, message } from 'antd';
-import { ossHost } from '../../utils/config';
-import { StandardTableList } from '../../components/RBList';
-import RBVideoPlayer from '../../components/RBVideoPlayer';
-import { renderStatus, renderVideoQuality } from '../../utils/utils';
+import { Modal } from 'antd';
+import { StandardTableList } from '../../../components/RBList/index';
+import RBVideoPlayer from '../../../components/RBVideoPlayer/index';
+import { renderStatus, renderVideoQuality } from '../../../utils/utils';
 
 function VideoTableList({
-  dataSource, loading, totalSize, pageSize, pageNo, modalDestory, currentItem,
-  onFilterClick, onBatchClick, onModalCreate, onModalDestory,
+  dataSource, loading, totalSize, pageSize, pageNo, modalDestroy, currentItem,
+  onFilterClick, onBatchClick, onModalCreate, onModalDestroy,
 }) {
   const pagination = {
     pageNo,
@@ -80,12 +79,12 @@ function VideoTableList({
         header={{ basicSearch, onFilterClick }}
         footer={{ pagination, batchActions, onBatchClick }}
       />
-      {!modalDestory && (
+      {!modalDestroy && (
       <Modal
         title={currentItem.name}
         visible
         footer={null}
-        onCancel={onModalDestory}
+        onCancel={onModalDestroy}
         maskClosable={false}
         width={800}
       >

+ 60 - 10
src/routes/Shelves/Course/CourseEdit.js

@@ -7,7 +7,6 @@ import FooterToolbar from '../../../components/FooterToolbar';
 import Selector from '../../../components/RBTableSelector/Selector';
 import { addRowKey } from '../../../utils/utils';
 import { PRODUCT_COURSE, STATUS_NORMAL } from '../../../utils/config';
-import styles from './CourseEdit.less';
 
 @connect(({ loading, shelves, tag }) => ({
   tag,
@@ -101,7 +100,45 @@ export default class CourseEdit extends Component {
     });
   }
   handleTagSelectorModalShow = () => {
-    this.setState({ tagSelectorDestroy: false });
+    this.setState({
+      tagSelectorDestroy: false,
+    });
+    const { merchantId } = this.state;
+    this.props.dispatch({
+      type: 'tag/fetchTagList',
+      payload: { merchantId },
+    });
+  }
+  handleTagSelectorCancel = () => {
+    this.setState({
+      tagSelectorDestroy: true,
+    });
+  }
+  handleTagSelectorChange = (params) => {
+    const { merchantId } = this.state;
+    this.props.dispatch({
+      type: 'tag/fetchTagList',
+      payload: { merchantId, ...params },
+    });
+  }
+  handleTagSelectorFinish = (rows) => {
+    const { pid, merchantId } = this.state;
+    const newTagIds = (rows || []).map(row => row.id);
+    this.props.dispatch({
+      type: 'shelves/updateItemTags',
+      payload: {
+        pid,
+        merchantId,
+        tags: newTagIds,
+      },
+      states: {
+        pid,
+        merchantId,
+      },
+    });
+    this.setState({
+      tagSelectorDestroy: true,
+    });
   }
   handlePageBack=() => {
     this.props.dispatch(routerRedux.push({
@@ -111,7 +148,7 @@ export default class CourseEdit extends Component {
   }
   render() {
     const { tagSelectorDestroy } = this.state;
-    const { submitting, tLoading, shelves, form } = this.props;
+    const { submitting, tLoading, shelves, tag, form } = this.props;
     const { getFieldDecorator } = form;
     const { currentItem } = shelves;
     const { goods, tags } = currentItem;
@@ -131,11 +168,23 @@ export default class CourseEdit extends Component {
           )}
         </Card>
         <Card title="栏目管理" style={{ marginBottom: 70 }}>
-          {tags && tags.map((item, index) =>
-            <Tag closable afterClose={() => this.handleTagClose(index)} color="#87d068" style={styles.tag} key={item.id}>{item.name}</Tag>
-          )}
-          <Tag style={{ borderStyle: 'dashed' }}><Icon type="plus" />添加栏目</Tag>
-          {!tagSelectorDestroy &&
+          {tags && tags.map((item, index) => (
+            <Tag
+              closable
+              color="#87d068"
+              key={item.id}
+              afterClose={() => this.handleTagClose(index)}
+            >
+              {item.name}
+            </Tag>
+          ))}
+          <Tag
+            style={{ borderStyle: 'dashed' }}
+            onClick={this.handleTagSelectorModalShow}
+          >
+            <Icon type="plus" />添加栏目
+          </Tag>
+          {!tagSelectorDestroy && (
             <Modal
               width={1100}
               footer={null}
@@ -152,12 +201,13 @@ export default class CourseEdit extends Component {
                 pageNo={tag.pageNo}
                 pageSize={tag.pageSize}
                 totalSize={tag.totalSize}
+                selectedRows={tags}
                 onCancel={this.handleTagSelectorCancel}
                 onChange={this.handleTagSelectorChange}
                 onFinish={this.handleTagSelectorFinish}
-            />
+              />
             </Modal>
-          }
+          )}
         </Card>
         <FooterToolbar style={{ width: '100%' }}>
           <Button

+ 0 - 9
src/routes/Shelves/Course/CourseEdit.less

@@ -1,9 +0,0 @@
-@import "~antd/lib/style/themes/default.less";
-
-:global(.ant-tag) {
-  width: 137px;
-  text-align: center;
-  margin-top: 5px;
-  height: 25px;
-  line-height: 25px;
-}

+ 7 - 19
src/routes/Shelves/Course/CourseList.js

@@ -4,8 +4,8 @@ import { connect } from 'dva';
 import { routerRedux } from 'dva/router';
 import { Card, Modal, Button, message } from 'antd';
 import { StandardTableList } from '../../../components/RBList';
+import Ellipsis from '../../../components/Ellipsis';
 import { renderStatus, addRowKey } from '../../../utils/utils';
-import styles from './CourseList.less';
 
 const Message = message;
 
@@ -82,13 +82,13 @@ export default class CourseListPage extends Component {
         <div>
           <Button
             size="small"
-            className={styles.editBtn}
+            className="editBtn"
             onClick={() => this.handleEditOperation(item)}
           >编辑
           </Button>
           <Button
             size="small"
-            className={styles.delBtn}
+            className="delBtn"
             onClick={() => this.handleDeleteOperation(item)}
           >下架
           </Button>
@@ -121,26 +121,13 @@ export default class CourseListPage extends Component {
       title: '课程编号',
       key: 1,
       dataIndex: 'code',
-      render: (text, record) => (
-        <a
-          className={styles.link}
-          onClick={() => this.handleEditOperation(record)}
-        >
-          {text}
-        </a>
-      ),
       width: '15%',
     }, {
       title: '课程名称',
       key: 2,
       dataIndex: 'name',
-      render: (text, record) => (
-        <a
-          className={styles.link}
-          onClick={() => this.handleEditOperation(record)}
-        >
-          {text}
-        </a>
+      render: text => (
+        <Ellipsis tooltip lines={1}>{text}</Ellipsis>
       ),
       width: '30%',
     }, {
@@ -152,7 +139,7 @@ export default class CourseListPage extends Component {
       title: '上架状态',
       key: 4,
       dataIndex: 'status',
-      render: text => renderStatus(text),
+      render: text => renderStatus(text, '已下架', '已上架'),
       width: '10%',
     }, {
       title: '更新时间',
@@ -166,6 +153,7 @@ export default class CourseListPage extends Component {
       dataIndex: 'operation',
       render: (_, record) => renderOperation(record),
       width: '13%',
+      align: 'right',
     }];
     return (
       <Card>

+ 0 - 16
src/routes/Shelves/Course/CourseList.less

@@ -1,16 +0,0 @@
-@import "~antd/lib/style/themes/default.less";
-
-.link {
-  font-weight: 500;
-}
-.editBtn {
-  margin-right: 10px;
-  background: @primary-color;
-  color: #fff;
-  font-weight: 500;
-}
-.delBtn {
-  background: #f5222d;
-  color: #fff;
-  font-weight: 500;
-}

+ 137 - 9
src/routes/Shelves/Package/PackageEdit.js

@@ -1,18 +1,21 @@
-import React, { Component} from 'react';
-import { Card, Form, Button } from 'antd';
+import React, { Component } from 'react';
+import { Card, Modal, Form, Button, Tag, Icon } from 'antd';
 import { connect } from 'dva';
 import { routerRedux } from 'dva/router';
 import TableForm from './TableForm';
-import FooterToolbar from '../../../components/FooterToolbar/index';
-import { STATUS_NORMAL } from '../../../utils/config';
+import FooterToolbar from '../../../components/FooterToolbar';
+import Selector from '../../../components/RBTableSelector/Selector';
 import { addRowKey } from '../../../utils/utils';
+import { PRODUCT_PACKAGE, STATUS_NORMAL } from '../../../utils/config';
 
-@connect(({ loading, shelves }) => ({
+@connect(({ loading, shelves, tag }) => ({
+  tag,
   shelves,
+  tLoading: loading.models.tag,
   submitting: loading.models.shelves,
 }))
 @Form.create()
-export default class ShelvesEdit extends Component {
+export default class PackageEdit extends Component {
   constructor(props) {
     super(props);
     const { location } = props;
@@ -22,6 +25,7 @@ export default class ShelvesEdit extends Component {
       pid,
       merchantId,
       productType,
+      tagSelectorDestroy: true,
     };
   }
   componentDidMount() {
@@ -35,25 +39,105 @@ export default class ShelvesEdit extends Component {
     });
   }
   handleGoodsCreate=(data) => {
+    const { pid, merchantId } = this.state;
     this.props.dispatch({
       type: 'shelves/createItemPrice',
       payload: {
         ...data,
         ...this.state,
+        productType: PRODUCT_PACKAGE,
         status: STATUS_NORMAL,
       },
+      states: {
+        pid,
+        merchantId,
+      },
     });
   }
   handleGoodsUpdate=(data) => {
+    const { pid, merchantId } = this.state;
     this.props.dispatch({
       type: 'shelves/updateItemPrice',
-      payload: data,
+      payload: {
+        ...data,
+        ...this.state,
+      },
+      states: {
+        pid,
+        merchantId,
+      },
     });
   }
   handleGoodsDelete=(data) => {
+    const { pid, merchantId } = this.state;
     this.props.dispatch({
       type: 'shelves/deleteItemPrice',
       payload: data,
+      states: {
+        pid,
+        merchantId,
+      },
+    });
+  }
+  handleTagClose=(index) => {
+    const { pid, merchantId } = this.state;
+    const { shelves } = this.props;
+    const { currentItem } = shelves;
+    const { tags } = currentItem;
+    const newTags = tags.filter((item, location) => location !== index);
+    const newTagIds = newTags.map(item => item.id);
+    this.props.dispatch({
+      type: 'shelves/updateItemTags',
+      payload: {
+        pid,
+        merchantId,
+        tags: newTagIds,
+      },
+      states: {
+        pid,
+        merchantId,
+      },
+    });
+  }
+  handleTagSelectorModalShow = () => {
+    this.setState({
+      tagSelectorDestroy: false,
+    });
+    const { merchantId } = this.state;
+    this.props.dispatch({
+      type: 'tag/fetchTagList',
+      payload: { merchantId },
+    });
+  }
+  handleTagSelectorCancel = () => {
+    this.setState({
+      tagSelectorDestroy: true,
+    });
+  }
+  handleTagSelectorChange = (params) => {
+    const { merchantId } = this.state;
+    this.props.dispatch({
+      type: 'tag/fetchTagList',
+      payload: { merchantId, ...params },
+    });
+  }
+  handleTagSelectorFinish = (rows) => {
+    const { pid, merchantId } = this.state;
+    const newTagIds = (rows || []).map(row => row.id);
+    this.props.dispatch({
+      type: 'shelves/updateItemTags',
+      payload: {
+        pid,
+        merchantId,
+        tags: newTagIds,
+      },
+      states: {
+        pid,
+        merchantId,
+      },
+    });
+    this.setState({
+      tagSelectorDestroy: true,
     });
   }
   handlePageBack=() => {
@@ -63,14 +147,15 @@ export default class ShelvesEdit extends Component {
     }));
   }
   render() {
-    const { submitting, shelves, form } = this.props;
+    const { tagSelectorDestroy } = this.state;
+    const { submitting, tLoading, shelves, tag, form } = this.props;
     const { getFieldDecorator } = form;
     const { currentItem } = shelves;
     const { goods, tags } = currentItem;
 
     return (
       <div>
-        <Card title="价" style={{marginBottom: 16}}>
+        <Card title="价格管理" style={{ marginBottom: 16 }}>
           {getFieldDecorator('goods', {
             initialValue: addRowKey(goods),
           })(
@@ -82,6 +167,48 @@ export default class ShelvesEdit extends Component {
             />
           )}
         </Card>
+        <Card title="栏目管理" style={{ marginBottom: 70 }}>
+          {tags && tags.map((item, index) => (
+            <Tag
+              closable
+              afterClose={() => this.handleTagClose(index)}
+              color="#87d068"
+              key={item.id}
+            >
+              {item.name}
+            </Tag>
+          ))}
+          <Tag
+            style={{ borderStyle: 'dashed' }}
+            onClick={this.handleTagSelectorModalShow}
+          >
+            <Icon type="plus" />添加栏目
+          </Tag>
+          {!tagSelectorDestroy && (
+            <Modal
+              width={1100}
+              footer={null}
+              visible
+              title="标签列表"
+              maskClosable={false}
+              onCancel={this.handleMerchantSelectorCancel}
+            >
+              <Selector
+                multiple
+                loading={tLoading}
+                selectorName="Tag"
+                list={tag.list}
+                pageNo={tag.pageNo}
+                pageSize={tag.pageSize}
+                totalSize={tag.totalSize}
+                selectedRows={tags}
+                onCancel={this.handleTagSelectorCancel}
+                onChange={this.handleTagSelectorChange}
+                onFinish={this.handleTagSelectorFinish}
+              />
+            </Modal>
+          )}
+        </Card>
         <FooterToolbar style={{ width: '100%' }}>
           <Button
             type="primary"
@@ -94,3 +221,4 @@ export default class ShelvesEdit extends Component {
     );
   }
 }
+

+ 0 - 0
src/routes/Shelves/Package/PackageEdit.less


+ 9 - 21
src/routes/Shelves/Package/PackageList.js

@@ -3,9 +3,9 @@ import moment from 'moment';
 import { connect } from 'dva';
 import { routerRedux } from 'dva/router';
 import { Card, Modal, Button, message } from 'antd';
+import Ellipsis from '../../../components/Ellipsis/index';
 import { StandardTableList } from '../../../components/RBList';
 import { renderStatus, addRowKey } from '../../../utils/utils';
-import styles from './PackageList.less';
 
 const Message = message;
 
@@ -81,13 +81,13 @@ export default class PackageListPage extends Component {
         <div>
           <Button
             size="small"
-            className={styles.editBtn}
+            className="editBtn"
             onClick={() => this.handleEditOperation(item)}
           >编辑
           </Button>
           <Button
             size="small"
-            className={styles.delBtn}
+            className="delBtn"
             onClick={() => this.handleDeleteOperation(item)}
           >下架
           </Button>
@@ -120,28 +120,15 @@ export default class PackageListPage extends Component {
       title: '套餐包编号',
       key: 1,
       dataIndex: 'code',
-      render: (text, record) => (
-        <a
-          className={styles.link}
-          onClick={() => this.handleEditOperation(record)}
-        >
-          {text}
-        </a>
-      ),
-      width: '15%',
+      width: '20%',
     }, {
       title: '套餐包名称',
       key: 2,
       dataIndex: 'name',
-      render: (text, record) => (
-        <a
-          className={styles.link}
-          onClick={() => this.handleEditOperation(record)}
-        >
-          {text}
-        </a>
+      render: text => (
+        <Ellipsis tooltip lines={1}>{text}</Ellipsis>
       ),
-      width: '30%',
+      width: '25%',
     }, {
       title: '上架渠道',
       key: 3,
@@ -151,7 +138,7 @@ export default class PackageListPage extends Component {
       title: '上架状态',
       key: 4,
       dataIndex: 'status',
-      render: text => renderStatus(text),
+      render: text => renderStatus(text, '已下架', '已上架'),
       width: '10%',
     }, {
       title: '更新时间',
@@ -165,6 +152,7 @@ export default class PackageListPage extends Component {
       dataIndex: 'operation',
       render: (_, record) => renderOperation(record),
       width: '13%',
+      align: 'right',
     }];
     return (
       <Card>

+ 0 - 16
src/routes/Shelves/Package/PackageList.less

@@ -1,16 +0,0 @@
-@import "~antd/lib/style/themes/default.less";
-
-.link {
-  font-weight: 500;
-}
-.editBtn {
-  margin-right: 10px;
-  background: @primary-color;
-  color: #fff;
-  font-weight: 500;
-}
-.delBtn {
-  background: #f5222d;
-  color: #fff;
-  font-weight: 500;
-}

+ 0 - 315
src/routes/Shelves/Record/ShelvesCreate.js

@@ -1,315 +0,0 @@
-import React, { Component } from 'react';
-import { connect } from 'dva';
-import { routerRedux } from 'dva/router';
-import { message, Modal, Table, Card, Button } from 'antd';
-import Selector from '../../../components/RBTableSelector/Selector';
-import FooterToolbar from '../../../components/FooterToolbar/index';
-import { STATUS_NORMAL } from '../../../utils/config';
-import { renderCategory, statusCodeToName } from '../../../utils/utils';
-import styles from './ShelvesCreate.less';
-
-const Message = message;
-
-function firstLetterUpper(str) {
-  return str.substring(0, 1).toUpperCase() + str.substring(1);
-}
-
-function getItemName(str) {
-  if (str === 'course') {
-    return '课程';
-  } else if (str === 'support') {
-    return '配套';
-  } else if (str === 'package') {
-    return '套餐包';
-  } else {
-    return '产品';
-  }
-}
-
-@connect(({ loading, shelves, product, merchant }) => ({
-  product,
-  shelves,
-  merchant,
-  mLoading: loading.models.merchant,
-  pLoading: loading.models.product,
-  submitting: loading.models.shelves,
-}))
-export default class ShelvesCreatePage extends Component {
-  constructor(props) {
-    super(props);
-    const { location } = props;
-    const { state } = location;
-    const { itemType } = state;
-    this.state = {
-      itemType,
-      productItem: {},
-      merchantItem: {},
-      productSelectorDestroy: true,
-      merchantSelectorDestroy: true,
-    };
-  }
-  handleProductSelectorModalShow = () => {
-    const { itemType } = this.state;
-    this.setState({
-      productSelectorDestroy: false,
-    });
-    this.props.dispatch({
-      type: `product/fetch${firstLetterUpper(itemType)}List`,
-      payload: {},
-    });
-  };
-  handleMerchantSelectorModalShow = () => {
-    this.setState({
-      merchantSelectorDestroy: false,
-    });
-    this.props.dispatch({
-      type: 'merchant/fetchMerchantList',
-      payload: {},
-    });
-  };
-  handleProductSelectorChange = (params) => {
-    const { itemType } = this.state;
-    this.props.dispatch({
-      type: `product/fetch${firstLetterUpper(itemType)}List`,
-      payload: params,
-    });
-  };
-  handleMerchantSelectorChange = (params) => {
-    this.props.dispatch({
-      type: 'merchant/fetchMerchantList',
-      payload: params,
-    });
-  };
-  handleProductSelectorFinish = (rows) => {
-    this.setState({
-      productSelectorDestroy: true,
-      productItem: rows[0],
-    });
-  };
-  handleMerchantSelectorFinish = (rows) => {
-    this.setState({
-      merchantSelectorDestroy: true,
-      merchantItem: rows[0],
-    });
-  };
-  handleProductSelectorCancel = () => {
-    this.setState({
-      productSelectorDestroy: true,
-    });
-  };
-  handleMerchantSelectorCancel = () => {
-    this.setState({
-      merchantSelectorDestroy: true,
-    });
-  };
-  handlePageBack = () => {
-    const { itemType } = this.state;
-    this.props.dispatch(routerRedux.push({
-      pathname: `/shelves/${itemType}`,
-      state: this.props.location.state,
-    }));
-  };
-  handlePageSubmit = (e) => {
-    e.preventDefault();
-    const { productItem, merchantItem, itemType } = this.state;
-    const { pid } = productItem;
-    const { id } = merchantItem;
-    if (!pid) {
-      Message.error(`请选择要上架的${getItemName(itemType)}!`);
-      return;
-    }
-    if (!id) {
-      Message.error('请选择要上架的渠道!');
-      return;
-    }
-    this.props.dispatch({
-      type: 'shelves/createItem',
-      payload: {
-        pid,
-        merchantId: id,
-        status: STATUS_NORMAL,
-      },
-      states: this.props.location.state,
-    });
-  };
-
-  render() {
-    const { submitting, pLoading, mLoading, merchant, product } = this.props;
-    const {
-      productSelectorDestroy, merchantSelectorDestroy, itemType, productItem, merchantItem,
-    } = this.state;
-
-    // format selected data
-    const productTypeName = getItemName(itemType);
-    const productItemFormatter = () => {
-      const { code, name, status } = productItem;
-      return [{
-        key: `${productTypeName}编号:`,
-        value: code,
-      }, {
-        key: `${productTypeName}名称:`,
-        value: name,
-      }, {
-        key: `${productTypeName}状态:`,
-        value: statusCodeToName(status),
-      }];
-    };
-    const merchantItemFormatter = () => {
-      const { code, name, status, simple, contactName, mobile, domain } = merchantItem;
-      return [{
-        key: '商户编号:',
-        value: code,
-      }, {
-        key: '商户名称:',
-        value: name,
-      }, {
-        key: '商户简称:',
-        value: simple,
-      }, {
-        key: '商户类型:',
-        value: renderCategory(domain),
-      }, {
-        key: '商户联系人:',
-        value: contactName,
-      }, {
-        key: '联系人电话:',
-        value: mobile,
-      }, {
-        key: '商户状态:',
-        value: statusCodeToName(status),
-      }];
-    };
-
-    // table columns
-    const columns = [{
-      title: '字段名',
-      key: 1,
-      dataIndex: 'key',
-      width: '15%',
-    }, {
-      title: '字段值',
-      key: 2,
-      dataIndex: 'value',
-      width: '65%',
-    }];
-
-    // render modal selector
-    const getProductModal = () => {
-      return (
-        <Modal
-          width={900}
-          footer={null}
-          visible
-          title={`${getItemName(itemType)}列表`}
-          maskClosable={false}
-          onCancel={this.handleProductSelectorCancel}
-        >
-          <Selector
-            multiple={false}
-            loading={pLoading}
-            selectorName={firstLetterUpper(itemType)}
-            list={product.list}
-            pageNo={product.pageNo}
-            pageSize={product.pageSize}
-            totalSize={product.totalSize}
-            onCancel={this.handleProductSelectorCancel}
-            onChange={this.handleProductSelectorChange}
-            onFinish={this.handleProductSelectorFinish}
-          />
-        </Modal>
-      );
-    };
-    const getMerchantModal = () => {
-      return (
-        <Modal
-          width={1100}
-          footer={null}
-          visible
-          title="商户列表"
-          maskClosable={false}
-          onCancel={this.handleMerchantSelectorCancel}
-        >
-          <Selector
-            multiple={false}
-            loading={mLoading}
-            selectorName="Merchant"
-            list={merchant.list}
-            pageNo={merchant.pageNo}
-            pageSize={merchant.pageSize}
-            totalSize={merchant.totalSize}
-            onCancel={this.handleMerchantSelectorCancel}
-            onChange={this.handleMerchantSelectorChange}
-            onFinish={this.handleMerchantSelectorFinish}
-          />
-        </Modal>
-      );
-    };
-
-    // render card title
-    const renderProductCardName = () => {
-      return (
-        <div className={styles.cardName}>
-          <span>
-            <a onClick={this.handleProductSelectorModalShow}>
-              {`选择${getItemName(itemType)}`}
-            </a>
-          </span>
-        </div>
-      );
-    };
-    const renderMerchantCardName = () => {
-      return (
-        <div className={styles.cardName}>
-          <span>
-            <a onClick={this.handleMerchantSelectorModalShow}>
-              选择商户
-            </a>
-          </span>
-        </div>
-      );
-    };
-
-    return (
-      <div>
-        {/* 产品选择Card */}
-        <Card title={renderProductCardName()} style={{ marginBottom: 16 }}>
-          <Table
-            bordered
-            showHeader={false}
-            pagination={false}
-            columns={columns}
-            className={styles.table}
-            dataSource={productItemFormatter()}
-          />
-          {!productSelectorDestroy && getProductModal()}
-        </Card>
-        {/* 渠道选择Card */}
-        <Card title={renderMerchantCardName()} style={{ marginBottom: 70 }}>
-          <Table
-            bordered
-            showHeader={false}
-            pagination={false}
-            columns={columns}
-            className={styles.table}
-            dataSource={merchantItemFormatter()}
-          />
-          {!merchantSelectorDestroy && getMerchantModal()}
-        </Card>
-        <FooterToolbar style={{ width: '100%' }}>
-          <Button
-            onClick={this.handlePageBack}
-            style={{ marginRight: 10 }}
-          >取消
-          </Button>
-          <Button
-            type="primary"
-            loading={submitting}
-            onClick={this.handlePageSubmit}
-          >提交
-          </Button>
-        </FooterToolbar>
-      </div>
-    );
-  }
-}
-

+ 0 - 29
src/routes/Shelves/Record/ShelvesCreate.less

@@ -1,29 +0,0 @@
-@import "../../../../node_modules/antd/lib/style/themes/default.less";
-
-.cardName {
-  & > span {
-    display: inline-block;
-    height: 24px;
-    padding: 0 7px;
-    vertical-align: bottom;
-  }
-  :global {
-    .ant-btn-primary {
-      margin-left: 10px;
-    }
-  }
-}
-
-.table {
-  :global {
-    .ant-table-body > table {
-      padding: 0 !important;
-    }
-    .ant-table-tbody > tr > td {
-      &:first-child {
-        background: #69c0ff;
-        font-weight: 500;
-      }
-    }
-  }
-}

+ 0 - 80
src/routes/Shelves/Record/ShelvesEdit.js

@@ -1,80 +0,0 @@
-import React, { Component} from 'react';
-import { Card, Form, Modal, Table, InputNumber, Button } from 'antd';
-import { connect } from 'dva';
-import { routerRedux } from 'dva/router';
-import TableForm from './TableForm';
-import { STATUS_NORMAL } from '../../../utils/config';
-
-@connect(({ loading, shelves }) => ({
-  shelves,
-  submitting: loading.models.shelves,
-}))
-@Form.create()
-export default class ShelvesEdit extends Component {
-  constructor(props) {
-    super(props);
-    const { location } = props;
-    const { state } = location;
-    const { merchantId, pid, productType } = state;
-    this.state = {
-      pid,
-      merchantId,
-      productType,
-    };
-  }
-  componentDidMount() {
-    const { merchantId, pid } = this.state;
-    this.props.dispatch({
-      type: 'shelves/fetchItemDetail',
-      payload: {
-        pid,
-        merchantId,
-      },
-    });
-  }
-  handleGoodsCreate=(data) => {
-    this.props.dispatch({
-      type: 'shelves/createItemPrice',
-      payload: {
-        ...data,
-        ...this.state,
-        status: STATUS_NORMAL,
-      },
-    });
-  }
-  handleGoodsUpdate=(data) => {
-    this.props.dispatch({
-      type: 'shelves/updateItemPrice',
-      payload: data,
-    });
-  }
-  handleGoodsDelete=(data) => {
-    this.props.dispatch({
-      type: 'shelves/deleteItemPrice',
-      payload: data,
-    });
-  }
-  render() {
-    const { submitting, shelves, form } = this.props;
-    const { getFieldDecorator } = form;
-    const { currentItem } = shelves;
-    const { goods, tags } = currentItem;
-
-    return (
-      <div>
-        <Card title="定价" style={{marginBottom: 16}}>
-          {getFieldDecorator('goods', {
-            initialValue: goods,
-          })(
-            <TableForm
-              loading={submitting}
-              onCreate={this.handleGoodsCreate}
-              onUpdate={this.handleGoodsUpdate}
-              onDelete={this.handleGoodsDelete}
-            />
-          )}
-        </Card>
-      </div>
-    );
-  }
-}

+ 0 - 0
src/routes/Shelves/Record/ShelvesEdit.less


+ 0 - 214
src/routes/Shelves/Record/ShelvesList.js

@@ -1,214 +0,0 @@
-import React, { Component } from 'react';
-import pathToRegexp from 'path-to-regexp';
-import moment from 'moment';
-import { connect } from 'dva';
-import { routerRedux } from 'dva/router';
-import { Card, Modal, Button, message } from 'antd';
-import { StandardTableList } from '../../../components/RBList/index';
-import { renderStatus, addRowKey } from '../../../utils/utils';
-import styles from './ShelvesList.less';
-
-const Message = message;
-
-function firstLetterUpper(str) {
-  return str.substring(0, 1).toUpperCase() + str.substring(1);
-}
-function getItemName(str) {
-  if (str === 'course') {
-    return '课程';
-  } else if (str === 'support') {
-    return '配套';
-  } else if (str === 'package') {
-    return '套餐包';
-  } else {
-    return '产品';
-  }
-}
-
-@connect(({ loading, shelves }) => ({
-  shelves,
-  loading: loading.models.shelves,
-}))
-export default class ShelvesListPage extends Component {
-  constructor(props) {
-    super(props);
-    const { state, pathname } = props.location;
-    const match = pathToRegexp('/shelves/:itemType').exec(pathname);
-    this.state = {
-      UIParams: (state || {}).UIParams, // 组件的状态参数
-      Queryers: (state || {}).Queryers, // 查询的条件参数
-      itemType: match[1], // 货架产品类型
-    };
-  }
-  componentDidMount() {
-    const { itemType } = this.state;
-    this.props.dispatch({
-      type: `shelves/fetch${firstLetterUpper(itemType)}ItemList`,
-      payload: { ...this.state.Queryers },
-    });
-  }
-  handleCreateOperation = () => {
-    this.props.dispatch(routerRedux.push({
-      pathname: '/shelves/create',
-      state: this.state,
-    }));
-  }
-  handleDeleteOperation = (item) => {
-    const { itemType } = this.state;
-    Modal.confirm({
-      okText: '确定',
-      cancelText: '取消',
-      title: `你确定要下架该${getItemName(itemType)}吗?`,
-      onOk: () => {
-        this.props.dispatch({
-          type: 'shelves/deleteItem',
-          payload: { id: item.id },
-          states: this.state,
-        });
-      },
-    });
-  }
-  handleEditOperation = (item) => {
-    const { itemType } = this.state;
-    this.props.dispatch(routerRedux.push({
-      pathname: '/shelves/edit',
-      state: {
-        pid: item.pid,
-        merchantId: item.merchantId,
-        productType: itemType,
-        ...this.state,
-      },
-    }));
-  }
-  handleFilterOperation = (params, states) => {
-    const { itemType }  = this.state;
-    this.props.dispatch({
-      type: `shelves/fetch${firstLetterUpper(itemType)}ItemList`,
-      payload: params,
-    });
-    this.setState({
-      UIParams: states,
-      Queryers: params,
-    });
-  }
-  handleBatchOperation = () => {
-    Message.info('暂不支持批量操作!');
-  }
-
-  render() {
-    const { itemType } = this.state;
-    const { loading, shelves } = this.props;
-    const { list, totalSize, pageSize, pageNo } = shelves;
-
-    const renderOperation = (item) => {
-      return (
-        <div>
-          <Button
-            size="small"
-            className={styles.editBtn}
-            onClick={() => this.handleEditOperation(item)}
-          >编辑
-          </Button>
-          <Button
-            size="small"
-            className={styles.delBtn}
-            onClick={() => this.handleDeleteOperation(item)}
-          >下架
-          </Button>
-        </div>
-      );
-    };
-
-    const batchActions = [{
-      key: 'delete',
-      name: '批量删除',
-    }, {
-      key: 'recovery',
-      name: '批量恢复',
-    }];
-    const basicSearch = {
-      keys: [{
-        name: `${getItemName(itemType)}编号`,
-        field: 'code',
-      }, {
-        name: `${getItemName(itemType)}名称`,
-        field: 'name',
-      }],
-    };
-    const pagination = {
-      pageNo,
-      pageSize,
-      totalSize,
-    };
-    const columns = [{
-      title: `${getItemName(itemType)}编号`,
-      key: 1,
-      dataIndex: 'code',
-      render: (text, record) => (
-        <a
-          className={styles.link}
-          onClick={() => this.handleEditOperation(record)}
-        >
-          {text}
-        </a>
-      ),
-      width: '15%',
-    }, {
-      title: `${getItemName(itemType)}名称`,
-      key: 2,
-      dataIndex: 'name',
-      render: (text, record) => (
-        <a
-          className={styles.link}
-          onClick={() => this.handleEditOperation(record)}
-        >
-          {text}
-        </a>
-      ),
-      width: '30%',
-    }, {
-      title: '上架渠道',
-      key: 3,
-      dataIndex: 'merchantName',
-      width: '14%',
-    }, {
-      title: '上架状态',
-      key: 4,
-      dataIndex: 'status',
-      render: text => renderStatus(text),
-      width: '10%',
-    }, {
-      title: '更新时间',
-      key: 5,
-      dataIndex: 'gmtModified',
-      render: text => moment(text).format('YYYY-MM-DD HH:mm:ss'),
-      width: '17%',
-    }, {
-      title: '操作',
-      key: 6,
-      dataIndex: 'operation',
-      render: (_, record) => renderOperation(record),
-      width: '13%',
-    }];
-    return (
-      <Card>
-        <StandardTableList
-          columns={columns}
-          loading={loading}
-          dataSource={addRowKey(list)}
-          header={{
-            basicSearch,
-            onFilterClick: this.handleFilterOperation,
-            onCreateClick: this.handleCreateOperation,
-          }}
-          footer={{
-            pagination,
-            batchActions,
-            onBatchClick: this.handleBatchOperation,
-          }}
-          keepUIState={{ ...this.state.UIParams }}
-        />
-      </Card>
-    );
-  }
-}

+ 0 - 16
src/routes/Shelves/Record/ShelvesList.less

@@ -1,16 +0,0 @@
-@import "../../../../node_modules/antd/lib/style/themes/default.less";
-
-.link {
-  font-weight: 500;
-}
-.editBtn {
-  margin-right: 10px;
-  background: @primary-color;
-  color: #fff;
-  font-weight: 500;
-}
-.delBtn {
-  background: #f5222d;
-  color: #fff;
-  font-weight: 500;
-}

+ 0 - 333
src/routes/Shelves/Record/TableForm.js

@@ -1,333 +0,0 @@
-import React, { PureComponent, Fragment } from 'react';
-import {
-  Table,
-  Button,
-  Select,
-  InputNumber,
-  Popconfirm,
-  Divider,
-  message,
-} from 'antd';
-import {
-  CHARGE_UNIT_YEAR,
-  CHARGE_UNIT_SEASON,
-  CHARGE_UNIT_HALF_YEAR,
-  DURATION_HALF_YEAR,
-  DURATION_YEAR,
-  DURATION_SEASON,
-} from '../../../utils/config';
-import styles from './TableForm.less';
-
-const chargeUnitMap = [{
-  text: CHARGE_UNIT_YEAR,
-  value: CHARGE_UNIT_YEAR,
-}, {
-  text: CHARGE_UNIT_HALF_YEAR,
-  value: CHARGE_UNIT_HALF_YEAR,
-}, {
-  text: CHARGE_UNIT_SEASON,
-  value: CHARGE_UNIT_SEASON,
-}];
-const durationMap = {
-  [CHARGE_UNIT_SEASON]: DURATION_SEASON,
-  [CHARGE_UNIT_HALF_YEAR]: DURATION_HALF_YEAR,
-  [CHARGE_UNIT_YEAR]: DURATION_YEAR,
-};
-
-export default class TableForm extends PureComponent {
-  constructor(props) {
-    super(props);
-
-    this.state = {
-      data: props.value,
-      loading: props.loading,
-    };
-  }
-  componentWillReceiveProps(nextProps) {
-    if ('value' in nextProps) {
-      this.setState({
-        data: nextProps.value,
-      });
-    }
-  }
-  getRowByKey(key, newData) {
-    return (newData || this.state.data).filter(item => item.key === key)[0];
-  }
-  index = 0;
-  cacheOriginData = {};
-  toggleEditable=(e, key) => {
-    e.preventDefault();
-    const newData = this.state.data.map(item => ({ ...item }));
-    const target = this.getRowByKey(key, newData);
-    if (target) {
-      // 进入编辑状态时保存原始数据
-      if (!target.editable) {
-        this.cacheOriginData[key] = { ...target };
-      }
-      target.editable = !target.editable;
-      this.setState({ data: newData });
-    }
-  }
-  chargeUnitSelectable=(value) => {
-    const tmp = this.state.data.find(item => item.chargeUnit === value);
-    return tmp !== undefined;
-  }
-  remove(record) {
-    const { key, isNew } = record;
-    const newData = this.state.data.filter(item => item.key !== key);
-    this.setState({ data: newData });
-    if (!isNew) {
-      this.props.onDelete({ goodsId: key });
-    }
-  }
-  newPrice = () => {
-    const newData = this.state.data.map(item => ({ ...item }));
-    newData.push({
-      key: `NEW_TEMP_ID_${this.index}`,
-      cpPrice: '',
-      merchantPrice: '',
-      terminalPrice: '',
-      editable: true,
-      isNew: true,
-    });
-    this.index += 1;
-    this.setState({ data: newData });
-  }
-  handleFieldChange(value, fieldName, key) {
-    const newData = this.state.data.map(item => ({ ...item }));
-    const target = this.getRowByKey(key, newData);
-    if (target) {
-      target[fieldName] = value;
-      this.setState({ data: newData });
-    }
-  }
-  handleSelectChange(value, key) {
-    const newData = this.state.data.map(item => ({ ...item }));
-    const target = this.getRowByKey(key, newData);
-    if (target) {
-      target.chargeUnit = value;
-      this.setState({ data: newData });
-    }
-  }
-  saveRow(e, key) {
-    e.persist();
-    if (this.clickedCancel) {
-      this.clickedCancel = false;
-      return;
-    }
-    const target = this.getRowByKey(key) || {};
-    if (!target.chargeUnit || !target.cpPrice || !target.merchantPrice || !target.terminalPrice) {
-      message.error('请填写完整价格信息');
-      e.target.focus();
-      return;
-    }
-    let sort = 0;
-    const { chargeUnit, cpPrice, merchantPrice, terminalPrice, duration } = target;
-    if (chargeUnit === CHARGE_UNIT_HALF_YEAR) {
-      sort = 1;
-    } else if (chargeUnit === CHARGE_UNIT_YEAR) {
-      sort = 2;
-    }
-    if (target.isNew) {
-      this.props.onCreate({
-        sort,
-        cpPrice,
-        duration,
-        chargeUnit,
-        merchantPrice,
-        terminalPrice,
-      });
-    } else {
-      this.props.onUpdate({
-        sort,
-        cpPrice,
-        duration,
-        chargeUnit,
-        merchantPrice,
-        terminalPrice,
-      });
-    }
-    delete target.isNew;
-    this.toggleEditable(e, key);
-  }
-  cancel(e, key) {
-    this.clickedCancel = true;
-    e.preventDefault();
-    const newData = this.state.data.map(item => ({ ...item }));
-    const target = this.getRowByKey(key, newData);
-    if (this.cacheOriginData[key]) {
-      Object.assign(target, this.cacheOriginData[key]);
-      target.editable = false;
-      delete this.cacheOriginData[key];
-    }
-    this.setState({ data: newData });
-    this.clickedCancel = false;
-  }
-  render() {
-    const columns = [{
-      title: '计价单位',
-      dataIndex: 'chargeUnit',
-      key: 'chargeUnit',
-      width: '15%',
-      align: 'center',
-      render: (text, record) => {
-        if (record.editable) {
-          return (
-            <Select
-              placeholder="请选择"
-              style={{ width: '100%' }}
-              value={text}
-              onChange={value => this.handleSelectChange(value, record.key)}
-            >
-              {
-                chargeUnitMap.map(item => (
-                  <Select.Option
-                    key={item.value}
-                    value={item.value}
-                    disabled={this.chargeUnitSelectable(item.value)}
-                  >
-                    {item.text}
-                  </Select.Option>
-                ))
-              }
-            </Select>
-          );
-        }
-        return text;
-      },
-    }, {
-      title: '时长(天)',
-      dataIndex: 'duration',
-      key: 'duration',
-      width: '15%',
-      align: 'center',
-      render: (_, record) => {
-        if (record.chargeUnit) {
-          return durationMap[record.chargeUnit];
-        }
-        return '';
-      },
-    }, {
-      title: '供应商售价(¥)',
-      dataIndex: 'cpPrice',
-      key: 'cpPrice',
-      width: '20%',
-      align: 'center',
-      render: (text, record) => {
-        if (record.editable) {
-          return (
-            <InputNumber
-              min={1}
-              value={text}
-              onChange={e => this.handleFieldChange(e, 'cpPrice', record.key)}
-              style={{ width: '100%', border: 'unset' }}
-              placeholder="请输入"
-            />
-          );
-        }
-        return text;
-      },
-    }, {
-      title: '平台方售价(¥)',
-      dataIndex: 'merchantPrice',
-      key: 'merchantPrice',
-      width: '20%',
-      align: 'center',
-      render: (text, record) => {
-        if (record.editable) {
-          return (
-            <InputNumber
-              min={1}
-              value={text}
-              onChange={value => this.handleFieldChange(value, 'merchantPrice', record.key)}
-              style={{ width: '100%', border: 'unset' }}
-              placeholder="请输入"
-            />
-          );
-        }
-        return text;
-      },
-    }, {
-      title: '终端显示价格(¥)',
-      dataIndex: 'terminalPrice',
-      key: 'terminalPrice',
-      width: '20%',
-      align: 'center',
-      render: (text, record) => {
-        if (record.editable) {
-          return (
-            <InputNumber
-              min={1}
-              value={text}
-              onChange={value => this.handleFieldChange(value, 'terminalPrice', record.key)}
-              style={{ width: '100%', border: 'unset' }}
-              placeholder="请输入"
-            />
-          );
-        }
-        return text;
-      },
-    }, {
-      title: '操作',
-      key: 'action',
-      align: 'center',
-      render: (text, record) => {
-        if (!!record.editable && this.state.loading) {
-          return null;
-        }
-        if (record.editable) {
-          if (record.isNew) {
-            return (
-              <span>
-                <a onClick={e => this.saveRow(e, record.key)}>添加</a>
-                <Divider type="vertical" />
-                <Popconfirm title="是否要删除此种价格?" onConfirm={() => this.remove(record.key)}>
-                  <a>删除</a>
-                </Popconfirm>
-              </span>
-            );
-          }
-          return (
-            <span>
-              <a onClick={e => this.saveRow(e, record.key)}>保存</a>
-              <Divider type="vertical" />
-              <a onClick={e => this.cancel(e, record.key)}>取消</a>
-            </span>
-          );
-        }
-        return (
-          <span>
-            <a onClick={e => this.toggleEditable(e, record.key)}>编辑</a>
-            <Divider type="vertical" />
-            <Popconfirm title="是否要删除此种价格?" onConfirm={() => this.remove(record)}>
-              <a>删除</a>
-            </Popconfirm>
-          </span>
-        );
-      },
-    }];
-
-    return (
-      <Fragment>
-        <Table
-          bordered
-          pagination={false}
-          columns={columns}
-          loading={this.state.loading}
-          dataSource={this.state.data}
-          rowClassName={() => {
-            return styles.editable;
-          }}
-        />
-        <Button
-          style={{ width: '100%', marginTop: 16, marginBottom: 8 }}
-          type="dashed"
-          onClick={this.newPrice}
-          icon="plus"
-        >
-          新增价格
-        </Button>
-      </Fragment>
-    );
-  }
-}

+ 0 - 8
src/routes/Shelves/Record/TableForm.less

@@ -1,8 +0,0 @@
-@import "../../../../node_modules/antd/lib/style/themes/default.less";
-
-.editable {
-  td {
-    height: 32px;
-    padding: 0 !important;
-  }
-}

+ 0 - 32
src/routes/Shelves/Record/index.js

@@ -1,32 +0,0 @@
-import React, { Component } from 'react';
-import { Route, Switch } from 'dva/router';
-import { connect } from 'dva';
-import PageHeaderLayout from '../../../layouts/PageHeaderLayout';
-import { getRoutes } from '../../../utils/utils';
-
-@connect()
-export default class Sheleves extends Component {
-  render() {
-    const { match, routerData } = this.props;
-    const routes = getRoutes(match.path, routerData);
-
-    return (
-      <PageHeaderLayout>
-        <Switch>
-          {
-            routes.map(item =>
-              (
-                <Route
-                  key={item.key}
-                  path={item.path}
-                  component={item.component}
-                  exact={item.exact}
-                />
-              )
-            )
-          }
-        </Switch>
-      </PageHeaderLayout>
-    );
-  }
-}

+ 140 - 11
src/routes/Shelves/Support/SupportEdit.js

@@ -1,18 +1,21 @@
-import React, { Component} from 'react';
-import { Card, Form, Modal, Table, InputNumber, Button } from 'antd';
+import React, { Component } from 'react';
+import { Card, Modal, Form, Button, Tag, Icon } from 'antd';
 import { connect } from 'dva';
 import { routerRedux } from 'dva/router';
-import FooterToolbar from '../../../components/FooterToolbar/index';
 import TableForm from './TableForm';
-import { STATUS_NORMAL } from '../../../utils/config';
+import FooterToolbar from '../../../components/FooterToolbar';
+import Selector from '../../../components/RBTableSelector/Selector';
 import { addRowKey } from '../../../utils/utils';
+import { PRODUCT_SUPPORT, STATUS_NORMAL } from '../../../utils/config';
 
-@connect(({ loading, shelves }) => ({
+@connect(({ loading, shelves, tag }) => ({
+  tag,
   shelves,
+  tLoading: loading.models.tag,
   submitting: loading.models.shelves,
 }))
 @Form.create()
-export default class ShelvesEdit extends Component {
+export default class SupportEdit extends Component {
   constructor(props) {
     super(props);
     const { location } = props;
@@ -22,6 +25,7 @@ export default class ShelvesEdit extends Component {
       pid,
       merchantId,
       productType,
+      tagSelectorDestroy: true,
     };
   }
   componentDidMount() {
@@ -35,25 +39,106 @@ export default class ShelvesEdit extends Component {
     });
   }
   handleGoodsCreate=(data) => {
+    const { pid, merchantId } = this.state;
     this.props.dispatch({
       type: 'shelves/createItemPrice',
       payload: {
-        ...data,
-        ...this.state,
+        pid,
+        merchantId,
+        productType: PRODUCT_SUPPORT,
         status: STATUS_NORMAL,
+        ...data,
+      },
+      states: {
+        pid,
+        merchantId,
       },
     });
   }
   handleGoodsUpdate=(data) => {
+    const { pid, merchantId } = this.state;
     this.props.dispatch({
       type: 'shelves/updateItemPrice',
-      payload: data,
+      payload: {
+        ...data,
+        ...this.state,
+      },
+      states: {
+        pid,
+        merchantId,
+      },
     });
   }
   handleGoodsDelete=(data) => {
+    const { pid, merchantId } = this.state;
     this.props.dispatch({
       type: 'shelves/deleteItemPrice',
       payload: data,
+      states: {
+        pid,
+        merchantId,
+      },
+    });
+  }
+  handleTagClose=(index) => {
+    const { pid, merchantId } = this.state;
+    const { shelves } = this.props;
+    const { currentItem } = shelves;
+    const { tags } = currentItem;
+    const newTags = tags.filter((item, location) => location !== index);
+    const newTagIds = newTags.map(item => item.id);
+    this.props.dispatch({
+      type: 'shelves/updateItemTags',
+      payload: {
+        pid,
+        merchantId,
+        tags: newTagIds,
+      },
+      states: {
+        pid,
+        merchantId,
+      },
+    });
+  }
+  handleTagSelectorModalShow = () => {
+    this.setState({
+      tagSelectorDestroy: false,
+    });
+    const { merchantId } = this.state;
+    this.props.dispatch({
+      type: 'tag/fetchTagList',
+      payload: { merchantId },
+    });
+  }
+  handleTagSelectorCancel = () => {
+    this.setState({
+      tagSelectorDestroy: true,
+    });
+  }
+  handleTagSelectorChange = (params) => {
+    const { merchantId } = this.state;
+    this.props.dispatch({
+      type: 'tag/fetchTagList',
+      payload: { merchantId, ...params },
+    });
+  }
+  handleTagSelectorFinish = (rows) => {
+    const { pid, merchantId } = this.state;
+    const newTagIds = (rows || []).map(row => row.id);
+    this.props.dispatch({
+      type: 'shelves/updateItemTags',
+      payload: {
+        pid,
+        merchantId,
+        tags: newTagIds,
+      },
+      states: {
+        pid,
+        merchantId,
+      },
+    });
+    this.setState({
+      tagSelectorDestroy: true,
     });
   }
   handlePageBack=() => {
@@ -63,14 +148,15 @@ export default class ShelvesEdit extends Component {
     }));
   }
   render() {
-    const { submitting, shelves, form } = this.props;
+    const { tagSelectorDestroy } = this.state;
+    const { submitting, tLoading, shelves, tag, form } = this.props;
     const { getFieldDecorator } = form;
     const { currentItem } = shelves;
     const { goods, tags } = currentItem;
 
     return (
       <div>
-        <Card title="价" style={{marginBottom: 16}}>
+        <Card title="价格管理" style={{ marginBottom: 16 }}>
           {getFieldDecorator('goods', {
             initialValue: addRowKey(goods),
           })(
@@ -82,6 +168,48 @@ export default class ShelvesEdit extends Component {
             />
           )}
         </Card>
+        <Card title="栏目管理" style={{ marginBottom: 70 }}>
+          {tags && tags.map((item, index) => (
+            <Tag
+              closable
+              key={item.id}
+              color="#87d068"
+              afterClose={() => this.handleTagClose(index)}
+            >
+              {item.name}
+            </Tag>
+          ))}
+          <Tag
+            style={{ borderStyle: 'dashed' }}
+            onClick={this.handleTagSelectorModalShow}
+          >
+            <Icon type="plus" />添加栏目
+          </Tag>
+          {!tagSelectorDestroy && (
+            <Modal
+              width={1100}
+              footer={null}
+              visible
+              title="标签列表"
+              maskClosable={false}
+              onCancel={this.handleMerchantSelectorCancel}
+            >
+              <Selector
+                multiple
+                loading={tLoading}
+                selectorName="Tag"
+                list={tag.list}
+                pageNo={tag.pageNo}
+                pageSize={tag.pageSize}
+                totalSize={tag.totalSize}
+                selectedRows={tags}
+                onCancel={this.handleTagSelectorCancel}
+                onChange={this.handleTagSelectorChange}
+                onFinish={this.handleTagSelectorFinish}
+              />
+            </Modal>
+          )}
+        </Card>
         <FooterToolbar style={{ width: '100%' }}>
           <Button
             type="primary"
@@ -94,3 +222,4 @@ export default class ShelvesEdit extends Component {
     );
   }
 }
+

+ 0 - 0
src/routes/Shelves/Support/SupportEdit.less


+ 7 - 19
src/routes/Shelves/Support/SupportList.js

@@ -3,9 +3,9 @@ import moment from 'moment';
 import { connect } from 'dva';
 import { routerRedux } from 'dva/router';
 import { Card, Modal, Button, message } from 'antd';
+import Ellipsis from '../../../components/Ellipsis';
 import { StandardTableList } from '../../../components/RBList';
 import { renderStatus, addRowKey } from '../../../utils/utils';
-import styles from './SupportList.less';
 
 const Message = message;
 
@@ -82,13 +82,13 @@ export default class SupportListPage extends Component {
         <div>
           <Button
             size="small"
-            className={styles.editBtn}
+            className="editBtn"
             onClick={() => this.handleEditOperation(item)}
           >编辑
           </Button>
           <Button
             size="small"
-            className={styles.delBtn}
+            className="delBtn"
             onClick={() => this.handleDeleteOperation(item)}
           >下架
           </Button>
@@ -121,26 +121,13 @@ export default class SupportListPage extends Component {
       title: '配套编号',
       key: 1,
       dataIndex: 'code',
-      render: (text, record) => (
-        <a
-          className={styles.link}
-          onClick={() => this.handleEditOperation(record)}
-        >
-          {text}
-        </a>
-      ),
       width: '15%',
     }, {
       title: '配套名称',
       key: 2,
       dataIndex: 'name',
-      render: (text, record) => (
-        <a
-          className={styles.link}
-          onClick={() => this.handleEditOperation(record)}
-        >
-          {text}
-        </a>
+      render: text => (
+        <Ellipsis tooltip lines={1}>{text}</Ellipsis>
       ),
       width: '30%',
     }, {
@@ -152,7 +139,7 @@ export default class SupportListPage extends Component {
       title: '上架状态',
       key: 4,
       dataIndex: 'status',
-      render: text => renderStatus(text),
+      render: text => renderStatus(text, '已下架', '已上架'),
       width: '10%',
     }, {
       title: '更新时间',
@@ -166,6 +153,7 @@ export default class SupportListPage extends Component {
       dataIndex: 'operation',
       render: (_, record) => renderOperation(record),
       width: '13%',
+      align: 'right',
     }];
     return (
       <Card>

+ 0 - 16
src/routes/Shelves/Support/SupportList.less

@@ -1,16 +0,0 @@
-@import "~antd/lib/style/themes/default.less";
-
-.link {
-  font-weight: 500;
-}
-.editBtn {
-  margin-right: 10px;
-  background: @primary-color;
-  color: #fff;
-  font-weight: 500;
-}
-.delBtn {
-  background: #f5222d;
-  color: #fff;
-  font-weight: 500;
-}

+ 11 - 47
src/routes/Shelves/Support/TableForm.js

@@ -8,31 +8,13 @@ import {
   Divider,
   message,
 } from 'antd';
-import {
-  CHARGE_UNIT_YEAR,
-  CHARGE_UNIT_SEASON,
-  CHARGE_UNIT_HALF_YEAR,
-  DURATION_HALF_YEAR,
-  DURATION_YEAR,
-  DURATION_SEASON,
-} from '../../../utils/config';
+import { CHARGE_UNIT_ITEM } from '../../../utils/config';
 import styles from './TableForm.less';
 
 const chargeUnitMap = [{
-  text: CHARGE_UNIT_YEAR,
-  value: CHARGE_UNIT_YEAR,
-}, {
-  text: CHARGE_UNIT_HALF_YEAR,
-  value: CHARGE_UNIT_HALF_YEAR,
-}, {
-  text: CHARGE_UNIT_SEASON,
-  value: CHARGE_UNIT_SEASON,
+  text: CHARGE_UNIT_ITEM,
+  value: CHARGE_UNIT_ITEM,
 }];
-const durationMap = {
-  [CHARGE_UNIT_SEASON]: DURATION_SEASON,
-  [CHARGE_UNIT_HALF_YEAR]: DURATION_HALF_YEAR,
-  [CHARGE_UNIT_YEAR]: DURATION_YEAR,
-};
 
 export default class TableForm extends PureComponent {
   constructor(props) {
@@ -121,30 +103,23 @@ export default class TableForm extends PureComponent {
       e.target.focus();
       return;
     }
-    let sort = 0;
-    const { chargeUnit, cpPrice, merchantPrice, terminalPrice, duration } = target;
-    if (chargeUnit === CHARGE_UNIT_HALF_YEAR) {
-      sort = 1;
-    } else if (chargeUnit === CHARGE_UNIT_YEAR) {
-      sort = 2;
-    }
+    const { id, chargeUnit, cpPrice, merchantPrice, terminalPrice } = target;
     if (target.isNew) {
       this.props.onCreate({
-        sort,
         cpPrice,
-        duration,
         chargeUnit,
         merchantPrice,
         terminalPrice,
+        duration: 0,
       });
     } else {
       this.props.onUpdate({
-        sort,
+        id,
         cpPrice,
-        duration,
         chargeUnit,
         merchantPrice,
         terminalPrice,
+        duration: 0,
       });
     }
     delete target.isNew;
@@ -168,7 +143,7 @@ export default class TableForm extends PureComponent {
       title: '计价单位',
       dataIndex: 'chargeUnit',
       key: 'chargeUnit',
-      width: '15%',
+      width: '20%',
       align: 'center',
       render: (text, record) => {
         if (record.editable) {
@@ -178,6 +153,7 @@ export default class TableForm extends PureComponent {
               style={{ width: '100%' }}
               value={text}
               onChange={value => this.handleSelectChange(value, record.key)}
+              className={styles.select}
             >
               {
                 chargeUnitMap.map(item => (
@@ -196,18 +172,6 @@ export default class TableForm extends PureComponent {
         return text;
       },
     }, {
-      title: '时长(天)',
-      dataIndex: 'duration',
-      key: 'duration',
-      width: '15%',
-      align: 'center',
-      render: (_, record) => {
-        if (record.chargeUnit) {
-          return durationMap[record.chargeUnit];
-        }
-        return '';
-      },
-    }, {
       title: '供应商售价(¥)',
       dataIndex: 'cpPrice',
       key: 'cpPrice',
@@ -281,7 +245,7 @@ export default class TableForm extends PureComponent {
               <span>
                 <a onClick={e => this.saveRow(e, record.key)}>添加</a>
                 <Divider type="vertical" />
-                <Popconfirm title="是否要删除此价格?" onConfirm={() => this.remove(record.key)}>
+                <Popconfirm title="是否要删除此价格?" onConfirm={() => this.remove(record)}>
                   <a>删除</a>
                 </Popconfirm>
               </span>
@@ -299,7 +263,7 @@ export default class TableForm extends PureComponent {
           <span>
             <a onClick={e => this.toggleEditable(e, record.key)}>编辑</a>
             <Divider type="vertical" />
-            <Popconfirm title="是否要删除此价格?" onConfirm={() => this.remove(record)}>
+            <Popconfirm title="是否要删除此价格?" onConfirm={() => this.remove(record)}>
               <a>删除</a>
             </Popconfirm>
           </span>

+ 5 - 0
src/routes/Shelves/Support/TableForm.less

@@ -6,3 +6,8 @@
     padding: 0 !important;
   }
 }
+.select {
+  :global(.ant-select-selection) {
+    border: unset;
+  }
+}

+ 6 - 22
src/routes/Terminal/User/TerminalList.js

@@ -8,7 +8,6 @@ import RBRemoteSelect from '../../../components/RBRemoteSelect/index';
 import Ellipsis from '../../../components/Ellipsis/index';
 import { addRowKey, renderStatus } from '../../../utils/utils';
 import { STATUS_NORMAL } from '../../../utils/config';
-import styles from './TerminalList.less';
 
 const Message = message;
 
@@ -185,13 +184,13 @@ export default class TerminalListPage extends Component {
         <div>
           <Button
             size="small"
-            className={styles.editBtn}
+            className="editBtn"
             onClick={() => this.handleEditOperation(item)}
           >编辑
           </Button>
           <Button
             size="small"
-            className={styles.ubBtn}
+            className="depositBtn"
             onClick={() => this.handleDeviceUnboundOperation(item)}
           >解绑
           </Button>
@@ -199,14 +198,14 @@ export default class TerminalListPage extends Component {
             item.status === STATUS_NORMAL ? (
               <Button
                 size="small"
-                className={styles.delBtn}
+                className="delBtn"
                 onClick={() => this.handleDisableOperation(item)}
               >禁用
               </Button>
             ) : (
               <Button
                 size="small"
-                className={styles.recBtn}
+                className="delBtn"
                 onClick={() => this.handleRecoverOperation(item)}
               >解禁
               </Button>
@@ -243,33 +242,17 @@ export default class TerminalListPage extends Component {
       title: '终端编号',
       key: 1,
       dataIndex: 'code',
-      render: (text, record) => (
-        <a
-          className={styles.link}
-          onClick={() => this.handleEditOperation(record)}
-        >
-          {text}
-        </a>
-      ),
       width: '15%',
     }, {
       title: '终端名称',
       key: 2,
       dataIndex: 'name',
-      render: (text, record) => (
-        <a
-          className={styles.link}
-          onClick={() => this.handleEditOperation(record)}
-        >
-          {text}
-        </a>
-      ),
       width: '12%',
     }, {
       title: '所属校区',
       key: 3,
       dataIndex: 'campusName',
-      render: (text) => renderCampusName(text),
+      render: text => renderCampusName(text),
       width: '20%',
     }, {
       title: '所属渠道',
@@ -294,6 +277,7 @@ export default class TerminalListPage extends Component {
       dataIndex: 'operation',
       render: (_, record) => renderOperation(record),
       width: '18%',
+      align: 'right',
     }];
     return (
       <Card>

+ 0 - 28
src/routes/Terminal/User/TerminalList.less

@@ -1,28 +0,0 @@
-@import "../../../../node_modules/antd/lib/style/themes/default.less";
-
-.link {
-  font-weight: 500;
-}
-.editBtn {
-  margin-right: 10px;
-  background: @primary-5;
-  color: #fff;
-  font-weight: 500;
-}
-.recBtn {
-  margin-right: 10px;
-  background: #a0d911;
-  color: #fff;
-  font-weight: 500;
-}
-.delBtn {
-  background: #f5222d;
-  color: #fff;
-  font-weight: 500;
-}
-.ubBtn {
-  margin-right: 10px;
-  background: #a0d911;
-  color: #fff;
-  font-weight: 500;
-}

+ 3 - 3
src/routes/Terminal/WhiteList/WhiteList.js

@@ -6,7 +6,6 @@ import { Card, Modal, Button, message } from 'antd';
 import { StandardTableList } from '../../../components/RBList';
 import { addRowKey, renderStatus } from '../../../utils/utils';
 import { STATUS_DELETE } from '../../../utils/config';
-import styles from '../User/TerminalList.less';
 
 const Message = message;
 
@@ -83,14 +82,14 @@ export default class WhiteListPage extends Component {
           <Button
             size="small"
             disabled={item.status === STATUS_DELETE}
-            className={styles.editBtn}
+            className="editBtn"
             onClick={() => this.handleEditOperation(item)}
           >
             编辑
           </Button>
           <Button
             size="small"
-            className={styles.delBtn}
+            className="delBtn"
             onClick={() => this.handleDeleteOperation(item)}
           >
             删除
@@ -159,6 +158,7 @@ export default class WhiteListPage extends Component {
       dataIndex: 'operation',
       render: (_, record) => renderOperation(record),
       width: '13%',
+      align: 'right',
     }];
     return (
       <Card>

+ 1 - 1
src/routes/Trade/Order/SubOrderDetail.js

@@ -169,7 +169,7 @@ export default class SubOrderDetailPage extends Component {
     return (
       <div>
         {/* 该订单的一些基础信息 */}
-        <Card>
+        <Card style={{ marginBottom: 70 }}>
           <Table
             bordered
             size="small"

+ 1 - 0
src/routes/Trade/ShopCart/ShopCartList.js

@@ -195,6 +195,7 @@ export default class ShopCartListPage extends Component {
       dataIndex: 'operation',
       render: (_, record) => renderOperation(record),
       width: '10%',
+      align: 'right',
     }];
     return (
       <Card>

+ 0 - 0
src/routes/Trade/ShopCart/ShopCartList.less


+ 4 - 2
src/utils/config.js

@@ -31,13 +31,14 @@ const DOMAIN_PJ = 3010;
 const CHARGE_UNIT_SEASON = '季';
 const CHARGE_UNIT_HALF_YEAR = '半年';
 const CHARGE_UNIT_YEAR = '年';
+const CHARGE_UNIT_ITEM = '件';
 const DURATION_SEASON = 90;
 const DURATION_HALF_YEAR = 180;
 const DURATION_YEAR = 365;
 
 const PAGE_SIZE = 20;
 
-const fileMaxSize = 15; // Picture max size should below 2M
+const FILE_MAX_SIZE = 5; // Index max size should below 5M
 const pageSize = 20;
 const plantform = 'LJ';
 const projectName = 'RealBull';
@@ -86,9 +87,11 @@ const api = {
 };
 
 export {
+  FILE_MAX_SIZE,
   CHARGE_UNIT_YEAR,
   CHARGE_UNIT_SEASON,
   CHARGE_UNIT_HALF_YEAR,
+  CHARGE_UNIT_ITEM,
   DURATION_YEAR,
   DURATION_SEASON,
   DURATION_HALF_YEAR,
@@ -123,5 +126,4 @@ export {
   ossHost,
   api,
   pageSize,
-  fileMaxSize,
 };