Browse Source

添加等级组件
添加type 2样式
添加下载

martin.ma 4 years ago
parent
commit
c3ac5c3d63

+ 142 - 32
assets/css/dynamic/info.scss

@@ -1,5 +1,6 @@
 .dynamic-info-wrapper-mobile {
   //   margin-top: 10px;
+  width: 100%;
 }
 
 .dynamic-info-main {
@@ -41,22 +42,23 @@
   line-height: 20px;
 }
 
-.dynamic-info-user-level {
-  display: inline-block;
-  background: #ffd257;
-  border-radius: 3px;
-  height: 13px;
-  padding: 0 5px;
+// .dynamic-info-user-level {
+//   display: inline-block;
+//   background: #ffd257;
+//   border-radius: 3px;
+//   height: 13px;
+//   padding: 0 5px;
 
-  font-size: 10px;
-  font-family: FontName, FontName-Regular;
-  font-weight: 400;
-  color: #222222;
-  line-height: 13px;
-  letter-spacing: -0.95px;
-}
+//   font-size: 10px;
+//   font-family: FontName, FontName-Regular;
+//   font-weight: 400;
+//   color: #222222;
+//   line-height: 13px;
+//   letter-spacing: -0.95px;
+// }
 
 .dynamic-info-user-title {
+  margin-top: 3px;
   font-size: 11px;
   font-family: PingFangSC, PingFangSC-Regular;
   font-weight: 400;
@@ -68,8 +70,8 @@
 .dynamic-info-user-menu {
   width: 20px;
   height: 20px;
-    background:url("~@/assets/img/dynamic/menu.png") no-repeat 50% 50%;
-    background-size: 100% auto;
+  background: url("~@/assets/img/dynamic/menu.png") no-repeat 50% 50%;
+  background-size: 100% auto;
 }
 
 .dynamic-info-content {
@@ -106,10 +108,22 @@
 
 .dynamic-info-img-item {
   width: 27.8vw;
-  img {
-    width: 100%;
-    border-radius: 6px;
-  }
+  // height:0;
+  height:27.8vw;
+  // padding-bottom: 100%;
+  position: relative;
+  overflow: hidden;
+  border-radius: 6px;
+  background-position: 50% top;
+  background-repeat: no-repeat;
+  background-size:100% auto
+  // img {
+  //   position: absolute;
+  //   left: 0;
+  //   top: 0;
+  //   width: 100%;
+  //   border-radius: 6px;
+  // }
 }
 
 .dynamic-info-resources-link {
@@ -143,6 +157,10 @@
   font-weight: 400;
   text-align: left;
   color: #222222;
+
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
 }
 
 .dynamic-info-like {
@@ -161,12 +179,12 @@
   align-items: center;
 }
 .dynamic-info-like-count {
-    background:url("~@/assets/img/dynamic/like.png") no-repeat left 50%;
-    background-size: auto 100%;
+  background: url("~@/assets/img/dynamic/like.png") no-repeat left 50%;
+  background-size: auto 100%;
 }
 .dynamic-info-comment-count {
-    background:url("~@/assets/img/dynamic/comment.png") no-repeat left 50%;
-    background-size: auto 100%;
+  background: url("~@/assets/img/dynamic/comment.png") no-repeat left 50%;
+  background-size: auto 100%;
   margin-left: 30px;
 }
 
@@ -189,19 +207,18 @@
   background: #ffffff;
   margin-bottom: 20px;
   border-radius: 10px;
-  
 }
 
 .dynamic-comment-item {
   display: flex;
   padding: 21px 10px 0px;
-  &:nth-last-child(1){
-    .dynamic-comment-content{
-        &::after{
-            display: none
-        }
+  &:nth-last-child(1) {
+    .dynamic-comment-content {
+      &::after {
+        display: none;
+      }
     }
- }
+  }
 }
 
 .dynamic-comment-avatar {
@@ -248,12 +265,12 @@
 .dynamic-comment-more {
   width: 20px;
   height: 20px;
-  background:url("~@/assets/img/dynamic/menu.png") no-repeat 50% 50%;
+  background: url("~@/assets/img/dynamic/menu.png") no-repeat 50% 50%;
   background-size: 100% auto;
 }
 
 .dynamic-comment-content {
-    // padding-right: 10px;
+  // padding-right: 10px;
   margin-top: 4px;
   position: relative;
   overflow: hidden;
@@ -276,3 +293,96 @@
     transform: translateY(50%);
   }
 }
+
+.dynamic-info-resources-area {
+  margin-top: 10px;
+  background: rgba(244, 245, 249, 0.8);
+  border-radius: 10px;
+  padding: 18px 10px 20px;
+}
+.resources-top {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.resources-title {
+  font-size: 14px;
+  font-family: PingFangSC, PingFangSC-Regular;
+  font-weight: 400;
+  text-align: left;
+  color: #222222;
+  line-height: 20px;
+}
+.resources-price {
+  font-size: 14px;
+  font-family: PingFangSC, PingFangSC-Regular;
+  font-weight: 400;
+  text-align: center;
+  color: #308eff;
+  line-height: 20px;
+}
+
+.resource-tag {
+  margin-top: 11px;
+}
+
+.resources-tag-item {
+  display: inline-block;
+  line-height: 1;
+  padding: 10px 5px;
+  background-color: rgba(255, 255, 255, 0.8);
+  border-radius: 3px;
+
+  opacity: 0.8;
+font-size: 11px;
+font-family: PingFangSC, PingFangSC-Regular;
+font-weight: 400;
+// text-align: right;
+color: #666666
+
+}
+
+.resource-company {
+  margin-top: 15px;
+  display: flex;
+}
+
+.resource-company-img {
+  width: 18px;
+  height: 18px;
+  border-radius: 9px;
+  overflow: hidden;
+  img {
+    width: 18px;
+    height: 18px;
+    border-radius: 9px;
+  }
+}
+
+.resource-company-name {
+  flex: 1;
+  margin-left: 5px;
+  font-size: 11px;
+  font-family: PingFangSC, PingFangSC-Regular;
+  font-weight: 400;
+  text-align: left;
+  color: #666666;
+  line-height: 16px;
+}
+
+
+.dynamic-bottom{
+  position:fixed;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  height:155px;
+  background:url('~@/assets/img/dynamic/bg.png') repeat-x left bottom;
+}
+.dynamic-bottom-btn{
+  margin:40px auto 0 ;
+  width:350px;
+  height:78px;
+  background:url('~@/assets/img/dynamic/btn.png') no-repeat 50% 50%;
+}

BIN
assets/img/dynamic/bg.png


BIN
assets/img/dynamic/btn.png


BIN
assets/img/level/level_0.png


BIN
assets/img/level/level_1.png


BIN
assets/img/level/level_10.png


BIN
assets/img/level/level_11.png


BIN
assets/img/level/level_12.png


BIN
assets/img/level/level_2.png


BIN
assets/img/level/level_3.png


BIN
assets/img/level/level_4.png


BIN
assets/img/level/level_5.png


BIN
assets/img/level/level_6.png


BIN
assets/img/level/level_7.png


BIN
assets/img/level/level_8.png


BIN
assets/img/level/level_9.png


+ 1 - 1
components/dynamic/DynamicInfo.js

@@ -44,7 +44,7 @@ export default class DynamicInfoData {
          if (Number(res.status) === 1) {
             let dynamicList = res.data.list
             console.log(dynamicList)
-            dynamicDetail = {...dynamicList[2]}
+            dynamicDetail = {...dynamicList[0]}
          }else{
             this.isExist = false
          }

+ 27 - 0
components/level-tag.vue

@@ -0,0 +1,27 @@
+<template>
+<span v-if="level > 1" class="user-level" :class="'level-'+level"></span>
+</template>
+
+<script>
+export default {
+    props: ['level']
+}
+</script>
+
+<style lang="scss" scoped>
+@for $i from 0 through 12 {
+    .level-#{$i} {
+        background-image: url("~@/assets/img/level/level_0.png");
+    }
+}
+
+.user-level {
+    width: 25px;
+    height: 15px;
+    display: inline-block;
+    background-size: 100% auto;
+    background-position: 50% 50%;
+    background-repeat: no-repeat;
+    vertical-align: baseline;
+}
+</style>

+ 98 - 0
layouts/noheader.vue

@@ -0,0 +1,98 @@
+<template>
+  <div class="container" id="markIsAppWebview" :data-app="deviceType.app">
+     <nuxt class="main"/>
+  </div>
+</template>
+
+<script>
+  import ProginnHeader from "@/components/header";
+  import ProginnFooter from "@/components/footer";
+  import WxHeader from "@/components/wx_header";
+  import {mapState, mapMutations} from "vuex";
+  import Stats from "@/mixins/stats";
+
+  export default {
+    components: {
+      ProginnHeader,
+      ProginnFooter,
+      WxHeader
+    },
+    data() {
+      return {
+        isWeixinApp: true
+      }
+    },
+    mixins: [Stats],
+    computed: {
+      ...mapState(["isPC", "isWeixin", "deviceType", "noneCommonFooter"])
+    },
+    mounted() {
+      console.log("route.path", this.$route);
+      this.isWeixinApp = navigator.userAgent.indexOf("miniProgram") > -1;
+      this.checkTerminal();
+      window.addEventListener("resize", this.checkInnerWidth);
+      // 修改密码处理
+      if (
+        this.$route.path.includes("/setting/check/change_mobile") ||
+        this.$route.path.includes("/setting/check/real_info")
+      ) {
+        // 如果上页不是验证码页面,则认为是复制地址过来,强制踢出
+        if (
+          localStorage.getItem("proginn-history") !== "/setting/check/old_mobile"
+        ) {
+          this.$message("请验证旧手机号。");
+          setTimeout(() => {
+            this.$router.replace("/setting/check/old_mobile");
+          }, 1500);
+        }
+      } else {
+        localStorage.removeItem("proginn-history");
+      }
+    },
+    methods: {
+      ...mapMutations(["updateIsPC", "updateIsWeixin"]),
+      checkTerminal() {
+        this.updateIsPC({
+          isPC: window.innerWidth > 960
+        });
+        this.updateIsWeixin({
+          isWeixin: window.navigator.userAgent
+            .toLowerCase()
+            .match(/MicroMessenger/i)
+        });
+      }
+    }
+  };
+</script>
+
+
+<style>
+  *,
+  *:before,
+  *:after {
+    box-sizing: border-box;
+    margin: 0;
+  }
+
+  .container {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+  }
+
+  .main {
+    min-width: 1000px;
+    min-height: calc(100vh - 376px);
+    margin: 20px 0 30px !important;
+  }
+
+  .__nuxt-error-page .title {
+    font-size: 100%;
+  }
+
+  @media screen and (max-width: 960px) {
+    .main {
+      min-width: auto;
+    }
+  }
+</style>

+ 226 - 127
pages/frontend/dynamic/info.vue

@@ -1,53 +1,98 @@
 <template>
-<ErrorPage404 v-if="!isExist"></ErrorPage404>
-<div v-else :class="mobile ? 'mobileMain' : 'mobileWeb'" :style="{marginTop: mainMarginTop}">
-    <div class="dynamic-info-wrapper-mobile">
-        <div class="dynamic-info-main">
-            <div class="dynamic-info-user">
-                <div class="dynamic-info-user-avatar">
-                    <img :src="dynamicDetail.user_info.icon_url" />
-                </div>
-                <div class="dynamic-info-user-info">
-                    <div class="dynamic-info-user-nickname">{{dynamicDetail.title}} <span class="dynamic-info-user-level">F{{dynamicDetail.user_info.freework_level}}</span></div>
-                    <div class="dynamic-info-user-title">
-                        <span>{{dynamicDetail.title}}</span>
-                        <span>{{dynamicDetail.user_info.tag[1] ? "· "+dynamicDetail.user_info.tag[1].name : ''}}</span>
-                    </div>
-                </div>
-                <div class="dynamic-info-user-menu"></div>
-            </div>
-            <div class="dynamic-info-content">
-                {{dynamicDetail.title}}
+  <ErrorPage404 v-if="!isExist"></ErrorPage404>
+  <div v-else :style="{ marginTop: mainMarginTop, width: '100%' }">
+    <div class="dynamic-info-wrapper-mobile" v-if="isInit">
+      <div class="dynamic-info-main">
+        <div class="dynamic-info-user">
+          <div class="dynamic-info-user-avatar">
+            <img :src="user_info.icon_url || ''" />
+          </div>
+          <div class="dynamic-info-user-info">
+            <div class="dynamic-info-user-nickname">
+              <span>{{ user_info.nickname }}</span>
+              <LevelTag :level="user_info.freework_level"></LevelTag>
             </div>
-            <div class="dynamic-info-type-area">
-                <div class="dynamic-info-type">
-                    # {{dynamicDetail.type_text}}
-                </div>
-            </div>
-            <div class="dynamic-info-img-list">
-                <div class="dynamic-info-img-item" v-for="item in dynamicDetail.img" :key="item.img">
-                    <img :src="item.img" />
-                </div>
+            <div class="dynamic-info-user-title">
+              <span>{{ user_info.tag[0] ? user_info.tag[0].name : "" }}</span>
+              <span>{{
+                user_info.tag[1] ? "· " + user_info.tag[1].name : ""
+              }}</span>
             </div>
+          </div>
+          <div class="dynamic-info-user-menu"></div>
+        </div>
+        <div class="dynamic-info-content">
+          {{ dynamicDetail.title }}
+        </div>
+        <div class="dynamic-info-type-area">
+          <div class="dynamic-info-type"># {{ dynamicDetail.type_text }}</div>
+        </div>
+        <div class="dynamic-info-img-list" v-if="dynamicDetail.img.length > 0">
+          <div
+            class="dynamic-info-img-item"
+            v-for="item in dynamicDetail.img"
+            :key="item.img"
+            :style="{
+                'background-image':'url('+ item.img+')'
+            }"
+          >
+            <!-- <img :src="" /> -->
+          </div>
+        </div>
 
-            <div class="dynamic-info-resources-link">
-                <div class="dynamic-info-resources-img">
-                    <img src="https://iph.href.lu/100x100?fg=666666&bg=cccccc" />
-                </div>
-                <div class="dynamic-info-resources-title">仿微信Flutter开发源码</div>
-            </div>
+        <!-- 根据type去显示 -->
+        <div
+          v-if="dynamicDetail.type != 2"
+          class="dynamic-info-resources-link"
+          @click="gotoPage(resources.resources_url)"
+        >
+          <div class="dynamic-info-resources-img">
+            <img :src="resources.resources_img" />
+          </div>
+          <div class="dynamic-info-resources-title">
+            {{ resources.resources_title }}
+          </div>
+        </div>
 
-            <div class="dynamic-info-like">
-                <div class="dynamic-info-like-item dynamic-info-like-count">
-                    {{dynamicDetail.z_num}}
-                </div>
-                <div class="dynamic-info-like-item dynamic-info-comment-count">
-                    {{dynamicDetail.c_num}}
-                </div>
+        <div
+          v-else
+          class="dynamic-info-resources-area"
+          @click="gotoPage(resources.resources_url)"
+        >
+          <div class="resources-top">
+            <div class="resources-title">{{ resources.resources_title}}</div>
+            <div class="resources-price">{{resources.resources_price}}</div>
+          </div>
+          <div class="resource-tag">
+            <div
+              v-for="item in resources.resources_tag"
+              :key="item"
+              class="resources-tag-item"
+            >
+              {{ item.name }}
+            </div>
+            <!-- <div class="resources-tag-item">产品分析</div>
+                    <div class="resources-tag-item">产品分析</div> -->
+          </div>
+          <div class="resource-company">
+            <div class="resource-company-img">
+              <img src="https://iph.href.lu/100x100?fg=666666&bg=cccccc" />
             </div>
+            <div class="resource-company-name">{{resources.resources_form}}</div>
+          </div>
+        </div>
+
+        <div class="dynamic-info-like">
+          <div class="dynamic-info-like-item dynamic-info-like-count">
+            {{ dynamicDetail.z_num }}
+          </div>
+          <div class="dynamic-info-like-item dynamic-info-comment-count">
+            {{ dynamicDetail.c_num }}
+          </div>
         </div>
+      </div>
 
-        <div class="dynamic-comment-main">
+      <!-- <div class="dynamic-comment-main">
             <div class="dynamic-comment-title">评论</div>
 
             <ul class="dynamic-comment-list">
@@ -97,102 +142,156 @@
                     </div>
                 </li>
             </ul>
-        </div>
+        </div> -->
+    </div>
+
+
+    <div class="dynamic-bottom">
+        <div class="dynamic-bottom-btn" @click="gotoDownload"></div>
     </div>
-</div>
+  </div>
 </template>
 
 <script>
-import {
-    mapState
-} from "vuex"
-import DynamicInfoData from "@/components/dynamic/DynamicInfo.js"
-import qs from "qs"
-import ErrorPage404 from "@/components/error_page/404.vue"
+import { mapState } from "vuex";
+import DynamicInfoData from "@/components/dynamic/DynamicInfo.js";
+import qs from "qs";
+import ErrorPage404 from "@/components/error_page/404.vue";
+import LevelTag from "@/components/level-tag.vue";
 
 export default {
-    name: 'SeoDynamicDetail',
-    data() {
-        return {
-            baseUrl: '',
-            isWeixinApp: true,
-            isExist: true,
-        }
-    },
-    components: {
-        ErrorPage404
-    },
-    head() {
-        const {
-            title = "",
-                keyword = "",
-                description = "",
-                h1 = "",
-                canonical = "",
-                metaLocation
-        } = this.head || {}
-        let obj = {
-            title: title,
-            meta: [{
-                name: "keywords",
-                content: keyword
-            }, {
-                name: "description",
-                content: description
-            }, {
-                name: "h1",
-                content: h1
-            }, {
-                name: "viewport",
-                content: "width=device-width, initial-scale=1.0, viewport-fit=cover"
-            }],
-            link: [{
-                rel: "canonical",
-                href: canonical
-            }]
-        }
-        if (metaLocation) {
-            obj.meta.push({
-                name: "location",
-                content: metaLocation
-            })
-        }
-        return obj
-    },
-    computed: {
-        ...mapState(["deviceType"]),
-        showWxHeader() {
-            return !this.deviceType.app && !this.isWeixinApp &&
-                (this.deviceType.android || this.deviceType.ios)
+  name: "DynamicDetail",
+  layout: "noheader",
+  data() {
+    return {
+      baseUrl: "",
+      isWeixinApp: true,
+      isExist: true,
+      dynamicDetail: {},
+      user_info: {},
+      resources: {},
+      isInit: false
+    };
+  },
+  components: {
+    ErrorPage404,
+    LevelTag
+  },
+  head() {
+    const {
+      title = "",
+      keyword = "",
+      description = "",
+      h1 = "",
+      canonical = "",
+      metaLocation
+    } = this.head || {};
+    let obj = {
+      title: title,
+      meta: [
+        {
+          name: "keywords",
+          content: keyword
+        },
+        {
+          name: "description",
+          content: description
+        },
+        {
+          name: "h1",
+          content: h1
         },
-        mainMarginTop() {
-            if (this.mobile && this.showWxHeader) {
-                return '0 !important'
-            } else if (this.mobile) {
-                return '0px !important'
-            } else {
-                return '20px !important'
-            }
+        {
+          name: "viewport",
+          content: "width=device-width, initial-scale=1.0, viewport-fit=cover"
         }
+      ],
+      link: [
+        {
+          rel: "canonical",
+          href: canonical
+        }
+      ]
+    };
+    if (metaLocation) {
+      obj.meta.push({
+        name: "location",
+        content: metaLocation
+      });
+    }
+    return obj;
+  },
+  computed: {
+    ...mapState(["deviceType"]),
+    showWxHeader() {
+      return (
+        !this.deviceType.app &&
+        !this.isWeixinApp &&
+        (this.deviceType.android || this.deviceType.ios)
+      );
     },
-    async asyncData({
-        ...params
-    }) {
-        let dynamicInfoData = new DynamicInfoData(params)
-        let ans = await dynamicInfoData.dealData()
+    mainMarginTop() {
+      if (this.mobile && this.showWxHeader) {
+        return "0 !important";
+      } else if (this.mobile) {
+        return "0px !important";
+      } else {
+        return "20px !important";
+      }
+    }
+  },
+  // async asyncData({
+  //     ...params
+  // }) {
+  //     let dynamicInfoData = new DynamicInfoData(params)
+  //     let ans = await dynamicInfoData.dealData()
 
-        return {
-            ...ans
-        }
+  //     return {
+  //         ...ans
+  //     }
+  // },
+  mounted() {
+    const self = this;
+    this.isWeixinApp = navigator.userAgent.indexOf("miniProgram") > -1;
+    this.fetchData();
+  },
+  methods: {
+    async fetchData() {
+      // console.log(this)
+      if (!this.$route.params.id) {
+        this.isExist = false;
+        return;
+      }
+      let dynamicId = this.$route.params.id;
+      let res = await this.$axios.$post("/uapi/dynamic/get_dynamic_detail", {
+        dynamic_id: dynamicId
+      });
+      this.isInit = true;
+
+      //   let dynamicDetail = {};
+      if (Number(res.status) === 1) {
+        let dynamicList = res.data.list;
+        this.dynamicDetail = {
+          ...dynamicList[0]
+        };
+        this.user_info = {
+          ...dynamicList[0].user_info
+        };
+        this.resources = {
+          ...dynamicList[0].resources
+        };
+      } else {
+        this.isExist = false;
+      }
     },
-    mounted() {
-        const self = this
-        this.isWeixinApp = navigator.userAgent.indexOf("miniProgram") > -1
+    gotoPage(url) {
+      location.href = url;
     },
-    methods: {
-
+    gotoDownload(){
+        location.href = "https://a.app.qq.com/o/simple.jsp?pkgname=com.proginn"
     }
-}
+  }
+};
 </script>
 
 <style lang="scss" scoped>
@@ -200,10 +299,10 @@ export default {
 </style>
 <style lang="scss">
 strong {
-    font-weight: bold !important;
+  font-weight: bold !important;
 }
 
 em {
-    font-style: italic !important;
+  font-style: italic !important;
 }
 </style>

+ 1 - 1
plugins/seoRouter.js

@@ -158,7 +158,7 @@ const extendRoutes = (routes, resolve) => {
     // 分享动态详情页
     ...[
       {
-        name: 'SeoDynamicDetail',
+        name: 'DynamicDetail',
         path: '/dynamic/info/:id?',
         component: resolve(__dirname, '../pages/frontend/dynamic/info.vue')
       }