Procházet zdrojové kódy

fix(service): 支付

Go před 4 roky
rodič
revize
1d2e10dc9c
100 změnil soubory, kde provedl 599 přidání a 216 odebrání
  1. 1 0
      front/project/admin/routes/course/data/index.js
  2. 1 0
      front/project/admin/routes/course/dataDetail/index.js
  3. 1 0
      front/project/admin/routes/course/dataHistory/index.js
  4. 1 0
      front/project/admin/routes/course/detail/index.js
  5. 1 0
      front/project/admin/routes/course/experience/index.js
  6. 1 0
      front/project/admin/routes/course/experienceDetail/index.js
  7. 1 0
      front/project/admin/routes/course/invoice/index.js
  8. 1 0
      front/project/admin/routes/course/list/index.js
  9. 1 0
      front/project/admin/routes/course/package/index.js
  10. 1 0
      front/project/admin/routes/course/preview/index.js
  11. 1 0
      front/project/admin/routes/course/previewDetail/index.js
  12. 1 0
      front/project/admin/routes/course/student/index.js
  13. 1 0
      front/project/admin/routes/course/vsDetail/index.js
  14. 1 0
      front/project/admin/routes/interaction/askQuestion/index.js
  15. 1 0
      front/project/admin/routes/interaction/askQuestionDetail/index.js
  16. 1 0
      front/project/admin/routes/interaction/comment/index.js
  17. 1 0
      front/project/admin/routes/interaction/faq/index.js
  18. 1 0
      front/project/admin/routes/interaction/feedback/index.js
  19. 1 0
      front/project/admin/routes/ready/article/index.js
  20. 1 0
      front/project/admin/routes/ready/articleDetail/index.js
  21. 1 0
      front/project/admin/routes/ready/data/index.js
  22. 1 0
      front/project/admin/routes/ready/feedback/index.js
  23. 1 0
      front/project/admin/routes/ready/read/index.js
  24. 1 0
      front/project/admin/routes/ready/readDetail/index.js
  25. 1 0
      front/project/admin/routes/ready/room/index.js
  26. 1 0
      front/project/admin/routes/setting/contract/index.js
  27. 1 0
      front/project/admin/routes/setting/contractDetail/index.js
  28. 1 0
      front/project/admin/routes/setting/index/index.js
  29. 1 0
      front/project/admin/routes/setting/place/index.js
  30. 1 0
      front/project/admin/routes/setting/promote/index.js
  31. 1 0
      front/project/admin/routes/setting/rank/index.js
  32. 1 0
      front/project/admin/routes/setting/service/index.js
  33. 1 0
      front/project/admin/routes/setting/struct/index.js
  34. 1 0
      front/project/admin/routes/setting/time/index.js
  35. 1 0
      front/project/admin/routes/show/ad/index.js
  36. 1 0
      front/project/admin/routes/show/comment/index.js
  37. 1 0
      front/project/admin/routes/show/deploy/index.js
  38. 1 0
      front/project/admin/routes/show/faq/index.js
  39. 2 2
      front/project/admin/routes/show/index.js
  40. 1 0
      front/project/admin/routes/show/message/index.js
  41. 1 0
      front/project/admin/routes/show/messageDetail/index.js
  42. 1 0
      front/project/admin/routes/show/tips/index.js
  43. 1 0
      front/project/admin/routes/student/askCourse/index.js
  44. 1 0
      front/project/admin/routes/student/askCourseDetail/index.js
  45. 1 0
      front/project/admin/routes/student/askQuestion/index.js
  46. 1 0
      front/project/admin/routes/student/askQuestionDetail/index.js
  47. 1 0
      front/project/admin/routes/student/study/index.js
  48. 1 0
      front/project/admin/routes/student/studyDetail/index.js
  49. 1 0
      front/project/admin/routes/subject/examination/index.js
  50. 1 0
      front/project/admin/routes/subject/exercise/index.js
  51. 1 0
      front/project/admin/routes/subject/question/index.js
  52. 1 0
      front/project/admin/routes/subject/sentence/index.js
  53. 1 0
      front/project/admin/routes/subject/sentenceArticle/index.js
  54. 1 0
      front/project/admin/routes/subject/sentenceQuestion/index.js
  55. 1 0
      front/project/admin/routes/subject/textbook/index.js
  56. 1 0
      front/project/admin/routes/subject/textbookQuestion/index.js
  57. 1 0
      front/project/admin/routes/system/manager/list/index.js
  58. 1 0
      front/project/admin/routes/textbook/feedback/index.js
  59. 1 0
      front/project/admin/routes/textbook/library/index.js
  60. 1 0
      front/project/admin/routes/textbook/topic/index.js
  61. 1 0
      front/project/admin/routes/textbook/topicDetail/index.js
  62. 1 0
      front/project/admin/routes/user/abnormal/index.js
  63. 1 0
      front/project/admin/routes/user/detail/index.js
  64. 1 0
      front/project/admin/routes/user/list/index.js
  65. 1 0
      front/project/admin/routes/user/order/index.js
  66. 1 0
      front/project/admin/routes/user/orderDetail/index.js
  67. 1 0
      front/project/admin/routes/user/recordAll/index.js
  68. 1 0
      front/project/admin/routes/user/recordBuy/index.js
  69. 1 0
      front/project/admin/routes/user/student/index.js
  70. 3 3
      front/project/www/components/Login/index.js
  71. 114 1
      front/project/www/components/OtherModal/index.js
  72. 6 2
      front/project/www/components/PayModal/index.js
  73. 1 1
      front/project/www/components/QrCode/index.js
  74. 5 2
      front/project/www/components/VipRenew/index.js
  75. 7 1
      front/project/www/routes/course/note/page.js
  76. 87 65
      front/project/www/routes/my/collect/page.js
  77. 103 65
      front/project/www/routes/my/error/page.js
  78. 7 1
      front/project/www/routes/my/main/page.js
  79. 7 1
      front/project/www/routes/my/note/page.js
  80. 7 1
      front/project/www/routes/my/tools/page.js
  81. 1 1
      front/project/www/routes/page/ready/page.js
  82. 45 23
      front/project/www/routes/paper/question/detail/index.js
  83. 44 8
      front/project/www/routes/paper/report/page.js
  84. 1 1
      front/project/www/routes/question/detail/index.js
  85. 19 1
      front/project/www/routes/question/search/page.js
  86. 8 0
      front/project/www/stores/my.js
  87. 11 13
      front/project/www/stores/user.js
  88. 4 4
      server/data/src/main/java/com/qxgmat/data/relation/mapping/UserCollectQuestionRelationMapper.xml
  89. 4 3
      server/gateway-api/src/main/java/com/qxgmat/controller/api/AuthController.java
  90. 14 0
      server/gateway-api/src/main/java/com/qxgmat/controller/api/MyController.java
  91. 1 0
      server/gateway-api/src/main/java/com/qxgmat/service/extend/MessageExtendService.java
  92. 2 0
      server/gateway-api/src/main/java/com/qxgmat/service/extend/OrderFlowService.java
  93. 11 9
      server/gateway-api/src/main/java/com/qxgmat/service/extend/TradeService.java
  94. 1 0
      server/gateway-api/src/main/profile/dev/application-runtime.yml
  95. 1 0
      server/gateway-api/src/main/profile/prod/application-runtime.yml
  96. 1 0
      server/gateway-api/src/main/profile/test/application-runtime.yml
  97. 2 2
      server/gateway-api/src/main/resources/application.yml
  98. 9 5
      server/tools/src/main/java/com/nuliji/tools/pay/Alipay.java
  99. 3 1
      server/tools/src/main/java/com/nuliji/tools/pay/WechatPay.java
  100. 0 0
      server/tools/src/main/java/com/tencent/protocol/pay_protocol/JsReqData.java

+ 1 - 0
front/project/admin/routes/course/data/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/course/dataDetail/index.js

@@ -9,6 +9,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   showKey: 'course-data',
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/course/dataHistory/index.js

@@ -9,6 +9,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   showKey: 'course-data',
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/course/detail/index.js

@@ -9,6 +9,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   showKey: 'course',
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/course/experience/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/course/experienceDetail/index.js

@@ -9,6 +9,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   showKey: 'course-experience',
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/course/invoice/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/course/list/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/course/package/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/course/preview/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/course/previewDetail/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   showKey: 'course-preview',
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/course/student/index.js

@@ -9,6 +9,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   showKey: 'course-student',
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/course/vsDetail/index.js

@@ -9,6 +9,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   showKey: 'course',
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/interaction/askQuestion/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/interaction/askQuestionDetail/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   showKey: 'interaction-ask-question',
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/interaction/comment/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/interaction/faq/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/interaction/feedback/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/ready/article/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/ready/articleDetail/index.js

@@ -9,6 +9,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   showKey: 'ready-article',
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/ready/data/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/ready/feedback/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/ready/read/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/ready/readDetail/index.js

@@ -9,6 +9,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   showKey: 'ready-read',
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/ready/room/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/setting/contract/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/setting/contractDetail/index.js

@@ -9,6 +9,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   showKey: 'setting-contract',
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/setting/index/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/setting/place/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/setting/promote/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/setting/rank/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/setting/service/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/setting/struct/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/setting/time/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/show/ad/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/show/comment/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/show/deploy/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/show/faq/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 2 - 2
front/project/admin/routes/show/index.js

@@ -1,5 +1,5 @@
 
-import tips from './tips';
+// import tips from './tips';
 import faq from './faq';
 import comment from './comment';
 import ad from './ad';
@@ -7,4 +7,4 @@ import message from './message';
 import messageDetail from './messageDetail';
 import deploy from './deploy';
 
-export default [tips, faq, comment, ad, message, messageDetail, deploy];
+export default [faq, comment, ad, message, messageDetail, deploy];

+ 1 - 0
front/project/admin/routes/show/message/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/show/messageDetail/index.js

@@ -9,6 +9,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   showKey: 'show-message',
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/show/tips/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/student/askCourse/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/student/askCourseDetail/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   showKey: 'course-ask',
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/student/askQuestion/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/student/askQuestionDetail/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   showKey: 'student-ask-question',
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/student/study/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/student/studyDetail/index.js

@@ -9,6 +9,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   showKey: 'course-study',
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/subject/examination/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/subject/exercise/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

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

@@ -9,6 +9,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/subject/sentence/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/subject/sentenceArticle/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   showKey: 'subject-sentence',
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/subject/sentenceQuestion/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   showKey: 'subject-sentence',
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/subject/textbook/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/subject/textbookQuestion/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   showKey: 'subject-textbook',
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/system/manager/list/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/textbook/feedback/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/textbook/library/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/textbook/topic/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/textbook/topicDetail/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   showKey: 'textbook-topic',
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/user/abnormal/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/user/detail/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   showKey: 'user-list',
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/user/list/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/user/order/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/user/orderDetail/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   showKey: 'user-order',
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/user/recordAll/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/user/recordBuy/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

+ 1 - 0
front/project/admin/routes/user/student/index.js

@@ -8,6 +8,7 @@ export default {
   needLogin: true,
   module,
   group,
+  repeat: true,
   index: true,
   component() {
     return import('./page');

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

@@ -118,7 +118,7 @@ export default class Login extends Component {
   }
 
   scanLogin(code) {
-    User.loginWechat(code, false)
+    User.loginWechat(code, true, false)
       .then(result => {
         if (result.bindMobile) {
           this.close();
@@ -132,7 +132,7 @@ export default class Login extends Component {
   }
 
   scanBind(code) {
-    User.loginWechat(code, false)
+    User.loginWechat(code, false, false)
       .then(() => {
         this.close();
       })
@@ -219,7 +219,7 @@ export default class Login extends Component {
       this.needScan = true;
       scanNumber += 1;
     }
-    this.setState({ scanNumber, type, empty: {}, mobileError: '', emailError: '', validError: '', data: {} });
+    this.setState({ scanNumber, type, empty: {}, mobileError: '', emailError: '', validError: '', data: { area: MobileArea[0].value } });
   }
 
   render() {

+ 114 - 1
front/project/www/components/OtherModal/index.js

@@ -7,8 +7,9 @@ import FileUpload from '@src/components/FileUpload';
 import Assets from '@src/components/Assets';
 import scale from '@src/services/Scale';
 import { asyncSMessage } from '@src/services/AsyncTools';
+import AnswerButton from '../AnswerButton';
 import { SelectInput, VerificationInput, Input } from '../Login';
-import { MobileArea, TextbookFeedbackTarget, TextbookSubject } from '../../../Constant';
+import { MobileArea, TextbookFeedbackTarget, TextbookSubject, AskTarget } from '../../../Constant';
 import Invite from '../Invite';
 import Modal from '../Modal';
 import { Common } from '../../stores/common';
@@ -1395,3 +1396,115 @@ export class SuppleFinishModal extends Component {
     );
   }
 }
+
+export class QuestionNoteModal extends Component {
+  constructor(props) {
+    super(props);
+    this.state = { data: {}, noteField: AskTarget[0].value };
+  }
+
+  componentWillReceiveProps(nextProps) {
+    if (nextProps.show && nextProps.defaultData) {
+      this.setState({ data: Object.assign({}, nextProps.defaultData, this.state.data) });
+    }
+  }
+
+  changeData(field, value) {
+    let { data, empty } = this.state;
+    data = data || {};
+    empty = empty || {};
+    data[field] = value;
+    if (value) empty[field] = !value;
+    this.setState({ data, empty });
+  }
+
+  onConfirm(close) {
+    const { questionNo, onConfirm } = this.props;
+    const { data } = this.state;
+    return My.updateQuestionNote(questionNo.id, data).then(() => {
+      if (close) {
+        this.setState({ data: {}, noteField: AskTarget[0].value });
+        if (onConfirm) onConfirm();
+      }
+    });
+  }
+
+  onCancel() {
+    const { onCancel } = this.props;
+    this.setState({ data: { content: '' } });
+    if (onCancel) onCancel();
+  }
+
+  render() {
+    const { show, getContainer } = this.props;
+    const { data, noteField } = this.state;
+    return (
+      <Modal
+        show={show}
+        title="笔记"
+        width={630}
+        getContainer={getContainer}
+        confirmText="提交"
+        onConfirm={() => this.onConfirm()}
+        onCancel={() => this.onCancel()}
+      >
+        <div className="content">
+          <div className="tabs">
+            {AskTarget.map(item => {
+              return (
+                <div
+                  className={`tab ${noteField === item.key ? 'active' : ''}`}
+                  onClick={() => {
+                    this.setState({ noteField: item.key });
+                  }}
+                >
+                  <div className="text">{item.label}</div>
+                  <div className="date">{data[`${item.key}Time`] ? formatDate(data[`${item.key}Time`]) : ''}</div>
+                </div>
+              );
+            })}
+          </div>
+          <div className="input">
+            <textarea
+              className="textarea"
+              value={data[`${noteField}Content`] || ''}
+              placeholder="记下笔记,方便以后复习"
+              onChange={e => {
+                data[`${noteField}Time`] = new Date();
+                data[`${noteField}Content`] = e.target.value;
+                this.setState({ data });
+              }}
+            />
+            <div className="bottom">
+              <AnswerButton
+                theme="cancel"
+                size="lager"
+                onClick={() => {
+                  this.onCancel();
+                }}
+              >
+                取消
+                </AnswerButton>
+              <AnswerButton
+                size="lager"
+                onClick={() => {
+                  this.onConfirm();
+                }}
+              >
+                编辑
+                </AnswerButton>
+              <AnswerButton
+                size="lager"
+                onClick={() => {
+                  this.onConfirm(true);
+                }}
+              >
+                保存
+                </AnswerButton>
+            </div>
+          </div>
+        </div>
+      </Modal>
+    );
+  }
+}

+ 6 - 2
front/project/www/components/PayModal/index.js

@@ -44,6 +44,7 @@ export class PayModal extends Component {
       case 'alipay':
         handler = Order.alipayQr(order.id)
           .then((result) => {
+            result.qr = Main.qrCode(result.request);
             this.setState({ payInfo: result });
           });
         break;
@@ -92,8 +93,11 @@ export class PayModal extends Component {
         // 查询最后有效期
         My.getVipInfo().then(vip => {
           checkout.info.result = checkout.info.result.replace('{endTime}', formatDate(vip.expireTime, 'YYYY-MM-DD'));
+          User.refreshToken();
           this.setState({ show: false, showVipEnd: true, order: result, checkout });
         });
+      } else if (checkout.productType === 'service') {
+        User.refreshToken();
       } else if (order.checkouts.length === 1 && checkout.productType === 'data') {
         this.setState({ show: false, showDataEnd: true, order: result, checkout });
       } else if (order.checkouts.length === 1) {
@@ -254,7 +258,7 @@ export class PayMModal extends Component {
             />
             <div hidden={pay === 'bank'} className="pay">
               <div className="qrcode">
-                <QrCode width={140} height={140} qrCode={payInfo.qr} vague={!checked} />
+                <QrCode width={140} height={140} qrCode={payInfo.qr} vague={!checked} refresh onRefresh={() => onChangePay(pay)} />
               </div>
               <div className="t">请使用手机微信或支付宝扫码付款</div>
               <div className="t">支付金额: ¥ {order.money}</div>
@@ -343,7 +347,7 @@ export class PayMutilModal extends Component {
             />
             <div hidden={pay === 'bank'} className="pay">
               <div className="qrcode">
-                <QrCode width={140} height={140} qrCode={payInfo.qr} vague={!checked} />
+                <QrCode width={140} height={140} qrCode={payInfo.qr} vague={!checked} refresh onRefresh={() => onChangePay(pay)} />
               </div>
               <div className="t">请使用手机微信或支付宝扫码付款</div>
               <div className="t">支付金额: ¥ {order.money}</div>

+ 1 - 1
front/project/www/components/QrCode/index.js

@@ -7,7 +7,7 @@ function QrCode(props) {
   const { className = '', qrCode, width, height, vague = false, refresh = false, onRefresh } = props;
   return (
     <div className={`qr-code-item ${className}`}>
-      {!vague && <Assets width={width} height={height} src={qrCode} />}
+      {!vague && qrCode && <Assets width={width} height={height} src={qrCode} />}
       {vague && <Assets width={width} height={height} name='' />}
       {refresh && <div style={{ lineHeight: `${height}px` }} className='fixed-refresh' onClick={() => onRefresh && onRefresh()}><Icon type="sync" /></div>}
     </div>

+ 5 - 2
front/project/www/components/VipRenew/index.js

@@ -72,6 +72,7 @@ export default class extends Component {
       default:
         handler = Order.alipayQr(order.id)
           .then((result) => {
+            result.qr = Main.qrCode(result.request);
             this.setState({ payInfo: result });
           });
     }
@@ -114,6 +115,7 @@ export default class extends Component {
         // 查询最后有效期
         My.getVipInfo().then(vip => {
           checkout.info.result = checkout.info.result.replace('{endTime}', formatDate(vip.expireTime, 'YYYY-MM-DD'));
+          User.refreshToken();
           this.setState({ show: false, showEnd: true, order: result, checkout });
         });
       } else {
@@ -124,8 +126,9 @@ export default class extends Component {
 
   close() {
     const { onClose } = this.props;
+    const { showEnd } = this.state;
     this.setState({ tab: '2', showEnd: false, select: null, pay: null, order: {}, checkout: {} });
-    onClose();
+    onClose(showEnd);
   }
 
   render() {
@@ -193,7 +196,7 @@ export default class extends Component {
               onChange={key => this.changePay(key)}
             />
             <div className="qrcode">
-              <QrCode width={140} height={140} qrCode={payInfo.qr} refresh />
+              <QrCode width={140} height={140} qrCode={payInfo.qr} refresh onRefresh={() => this.changePay(pay)} />
             </div>
             <div className="t">请使用手机微信或支付宝扫码付款</div>
             {order && <div className="t">支付金额: ¥ {order.money}</div>}

+ 7 - 1
front/project/www/routes/course/note/page.js

@@ -282,7 +282,13 @@ export default class extends Page {
         data={info}
         onReal={() => this.setState({ showVip: false, showReal: true })}
         onPrepare={() => this.setState({ showVip: false, showExamination: true })}
-        onClose={() => this.setState({ showVip: false })}
+        onClose={(result) => {
+          if (result) {
+            this.refresh();
+          } else {
+            this.setState({ showVip: false });
+          }
+        }}
       />,
     ];
   }

+ 87 - 65
front/project/www/routes/my/collect/page.js

@@ -7,7 +7,7 @@ import { timeRange, getMap, formatPercent, formatMonth, formatDate, formatSecond
 import UserLayout from '../../../layouts/User';
 import UserTable from '../../../components/UserTable';
 import UserAction from '../../../components/UserAction';
-import { RealAuth } from '../../../components/OtherModal';
+import { RealAuth, QuestionNoteModal } from '../../../components/OtherModal';
 import Examination from '../../../components/Examination';
 import VipRenew from '../../../components/VipRenew';
 import menu, { refreshQuestionType } from '../index';
@@ -23,67 +23,6 @@ const QuestionTypeMap = getMap(QuestionType, 'value', 'label');
 const PrepareStatusMap = getMap(PrepareStatus, 'value', 'short');
 const ExperiencePercentMap = getMap(ExperiencePercent, 'value', 'label');
 
-const columns = [
-  {
-    key: 'question_type',
-    title: '题型',
-    render: (text, record) => {
-      return QuestionTypeMap[record.questionType];
-    },
-    fixSort: true,
-  },
-  {
-    key: 'title',
-    title: '题目ID',
-    fixSort: true,
-  },
-  {
-    key: 'description',
-    title: '内容',
-  },
-  {
-    key: 'time',
-    title: '耗时',
-    sort: true,
-    render: (text, record) => {
-      const user = record.stat.userTime / record.stat.userNumber;
-      const all = record.questionNo.totalTime / record.questionNo.totalNumber;
-      return <div className="sub">
-        <div className="t-2 t-s-12">{formatSeconds(user)}<Assets height={10} width={10} name={user > all ? 'up' : 'down'} /></div>
-        <div className="t-6 t-s-12">全站{formatSeconds(all)}</div>
-      </div>;
-    },
-  },
-  {
-    key: 'correct',
-    title: '错误率',
-    sort: true,
-    render: (text, record) => {
-      return <div className="sub">
-        <div className="t-2 t-s-12">{formatPercent(record.stat.userNumber - record.stat.userCorrect, record.stat.userNumber, false)}</div>
-        <div className="t-6 t-s-12">{record.stat.userNumber - record.stat.userCorrect}/{record.stat.userNumber}</div>
-      </div>;
-    },
-  },
-  {
-    key: 'latest_time',
-    title: '最近做题',
-    render: (text) => {
-      return <div className="sub">
-        <div className="t-2 t-s-12">{text.split(' ')[0]}</div>
-        <div className="t-6 t-s-12">{text.split(' ')[1]}</div>
-      </div>;
-    },
-  },
-  {
-    key: '',
-    title: '',
-    render: (text, record) => {
-      return <div><GIcon name="note" active={record.note} /></div>;
-    },
-  },
-];
-
 const exportType = [
   { key: 'question', title: '题目' },
   { key: 'official', title: '官方解析' },
@@ -113,6 +52,69 @@ export default class extends Page {
     };
   }
 
+  init() {
+    this.columns = [
+      {
+        key: 'question_type',
+        title: '题型',
+        render: (text, record) => {
+          return QuestionTypeMap[record.questionType];
+        },
+        fixSort: true,
+      },
+      {
+        key: 'title',
+        title: '题目ID',
+        fixSort: true,
+      },
+      {
+        key: 'description',
+        title: '内容',
+      },
+      {
+        key: 'time',
+        title: '耗时',
+        sort: true,
+        render: (text, record) => {
+          const user = record.stat.userTime / record.stat.userNumber;
+          const all = record.questionNo.totalTime / record.questionNo.totalNumber;
+          return <div className="sub">
+            <div className="t-2 t-s-12">{formatSeconds(user)}<Assets height={10} width={10} name={user > all ? 'up' : 'down'} /></div>
+            <div className="t-6 t-s-12">全站{formatSeconds(all)}</div>
+          </div>;
+        },
+      },
+      {
+        key: 'correct',
+        title: '错误率',
+        sort: true,
+        render: (text, record) => {
+          return <div className="sub">
+            <div className="t-2 t-s-12">{formatPercent(record.stat.userNumber - record.stat.userCorrect, record.stat.userNumber, false)}</div>
+            <div className="t-6 t-s-12">{record.stat.userNumber - record.stat.userCorrect}/{record.stat.userNumber}</div>
+          </div>;
+        },
+      },
+      {
+        key: 'latest_time',
+        title: '最近做题',
+        render: (text) => {
+          return <div className="sub">
+            <div className="t-2 t-s-12">{text.split(' ')[0]}</div>
+            <div className="t-6 t-s-12">{text.split(' ')[1]}</div>
+          </div>;
+        },
+      },
+      {
+        key: '',
+        title: '',
+        render: (text, record, index) => {
+          return <div><GIcon name="note" active={record.note} onClick={() => this.note(index)} /></div>;
+        },
+      },
+    ];
+  }
+
   initData() {
     const data = Object.assign(this.state, this.state.search);
     data.filterMap = this.state.search;
@@ -174,6 +176,16 @@ export default class extends Page {
     });
   }
 
+  note(index) {
+    const { list } = this.props;
+    const userQuestion = list[index];
+    const { questionNo } = userQuestion;
+    My.getQuestionNote(questionNo.id)
+      .then(result => {
+        this.setState({ questionNo, note: result || {}, showNote: true, index });
+      });
+  }
+
   onTabChange(tab) {
     const data = { tab };
     this.refreshQuery(data);
@@ -440,7 +452,7 @@ export default class extends Page {
         />
         <UserTable
           select
-          columns={columns}
+          columns={this.columns}
           sortMap={sortMap}
           data={list}
           current={page}
@@ -483,7 +495,7 @@ export default class extends Page {
   }
 
   renderModal() {
-    const { article = {}, showTips, showWarn, warn = {}, showClearConfirm, clearInfo = {}, showGroupConfirm, groupInfo = {}, showExportConfirm, showExportAuthConfirm, exportInfo = {}, showExportWait, showExamination, showVip, showReal } = this.state;
+    const { article = {}, showTips, showWarn, warn = {}, showClearConfirm, clearInfo = {}, showGroupConfirm, groupInfo = {}, showExportConfirm, showExportAuthConfirm, exportInfo = {}, showExportWait, showExamination, showVip, showReal, showNote, note = {}, questionNo = {}, list } = this.state;
     const { info } = this.props.user;
     return [
       <ArticleDetail show={this.state.showDetail} data={article} onClose={() => this.setState({ showDetail: false })} onPrev={() => this.prevArticle()} onNext={() => this.nextArticle()} />,
@@ -613,8 +625,18 @@ export default class extends Page {
         data={info}
         onReal={() => this.setState({ showVip: false, showReal: true })}
         onPrepare={() => this.setState({ showVip: false, showExamination: true })}
-        onClose={() => this.setState({ showVip: false })}
+        onClose={(result) => {
+          if (result) {
+            this.refresh();
+          } else {
+            this.setState({ showVip: false });
+          }
+        }}
       />,
+      <QuestionNoteModal show={showNote} defaultData={note} questionNo={questionNo} onConfirm={() => {
+        list[this.state.index].note = true;
+        this.setState({ showNote: false, list });
+      }} onCancel={() => this.setState({ showNote: false })} />,
     ];
   }
 }

+ 103 - 65
front/project/www/routes/my/error/page.js

@@ -7,7 +7,7 @@ import { timeRange, formatDate, getMap, formatSeconds, formatPercent } from '@sr
 import UserLayout from '../../../layouts/User';
 import UserTable from '../../../components/UserTable';
 import UserAction from '../../../components/UserAction';
-import { RealAuth } from '../../../components/OtherModal';
+import { RealAuth, QuestionNoteModal } from '../../../components/OtherModal';
 import Examination from '../../../components/Examination';
 import VipRenew from '../../../components/VipRenew';
 import menu, { refreshQuestionType, refreshStruct } from '../index';
@@ -22,67 +22,6 @@ import { User } from '../../../stores/user';
 
 const QuestionTypeMap = getMap(QuestionType, 'value', 'label');
 
-const columns = [
-  {
-    key: 'question_type',
-    title: '题型',
-    render: (text, record) => {
-      return QuestionTypeMap[record.questionType];
-    },
-    fixSort: true,
-  },
-  {
-    key: 'title',
-    title: '题目ID',
-    fixSort: true,
-  },
-  {
-    key: 'description',
-    title: '内容',
-  },
-  {
-    key: 'time',
-    title: '耗时',
-    sort: true,
-    render: (text, record) => {
-      const user = record.stat.userTime / record.stat.userNumber;
-      const all = record.questionNo.totalTime / record.questionNo.totalNumber;
-      return <div className="sub">
-        <div className="t-2 t-s-12">{formatSeconds(user)}<Assets height={10} width={10} name={user > all ? 'up' : 'down'} /></div>
-        <div className="t-6 t-s-12">全站{formatSeconds(all)}</div>
-      </div>;
-    },
-  },
-  {
-    key: 'correct',
-    title: '错误率',
-    sort: true,
-    render: (text, record) => {
-      return <div className="sub">
-        <div className="t-2 t-s-12">{formatPercent(record.stat.userNumber - record.stat.userCorrect, record.stat.userNumber, false)}</div>
-        <div className="t-6 t-s-12">{record.stat.userNumber - record.stat.userCorrect}/{record.stat.userNumber}</div>
-      </div>;
-    },
-  },
-  {
-    key: 'latest_time',
-    title: '最近做题',
-    render: (text) => {
-      return <div className="sub">
-        <div className="t-2 t-s-12">{text.split(' ')[0]}</div>
-        <div className="t-6 t-s-12">{text.split(' ')[1]}</div>
-      </div>;
-    },
-  },
-  {
-    key: '',
-    title: '',
-    render: (text, record) => {
-      return <div><GIcon name="star" active={record.collect} className="m-r-5" /><GIcon name="note" active={record.note} /></div>;
-    },
-  },
-];
-
 const exportType = [
   { key: 'question', title: '题目' },
   { key: 'official', title: '官方解析' },
@@ -110,6 +49,69 @@ export default class extends Page {
     };
   }
 
+  init() {
+    this.columns = [
+      {
+        key: 'question_type',
+        title: '题型',
+        render: (text, record) => {
+          return QuestionTypeMap[record.questionType];
+        },
+        fixSort: true,
+      },
+      {
+        key: 'title',
+        title: '题目ID',
+        fixSort: true,
+      },
+      {
+        key: 'description',
+        title: '内容',
+      },
+      {
+        key: 'time',
+        title: '耗时',
+        sort: true,
+        render: (text, record) => {
+          const user = record.stat.userTime / record.stat.userNumber;
+          const all = record.questionNo.totalTime / record.questionNo.totalNumber;
+          return <div className="sub">
+            <div className="t-2 t-s-12">{formatSeconds(user)}<Assets height={10} width={10} name={user > all ? 'up' : 'down'} /></div>
+            <div className="t-6 t-s-12">全站{formatSeconds(all)}</div>
+          </div>;
+        },
+      },
+      {
+        key: 'correct',
+        title: '错误率',
+        sort: true,
+        render: (text, record) => {
+          return <div className="sub">
+            <div className="t-2 t-s-12">{formatPercent(record.stat.userNumber - record.stat.userCorrect, record.stat.userNumber, false)}</div>
+            <div className="t-6 t-s-12">{record.stat.userNumber - record.stat.userCorrect}/{record.stat.userNumber}</div>
+          </div>;
+        },
+      },
+      {
+        key: 'latest_time',
+        title: '最近做题',
+        render: (text) => {
+          return <div className="sub">
+            <div className="t-2 t-s-12">{text.split(' ')[0]}</div>
+            <div className="t-6 t-s-12">{text.split(' ')[1]}</div>
+          </div>;
+        },
+      },
+      {
+        key: '',
+        title: '',
+        render: (text, record, index) => {
+          return <div><GIcon name="star" active={record.collect} className="m-r-5" onClick={() => this.toggleCollect(index)} /><GIcon name="note" active={record.note} onClick={() => this.note(index)} /></div>;
+        },
+      },
+    ];
+  }
+
   initData() {
     const data = Object.assign(this.state, this.state.search);
     data.filterMap = this.state.search;
@@ -161,6 +163,32 @@ export default class extends Page {
     });
   }
 
+  toggleCollect(index) {
+    const { list } = this.props;
+    const userQuestion = list[index];
+    if (!userQuestion.collect) {
+      My.addQuestionCollect(userQuestion.questionNo.id).then(() => {
+        userQuestion.collect = true;
+        this.setState({ list });
+      });
+    } else {
+      My.delQuestionCollect(userQuestion.questionNo.id).then(() => {
+        userQuestion.collect = false;
+        this.setState({ list });
+      });
+    }
+  }
+
+  note(index) {
+    const { list } = this.props;
+    const userQuestion = list[index];
+    const { questionNo } = userQuestion;
+    My.getQuestionNote(questionNo.id)
+      .then(result => {
+        this.setState({ questionNo, note: result || {}, showNote: true, index });
+      });
+  }
+
   onTabChange(tab) {
     const data = { tab };
     this.refreshQuery(data);
@@ -422,7 +450,7 @@ export default class extends Page {
         />
         <UserTable
           select
-          columns={columns}
+          columns={this.columns}
           sortMap={sortMap}
           data={list}
           current={page}
@@ -439,7 +467,7 @@ export default class extends Page {
   }
 
   renderModal() {
-    const { showTips, showWarn, warn = {}, showClearConfirm, clearInfo = {}, showGroupConfirm, groupInfo = {}, showExportConfirm, showExportAuthConfirm, exportInfo = {}, showExportWait, showExamination, showVip, showReal } = this.state;
+    const { showTips, showWarn, warn = {}, showClearConfirm, clearInfo = {}, showGroupConfirm, groupInfo = {}, showExportConfirm, showExportAuthConfirm, exportInfo = {}, showExportWait, showExamination, showVip, showReal, showNote, note = {}, questionNo = {}, list } = this.state;
     const { info } = this.props.user;
     return [
       <Modal show={showTips} title="操作提示" confirmText="好的,知道了" btnAlign="center" onConfirm={() => this.setState({ showTips: false })}>
@@ -557,8 +585,18 @@ export default class extends Page {
         data={info}
         onReal={() => this.setState({ showVip: false, showReal: true })}
         onPrepare={() => this.setState({ showVip: false, showExamination: true })}
-        onClose={() => this.setState({ showVip: false })}
+        onClose={(result) => {
+          if (result) {
+            this.refresh();
+          } else {
+            this.setState({ showVip: false });
+          }
+        }}
       />,
+      <QuestionNoteModal show={showNote} defaultData={note} questionNo={questionNo} onConfirm={() => {
+        list[this.state.index].note = true;
+        this.setState({ showNote: false, list });
+      }} onCancel={() => this.setState({ showNote: false })} />,
     ];
   }
 }

+ 7 - 1
front/project/www/routes/my/main/page.js

@@ -640,7 +640,13 @@ export default class extends Page {
           data={info}
           onReal={() => this.setState({ showVip: false, showReal: true })}
           onPrepare={() => this.setState({ showVip: false, showExamination: true })}
-          onClose={() => this.setState({ showVip: false })}
+          onClose={(result) => {
+            if (result) {
+              this.refresh();
+            } else {
+              this.setState({ showVip: false });
+            }
+          }}
         />
       </div>
     );

+ 7 - 1
front/project/www/routes/my/note/page.js

@@ -532,7 +532,13 @@ export default class extends Page {
         data={info}
         onReal={() => this.setState({ showVip: false, showReal: true })}
         onPrepare={() => this.setState({ showVip: false, showExamination: true })}
-        onClose={() => this.setState({ showVip: false })}
+        onClose={(result) => {
+          if (result) {
+            this.refresh();
+          } else {
+            this.setState({ showVip: false });
+          }
+        }}
       />,
     ];
   }

+ 7 - 1
front/project/www/routes/my/tools/page.js

@@ -435,7 +435,13 @@ export default class extends Page {
           data={info}
           onReal={() => this.setState({ showVip: false, showReal: true })}
           onPrepare={() => this.setState({ showVip: false, showExamination: true })}
-          onClose={() => this.setState({ showVip: false })}
+          onClose={(result) => {
+            if (result) {
+              this.refresh();
+            } else {
+              this.setState({ showVip: false });
+            }
+          }}
         />
       </div>
     );

+ 1 - 1
front/project/www/routes/page/ready/page.js

@@ -146,7 +146,7 @@ export default class extends Page {
         });
         this.categoryMap = getMap(result.category, 'id');
         const list = formatTreeData(result.category, 'id', 'title', 'parentId');
-        const readPlates = result.read.plates.map((row, index) => {
+        const readPlates = ((result.read || {}).plates || []).map((row, index) => {
           row.title = row.plate;
           row.key = `${index + 1}`;
           return row;

+ 45 - 23
front/project/www/routes/paper/question/detail/index.js

@@ -17,9 +17,11 @@ import AnswerList from '../../../../components/AnswerList';
 import AnswerButton from '../../../../components/AnswerButton';
 import AnswerTable from '../../../../components/AnswerTable';
 import OtherAnswer from '../../../../components/OtherAnswer';
+import { QuestionNoteModal } from '../../../../components/OtherModal';
 import { AskTarget } from '../../../../../Constant';
 import { Question } from '../../../../stores/question';
 import { My } from '../../../../stores/my';
+import { User } from '../../../../stores/user';
 import Sentence from '../../process/sentence';
 
 export default class extends Component {
@@ -51,11 +53,25 @@ export default class extends Component {
     });
   }
 
+  changeData(type, field, value) {
+    let { data, empty } = this.state;
+    data = data || {};
+    empty = empty || {};
+    data[type] = data[type] || {};
+    data[type][field] = value;
+    empty[type] = empty[type] || {};
+    if (value) empty[type][field] = !value;
+    this.setState({ data, empty });
+  }
+
   submitAsk() {
     const { userQuestion, questionNo = {} } = this.props;
     const { ask = {} } = this.state;
-    if (!ask.originContent || !ask.content || !ask.target) return;
-    My.addQuestionAsk(userQuestion.id, ask.target, questionNo.id, ask.originContent, ask.content).then(() => {
+    if (!ask.originContent || !ask.content || !ask.target) {
+      this.setState({ empty: { ask: { originContent: !ask.originContent, content: !ask.content, target: !ask.target } } });
+      return Promise.reject();
+    }
+    return My.addQuestionAsk(userQuestion.id, ask.target, questionNo.id, ask.originContent, ask.content).then(() => {
       this.setState({ askModal: false, askOkModal: true, ask: {} });
     }).catch(err => {
       this.setState({ askError: err.message, ask: {} });
@@ -65,8 +81,11 @@ export default class extends Component {
   submitFeedbackError() {
     const { questionNo = {} } = this.props;
     const { feedback = {} } = this.state;
-    if (!feedback.originContent || !feedback.content || !feedback.target) return;
-    My.addFeedbackErrorQuestion(
+    if (!feedback.originContent || !feedback.content || !feedback.target) {
+      this.setState({ empty: { feedback: { originContent: !feedback.originContent, content: !feedback.content, target: !feedback.target } } });
+      return Promise.reject();
+    }
+    return My.addFeedbackErrorQuestion(
       questionNo.id,
       questionNo.title,
       feedback.target,
@@ -314,7 +333,7 @@ export default class extends Component {
   }
 
   renderBase() {
-    const { questionStatus, userQuestion = {}, paper = {}, detail } = this.props;
+    const { questionStatus, userQuestion = {}, questionNo = {}, paper = {}, detail } = this.props;
     const { showIds } = this.state;
     return (
       <div
@@ -337,7 +356,7 @@ export default class extends Component {
             </Tooltip>
           </div>
           <div className="center">
-            <AnswerButton className="item" onClick={() => this.setState({ noteModal: true })}>
+            <AnswerButton className="item" onClick={() => User.needLogin().then(() => this.setState({ noteModal: true }))}>
               笔记
             </AnswerButton>
             {questionStatus >= 0 && (
@@ -345,7 +364,9 @@ export default class extends Component {
                 className="item"
                 onClick={() => {
                   if (questionStatus > 0) {
-                    this.setState({ askModal: true, ask: { target: AskTarget[0].value } });
+                    User.needLogin().then(() => {
+                      this.setState({ askModal: true, ask: { target: AskTarget[0].value } });
+                    });
                   } else {
                     this.setState({ askFailModal: true });
                   }
@@ -354,7 +375,7 @@ export default class extends Component {
                 提问
               </AnswerButton>
             )}
-            <AnswerButton className="item" onClick={() => this.setState({ feedbackModal: true, feedback: { position: AskTarget[0].value } })}>
+            <AnswerButton className="item" onClick={() => User.needLogin().then(() => this.setState({ feedbackModal: true, feedback: { position: AskTarget[0].value } }))}>
               纠错
             </AnswerButton>
           </div>
@@ -372,7 +393,8 @@ export default class extends Component {
         {this.state.askFailModal && this.renderAskFail()}
         {this.state.feedbackModal && this.renderFeedbackError()}
         {this.state.feedbackOkModal && this.renderFeedbackErrorOk()}
-        {this.state.noteModal && this.renderNote()}
+        {/* {this.state.noteModal && this.renderNote()} */}
+        <QuestionNoteModal show={this.state.noteModal} defaultData={this.state.note} questionNo={questionNo} onConfirm={() => this.setState({ noteModal: false })} onCancel={() => this.setState({ noteModal: false })} />
       </div>
     );
   }
@@ -623,7 +645,8 @@ export default class extends Component {
   }
 
   renderAsk() {
-    const { ask = {} } = this.state;
+    const { ask = {}, empty = {} } = this.state;
+    const emptyAsk = empty.ask || {};
     return (
       <div className="modal ask">
         <div className="mask" />
@@ -639,8 +662,7 @@ export default class extends Component {
                 value={ask.target}
                 list={AskTarget}
                 onChange={item => {
-                  ask.target = item.value;
-                  this.setState({ ask });
+                  this.changeData('ask', 'target', item.value);
                 }}
               />
               进行提问
@@ -650,9 +672,9 @@ export default class extends Component {
               className="textarea"
               value={ask.originContent}
               placeholder="请复制粘贴有疑问的内容。"
+              empty={emptyAsk.originContent}
               onChange={e => {
-                ask.originContent = e.target.value;
-                this.setState({ ask });
+                this.changeData('ask', 'originContent', e.target.value);
               }}
             />
             <div className="label">针对以上内容的问题是:</div>
@@ -660,9 +682,9 @@ export default class extends Component {
               className="textarea"
               value={ask.content}
               placeholder="提问频率高的问题会被优先回答哦。"
+              empty={emptyAsk.content}
               onChange={e => {
-                ask.content = e.target.value;
-                this.setState({ ask });
+                this.changeData('ask', 'content', e.target.value);
               }}
             />
           </div>
@@ -751,7 +773,8 @@ export default class extends Component {
   }
 
   renderFeedbackError() {
-    const { feedback = {} } = this.state;
+    const { feedback = {}, empty } = this.state;
+    const emptyFeedback = empty.feedback || {};
     return (
       <div className="modal error">
         <div className="mask" />
@@ -767,8 +790,7 @@ export default class extends Component {
                 value={feedback.target}
                 list={AskTarget}
                 onChange={item => {
-                  feedback.target = item.value;
-                  this.setState({ feedback });
+                  this.changeData('feedback', 'target', item.value);
                 }}
               />
               进行提问
@@ -778,9 +800,9 @@ export default class extends Component {
               className="textarea"
               value={feedback.originContent}
               placeholder="你可以适当扩大复制范围以使我们准确定位,感谢。"
+              empty={emptyFeedback.originContent}
               onChange={(e) => {
-                feedback.originContent = e.target.value;
-                this.setState({ feedback });
+                this.changeData('feedback', 'originContent', e.target.value);
               }}
             />
             <div className="label">应该改为:</div>
@@ -788,9 +810,9 @@ export default class extends Component {
               className="textarea"
               value={feedback.content}
               placeholder="只需提供正确内容即可"
+              empty={emptyFeedback.content}
               onChange={(e) => {
-                feedback.content = e.target.value;
-                this.setState({ feedback });
+                this.changeData('feedback', 'content', e.target.value);
               }} />
           </div>
           <div className="bottom">

+ 44 - 8
front/project/www/routes/paper/report/page.js

@@ -12,6 +12,8 @@ import { Question } from '../../../stores/question';
 import { Button } from '../../../components/Button';
 import Tabs from '../../../components/Tabs';
 import { Icon as GIcon } from '../../../components/Icon';
+import { QuestionNoteModal } from '../../../components/OtherModal';
+import { My } from '../../../stores/my';
 import {
   QuestionDifficult,
   ExaminationQuestionType,
@@ -620,6 +622,32 @@ export default class extends Page {
     this.setState({ order, list });
   }
 
+  toggleCollect(index) {
+    const { list } = this.props;
+    const userQuestion = list[index];
+    if (!userQuestion.collect) {
+      My.addQuestionCollect(userQuestion.questionNo.id).then(() => {
+        userQuestion.collect = true;
+        this.setState({ list });
+      });
+    } else {
+      My.delQuestionCollect(userQuestion.questionNo.id).then(() => {
+        userQuestion.collect = false;
+        this.setState({ list });
+      });
+    }
+  }
+
+  note(index) {
+    const { list } = this.props;
+    const userQuestion = list[index];
+    const { questionNo } = userQuestion;
+    My.getQuestionNote(questionNo.id)
+      .then(result => {
+        this.setState({ questionNo, note: result || {}, showNote: true, index });
+      });
+  }
+
   renderView() {
     const { report = {}, search = {} } = this.state;
     const { info } = search;
@@ -750,7 +778,7 @@ export default class extends Page {
   }
 
   renderSentenceQuestion() {
-    const { report, list, order } = this.state;
+    const { report, list, order, showNote, note = {}, questionNo = {} } = this.state;
     return <div className='sentence question'>
       <div className='header'>
         <div className='content'>
@@ -786,7 +814,7 @@ export default class extends Page {
               </tr>
             </thead>
             <tbody>
-              {(list || []).map(row => {
+              {(list || []).map((row, index) => {
                 return <tr>
                   <td>{row.no}</td>
                   <td>
@@ -796,14 +824,18 @@ export default class extends Page {
                   <td><GIcon name={row.detail.subject && row.detail.predicate && row.detail.object ? 'right' : 'error'} noHover /></td>
                   <td><GIcon name={row.detail.options ? 'right' : 'error'} noHover /></td>
                   <td>{formatMinuteSecond(row.userTime)}</td>
-                  <td><GIcon name='star' active={row.collect} noHover /></td>
-                  <td><GIcon name='note' active={row.note} noHover /></td>
+                  <td><GIcon name='star' active={row.collect} onClick={() => this.toggleCollect(index)} /></td>
+                  <td><GIcon name='note' active={row.note} onClick={() => this.note(index)} /></td>
                 </tr>;
               })}
             </tbody>
           </table>
         </div>
       </div>
+      <QuestionNoteModal show={showNote} defaultData={note} questionNo={questionNo} onConfirm={() => {
+        list[this.state.index].note = true;
+        this.setState({ showNote: false, list });
+      }} onCancel={() => this.setState({ showNote: false })} />
     </div>;
   }
 
@@ -869,7 +901,7 @@ export default class extends Page {
   }
 
   renderExerciseQuestion() {
-    const { report, list, order } = this.state;
+    const { report, list, order, showNote, note = {}, questionNo = {} } = this.state;
     return <div className='sentence question'>
       <div className='header'>
         <div className='content'>
@@ -908,7 +940,7 @@ export default class extends Page {
               </tr>
             </thead>
             <tbody>
-              {(list || []).map(row => {
+              {(list || []).map((row, index) => {
                 return <tr>
                   <td>{row.no}</td>
                   <td>
@@ -919,14 +951,18 @@ export default class extends Page {
                   <td>{row.question.difficult}</td>
                   <td>{formatMinuteSecond(row.userTime)}</td>
                   <td>{row.question.place}</td>
-                  <td><GIcon name='star' active={row.collect} noHover /></td>
-                  <td><GIcon name='note' active={row.note} noHover /></td>
+                  <td><GIcon name='star' active={row.collect} onClick={() => this.toggleCollect(index)} /></td>
+                  <td><GIcon name='note' active={row.note} onClick={() => this.note(index)} /></td>
                 </tr>;
               })}
             </tbody>
           </table>
         </div>
       </div>
+      <QuestionNoteModal show={showNote} defaultData={note} questionNo={questionNo} onConfirm={() => {
+        list[this.state.index].note = true;
+        this.setState({ showNote: false, list });
+      }} onCancel={() => this.setState({ showNote: false })} />
     </div>;
   }
 

+ 1 - 1
front/project/www/routes/question/detail/index.js

@@ -2,7 +2,7 @@ export default {
   path: '/question/detail/:id',
   key: 'question-detail',
   title: '题目详情',
-  needLogin: true,
+  needLogin: false,
   repeat: true,
   hideHeader: true,
   component() {

+ 19 - 1
front/project/www/routes/question/search/page.js

@@ -135,6 +135,24 @@ export default class extends Page {
     My.addSearchHistory(id);
   }
 
+  toggleCollect(index) {
+    const { list } = this.props;
+    const questionNo = list[index];
+    if (!questionNo.collect) {
+      My.addQuestionCollect(questionNo.id).then(() => {
+        questionNo.collect = true;
+        questionNo.collectNumber += 1;
+        this.setState({ list });
+      });
+    } else {
+      My.delQuestionCollect(questionNo.id).then(() => {
+        questionNo.collect = false;
+        questionNo.collectNumber -= 1;
+        this.setState({ list });
+      });
+    }
+  }
+
   renderView() {
     const { searchResult } = this.state;
     return (
@@ -357,7 +375,7 @@ class SearchItem extends Component {
             <span className="m-r-1">{data.question.difficult}</span>
             <span className="m-r-1">用时: {formatSeconds(data.totalTime / data.totalNumer)}</span>
             <span className="m-r-1">{formatPercent(data.totalCorrect, data.totalNumber, false)}</span>
-            <span>收藏 {data.collectNumber}</span>
+            <span>收藏 {data.collectNumber || 0}</span>
           </div>
         </div>
         <div className="t-1 p-20">{data.question.description}</div>

+ 8 - 0
front/project/www/stores/my.js

@@ -240,6 +240,14 @@ export default class MyStore extends BaseStore {
   }
 
   /**
+   * 获取题目笔记
+   * @param {*} questionNoId
+   */
+  getQuestionNote(questionNoId) {
+    return this.apiGet('/my/note/question', { questionNoId });
+  }
+
+  /**
    * 更新题目笔记
    * @param {*} questionNoId
    * @param {*} content

+ 11 - 13
front/project/www/stores/user.js

@@ -89,17 +89,15 @@ export default class UserStore extends BaseStore {
   }
 
   initAfter() {
-    if (this.getToken()) {
-      this.refreshToken().then(() => {
-        if (this.adminLogin) {
-          window.location.href = window.location.href.replace(`token=${this.adminLogin}`, '').replace('&&', '&');
-        }
-      }).catch(() => {
-        if (this.adminLogin) {
-          window.location.href = window.location.href.replace(`token=${this.adminLogin}`, '').replace('&&', '&');
-        }
-      });
-    }
+    this.refreshToken().then(() => {
+      if (this.adminLogin) {
+        window.location.href = window.location.href.replace(`token=${this.adminLogin}`, '').replace('&&', '&');
+      }
+    }).catch(() => {
+      if (this.adminLogin) {
+        window.location.href = window.location.href.replace(`token=${this.adminLogin}`, '').replace('&&', '&');
+      }
+    });
   }
 
   needPay(order) {
@@ -220,8 +218,8 @@ export default class UserStore extends BaseStore {
     });
   }
 
-  loginWechat(code, auto) {
-    return this.apiGet('/auth/wechat_pc', { code }).then(result => {
+  loginWechat(code, login, auto) {
+    return this.apiGet('/auth/wechat_pc', { code, login }).then(result => {
       this.infoHandle(result, auto);
       return result;
     });

+ 4 - 4
server/data/src/main/java/com/qxgmat/data/relation/mapping/UserCollectQuestionRelationMapper.xml

@@ -28,7 +28,7 @@
     from `user_collect_question` ucq
     left join `user_question` uq on uq.`question_id` = ucq.`question_id` and uq.`user_id`=#{userId,jdbcType=VARCHAR}
     left join `user_report` ur on ur.`id` = uq.`report_id`
-    left join `question` q on q.`id` = uq.`question_id`
+    left join `question` q on q.`id` = ucq.`question_id`
     and (q.`question_module` = 'base' or q.`question_module` = 'sentence')
     <if test="questionTypes != null">
       and
@@ -47,7 +47,7 @@
     left join `sentence_question` sq on sq.`question_id` = q.`id`
       and (q.`question_module` = 'sentence')
     where
-    q.`id` > 0 and uq.`id` > 0
+    q.`id` > 0
     <if test="keyword != null">
       and (q.`stem` like #{keywordLike,jdbcType=VARCHAR}
       or qn.`title` like #{keywordLike,jdbcType=VARCHAR}
@@ -85,7 +85,7 @@
     from `user_collect_question` ucq
     left join `user_question` uq on uq.`question_id` = ucq.`question_id` and uq.`user_id`=#{userId,jdbcType=VARCHAR}
     left join `user_report` ur on ur.`id` = uq.`report_id`
-    left join `question` q on q.`id` = uq.`question_id`
+    left join `question` q on q.`id` = ucq.`question_id`
     and (q.`question_module` = 'base' or q.`question_module` = 'textbook')
     <if test="questionTypes != null">
       and
@@ -110,7 +110,7 @@
         and tq.`year` = #{year,jdbcType=VARCHAR}
       </if>
     where
-    q.`id` > 0 and uq.`id` > 0
+    q.`id` > 0
     <if test="keyword != null">
       and (q.`stem` like #{keywordLike,jdbcType=VARCHAR}
       or qn.`title` like #{keywordLike,jdbcType=VARCHAR}

+ 4 - 3
server/gateway-api/src/main/java/com/qxgmat/controller/api/AuthController.java

@@ -141,10 +141,11 @@ public class AuthController {
     @ApiOperation(value = "直接微信二维码登录", httpMethod = "GET")
     public Response<MyDto> directWechatPc(
             @RequestParam(required = false, defaultValue = "") String code,
+            @RequestParam(required = false) boolean login,
             HttpSession session, HttpServletRequest request) {
         User user = (User) shiroHelp.getLoginUser();
         try{
-            if (user == null || user.getId() == null || user.getId()==0){
+            if (user == null || user.getId() == null || user.getId()==0 || login){
                 // 直接二维码登录
                 shiroHelp.getSession().login(shiroHelp.oauth(code, "wechat_pc", true));
             }else{
@@ -152,7 +153,7 @@ public class AuthController {
                 usersService.Oauth(user, code, "wechat_pc", true);
             }
         }catch (Exception e){
-            throw new ParameterException("登录失败");
+            throw new ParameterException("登录失败", e);
         }
         User openUser = (User) shiroHelp.getLoginUser();
         if (openUser.getId() != null && openUser.getId() > 0){
@@ -176,7 +177,7 @@ public class AuthController {
             // userInfo:true,第一次登录,尝试授权,等待绑定手机号
             shiroHelp.getSession().login(shiroHelp.oauth(code, "wechat_native", userInfo));
         }catch (Exception e){
-            throw new ParameterException("登录失败");
+            throw new ParameterException("登录失败",e);
         }
         User openUser = (User) shiroHelp.getLoginUser();
         if (openUser.getId() != null && openUser.getId() > 0){

+ 14 - 0
server/gateway-api/src/main/java/com/qxgmat/controller/api/MyController.java

@@ -1145,6 +1145,20 @@ public class MyController {
         return ResponseHelp.success(true);
     }
 
+    @RequestMapping(value = "/note/question", method = RequestMethod.GET)
+    @ApiOperation(value = "获取题目笔记", notes = "获取题目笔记", httpMethod = "GET")
+    public Response<UserNoteQuestionDetailDto> getNoteQuestion(int questionNoId)  {
+        User user = (User) shiroHelp.getLoginUser();
+        QuestionNo questionNo = questionNoService.get(questionNoId);
+        UserNoteQuestion note = userNoteQuestionService.getByUserAndQuestion(user.getId(), questionNo.getQuestionId());
+        if (note == null){
+            note = UserNoteQuestion.builder().build();
+        }
+        UserNoteQuestionDetailDto dto = Transform.convert(note, UserNoteQuestionDetailDto.class);
+
+        return ResponseHelp.success(dto);
+    }
+
     @RequestMapping(value = "/note/question", method = RequestMethod.PUT)
     @ApiOperation(value = "更新题目笔记", notes = "更新题目笔记", httpMethod = "PUT")
     public Response<Boolean> updateNoteQuestion(@RequestBody @Validated UserNoteQuestionDto dto)  {

+ 1 - 0
server/gateway-api/src/main/java/com/qxgmat/service/extend/MessageExtendService.java

@@ -366,6 +366,7 @@ public class MessageExtendService {
                     map.put("useExpireDays", String.valueOf(one.getUseExpireDays()));
                     switch(key){
                         case VIP:
+                            map.put("expireTime", getDate(one.getUseEndTime()));
                             send(user, MessageCategory.VIP_PAY, map, one.getId());
                             break;
                         case TEXTBOOK:

+ 2 - 0
server/gateway-api/src/main/java/com/qxgmat/service/extend/OrderFlowService.java

@@ -18,6 +18,7 @@ import com.qxgmat.service.UserServiceService;
 import com.qxgmat.service.UsersService;
 import com.qxgmat.service.annotation.*;
 import com.qxgmat.service.inline.*;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -761,6 +762,7 @@ public class OrderFlowService {
     @Transactional
     public boolean payed(Integer orderId, Integer userId, Long payId, Date payTime, PayMethod payMethod, String transactionNo){
         UserOrder userOrder = userOrderService.get(orderId);
+        System.out.println(orderId);
         if (userOrder == null) return false;
         if (userOrder.getPayStatus() > 0) return false;
         userOrderService.edit(UserOrder.builder()

+ 11 - 9
server/gateway-api/src/main/java/com/qxgmat/service/extend/TradeService.java

@@ -112,20 +112,21 @@ public class TradeService extends AbstractService {
         if(pay == null)
             throw new ParameterException("支付信息错误");
 
-        if(pay.getTradeStatus() == TradeStatus.SUCCESS.index
-                || pay.getTradeStatus() == TradeStatus.FINISH.index)
-            return pay;
+//        if(pay.getTradeStatus() == TradeStatus.SUCCESS.index
+//                || pay.getTradeStatus() == TradeStatus.FINISH.index)
+//            return pay;
 
         if(pay.getTradeStatus() == TradeStatus.CANCEL.index
                 || pay.getTradeStatus() == TradeStatus.CLOSE.index)
             throw new ParameterException("该支付无效");
 
-        Callback callback = payCallback.get(pay.getModule());
+        Callback callback = payCallback.get(PayModule.ValueOf(pay.getModule()));
         try {
             boolean r = callback.callback(pay);
             if (!r)
                 throw new SystemException("支付回调失败");
         }catch (Exception e){
+            e.printStackTrace();
             throw new SystemException("支付回调失败", e);
         }
         return pay;
@@ -179,12 +180,13 @@ public class TradeService extends AbstractService {
      */
     public String server(Pay pay, ResultInfo info) throws SystemException{
         PaySource paySource = getHandler(PayChannel.ValueOf(pay.getChannel()));
-        if(paySource.validTrade(info, payService.getInfo(pay))){
+        if(!paySource.validTrade(info, payService.getInfo(pay))){
             throw new SystemException(206, "支付校验错误");
         }
-        if(pay.getMoney().equals(info.getMoney())){
-            throw new SystemException(206, "支付金额错误");
-        }
+        // 微信支付返回小数点,校验存在问题
+//        if(!pay.getMoney().equals(info.getMoney())){
+//            throw new SystemException(206, "支付金额错误");
+//        }
         analyse(pay, paySource, info);
         if(payService.isPayed(pay)){
             payed(pay);
@@ -348,7 +350,7 @@ public class TradeService extends AbstractService {
      * @return
      */
     private String getNotifyUrl(PayChannel channel){
-        return payHelp.getNotifyUrl() + channel.key;
+        return payHelp.getNotifyUrl() + "/" + channel.key;
     }
 
     /**

+ 1 - 0
server/gateway-api/src/main/profile/dev/application-runtime.yml

@@ -86,6 +86,7 @@ spring:
 upload:
   local_path: ../upload/
   web_url: /upload/
+  water: /upload
 
 third:
   wechat:

+ 1 - 0
server/gateway-api/src/main/profile/prod/application-runtime.yml

@@ -86,6 +86,7 @@ spring:
 upload:
   local_path: ../upload/
   web_url: /upload/
+  water: /upload
 
 third:
   wechat:

+ 1 - 0
server/gateway-api/src/main/profile/test/application-runtime.yml

@@ -86,6 +86,7 @@ spring:
 upload:
   local_path: ../upload/
   web_url: /upload/
+  water: /upload
 
 third:
   wechat:

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 2 - 2
server/gateway-api/src/main/resources/application.yml


+ 9 - 5
server/tools/src/main/java/com/nuliji/tools/pay/Alipay.java

@@ -7,6 +7,7 @@ import com.alipay.api.AlipayConstants;
 import com.alipay.api.DefaultAlipayClient;
 import com.alipay.api.domain.AlipayTradeAppPayModel;
 import com.alipay.api.domain.AlipayTradePrecreateModel;
+import com.alipay.api.internal.util.AlipayLogger;
 import com.alipay.api.internal.util.AlipaySignature;
 import com.alipay.api.request.AlipayTradeAppPayRequest;
 import com.alipay.api.request.AlipayTradePrecreateRequest;
@@ -43,6 +44,7 @@ public class Alipay implements PaySource{
         this.appKey = appKey;
         this.appPublicKey = appPublicKey;
         logger.debug("alipay=>{},{}", appKey, appPublicKey);
+        AlipayLogger.setNeedEnableLogger(true);
         alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", appId, appKey, "json", "utf-8", appPublicKey, AlipayConstants.SIGN_TYPE_RSA2);
     }
     @Override
@@ -143,7 +145,7 @@ public class Alipay implements PaySource{
 
     @Override
     public boolean validTrade(ResultInfo info, PayInfo payInfo) {
-        if(info.getAppId() != payInfo.getAppId()) return false;
+        if(!info.getAppId().equals(payInfo.getAppId())) return false;
 //        if(info.getPid() != payInfo.getPid()) return false;
 
         return true;
@@ -186,9 +188,10 @@ public class Alipay implements PaySource{
 //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
         AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
         model.setBody(body);
+        model.setStoreId("web");
         model.setSubject(subject);
         model.setOutTradeNo(payNo);
-        model.setTimeoutExpress("30m");
+        model.setTimeoutExpress("5m");
         model.setTotalAmount(money.toString());
         model.setProductCode("FACE_TO_FACE_PAYMENT");
         request.setBizModel(model);
@@ -201,12 +204,13 @@ public class Alipay implements PaySource{
 
         try {
             //这里和普通的接口调用不同,使用的是sdkExecute
-            AlipayTradePrecreateResponse response = alipayClient.sdkExecute(request);
-//            System.out.println(response.getBody());//就是orderString 可以直接给客户端请求,无需再做处理。
-            payInfo.setRequest(response.getBody());
+            AlipayTradePrecreateResponse response = alipayClient.execute(request);
+            logger.debug("{}", response.getBody());
+            payInfo.setRequest(response.getQrCode());
             payInfo.setStatus("ok");
         } catch (AlipayApiException e) {
             e.printStackTrace();
+            logger.error("{}", e);
             payInfo.setStatus("fail");
             payInfo.setRequest(request);
         }

+ 3 - 1
server/tools/src/main/java/com/nuliji/tools/pay/WechatPay.java

@@ -47,7 +47,7 @@ public class WechatPay implements PaySource {
 
     @Override
     public ResultInfo notifyTrade(HttpServletRequest request) throws Exception {
-        InputStream is = request.getInputStream();
+//        InputStream is = request.getInputStream();
         BufferedReader br = request.getReader();
 
         String str;
@@ -113,6 +113,8 @@ public class WechatPay implements PaySource {
 
     @Override
     public boolean validTrade(ResultInfo info, PayInfo payInfo) {
+        logger.debug("appId: {}, {}", info.getAppId(), payInfo.getAppId());
+        logger.debug("pid: {}, {}", info.getPid(), payInfo.getPid());
         if(!info.getAppId().equals(payInfo.getAppId())) return false;
         if(!info.getPid().equals(payInfo.getPid())) return false;
 

+ 0 - 0
server/tools/src/main/java/com/tencent/protocol/pay_protocol/JsReqData.java


Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů