123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- <template>
- <div class="doc-container van-hairline--bottom" @click="clickCard">
- <div class="docs-card oneline" v-if="cardType === 'oneline'" key="docs-card">
- <div class="docs-header flex-r-c center">
- <van-icon :name="docTypeIcon" />
- <div class="d-title flex van-ellipsis" v-html="hightLightTitle"></div>
- <Price :price="price" />
- </div>
- </div>
- <div class="docs-card image flex-r-c" v-else-if="cardType === 'image'" key="docs-card">
- <div class="image-container">
- <img v-lazy="imageSrc" />
- <van-icon class="doc-type-icon" :name="docTypeIcon" />
- </div>
- <div class="image-info-container flex-c-c flex">
- <div class="d-title van-multi-ellipsis--l2">{{ title }}</div>
- <div class="card-info-item">
- <div>
- <div class="card-info-item uploader" v-if="uploader">贡献者:{{ uploader }}</div>
- <div class="subinfo-container subinfo-items">
- <span class="subinfo-item" :class="index === subInfo.length - 1 ? 'last' : ''"
- v-for="(item, index) in subInfo" :key="index">{{ item }}</span>
- </div>
- </div>
- <div class="card-info-item price">
- <slot name="price">
- <Price :price="price" v-if="price !== -1" />
- </slot>
- </div>
- </div>
- </div>
- </div>
- <div class="docs-card" v-else key="docs-card">
- <div class="docs-header flex-r-c">
- <van-icon :name="docTypeIcon" />
- <div class="d-title flex van-ellipsis" v-html="hightLightTitle"></div>
- </div>
- <div class="docs-content docs-desc van-multi-ellipsis--l2" v-if="hightLightDesc" v-html="hightLightDesc"></div>
- <div class="docs-footer flex-r-c center">
- <div class="c-f-left subinfo-container">
- <span class="f-l-item subinfo-item card-time" :class="index === subInfo.length - 1 ? 'last' : ''"
- v-for="(item, index) in subInfo" :key="index">{{ item }}</span>
- <slot name="leftEnd">
- <span class="type-tag"
- v-if="productType"
- :class="productType === 2 ? 'boutique' : 'free'">{{ productType === 2 ? '付费精品' : '会员免费' }}</span>
- </slot>
- </div>
- <div class="c-f-right flex-r-c">
- <slot name="price">
- <Price :price="price" v-if="price !== -1" />
- </slot>
- </div>
- </div>
- </div>
- </div>
- </template>
- <script lang="ts">
- import { Component, Vue, Prop } from 'vue-property-decorator'
- import Price from '@/components/docs-card/Price.vue'
- import { Icon } from 'vant'
- import { replaceKeyword, docTypeConvert } from '@/utils/globalFunctions'
- @Component({
- name: 'docs-card',
- components: {
- [Icon.name]: Icon,
- Price
- }
- })
- export default class DocsCard extends Vue {
- @Prop({ default: '' }) title!: string;
- @Prop({ default: '' }) cardType?: string | undefined; // oneline, image
- @Prop({ default: '' }) desc?: string | undefined;
- @Prop({ default: 'pdf' }) docType?: string | undefined; // 文档类型
- @Prop({ default: '' }) imageSrc?: string | undefined;
- @Prop({ default: '' }) uploader?: string | undefined;
- @Prop({ default: -1 }) price?: string | number;
- @Prop({ default: false }) isVip?: boolean;
- @Prop({ default: 0 }) productType?: number;
- @Prop({
- type: Array,
- default () {
- return []
- }
- }) subInfo?: Array<string>;
- @Prop({
- type: Array,
- default () {
- return []
- }
- }) highlightKey?: Array<string>;
- get docTypeIcon () {
- return `diy-${docTypeConvert(this.docType)}`
- }
- get hightLightTitle () {
- return replaceKeyword(this.title, this.highlightKey, [
- '<span class="highlight-text">',
- '</span>'
- ])
- }
- get hightLightDesc () {
- return replaceKeyword(this.desc, this.highlightKey, [
- '<span class="highlight-text">',
- '</span>'
- ])
- }
- clickCard () {
- this.$emit('onClick')
- }
- }
- </script>
- <style lang="scss" scoped>
- .docs-card {
- padding: 16px;
- box-sizing: border-box;
- background-color: #fff;
- .type-tag {
- padding: 4px 5px;
- border-radius: 2px;
- font-size: 10px;
- white-space: nowrap;
- &.free {
- background: linear-gradient(98deg, #FFA674 0%, #F01212 100%);
- color: #fff;
- }
- &.boutique{
- background: linear-gradient(270deg, #F1D090 0%, #FAE7CA 100%);
- color: #C26F33;
- }
- }
- &.oneline {
- padding: 8px 16px;
- .docs-header {
- .d-title {
- margin: 0 6px;
- }
- }
- }
- .docs-desc,
- .d-title {
- ::v-deep {
- em {
- color: $color_main;
- }
- }
- }
- @include diy-icon('pdf');
- @include diy-icon('word');
- @include diy-icon('excel');
- @include diy-icon('ppt');
- @include diy-icon('txt');
- .docs-header {
- .d-title {
- margin-left: 4px;
- font-size: 16px;
- color: #171826;
- }
- }
- .docs-content {
- margin-top: 8px;
- font-size: 13px;
- line-height: 20px;
- color: #5F5E64;
- }
- .docs-footer {
- margin-top: 8px;
- justify-content: space-between;
- }
- .subinfo-container {
- color: #999;
- font-size: 12px;
- line-height: 18px;
- .subinfo-item {
- position: relative;
- margin-right: 16px;
- &.last {
- margin-right: 8px;
- }
- &.noline:after,
- &.last:after {
- content: unset;
- }
- &:after {
- content: "";
- position: absolute;
- top: 50%;
- right: -8px;
- margin-top: -6px;
- width: 1px;
- height: 12px;
- background-color: rgba($color: #000, $alpha: 0.05);
- }
- }
- }
- .image-container {
- position: relative;
- width: 100px;
- height: 124px;
- border: 1px solid rgba($color: #000, $alpha: 0.05);
- border-radius: 6px;
- overflow: hidden;
- img {
- width: 100%;
- height: 100%;
- }
- .doc-type-icon {
- position: absolute;
- right: 2px;
- bottom: 3px;
- }
- }
- .image-info-container {
- margin-left: 17px;
- .card-info-item {
- margin-top: 2px;
- }
- .uploader {
- color: #999;
- font-size: 12px;
- line-height: 18px;
- }
- .price {
- margin-top: 8px;
- }
- }
- &:active {
- background-color: #f5f6f7;
- }
- }
- </style>
|