소스 검색

feat(front): 长难句,字符长度

Go 5 년 전
부모
커밋
ec0efff8a9

+ 1 - 0
front/project/admin/routes/subject/question/page.js

@@ -421,6 +421,7 @@ export default class extends Page {
                 ['image', 'table', 'select'],
                 [{ header: '1' }, { header: '2' }],
                 ['bold', 'underline', 'blockquote'],
+                [{ color: ['red', 'green', 'blue', 'orange', 'violet', '#d0d1d2', 'black'] }],
                 [{ list: 'ordered' }, { list: 'bullet' }, { indent: '-1' }, { indent: '+1' }],
               ],
               handlers: {

+ 3 - 1
front/project/www/components/Login/index.js

@@ -127,7 +127,9 @@ export default class Login extends Component {
         }
       })
       .catch(err => {
-        asyncSMessage(err.message, 'error');
+        if (err.message !== '') {
+          asyncSMessage(err.message, 'error');
+        }
       });
   }
 

+ 54 - 2
front/project/www/components/OtherModal/index.js

@@ -369,6 +369,57 @@ export class EditInfo extends Component {
     this.setState({ data, empty, nicknameError: null });
   }
 
+  strLen(str) {
+    let len = 0;
+    for (let i = 0; i < str.length; i += 1) {
+      if (str.charCodeAt(i) > 255 || str.charCodeAt(i) < 0) len += 2; else len += 1;
+    }
+    return len;
+  }
+
+  // 将字符串拆成字符,并存到数组中
+  strToChars(str) {
+    const chars = [];
+    for (let i = 0; i < str.length; i += 1) {
+      chars[i] = [str.substr(i, 1), this.isCHS(str, i)];
+    }
+    return chars;
+  }
+
+  // 判断某个字符是否是汉字
+  isCHS(str, i) {
+    if (str.charCodeAt(i) > 255 || str.charCodeAt(i) < 0) {
+      return true;
+    }
+    return false;
+  }
+
+  // 截取字符串(从start字节到end字节)
+  subCHString(str, start, end) {
+    let len = 0;
+    let s = '';
+    const chars = this.strToChars(str);
+    for (let i = 0; i < str.length; i += 1) {
+      if (chars[i][1]) {
+        len += 2;
+      } else {
+        len += 1;
+      }
+      if (end < len) {
+        return s;
+      }
+      if (start < len) {
+        s += chars[i][0];
+      }
+    }
+    return s;
+  }
+
+  // 截取字符串(从start字节截取length个字节)
+  subCHStr(str, start, length) {
+    return this.subCHString(str, start, start + length);
+  }
+
   submit() {
     const { data, nicknameError } = this.state;
     if (nicknameError) return;
@@ -376,8 +427,9 @@ export class EditInfo extends Component {
       this.setState({ empty: { nickname: !data.nickname } });
       return;
     }
-    if (data.nickname.length < 2 || data.nickname.length > 14) {
-      this.setState({ nicknameError: '用户名长度不足2个自负或超过14个字符' });
+    const len = this.strLen(data.nickname);
+    if (len < 2 || len > 14) {
+      this.setState({ nicknameError: '用户名长度不足2个字符或超过14个字符' });
       return;
     }
     const { nickname, avatar } = data;

+ 2 - 2
front/project/www/routes/course/dataDetail/page.js

@@ -42,11 +42,11 @@ export default class extends Page {
       this.setState({ data: result });
     });
     this.view(id);
-    Main.listFaq({ page: 1, size: 100, channel: 'course_data' }).then(result => {
+    Main.listFaq({ page: 1, size: 100, channel: 'course_data', position: id }).then(result => {
       this.faqs = result.list;
       this.setState({ faqs: result.list });
     });
-    Main.listComment({ page: 1, size: 100, channel: 'course_data' }).then(result => {
+    Main.listComment({ page: 1, size: 100, channel: 'course_data', position: id }).then(result => {
       this.comments = result.list;
       this.setState({ comments: result.list });
     });

+ 4 - 0
front/project/www/routes/course/detail/page.js

@@ -208,6 +208,10 @@ export default class extends Page {
       }
       this.refreshNote();
     });
+    Main.listComment({ page: 1, size: 100, channel: 'course-video', position: id }).then(result => {
+      this.comments = result.list;
+      this.setState({ comments: result.list });
+    });
   }
 
   refreshAsk(position) {

+ 39 - 15
front/project/www/routes/exercise/main/page.js

@@ -1,7 +1,7 @@
 import React from 'react';
 import './index.less';
 import { Modal } from 'antd';
-import { Link } from 'react-router-dom';
+// import { Link } from 'react-router-dom';
 import Page from '@src/containers/Page';
 import { asyncConfirm } from '@src/services/AsyncTools';
 import { formatTreeData, formatSeconds, formatDate, formatPercent, getMap } from '@src/services/Tools';
@@ -274,7 +274,7 @@ export default class extends Page {
     return {
       tab1: SENTENCE,
       tab2: '',
-      tab3: '1',
+      tab3: 'faq',
       previewType: PREVIEW_COURSE,
       tabs: [],
       allCourse: [],
@@ -356,6 +356,11 @@ export default class extends Page {
           // result.code = '123123';
           // result.trailPages = 20;
           this.setState({ sentence: result });
+          if (result.dataId) {
+            Main.listComment({ page: 1, size: 100, channel: 'course_data', position: result.dataId }).then(r => {
+              this.setState({ comments: r.list });
+            });
+          }
           return result;
         })
         .then(({ code, trailPages, chapters }) => {
@@ -423,6 +428,9 @@ export default class extends Page {
             this.setState({ paperList: result, paperFilterList: result });
           });
         });
+      Main.listFaq({ page: 1, size: 100, channel: 'exercise-sentence' }).then(result => {
+        this.setState({ faqs: result.list });
+      });
     }
   }
 
@@ -670,7 +678,7 @@ export default class extends Page {
   }
 
   renderView() {
-    const { tab1, tab2, tab3, tabs, latest, sentenceModel, previewType, courseTabs = [] } = this.state;
+    const { tab1, tab2, tabs, latest, sentenceModel, previewType, courseTabs = [] } = this.state;
     const [subject] = tabs.filter(row => row.key === tab1);
     const children = (subject && subject.children) ? subject.children : (tab1 === 'preview' && previewType === PREVIEW_COURSE ? courseTabs : []);
     return (
@@ -711,17 +719,9 @@ export default class extends Page {
           {tab1 === SENTENCE && this.renderSentence()}
           {tab1 === PREVIEW && this.renderPreview()}
 
-          {this.state.faqs && <QAList data={this.state.faqs} active={'faq'} tabs={[{ key: 'faq', name: 'FAQs' }]} />}
-        </div>
-        <div className='bottom-info'>
-          <div className='content'>
-            <Tabs active={tab3} space={7.5} type='tag' theme='white' tabs={[{ key: '1', title: '千行长难句' }, { key: '2', title: '关于CODE' }, { key: '3', title: '考生评价' }]} onChange={(key) => this.setState({ tab3: key })} />
-            {tab3 === '1' && <AnswerCarousel hideBtn />}
-            {tab3 === '3' && [{}].map((item) => {
-              return <Comment data={item} />;
-            })}
-          </div>
+          {tab1 !== SENTENCE && this.state.faqs && <QAList data={this.state.faqs} active={'faq'} tabs={[{ key: 'faq', name: 'FAQs' }]} />}
         </div>
+        {tab1 === SENTENCE && this.renderSentenceInfo()}
         {sentenceModel && this.renderInputCodeModel()}
       </div>
     );
@@ -902,6 +902,30 @@ export default class extends Page {
     return this.renderInputCode();
   }
 
+  renderSentenceInfo() {
+    const { sentence = {}, tab3, sentenceInfo = {}, faqs = [], comments = [] } = this.state;
+    const { sentenceTrail } = this.props.user;
+    if (sentence.code || sentenceTrail) {
+      return null;
+    }
+    return <div className='bottom-info'>
+      <div className='content'>
+        <Tabs active={tab3} space={7.5} type='tag' theme='white' tabs={[{ key: 'faq', title: '千行长难句' }, { key: 'code', title: '关于CODE' }, { key: 'comment', title: '考生评价' }]} onChange={(key) => {
+          this.setState({ tab3: key });
+        }} />
+        {tab3 === 'faq' && <AnswerCarousel
+          hideBtn
+          list={faqs}
+          onFaq={() => User.needLogin().then(() => this.setState({ showFaq: true, faq: { channel: 'exercise-sentence' } }))}
+        />}
+        {tab3 === 'code' && <div dangerouslySetInnerHTML={{ __html: sentenceInfo.detail }} />}
+        {tab3 === 'comment' && (comments || []).map((item) => {
+          return <Comment data={item} />;
+        })}
+      </div>
+    </div>;
+  }
+
   renderSentenceArticle() {
     const {
       sentence = {},
@@ -1082,11 +1106,11 @@ export default class extends Page {
               }}
             />
             {sentenceError && <div className="error">{sentenceError}</div>}
-            <div className="tip">
+            {/* <div className="tip">
               <Link to="/" className="right link">
                 什么是CODE?
               </Link>
-            </div>
+            </div> */}
           </div>
           <div className="btn-list">
             <AnswerButton size="lager" theme="confirm" width={150} onClick={() => this.activeSentence()}>

+ 1 - 1
front/src/components/Editor/index.js

@@ -11,7 +11,7 @@ const modules = {
         'bold',
         'underline',
         'blockquote',
-        // { color: ['red', 'green', 'blue', 'orange', 'violet', '#d0d1d2', 'black'] },
+        { color: ['red', 'green', 'blue', 'orange', 'violet', '#d0d1d2', 'black'] },
       ],
       [{ list: 'ordered' }, { list: 'bullet' }, { indent: '-1' }, { indent: '+1' }],
       // ['image'],

+ 1 - 0
server/gateway-api/src/main/java/com/qxgmat/controller/api/SentenceController.java

@@ -116,6 +116,7 @@ public class SentenceController
         // 评论: 通过资料的长难句分类获取该资料的评论
         CourseData courseData = courseDataService.getSentence();
         if(courseData != null){
+            dto.setDataId(courseData.getId());
             List<Comment> commentList = commentService.list(1, 1, "course_data", courseData.getId().toString());
             dto.setComments(Transform.convert(commentList, CommentExtendDto.class));
         }

+ 30 - 3
server/gateway-api/src/main/java/com/qxgmat/service/UsersService.java

@@ -156,9 +156,9 @@ public class UsersService extends AbstractService {
             }
         }
         if (openUser == null || openUser.getNickname() == null|| openUser.getNickname().isEmpty() || openUser.getNickname().equals("qx"+openUser.getMobile())){
-            mm.setNickname(data.getNickName());
+            mm.setNickname(getSubString(data.getNickName(), 14));
             if(openUser != null){
-                openUser.setNickname(data.getNickName());
+                openUser.setNickname(getSubString(data.getNickName(), 14));
             }
         }
 
@@ -251,11 +251,38 @@ public class UsersService extends AbstractService {
         if(openUser.getWechatUnionid() != null) user.setWechatUnionid(openUser.getWechatUnionid());
         if(openUser.getWechatAccessToken() != null) user.setWechatAccessToken(openUser.getWechatAccessToken());
         if(openUser.getWechatRefreshToken() != null) user.setWechatRefreshToken(openUser.getWechatRefreshToken());
-        if(openUser.getNickname() != null && (user.getNickname() == null || user.getNickname().isEmpty() || user.getNickname().equals("qx" + user.getMobile()))) user.setNickname(openUser.getNickname());
+        if(openUser.getNickname() != null && (user.getNickname() == null || user.getNickname().isEmpty() || user.getNickname().equals("qx" + user.getMobile()))) user.setNickname(getSubString(openUser.getNickname(), 14));
         if(openUser.getAvatar() != null && (user.getAvatar() == null || user.getAvatar().isEmpty())) user.setAvatar(openUser.getAvatar());
         return user;
     }
 
+    public static String getSubString(String str, int length) {
+        int count = 0;
+        int offset = 0;
+        char[] c = str.toCharArray();
+        int size = c.length;
+        if(size >= length){
+            for (int i = 0; i < c.length; i++) {
+                if (c[i] > 256) {
+                    offset = 2;
+                    count += 2;
+                } else {
+                    offset = 1;
+                    count++;
+                }
+                if (count == length) {
+                    return str.substring(0, i + 1);
+                }
+                if ((count == length + 1 && offset == 2)) {
+                    return str.substring(0, i);
+                }
+            }
+        }else{
+            return str;
+        }
+        return "";
+    }
+
     // 获取微信快到期账号
     public Page<User> listByWechatExpire(int page, int size, Date expire){
         Example example = new Example(User.class);