• 10 专题模块


    专题部分

    投稿记录功能

    article/models.py

    修改后的模型类: 外键关联表加related_name,方便查询

    from django.db import models
    from renranapi.utils.models import BaseModel
    from users.models import User
    # create your models here.
    class ArticleCollection(BaseModel):
        """文集模型"""
        name = models.CharField(max_length=200, verbose_name="文章标题")
        user = models.ForeignKey(User, on_delete=models.DO_NOTHING, verbose_name="用户")
        class Meta:
            db_table = "rr_article_collection"
            verbose_name = "文集"
            verbose_name_plural = verbose_name
    
        def __str__(self):
            return self.name
    
    class Special(BaseModel):
        """专题模型"""
        name = models.CharField(max_length=200, verbose_name="标题")
        image = models.ImageField(null=True, blank=True, verbose_name="封面图片")
        notice = models.TextField(null=True, blank=True, verbose_name="专题公告")
        article_count = models.IntegerField(default=0, null=True, blank=True, verbose_name="文章总数")
        follow_count = models.IntegerField(default=0, null=True, blank=True, verbose_name="关注量")
        collect_count = models.IntegerField(default=0, null=True, blank=True, verbose_name="收藏量")
        user = models.ForeignKey(User, on_delete=models.DO_NOTHING, verbose_name="创建人")
        class Meta:
            db_table = "rr_special"
            verbose_name = "专题"
            verbose_name_plural = verbose_name
    
        def __str__(self):
            return self.name
    
    
    class Article(BaseModel):
        """文章模型"""
        title = models.CharField(max_length=200, verbose_name="文章标题")
        content = models.TextField(null=True, blank=True, verbose_name="文章内容")
        render = models.TextField(null=True,blank=True,verbose_name='文章内容(解析后)')
        user = models.ForeignKey(User, on_delete=models.DO_NOTHING, verbose_name="用户")
        collection = models.ForeignKey(ArticleCollection, on_delete=models.CASCADE, verbose_name="文集")
        pub_date = models.DateTimeField(null=True, default=None, verbose_name="发布时间")
        access_pwd = models.CharField(max_length=15,null=True, blank=True, verbose_name="访问密码")
        read_count = models.IntegerField(default=0, null=True, blank=True, verbose_name="阅读量")
        like_count = models.IntegerField(default=0, null=True, blank=True, verbose_name="点赞量")
        collect_count = models.IntegerField(default=0, null=True, blank=True, verbose_name="收藏量")
        comment_count = models.IntegerField(default=0, null=True, blank=True, verbose_name="评论量")
        reward_count = models.IntegerField(default=0, null=True, blank=True, verbose_name="赞赏量")
        is_public = models.BooleanField(default=False, verbose_name="是否公开")
        class Meta:
            db_table = "rr_article"
            verbose_name = "文章"
            verbose_name_plural = verbose_name
    
    
    class SpecialArticle(BaseModel):
        """文章和专题的绑定关系"""
        article = models.ForeignKey(Article,related_name='article_special',on_delete=models.CASCADE, verbose_name="文章")
        special = models.ForeignKey(Special,related_name='special_article', on_delete=models.CASCADE, verbose_name="专题")
    
        class Meta:
            db_table = "rr_special_article"
            verbose_name = "专题的文章"
            verbose_name_plural = verbose_name
    
    
    class SpecialManager(BaseModel):
        """专题管理员"""
        user = models.ForeignKey(User, related_name='user_special', on_delete=models.DO_NOTHING, verbose_name="管理员")
        special = models.ForeignKey(Special, related_name='special_user',on_delete=models.CASCADE, verbose_name="专题")
    
        class Meta:
            db_table = "rr_special_manager"
            verbose_name = "专题的管理员"
            verbose_name_plural = verbose_name
    
    
    class SpecialFocus(BaseModel):
        """专题关注"""
        user = models.ForeignKey(User, related_name='focus_special', on_delete=models.DO_NOTHING, verbose_name="管理员")
        special = models.ForeignKey(Special, related_name='special_focus', on_delete=models.CASCADE, verbose_name="专题")
    
        class Meta:
            db_table = "rr_special_focus"
            verbose_name = "专题的关注"
            verbose_name_plural = verbose_name
    
    
    class SpecialCollection(BaseModel):
        """专题收藏"""
        user = models.ForeignKey(User,related_name='shoucang_special',  on_delete=models.DO_NOTHING, verbose_name="人员")
        special = models.ForeignKey(Special,related_name='special_shoucang',  on_delete=models.CASCADE, verbose_name="专题")
    
        class Meta:
            db_table = "rr_special_collection"
            verbose_name = "专题收藏"
            verbose_name_plural = verbose_name
    
    
    class ArticleImage(BaseModel):
        """文章图片"""
        group = models.CharField(max_length=15,null=True, blank=True, verbose_name="组名")
        image = models.ImageField(null=True, blank=True, verbose_name="图片地址")
        # user = models.IntegerField(null=True, blank=True, verbose_name="上传图片的用户") #可以设置这么一个字段先,表示哪个用户上传的图片
    
        class Meta:
            db_table = "rr_article_image"
            verbose_name = "文章图片"
            verbose_name_plural = verbose_name
    
    
    
    

    1.创建文章投稿记录模型

    article/models.py

    class ArticlePostLog(BaseModel):
        """文章的投稿记录"""
        POST_STATUS = (
            (0,"未审核"),
            (1,"审核通过"),
            (2,"审核未通过"),
        )
        user = models.ForeignKey(User, on_delete=models.DO_NOTHING, verbose_name="投稿人")
        special = models.ForeignKey(Special, on_delete=models.CASCADE, verbose_name="专题")
        article = models.ForeignKey(Article, on_delete=models.CASCADE, verbose_name="文章")
        status = models.IntegerField(choices=POST_STATUS, default=0, verbose_name="审核状态")
        manager = models.IntegerField(default=None, null=True,blank=True, verbose_name="审核人")
        post_time = models.DateTimeField(default=None, null=True,blank=True, verbose_name="审核时间")
    
        class Meta:
            db_table = "rr_article_post"
            verbose_name = "文章的投稿记录"
            verbose_name_plural = verbose_name
    

    数据迁移

    python manage.py makemigrations
    python manage.py migrate
    

    创建专题的测试数据, 把专题相关模型注册到adminx.py文件, 后台添加测试数据

    2.展示专题和当前文章收录状态

    后端接口

    路由:article/urls.py

    path('special/list/',views.SpecialListView.as_view()),
    path('recommend_special/list/',views.RecommendSpecialListView.as_view()),
    

    视图:article/views.py

    # 展示我的专题列表
    class SpecialListView(APIView):
        permission_classes = [IsAuthenticated]
    
        def get(self,request):
            article_id = request.query_params.get('article_id')
            queryset = models.Special.objects.filter(user_id=self.request.user.id, is_show=True, is_delete=False)
            # 通过专题,将专题的文章查询出来,与当前文章进行对比,如果有,证明该专题已收录文章
            data = []
            for obj in queryset:
                # 反向查询 -- 根据专题查文章
                article_id_list = [i.get('article_id') for i in obj.special_article.all().values('article_id')]
                if int(article_id) in article_id_list:
                    data.append({
                        'id':obj.id,
                        'name':obj.name,
                        'image':obj.image.url,
                        'is_shoulu':True,
                    })
                else:
                    data.append({
                        'id': obj.id,
                        'name': obj.name,
                        'image': obj.image.url,
                        'is_shoulu': False,
                    })
    
            return Response({'data':data})
    
    # 展示推荐专题列表(找关注量前10的专题)
    class RecommendSpecialListView(ListAPIView):
        permission_classes = [IsAuthenticated]
        serializer_class = RecommendSpecialModelSerializer
        count = models.Special.objects.filter(is_show=True,is_delete=False).count()
        if count <= 10:
            queryset = models.Special.objects.filter(is_show=True,is_delete=False).order_by('-follow_count')[:count]
        else:
            queryset = models.Special.objects.filter(is_show=True, is_delete=False).order_by('-follow_count')[:10]
    
    

    序列化器:article/serializers.py

    # 推荐专题列表
    class RecommendSpecialModelSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.Special
            fields = ['id','name','image','article_count','follow_count']
    
    

    前端页面

    前端指定路由,routers/index.js

    import Vue from 'vue'
    
    import PostArticle from "@/components/PostArticle";
    Vue.use(Router);
    
    export default new Router({
      mode: "history",
      routes: [
        { //专题模块
          path: '/postarticle',
          name: 'PostArticle',
          component: PostArticle
        },
      ]
    })
    
    

    客户端实现发布文章以后的投稿页面 -- PostArticle.vue

    <template>
        <div id="writed">
          <div class="_3PLTX">
            <div class="_2Mx1k">
              <div class="_3CoyQ">
                <router-link :to="`/article/${article_id}`" class="_2-ZiM">{{article_title}}</router-link>
                <br>
                <router-link :to="`/article/${article_id}`" class="_2ajaT">发布成功,点击查看文章</router-link>
              </div>
              <ul class="zelSB">
                <li class="_35P4c"><i class="fa fa-weibo"></i>微博</li>
                <li class="_1c1Eo"><i class="fa fa-wechat"></i>微信</li>
                <li class="_1HWk1"><i class="fa fa-link"></i>复制链接</li>
                <li class="_3FrjS _3Qjz6 _2_WAp _2po2r cRfUr" title="">
                  <span class="">更多分享</span>
                </li>
              </ul>
            </div>
            <div class="_3Q2EW" @click="$router.back()">×</div>
            <div class="_1s967"></div>
            <div class="_2w_E5">
              <div class="_23R_O">
                <div class="_1WCUC">
                  <i class="fa fa-search fa-2x"></i><input type="text" placeholder="搜索专题">
                </div>
                <div class="_3dZoJ">向专题投稿,让文章被更多人发现</div>
              </div>
              <div>
                <div class="_18jMg">
                  <h3>我管理的专题<a href="">新建</a></h3>
                  <ul class="_1hEmG">
                    <li v-for="(my_special_value,my_special_index) in my_special_list" :key="my_special_index">
                      <a>收录</a>
                      <img alt="png" :src="my_special_value.image">
                      <span class="_1CN24" :title="my_special_value.name">{{my_special_value.name}}</span>
                    </li>
                  </ul>
                </div>
                <div class="_18jMg">
                  <h3>推荐专题</h3>
                  <div>
                    <ul class="_1hEmG">
                      <li class="_3GDE6" v-for="(recommend_special_value,recommend_special_index) in recommend_special_list" :key="recommend_special_index">
                        <img alt="png" :src="recommend_special_value.image">
                        <span class="_1CN24">{{recommend_special_value.name}}<em>{{recommend_special_value.article_count}}篇文章,{{recommend_special_value.follow_count}}人关注</em></span>
                        <a data-collection-id="83" data-post-text="投稿" data-posting-text="投稿中" data-posted-text="等待审核">投稿</a>
                      </li>
                    </ul>
                    <div class="_27pBl">没有更多了 </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
    </template>
    
    <script>
        export default {
            name: "PostArticle",
            data(){
               return {
                 my_special_list:[], // 我的的专题列表
                 recommend_special_list:[], // 推荐的专题列表
                 token: "",
                 article_id: 0,
                 article_title:"",
               }
            },
            created() {
                this.token = this.$settings.check_user_login(this);
                // 从本地存储中提取当前文章的ID和标题
                this.article_id   = sessionStorage.article_id;
                this.article_title = sessionStorage.article_title;
                this.get_my_special_list();
                this.get_recommend_special_list();
            },
            methods:{
    
              // 获取我管理的专题列表
              get_my_special_list(){
                this.$axios.get(`${this.$settings.host}/article/special/list/`,{
                  params:{
                    article_id: this.article_id,
                  },
                  headers:{
                    Authorization: "jwt " + this.token,
                  }
                }).then((res)=>{
                  this.my_special_list = res.data;
                }).catch((error)=>{
                  this.$message.error("对不起,获取专题列表失败!");
                });
              },
    
              // 获取推荐的专题列表
              get_recommend_special_list(){
                this.$axios.get(`${this.$settings.host}/article/recommend_special/list/`,{
    
                  headers:{
                    Authorization: "jwt " + this.token,
                  }
                }).then((res)=>{
                  this.recommend_special_list = res.data;
                }).catch((error)=>{
                  this.$message.error("对不起,获取推荐专题列表失败!");
                });
              },
            }
        }
    </script>
    
    
    <style scoped>
    ::selection {
      color: #fff;
      background: #1890ff;
    }
    .writed{
       100%;
      height: 100%;
      max- 100vw;
      max-height: 100vh;
      color: rgba(0,0,0,.65);
      font-size: 14px;
      font-variant: tabular-nums;
      line-height: 1.5;
    }
    .writed *{
      box-sizing: border-box;
    }
    ._3PLTX{
          position: fixed;
        top: 0;
        left: 0;
         100%;
        height: 100%;
        background-color: #fff;
        z-index: 1010;
        overflow-y: auto;
    }
    ._3PLTX ._2Mx1k {
        background-color: #f2f2f2;
        padding-bottom: 110px;
    }
    ._3PLTX ._2Mx1k ._3CoyQ {
        padding: 80px 0 40px;
        text-align: center;
    }
    ._3PLTX ._2Mx1k ._3CoyQ ._2-ZiM {
        display: inline-block;
        height: 40px;
        font-size: 28px;
        font-weight: 500;
        color: #333;
        margin-bottom: 24px;
    }
    ._3PLTX ._2Mx1k ._3CoyQ ._2ajaT {
        font-size: 16px;
        font-weight: 600;
        color: #42c02e;
    }
    ._3PLTX ._2Mx1k ._3CoyQ ._2ajaT:before {
        content: "";
        display: inline-block;
         18px;
        height: 10px;
        border: 3px solid #42c02e;
        border- 0 0 4px 4px;
        transform: rotate(-45deg);
        transition: 0s;
        position: relative;
        bottom: 4px;
        right: 8px;
    }
    ._3PLTX ._2Mx1k .zelSB {
        text-align: center;
        color: #fff;
        font-size: 14px;
    }
    ._3PLTX ._2Mx1k .zelSB>li {
        display: inline-block;
         124px;
        line-height: 38px;
        border-radius: 100px;
        margin: 0 15px;
        cursor: pointer;
        padding: 0;
        text-align: center;
    }
    ._3PLTX ._2Mx1k .zelSB li._35P4c {
        background-color: #e05244;
    }
    ._3PLTX ._2Mx1k .zelSB>li i {
        margin-right: 5px;
    }
    ._3PLTX ._2Mx1k .zelSB li._1c1Eo {
        background-color: #07b225;
    }
    ._3PLTX ._2Mx1k .zelSB li._1HWk1 {
        background-color: #3194d0;
    }
    ._2po2r {
        padding: 10px 20px;
        line-height: 20px;
        white-space: nowrap;
        text-align: left;
        position: relative;
        border-bottom: 1px solid #d9d9d9;
    }
    .cRfUr {
        border-bottom: 1px solid #d9d9d9;
    }
    ._2po2r:last-child {
        border-radius: 0 0 4px 4px;
        border-bottom: 0;
    }
    ._3PLTX ._2Mx1k .zelSB>li {
        display: inline-block;
         124px;
        line-height: 38px;
        border-radius: 100px;
        margin: 0 15px;
        cursor: pointer;
        padding: 0;
        text-align: center;
    }
    ._3PLTX ._2Mx1k .zelSB li._3Qjz6 {
        background-color: #a7a7a7;
        position: relative;
    }
    ._3PLTX ._3Q2EW {
        position: fixed;
        top: 50px;
        right: 100px;
        font-size: 30px;
        font-weight: 700;
        padding: 5px;
        cursor: pointer;
    }
    ._3PLTX ._1s967 {
        height: 40px;
        border-radius: 50% 50% 0 0/100% 100% 0 0;
        background-color: #fff;
        margin-top: -40px;
    }
    ._3PLTX ._2w_E5 {
        margin: 40px auto 0;
         700px;
        font-size: 14px;
    }
    ._3PLTX ._2w_E5 ._23R_O {
        margin-bottom: 36px;
    }
    ._3PLTX ._2w_E5 ._23R_O ._1WCUC {
        float: right;
        border: 1px solid #d9d9d9;
        position: relative;
         200px;
        height: 34px;
        border-radius: 17px;
        padding: 5px 20px 5px 30px;
    }
    ._3PLTX ._2w_E5 ._23R_O ._1WCUC i {
        position: absolute;
        left: 10px;
        top: 50%;
        margin-top: -8px;
        font-size: 16px;
        color: #ccc;
    }
    ._3PLTX ._2w_E5 ._23R_O ._1WCUC input {
        line-height: 24px;
        height: 24px;
         100%;
        font-size: 14px;
        background-color: transparent;
    }
    ._3PLTX ._2w_E5 ._23R_O ._3dZoJ {
        font-size: 16px;
        font-weight: 500;
        line-height: 38px;
    }
    ._3PLTX ._2w_E5 ._18jMg {
        position: relative;
        margin-bottom: 50px;
    }
    ._3PLTX ._2w_E5 ._18jMg h3 {
        margin-bottom: 0;
        height: 40px;
        line-height: 40px;
        padding: 0 6px 0 14px;
        background-color: #f2f2f2;
        font-size: 14px;
    }
    ._3PLTX ._2w_E5 a {
        color: #42c02e;
    }
    ._3PLTX ._2w_E5 ._18jMg h3 a {
        margin-left: 15px;
    }
    ._3PLTX ._2w_E5 ._18jMg ._1hEmG {
        position: relative;
        margin: 1px 0 0 1px;
        zoom: 1;
        min-height: 72px;
    }
    ._3PLTX ._2w_E5 ._18jMg ._1hEmG:after, ._3PLTX ._2w_E5 ._18jMg ._1hEmG:before {
        content: " ";
        display: table;
    }
    ._3PLTX ._2w_E5 ._18jMg ._1hEmG li {
        float: left;
         234px;
        border: 1px solid #f2f2f2;
        position: relative;
        margin: -1px 0 0 -1px;
        list-style-type: none;
    }
    ._3PLTX ._2w_E5 a {
        color: #42c02e;
    }
    ._3PLTX ._2w_E5 ._18jMg ._1hEmG li a {
        position: absolute;
        top: 24px;
        right: 15px;
    }
    img {
        vertical-align: middle;
        border-style: none;
    }
    ._3PLTX ._2w_E5 ._18jMg ._1hEmG li img {
        position: absolute;
        left: 15px;
        height: 40px;
         40px;
        top: 15px;
        border-radius: 10%;
    }
    ._3PLTX ._2w_E5 ._18jMg ._1hEmG li ._1CN24 {
        display: block;
        font-weight: 700;
        color: #595959;
         100%;
        padding: 0 60px 0 75px;
        line-height: 70px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    ._3PLTX ._2w_E5 ._23R_O ._1WCUC input {
      line-height: 24px;
      height: 24px;
       100%;
      font-size: 14px;
      background-color: transparent;
      outline: none;
      border: 0;
    }
    ._3PLTX ._2w_E5 ._23R_O ._1WCUC i {
        position: absolute;
        left: 10px;
        top: 50%;
        margin-top: -8px;
        font-size: 16px;
        color: #ccc;
    }
    ._3PLTX ._2w_E5 ._23R_O ._1WCUC {
        float: right;
        border: 1px solid #d9d9d9;
        position: relative;
         200px;
        height: 34px;
        border-radius: 17px;
        padding: 5px 20px 5px 30px;
    }
    ._3PLTX ._2w_E5 ._18jMg ._1hEmG ._3GDE6 {
         49.85666666%;
    }
    ._3PLTX ._2w_E5 ._18jMg ._1hEmG li img {
        position: absolute;
        left: 15px;
        height: 40px;
         40px;
        top: 15px;
        border-radius: 10%;
    }
    img {
        vertical-align: middle;
        border-style: none;
    }
    ._3PLTX ._2w_E5 ._18jMg ._1hEmG li ._1CN24 {
        display: block;
        font-weight: 700;
        color: #595959;
         100%;
        padding: 0 60px 0 75px;
        line-height: 70px;
        overflow: hidden;
        -o-text-overflow: ellipsis;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    ._1hEmG a{
      cursor: pointer;
    }
    ._3PLTX ._2w_E5 ._18jMg ._1hEmG ._3GDE6 ._1CN24 {
        display: block;
        padding: 18px 65px 16px;
        line-height: 1;
    }
    ._3PLTX ._2w_E5 ._18jMg ._1hEmG ._3GDE6 ._1CN24 em {
        font-weight: 400;
        font-style: normal;
        color: #999;
        display: block;
        margin-top: 8px;
        font-size: 12px;
    }
    ._3PLTX ._2w_E5 a {
        color: #42c02e;
    }
    ._3PLTX ._2w_E5 ._18jMg ._1hEmG li a {
        position: absolute;
        top: 24px;
        right: 15px;
    }
    ._3PLTX ._2w_E5 ._18jMg ._1hEmG:after {
      clear: both;
      visibility: hidden;
      font-size: 0;
      height: 0;
    }
    ._3PLTX ._27pBl {
        padding: 30px 0;
        text-align: center;
    }
    ._3PLTX ._2w_E5 ._18jMg ._1hEmG ._3GDE6 ._1CN24 {
        display: block;
        padding: 18px 65px 16px;
        line-height: 1;
    }
    </style>
    
    
    点击发布跳转到专题页面

    write.vue

              // 文章发布
              article_public(id,index){
                let token = this.$settings.check_user_login(this)
                this.$axios.put(`${this.$settings.host}/article/change_public/${id}/`,{
                  is_public:true
                },{
                  headers:{
                    'Authorization':`jwt ${token}`,
                  },
                }).then((res)=>{
                  this.article_list[index].is_public = true;
                  // 保存文章id和文章标题到本地
                  sessionStorage.article_id = id;
                  sessionStorage.article_title = this.article_list[index].title;
                  // 发布成功跳转到专题页面
                  this.$router.push('/postarticle')
    
                }).catch((error)=>{
                  this.$message.error('文章发布失败!')
                })
              },
    

    实现专题收录文章的功能

    如果投稿的专题管理员就是当前登录用户,那么就不需要管理员审核,不然是需要对应专题的管理员审核的。

    后台接口

    路由:article/urls.py

    path('shoulu/',views.ShouLuView.as_view()),
    

    视图: article/views.py

    # 专题收录(投稿)文章
    class ShouLuView(APIView):
        permission_classes = [IsAuthenticated]
        def put(self,request):
            article_id = request.data.get('article_id')
            special_id = request.data.get('special_id')
    
            # 校验文章是否存在
            try:
                article_obj = models.Article.objects.get(id=article_id)
            except:
                return Response({'error':'当前文章不存在!'})
    
            # 校验专题是否存在
            try:
                special_obj = models.Special.objects.get(id=special_id)
            except:
                return Response({'error':'当前专题不存在!'})
    
            # 判断当前文章与当前专题是否有了投稿记录,并且投稿记录状态是0或1,不需要再保持记录,否则可以保存
            obj_list = models.ArticlePostLog.objects.filter(user_id=self.request.user.id,special_id=special_id,article_id=article_id)
            if obj_list.exists(): # 如果已经投稿,查看最新投稿记录状态
                last_post_log = obj_list.order_by('-created_time').first()
                if last_post_log.status != 2:
                    return Response({'error':'文章已投稿,不需要重复投递!'},status=400)
    
            # 1.如果投稿的专题是自己管理的专题,那么不需要审核
            my_special_id_list = [i.special_id for i in models.SpecialManager.objects.filter(user_id = self.request.user.id)]
            if special_id in my_special_id_list:
                # 同时添加多表数据,需要开启事物
                with transaction.atomic():
                    models.ArticlePostLog.objects.create(
                        user_id=self.request.user.id,
                        special_id=special_id,
                        article_id=article_id,
                        status=1,# 审核通过
                        manager=self.request.user.id,
                        post_time=datetime.datetime.now(),
                    )
                    # 投稿状态记录通过,添加专题文章关系表
                    models.SpecialArticle.objects.create(
                        special_id = special_id,
                        article_id = article_id,
                    )
                return Response({'msg': 'ok','status':1}) # 1--表示成功,0--审核中
            else:
                # 2.如果不是,需要审核
    
                models.ArticlePostLog.objects.create(
                    user_id = self.request.user.id,
                    special_id = special_id,
                    article_id = article_id,
                    status = 0,# 未审核
                    manager = self.request.user.id,
                    post_time = datetime.datetime.now(),
                )
    
                return Response({'msg':'ok','status':0})
    

    前端页面

    PostArticle.vue -- 点击收录事件

    <template>
        <div id="writed">
          <div class="_3PLTX">
            <div class="_2Mx1k">
              <div class="_3CoyQ">
                <router-link :to="`/article/${article_id}`" class="_2-ZiM">{{article_title}}</router-link>
                <br>
                <router-link :to="`/article/${article_id}`" class="_2ajaT">发布成功,点击查看文章</router-link>
              </div>
              <ul class="zelSB">
                <li class="_35P4c"><i class="fa fa-weibo"></i>微博</li>
                <li class="_1c1Eo"><i class="fa fa-wechat"></i>微信</li>
                <li class="_1HWk1"><i class="fa fa-link"></i>复制链接</li>
                <li class="_3FrjS _3Qjz6 _2_WAp _2po2r cRfUr" title="">
                  <span class="">更多分享</span>
                </li>
              </ul>
            </div>
            <div class="_3Q2EW" @click="$router.back()">×</div>
            <div class="_1s967"></div>
            <div class="_2w_E5">
              <div class="_23R_O">
                <div class="_1WCUC">
                  <i class="fa fa-search fa-2x"></i><input type="text" placeholder="搜索专题">
                </div>
                <div class="_3dZoJ">向专题投稿,让文章被更多人发现</div>
              </div>
              <div>
                <div class="_18jMg">
                  <h3>我管理的专题<a href="">新建</a></h3>
                  <ul class="_1hEmG">
                    <li v-for="(my_special_value,my_special_index) in my_special_list" :key="my_special_index">
                      <a v-if="my_special_value.is_shoulu">已收录</a>
                      <a @click.stop="shoulu(my_special_value.id,my_special_index)">收录</a>
                      <img alt="png" :src="my_special_value.image">
                      <span class="_1CN24" :title="my_special_value.name">{{my_special_value.name}}</span>
                    </li>
                  </ul>
                </div>
                <div class="_18jMg">
                  <h3>推荐专题</h3>
                  <div>
                    <ul class="_1hEmG">
                      <li class="_3GDE6" v-for="(recommend_special_value,recommend_special_index) in recommend_special_list" :key="recommend_special_index">
                        <img alt="png" :src="recommend_special_value.image">
                        <span class="_1CN24">{{recommend_special_value.name}}<em>{{recommend_special_value.article_count}}篇文章,{{recommend_special_value.follow_count}}人关注</em></span>
                        <a data-collection-id="83" data-post-text="投稿" data-posting-text="投稿中" data-posted-text="等待审核">投稿</a>
                      </li>
                    </ul>
                    <div class="_27pBl">没有更多了 </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
    </template>
    
    <script>
        export default {
            name: "PostArticle",
            data(){
               return {
                 my_special_list:[], // 我的的专题列表
                 recommend_special_list:[], // 推荐的专题列表
                 token: "",
                 article_id: 0,
                 article_title:"",
               }
            },
            created() {
    			....
            },
            methods:{
              // 收录文章
              shoulu(special_id,index){
                // special_id -- 专题id  index--专题索引
                this.$axios.put(`${this.$settings.host}/article/shoulu/`,{
                  article_id: this.article_id,
                  special_id: special_id,
                },{
                  headers:{
                    Authorization: "jwt " + this.token,
                  }
                }).then((res)=>{
                  this.my_special_list[index].is_shoulu = true;
                  this.$message.success('收录成功!')
                }).catch((error)=>{
                  this.$message.error(error.response.data.error);
                });
              },
            }
        }
    </script>
    
    

    文章详情页

    后台接口

    路由:article/urls.py

    re_path('article_detail/(?P<pk>d+)/',views.ArticleDetailView.as_view()),
    

    视图:article/views.py

    # 文章详情数据  RetrieveAPIView -- 获取单条数据
    class ArticleDetailView(RetrieveAPIView):
        permission_classes = [IsAuthenticated]
        queryset = models.Article.objects.filter(is_show=True,is_delete=False)
        serializer_class = ArticleDetailSerializer
    

    序列化器类:article/serializers.py

    # 用户表
    class UserModelSerializer(serializers.ModelSerializer):
        class Meta:
            model = User
            fields = ['id','username','nickname','avatar']
    
    # 文集表
    class CollectionModelSerializer(serializers.ModelSerializer):
        # 序列化器嵌套 反向查询 如果外建关联related_name = 'xxx'
        # xxx = ArticleDetailSerializer(many=True) --反向查询
        class Meta:
            model = models.ArticleCollection
            fields = ['id','name']
    
    # 文章详情数据
    class ArticleDetailSerializer(serializers.ModelSerializer):
        # 序列化器嵌套 正向查询
        collection = CollectionModelSerializer()
        user = UserModelSerializer()
        class Meta:
            model = models.Article
            fields = ['id','title','content','render','user',
                      'collection','pub_date','read_count',
                      'like_count','collect_count',
                      'comment_count','reward_count','created_time']
    

    前端页面

    在PostArticle.vue中打通跳转到文章详情页的链接:

    <div class="_3CoyQ">
                <router-link :to="`/article/${article_id}`" class="_2-ZiM">{{article_title}}</router-link>
                <br>
                <router-link :to="`/article/${article_id}`" class="_2ajaT">发布成功,点击查看文章</router-link>
              </div>
    

    在router/index.js中创建路由,代码:

    import Vue from 'vue'
    import Router from 'vue-router'
    import Article from "@/components/Article";
    Vue.use(Router);
    
    export default new Router({
      mode: "history",
      routes: [
        {
           name:"Article",
           path:"/article/:id",// 动态路由  /article/2 ---this.$route.params.id 就可以拿到文章id
           component: Article,
         },
      ]
    })
    
    

    创建Article.vue组件:

    <template>
      <div class="_21bLU4 _3kbg6I">
       <Header></Header>
       <div class="_3VRLsv" role="main">
        <div class="_gp-ck">
         <section class="ouvJEz">
          <h1 class="_1RuRku">废掉一个人最快的方法,就是让他闲着</h1>
          <div class="rEsl9f">
           <div class="_2mYfmT">
            <a class="_1OhGeD" href="/u/a70487cda447" target="_blank" rel="noopener noreferrer"><img class="_13D2Eh" src="https://upload.jianshu.io/users/upload_avatars/18529254/.png?imageMogr2/auto-orient/strip|imageView2/1/w/96/h/96/format/webp" alt="" /></a>
            <div style="margin-left: 8px;">
             <div class="_3U4Smb">
              <span class="FxYr8x"><a class="_1OhGeD" href="/u/a70487cda447" target="_blank" rel="noopener noreferrer">書酱</a></span>
              <button data-locale="zh-CN" type="button" class="_3kba3h _1OyPqC _3Mi9q9 _34692-"><span>关注</span></button>
             </div>
             <div class="s-dsoj">
              <time datetime="2020-01-08T12:01:00.000Z">2020.01.08 20:01:00</time>
              <span>字数 2,510</span>
              <span>阅读 168</span>
             </div>
            </div>
           </div>
          </div>
          <article class="_2rhmJa">
           <div class="image-package">
            <div class="image-container" style="max- 640px; max-height: 420px; background-color: transparent;">
             <div class="image-container-fill" style="padding-bottom: 65.63%;"></div>
             <div class="image-view" data-width="640" data-height="420">
              <img src="https://upload-images.jianshu.io/upload_images/18529254-f62fac0d998cff23?imageMogr2/auto-orient/strip|imageView2/2/w/640/format/webp" />
             </div>
            </div>
            <div class="image-caption"></div>
           </div>
           <p>文/小鸟飞过</p>
           <p>罗曼&middot;罗兰说:“生活中最沉重的负担不是工作,而是无聊。”</p>
           <div class="image-package">
            <div class="image-container" style="max- 700px; max-height: 152px; background-color: transparent;">
             <div class="image-container-fill" style="padding-bottom: 14.069999999999999%;"></div>
             <div class="image-view" data-width="1080" data-height="152">
              <img src="http://upload-images.jianshu.io/upload_images/18529254-a932f0ad8fbd51bb?imageMogr2/auto-orient/strip|imageView2/2/w/1080/format/webp" />
             </div>
            </div>
            <div class="image-caption"></div>
           </div>
           <p><strong>废掉一个人最快的方法</strong></p>
           <p><strong>就是让他闲着</strong></p>
           <p>这段时间,综艺节目《妻子的浪漫旅行第三季3》正在热播,四对明星夫妻的相处模式曝光,也让观众更了解了曾经饱受争议的女人唐一菲。</p>
           <p>有人很喜欢她大大咧咧的女侠性格,有人为她叫屈,当然还是有人骂她,说她旧事重提。</p>
           <p>而我,则是觉得非常惋惜。</p>
           <p>唐一菲是中央戏剧学院表演系毕业,真正的科班出身。</p>
           <p>从2003年到2011年,基本保证每年都有作品,要么拍电视剧、要么拍电影,2008年出演新版《红楼梦》的秦可卿也是颇为动人。</p>
           <div class="image-package">
            <div class="image-container" style="max- 533px; max-height: 510px; background-color: transparent;">
             <div class="image-container-fill" style="padding-bottom: 95.67999999999999%;"></div>
             <div class="image-view" data-width="533" data-height="510">
              <img src="http://upload-images.jianshu.io/upload_images/18529254-d92ace292d78aecb?imageMogr2/auto-orient/strip|imageView2/2/w/533/format/webp" />
             </div>
            </div>
            <div class="image-caption"></div>
           </div>
           <p>可是自2012年结婚后,8年时间里,只拍了一部电视剧,就再也没了一点儿消息,仿佛整个人生都停滞了。</p>
           <p>她在《妻子3》中展现出的婚姻状态是非常可悲的。</p>
           <p>一喝酒,就是吐槽自己的人生被毁了。</p>
           <div class="image-package">
            <div class="image-container" style="max- 532px; max-height: 394px;">
             <div class="image-container-fill" style="padding-bottom: 74.06%;"></div>
             <div class="image-view" data-width="532" data-height="394">
              <img data-original-src="//upload-images.jianshu.io/upload_images/18529254-5f20af5bb10bfa12" data-original-width="532" data-original-height="394" data-original-format="image/jpeg" data-original-filesize="17915" data-image-index="3" style="cursor: zoom-in;" class="image-loading" />
             </div>
            </div>
            <div class="image-caption"></div>
           </div>
           <p>要么直接形容老公凌潇肃是缩头乌龟。</p>
           <div class="image-package">
            <div class="image-container" style="max- 506px; max-height: 360px;">
             <div class="image-container-fill" style="padding-bottom: 71.15%;"></div>
             <div class="image-view" data-width="506" data-height="360">
              <img data-original-src="//upload-images.jianshu.io/upload_images/18529254-f2478cdc59c7e193" data-original-width="506" data-original-height="360" data-original-format="image/jpeg" data-original-filesize="23772" data-image-index="4" style="cursor: zoom-in;" class="image-loading" />
             </div>
            </div>
            <div class="image-caption"></div>
           </div>
           <p>作者简介:小鸟飞过,富小书的人,富书专栏作者,写温暖的文字,传递美好的情感;本文首发富小书(ID:fxsfrc),你身边最好的闺蜜,富书2018重磅推出新书《好好生活》。</p>
           <p><strong>注:本文章图片来源网络,如有侵权,请联系删除。</strong></p>
          </article>
          <div></div>
          <div class="_1kCBjS">
           <div class="_18vaTa">
            <div class="_3BUZPB">
             <div class="_2Bo4Th" role="button" tabindex="-1" aria-label="给文章点赞">
              <i aria-label="ic-like" class="anticon">
               <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class="">
                <use xlink:href="#ic-like"></use>
               </svg></i>
             </div>
             <span class="_1LOh_5" role="button" tabindex="-1" aria-label="查看点赞列表">8人点赞<i aria-label="icon: right" class="anticon anticon-right">
               <svg viewbox="64 64 896 896" focusable="false" class="" data-icon="right" width="1em" height="1em" fill="currentColor" aria-hidden="true">
                <path d="M765.7 486.8L314.9 134.7A7.97 7.97 0 0 0 302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 0 0 0-50.4z"></path>
               </svg></i></span>
            </div>
            <div class="_3BUZPB">
             <div class="_2Bo4Th" role="button" tabindex="-1">
              <i aria-label="ic-dislike" class="anticon">
               <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class="">
                <use xlink:href="#ic-dislike"></use>
               </svg></i>
             </div>
            </div>
           </div>
           <div class="_18vaTa">
            <a class="_3BUZPB _1x1ok9 _1OhGeD" href="/nb/38290018" target="_blank" rel="noopener noreferrer"><i aria-label="ic-notebook" class="anticon">
              <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class="">
               <use xlink:href="#ic-notebook"></use>
              </svg></i><span>随笔</span></a>
            <div class="_3BUZPB ant-dropdown-trigger">
             <div class="_2Bo4Th">
              <i aria-label="ic-others" class="anticon">
               <svg width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class="">
                <use xlink:href="#ic-others"></use>
               </svg></i>
             </div>
            </div>
           </div>
          </div>
          <div class="_19DgIp" style="margin-top:24px;margin-bottom:24px"></div>
          <div class="_13lIbp">
           <div class="_191KSt">
            &quot;小礼物走一走,来简书关注我&quot;
           </div>
           <button type="button" class="_1OyPqC _3Mi9q9 _2WY0RL _1YbC5u"><span>赞赏支持</span></button>
           <span class="_3zdmIj">还没有人赞赏,支持一下</span>
          </div>
          <div class="d0hShY">
           <a class="_1OhGeD" href="/u/a70487cda447" target="_blank" rel="noopener noreferrer"><img class="_27NmgV" src="https://upload.jianshu.io/users/upload_avatars/18529254/.png?imageMogr2/auto-orient/strip|imageView2/1/w/100/h/100/format/webp" alt="  " /></a>
           <div class="Uz-vZq">
            <div class="Cqpr1X">
             <a class="HC3FFO _1OhGeD" href="/u/a70487cda447" title="書酱" target="_blank" rel="noopener noreferrer">書酱</a>
             <span class="_2WEj6j" title="你读书的样子真好看。">你读书的样子真好看。</span>
            </div>
            <div class="lJvI3S">
             <span>总资产0</span>
             <span>共写了78.7W字</span>
             <span>获得6,072个赞</span>
             <span>共1,308个粉丝</span>
            </div>
           </div>
           <button data-locale="zh-CN" type="button" class="_1OyPqC _3Mi9q9"><span>关注</span></button>
          </div>
         </section>
         <div id="note-page-comment">
          <div class="lazyload-placeholder"></div>
         </div>
        </div>
        <aside class="_2OwGUo">
         <section class="_3Z3nHf">
          <div class="_3Oo-T1">
           <a class="_1OhGeD" href="/u/a70487cda447" target="_blank" rel="noopener noreferrer"><img class="_3T9iJQ" src="https://upload.jianshu.io/users/upload_avatars/18529254/.png?imageMogr2/auto-orient/strip|imageView2/1/w/90/h/90/format/webp" alt="" /></a>
           <div class="_32ZTTG">
            <div class="_2O0T_w">
             <div class="_2v-h3G">
              <span class="_2vh4fr" title="書酱"><a class="_1OhGeD" href="/u/a70487cda447" target="_blank" rel="noopener noreferrer">書酱</a></span>
             </div>
             <button data-locale="zh-CN" type="button" class="tzrf9N _1OyPqC _3Mi9q9 _34692-"><span>关注</span></button>
            </div>
            <div class="_1pXc22">
             总资产0
            </div>
           </div>
          </div>
          <div class="_19DgIp"></div>
         </section>
         <div>
          <div class="">
           <section class="_3Z3nHf">
            <h3 class="QHRnq8 QxT4hD"><span>推荐阅读</span></h3>
            <div class="cuOxAY" role="listitem">
             <div class="_3L5YSq" title="这些话没人告诉你,但必须知道的社会规则">
              <a class="_1-HJSV _1OhGeD" href="/p/a3e56a0559ff" target="_blank" rel="noopener noreferrer">这些话没人告诉你,但必须知道的社会规则</a>
             </div>
             <div class="_19haGh">
              阅读 5,837
             </div>
            </div>
            <div class="cuOxAY" role="listitem">
             <div class="_3L5YSq" title="浙大学霸最美笔记曝光:真正的牛人,都“变态”到了极致">
              <a class="_1-HJSV _1OhGeD" href="/p/d2a3724e2839" target="_blank" rel="noopener noreferrer">浙大学霸最美笔记曝光:真正的牛人,都“变态”到了极致</a>
             </div>
             <div class="_19haGh">
              阅读 12,447
             </div>
            </div>
            <div class="cuOxAY" role="listitem">
             <div class="_3L5YSq" title="征服一个女人最好的方式:不是讨好她,而是懂得去折腾她">
              <a class="_1-HJSV _1OhGeD" href="/p/f6acf67f039b" target="_blank" rel="noopener noreferrer">征服一个女人最好的方式:不是讨好她,而是懂得去折腾她</a>
             </div>
             <div class="_19haGh">
              阅读 5,311
             </div>
            </div>
            <div class="cuOxAY" role="listitem">
             <div class="_3L5YSq" title="告别平庸的15个小方法">
              <a class="_1-HJSV _1OhGeD" href="/p/cff7eb6b232b" target="_blank" rel="noopener noreferrer">告别平庸的15个小方法</a>
             </div>
             <div class="_19haGh">
              阅读 7,040
             </div>
            </div>
            <div class="cuOxAY" role="listitem">
             <div class="_3L5YSq" title="轻微抑郁的人,会说这3句“口头禅”,若你一个不占,偷着乐吧">
              <a class="_1-HJSV _1OhGeD" href="/p/2a0ca1729b4b" target="_blank" rel="noopener noreferrer">轻微抑郁的人,会说这3句“口头禅”,若你一个不占,偷着乐吧</a>
             </div>
             <div class="_19haGh">
              阅读 16,411
             </div>
            </div>
           </section>
          </div>
         </div>
        </aside>
       </div>
       <Footer></Footer>
      </div>
    </template>
    
    <script>
        import Header from "./common/Header";
        import Footer from "./common/Footer";
        export default {
          name: "Article",
          components:{
            Header,
            Footer,
          },
          data(){
            return{
              token:'',
              article_detail_data:{
                user:{},
                collection:{},
              }, // 存放文章详情数据
            }
          },
          created() {
            this.token = this.$settings.check_user_login(this);
            this.get_article_detail()
          },
          methods:{
            // 获取文章详细信息
            get_article_detail(){
              this.$axios.get(`${this.$settings.host}/article/article_detail/${this.$route.params.id}/`,{
                headers:{
                    Authorization: "jwt " + this.token,
                  }
              }).then((res)=>{
                this.article_detail_data = res.data;
                this.$message.success('获取文章详情数据成功')
              }).catch((error)=>{
                this.$message.error('获取文章详情数据失败!')
              })
            }
          },
    
        }
    </script>
    
    
    <style scoped>
    *,:after,:before {
    	box-sizing: border-box
    }
    
    a:hover {
    	color: #fa9e87
    }
    
    a:active {
    	color: #c75342
    }
    
    a:active,a:hover {
    	text-decoration: none;
    	outline: 0
    }
    
    a[disabled] {
    	color: rgba(0,0,0,.25);
    	cursor: not-allowed;
    	pointer-events: none
    }
    
    img {
    	vertical-align: middle;
    	border-style: none
    }
    
    svg:not(:root) {
    	overflow: hidden
    }
    [role=button],a,area,button,input:not([type=range]),label,select,summary,textarea {
    	-ms-touch-action: manipulation;
    	touch-action: manipulation
    }
    
    button,input,optgroup,select,textarea {
    	margin: 0;
    	color: inherit;
    	font-size: inherit;
    	font-family: inherit;
    	line-height: inherit
    }
    
    button,input {
    	overflow: visible
    }
    
    button,select {
    	text-transform: none
    }[type=reset],[type=submit],button,html [type=button] {
    	-webkit-appearance: button
    }[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner {
    	padding: 0;
    	border-style: none
    }
    
    input[type=checkbox],input[type=radio] {
    	-webkit-box-sizing: border-box;
    	box-sizing: border-box;
    	padding: 0
    }
    
    input[type=date],input[type=datetime-local],input[type=month],input[type=time] {
    	-webkit-appearance: listbox
    }
    
    textarea {
    	overflow: auto;
    	resize: vertical
    }
    
    fieldset {
    	min- 0;
    	margin: 0;
    	padding: 0;
    	border: 0
    }
    
    legend {
    	display: block;
    	 100%;
    	max- 100%;
    	margin-bottom: .5em;
    	padding: 0;
    	color: inherit;
    	font-size: 1.5em;
    	line-height: inherit;
    	white-space: normal
    }
    
    progress {
    	vertical-align: baseline
    }
    
    ::selection {
    	color: #fff;
    	background: #ec7259
    }
    
    .anticon {
    	display: inline-block;
    	color: inherit;
    	font-style: normal;
    	line-height: 0;
    	text-align: center;
    	text-transform: none;
    	vertical-align: -.125em;
    	text-rendering: optimizeLegibility;
    	-webkit-font-smoothing: antialiased;
    	-moz-osx-font-smoothing: grayscale
    }
    
    .anticon>* {
    	line-height: 1
    }
    
    .anticon svg {
    	display: inline-block
    }
    
    .anticon:before {
    	display: none
    }
    
    .anticon .anticon-icon {
    	display: block
    }
    
    .anticon[tabindex] {
    	cursor: pointer
    }
    
    ._3Vh8Z9-info ._3Vh8Z9-notice-content .anticon,._3Vh8Z9-loading ._3Vh8Z9-notice-content .anticon {
    	color: #0681d0
    }
    
    ._3Vh8Z9-success ._3Vh8Z9-notice-content .anticon {
    	color: #42c02e
    }
    
    ._3Vh8Z9-warning ._3Vh8Z9-notice-content .anticon {
    	color: #fa0
    }
    
    ._3Vh8Z9-error ._3Vh8Z9-notice-content .anticon {
    	color: #f50
    }
    
    
    ._1OyPqC {
    	position: relative;
    	flex-shrink: 0;
    	display: inline-flex;
    	justify-content: center;
    	align-items: center;
    	border-radius: 50px;
    	touch-action: manipulation;
    	cursor: pointer;
    	background-image: none;
    	white-space: nowrap;
    	-webkit-user-select: none;
    	-moz-user-select: none;
    	-ms-user-select: none;
    	user-select: none;
    	transition: all .2s cubic-bezier(.645,.045,.355,1);
    	font-size: 14px;
    	padding: 4px 12px;
    	color: #969696;
    	background-color: #fff;
    	border: 1px solid #999
    }
    
    ._1OyPqC+._1OyPqC,._1OyPqC>.anticon+span,._1OyPqC>span+.anticon {
    	margin-left: 8px
    }
    
    ._1OyPqC:focus,._1OyPqC:hover {
    	color: #7d7d7d;
    	background-color: #fff;
    	border-color: #999
    }
    
    ._1OyPqC:active {
    	color: #636363;
    	background-color: #fff;
    	border-color: #999
    }
    
    body.reader-night-mode ._1OyPqC {
    	color: #b3b3b3;
    	background-color: #3d3d3d;
    	border-color: #999
    }
    
    body.reader-night-mode ._1OyPqC:focus,body.reader-night-mode ._1OyPqC:hover {
    	color: #ccc;
    	background-color: #3d3d3d;
    	border-color: #999
    }
    
    body.reader-night-mode ._1OyPqC:active {
    	color: #e6e6e6;
    	background-color: #3d3d3d;
    	border-color: #999
    }
    
    ._3Mi9q9,._3Mi9q9[disabled]:hover {
    	color: #ec7259;
    	background-color: #fff;
    	border-color: #ec7259
    }
    
    ._3Mi9q9:focus,._3Mi9q9:hover {
    	color: #ec7259;
    	background-color: #fef8f7;
    	border-color: #ec7259
    }
    
    ._3Mi9q9:active {
    	color: #ec7259;
    	background-color: #fdf1ee;
    	border-color: #ec7259
    }
    
    body.reader-night-mode ._3Mi9q9,body.reader-night-mode ._3Mi9q9[disabled]:hover {
    	color: #ec7259;
    	background-color: #3d3d3d;
    	border-color: #ec7259
    }
    
    body.reader-night-mode ._3Mi9q9:focus,body.reader-night-mode ._3Mi9q9:hover {
    	color: #ec7259;
    	background-color: #46403f;
    	border-color: #ec7259
    }
    
    body.reader-night-mode ._3Mi9q9:active {
    	color: #ec7259;
    	background-color: #4f4240;
    	border-color: #ec7259
    }
    
    ._3Mi9q9._2SIRy5:before {
    	content: "";
    	position: absolute;
    	border-radius: inherit;
    	border: 0 solid #ec7259;
    	animation: ZAhfCQ .3s ease-out forwards
    }
    
    ._3Mi9q9._1YbC5u,._3Mi9q9._1YbC5u[disabled]:hover {
    	color: #fff;
    	background-color: #ec7259;
    	border-color: #ec7259
    }
    
    ._3Mi9q9._1YbC5u:focus,._3Mi9q9._1YbC5u:hover {
    	color: #fff;
    	background-color: #ed7961;
    	border-color: #ec7259
    }
    
    ._3Mi9q9._1YbC5u:active {
    	color: #fff;
    	background-color: #ee806a;
    	border-color: #ec7259
    }
    
    body.reader-night-mode ._3Mi9q9._1YbC5u,body.reader-night-mode ._3Mi9q9._1YbC5u[disabled]:hover {
    	color: #fff;
    	background-color: #ec7259;
    	border-color: #ec7259
    }
    
    body.reader-night-mode ._3Mi9q9._1YbC5u:focus,body.reader-night-mode ._3Mi9q9._1YbC5u:hover {
    	color: #fff;
    	background-color: #ed7961;
    	border-color: #ec7259
    }
    
    body.reader-night-mode ._3Mi9q9._1YbC5u:active {
    	color: #fff;
    	background-color: #ee806a;
    	border-color: #ec7259
    }
    
    ._3tVfGA {
    	color: #999
    }
    
    ._3tVfGA hr {
    	margin: 16px 0;
    	border: none;
    	border-top: 1px solid #eee
    }
    
    body.reader-night-mode ._3tVfGA hr {
    	border-color: #2f2f2f
    }
    
    .PY53UF:hover>i {
    	visibility: visible;
    	opacity: 1
    }
    
    .PY53UF>span {
    	margin-right: 4px;
    	overflow: hidden;
    	text-overflow: ellipsis;
    	white-space: nowrap
    }
    
    .PY53UF>i {
    	font-size: 12px;
    	visibility: hidden;
    	opacity: 0
    }
    
    
    ._3VRLsv {
    	box-sizing: content-box;
    	 1000px;
    	padding-left: 16px;
    	padding-right: 16px;
    	margin-left: auto;
    	margin-right: auto
    }
    
    ._3Z3nHf,.ouvJEz {
    	background-color: #fff;
    	border-radius: 4px;
    	margin-bottom: 10px
    }
    
    body.reader-night-mode ._3Z3nHf,body.reader-night-mode .ouvJEz {
    	background-color: #3d3d3d
    }
    
    ._3kbg6I {
    	background-color: #f9f9f9
    }
    
    body.reader-night-mode ._3kbg6I {
    	background-color: #2d2d2d
    }
    
    ._3VRLsv {
    	display: flex;
    	justify-content: center;
    	align-items: flex-start;
    	min-height: calc(100vh - 66px);
    	padding-top: 10px;
    	font-size: 16px
    }
    
    ._gp-ck {
    	flex-shrink: 0;
    	 730px;
    	margin-bottom: 24px;
    	margin-right: 10px
    }
    
    .ouvJEz {
    	padding: 24px
    }
    
    ._2OwGUo {
    	flex-shrink: 0;
    	 260px
    }
    
    ._3Z3nHf {
    	padding: 16px
    }
    
    .QxT4hD {
    	display: flex;
    	justify-content: space-between;
    	align-items: center;
    	margin-bottom: 16px;
    	padding-left: 12px;
    	border-left: 4px solid #ec7259;
    	font-size: 18px;
    	font-weight: 500;
    	height: 20px;
    	line-height: 20px
    }
    
    ._3Fatyw>i {
    	font-size: 18px;
    	margin-right: 4px
    }
    
    .nnghRR>p {
    	margin-bottom: 0
    }
    
    
    .LtPwLP>div {
    	min-height: 100px;
    	flex-grow: 1
    }
    
    .LtPwLP img {
    	 150px;
    	height: 100px;
    	border-radius: 4px;
    	border: 1px solid #f2f2f2;
    	flex-shrink: 0
    }
    
    ._3nj4GN>span {
    	margin-left: 8px;
    	line-height: 20px
    }
    
    ._3nj4GN .anticon {
    	font-size: 22px
    }
    
    .rEsl9f {
    	display: flex;
    	justify-content: space-between;
    	align-items: center;
    	margin-bottom: 32px;
    	font-size: 13px
    }
    
    .s-dsoj {
    	display: flex;
    	color: #969696
    }
    
    .s-dsoj>:not(:last-child) {
    	margin-right: 10px
    }
    
    ._3tCVn5 i {
    	margin-right: .5em
    }
    
    ._2mYfmT {
    	display: flex;
    	align-items: center
    }
    
    ._13D2Eh {
    	display: block;
    	border-radius: 50%;
    	border: 1px solid #eee;
    	min- 48px;
    	min-height: 48px;
    	 48px;
    	height: 48px
    }
    
    body.reader-night-mode ._13D2Eh {
    	border-color: #2f2f2f
    }
    
    ._3U4Smb {
    	display: flex;
    	align-items: center;
    	margin-bottom: 6px
    }
    
    .FxYr8x {
    	font-size: 16px;
    	font-weight: 500;
    	margin-right: 8px
    }
    
    ._3kba3h {
    	padding: 2px 9px
    }
    
    ._2rhmJa code,._2rhmJa pre,._2rhmJa pre[class*=language-] {
    	font-family: Consolas,Monaco,"Andale Mono","Ubuntu Mono",monospace;
    	font-size: 12px
    }
    
    ._2rhmJa {
    	font-weight: 400;
    	line-height: 1.8;
    	margin-bottom: 20px
    }
    
    
    ._2rhmJa h1,._2rhmJa h2,._2rhmJa h3,._2rhmJa h4,._2rhmJa h5,._2rhmJa h6 {
    	margin-bottom: 16px
    }
    
    ._2rhmJa h1 {
    	font-size: 26px
    }
    
    ._2rhmJa h2 {
    	font-size: 24px
    }
    
    ._2rhmJa h3 {
    	font-size: 22px
    }
    
    ._2rhmJa h4 {
    	font-size: 20px
    }
    
    ._2rhmJa h5 {
    	font-size: 18px
    }
    
    ._2rhmJa h6 {
    	font-size: 16px
    }
    
    ._2rhmJa p {
    	margin-bottom: 20px;
    	word-break: break-word
    }
    
    ._2rhmJa hr {
    	margin: 0 0 20px;
    	border: 0;
    	border-top: 1px solid #eee!important
    }
    
    body.reader-night-mode ._2rhmJa hr {
    	border-color: #2f2f2f!important
    }
    
    ._2rhmJa blockquote {
    	padding: 20px;
    	background-color: #fafafa;
    	border-left: 6px solid #e6e6e6;
    	word-break: break-word;
    	font-size: 16px;
    	font-weight: normal;
    	line-height: 30px;
    	margin: 0 0 20px
    }
    
    body.reader-night-mode ._2rhmJa blockquote {
    	background-color: #595959;
    	border-color: #262626
    }
    
    ._2rhmJa blockquote h1:last-child,._2rhmJa blockquote h2:last-child,._2rhmJa blockquote h3:last-child,._2rhmJa blockquote h4:last-child,._2rhmJa blockquote h5:last-child,._2rhmJa blockquote h6:last-child,._2rhmJa blockquote li:last-child,._2rhmJa blockquote ol:last-child,._2rhmJa blockquote p:last-child,._2rhmJa blockquote ul:last-child {
    	margin-bottom: 0
    }
    
    ._2rhmJa blockquote .image-package {
    	 100%;
    	margin-left: 0
    }
    
    ._2rhmJa ol,._2rhmJa ul {
    	word-break: break-word;
    	margin: 0 0 20px 20px
    }
    
    ._2rhmJa ol li,._2rhmJa ul li {
    	line-height: 30px
    }
    
    ._2rhmJa ol li ol,._2rhmJa ol li ul,._2rhmJa ul li ol,._2rhmJa ul li ul {
    	margin-top: 16px
    }
    
    ._2rhmJa ol {
    	list-style-type: decimal
    }
    
    ._2rhmJa ul {
    	list-style-type: disc
    }
    
    ._2rhmJa code {
    	padding: 2px 4px;
    	border: none;
    	vertical-align: middle;
    	white-space: pre-wrap
    }
    
    ._2rhmJa :not(pre) code {
    	color: #c7254e;
    	background-color: #f2f2f2
    }
    
    body.reader-night-mode ._2rhmJa :not(pre) code {
    	background-color: #262626
    }
    
    ._2rhmJa pre,._2rhmJa pre[class*=language-] {
    	word-wrap: normal;
    	word-break: break-all;
    	white-space: pre;
    	overflow-x: scroll;
    	overscroll-behavior-x: contain;
    	margin-top: 0;
    	margin-bottom: 20px;
    	border-radius: 4px;
    	z-index: 0;
    	padding: 1em;
    	line-height: 1.5;
    	color: #ccc;
    	background: #2d2d2d
    }
    
    ._2rhmJa pre[class*=language-] code,._2rhmJa pre code {
    	padding: 0;
    	background-color: transparent;
    	color: inherit;
    	white-space: pre;
    	vertical-align: unset
    }
    
    ._2rhmJa table {
    	 100%;
    	margin-bottom: 20px;
    	border-collapse: collapse;
    	border: 1px solid #eee;
    	border-left: none;
    	word-break: break-word
    }
    
    body.reader-night-mode ._2rhmJa table,body.reader-night-mode ._2rhmJa table td,body.reader-night-mode ._2rhmJa table th {
    	border-color: #2f2f2f
    }
    
    ._2rhmJa table td,._2rhmJa table th {
    	padding: 8px;
    	border: 1px solid #eee;
    	line-height: 20px;
    	vertical-align: middle
    }
    
    ._2rhmJa table th {
    	font-weight: bold
    }
    
    ._2rhmJa table thead th {
    	vertical-align: middle;
    	text-align: inherit
    }
    
    ._2rhmJa table tr:nth-of-type(2n) {
    	background-color: hsla(0,0%,70.2%,.15)
    }
    
    ._2rhmJa table .image-package {
    	 100%;
    	margin-left: 0
    }
    
    ._2rhmJa img {
    	max- 100%
    }
    
    ._2rhmJa .image-package {
    	 100%;
    	margin: 0;
    	padding-bottom: 25px;
    	text-align: center;
    	font-size: 0
    }
    
    ._2rhmJa .image-package img {
    	max- 100%;
    	 auto;
    	height: auto;
    	vertical-align: middle;
    	border: 0
    }
    
    body.reader-night-mode ._2rhmJa .image-package img {
    	opacity: .85
    }
    
    ._2rhmJa .image-package .image-container {
    	position: relative;
    	z-index: 95;
    	background-color: #e6e6e6;
    	transition: background-color .1s linear;
    	margin: 0 auto
    }
    
    body.reader-night-mode ._2rhmJa .image-package .image-container {
    	background-color: #595959
    }
    
    ._2rhmJa .image-package .image-container-fill {
    	z-index: 90
    }
    
    ._2rhmJa .image-package .image-container .image-view {
    	position: absolute;
    	top: 0;
    	left: 0;
    	 100%;
    	height: 100%;
    	overflow: hidden
    }
    
    ._2rhmJa .image-package .image-container .image-view-error {
    	cursor: pointer;
    	color: grey
    }
    
    body.reader-night-mode ._2rhmJa .image-package .image-container .image-view-error {
    	color: #b3b3b3
    }
    
    ._2rhmJa .image-package .image-container .image-view-error:after {
    	content: "56FE724783B753D659318D25FF0C8BF770B951FB91CD8BD5";
    	position: absolute;
    	top: 50%;
    	left: 50%;
    	 100%;
    	transform: translate(-50%,-50%);
    	color: inherit;
    	font-size: 14px
    }
    
    ._2rhmJa .image-package .image-container .image-view img.image-loading {
    	opacity: .3
    }
    
    ._2rhmJa .image-package .image-container .image-view img {
    	transition: all .15s linear;
    	z-index: 95;
    	opacity: 1
    }
    
    ._2rhmJa .image-package .image-caption {
    	min- 20%;
    	max- 80%;
    	min-height: 43px;
    	display: inline-block;
    	padding: 10px;
    	margin: 0 auto;
    	border-bottom: 1px solid #eee;
    	font-size: 13px;
    	color: #999
    }
    
    ._2rhmJa .image-package .image-caption:empty {
    	display: none
    }
    
    body.reader-night-mode ._2rhmJa .image-package .image-caption {
    	border-color: #2f2f2f
    }
    
    ._2rhmJa .math-block[mathimg="1"] {
    	display: block;
    	margin: 1em auto
    }
    
    ._2rhmJa .math-inline[mathimg="1"] {
    	display: inline;
    	margin: 0 3px;
    	vertical-align: middle
    }
    
    ._2rhmJa .math-block[mathimg="1"],._2rhmJa .math-inline[mathimg="1"] {
    	max- 100%
    }
    
    body.reader-night-mode ._2rhmJa .math-block[mathimg="1"],body.reader-night-mode ._2rhmJa .math-inline[mathimg="1"] {
    	filter: invert(.8)
    }
    
    ._3GbnS5 {
    	padding: 0;
    	line-height: 1.5;
    	position: relative;
    	 100%;
    	height: 1px;
    	margin: 20px 0;
    	border: none;
    	border-top: #b3b3b3;
    	display: table;
    	white-space: nowrap;
    	text-align: center
    }
    
    ._3GbnS5:after,._3GbnS5:before {
    	content: "";
    	display: table-cell;
    	position: relative;
    	top: 50%;
    	left: 0;
    	 50%;
    	border-top: 1px solid;
    	border-top-color: inherit;
    	transform: scaleY(.5) translateY(50%);
    	transform-origin: 50% 50% 0;
    	transform-origin: initial
    }
    
    ._2Lt-af {
    	display: inline-block;
    	padding: 0 12px;
    	font-size: 14px;
    	font-weight: normal;
    	text-align: center;
    	white-space: nowrap;
    	color: #b3b3b3;
    	-webkit-user-select: none;
    	-moz-user-select: none;
    	-ms-user-select: none;
    	user-select: none
    }
    
    ._2Lt-af>a {
    	margin-left: .5em
    }
    
    ._19DgIp {
    	 100%;
    	height: 1px;
    	margin: 16px 0;
    	background-color: #eee
    }
    
    body.reader-night-mode ._19DgIp {
    	background-color: #2f2f2f
    }
    
    ._1kCBjS {
    	justify-content: space-between;
    	font-size: 14px;
    	color: #969696;
    	-webkit-user-select: none;
    	-moz-user-select: none;
    	-ms-user-select: none;
    	user-select: none
    }
    
    ._1kCBjS,._3BUZPB,._18vaTa {
    	display: flex;
    	align-items: center
    }
    
    ._3BUZPB>span {
    	margin-left: 8px
    }
    
    ._3BUZPB:not(:last-child) {
    	margin-right: 12px
    }
    
    ._2Bo4Th {
    	display: flex;
    	align-items: center;
    	justify-content: center;
    	 40px;
    	height: 40px;
    	color: #969696;
    	border: 1px solid #eee;
    	border-radius: 50%;
    	font-size: 18px;
    	cursor: pointer
    }
    
    body.reader-night-mode ._2Bo4Th {
    	border-color: #2f2f2f
    }
    
    
    ._1LOh_5 {
    	cursor: pointer
    }
    
    ._1LOh_5 .anticon {
    	font-size: 12px
    }
    
    ._1x1ok9 {
    	cursor: pointer
    }
    
    ._1x1ok9 .anticon {
    	font-size: 16px
    }
    
    ._1yN79W {
    	background-color: #f2f2f2
    }
    
    ._1yN79W:-ms-input-placeholder {
    	color: #999
    }
    
    ._1yN79W::-ms-input-placeholder {
    	color: #999
    }
    
    ._1yN79W::placeholder {
    	color: #999
    }
    
    body.reader-night-mode ._1yN79W {
    	background-color: #333
    }
    
    ._3uZ5OL {
    	text-align: center;
    	padding: 48px 64px;
      ext-align: center;
      padding: 48px 64px;
       50%;
      position: fixed;
      top: 0;
      height: 540px;
      border-radius: 5px;
      left: 0;
      right: 0;
      bottom: 0;
      background: #eee;
      z-index: 999;
      margin: auto;
    }
    
    ._2PLkjk {
    	display: flex;
    	justify-content: center;
    	align-items: center;
    	margin-bottom: 24px
    }
    
    ._2R1-48 {
    	min- 50px;
    	min-height: 50px;
    	 50px;
    	height: 50px;
    	border-radius: 50%;
    	border: 1px solid #eee
    }
    
    ._2h5tnQ {
    	font-size: 24px;
    	font-weight: 500;
    	margin-left: 16px
    }
    
    ._1-bCJJ {
    	flex-wrap: wrap
    }
    
    ._1-bCJJ,.LMa6S_ {
    	display: flex;
    	justify-content: center
    }
    
    .LMa6S_ {
    	align-items: center;
    	 162.5px;
    	height: 56px;
    	font-size: 16px;
    	color: #969696;
    	margin-bottom: 12px;
    	margin-right: 12px;
    	border-radius: 10px;
    	border: 1px solid #eee;
    	cursor: pointer;
    	-webkit-user-select: none;
    	-moz-user-select: none;
    	-ms-user-select: none;
    	user-select: none
    }
    
    body.reader-night-mode .LMa6S_ {
    	border-color: #2f2f2f
    }
    
    .LMa6S_._1vONvL {
    	color: #ec7259
    }
    
    .LMa6S_._1vONvL,body.reader-night-mode .LMa6S_._1vONvL {
    	border-color: #ec7259
    }
    
    .LMa6S_._1sSZ6C {
    	cursor: not-allowed;
    	color: #969696;
    	opacity: .5
    }
    
    .LMa6S_>i {
    	font-size: 20px
    }
    
    .LMa6S_>span {
    	font-size: 28px;
    	font-style: italic
    }
    
    .LMa6S_:nth-child(3n) {
    	margin-right: 0
    }
    
    .LMa6S_:nth-last-child(-n+3) {
    	margin-bottom: 0
    }
    
    .LMa6S_:last-child {
    	margin-right: 0
    }
    
    ._2ByDWa>span {
    	font-size: 16px;
    	font-style: normal;
    	opacity: 1
    }
    
    ._2ByDWa>input {
    	position: absolute;
    	top: 50%;
    	left: 50%;
    	 100%;
    	height: 36px;
    	margin: 0 auto;
    	text-align: center;
    	transform: translate(-50%,-50%);
    	background-color: transparent;
    	opacity: 0;
    	cursor: pointer
    }
    
    ._2ByDWa>input::-webkit-inner-spin-button,._2ByDWa>input::-webkit-outer-spin-button {
    	display: none
    }
    
    ._2ByDWa._1vONvL>span {
    	opacity: 0
    }
    
    ._2ByDWa._1vONvL>input {
    	opacity: 1;
    	cursor: text
    }
    
    ._3PA8BN>i {
    	font-size: 30px
    }
    
    ._3PA8BN>span {
    	font-size: 16px;
    	font-style: normal;
    	margin-left: 4px
    }
    
    ._3PA8BN,._3PA8BN._1vONvL {
    	color: #404040
    }
    
    body.reader-night-mode ._3PA8BN,body.reader-night-mode ._3PA8BN._1vONvL {
    	color: #b3b3b3
    }
    
    ._1yN79W {
    	display: block;
    	 100%;
    	height: 80px;
    	resize: none;
    	margin-top: 12px;
    	padding: 12px;
    	border: none;
    	border-radius: 10px
    }
    
    ._1_B577 {
    	font-size: 15px;
    	margin: 12px 0
    }
    
    ._3A-4KL {
    	margin-top: 24px;
    	font-size: 18px;
    	font-weight: normal;
    	padding: 10px 48px
    }
    
    .d0hShY {
    	display: flex;
    	align-items: center;
    	background-color: #fafafa;
    	border-radius: 4px;
    	padding: 12px 16px
    }
    
    body.reader-night-mode .d0hShY {
    	background-color: #333
    }
    
    ._27NmgV {
    	border-radius: 50%;
    	border: 1px solid #eee;
    	min- 50px;
    	min-height: 50px;
    	 50px;
    	height: 50px
    }
    
    body.reader-night-mode ._27NmgV {
    	border-color: #2f2f2f
    }
    
    .Uz-vZq {
    	flex-grow: 1;
    	margin: 0 12px;
    	overflow: hidden
    }
    
    .Cqpr1X {
    	display: flex;
    	align-items: center;
    	margin-bottom: 2px
    }
    
    .HC3FFO {
    	flex-shrink: 0;
    	font-size: 16px;
    	font-weight: 500
    }
    ._3GlyHK,.HC3FFO {
    	margin-right: 6px
    }
    ._2WEj6j {
    	font-size: 14px;
    	color: #666;
    	overflow: hidden;
    	text-overflow: ellipsis;
    	white-space: nowrap
    }
    .lJvI3S {
    	font-size: 14px;
    	color: #969696
    }
    .lJvI3S>span {
    	margin-right: 12px
    }
    .lJvI3S>span:last-child {
    	margin-right: 0
    }
    ._3MbC71>span {
    	margin-right: 6px
    }
    ._14FSyQ,.H4XBOO>img {
    	 24px;
    	height: 24px;
    	min- 24px;
    	min-height: 24px;
    	border-radius: 50%;
    	border: 2px solid #fff
    }
    body.reader-night-mode .H4XBOO>img {
    	border-color: #3d3d3d
    }
    ._13lIbp {
    	display: flex;
    	flex-direction: column;
    	align-items: center;
    	margin: 40px 0 32px
    }
    
    ._191KSt {
    	font-size: 16px;
    	font-weight: 500;
    	margin-bottom: 16px
    }
    ._3zdmIj {
    	color: #666;
    	margin-top: 24px
    }
    
    ._37OvKa>i {
    	color: #ec7259;
    	font-size: 20px;
    	margin-right: 8px
    }
    
    
    ._3S34Y_>img {
    	 144px;
    	height: 144px;
    	margin-bottom: 12px
    }
    
    ._2JdSds>span {
    	margin-left: 2px;
    	pointer-events: none
    }
    
    ._3yPTTQ>i {
    	font-size: 16px;
    	margin-right: 4px
    }
    
    </style>
    
    
  • 相关阅读:
    C#应用程序中的输入法
    201871010128杨丽霞《面向对象程序设计(java)》第六七周学习总结
    201871010128杨丽霞《面向对象程序设计(java)》第一周学习总结
    201871010128杨丽霞《面向对象程序设计(java)》第二周学习总结
    201871010128杨丽霞《面向对象程序设计(java)》第四周学习总结
    201871010128杨丽霞《面向对象程序设计(java)》第七周学习总
    201871010128杨丽霞《面向对象程序设计(java)》第十周学习总结
    201871010128杨丽霞《面向对象程序设计(Java)》第十一周学习总结
    201871010128杨丽霞《面向对象程序设计(java)》第八周学习总结
    201871010128杨丽霞《面向对象程序设计(Java)》第十二周学习总结
  • 原文地址:https://www.cnblogs.com/jia-shu/p/14677179.html
Copyright © 2020-2023  润新知