Ver código fonte

Merge branch '3.7' into debug

bding 2 meses atrás
pai
commit
b3092a1792

+ 1 - 1
src/Activity/ActivitySpecialInfo.tsx

@@ -55,7 +55,7 @@ const ActivitySpecialInfo: React.FC<IActivitySpecialInfo> = props => {
           content: (
             <div>
               <p>您已开启【专项调研】新活动通知</p>
-              <p>请关注【查研观向小助手】公众号,及时获取微信消息提醒</p>
+              <p>请关注【买方研选】公众号,及时获取微信消息提醒</p>
             </div>
           ),
           okText: '知道了',

+ 1 - 0
src/Column/Column.service.ts

@@ -38,6 +38,7 @@ export interface IDocsList {
   DocIcon?: string
 }
 export interface IColumnInfo {
+  SpecialLikeCount: number
   BgImg: string
   BgImgPc: string
   CollectNum: number

+ 3 - 1
src/Column/ColumnEditor.tsx

@@ -147,7 +147,7 @@ const ColumnEditor: React.FC<IColumnEditorProps> = props => {
           ? message.success(res.data.Msg)
           : Modal.success({
               title: '提醒',
-              content: '提交成功,审核结果将通过公众号消息提醒您,请留意[查研观向小助手]公众号',
+              content: '提交成功,审核结果将通过公众号消息提醒您,请留意[买方研选]公众号',
               okText: '知道了',
               centered: true
             })
@@ -478,6 +478,8 @@ const ColumnEditor: React.FC<IColumnEditorProps> = props => {
         <>
           <Prompt message="您有未保存的数据,确定离开本页面吗?" when={hasModify} />
           <Picture visible={!!bigImg} imgSrc={bigImg} onClose={handleToCloseBigImg} />
+          <div className="columnedit-prompt-text">请关注【买方研选】公众号,获取读者点赞留言提醒</div>
+
           <div className="columnedit-top">
             <strong>发布内容</strong>
             <div className="columnedit-select">

+ 3 - 1
src/Column/ColumnIndex.tsx

@@ -395,7 +395,9 @@ const ColumnIndex: React.FC<IColumnIndexProps> = props => {
                       showCollectionsFansModal('收藏')
                     }}
                   >
-                    <div className="columnindex-count">{columnInfo?.CollectNum || 0}</div>
+                    <div className="columnindex-count">
+                      {columnInfo?.CollectNum + columnInfo?.SpecialLikeCount || 0}
+                    </div>
                     <div className="columnindex-count-title">获赞与收藏</div>
                   </div>
                   <div

+ 4 - 3
src/Column/components/ColumnContentMessage.tsx

@@ -102,7 +102,7 @@ const ColumnContentMessage: React.FC<IColumnCenterProps> = props => {
             setInputShow(true)
           }}
         >
-          留言会私信给作者,作者设置留言公开后将在文章下展示
+          请写下您的留言
         </div>
       ) : (
         <div style={{ marginTop: 20, marginBottom: 20 }}>
@@ -112,6 +112,7 @@ const ColumnContentMessage: React.FC<IColumnCenterProps> = props => {
             required
             value={messageContent}
             onChange={handleChangeMessage}
+            autoFocus
           />
           <div className={styles['columndetail-messge-ipt-btn']}>
             <span
@@ -135,7 +136,7 @@ const ColumnContentMessage: React.FC<IColumnCenterProps> = props => {
             <div className={styles['item-img-btn']}>
               <div>
                 <img src={item.Headimgurl} />
-                <span>{item.CreateTime}</span>
+                <span style={{ color: '#999999' }}>{item.CreateTime}</span>
               </div>
               <div>
                 {item.Status === 0 ? (
@@ -164,7 +165,7 @@ const ColumnContentMessage: React.FC<IColumnCenterProps> = props => {
                   <div className={styles['child-item-img-btn']}>
                     <div>
                       <img src={child.Headimgurl} />
-                      <span>{child.CreateTime}</span>
+                      <span style={{ color: '#999999' }}>{child.CreateTime}</span>
                     </div>
                     <>
                       <div>

+ 2 - 1
src/Column/components/ColumnFansModal.tsx

@@ -20,7 +20,7 @@ interface IColumnAuthorFansData {
 /**研选专栏 */
 const ColumnFansModal: React.FC<IColumnCenterProps> = props => {
   const { open, onClose } = props
-  const pageSize = 9
+  const pageSize = 10
   const customData = {
     emptyText: '暂时没有粉丝'
   }
@@ -57,6 +57,7 @@ const ColumnFansModal: React.FC<IColumnCenterProps> = props => {
   return (
     <Modal title="粉丝列表" open={open} onCancel={handleOnClose} footer={null}>
       <InfiniteScroll
+        height={300}
         dataLength={listData?.length || 0}
         next={handleGetMore}
         hasMore={hasMore}

+ 10 - 5
src/Column/components/ColumnMessage.tsx

@@ -70,12 +70,15 @@ const ColumnMessage: React.FC<IColumnCenterProps> = props => {
 
   // 设置共开的按钮点击事件
   const setupClickHandler = () => {
-    postMessagePublic(selectCheckbox, 1)
+    if (selectCheckbox.length) {
+      postMessagePublic(selectCheckbox, 1)
+    }
   }
 
   // 留言的确定事件
   const handleFinish = (value: { Content: string }) => {
     applyCheckColumnNote(replyItemID, value.Content, replyParentId)
+    handleOnModalClose()
   }
   // 留言的取消事件
   const handleOnModalClose = () => {
@@ -209,7 +212,7 @@ const ColumnMessage: React.FC<IColumnCenterProps> = props => {
               <div key={item.MessageId} style={{ marginBottom: 30 }} className="columncenter-content-messgae">
                 <div className="columncenter-content-disclosure"> {item.Content}</div>
                 <div className="columncenter-content-img-time">
-                  <span> {item.RealName}</span>
+                  <img src={item.Headimgurl} alt="" />
                   <span style={{ marginLeft: 10 }}> {item.CreateTime}</span>
                 </div>
                 <div className="columncenter-content-item-title">
@@ -225,15 +228,17 @@ const ColumnMessage: React.FC<IColumnCenterProps> = props => {
                       className="columncenter-content-btn"
                       onClick={() => cancelSelectionHandler(item)}
                     >
-                      取消精选
+                      取消公开
                     </span>
                   </div>
                 </div>
                 {item.ChildList.length > 0 &&
                   item.ChildList.map(child => (
                     <div key={child.MessageId} style={{ marginLeft: 20 }}>
-                      <div className="columncenter-content-disclosure"> {child.Content}</div>
-                      {child.CreateTime}
+                      <div className="columncenter-content-disclosure">
+                        <img src={child.Headimgurl} alt="" /> {child.Content}
+                      </div>
+                      <span>{child.CreateTime}</span>
                     </div>
                   ))}
               </div>

+ 9 - 2
src/Column/components/LikesCollections.tsx

@@ -1,5 +1,6 @@
 import React, { useEffect, useState } from 'react'
 import useRequest from '@ahooksjs/use-request/es'
+import { LikeOutlined, StarOutlined } from '@ant-design/icons'
 
 import { Modal } from 'antd'
 
@@ -18,8 +19,14 @@ const LikesCollections: React.FC<IColumnCenterProps> = props => {
   }
   return (
     <Modal title="获赞与收藏" open={open} onCancel={handleOnClose} footer={null}>
-      <div>当前获得点赞数 {columnInfoFrom?.CollectNum}</div>
-      <div>当前获得收藏数 {columnInfoFrom?.SpecialLikeCount}</div>
+      <div style={{ margin: '20px 0' }}>
+        <LikeOutlined style={{ marginRight: 10, color: '#666666' }} />
+        当前获得点赞数&nbsp;&nbsp; <span style={{ color: '#faa12f' }}>{columnInfoFrom?.SpecialLikeCount}</span>
+      </div>
+      <div>
+        <StarOutlined style={{ marginRight: 10, color: '#666666' }} />
+        当前获得收藏数&nbsp;&nbsp; <span style={{ color: '#faa12f' }}>{columnInfoFrom?.CollectNum}</span>
+      </div>
     </Modal>
   )
 }

+ 6 - 0
src/Column/css/ColumnEditor.module.scss

@@ -5,6 +5,12 @@
   background: #ffffff;
   padding: 0 20px;
   :global {
+    .columnedit-prompt-text {
+      padding-top: 20px;
+      color: #F1A84A;
+      font-size: 16px;
+      text-decoration: underline;
+    }
     .columnedit-top {
       padding: 20px 0;
       border-bottom: 1px solid #f0f1f3;

+ 13 - 0
src/Column/css/ColumnIndex.module.scss

@@ -306,8 +306,16 @@
         margin-bottom: 10px;
       }
       .columncenter-content-disclosure {
+        display: flex;
+        align-items: center;
         font-weight: 600;
         margin: 10px 0;
+        img {
+          display: block;
+          margin-right: 8px;
+          width: 20px;
+          height: 20px;
+        }
       }
       .columncenter-operate-btn {
         width: 87px;
@@ -348,9 +356,14 @@
         justify-content: space-between;
         align-items: center;
         .item-title {
+          flex: 1;
           font-size: 14px;
           color: #F1A84A;
+          padding-right: 10px;
           cursor: pointer;
+          overflow: hidden;
+          text-overflow: ellipsis;
+          white-space: nowrap;
         }
       }
       .columncenter-content-child {

+ 7 - 2
src/Column/css/ColumnMessage.module.scss

@@ -1,7 +1,7 @@
 .columndetail-messge-select-ipt {
   margin-top: 20px;
   width: 100%;
-  height: 97px;
+  height: 57px;
   padding: 10px 20px;
   border-radius: 3px;
   background-color: #f0f1f3;
@@ -99,7 +99,12 @@
 .columndetail-messge-content {
   margin: 10px 0;
 }
-
+.message-fans-box {
+  height: 300px;
+  width: 100%;
+  overflow: hidden;
+  overflow-x: auto;
+}
 .message-fans-content {
   display: flex;
   align-items: center;

+ 2 - 0
src/Login2p/Login2pContext.tsx

@@ -153,6 +153,8 @@ const Login2pProvider: React.FC<ContextProviderProps> = ({ children }: ContextPr
         setUserInfo(data.data.Data)
         loginEnd(data.data.Data?.Authorization, next)
       }
+    } else {
+      message.error(data.data.Msg)
     }
   }
   const { run: getUserDetail, loading: getUserDetailLoading } = useRequest(() => Login2pService.getUserDetail(jwt), {

+ 98 - 0
src/Material/Material.service.ts

@@ -1,5 +1,6 @@
 import NewAxiosInstanceFunc from '../Service/NewAxiosInstance'
 import { INewResponse } from '../Service/INewResponse'
+
 import { IItemType } from './components/Item.component'
 import { IIndepthArticleItem } from 'Indepth/Indepth.service'
 export const visitorToken =
@@ -98,6 +99,7 @@ export interface IGetListBySearchItem {
   Pv: number
 }
 export interface IArcticleDetail {
+  ChartPermissionName: string //是否是固收
   Abstract: string // 摘要
   Annotation: string // 核心观点
   ArticleId: number
@@ -215,7 +217,97 @@ export enum EOrderStatus {
   Payed = 2, // 2:已支付
   Refund = 3 // 3:已退款
 }
+export interface IArticleInfoExpand extends IArticleInfo {
+  type: IArticleType
+  industry: IArticleIndustry
+  corpus: { tree: string } | null
+  field?: IArticleField
+  series?: IArticleSeries
+  author: IArticleAuthor
+  co_author?: IArticleAuthor[]
+  truncate?: number
+}
+export interface ISelect {
+  id: number
+  name: string
+  description?: string
+}
+export interface IArticleAuthor {
+  name?: string
+  phone_number?: string
+}
+export interface IArticleIndustry {
+  id: number
+  name: string
+  description: string
+  field: IArticleField[]
+  series: IArticleSeries[]
+}
 
+export interface IArticleSeries extends ISelect {
+  id: number
+  name: string
+  description: string
+  industry_id?: number
+}
+export interface IArticleField extends ISelect {
+  id: number
+  name: string
+  description: string
+  count?: number
+}
+export interface IArticleContent {
+  id: number
+  abstract: string
+  annotation: string
+  body: string
+  auto_save: string | null
+}
+
+export interface IArticleType extends ISelect {
+  id: number
+  name: string
+  description: string
+  count?: number
+}
+export interface IArticleInfo {
+  id: number
+  title: string
+  title_en: string
+  frequency: string
+  publish_date: Date
+  author_phone_number: number
+  cover: string
+  industry_id: number
+  field_id: number
+  series_id: number
+  type_id: number
+  is_focused: number
+  stock: string[]
+  content: IArticleContent
+  publish_status: number
+  publish_area: PublishArea
+  create_date: Date
+  update_date: Date
+  is_active: boolean
+}
+export enum PublishArea {
+  MAINLAND = 'mainland',
+  HK = 'hk',
+  ALL = 'all'
+}
+export interface IArticleContent {
+  id: number
+  abstract: string
+  annotation: string
+  body: string
+  auto_save: string | null
+}
+
+export interface IVmpDetails {
+  code: number
+  data: IArticleInfoExpand
+}
 export const MaterialService = {
   getHomeList: (params: IGetHomeListParams): INewResponse<IGetHomeListRes> =>
     NewAxiosInstanceFunc({
@@ -251,6 +343,12 @@ export const MaterialService = {
       method: 'get',
       params: { ArticleId }
     }),
+  getVmpDetails: (ArticleId: number): INewResponse<IVmpDetails> =>
+    NewAxiosInstanceFunc({
+      url: `/article/detail_vmp`,
+      method: 'get',
+      params: { ArticleId }
+    }),
   getResearchIntroduce: (): INewResponse<{ List: IIntroduceItem[] }> =>
     NewAxiosInstanceFunc({
       url: `/config/research/introduce`,

+ 16 - 4
src/Material/MaterialInfo.tsx

@@ -42,6 +42,8 @@ const MaterialInfo: React.FC<IMaterialInfoProps> = props => {
     manual: true,
     formatResult: response => response.data.Data,
     onSuccess: res => {
+      res?.Detail.ChartPermissionName === '固收' &&
+        (res.Detail.Body = setDetailToken(res.Detail.Body, res.Detail.VmpAuthorization))
       res?.Detail && setWxShare(res?.Detail.Title, res.Detail.Abstract.replace(/<[^>]+>/g, ''), res?.Detail.ShareImg)
       res?.Detail?.IsSpecialArticle
         ? setSpecialType(ISpecialType.SpecialArticle)
@@ -49,6 +51,15 @@ const MaterialInfo: React.FC<IMaterialInfoProps> = props => {
     }
   })
 
+  // 同步弘则固收后处理iframe后面拼接token
+  const setDetailToken = (body: string, token: string) => {
+    const updatedRichText = body.replace(
+      /<iframe\s+src="([^"]*\/display\/(\d+))"([^>]*)><\/iframe>/g,
+      `<iframe src="$1?token=${token}"$3></iframe>`
+    )
+    return updatedRichText
+  }
+
   // 收藏/取消收藏
   const { run: applyCollect } = useRequest(MaterialService.postActicleCollect, {
     manual: true,
@@ -112,16 +123,17 @@ const MaterialInfo: React.FC<IMaterialInfoProps> = props => {
     })
   }
   const handleToRefresh = () => {
-    console.log('有没有触发')
-
-    // refreshArcticleDetail()
+    refreshArcticleDetail()
   }
   return (
     <Spin spinning={infoLoading}>
       <AskAdd visible={visibleAsk} ID={props.articleID} onApply={handleApplyComment} onCloseModel={handleOkAsk} />
       <ValidateEmpty loading={infoLoading} data={data}>
         <div className={`${media.isSmallMax ? styles['research-container-moblie'] : styles['art-white-bg']}`}>
-          {login2p.jwt && data?.HasPermission && data?.HasPermission === INewPermissionType.OK ? (
+          {login2p.jwt &&
+          data?.HasPermission &&
+          data?.HasPermission === INewPermissionType.OK &&
+          data?.Detail.ChartPermissionName !== '固收' ? (
             <div className={styles['material-info-option']}>
               <span className="material-option-item" onClick={() => setVisibleAsk(true)}>
                 <img src={CommentFillSvg} alt="icon" className="option-icon" />

+ 4 - 1
src/Material/components/ArticleCard.tsx

@@ -35,7 +35,10 @@ const ArticleCard: React.FC<IArticleCard> = props => {
           dangerouslySetInnerHTML={{
             __html: item?.IsResearch
               ? `${formatLabel(item.LabelKeywordImgLink)}<span>${title || item?.Title}</span>`
-              : title || item?.Title
+              : `<img src=${
+                  item.LabelKeywordImgLink || 'https://hzstatic.hzinsights.com/cygx_web/config/gushou.png'
+                } alt="标签" class="mfyx-label-img" /><span>${title || item?.Title}</span>`
+            // title || item?.Title
           }}
         />
       </div>

+ 32 - 5
src/Material/components/Research.container.tsx

@@ -1,13 +1,13 @@
-import React, { useEffect } from 'react'
+import React, { useEffect, useState } from 'react'
 import { Link } from 'react-router-dom'
 import useRequest from '@ahooksjs/use-request'
 import { useHistory } from 'react-router-dom'
 import dayjs from 'dayjs'
 
-import { Affix, Breadcrumb, Col, Divider, Row, Timeline, Typography, Watermark } from 'antd'
+import { Affix, Breadcrumb, Col, Divider, Row, Timeline, Typography, Watermark, Tag } from 'antd'
 
 import { VmpSeverError } from 'components/Empty'
-import { MaterialService, IArcticleInfo, IArcticleHotListItem } from '../Material.service'
+import { MaterialService, IArcticleInfo, IArcticleHotListItem, IArticleInfoExpand } from '../Material.service'
 import { useMedia } from 'Context/Media/MediaContext'
 import { useLogin2p } from 'Login2p/Login2pContext'
 import styles from '../css/MaterialInfo.module.scss'
@@ -22,7 +22,7 @@ type ResearchContainerProps = {
 const ResearchContainer: React.FC<ResearchContainerProps> = props => {
   const { info, handleToRefresh } = props
   // const [showDisclaimers, setShowDisclaimers] = useState(false)
-
+  const [articleInfo, setArticleInfo] = useState<IArticleInfoExpand>()
   const { data: hotList, run } = useRequest(MaterialService.getArcticleHotList, {
     manual: true,
     formatResult: response => response.data.Data?.List
@@ -34,9 +34,20 @@ const ResearchContainer: React.FC<ResearchContainerProps> = props => {
   const inlineStyleConfig = {
     titleLevel: media.isSmallMax ? 4 : 2
   }
+  const { run: getVmpGSDetails } = useRequest(MaterialService.getVmpDetails, {
+    manual: true,
+
+    onSuccess: res => {
+      const { data } = res.data.Data
+      setArticleInfo(data)
+    }
+  })
 
   useEffect(() => {
     run(info.Detail.ArticleId)
+    if (info.Detail.ChartPermissionName === '固收') {
+      getVmpGSDetails(info.Detail.ArticleId)
+    }
     // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [])
 
@@ -95,6 +106,21 @@ const ResearchContainer: React.FC<ResearchContainerProps> = props => {
               <div className="gray-text fz12">{dayjs(info.Detail.PublishDate).format('YYYY-MM-DD HH:mm')}</div>
             </div>
           </div>
+          {articleInfo && info?.HasPermission === INewPermissionType.OK && (
+            <p>
+              {articleInfo.industry ? <Tag color="blue">{articleInfo.industry?.name}</Tag> : <></>}
+              {articleInfo.field ? <Tag color="red">{articleInfo.field?.name}</Tag> : <></>}
+              {articleInfo.type ? <Tag color="purple">{articleInfo.type.name}</Tag> : <></>}
+              {articleInfo.frequency ? <Tag color="green">{articleInfo.frequency}</Tag> : <></>}
+              {articleInfo.series ? <Tag color="volcano">{articleInfo.series.name}</Tag> : <></>}
+              {articleInfo.stock?.length > 0 &&
+                articleInfo.stock?.map((item, index) => (
+                  <Tag color="cyan" key={`stock-${index}`}>
+                    {item}
+                  </Tag>
+                ))}
+            </p>
+          )}
           <Row gutter={24}>
             <Col
               xs={{ span: 24, offset: 0 }}
@@ -120,7 +146,8 @@ const ResearchContainer: React.FC<ResearchContainerProps> = props => {
                 )}
                 {
                   // annotation 可能能null
-                  info.Detail.Annotation?.replace('<p><br></p>', '') ? (
+                  info.Detail.Annotation?.replace('<p><br></p>', '') &&
+                  info?.HasPermission === INewPermissionType.OK ? (
                     <>
                       <Typography.Paragraph>
                         <Typography.Text style={{ fontSize: 20 }} italic strong>