Explorar o código

feat(server): 推荐阅读

Go %!s(int64=4) %!d(string=hai) anos
pai
achega
264515e86a

+ 60 - 9
front/project/admin/routes/ready/read/page.js

@@ -1,5 +1,5 @@
 import React from 'react';
-import { Link } from 'react-router-dom';
+// import { Link } from 'react-router-dom';
 import { Button, Switch, Modal } from 'antd';
 import './index.less';
 import Page from '@src/containers/Page';
@@ -9,7 +9,7 @@ import EditTableCell from '@src/components/EditTableCell';
 import ActionLayout from '@src/layouts/ActionLayout';
 import TableLayout from '@src/layouts/TableLayout';
 import { formatDate, getMap } from '@src/services/Tools';
-import { asyncSMessage, asyncDelConfirm } from '@src/services/AsyncTools';
+import { asyncSMessage, asyncDelConfirm, asyncForm } from '@src/services/AsyncTools';
 // import { SwitchSelect } from '../../../../Constant';
 import { Ready } from '../../../stores/ready';
 
@@ -20,9 +20,9 @@ export default class extends Page {
       key: 'add',
       type: 'primary',
       name: '创建',
-      render: (item) => {
-        return <Link to='/ready/read/detail'><Button>{item.name}</Button></Link>;
-      },
+      // render: (item) => {
+      //   return <Link to='/ready/read/detail'><Button>{item.name}</Button></Link>;
+      // },
     }, {
       key: 'struct',
       name: '管理板块',
@@ -47,7 +47,9 @@ export default class extends Page {
       dataIndex: 'handler',
       render: (text, record) => {
         return <div className="table-button">
-          {<Link to={`/ready/read/detail/${record.id}`}>编辑</Link>}
+          {<a onClick={() => {
+            this.editAction(record);
+          }}>编辑</a>}
           {<a onClick={() => {
             this.deleteAction(record);
           }}>删除</a>}
@@ -55,6 +57,27 @@ export default class extends Page {
       },
     }];
 
+    this.itemList = [{
+      key: 'id',
+      type: 'hidden',
+    }, {
+      key: 'plate',
+      type: 'select',
+      name: '板块',
+      select: [],
+      required: true,
+    }, {
+      key: 'title',
+      type: 'input',
+      name: '标题',
+      required: true,
+    }, {
+      key: 'link',
+      type: 'input',
+      name: '链接',
+      required: true,
+    }];
+
     this.structColumns = [{
       title: '板块名称',
       dataIndex: 'plate',
@@ -81,10 +104,10 @@ export default class extends Page {
       },
     }, {
       title: '按钮名称',
-      dataIndex: 'title',
+      dataIndex: 'text',
       render: (text, record, index) => {
         return <EditTableCell value={text} onChange={(v) => {
-          this.changeStruct(index, 'title', v);
+          this.changeStruct(index, 'text', v);
         }} />;
       },
     }];
@@ -103,7 +126,11 @@ export default class extends Page {
 
   refreshStruct(result) {
     result = result || {};
-    result.plates = (result.plates || []).map((row, index) => { row.value = index + 1; return row; });
+    result.plates = (result.plates || []).map((row, index) => {
+      row.title = row.plate;
+      row.value = `${index + 1}`;
+      return row;
+    });
     this.structMap = getMap(result.plates, 'value', 'plate');
     this.setState({ struct: result });
   }
@@ -135,6 +162,30 @@ export default class extends Page {
     });
   }
 
+  addAction() {
+    this.itemList[1].select = this.state.struct.plates;
+    asyncForm('创建', this.itemList, {}, data => {
+      return Ready.addRead(data).then(() => {
+        asyncSMessage('添加成功!');
+        this.refresh();
+      });
+    }).then(component => {
+      this.formF = component;
+    });
+  }
+
+  editAction(row) {
+    this.itemList[1].select = this.state.struct.plates;
+    asyncForm('编辑', this.itemList, row, data => {
+      return Ready.editRead(data).then(() => {
+        asyncSMessage('编辑成功!');
+        this.refresh();
+      });
+    }).then(component => {
+      this.formF = component;
+    });
+  }
+
   deleteAction(row) {
     asyncDelConfirm('删除确认', '是否删除选中?', () => {
       const handler = Ready.delRead({ id: row.id });

+ 45 - 26
front/project/www/routes/page/ready/page.js

@@ -1,6 +1,6 @@
 import React from 'react';
 import './index.less';
-import { Link } from 'react-router-dom';
+// import { Link } from 'react-router-dom';
 import { Anchor, Icon } from 'antd';
 import Assets from '@src/components/Assets';
 import Page from '@src/containers/Page';
@@ -8,7 +8,7 @@ import Select from '../../../components/Select';
 import Button from '../../../components/Button';
 import QAList from '../../../components/QAList';
 import Tabs from '../../../components/Tabs';
-import { SuppleModal, SuppleFinishModal } from '../../../components/OtherModal';
+import { SuppleModal, SuppleFinishModal, FaqModal, FinishModal } from '../../../components/OtherModal';
 import { Main } from '../../../stores/main';
 import { User } from '../../../stores/user';
 import { getMap, formatTreeData } from '../../../../../src/services/Tools';
@@ -18,6 +18,8 @@ export default class extends Page {
     this.areaMap = {};
     this.categoryMap = {};
     this.loadArticleMap = {};
+    this.readPlateMap = {};
+    this.loadReadMap = {};
     this.dataList = null;
     return {
       readTab: '1',
@@ -144,7 +146,13 @@ export default class extends Page {
         });
         this.categoryMap = getMap(result.category, 'id');
         const list = formatTreeData(result.category, 'id', 'title', 'parentId');
-        this.setState({ list });
+        const readPlates = result.read.plates.map((row, index) => {
+          row.title = row.plate;
+          row.key = `${index + 1}`;
+          return row;
+        });
+        this.readPlateMap = getMap(readPlates, 'key');
+        this.setState({ list, readPlates });
         this.changePage(list[0].id);
       });
   }
@@ -205,18 +213,6 @@ export default class extends Page {
     }
   }
 
-  refreshRead() {
-    if (!this.readList) {
-      Main.listRead({ page: 1, size: 1000, plate: 'getready' })
-        .then(result => {
-          this.readList = result.list;
-          this.setState({ reads: this.readList });
-        });
-    } else {
-      this.setState({ reads: this.readList });
-    }
-  }
-
   refreshFaq() {
     if (!this.faqList) {
       Main.listFaq({ page: 1, size: 1000, channel: 'getready' })
@@ -297,8 +293,25 @@ export default class extends Page {
     this.setState({ current: key });
   }
 
+  refreshRead() {
+    // init
+    const { readPlates } = this.state;
+    this.onChangeReadTab(readPlates[0].key);
+  }
+
   onChangeReadTab(key) {
-    this.setState({ readTab: key });
+    const plate = this.readPlateMap[key];
+    this.setState({ readTab: key, plate, reads: [] });
+    if (!this.loadReadMap[key]) {
+      Main.listRead({ page: 1, size: 100, plate: key })
+        .then(result => {
+          this.loadReadMap[key] = result.list;
+          this.setState({ reads: result.list });
+        });
+    } else {
+      const list = this.loadReadMap[key];
+      this.setState({ reads: list });
+    }
   }
 
   renderView() {
@@ -350,7 +363,7 @@ export default class extends Page {
             {!!detail.isFaq && this.renderFaq()}
           </div>
         </div>
-      </div >
+      </div>
     );
   }
 
@@ -415,7 +428,8 @@ export default class extends Page {
   }
 
   renderRead() {
-    const { readTab, reads = [] } = this.state;
+    const { readTab, reads = [], readPlates, plate = {} } = this.state;
+    console.log(plate);
     return <div className='read-layout'>
       <Tabs
         className='m-b-2'
@@ -423,26 +437,31 @@ export default class extends Page {
         theme="gray"
         space={2.5}
         active={readTab}
-        tabs={[{ title: '单项攻略', key: '1' }, { title: '模考&PACE', key: '2' }, { title: '换库&机经', key: '3' }, { title: '经验分享', key: '4' }, { title: '申请相关', key: '5' }]}
+        tabs={readPlates}
         onChange={key => this.onChangeReadTab(key)}
       />
-      <div className='m-b-2'>
-        <Button className='m-r-1'>CAT模考 ></Button>
-        <Button>非CAT模考 ></Button>
-      </div>
+      {!!plate.jump && <div className='m-b-2'>
+        <Button className='m-r-1' onClick={() => openLink(plate.link)}>{plate.text}</Button>
+      </div>}
       {reads.map((item) => {
         return <div className='m-b-5'>
-          <Link to={item.path}>{item.title}</Link>
+          <a href={item.link || ''} target="_blank">{item.title}</a>
         </div>;
       })}
     </div>;
   }
 
   renderFaq() {
-    const { faqs = [] } = this.state;
+    const { faqs = [], showFaq, showFinish, faq = {} } = this.state;
     return <div className='faq-layout'>
-      <Button>我要提问 ></Button>
+      <Button onClick={() => this.setState({ showFaq: true, faq: { channel: 'getready' } })}>我要提问 ></Button>
       <QAList data={faqs} />
+
+      <FaqModal show={showFaq} defaultData={faq} onCancel={() => this.setState({ showFaq: false, faq: {} })} onConfirm={() => this.setState({ showFaq: false, faq: {}, showFinish: true })} />
+      <FinishModal
+        show={showFinish}
+        onConfirm={() => this.setState({ showFinish: false })}
+      />
     </div>;
   }
 }

+ 35 - 0
server/data/src/main/java/com/qxgmat/data/dao/entity/ReadyRead.java

@@ -23,6 +23,12 @@ public class ReadyRead implements Serializable {
     @Column(name = "`title`")
     private String title;
 
+    /**
+     * 链接
+     */
+    @Column(name = "`link`")
+    private String link;
+
     @Column(name = "`create_time`")
     private Date createTime;
 
@@ -88,6 +94,24 @@ public class ReadyRead implements Serializable {
     }
 
     /**
+     * 获取链接
+     *
+     * @return link - 链接
+     */
+    public String getLink() {
+        return link;
+    }
+
+    /**
+     * 设置链接
+     *
+     * @param link 链接
+     */
+    public void setLink(String link) {
+        this.link = link;
+    }
+
+    /**
      * @return create_time
      */
     public Date getCreateTime() {
@@ -142,6 +166,7 @@ public class ReadyRead implements Serializable {
         sb.append(", id=").append(id);
         sb.append(", plate=").append(plate);
         sb.append(", title=").append(title);
+        sb.append(", link=").append(link);
         sb.append(", createTime=").append(createTime);
         sb.append(", updateTime=").append(updateTime);
         sb.append(", content=").append(content);
@@ -189,6 +214,16 @@ public class ReadyRead implements Serializable {
         }
 
         /**
+         * 设置链接
+         *
+         * @param link 链接
+         */
+        public Builder link(String link) {
+            obj.setLink(link);
+            return this;
+        }
+
+        /**
          * @param createTime
          */
         public Builder createTime(Date createTime) {

+ 2 - 1
server/data/src/main/java/com/qxgmat/data/dao/mapping/ReadyReadMapper.xml

@@ -8,6 +8,7 @@
     <id column="id" jdbcType="INTEGER" property="id" />
     <result column="plate" jdbcType="VARCHAR" property="plate" />
     <result column="title" jdbcType="VARCHAR" property="title" />
+    <result column="link" jdbcType="VARCHAR" property="link" />
     <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
     <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
   </resultMap>
@@ -21,7 +22,7 @@
     <!--
       WARNING - @mbg.generated
     -->
-    `id`, `plate`, `title`, `create_time`, `update_time`
+    `id`, `plate`, `title`, `link`, `create_time`, `update_time`
   </sql>
   <sql id="Blob_Column_List">
     <!--

+ 1 - 0
server/data/src/main/resources/db/migration/V1__init_table.sql

@@ -630,6 +630,7 @@ CREATE TABLE ready_read (
   plate varchar(255) NOT NULL DEFAULT '' COMMENT '板块',
   title varchar(255) NOT NULL DEFAULT '' COMMENT '标题',
   content text COMMENT '内容',
+  link varchar(255) NOT NULL DEFAULT '' COMMENT '链接',
   create_time datetime DEFAULT NULL,
   update_time datetime DEFAULT NULL,
   PRIMARY KEY (id),

+ 10 - 0
server/gateway-api/src/main/java/com/qxgmat/dto/admin/request/ReadyReadDto.java

@@ -14,6 +14,8 @@ public class ReadyReadDto {
 
     private String content;
 
+    private String link;
+
     public Integer getId() {
         return id;
     }
@@ -45,4 +47,12 @@ public class ReadyReadDto {
     public void setPlate(String plate) {
         this.plate = plate;
     }
+
+    public String getLink() {
+        return link;
+    }
+
+    public void setLink(String link) {
+        this.link = link;
+    }
 }