yuelujie 3 months ago
parent
commit
60be7c25f7
49 changed files with 3046 additions and 580 deletions
  1. 9 0
      apps/bigmember_pc/src/api/modules/common.js
  2. 38 1
      apps/bigmember_pc/src/api/modules/pay.js
  3. BIN
      apps/bigmember_pc/src/assets/images/credit-report-icon.png
  4. BIN
      apps/bigmember_pc/src/assets/images/投标企业信用报告.pdf
  5. 20 1
      apps/bigmember_pc/src/router/modules/order.js
  6. 22 4
      apps/bigmember_pc/src/router/modules/report.js
  7. 2 1
      apps/bigmember_pc/src/store/order.js
  8. 86 20
      apps/bigmember_pc/src/views/article-content/components/ContentHeader.vue
  9. 14 0
      apps/bigmember_pc/src/views/article-content/composables/useArticleUtil.js
  10. 11 2
      apps/bigmember_pc/src/views/article-content/composables/useContentStore.js
  11. 10 3
      apps/bigmember_pc/src/views/order/components/big-member/header-adsense.vue
  12. 4 0
      apps/bigmember_pc/src/views/order/components/common/form.vue
  13. 22 0
      apps/bigmember_pc/src/views/order/components/credit-report/buy-tip.vue
  14. 353 0
      apps/bigmember_pc/src/views/order/components/credit-report/info.vue
  15. 9 2
      apps/bigmember_pc/src/views/order/components/data-pack/header-adsense.vue
  16. 9 2
      apps/bigmember_pc/src/views/order/components/vipsubscribe/header-adsense.vue
  17. 1 1
      apps/bigmember_pc/src/views/order/layout.vue
  18. 498 0
      apps/bigmember_pc/src/views/reportDownload/examine.vue
  19. 153 0
      apps/bigmember_pc/src/views/reportDownload/preview.vue
  20. 458 276
      apps/bigmember_pc/src/views/reportDownload/record.vue
  21. 19 0
      apps/mobile/src/api/modules/pay.js
  22. BIN
      apps/mobile/src/assets/image/example-min.pdf
  23. BIN
      apps/mobile/src/assets/image/reportanalysis/credit-corner-bg.png
  24. 13 1
      apps/mobile/src/assets/js/productLink.js
  25. 0 1
      apps/mobile/src/main.js
  26. 10 1
      apps/mobile/src/router/modules/common.js
  27. 17 0
      apps/mobile/src/router/modules/order.js
  28. 14 1
      apps/mobile/src/store/modules/createOrder.js
  29. 2 2
      apps/mobile/src/views/ai-search/index.vue
  30. 74 28
      apps/mobile/src/views/article/components/ContentHeader.vue
  31. 12 2
      apps/mobile/src/views/article/components/PDF.vue
  32. 3 0
      apps/mobile/src/views/article/content-new.vue
  33. 0 1
      apps/mobile/src/views/article/content.vue
  34. 168 0
      apps/mobile/src/views/common/pdfViewExample.vue
  35. 22 5
      apps/mobile/src/views/create-order/components/bigmember/HeaderAdsense.vue
  36. 14 0
      apps/mobile/src/views/create-order/components/creditreport/Default.vue
  37. 110 0
      apps/mobile/src/views/create-order/components/creditreport/Footer.vue
  38. 351 0
      apps/mobile/src/views/create-order/components/creditreport/ProductionCard.vue
  39. 22 5
      apps/mobile/src/views/create-order/components/datapack/HeaderAdsense.vue
  40. 22 5
      apps/mobile/src/views/create-order/components/vipsubscribe/HeaderAdsense.vue
  41. 210 102
      apps/mobile/src/views/reportAnalysis/components/listItem.vue
  42. 160 46
      apps/mobile/src/views/reportAnalysis/reportDownload.vue
  43. 6 6
      apps/mobile/vite.config.js
  44. 2 1
      configs/proxy/dev-proxy.js
  45. 13 13
      package.json
  46. 56 29
      plugins/bind-phone-mobile/src/utils/appFn.js
  47. 0 8
      plugins/gift-friends/src/entry.js
  48. 0 8
      plugins/gift-friends/src/utils/plugins/index.js
  49. 7 2
      plugins/login-auth/src/module-model/wxQrcode.ts

+ 9 - 0
apps/bigmember_pc/src/api/modules/common.js

@@ -15,3 +15,12 @@ export function getCustomInfo (data) {
     data
   })
 }
+
+// 附件上传
+export function ajaxUploadFile(data) {
+  return request({
+    url: '/front/filemanage/upload',
+    method: 'post',
+    data
+  })
+}

+ 38 - 1
apps/bigmember_pc/src/api/modules/pay.js

@@ -72,7 +72,7 @@ export function getPDFPackDetail(params) {
 export function getPDFPackBalance() {
   return request({
     url: '/jypay/pdfExportPack/account',
-    method: 'post',
+    method: 'post'
   })
 }
 
@@ -128,3 +128,40 @@ export function getGiftRecordDetail(data) {
     data: qs.stringify(data)
   })
 }
+
+// 投标企业信用报告-信用报告查询
+export function ajaxGetCreditReport(data) {
+  data = qs.stringify(data)
+  return request({
+    url: '/subscribepay/bidCreditReport/report/get',
+    method: 'post',
+    data
+  })
+}
+
+// 投标企业信用报告-信用报告修改
+export function ajaxUpdateCreditReport(data) {
+  return request({
+    url: '/subscribepay/bidCreditReport/report/update',
+    method: 'post',
+    data
+  })
+}
+
+// 投标企业信用报告-投标企业名称联想
+export function ajaxBiddingEntSearch(data) {
+  data = qs.stringify(data)
+  return request({
+    url: '/subscribepay/bidCreditReport/entSearch',
+    method: 'post',
+    data
+  })
+}
+
+// 投标企业信用报告-获取配置项
+export function ajaxGetConfig() {
+  return request({
+    url: '/subscribepay/config',
+    method: 'post'
+  })
+}

BIN
apps/bigmember_pc/src/assets/images/credit-report-icon.png


BIN
apps/bigmember_pc/src/assets/images/投标企业信用报告.pdf


+ 20 - 1
apps/bigmember_pc/src/router/modules/order.js

@@ -293,7 +293,26 @@ export default [
             }
           }
         ]
-      }
+      },
+      {
+        path: 'credit-report',
+        components: commonOrder({
+          info: () => import('@/views/order/components/credit-report/info.vue')
+        }),
+        children: [
+          {
+            path: '',
+            meta: {
+              title: '购买投标企业信用报告',
+              productId: 150
+            },
+            components: {
+              'buy-tip': () =>
+                import('@/views/order/components/credit-report/buy-tip.vue')
+            }
+          }
+        ]
+      },
     ]
   }
 ]

+ 22 - 4
apps/bigmember_pc/src/router/modules/report.js

@@ -9,7 +9,7 @@ export default [
     },
     component: () => import('@/views/reportDownload/index.vue')
   },
-  //下载的PDF
+  // 下载的PDF
   {
     path: '/report/pdf',
     name: 'report_download_pdf',
@@ -18,20 +18,38 @@ export default [
       {
         path: 'market',
         name: 'pdf_market',
-        component: () => import('@/views/download-pdf/marketReport.vue'),
+        component: () => import('@/views/download-pdf/marketReport.vue')
       },
       // 企业中标分析
       {
         path: 'ent',
         name: 'pdf_ent',
-        component: () => import('@/views/download-pdf/entReport.vue'),
+        component: () => import('@/views/download-pdf/entReport.vue')
       },
       // 业主采购分析
       {
         path: 'prop',
         name: 'pdf_prop',
-        component: () => import('@/views/download-pdf/propReport.vue'),
+        component: () => import('@/views/download-pdf/propReport.vue')
       }
     ]
+  },
+  // 报告样例/报告预览
+  {
+    path: '/free/report/preview',
+    name: 'report_preview',
+    meta: {
+      title: '报告预览'
+    },
+    component: () => import('@/views/reportDownload/preview.vue')
+  },
+  // 报告审核
+  {
+    path: '/free/report/examine',
+    name: 'report_examine',
+    meta: {
+      title: '报告审核'
+    },
+    component: () => import('@/views/reportDownload/examine.vue')
   }
 ]

+ 2 - 1
apps/bigmember_pc/src/store/order.js

@@ -71,7 +71,8 @@ const productNameMap = {
   118: '剑鱼文库会员',
   201: '企业中标分析报告下载包',
   202: '业主采购分析报告下载包',
-  203: '市场分析定制报告下载包'
+  203: '市场分析定制报告下载包',
+  150: '投标企业信用报告'
 }
 
 const Hooks = {

+ 86 - 20
apps/bigmember_pc/src/views/article-content/components/ContentHeader.vue

@@ -7,7 +7,8 @@ import {
   ContentModel,
   ContentId,
   IsSunPublishContent,
-  useRenMaiModel
+  useRenMaiModel,
+  showCreditReportButton
 } from '@/views/article-content/composables/useContentStore'
 import { computed, getCurrentInstance, onMounted, ref } from 'vue'
 import { useRoute } from 'vue-router/composables'
@@ -19,7 +20,10 @@ import BidrenewalDialog from '@/views/BidrenewalDialog/index.vue'
 import { useQuickJoinBidModel } from '@/composables/quick-join-bid'
 import WorkspaceButtonGroup from '@/components/dialog/WorkspaceButtonGroup.vue'
 import ContentBIActions from '@/views/article-content/components/ContentBIActions.vue'
-import { GetInWhichContainer } from '@/views/article-content/composables/useArticleUtil'
+import {
+  GetInWhichContainer,
+  doOpenCreditReportPage
+} from '@/views/article-content/composables/useArticleUtil'
 
 const getters = useStore().getters
 const vt = computed(() => {
@@ -36,7 +40,9 @@ const headerType = computed(() => {
 
 const sunPublishContent = computed(() => IsSunPublishContent.value)
 
-const headerTypeShow = computed(() => ContentModel.value.isSelfSite || sunPublishContent.value)
+const headerTypeShow = computed(
+  () => ContentModel.value.isSelfSite || sunPublishContent.value
+)
 
 const keepLabel = [
   {
@@ -108,6 +114,13 @@ const {
   showRenMaiButton,
   loading: remMaiLoading
 } = useRenMaiModel(ContentModel)
+
+// console.log(ContentModel.value, ContentModel.value?._ob?.topType, ContentModel.value?._ob?.subType, ContentModel.value.isCaigouyixiang)
+const buyerName = ref('')
+buyerName.value = ContentModel.value?._summary?._s?.buyer || ''
+const infoType = computed(() => {
+  return ContentModel.value?._ob?.topType || ContentModel.value?._ob?.subType
+})
 </script>
 
 <template>
@@ -153,7 +166,6 @@ const {
             <span class="text">转给同事</span>
           </div>
         </template>
-        
 
         <div class="action-item">
           <el-popover
@@ -206,7 +218,6 @@ const {
             ></article-star>
           </div>
         </template>
-        
       </div>
       <div class="actions" v-if="isUseBIActions">
         <content-b-i-actions
@@ -258,18 +269,37 @@ const {
         </div>
       </div>
     </div>
-    <div class="expands-actions" v-if="!sunPublishContent">
-      <div class="expands-actions-l"></div>
-      <div class="expands-actions-r">
-        <el-button
-          type="primary"
-          v-if="showRenMaiButton"
-          :loading="remMaiLoading"
-          class="relationship-button"
-          @click="findRenMai"
-        >
-          <i class="iconfont icon-renmai"></i>找人脉
-        </el-button>
+    <div
+      class="flex flex-(items-center justify-end)"
+      v-if="showCreditReportButton"
+    >
+      <div class="credit-report">
+        <div class="report-container">
+          <div class="report-text">
+            通过信用背书、风险预警、政策适配,赋能投标突围
+          </div>
+          <button
+            class="report-btn"
+            :data-info-type="infoType"
+            @click="doOpenCreditReportPage($event, buyerName)"
+          >
+            投标企业信用报告
+          </button>
+        </div>
+      </div>
+      <div class="expands-actions" v-if="!sunPublishContent">
+        <div class="expands-actions-l"></div>
+        <div class="expands-actions-r">
+          <el-button
+            type="primary"
+            v-if="showRenMaiButton"
+            :loading="remMaiLoading"
+            class="relationship-button"
+            @click="findRenMai"
+          >
+            <i class="iconfont icon-renmai"></i>找人脉
+          </el-button>
+        </div>
       </div>
     </div>
     <!-- 分享弹窗 -->
@@ -348,10 +378,10 @@ const {
   .tags {
     margin-top: 12px;
     .tag-orange {
-      color: #FA6F33;
-      background-color: #FFF1EB;
+      color: #fa6f33;
+      background-color: #fff1eb;
       &.border {
-        border: 1px solid #F56500;
+        border: 1px solid #f56500;
       }
     }
   }
@@ -487,10 +517,46 @@ const {
   justify-content: space-between;
 }
 .relationship-button {
+  margin-left: 10px;
   padding: 6px 20px;
   height: 30px;
+  background: linear-gradient(281deg, #28c1e2 3.53%, #5fd4e3 98.32%);
+  border: 0;
   .iconfont {
     margin-right: 2px;
   }
 }
+.credit-report {
+  display: flex;
+  justify-content: flex-end;
+  .report-container {
+    display: flex;
+    height: 30px;
+    margin-top: 8px;
+    align-items: center;
+    background: rgba(42, 190, 209, 0.16);
+    border-radius: 4px;
+    border: 1px solid rgba(42, 190, 209, 0.16);
+  }
+  .report-text {
+    flex: 1;
+    display: flex;
+    align-items: center;
+    height: 30px;
+    padding: 0 12px;
+    color: #2abed1;
+    font-size: 14px;
+  }
+  .report-btn {
+    display: flex;
+    align-items: center;
+    height: 30px;
+    margin-right: -1px;
+    color: #fff;
+    padding: 0 12px;
+    font-size: 14px;
+    border-radius: 4px;
+    background: linear-gradient(281deg, #28c1e2 3.53%, #5fd4e3 98.32%);
+  }
+}
 </style>

+ 14 - 0
apps/bigmember_pc/src/views/article-content/composables/useArticleUtil.js

@@ -88,3 +88,17 @@ export function GetInWhichContainer() {
   const InWhichContainer = window.parent !== window ? 'in-app' : 'in-web'
   return InWhichContainer
 }
+
+// 打开企业信用报告购买页
+export function doOpenCreditReportPage(event, buyer = '') {
+  const btnName = event.target.textContent.trim() || '投标企业信用报告'
+  const infoType = event.target.dataset.infoType || event.currentTarget.dataset.infoType || ''
+  const breakName = `${btnName}_${infoType}`
+  // 自定义埋点上报事件(数据统计需求:点击信用报告按钮要求统计到当前标讯的信息类型)
+  try {
+    window.__EasyJTrack.addTrack(breakName)
+    window.open('/swordfish/page_big_pc/order/credit-report?buyer=' + buyer, '_blank')
+  } catch (error) {
+    window.open('/swordfish/page_big_pc/order/credit-report?buyer=' + buyer, '_blank')
+  }
+}

+ 11 - 2
apps/bigmember_pc/src/views/article-content/composables/useContentStore.js

@@ -103,7 +103,8 @@ async function useContentStore() {
       ContentPageLoading.value = false
       if (IsSunPublishContent.value && model.content.changedTitle) {
         setPageTDK(model.content.tdk, window.top.document)
-      } else {
+      }
+      else {
         setPageTDK(model.content.tdk)
       }
     })
@@ -185,6 +186,13 @@ function useRenMaiModel(ContentModel) {
   }
 }
 
+const showCreditReportButton = computed(() => {
+  return (
+    ['采购意向', '预告', '招标'].includes(ContentModel.value?._ob?.topType)
+    || ContentModel.value.isCaigouyixiang
+  )
+})
+
 export {
   useContentStore,
   useRenMaiModel,
@@ -198,5 +206,6 @@ export {
   hasPowerToReadSunPublishContent,
   IsSunPublishContent,
   ContentIsError,
-  ContentErrorText
+  ContentErrorText,
+  showCreditReportButton
 }

+ 10 - 3
apps/bigmember_pc/src/views/order/components/big-member/header-adsense.vue

@@ -1,5 +1,5 @@
 <template>
-  <div className="data-pack-header-adsense">
+  <div class="bigmember-header-adsense header-adsense">
     <AdContainer
       :exposure-prefix="'PC购买页轮播广告位-' + code + '-'"
       :code="code"
@@ -11,7 +11,7 @@
 import AdContainer from '@/views/workspace/components/AdContainer.vue'
 
 export default {
-  name: 'data-pack-header-adsense',
+  name: 'bigmember-header-adsense',
   components: {
     AdContainer
   },
@@ -24,6 +24,13 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-.vip-subscribe-adsense {
+.header-adsense {
+  padding-top: 22px;
+  padding-bottom: 8px;
+  ::v-deep {
+    .el-carousel__container {
+      height: 80px;
+    }
+  }
 }
 </style>

+ 4 - 0
apps/bigmember_pc/src/views/order/components/common/form.vue

@@ -62,7 +62,11 @@ export default {
             phone: this.form.phone
           },
           this.form,
+<<<<<<< HEAD
           { phone: token ? phone : data.phone }
+=======
+          { phone: data.phone, reportMail: data.reportMail }
+>>>>>>> main
         )
         this.updateFormStatus(this.form)
       }

+ 22 - 0
apps/bigmember_pc/src/views/order/components/credit-report/buy-tip.vue

@@ -0,0 +1,22 @@
+<template>
+  <div class="buy-tip">
+    <p>购买须知:</p>
+    <p>剑鱼平台产品与服务属于虚拟数字产品,鉴于服务的特殊性,一旦开通权益不支持退款,请确认无误后进行支付。</p>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'buy-tip',
+}
+</script>
+
+<style scoped>
+.buy-tip {
+  margin-top: 28px;
+  font-size: 12px;
+  font-weight: 400;
+  color: #888888;
+  line-height: 16px;
+}
+</style>

+ 353 - 0
apps/bigmember_pc/src/views/order/components/credit-report/info.vue

@@ -0,0 +1,353 @@
+<template>
+  <div class="report-order-info">
+    <div class="report-order-info__header flex flex-justify-between">
+      <div>
+        <p class="report-role">报告作用:</p>
+        <p class="report-desc">
+          信用报告通过信用背书、风险预警、政策适配,三大核心作用,成为投标企业参与市场竞争的关键工具。
+        </p>
+      </div>
+      <button type="button" class="sample-btn" @click="onViewReportSample">
+        查看报告样例
+      </button>
+    </div>
+    <div class="report-order-info__main">
+      <el-form
+        :model="ruleForm"
+        :rules="rules"
+        ref="ruleForm"
+        label-width="104px"
+        @validate="updateFormState"
+      >
+        <el-form-item label="投标企业名称" prop="biddingName">
+          <el-select
+            v-model="ruleForm.biddingCode"
+            filterable
+            remote
+            :remote-method="querySearchEnt"
+            :loading="loading"
+            placeholder="必填"
+            :popper-append-to-body="false"
+            @change="selectBiddingName"
+          >
+            <el-option
+              v-for="item in biddingOptions"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="招标单位名称" prop="buyerName">
+          <el-autocomplete
+            class="inline-input"
+            v-model="ruleForm.buyerName"
+            :fetch-suggestions="querySearchBuyer"
+            :popper-append-to-body="false"
+            :highlight-first-item="true"
+            placeholder="必填"
+            @select="selectBuyerName"
+          ></el-autocomplete>
+        </el-form-item>
+        <el-form-item label="邮箱" prop="email">
+          <el-input
+            v-model="ruleForm.email"
+            placeholder="必填,报告将发送至邮箱"
+          ></el-input>
+        </el-form-item>
+        <p class="buy-notify">
+          支付成功后,系统将在{{
+            bidCreditReport_makeTime
+          }}内将报告发送至您的邮箱,您也可前往“资产-报告下载记录”查看详情。
+        </p>
+      </el-form>
+    </div>
+  </div>
+</template>
+
+<script>
+import { Form, FormItem, Input, Autocomplete, Select, Option } from 'element-ui'
+import { mapActions, mapMutations, mapGetters } from 'vuex'
+import {
+  ajaxGetConfig,
+  getBuyerAssociation,
+  ajaxBiddingEntSearch
+} from '@/api/modules'
+
+export default {
+  name: 'credit-report-order-info',
+  components: {
+    [Form.name]: Form,
+    [FormItem.name]: FormItem,
+    [Input.name]: Input,
+    [Autocomplete.name]: Autocomplete,
+    [Select.name]: Select,
+    [Option.name]: Option
+  },
+  data() {
+    const validateEmail = (rule, value, callback) => {
+      const status = /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)
+      if (value === '') {
+        return callback(new Error('邮箱不能为空'))
+      } else {
+        if (!status) {
+          return callback(new Error('邮箱格式错误'))
+        } else {
+          callback()
+        }
+      }
+    }
+    return {
+      ruleForm: {
+        biddingName: '',
+        biddingCode: '',
+        buyerName: '',
+        email: ''
+      },
+      rules: {
+        biddingName: [
+          { required: true, message: '投标企业名称不能为空', trigger: 'change' }
+        ],
+        buyerName: [
+          { required: true, message: '招标单位名称不能为空', trigger: 'change' }
+        ],
+        email: [{ required: true, validator: validateEmail, trigger: 'change' }]
+      },
+      reportInfo: {},
+      biddingOptions: [],
+      buyerOptions: [],
+      loading: false,
+      bidCreditReport_makeTime: ''
+    }
+  },
+  computed: {
+    ...mapGetters('order', ['productFormInfo']),
+    pass() {
+      const emailPass =
+        this.ruleForm.email &&
+        /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(this.ruleForm.email)
+      return Boolean(
+        this.ruleForm.biddingName && this.ruleForm.buyerName && emailPass
+      )
+    },
+    reportMail() {
+      return this.productFormInfo?.reportMail || ''
+    }
+  },
+  watch: {
+    reportMail: {
+      immediate: true,
+      handler(newVal) {
+        if (newVal) {
+          this.ruleForm.email = newVal
+        }
+      }
+    }
+  },
+  async created() {
+    if (this.$route.query && this.$route.query.buyer) {
+      this.ruleForm.buyerName = this.$route.query.buyer
+    }
+    this.getConfigInfo()
+    // 获取产品信息
+    await this.setProductInfo({
+      id: this.$route.meta.productId,
+      hooks: {
+        submit: this.doSubmit.bind(this)
+      }
+    })
+    this.updateUI({
+      submitText: '立即抢购'
+    })
+    this.updateFormState()
+  },
+  methods: {
+    ...mapMutations('order', ['updateUI', 'updateCanNextMap']),
+    ...mapActions('order', ['setProductInfo']),
+    updateFormState() {
+      this.updateCanNextMap({
+        spec: this.pass
+      })
+    },
+    selectBiddingName(value) {
+      const selected = this.biddingOptions.find((item) => item.value === value)
+      if (selected) {
+        this.ruleForm.biddingName = selected.label
+      }
+    },
+    async querySearchEnt(queryString) {
+      if (queryString) {
+        this.loading = true
+        const { error_code: code, data } = await ajaxBiddingEntSearch({
+          entName: queryString
+        })
+        if (code === 0) {
+          this.biddingOptions = data?.map((item) => ({
+            value: item.cert_no,
+            label: item.name
+          }))
+        }
+        this.loading = false
+      } else {
+        this.biddingOptions = []
+      }
+    },
+    async querySearchBuyer(queryString, cb) {
+      if (queryString) {
+        const { error_code: code, data } = await getBuyerAssociation({
+          name: queryString
+        })
+        if (code === 0 && data && data?.list.length) {
+          this.buyerOptions = data?.list.map((item) => ({
+            value: item,
+            label: item
+          }))
+          cb(this.buyerOptions)
+        } else {
+          cb([])
+        }
+      } else {
+        cb([])
+      }
+    },
+    selectBuyerName(item) {
+      this.ruleForm.buyerName = item.label
+    },
+    async getConfigInfo() {
+      const { error_code: code, data } = await ajaxGetConfig()
+      if (code === 0 && data) {
+        this.bidCreditReport_makeTime = data?.bidCreditReport_makeTime || ''
+      }
+    },
+    onViewReportSample() {
+      // const link = this.$router.resolve({
+      //   path: '/free/report/preview',
+      //   query: {
+      //     source: 'bidCreditReportPreview'
+      //   }
+      // })
+      // window.open(link.href, '_blank')
+      window.open(
+        '/swordfish/page_big_pc/free/report/preview?source=bidCreditReportPreview',
+        '_blank'
+      )
+    },
+    /**
+     * 订单提交事件
+     * @param payload
+     * @param next
+     * @returns {Promise<*>}
+     */
+    async doSubmit(payload, next) {
+      // 处理参数格式化
+      const params = {
+        product: payload.productName,
+        productId: payload.productSpecId,
+        discountId: payload.offersId,
+        lotteryId: payload.offersId,
+        activityType: payload.activityType,
+        data: {
+          company: this.ruleForm.biddingName,
+          cert_no: this.ruleForm.biddingCode,
+          buyer: this.ruleForm.buyerName,
+          email: this.ruleForm.email,
+          order_phone: this.productFormInfo?.phone
+        }
+      }
+      // 发送请求
+      const { data, error_code: code, error_msg: message } = await next(params)
+      if (code === 0 && data?.needPay) {
+        const orderCode = data.order_code
+        location.href = '/front/creditReport/orderPay/' + orderCode
+      } else {
+        this.$message({
+          message: message || '创建订单失败,请刷新重试',
+          type: 'warning'
+        })
+      }
+      // 处理成功回调
+      return true
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.report-order-info {
+  padding: 0 32px;
+  &__header {
+    padding: 24px 0;
+    border-bottom: 1px solid #e0e0e0;
+  }
+  .report-role {
+    font-size: 14px;
+    line-height: 24px;
+    color: #1d1d1d;
+  }
+  .report-desc {
+    font-size: 14px;
+    line-height: 22px;
+    color: #686868;
+  }
+  .sample-btn {
+    width: 100px;
+    height: 30px;
+    line-height: 30px;
+    background: $color_main;
+    border-radius: 4px;
+    color: #fff;
+    font-size: 14px;
+  }
+  &__main {
+    padding: 24px 0 16px;
+    .buy-notify {
+      padding-left: 104px;
+      font-size: 14px;
+      color: #686868;
+      line-height: 22px;
+    }
+  }
+  ::v-deep {
+    .el-form-item__label {
+      padding-right: 8px;
+      font-size: 14px;
+      color: #1d1d1d;
+      line-height: 22px;
+      text-align: left;
+    }
+    .el-input__inner {
+      width: 590px;
+      height: 36px;
+      padding: 0 12px;
+      line-height: 36px;
+      color: #1d1d1d;
+    }
+    .el-form-item {
+      display: flex;
+      align-items: center;
+      margin-bottom: 20px;
+      &:last-of-type {
+        margin-bottom: 8px;
+        &.is-error {
+          margin-bottom: 20px;
+        }
+      }
+    }
+    .el-form-item__content {
+      margin-left: 0 !important;
+    }
+    .el-form-item.is-required:not(.is-no-asterisk)
+      .el-form-item__label-wrap
+      > .el-form-item__label:before,
+    .el-form-item.is-required:not(.is-no-asterisk)
+      > .el-form-item__label:before {
+      color: #ff3a20;
+    }
+  }
+}
+</style>
+<style>
+.selector-card.vip-sub-list-item.order-form {
+  display: none !important;
+}
+</style>

+ 9 - 2
apps/bigmember_pc/src/views/order/components/data-pack/header-adsense.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="data-pack-header-adsense">
+  <div class="data-pack-header-adsense header-adsense">
     <AdContainer
       :exposure-prefix="'PC购买页轮播广告位-' + code + '-'"
       :code="code"
@@ -23,6 +23,13 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-.vip-subscribe-adsense {
+.header-adsense {
+  padding-top: 22px;
+  padding-bottom: 8px;
+  ::v-deep {
+    .el-carousel__container {
+      height: 80px;
+    }
+  }
 }
 </style>

+ 9 - 2
apps/bigmember_pc/src/views/order/components/vipsubscribe/header-adsense.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="vip-subscribe-header-adsense">
+  <div class="vip-subscribe-header-adsense header-adsense">
     <AdContainer
       :exposure-prefix="'PC购买页轮播广告位-' + code + '-'"
       :code="code"
@@ -45,6 +45,13 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-.vip-subscribe-adsense {
+.header-adsense {
+  padding-top: 22px;
+  padding-bottom: 8px;
+  ::v-deep {
+    .el-carousel__container {
+      height: 80px;
+    }
+  }
 }
 </style>

+ 1 - 1
apps/bigmember_pc/src/views/order/layout.vue

@@ -1,8 +1,8 @@
 <template>
   <div class="page-create-order" v-loading="loading">
     <router-view name="head" v-if="pageLayout.header"></router-view>
-    <router-view name="headerAdsense"></router-view>
     <div class="page-create-order-content v-w1200">
+      <router-view name="headerAdsense"></router-view>
       <router-view
         class="page-create-order-content-title"
         name="title"

+ 498 - 0
apps/bigmember_pc/src/views/reportDownload/examine.vue

@@ -0,0 +1,498 @@
+<template>
+  <section class="report-examine v-w1200">
+    <el-form v-if="hasRecord" ref="form" :model="form" label-width="240px">
+      <el-form-item
+        label="无政府采购严重违法行为记录证明:"
+        prop="prove_purchase"
+      >
+        <el-upload
+          action="string"
+          :key="'upload-prove_purchase-' + form.prove_purchase"
+          :http-request="(file) => uploadFileHandle(file, 'prove_purchase')"
+          :limit="1"
+          :show-file-list="false"
+          :before-upload="beforeUpload"
+          accept="image/jpeg, image/jpg, image/png"
+        >
+          <div class="upload-container">
+            <div
+              v-if="form.prove_purchase"
+              class="avatar-container"
+              @click.stop
+            >
+              <img :src="domain + form.prove_purchase" class="avatar" />
+              <i
+                class="el-icon-error"
+                @click.stop="removeImg('prove_purchase')"
+              ></i>
+            </div>
+            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+          </div>
+          <div slot="tip" class="el-upload__tip">上传jpeg/jpg/png图片文件</div>
+        </el-upload>
+      </el-form-item>
+      <el-form-item label="有无政府采购严重违法行为:">
+        <el-radio-group v-model="form.prove_purchase_status">
+          <el-radio :label="0">无风险</el-radio>
+          <el-radio :label="1">有风险</el-radio>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="·无被执行记录证明:" prop="prove_executed">
+        <el-upload
+          action="string"
+          :key="'upload-prove_executed-' + form.prove_executed"
+          :http-request="(file) => uploadFileHandle(file, 'prove_executed')"
+          :limit="1"
+          :show-file-list="false"
+          :before-upload="beforeUpload"
+          accept="image/jpeg, image/jpg, image/png"
+        >
+          <div class="upload-container">
+            <div
+              v-if="form.prove_executed"
+              class="avatar-container"
+              @click.stop
+            >
+              <img :src="domain + form.prove_executed" class="avatar" />
+              <i
+                class="el-icon-error"
+                @click.stop="removeImg('prove_executed')"
+              ></i>
+            </div>
+            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+          </div>
+          <div slot="tip" class="el-upload__tip">上传jpeg/jpg/png图片文件</div>
+        </el-upload>
+      </el-form-item>
+      <el-form-item label="有无被执行记录:">
+        <el-radio-group v-model="form.prove_executed_status">
+          <el-radio :label="0">无风险</el-radio>
+          <el-radio :label="1">有风险</el-radio>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="无失信被执行记录证明:" prop="prove_dishonesty">
+        <el-upload
+          action="string"
+          :key="'upload-prove_dishonesty-' + form.prove_dishonesty"
+          :http-request="(file) => uploadFileHandle(file, 'prove_dishonesty')"
+          :limit="1"
+          :show-file-list="false"
+          :before-upload="beforeUpload"
+          accept="image/jpeg, image/jpg, image/png"
+        >
+          <div class="upload-container">
+            <div
+              v-if="form.prove_dishonesty"
+              class="avatar-container"
+              @click.stop
+            >
+              <img :src="domain + form.prove_dishonesty" class="avatar" />
+              <i
+                class="el-icon-error"
+                @click.stop="removeImg('prove_dishonesty')"
+              ></i>
+            </div>
+            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+          </div>
+          <div slot="tip" class="el-upload__tip">上传jpeg/jpg/png图片文件</div>
+        </el-upload>
+      </el-form-item>
+      <el-form-item label="有无失信被执行记录:">
+        <el-radio-group v-model="form.prove_dishonesty_status">
+          <el-radio :label="0">无风险</el-radio>
+          <el-radio :label="1">有风险</el-radio>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="无安全生产严重失信记录证明:" prop="prove_produce">
+        <el-upload
+          action="string"
+          :key="'upload-prove_produce-' + form.prove_produce"
+          :http-request="(file) => uploadFileHandle(file, 'prove_produce')"
+          :limit="1"
+          :show-file-list="false"
+          :before-upload="beforeUpload"
+          accept="image/jpeg, image/jpg, image/png"
+        >
+          <div class="upload-container">
+            <div v-if="form.prove_produce" class="avatar-container" @click.stop>
+              <img :src="domain + form.prove_produce" class="avatar" />
+              <i
+                class="el-icon-error"
+                @click.stop="removeImg('prove_produce')"
+              ></i>
+            </div>
+            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+          </div>
+          <div slot="tip" class="el-upload__tip">上传jpeg/jpg/png图片文件</div>
+        </el-upload>
+      </el-form-item>
+      <el-form-item label="有无安全生产严重失信记录:">
+        <el-radio-group v-model="form.prove_produce_status">
+          <el-radio :label="0">无风险</el-radio>
+          <el-radio :label="1">有风险</el-radio>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="信用中国:">
+        <el-upload
+          action="string"
+          :key="'upload-creditchina-' + form.creditchina"
+          :http-request="(file) => uploadFileHandle(file, 'creditchina')"
+          :limit="1"
+          :show-file-list="false"
+          :before-upload="beforeUpload"
+          accept=".pdf"
+        >
+          <div class="upload-container">
+            <el-tag
+              v-if="form.creditchina"
+              type="success"
+              closable
+              @close="removePdf"
+              @click.stop="handlePreviewPdf(form.creditchina)"
+            >
+              {{ pdfName }}
+            </el-tag>
+            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+          </div>
+          <div slot="tip" class="el-upload__tip">上传pdf文件</div>
+        </el-upload>
+      </el-form-item>
+      <el-form-item>
+        <el-button :disabled="disabled" type="primary" @click="onSubmit"
+          >提交</el-button
+        >
+      </el-form-item>
+    </el-form>
+    <Empty v-else>
+      <p>该记录不存在</p>
+    </Empty>
+    <el-dialog
+      title="提示"
+      :visible.sync="collectDialogVisible"
+      width="380px"
+      custom-class="collect-dialog"
+      :close-on-click-modal="false"
+      :close-on-press-escape="false"
+      center
+    >
+      <div class="dialog-content">
+        <p>该报告的表单信息已经收集过。</p>
+        <p v-if="reportInfo.confirmTime">
+          表单提交时间:
+          <span class="highlight-text">{{ reportInfo.confirmTime }}</span>
+        </p>
+        <p v-if="reportInfo.reportTime">
+          报告生成时间:
+          <span class="highlight-text">{{ reportInfo.reportTime }}</span>
+        </p>
+        <p v-if="reportInfo.emailTime">
+          邮件发送时间:
+          <span class="highlight-text">{{ reportInfo.emailTime }}</span>
+        </p>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="collectDialogVisible = false"
+          >我知道了</el-button
+        >
+      </span>
+    </el-dialog>
+    <el-dialog
+      title="提示"
+      :visible.sync="againDialogVisible"
+      width="380px"
+      custom-class="collect-dialog"
+      :close-on-click-modal="false"
+      :close-on-press-escape="false"
+      center
+    >
+      <div class="dialog-content">
+        <p>该报告的表单信息已经收集过,是否重新提交?</p>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="againDialogVisible = false">取 消</el-button>
+        <el-button type="primary" @click="confirmFn">确 定</el-button>
+      </span>
+    </el-dialog>
+  </section>
+</template>
+
+<script>
+import {
+  Form,
+  FormItem,
+  Radio,
+  RadioGroup,
+  Button,
+  Upload,
+  Tag,
+  Icon,
+  Dialog
+} from 'element-ui'
+import {
+  ajaxUploadFile,
+  ajaxUpdateCreditReport,
+  ajaxGetCreditReport
+} from '@/api/modules'
+import Empty from '@/components/common/Empty.vue'
+export default {
+  name: 'report-examine',
+  components: {
+    [Form.name]: Form,
+    [FormItem.name]: FormItem,
+    [Radio.name]: Radio,
+    [RadioGroup.name]: RadioGroup,
+    [Button.name]: Button,
+    [Upload.name]: Upload,
+    [Tag.name]: Tag,
+    [Icon.name]: Icon,
+    [Dialog.name]: Dialog,
+    Empty
+  },
+  data() {
+    return {
+      hasRecord: true,
+      id: '',
+      form: {
+        prove_purchase: '',
+        prove_purchase_status: 0,
+        prove_executed: '',
+        prove_executed_status: 0,
+        prove_dishonesty: '',
+        prove_dishonesty_status: 0,
+        prove_produce: '',
+        prove_produce_status: 0,
+        creditchina: ''
+      },
+      pdfName: '',
+      domain: window.location.origin,
+      reportInfo: {
+        confirmTime: null,
+        reportTime: null,
+        emailTime: null,
+        status: 0
+      },
+      collectDialogVisible: false,
+      againDialogVisible: false
+    }
+  },
+  computed: {
+    disabled() {
+      return (
+        !this.form.prove_purchase ||
+        !this.form.prove_executed ||
+        !this.form.prove_dishonesty ||
+        !this.form.prove_produce ||
+        !this.form.creditchina
+      )
+    }
+  },
+  created() {
+    this.id = this.$route.query?.id
+    if (this.id) {
+      this.getCreditReportForm()
+    }
+  },
+  methods: {
+    async getCreditReportForm() {
+      const { data, status, msg } = await ajaxGetCreditReport({ id: this.id })
+      if (status === 1) {
+        this.hasRecord = true
+        const {
+          prove_purchase,
+          prove_purchase_status,
+          prove_executed,
+          prove_executed_status,
+          prove_dishonesty,
+          prove_dishonesty_status,
+          prove_produce,
+          prove_produce_status,
+          creditchina
+        } = data
+        this.reportInfo.status = data.status
+        if (data.status > 0) {
+          this.form = {
+            prove_purchase,
+            prove_purchase_status,
+            prove_executed,
+            prove_executed_status,
+            prove_dishonesty,
+            prove_dishonesty_status,
+            prove_produce,
+            prove_produce_status,
+            creditchina
+          }
+          if (creditchina) {
+            const filename = creditchina.split('/').pop()
+            this.pdfName = filename
+          }
+          this.reportInfo.confirmTime = data.submit_time
+          this.reportInfo.reportTime = data.complete_time
+          this.reportInfo.emailTime = data.send_mail_time
+          this.collectDialogVisible = true
+          return
+        }
+      } else {
+        this.$toast(msg)
+        this.hasRecord = false
+      }
+    },
+    async uploadFileHandle(file, filed) {
+      const params = new FormData()
+      params.append('type', 'bidCreditReportFile')
+      params.append('bidCreditReportFile', file.file)
+      try {
+        const { error: code, url, filename } = await ajaxUploadFile(params)
+        if (code === 0 && url) {
+          this.form[filed] = url
+          if (filed === 'creditchina') {
+            this.pdfName = filename
+          }
+        } else {
+          this.form[filed] = ''
+        }
+      } catch (error) {
+        console.error('上传失败:', error)
+      }
+    },
+    handlePreviewPdf(url) {
+      if (!url) return
+      const pdfUrl = window.location.origin + url
+      window.open(pdfUrl, '_blank')
+    },
+    removePdf() {
+      this.form.creditchina = ''
+      this.pdfName = ''
+    },
+    removeImg(file) {
+      this.form[file] = ''
+    },
+    beforeUpload(file) {
+      const isLt2M = file.size / 1024 / 1024 < 10
+      if (!isLt2M) {
+        this.$toast('上传文件大小不能超过 10MB!')
+      }
+      return isLt2M
+    },
+    async confirmFn() {
+      const { error_code: code, error_msg: msg } = await ajaxUpdateCreditReport(
+        { ...this.form, id: this.id }
+      )
+      if (code === 0) {
+        this.$toast('提交成功')
+        window.location.reload()
+      } else {
+        this.$toast(msg)
+      }
+    },
+    onSubmit() {
+      if (this.reportInfo.status > 0) {
+        this.againDialogVisible = true
+        return
+      } else {
+        this.confirmFn()
+      }
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.report-examine {
+  background: #fff;
+  ::v-deep {
+    .el-form {
+      padding: 30px;
+    }
+    .el-form-item:nth-child(odd) {
+      margin-bottom: 10px;
+    }
+    .el-upload__input {
+      display: none !important;
+    }
+    .upload-container {
+      text-align: left;
+    }
+    .avatar-uploader .el-upload {
+      border: 1px dashed #d9d9d9;
+      border-radius: 6px;
+      cursor: pointer;
+      position: relative;
+      overflow: hidden;
+    }
+    .avatar-uploader .el-upload:hover {
+      border-color: #409eff;
+    }
+    .avatar-uploader-icon {
+      font-size: 28px;
+      color: #8c939d;
+      width: 120px;
+      height: 120px;
+      line-height: 120px;
+      text-align: center;
+      border: 1px dashed #d9d9d9;
+    }
+    .avatar-container {
+      position: relative;
+      width: 120px;
+      height: 120px;
+      border: 1px dashed #d9d9d9;
+      border-radius: 6px;
+      // overflow: hidden;
+    }
+    .el-icon-error {
+      display: none;
+      position: absolute;
+      right: -6px;
+      top: -6px;
+      z-index: 10;
+      font-size: 22px;
+      color: #1d1d1d;
+      &:hover {
+        color: #1d1d1d;
+      }
+    }
+    .avatar {
+      width: 100%;
+      height: 100%;
+      display: block;
+      z-index: 9;
+    }
+    .avatar-container:hover {
+      .el-icon-error {
+        display: block;
+      }
+    }
+  }
+}
+::v-deep {
+  .empty-container {
+    height: 500px;
+  }
+  .collect-dialog {
+    margin: 0 auto !important;
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+    border-radius: 8px;
+    .el-dialog__body {
+      padding: 20px 30px;
+    }
+    .el-dialog__footer {
+      padding: 10px 30px 24px;
+      .el-button {
+        padding: 10px 40px;
+        border-radius: 4px;
+      }
+    }
+    .dialog-content {
+      p {
+        margin-bottom: 8px;
+        line-height: 24px;
+        font-size: 14px;
+        color: #333;
+      }
+    }
+  }
+}
+</style>

+ 153 - 0
apps/bigmember_pc/src/views/reportDownload/preview.vue

@@ -0,0 +1,153 @@
+<template>
+  <div class="report-sample">
+    <div
+      class="sample-container"
+      ref="sampleContainer"
+      :style="{ 'padding-bottom': !loginFlag ? adHeight + 'px' : 0 }"
+      v-loading="loading"
+    >
+      <!-- <iframe
+        class="iframe"
+        :src="pdfUrl"
+        :style="{ height: iframeHeight }"
+        frameborder="0"
+        type="application/pdf"
+      ></iframe> -->
+      <object
+        class="iframe"
+        :data="pdfUrl"
+        :style="{ height: iframeHeight }"
+        type="application/pdf"
+        style="width: 100%; height: 100%"
+      >
+        <p>您的浏览器不支持PDF预览,请<a :href="pdfUrl">点击下载</a></p>
+      </object>
+      <AdSense
+        v-show="!loginFlag"
+        ref="adSense"
+        class="ad-sense ad-fixed"
+        :code="code"
+        @openUrl="openUrl"
+      ></AdSense>
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from 'vuex'
+import { getAssetsFile } from '@/utils'
+import AdSense from '@/views/order/components/adsense/index.vue'
+export default {
+  name: 'report-sample',
+  components: {
+    AdSense
+  },
+  data() {
+    return {
+      pdfUrl: '',
+      code: 'pc-credit-report-sample',
+      adHeight: 0,
+      loading: true
+    }
+  },
+  computed: {
+    ...mapGetters('user', ['loginFlag']),
+    iframeHeight() {
+      return this.adHeight ? `calc(100% - ${this.adHeight}px)` : '100%'
+    }
+  },
+  created() {
+    // 新增路由参数处理
+    if (!this.$route.query.source) {
+      this.$router.replace({
+        query: {
+          ...this.$route.query,
+          source: 'bidCreditReportPreview'
+        }
+      })
+    }
+    if (this.$route.query && this.$route.query.url) {
+      this.pdfUrl = decodeURIComponent(this.$route.query.url)
+      this.loading = false
+    } else {
+      this.pdfUrl = getAssetsFile('投标企业信用报告.pdf')
+      this.loading = false
+    }
+  },
+  mounted() {
+    setTimeout(() => {
+      this.getAdStyle()
+    }, 300)
+    if (!this.loginFlag) {
+      window.top.addEventListener('scroll', (event) => {
+        const jBottom = window.top.document.querySelector('.j-bottom')
+        if (!jBottom) return
+        // 计算元素位置
+        const rect = jBottom.getBoundingClientRect()
+        // 当元素顶部进入视口时(阈值设为窗口高度)
+        const isVisible = rect.top <= window.top.innerHeight
+        // 获取广告DOM元素
+        const adElement = this.$refs.adSense?.$el
+        const container = document.querySelector('.sample-container')
+        if (isVisible) {
+          adElement?.classList.remove('ad-fixed')
+          container?.style.setProperty('padding-bottom', 0)
+        } else {
+          adElement?.classList.add('ad-fixed')
+          container?.style.setProperty('padding-bottom', this.adHeight + 'px')
+        }
+        // 触发广告高度重新计算
+        this.getAdStyle()
+      })
+    }
+  },
+  methods: {
+    getAdStyle() {
+      this.$nextTick(() => {
+        if (this.$refs.adSense && this.$refs.adSense.$el) {
+          const adElement = this.$refs.adSense.$el
+          const height = adElement.clientHeight
+          this.adHeight = height
+        }
+      })
+    },
+    openUrl() {
+      // 打开登录弹框or跳转登录页面
+      // location.href = '/notin/page?source=bidCreditReportPreview'
+      const redirectUrl = '/swordfish/page_big_pc/order/credit-report'
+      this.$showLoginDialog(false, redirectUrl)
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.report-sample {
+  height: 100vh;
+  .sample-container {
+    display: flex;
+    flex-direction: column;
+    height: 100%;
+  }
+  .iframe {
+    flex: 1;
+    width: 1200px !important;
+    margin: 0 auto;
+  }
+  .adsense {
+    padding: 0;
+  }
+}
+</style>
+<style>
+.adsense .content {
+  padding: 0 !important;
+  cursor: pointer;
+}
+.ad-fixed {
+  position: fixed;
+  bottom: 0;
+  left: 0;
+  width: 100%;
+}
+</style>

+ 458 - 276
apps/bigmember_pc/src/views/reportDownload/record.vue

@@ -2,46 +2,74 @@
   <div class="report-download-record">
     <div class="page-header">
       <h1>报告下载记录</h1>
-      <em>注:请在有效期内使用,过期清零,不可转赠。</em>
     </div>
     <section class="box-container balance-box">
-      <div class="box-title">报告下载余额</div>
+      <div class="box-title">
+        报告下载余额<em class="balance-tips"
+          >注:请在有效期内使用,过期清零,不可转赠。</em
+        >
+      </div>
       <div class="card-row">
         <div class="card-col" v-for="item in cardList">
           <p class="title">{{ item.title }}</p>
           <div class="num">
-            <span><strong>{{ item.total }}</strong>份</span>
-            <el-button class="recharge-button" type="primary" @click="goRecharge(item)">立即充值</el-button>
+            <span
+              ><strong>{{ item.total }}</strong
+              >份</span
+            >
+            <el-button
+              class="recharge-button"
+              type="primary"
+              @click="goRecharge(item)"
+              >立即充值</el-button
+            >
           </div>
           <p class="date">
             <span v-if="item.total">最近有效期至:{{ item.minEndTime }}</span>
-            <span class="text-button" @click="goBalance(item)">查明细<i class="iconfont icon-more"></i></span>
+            <span class="text-button" @click="goBalance(item)"
+              >查明细<i class="iconfont icon-more"></i
+            ></span>
           </p>
         </div>
       </div>
     </section>
+    <section class="flex flex-(justify-between items-center) credit-report-box">
+      <div class="flex flex-items-center credit-report-content">
+        <p class="credit-report-title">投标企业信用报告</p>
+        <p class="credit-report-desc">
+          信用报告通过信用背书、风险预警、政策适配,三大核心作用,成为投标企业参与市场竞争的关键工具‌
+        </p>
+        <img
+          class="credit-report-icon"
+          src="@/assets/images/credit-report-icon.png"
+          alt="信用报告"
+        />
+      </div>
+      <div class="flex flex-items-center report-action">
+        <span class="view-report-sample" @click="goViewSample"
+          >查看报告样例</span
+        >
+        <button class="report-to-buy" @click="goBuyCreditReport">去购买</button>
+      </div>
+    </section>
     <section class="box-container record-box">
       <p class="box-title">报告下载记录</p>
-      <el-table
-        :data="listState.list"
-        v-show="!showEmpty"
-      >
+      <el-table :data="listState.list" v-show="!showEmpty">
         <el-table-column label="下载时间" width="170" align="center">
           <template slot-scope="scope">
             <span class="max-line-3">{{
-                (scope.row.l_createTime * 1000) | formatTime('yyyy-MM-dd HH:mm')
-              }}</span>
+              (scope.row.l_createTime * 1000) | formatTime('yyyy-MM-dd HH:mm')
+            }}</span>
           </template>
         </el-table-column>
         <el-table-column label="报告类型" width="230" align="center">
           <template slot-scope="scope">
-            {{scope.row.type | formatType}}
+            {{ scope.row.type | formatType }}
           </template>
-
         </el-table-column>
         <el-table-column label="报告说明" min-width="400">
           <template slot-scope="scope">
-           <!-- 市场分析报告-->
+            <!-- 市场分析报告-->
             <el-tooltip
               v-if="scope.row.type === '3'"
               effect="dark"
@@ -67,24 +95,30 @@
                 <div>
                   <span>成交时间:</span
                   ><span
-                >{{
-                    scope.row.rangeTimeStart | formatTime('yyyy-MM-dd')
-                  }}至{{
-                    scope.row.rangeTimeEnd | formatTime('yyyy-MM-dd')
-                  }}</span
-                >
+                    >{{
+                      scope.row.rangeTimeStart | formatTime('yyyy-MM-dd')
+                    }}至{{
+                      scope.row.rangeTimeEnd | formatTime('yyyy-MM-dd')
+                    }}</span
+                  >
                 </div>
                 <div v-if="scope.row.s_area && scope.row.s_area !== '{}'">
                   <span>项目地区:</span
                   ><span>{{ scope.row.s_area | formatArea }}</span>
                 </div>
-                <div v-if="scope.row.s_industry && scope.row.s_industry !== '{}'">
+                <div
+                  v-if="scope.row.s_industry && scope.row.s_industry !== '{}'"
+                >
                   <span>行业:</span
-                  ><span>{{ scope.row.s_industry | formatMarketIndustry }}</span>
+                  ><span>{{
+                    scope.row.s_industry | formatMarketIndustry
+                  }}</span>
                 </div>
                 <div v-if="scope.row.s_buyerClass">
                   <span>采购单位类型:</span
-                  ><span>{{ getFormatBuyerClass(scope.row.s_buyerClass) }}</span>
+                  ><span>{{
+                    getFormatBuyerClass(scope.row.s_buyerClass)
+                  }}</span>
                 </div>
               </div>
               <div>
@@ -100,128 +134,190 @@
                   <div>
                     <span>成交时间:</span
                     ><span
-                  >{{
-                      scope.row.rangeTimeStart | formatTime('yyyy-MM-dd')
-                    }}至{{
-                      scope.row.rangeTimeEnd | formatTime('yyyy-MM-dd')
-                    }}</span
-                  >
+                      >{{
+                        scope.row.rangeTimeStart | formatTime('yyyy-MM-dd')
+                      }}至{{
+                        scope.row.rangeTimeEnd | formatTime('yyyy-MM-dd')
+                      }}</span
+                    >
                   </div>
-                  <div class="ellipsis-1" v-if="scope.row.s_area && scope.row.s_area !== '{}'">
+                  <div
+                    class="ellipsis-1"
+                    v-if="scope.row.s_area && scope.row.s_area !== '{}'"
+                  >
                     <span>项目地区:</span
                     ><span>{{ scope.row.s_area | formatArea }}</span>
                   </div>
-                  <div class="ellipsis-1" v-if="scope.row.s_industry && scope.row.s_industry !== '{}'">
+                  <div
+                    class="ellipsis-1"
+                    v-if="scope.row.s_industry && scope.row.s_industry !== '{}'"
+                  >
                     <span>行业:</span
-                    ><span>{{ scope.row.s_industry | formatMarketIndustry }}</span>
+                    ><span>{{
+                      scope.row.s_industry | formatMarketIndustry
+                    }}</span>
                   </div>
-                  <div  class="ellipsis-1" v-if="scope.row.s_buyerClass">
+                  <div class="ellipsis-1" v-if="scope.row.s_buyerClass">
                     <span>采购单位类型:</span
-                    ><span>{{ getFormatBuyerClass(scope.row.s_buyerClass) }}</span>
+                    ><span>{{
+                      getFormatBuyerClass(scope.row.s_buyerClass)
+                    }}</span>
                   </div>
                 </div>
               </div>
             </el-tooltip>
+            <div v-else-if="scope.row.type === '4'" class="">
+              <div>
+                <span>投标企业名称:</span>
+                <span>{{ scope.row.ent }}</span>
+              </div>
+              <div>
+                <span>招标单位名称:</span>
+                <span>{{ scope.row.buyer }}</span>
+              </div>
+            </div>
             <!-- 业主采购、企业中标分析报告-->
             <el-tooltip
-                v-else
-                effect="dark"
-                placement="right"
-                popper-class="analyse-condition-tooltip"
-              >
-                <div
-                  slot="content"
-                  style="
+              v-else
+              effect="dark"
+              placement="right"
+              popper-class="analyse-condition-tooltip"
+            >
+              <div
+                slot="content"
+                style="
                   max-width: 300px !important;
                   font-size: 12px;
                   line-height: 22px;
                 "
-                >
+              >
+                <div v-if="scope.row.type === '1'">
+                  <span>目标企业:</span>
+                  <span
+                    class="highlight-name"
+                    @click="goEntPortrayal(scope.row.ent)"
+                    >{{ scope.row.entName }}</span
+                  >
+                </div>
+                <div v-if="scope.row.type === '2'">
+                  <span>目标业主:</span>
+                  <span
+                    class="highlight-name"
+                    @click="goUnitPortrayal(scope.row.ent)"
+                    >{{ scope.row.entName }}</span
+                  >
+                </div>
+                <div>
+                  <span>成交时间:</span
+                  ><span
+                    >{{ scope.row.rangeTimeStart }}至{{
+                      scope.row.rangeTimeEnd
+                    }}</span
+                  >
+                </div>
+                <div v-if="scope.row.match">
+                  <span>关键词:</span>
+                  <span>{{
+                    scope.row.match +
+                    (scope.row.exactMatch === '1' ? '(精准)' : '(模糊)')
+                  }}</span>
+                </div>
+                <div v-if="scope.row.matchRange">
+                  <span>搜索范围:</span
+                  ><span>{{ scope.row.matchRange | formatSelectType }}</span>
+                </div>
+                <div v-if="scope.row.area">
+                  <span>项目地区:</span><span>{{ scope.row.area }}</span>
+                </div>
+                <div v-if="scope.row.scopeClass">
+                  <span>行业:</span
+                  ><span>{{ getFormatIndustry(scope.row.scopeClass) }}</span>
+                </div>
+                <div v-if="scope.row.buyerClass && scope.row.type === '1'">
+                  <span>采购单位类型:</span
+                  ><span>{{ getFormatBuyerClass(scope.row.buyerClass) }}</span>
+                </div>
+              </div>
+              <div>
+                <div class="analyse-condition">
                   <div v-if="scope.row.type === '1'">
                     <span>目标企业:</span>
-                    <span class="highlight-name" @click="goEntPortrayal(scope.row.ent)">{{scope.row.entName}}</span>
+                    <span
+                      class="highlight-name"
+                      @click="goEntPortrayal(scope.row.ent)"
+                      >{{ scope.row.entName }}</span
+                    >
                   </div>
                   <div v-if="scope.row.type === '2'">
                     <span>目标业主:</span>
-                    <span class="highlight-name" @click="goUnitPortrayal(scope.row.ent)">{{scope.row.entName}}</span>
+                    <span
+                      class="highlight-name"
+                      @click="goUnitPortrayal(scope.row.ent)"
+                      >{{ scope.row.entName }}</span
+                    >
                   </div>
                   <div>
                     <span>成交时间:</span
                     ><span
-                  >{{scope.row.rangeTimeStart }}至{{scope.row.rangeTimeEnd }}</span>
+                      >{{ scope.row.rangeTimeStart }}至{{
+                        scope.row.rangeTimeEnd
+                      }}</span
+                    >
                   </div>
-                  <div v-if="scope.row.match">
+                  <div class="ellipsis-1" v-if="scope.row.match">
                     <span>关键词:</span>
-                    <span>{{ scope.row.match + (scope.row.exactMatch === '1' ? '(精准)': '(模糊)')}}</span>
+                    <span>{{
+                      scope.row.match +
+                      (scope.row.exactMatch === '1' ? '(精准)' : '(模糊)')
+                    }}</span>
                   </div>
-                  <div v-if="scope.row.matchRange">
+                  <div class="ellipsis-1" v-if="scope.row.matchRange">
                     <span>搜索范围:</span
                     ><span>{{ scope.row.matchRange | formatSelectType }}</span>
                   </div>
-                  <div v-if="scope.row.area">
-                    <span>项目地区:</span
-                    ><span>{{ scope.row.area }}</span>
+                  <div class="ellipsis-1" v-if="scope.row.area">
+                    <span>项目地区:</span><span>{{ scope.row.area }}</span>
                   </div>
-                  <div v-if="scope.row.scopeClass">
+                  <div class="ellipsis-1" v-if="scope.row.scopeClass">
                     <span>行业:</span
                     ><span>{{ getFormatIndustry(scope.row.scopeClass) }}</span>
                   </div>
-                  <div v-if="scope.row.buyerClass && scope.row.type === '1'">
-                    <span>采购单位类型:</span
-                    ><span>{{ getFormatBuyerClass(scope.row.buyerClass)}}</span>
-                  </div>
-                </div>
-                <div>
-                  <div class="analyse-condition">
-                    <div v-if="scope.row.type === '1'">
-                      <span>目标企业:</span>
-                      <span class="highlight-name" @click="goEntPortrayal(scope.row.ent)">{{scope.row.entName}}</span>
-                    </div>
-                    <div v-if="scope.row.type === '2'">
-                      <span>目标业主:</span>
-                      <span class="highlight-name" @click="goUnitPortrayal(scope.row.ent)">{{scope.row.entName}}</span>
-                    </div>
-                    <div>
-                    <span>成交时间:</span
-                    ><span
-                    >{{scope.row.rangeTimeStart }}至{{scope.row.rangeTimeEnd }}</span>
-                    </div>
-                    <div class="ellipsis-1" v-if="scope.row.match" >
-                      <span>关键词:</span>
-                      <span>{{ scope.row.match  + (scope.row.exactMatch === '1' ? '(精准)': '(模糊)')}}</span>
-                    </div>
-                    <div class="ellipsis-1" v-if="scope.row.matchRange">
-                    <span>搜索范围:</span
-                    ><span>{{ scope.row.matchRange | formatSelectType }}</span>
-                    </div>
-                    <div class="ellipsis-1"  v-if="scope.row.area">
-                    <span>项目地区:</span
-                    ><span>{{ scope.row.area }}</span>
-                    </div>
-                    <div class="ellipsis-1"  v-if="scope.row.scopeClass">
-                    <span>行业:</span
-                    ><span>{{ getFormatIndustry(scope.row.scopeClass)}}</span>
-                    </div>
-                    <div class="ellipsis-1"  v-if="scope.row.buyerClass && scope.row.type === '1'">
+                  <div
+                    class="ellipsis-1"
+                    v-if="scope.row.buyerClass && scope.row.type === '1'"
+                  >
                     <span>采购单位类型:</span
-                    ><span>{{ getFormatBuyerClass(scope.row.buyerClass)}}</span>
-                    </div>
+                    ><span>{{
+                      getFormatBuyerClass(scope.row.buyerClass)
+                    }}</span>
                   </div>
                 </div>
-              </el-tooltip>
+              </div>
+            </el-tooltip>
           </template>
         </el-table-column>
         <el-table-column min-width="100" label="操作" align="center">
           <template slot-scope="scope">
-            <a v-if="scope.row.s_pdfUrl" class="text-button" :download="scope.row.fileName + '.pdf'" :href="scope.row.s_pdfUrl" target="_blank">下载</a>
+            <a
+              v-if="scope.row.s_pdfUrl"
+              class="text-button"
+              :download="scope.row.fileName + '.pdf'"
+              :href="scope.row.s_pdfUrl"
+              target="_blank"
+              >下载</a
+            >
             <span v-else>--</span>
           </template>
         </el-table-column>
       </el-table>
-      <empty  v-show="showEmpty">
+      <empty v-show="showEmpty">
         <div class="flex-c-c center">
-          <div style="width:310px;text-align: center">暂无下载记录,您可前往查看市场分析定制报告,精准分析客户、竞对、市场</div>
-          <el-button class="view-report-btn" type="primary" @click="viewReport">查看报告</el-button>
+          <div style="width: 310px; text-align: center">
+            暂无下载记录,您可前往查看市场分析定制报告,精准分析客户、竞对、市场
+          </div>
+          <el-button class="view-report-btn" type="primary" @click="viewReport"
+            >查看报告</el-button
+          >
         </div>
       </empty>
 
@@ -241,7 +337,6 @@
         </el-pagination>
       </div>
     </section>
-
   </div>
 </template>
 
@@ -255,7 +350,7 @@ export default {
   components: {
     Empty
   },
-  data () {
+  data() {
     return {
       listState: {
         loaded: true, // 是否已经搜索过
@@ -292,9 +387,10 @@ export default {
         }
       ],
       typeObj: {
-        '1': '企业中标分析报告',
-        '2': '业主采购分析报告',
-        '3': '市场分析定制报告'
+        1: '企业中标分析报告',
+        2: '业主采购分析报告',
+        3: '市场分析定制报告',
+        4: '投标企业信用报告'
       }
     }
   },
@@ -344,7 +440,7 @@ export default {
         if (!value[key].length) {
           keyArr.push(key)
         } else {
-          for(const item of value[key]) {
+          for (const item of value[key]) {
             valueArr.push(key + '_' + item)
           }
         }
@@ -354,17 +450,17 @@ export default {
       return obj.industryText
     },
     FormatKeys: function (keys) {
-      if(!keys) return '-'
+      if (!keys) return '-'
       let tempStr = '-'
       const tempResult = []
       const tempList = JSON.parse(keys)
       tempList.forEach(function (v) {
         v.a_key.forEach(function (k) {
           let key = []
-          if(k.key) {
+          if (k.key) {
             key = key.concat(k.key)
           }
-          if(k.appendkey) {
+          if (k.appendkey) {
             key = key.concat(k.appendkey)
           }
           tempResult.push({
@@ -376,11 +472,12 @@ export default {
       tempStr = tempResult
         .map(function (v) {
           return v.key.join(' ') + '(' + v.type + ')'
-        }).join(',')
+        })
+        .join(',')
       return tempStr
     },
     formatSelectType: function (value) {
-      if(!value) return '-'
+      if (!value) return '-'
       const arr = value.split(',')
       const strArr = []
       const str = ''
@@ -390,15 +487,15 @@ export default {
         winner: '中标企业',
         agency: '招标代理机构'
       }
-      for(let item of arr) {
+      for (let item of arr) {
         strArr.push(obj[item])
       }
       return strArr.join(',')
     },
     formatType: function (value) {
-      if(!value) return '-'
+      if (!value) return '-'
       let result = ''
-      switch(Number(value)) {
+      switch (Number(value)) {
         case 1:
           result = '企业中标分析报告'
           break
@@ -408,14 +505,15 @@ export default {
         case 3:
           result = '市场分析定制报告'
           break
+        case 4:
+          result = '投标企业信用报告'
+          break
       }
       return result
     }
   },
   computed: {
-    ...mapGetters('user', [
-      'isMember'
-    ]),
+    ...mapGetters('user', ['isMember']),
     showEmpty() {
       return this.listState.list.length === 0 && this.listState.loaded
     }
@@ -431,7 +529,7 @@ export default {
       return obj.industryText
     },
     // 格式化采购单位
-    getFormatBuyerClass (val) {
+    getFormatBuyerClass(val) {
       const obj = formatBuyerClass(val)
       return obj.buyerClassText
     },
@@ -443,7 +541,7 @@ export default {
       const text = map[m] || map.content
       return text
     },
-    async getList () {
+    async getList() {
       try {
         const query = {
           page: this.listState.pageNum,
@@ -458,21 +556,30 @@ export default {
           if (this.listState.pageNum === 1) {
             this.listState.total = data.count
           }
-          const list = data.list?.map((v) => {
-            if (v.s_rangeTime) {
-              const rangeTimeArr = v.s_rangeTime.split('-')
-              v.rangeTimeStart = new Date(rangeTimeArr[0] * 1000).getTime()
-              v.rangeTimeEnd = new Date(rangeTimeArr[1] * 1000).getTime()
-            } else if(v.timeRange) {
-              const rangeTimeArr = v.timeRange.split('_')
-              v.rangeTimeStart = rangeTimeArr[0]
-              v.rangeTimeEnd = rangeTimeArr[1]
-            }
-            const creatTime = v.l_createTime ? new Date(v.l_createTime * 1000).pattern('yyyyMMdd') : new Date().pattern('yyyyMMdd')
-            const typeName = v.type ? this.typeObj[v.type.toString()] : '分析报告'
-            v.fileName = `剑鱼标讯-${typeName}-${creatTime}`
-            return v
-          }) || []
+          const list =
+            data.list?.map((v) => {
+              if (v.s_rangeTime) {
+                const rangeTimeArr = v.s_rangeTime.split('-')
+                v.rangeTimeStart = new Date(rangeTimeArr[0] * 1000).getTime()
+                v.rangeTimeEnd = new Date(rangeTimeArr[1] * 1000).getTime()
+              } else if (v.timeRange) {
+                const rangeTimeArr = v.timeRange.split('_')
+                v.rangeTimeStart = rangeTimeArr[0]
+                v.rangeTimeEnd = rangeTimeArr[1]
+              }
+              const creatTime = v.l_createTime
+                ? new Date(v.l_createTime * 1000).pattern('yyyyMMdd')
+                : new Date().pattern('yyyyMMdd')
+              if (v.type === '4') {
+                v.fileName = v.ent
+              } else {
+                const typeName = v.type
+                  ? this.typeObj[v.type.toString()]
+                  : '分析报告'
+                v.fileName = `剑鱼标讯-${typeName}-${creatTime}`
+              }
+              return v
+            }) || []
           this.listState.list = list || []
         } else {
           throw new Error(code)
@@ -493,11 +600,11 @@ export default {
       this.listState.pageSize = size
       this.getList()
     },
-    async getBalanceList () {
+    async getBalanceList() {
       const { data = {}, error_code: code } = await getPDFPackBalance()
-      if(code === 0 && data) {
-        for(let item of this.cardList) {
-          if(data[item.type]) {
+      if (code === 0 && data) {
+        for (let item of this.cardList) {
+          if (data[item.type]) {
             item.total = data[item.type].total
             item.minEndTime = data[item.type].minEndTime
           }
@@ -505,11 +612,14 @@ export default {
       }
     },
     // 立即充值
-    goRecharge (item) {
-      window.open(`/swordfish/page_big_pc/order/download-pack/${item.flag}`, '_self')
+    goRecharge(item) {
+      window.open(
+        `/swordfish/page_big_pc/order/download-pack/${item.flag}`,
+        '_self'
+      )
     },
     // 查看余额明细页面
-    goBalance (item) {
+    goBalance(item) {
       this.$router.push({
         path: '/report/download_record',
         query: {
@@ -519,184 +629,256 @@ export default {
       })
     },
     // 查看报告
-    viewReport () {
+    viewReport() {
       this.$router.push('/desktop/report_analysis')
     },
     // 跳转企业画像
-    goEntPortrayal (id) {
-      if(this.isMember) {
+    goEntPortrayal(id) {
+      if (this.isMember) {
         // 大会员
         window.open(`/swordfish/page_big_pc/ent_portrait/${id}`, '_blank')
       } else {
         // 非大会员
-        window.open(`/swordfish/page_big_pc/svip/ent_ser_portrait/${id}`, '_blank')
+        window.open(
+          `/swordfish/page_big_pc/svip/ent_ser_portrait/${id}`,
+          '_blank'
+        )
       }
     },
     // 进入采购单位画像
-    goUnitPortrayal (name) {
+    goUnitPortrayal(name) {
       window.open(`/swordfish/page_big_pc/unit_portrayal/${name}`, '_blank')
+    },
+    goViewSample() {
+      // const link = this.$router.resolve({
+      //   path: '/free/report/preview',
+      //   query: {
+      //     source: 'bidCreditReportPreview'
+      //   }
+      // })
+      // window.open(link.href, '_blank')
+      window.open(
+        '/swordfish/page_big_pc/free/report/preview?source=bidCreditReportPreview',
+        '_blank'
+      )
+    },
+    goBuyCreditReport() {
+      window.open('/swordfish/page_big_pc/order/credit-report', '_blank')
     }
   }
 }
-
 </script>
 
 <style lang="scss" scoped>
-  $char_color: #1d1d1d;
-  .in-app {
-    .report-download-record {
-      padding: 24px;
-    }
+$char_color: #1d1d1d;
+.in-app {
+  .report-download-record {
+    padding: 24px;
   }
+}
 
-  .report-download-record{
-    margin: 0 auto;
-    .page-header{
-      height: 40px;
-      line-height:40px;
-      vertical-align: text-bottom;
-      h1{
-        display: inline-block;
-        font-size: 24px;
-        line-height:38px;
-        color: $char_color;
-        margin-right: 12px;
-      }
-      em{
-        font-size:12px;
-        color: #999;
-        line-height:18px;
-      }
+.report-download-record {
+  margin: 0 auto;
+  .page-header {
+    height: 40px;
+    line-height: 40px;
+    vertical-align: text-bottom;
+    h1 {
+      display: inline-block;
+      font-size: 24px;
+      line-height: 38px;
+      color: $char_color;
+      margin-right: 12px;
     }
-    .box-container{
-      border-radius: 4px;
-      background: #fff;
-      .box-title{
-        font-size:16px;
-        color: $char_color;
-        line-height:24px;
-        margin-bottom: 12px;
-      }
+  }
+  .box-container {
+    border-radius: 4px;
+    background: #fff;
+    .box-title {
+      font-size: 16px;
+      color: $char_color;
+      line-height: 24px;
+      margin-bottom: 12px;
     }
-    .balance-box{
-      margin: 24px 0 16px;
-      padding: 12px 24px 32px;
-      .card-row{
-        display: grid;
-        grid-template-columns: 1fr 1fr 1fr;
-        grid-column-gap: 24px;
-      }
-      .card-col{
-        background: url(~@/assets/images/report/balance-bg.png) no-repeat center;
-        background-size: cover;
-        padding: 24px 32px;
-        border-radius: 8px;
-        box-shadow: 0 4px 8px rgba(0,0,0, 0.08);
-        font-size: 16px;
-        color: $char_color;
-        .num{
-          margin: 14px 0 20px;
-          display: flex;
-          align-items: flex-end;
-          strong {
-            font-size:40px;
-          }
-          >span{
-            margin-right: 11px;
-          }
+    .balance-tips {
+      margin-left: 12px;
+      font-size: 12px;
+      color: #999;
+      line-height: 18px;
+    }
+  }
+  .balance-box {
+    margin: 24px 0 16px;
+    padding: 12px 24px 32px;
+    .card-row {
+      display: grid;
+      grid-template-columns: 1fr 1fr 1fr;
+      grid-column-gap: 24px;
+    }
+    .card-col {
+      background: url(~@/assets/images/report/balance-bg.png) no-repeat center;
+      background-size: cover;
+      padding: 24px 32px;
+      border-radius: 8px;
+      box-shadow: 0 4px 8px rgba(0, 0, 0, 0.08);
+      font-size: 16px;
+      color: $char_color;
+      .num {
+        margin: 14px 0 20px;
+        display: flex;
+        align-items: flex-end;
+        strong {
+          font-size: 40px;
         }
+        > span {
+          margin-right: 11px;
+        }
+      }
 
-        .date{
-          font-size:14px;
-          color: #999;
-          line-height:22px;
+      .date {
+        font-size: 14px;
+        color: #999;
+        line-height: 22px;
 
-          span:nth-of-type(1) {
-            margin-right: 12px;
-          }
+        span:nth-of-type(1) {
+          margin-right: 12px;
         }
       }
     }
-    .record-box{
-      padding: 12px 20px 24px;
-    }
-    .recharge-button{
-      padding: 4px 17px;
-      font-size: 14px;
-      line-height: 22px;
+  }
+  .record-box {
+    padding: 12px 20px 24px;
+  }
+  .recharge-button {
+    padding: 4px 17px;
+    font-size: 14px;
+    line-height: 22px;
+  }
+  .text-button {
+    font-size: 14px;
+    line-height: 22px;
+    color: #2abed1;
+    cursor: pointer;
+  }
+  .highlight-name {
+    color: #2abed1;
+    cursor: pointer;
+    text-decoration: underline;
+  }
+  .icon-more {
+    font-size: 14px;
+    margin-left: 4px;
+    font-weight: bold;
+  }
+  .max-line-6 {
+    display: -webkit-box;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    -webkit-line-clamp: 6;
+    line-clamp: 6;
+    -webkit-box-orient: vertical;
+    box-orient: vertical;
+  }
+  .ellipsis-1 {
+    display: -webkit-box;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    -webkit-line-clamp: 1;
+    line-clamp: 1;
+    -webkit-box-orient: vertical;
+    box-orient: vertical;
+  }
+  .analyse-condition {
+    color: #1d1d1d;
+    font-size: 14px;
+    line-height: 22px;
+    &:hover {
+      color: #2abed1;
     }
-    .text-button{
+  }
+  .el-pagination-container {
+    margin-right: 0;
+    margin-top: 24px;
+    padding-bottom: 18px;
+  }
+  .view-report-btn {
+    font-size: 16px;
+    line-height: 24px;
+    padding: 6px 34px;
+    margin-top: 56px;
+    border-radius: 6px;
+  }
+  ::v-deep {
+    .el-table .cell {
       font-size: 14px;
+      font-weight: 400;
+      color: #1d1d1d;
       line-height: 22px;
-      color: #2abed1;
-      cursor: pointer;
+      border-bottom-color: rgba(255, 255, 255, 0.5);
     }
-    .highlight-name{
-      color: #2abed1;
-      cursor: pointer;
-      text-decoration: underline;
-    }
-    .icon-more{
-      font-size:14px;
-      margin-left: 4px;
-      font-weight:bold;
+    .el-table th.is-leaf {
+      line-height: 18px;
+      background: #f7f9fc;
+      border-bottom-color: transparent;
     }
-    .max-line-6 {
-      display: -webkit-box;
-      overflow: hidden;
-      text-overflow: ellipsis;
-      -webkit-line-clamp: 6;
-      line-clamp: 6;
-      -webkit-box-orient: vertical;
-      box-orient: vertical;
+    .empty-content-position.v-column .empty-main {
+      margin-top: 0;
     }
-    .ellipsis-1 {
-      display: -webkit-box;
-      overflow: hidden;
-      text-overflow: ellipsis;
-      -webkit-line-clamp: 1;
-      line-clamp: 1;
-      -webkit-box-orient: vertical;
-      box-orient: vertical;
+  }
+  .credit-report-box {
+    height: 60px;
+    padding: 0 24px;
+    margin-bottom: 16px;
+    background: linear-gradient(90deg, #e3fcff 0%, #ffffff 100%);
+    border-radius: 4px;
+    border: 1px solid #87dfea;
+    overflow: hidden;
+    .credit-report-content {
+      position: relative;
     }
-    .analyse-condition {
+    .credit-report-title {
+      margin-right: 12px;
       color: #1d1d1d;
+      font-size: 16px;
+      line-height: 24px;
+      white-space: nowrap;
+    }
+    .credit-report-desc {
+      position: relative;
+      color: #686868;
       font-size: 14px;
       line-height: 22px;
-      &:hover {
-        color: #2abed1;
-      }
+      z-index: 10;
     }
-    .el-pagination-container {
-      margin-right: 0;
-      margin-top:24px;
-      padding-bottom: 18px;
+    .report-action {
+      position: relative;
+      z-index: 10;
+      white-space: nowrap;
     }
-    .view-report-btn{
-      font-size:16px;
-      line-height: 24px;
-      padding: 6px 34px;
-      margin-top:56px;
-      border-radius: 6px;
+    .view-report-sample {
+      color: $color_main;
+      cursor: pointer;
+      font-size: 14px;
+      line-height: 22px;
     }
-    ::v-deep {
-      .el-table .cell {
-        font-size: 14px;
-        font-weight: 400;
-        color: #1d1d1d;
-        line-height: 22px;
-        border-bottom-color: rgba(255, 255, 255, 0.5);
-      }
-      .el-table th.is-leaf {
-        line-height: 18px;
-        background: #f7f9fc;
-        border-bottom-color: transparent;
-      }
-      .empty-content-position.v-column .empty-main {
-        margin-top:0;
-      }
+    .report-to-buy {
+      margin-left: 20px;
+      background: $color_main;
+      color: #fff;
+      font-size: 14px;
+      line-height: 22px;
+      padding: 4px 24px;
+      border-radius: 4px;
+    }
+    .credit-report-icon {
+      position: absolute;
+      top: 50%;
+      right: -80px;
+      width: 112px;
+      height: 60px;
+      transform: translateY(-50%);
+      z-index: 9;
     }
   }
-
-
+}
 </style>

+ 19 - 0
apps/mobile/src/api/modules/pay.js

@@ -405,3 +405,22 @@ export function vipGiftDetailAjax(data) {
     data
   })
 }
+
+export function creditReportEntSearch(data) {
+  data = qs.stringify(data)
+  return request({
+    url: '/subscribepay/bidCreditReport/entSearch',
+    method: 'POST',
+    data
+  })
+}
+
+// 企业信用报告生成时间配置
+export function creditReportTime(data) {
+  data = qs.stringify(data)
+  return request({
+    url: '/subscribepay/config',
+    method: 'POST',
+    data
+  })
+}

BIN
apps/mobile/src/assets/image/example-min.pdf


BIN
apps/mobile/src/assets/image/reportanalysis/credit-corner-bg.png


+ 13 - 1
apps/mobile/src/assets/js/productLink.js

@@ -12,6 +12,18 @@ export const productLinks = {
       app: '/jyapp/front/dataExport/toOrderDetail'
     }
   },
+  bidCreditRepoetLink: {
+    pay: {
+      wx: '/weixin/pay/checkout_bidcreditreport',
+      h5: '/jyapp/pay/checkout_bidcreditreport',
+      app: '/jyapp/pay/checkout_bidcreditreport'
+    },
+    orderDetail: {
+      wx: '/front/wx_bidcreditreport/wxToOrderDetail',
+      h5: '/jyapp/front/bidcreditreport/toOrderDetail',
+      app: '/jyapp/front/bidcreditreport/toOrderDetail'
+    }
+  },
   // VIP订阅
   vipSubLink: {
     pay: {
@@ -225,7 +237,7 @@ export const productLinks = {
       app: '/jyapp/common/enterpriseAnalysis/orderDetail'
     }
   },
-  //产品类型:业主采购分析报告下载包
+  // 产品类型:业主采购分析报告下载包
   ownerAnalysisLink: {
     pay: {
       wx: '/weixin/pay/checkout_ownerAnalysis',

+ 0 - 1
apps/mobile/src/main.js

@@ -11,7 +11,6 @@ import store from './store'
 import 'virtual:uno.css'
 import 'vant/lib/index.less'
 import '@/assets/style/index.scss'
-
 import 'dayjs/locale/zh-cn'
 
 import '@/utils/prototype'

+ 10 - 1
apps/mobile/src/router/modules/common.js

@@ -32,7 +32,7 @@ export default [
       title: '区域'
     }
   },
-  //  
+  //
   {
     path: '/vipsubscribeRights',
     name: 'vipsubscribeRights',
@@ -41,5 +41,14 @@ export default [
       header: true,
       title: '会员服务列表'
     }
+  },
+  {
+    path: '/pdfview',
+    name: 'pdfview',
+    component: () => import('@/views/common/pdfViewExample.vue'),
+    meta: {
+      header: true,
+      title: '投标企业信用报告样例'
+    }
   }
 ]

+ 17 - 0
apps/mobile/src/router/modules/order.js

@@ -118,6 +118,23 @@ export default [
             import('@/views/create-order/components/bigmember/HeaderAdsense'),
         })
       },
+      {
+        path: 'creditreport',
+        name: 'createCreditReportOrder',
+        meta: {
+          header: true,
+          productId: 150,
+          title: '购买投标企业信用报告'
+        },
+        components: createRouterNamedComponents({
+          default: () =>
+            import('@/views/create-order/components/creditreport/Default'),
+          activity: null,
+          form: null,
+          footer: () =>
+            import('@/views/create-order/components/creditreport/Footer')
+        })
+      },
       {
         path: 'datareport',
         name: 'createDataReportOrder',

+ 14 - 1
apps/mobile/src/store/modules/createOrder.js

@@ -69,6 +69,7 @@ const productNameMap = {
   115: '采购单位画像包',
   117: '数据报告',
   118: '剑鱼文库会员',
+  150: '投标企业信用报告',
   203: '市场分析定制报告下载包',
   201: '企业中标分析报告下载包',
   202: '业主采购分析报告下载包'
@@ -130,6 +131,7 @@ export default {
        * 113 省份订阅包
        * 114 附件下载包
        * 115 采购单位画像包
+       * 150 投标企业信用报告
        */
       id: -1,
       // 当前产品请求附加参数信息
@@ -174,9 +176,13 @@ export default {
       amount: false,
       submit: false
     },
-    isShowGiftNotice: false
+    isShowGiftNotice: false,
+    bidCreditReportInfo: {} // 投标企业信用报告信息
   }),
   mutations: {
+    SAVE_BID_CREDIT_REPORT_INFO(state, info) {
+      state.bidCreditReportInfo = info
+    },
     /**
      * 设置产品列表及更新下属信息
      * @param state
@@ -190,6 +196,7 @@ export default {
       state.productSpec.maps = productSpecMap
       state.product.index = defaultIndex
     },
+
     /**
      * 更新指定的产品规格信息
      * @param state
@@ -422,6 +429,9 @@ export default {
         )
       )
     },
+    async saveBidCreditReportInfo({ commit }, info) {
+      await commit('SAVE_BID_CREDIT_REPORT_INFO', Object.assign({}, info))
+    },
     // 根据商品ID、扩展等参数获取商品类型、规格等详细信息
     async getProductInfo({ commit, dispatch, getters, state }, payload) {
       // 合并一些请求参数
@@ -743,6 +753,9 @@ export default {
     }
   },
   getters: {
+    getBidCreditReportInfo(state) {
+      return state.bidCreditReportInfo
+    },
     // 用于提交订单的数据
     submitHooks(state) {
       return state.hooks.submit

+ 2 - 2
apps/mobile/src/views/ai-search/index.vue

@@ -972,7 +972,7 @@ init()
         <div
           class="bind-phone-popup"
           v-if="needBindPhone"
-          @click="checkBindPhone"
+          @click="checkBindPhone(false)"
         ></div>
       </div>
     </div>
@@ -981,7 +981,7 @@ init()
       <div
         v-if="needBindPhone || needLogin"
         class="bind-phone-popup"
-        @click="checkBindPhone"
+        @click="checkBindPhone(false)"
       />
       <div v-if="askModel.list.length === 0" class="ai-search--empty">
         <AppEmpty state="ai-logo">

+ 74 - 28
apps/mobile/src/views/article/components/ContentHeader.vue

@@ -23,8 +23,7 @@
         class="j-tag-item border gray round"
         :class="[tag.className]"
         :href="tag.link"
-        >{{ tag.label }}</a
-      >
+      >{{ tag.label }}</a>
     </div>
     <div v-if="showCollection" class="tag-list">
       <span
@@ -32,8 +31,7 @@
         :key="tag.id"
         class="j-tag-item blue round text-underline"
         @click="onCollectionTagClick(tag)"
-        >{{ tag.label }}</span
-      >
+      >{{ tag.label }}</span>
     </div>
     <div class="sub-info-line">
       <span class="info-publish-time">{{ content.time }}</span>
@@ -41,13 +39,22 @@
         参标人:{{ cbPersonText }}
       </span>
       <!-- 无参标人和时间一行 -->
-      <div
-        v-else-if="showRenMaiButton"
-        class="relationship-button"
-        @click="findRenMai"
-      >
-        <span class="relationship-icon j-icon j-base-icon icon-renmai" />
-        <span class="relationship-text">找人脉</span>
+      <div v-else-if="showRenMaiButton" class="sub-info-line">
+        <div v-if="showCreditReport" class="creditreport-button" @click="creditReport">
+          <span class="creditreport-text">投标企业信用报告</span>
+        </div>
+        <div
+          class="relationship-button"
+          @click="findRenMai"
+        >
+          <span class="relationship-icon j-icon j-base-icon icon-renmai" />
+          <span class="relationship-text">找人脉</span>
+        </div>
+      </div>
+      <div v-else class="sub-info-line">
+        <div v-if="showCreditReport" class="creditreport-button" @click="creditReport">
+          <span class="creditreport-text">投标企业信用报告</span>
+        </div>
       </div>
     </div>
     <div v-if="showRenMaiButton2" class="sub-info-line">
@@ -92,9 +99,9 @@ export default {
   },
   computed: {
     ...mapState({
-      content: (state) => state.article.mainModel.content,
-      summary: (state) => state.article.mainModel.summary,
-      otherModel: (state) => state.article.otherModel,
+      content: state => state.article.mainModel.content,
+      summary: state => state.article.mainModel.summary,
+      otherModel: state => state.article.otherModel,
       IsSunPublishContent() {
         return this.content.IsSunPublishContent || false
       },
@@ -116,7 +123,8 @@ export default {
       headerType() {
         if (this.IsSunPublishContent) {
           return this.content.publicType
-        } else {
+        }
+        else {
           return '业主委托项目'
         }
       }
@@ -128,16 +136,21 @@ export default {
       }
       const { inBiddingPersonList: bList } = this.otherModel
       if (Array.isArray(bList) && bList.length > 0) {
-        const list = bList.map((b) => b.trim()).filter((b) => !!b)
+        const list = bList.map(b => b.trim()).filter(b => !!b)
         if (list.length > 1) {
           return `${list.slice(0, 1).join(',')} 等`
-        } else {
+        }
+        else {
           return list.join(',')
         }
-      } else {
+      }
+      else {
         return ''
       }
     },
+    showCreditReport() {
+      return articleTypeArr.includes(this.content?._ob?.topType || this.content?._ob?.subType || '')
+    },
     showRenMaiButton() {
       if (this.IsSunPublishContent) {
         return ''
@@ -154,7 +167,6 @@ export default {
       return this.otherModel.collectionTags
     }
   },
-  created() {},
   methods: {
     async onCollectionTagClick(tag) {
       if (this.beforeLeavePage) {
@@ -173,12 +185,33 @@ export default {
         if (res && Array.isArray(res.data)) {
           return res.data.includes('bi_rmgl')
         }
-      } catch (error) {
+      }
+      catch (error) {
         console.log(error)
-      } finally {
+      }
+      finally {
         this.renmai.loading = false
       }
     },
+    creditReport() {
+      const buyer = this.summary?.buyers[0]?.name
+      const typeName = this.content?._ob?.topType || this.content?._ob?.subType
+      const breaker_name = `投标企业信用报告_${typeName}`
+      // 区分标讯类型埋点
+      try {
+        window.__EasyJTrack.addTrack(breaker_name, {
+          breaker_name
+        })
+      }
+      catch (e) {
+        console.log(e)
+      }
+      this.$router.push({
+        path: '/order/create/creditreport',
+        query: buyer ? { buyer } : {}
+      })
+    },
+
     async findRenMai() {
       const hasPower = await this.checkHasRemMaiPower()
       if (hasPower) {
@@ -189,7 +222,8 @@ export default {
           showCancelButton: false,
           confirmButtonText: '我知道了'
         })
-      } else {
+      }
+      else {
         // 弹窗
         // this.$toast('暂无权限')
         // 跳转大会员落地页
@@ -290,20 +324,32 @@ export default {
 }
 
 .sub-info-line-r {
-  position: relative;
+  display: flex;
+  align-items: center;
+}
+.creditreport-button {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  margin-right: 10px;
+  padding: 2px 8px;
+  line-height: 20px;
+  color: #fff;
+  background: linear-gradient(to right, #5FD4E3, #28C1E2);
+  border-radius: 4px;
 }
 .relationship-button {
-  position: relative;
-  right: -16px;
-  top: 0;
+  // position: relative;
+  // right: -16px;
+  // top: 0;
   display: flex;
   align-items: center;
   justify-content: space-between;
   padding: 2px 12px;
   height: 24px;
   color: #fff;
-  background-color: $main;
-  border-radius: 14px 0 0 14px;
+  background: linear-gradient(to right, #5FD4E3, #28C1E2);
+  border-radius: 4px;
   .j-icon {
     margin-right: 4px;
     width: 12px;

+ 12 - 2
apps/mobile/src/views/article/components/PDF.vue

@@ -1,8 +1,10 @@
 <template>
   <div class="pdf-box">
-    <van-loading v-if="loading" size="32px" vertical>加载中</van-loading>
+    <van-loading v-if="useLoading && loading" size="32px" vertical
+      >加载中</van-loading
+    >
     <div v-show="isRender" id="pdf-canvas" style="height: 100%; width: 100%">
-      <div class="pagination-container">
+      <div class="pagination-container" v-show="usePagination">
         <span class="pagination-now">1</span>
         <em>/</em>
         <span class="pagination-total"></span>
@@ -30,6 +32,14 @@ export default {
     [Loading.name]: Loading
   },
   props: {
+    useLoading: {
+      type: Boolean,
+      default: true
+    },
+    usePagination: {
+      type: Boolean,
+      default: true
+    },
     url: {
       type: String,
       default: ''

+ 3 - 0
apps/mobile/src/views/article/content-new.vue

@@ -0,0 +1,3 @@
+<template>
+  <h1>移动端详情页</h1>
+</template>

+ 0 - 1
apps/mobile/src/views/article/content.vue

@@ -1,4 +1,3 @@
-small-tab
 <template>
   <div class="article-content">
     <van-skeleton

+ 168 - 0
apps/mobile/src/views/common/pdfViewExample.vue

@@ -0,0 +1,168 @@
+<template>
+  <div class="pdf-view-example j-contanter">
+    <div class="j-main">
+      <PDF
+        v-if="pdfUrl"
+        :useLoading="false"
+        :usePagination="false"
+        :url="pdfUrl"
+      ></PDF>
+    </div>
+    <div v-if="!getUserId" class="j-footer">
+      <!-- /jyapp/free/login?url=/jy_mobile/order/create/creditreport&activity=bidCreditReportPreview -->
+      <AdSingle
+        ad="app-credit-report-sample"
+        :show-tag="false"
+        :show-close-icon="false"
+        class="adsense-container"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from 'vuex'
+import AdSingle from '@/components/ad/Ad'
+import { getAssetsFile } from '@/utils'
+import PDF from '@/views/article/components/PDF.vue'
+
+export default {
+  name: 'PdfViewExample',
+  components: {
+    AdSingle,
+    PDF
+  },
+  data() {
+    return {
+      pdfUrl: '',
+      pdf: null,
+      totalPages: 0,
+      currentPage: 1, // 新增
+      batchSize: 5, // 新增
+      config: {
+        PAGE_TO_VIEW: 0,
+        SCALE: 1.0,
+        CMAP_URL:
+          'https://cdn-common.jianyu360.com/cdn/lib/pdfjs-dist/2.1.266/cmaps/',
+        CMAP_PACKED: true,
+        workerSrc:
+          'https://cdn-common.jianyu360.com/cdn/lib/pdfjs-dist/2.1.266/build/pdf.worker.min.js'
+      }
+    }
+  },
+  computed: {
+    ...mapGetters('user', ['getUserId'])
+  },
+  created() {
+    this.$toast.loading('加载中...')
+
+    const { pdfUrl } = this.$route.query
+    if (pdfUrl) {
+      this.pdfUrl = decodeURIComponent(pdfUrl)
+    } else {
+      const pdfAssets = getAssetsFile('example-min.pdf')
+      // this.pdfUrl = 'https://cdn-common.jianyu360.cn/cdn/assets/file/example.pdf'
+      this.pdfUrl = pdfAssets
+    }
+  },
+  mounted() {
+    // const container = document.getElementById('pdf-view-container')
+    //
+    // this.loadPdf(this.pdfUrl, container)
+    // // 监听窗口的 resize 事件,实现自适应效果
+    // window.addEventListener('resize', () => {
+    //   container.innerHTML = ''
+    //   this.loadPdf(this.pdfUrl, container)
+    // })
+  },
+  methods: {
+    async loadPdf(pdfUrl, container) {
+      console.log('pdfUrl', pdfUrl)
+      try {
+        pdfjsLib.GlobalWorkerOptions.workerSrc = this.config.workerSrc
+        const loadingTask = pdfjsLib.getDocument({
+          url: pdfUrl,
+          cMapUrl: this.config.CMAP_URL,
+          cMapPacked: this.config.CMAP_PACKED,
+          disableRange: true,
+          disableAutoFetch: false, // 启动自动分块加载
+          // 添加缓存头
+          httpHeaders: {
+            'Cache-Control': 'max-age=3600' // 缓存 1 小时
+          },
+          // 增加网络请求超时时间,避免因网络问题导致加载失败
+          timeout: 30000,
+          // 减少初始加载的字节数,提高初始加载速度
+          initialDataSize: 1024 * 1024
+        })
+        this.pdf = await loadingTask.promise
+        this.totalPages = this.pdf.numPages
+        this.currentPage = 1
+        this.batchSize = 5 // 新增
+
+        await this.loadBatchPages(container) // 新增
+        this.$toast.clear()
+        // 监听滚动事件
+        container.addEventListener('scroll', () => this.handleScroll(container))
+      } catch (error) {
+        console.error('Error loading PDF:', error)
+      }
+    },
+    async loadBatchPages(container) {
+      // 加载当前页码开始的连续多页,这里以5页为例
+      // 分批加载,从当前页码开始,最多加载5页
+      const endPage = Math.min(
+        this.currentPage + this.batchSize - 1,
+        this.totalPages
+      )
+      for (let pageNum = this.currentPage; pageNum <= endPage; pageNum++) {
+        const page = await this.pdf.getPage(pageNum)
+        const viewport = page.getViewport({ scale: this.calculateScale(page) })
+        const canvas = document.createElement('canvas')
+        const ctx = canvas.getContext('2d')
+        canvas.height = viewport.height
+        canvas.width = viewport.width
+        container.appendChild(canvas)
+
+        await page.render({
+          canvasContext: ctx,
+          viewport
+        }).promise
+      }
+      this.currentPage = endPage + 1 // 更新当前页码
+    },
+    handleScroll(container) {
+      const { scrollTop, scrollHeight, clientHeight } = container
+      if (scrollTop + clientHeight >= scrollHeight - 100) {
+        // 当滚动到底部附近时
+        if (this.currentPage <= this.totalPages) {
+          this.loadBatchPages(container)
+        }
+      }
+    },
+    // 计算缩放比例以适应容器宽度
+    calculateScale(page) {
+      const containerWidth =
+        document.getElementById('pdf-view-container').clientWidth
+      const viewport = page.getViewport({ scale: 1 })
+      // 增加一个倍数来提高清晰度,例如 1.5
+      return (containerWidth / viewport.width) * 3
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+.pdf-view-example {
+  ::v-deep {
+    .pdf-box {
+      height: 100%;
+    }
+    .pdfjs {
+      padding-top: 0;
+    }
+    .pdfViewer {
+      padding: 0;
+    }
+  }
+}
+</style>

+ 22 - 5
apps/mobile/src/views/create-order/components/bigmember/HeaderAdsense.vue

@@ -1,7 +1,11 @@
 <template>
-  <div class='header-show-group'>
+  <div class="header-show-group">
     <!-- 轮播广告位 -->
-    <Swipe :skeleton='false' :exposure-prefix="'移动端购买页轮播广告位-' + getContentAdID + '-'"  :ad="getContentAdID" />
+    <Swipe
+      :skeleton="false"
+      :exposure-prefix="'移动端购买页轮播广告位-' + getContentAdID + '-'"
+      :ad="getContentAdID"
+    />
   </div>
 </template>
 <script>
@@ -18,12 +22,25 @@ export default {
   }
 }
 </script>
-<style lang="scss">
+<style lang="scss" scoped>
 .header-show-group {
   background-color: #fff;
 
-  .my-swipe {
-    margin: 4px 0;
+  ::v-deep {
+    .my-swipe {
+      margin: 0;
+
+      .van-swipe-item {
+        width: 100vw !important;
+        height: auto;
+        border-radius: unset;
+        margin: 0;
+
+        .van-image {
+          width: 100vw !important;
+        }
+      }
+    }
   }
 }
 </style>

+ 14 - 0
apps/mobile/src/views/create-order/components/creditreport/Default.vue

@@ -0,0 +1,14 @@
+<template>
+  <ProductionCard />
+</template>
+
+<script>
+import ProductionCard from './ProductionCard'
+
+export default {
+  name: 'ProductionCardDefault',
+  components: {
+    ProductionCard
+  }
+}
+</script>

+ 110 - 0
apps/mobile/src/views/create-order/components/creditreport/Footer.vue

@@ -0,0 +1,110 @@
+<template>
+  <div>
+    <SubmitBar
+      class="credit-order-footer"
+      :checked="canNextMap.read"
+      :params="params"
+      :confirm-btn-text="confirmBtnText"
+      :confirm-disabled="confirmDisabled"
+      :confirm-btn-tip-text="confirmBtnTipText"
+      cancel-btn-text="报告样例"
+      :show-cancel-btn="showCancelBtn"
+      :show-price="showPrice"
+      @input="checkedChange"
+      @confirmBtn="onConfirm"
+      @cancelBtn="onCreditRepoert"
+      @pass="checkedChange"
+      @toLink="saveBaseInfo"
+    />
+  </div>
+</template>
+
+<script>
+import { mapActions, mapGetters, mapMutations, mapState } from 'vuex'
+import SubmitBar from '@/components/create-order/SubmitBar'
+
+export default {
+  name: 'CreateOrderFooter',
+  components: {
+    SubmitBar
+  },
+  data() {
+    return {
+      showCancelBtn: true
+    }
+  },
+  computed: {
+    ...mapState('createOrder', ['canNextMap', 'hooks']),
+    ...mapGetters('createOrder', [
+      'productOrderAmount',
+      'productUI',
+      'canSubmitOrder',
+      'getBidCreditReportInfo'
+    ]),
+    params() {
+      const { pay, origin, discount } = this.productOrderAmount
+      const { deductCount } = this.productUI
+      return {
+        deductCount,
+        pay,
+        origin,
+        discount // 折扣,优惠了多少钱
+      }
+    },
+    confirmDisabled() {
+      return !this.canSubmitOrder
+    },
+    showPrice() {
+      // 个人支付显示价格信息
+      return this.productUI.personalPay
+    },
+    confirmBtnTipText() {
+      return this.productUI.personalPay ? undefined : '(支付后可开票)'
+    },
+    confirmBtnText() {
+      return this.productUI.submitText || '提交订单'
+    }
+  },
+  methods: {
+    ...mapMutations('createOrder', ['updateCanNextMap']),
+    ...mapActions('createOrder', ['submitCreatedProductOrder']),
+    checkedChange(f) {
+      this.updateCanNextMap({
+        read: f
+      })
+    },
+    onCreditRepoert() {
+      console.log(this.getBidCreditReportInfo, 'getBidCreditReportInfo')
+      // 将getBidCreditReportInfo保存到本地
+      this.saveBaseInfo()
+      this.$router.push({
+        path: '/common/pdfview'
+      })
+    },
+    saveBaseInfo() {
+      this.$storage.set('bidCreditReportInfo', this.getBidCreditReportInfo, { storage: sessionStorage })
+    },
+    onConfirm() {
+      this.submitCreatedProductOrder()
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.credit-order-footer {
+  ::v-deep {
+    .van-button--default {
+      flex: none;
+      width: 96px;
+      border: 1px solid #2ABED1;
+      background: rgba(42, 190, 209, 0.08);
+      color: #2ABED1;
+    }
+    .van-button--primary {
+      flex: none;
+      width: 96px;
+    }
+  }
+}
+</style>

+ 351 - 0
apps/mobile/src/views/create-order/components/creditreport/ProductionCard.vue

@@ -0,0 +1,351 @@
+<template>
+  <div class="production-card credit-report-production-card">
+    <div class="report-func">
+      <div class="report-func-title">
+        报告作用
+      </div>
+      <div class="report-func-content">
+        信用报告通过信用背书、风险预警、政策适配,三大核心作用,成为投标企业参与市场竞争的关键工具。
+      </div>
+    </div>
+    <div class="report-info">
+      <van-form ref="formRef">
+        <van-field
+          v-model="info.company"
+          class="ent-input-field"
+          required
+          type="textarea"
+          autosize
+          rows="1"
+          name="pattern"
+          label="投标企业名称"
+          placeholder="必填"
+          :show-error="false"
+          :rules="[
+            { required: true, message: '必填' },
+            { pattern: /^.{3,}$/, message: '输入内容需大于两个字' }, // 添加正则验证规则
+          ]"
+          @input="onInput($event, 'ent')"
+          @blur="onBlur('company')"
+        >
+          <template #extra>
+            <!-- 添加联想弹窗 -->
+            <div v-if="entList.length" class="ent-popup-container">
+              <div class="ent-popup-wrap">
+                <div v-for="(item, index) in entList" :key="index" class="wrap-list" @click="clickAssociation(item, 'ent')">
+                  {{ item.name }}
+                </div>
+              </div>
+            </div>
+          </template>
+        </van-field>
+        <van-field
+          v-model="info.buyer"
+          class="company-input-field"
+          required
+          type="textarea"
+          autosize
+          rows="1"
+          name="pattern"
+          label="招标单位名称"
+          placeholder="必填"
+          :show-error="false"
+          :rules="[
+            { required: true, message: '必填' },
+            { pattern: /^.{3,}$/, message: '输入内容需大于两个字' }, // 添加正则验证规则
+          ]"
+          @input="onInput($event, 'company')"
+          @blur="onBlur('buyer')"
+        >
+          <template #extra>
+            <!-- 添加联想弹窗 -->
+            <div v-if="companyList.length" class="ent-popup-container">
+              <div class="ent-popup-wrap">
+                <div v-for="(item, index) in companyList" :key="index" class="wrap-list" @click="clickAssociation(item, 'company')">
+                  {{ item.name }}
+                </div>
+              </div>
+            </div>
+          </template>
+        </van-field>
+        <van-field
+          v-model="info.email"
+          required
+          name="pattern"
+          label="邮箱"
+          placeholder="必填,报告将发送至邮箱"
+          :show-error="false"
+          :rules="[
+            { required: true, message: '请输入邮箱' },
+            { pattern: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/, message: '邮箱格式错误' }, // 邮箱校验正则规则
+          ]"
+          @blur="onBlur('email')"
+        />
+      </van-form>
+    </div>
+    <div class="report-tip">
+      支付成功后,系统将于{{ bidCreditReportTime }}内将报告发送至您的邮箱,您也可前往“资产-报告下载记录”查看详情。
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapActions, mapGetters, mapMutations } from 'vuex'
+import { Field, Form } from 'vant'
+import { debounce } from '@/utils/utils'
+import { mixinHeader } from '@/utils/mixins/header'
+import { openAppOrWxPage } from '@/utils'
+import { appCallOpenWindow } from '@/utils/callFn/appFn'
+import { creditReportEntSearch, creditReportTime } from '@/api/modules/'
+import orderActivityHelper from '@/utils/mixins/modules/order-activity-helper'
+
+export default {
+  name: 'CreditReportProductionCard',
+  components: {
+    [Form.name]: Form,
+    [Field.name]: Field
+  },
+  mixins: [mixinHeader, orderActivityHelper],
+  data() {
+    return {
+      pageLayoutConf: {
+        title: '购买投标企业信用报告',
+      },
+      conf: {
+        productName: '投标企业信用报告',
+        productId: 150,
+        linkKey: 'bidCreditRepoetLink',
+      },
+      info: {
+        company: '',
+        buyer: '',
+        cert_no: '',
+        email: ''
+      },
+      entList: [],
+      companyList: [],
+      bidCreditReportTime: 0
+    }
+  },
+  computed: {
+    ...mapGetters('createOrder', ['productExtend', 'productId', 'getBidCreditReportInfo'])
+  },
+  watch: {
+    info: {
+      deep: true,
+      handler(newVal) {
+        this.saveBidCreditReportInfo(newVal)
+      }
+    },
+  },
+  created() {
+    const { buyer } = this.$route.query
+    if (buyer) {
+      this.info.buyer = buyer
+    }
+  },
+  mounted() {
+    this.updatePayAmount()
+    this.getCreditReportTime()
+    this.getUserInfoFun()
+    const bidCreditReportInfo = this.$storage.get('bidCreditReportInfo', {}, {
+      storage: sessionStorage
+    })
+    if (Object.keys(bidCreditReportInfo).length) {
+      Object.assign(this.info, bidCreditReportInfo)
+      // 删除本地缓存
+      this.$storage.rm('bidCreditReportInfo', { storage: sessionStorage })
+    }
+  },
+  methods: {
+    ...mapActions('createOrder', ['setProductInfo', 'saveBidCreditReportInfo']),
+    ...mapActions('user', ['getUserInfo']),
+    async getCreditReportTime() {
+      const { error_code: code, data } = await creditReportTime()
+      if (code === 0) {
+        this.bidCreditReportTime = data.bidCreditReport_makeTime
+      }
+    },
+    async getUserInfoFun() {
+      const res = await this.getUserInfo()
+      if (res?.reportMail) {
+        this.info.email = res.reportMail || ''
+      }
+    },
+    async updatePayAmount() {
+      const { productId } = this.conf
+      this.setProductInfo({
+        id: productId,
+        hooks: {
+          submit: this.onSubmit.bind(this)
+        }
+      })
+    },
+    async onSubmit(pre, next) {
+      // 校验输入框是否全部填写完成,如果没有则不提交订单
+      let validBool = false
+      await this.$refs.formRef.validate().then((valid) => {
+        validBool = !valid
+      })
+      if (!validBool)
+        return
+      const payload = {
+        product: pre.productName,
+        productId: pre.productSpecId,
+        discountId: pre.offersId,
+        lotteryId: pre.offersId,
+        activityType: pre.activityType,
+        data: {
+          ...this.info
+        }
+      }
+      const res = await next(payload)
+      const { data } = res
+      if (data && data.needPay) {
+        const { linkKey } = this.conf
+        const query = this.getCommonQuery(data.order_code)
+        const orderDetailLinkInfo
+            = this.getProductionLinks(linkKey).orderDetail
+        const payLinkInfo = this.getProductionLinks(linkKey).pay
+        if (this.$envs.inApp || this.$envs.inWX) {
+          this.$storage.set(
+            `${this.$route.path}-redirect`,
+            {
+              urls: orderDetailLinkInfo,
+              query
+            },
+            { storage: sessionStorage }
+          )
+        }
+        openAppOrWxPage(payLinkInfo, {
+          query
+        })
+        return res
+      }
+    },
+    clickAssociation(item, type) {
+      if (type === 'ent') {
+        this.info.company = item.name
+        this.info.cert_no = item.cert_no
+        this.entList = []
+      }
+      else {
+        this.info.buyer = item.name
+        this.companyList = []
+      }
+    },
+    onInput(value, type) {
+      const pattner = /^.{3,}$/
+      if (!pattner.test(value))
+        return
+      this.getCompany(value, type)
+    },
+    onBlur(fieldName) {
+      // 投标企业名称必须选择联想内的企业
+      if (fieldName === 'company') {
+        if (!this.info.cert_no) {
+          this.info.company = ''
+        }
+      }
+    },
+    // 获取公司联想数据
+    getCompany: debounce(function (val, type) {
+      if (val) {
+        creditReportEntSearch({ entName: val }).then((res) => {
+          if (type === 'ent') {
+            this.entList = res.data || []
+          }
+          else {
+            this.companyList = res.data || []
+          }
+        })
+      }
+    }, 500)
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.credit-report-production-card {
+  .report-func {
+    padding: 12px 16px;
+    background: #fff;
+    .report-func-title {
+      font-size: 16px;
+      line-height: 24px;
+      color: #171826;
+      margin-bottom: 4px;
+    }
+    .report-func-content {
+      font-size: 13px;
+      line-height: 20px;
+      color:#5F5E64;
+    }
+  }
+  .report-info {
+    margin-top: 8px;
+    ::v-deep {
+      .van-cell {
+        padding: 15px 16px 15px 24px;
+        .van-cell__title {
+         font-size: 15px;
+         line-height: 22px;
+         color: #5F5E64;
+        }
+        input::placeholder, textarea::placeholder {
+          font-size: 15px;
+          line-height: 22px;
+          color: #C0C4CC;
+        }
+        .van-field__control {
+          white-space: normal;
+          word-wrap: break-word;
+        }
+        &.ent-input-field, &.company-input-field {
+          position: relative;
+          .ent-popup-container {
+            position: absolute;
+            top: 54px;
+            right: 20px;
+            overflow: hidden;
+            overflow-y: auto;
+            width: 230px;
+            max-height: 150px;
+            z-index: 1;
+            background: #fff;
+            border: 1px solid #2ABED1;
+            border-radius: 8px;
+          }
+          .ent-popup-wrap {
+            display: flex;
+            flex-direction: column;
+            .wrap-list {
+              width: 100%;
+              white-space: nowrap;
+              overflow: hidden;
+              text-overflow: ellipsis;
+              padding: 4px 10px;
+              font-size: 15px;
+              line-height: 22px;
+              color: #171826;
+              border-bottom: 1px solid rgba(0, 0, 0, 0.05);
+            }
+          }
+        }
+        &.van-field--error .van-field__control {
+          color: #171826;
+        }
+      }
+      .van-cell--required::before {
+        left: 16px;
+      }
+    }
+  }
+  .report-tip {
+    padding: 12px 16px;
+    font-size: 12px;
+    line-height: 18px;
+    color: #9B9CA3;
+  }
+}
+</style>

+ 22 - 5
apps/mobile/src/views/create-order/components/datapack/HeaderAdsense.vue

@@ -1,7 +1,11 @@
 <template>
-  <div class='header-show-group'>
+  <div class="header-show-group">
     <!-- 轮播广告位 -->
-    <Swipe :skeleton='false' :exposure-prefix="'移动端购买页轮播广告位-' + getContentAdID + '-'"  :ad="getContentAdID" />
+    <Swipe
+      :skeleton="false"
+      :exposure-prefix="'移动端购买页轮播广告位-' + getContentAdID + '-'"
+      :ad="getContentAdID"
+    />
   </div>
 </template>
 <script>
@@ -18,12 +22,25 @@ export default {
   }
 }
 </script>
-<style lang="scss">
+<style lang="scss" scoped>
 .header-show-group {
   background-color: #fff;
 
-  .my-swipe {
-    margin: 4px 0;
+  ::v-deep {
+    .my-swipe {
+      margin: 0;
+
+      .van-swipe-item {
+        width: 100vw !important;
+        height: auto;
+        border-radius: unset;
+        margin: 0;
+
+        .van-image {
+          width: 100vw !important;
+        }
+      }
+    }
   }
 }
 </style>

+ 22 - 5
apps/mobile/src/views/create-order/components/vipsubscribe/HeaderAdsense.vue

@@ -1,7 +1,11 @@
 <template>
-  <div class='header-show-group'>
+  <div class="header-show-group">
     <!-- 轮播广告位 -->
-    <Swipe :skeleton='false' :exposure-prefix="'移动端购买页轮播广告位-' + getContentAdID + '-'"  :ad="getContentAdID" />
+    <Swipe
+      :skeleton="false"
+      :exposure-prefix="'移动端购买页轮播广告位-' + getContentAdID + '-'"
+      :ad="getContentAdID"
+    />
   </div>
 </template>
 <script>
@@ -31,12 +35,25 @@ export default {
   }
 }
 </script>
-<style lang="scss">
+<style lang="scss" scoped>
 .header-show-group {
   background-color: #fff;
 
-  .my-swipe {
-    margin: 4px 0;
+  ::v-deep {
+    .my-swipe {
+      margin: 0;
+
+      .van-swipe-item {
+        width: 100vw !important;
+        height: auto;
+        border-radius: unset;
+        margin: 0;
+
+        .van-image {
+          width: 100vw !important;
+        }
+      }
+    }
   }
 }
 </style>

+ 210 - 102
apps/mobile/src/views/reportAnalysis/components/listItem.vue

@@ -1,12 +1,18 @@
 <template>
   <div id="listItem">
-    <div class="tag" :class="tagclass">{{ data.type | typeFilter }}</div>
-    <div class="toptime">{{ data.l_createTime | timeFilter }}</div>
+    <div class="tag" :class="tagclass">
+      {{ data.type | typeFilter }}
+    </div>
+    <div class="toptime">
+      {{ data.l_createTime | timeFilter }}
+    </div>
     <div class="content">
       <!-- 企业 -->
       <div v-if="tagclass === 'green'">
         <div class="item">
-          <p class="label">目标企业:</p>
+          <p class="label">
+            目标企业:
+          </p>
           <p
             class="value heigh_line ellipsis"
             @click="$emit('titleClick', data)"
@@ -15,89 +21,175 @@
           </p>
         </div>
         <div class="item">
-          <p class="label">成交时间:</p>
-          <p class="value">{{ data.timeRange | timeRangeF }}</p>
+          <p class="label">
+            成交时间:
+          </p>
+          <p class="value">
+            {{ data.timeRange | timeRangeF }}
+          </p>
         </div>
-        <div class="item" v-if="data.match">
-          <p class="label">关键词:</p>
-          <p class="value ellipsis">{{ matchF(data.match, data) }}</p>
+        <div v-if="data.match" class="item">
+          <p class="label">
+            关键词:
+          </p>
+          <p class="value ellipsis">
+            {{ matchF(data.match, data) }}
+          </p>
         </div>
-        <div class="item" v-if="data.matchRange">
-          <p class="label">搜索范围:</p>
-          <p class="value ellipsis">{{ data.matchRange | matchRangeF }}</p>
+        <div v-if="data.matchRange" class="item">
+          <p class="label">
+            搜索范围:
+          </p>
+          <p class="value ellipsis">
+            {{ data.matchRange | matchRangeF }}
+          </p>
         </div>
-        <div class="item" v-if="data.area">
-          <p class="label">项目地区:</p>
-          <p class="value ellipsis">{{ data.area | areaF }}</p>
+        <div v-if="data.area" class="item">
+          <p class="label">
+            项目地区:
+          </p>
+          <p class="value ellipsis">
+            {{ data.area | areaF }}
+          </p>
+        </div>
+        <div v-if="data.scopeClass" class="item">
+          <p class="label">
+            行业:
+          </p>
+          <p class="value ellipsis">
+            {{ data.scopeClass | scopeClassF }}
+          </p>
+        </div>
+        <div v-if="data.s_buyerClass" class="item">
+          <p class="label long">
+            采购单位类型:
+          </p>
+          <p class="value ellipsis">
+            {{ data.s_buyerClass | buyerClassF }}
+          </p>
         </div>
-        <div class="item" v-if="data.scopeClass">
-          <p class="label">行业:</p>
-          <p class="value ellipsis">{{ data.scopeClass | scopeClassF }}</p>
+      </div>
+      <div v-if="tagclass === 'blue2'">
+        <div v-if="data.ent" class="item">
+          <p class="label">
+            投标企业名称:
+          </p>
+          <p class="value ellipsis">
+            {{ data.ent }}
+          </p>
         </div>
-        <div class="item" v-if="data.s_buyerClass">
-          <p class="label long">采购单位类型:</p>
-          <p class="value ellipsis">{{ data.s_buyerClass | buyerClassF }}</p>
+        <div v-if="data.buyer" class="item">
+          <p class="label long">
+            投标单位名称:
+          </p>
+          <p class="value ellipsis">
+            {{ data.buyer }}
+          </p>
         </div>
       </div>
       <!-- 业主采购 -->
       <div v-if="tagclass === 'yellow'">
         <div class="item">
-          <p class="label">目标业主:</p>
+          <p class="label">
+            目标业主:
+          </p>
           <p class="value heigh_line" @click="$emit('titleClick', data)">
             {{ data.entName || '-' }}
           </p>
         </div>
         <div class="item">
-          <p class="label">成交时间:</p>
-          <p class="value">{{ data.timeRange | timeRangeF }}</p>
+          <p class="label">
+            成交时间:
+          </p>
+          <p class="value">
+            {{ data.timeRange | timeRangeF }}
+          </p>
         </div>
-        <div class="item" v-if="data.match">
-          <p class="label">关键词:</p>
-          <p class="value ellipsis">{{ matchF(data.match, data) }}</p>
+        <div v-if="data.match" class="item">
+          <p class="label">
+            关键词:
+          </p>
+          <p class="value ellipsis">
+            {{ matchF(data.match, data) }}
+          </p>
         </div>
-        <div class="item" v-if="data.matchRange">
-          <p class="label">搜索范围:</p>
-          <p class="value ellipsis">{{ data.matchRange | matchRangeF }}</p>
+        <div v-if="data.matchRange" class="item">
+          <p class="label">
+            搜索范围:
+          </p>
+          <p class="value ellipsis">
+            {{ data.matchRange | matchRangeF }}
+          </p>
         </div>
-        <div class="item" v-if="data.area">
-          <p class="label">项目地区:</p>
-          <p class="value ellipsis">{{ data.area | areaF }}</p>
+        <div v-if="data.area" class="item">
+          <p class="label">
+            项目地区:
+          </p>
+          <p class="value ellipsis">
+            {{ data.area | areaF }}
+          </p>
         </div>
-        <div class="item" v-if="data.scopeClass">
-          <p class="label">行业:</p>
-          <p class="value ellipsis">{{ data.scopeClass | scopeClassF }}</p>
+        <div v-if="data.scopeClass" class="item">
+          <p class="label">
+            行业:
+          </p>
+          <p class="value ellipsis">
+            {{ data.scopeClass | scopeClassF }}
+          </p>
         </div>
-        <div class="item" v-if="data.s_buyerClass">
-          <p class="label long">采购单位类型:</p>
-          <p class="value ellipsis">{{ data.s_buyerClass | buyerClassF }}</p>
+        <div v-if="data.s_buyerClass" class="item">
+          <p class="label long">
+            采购单位类型:
+          </p>
+          <p class="value ellipsis">
+            {{ data.s_buyerClass | buyerClassF }}
+          </p>
         </div>
       </div>
       <!-- 定制化分析 -->
       <div v-if="tagclass === 'blue'">
         <div class="item">
-          <p class="label">分析内容:</p>
-          <p class="value ellipsis" v-html="formatKeys(data.s_keysItems)"></p>
+          <p class="label">
+            分析内容:
+          </p>
+          <p class="value ellipsis" v-html="formatKeys(data.s_keysItems)" />
         </div>
         <div class="item">
-          <p class="label">匹配方式:</p>
-          <p class="value">{{ formatMatchWay(data.s_matchingMode) }}</p>
+          <p class="label">
+            匹配方式:
+          </p>
+          <p class="value">
+            {{ formatMatchWay(data.s_matchingMode) }}
+          </p>
         </div>
         <div class="item">
-          <p class="label">成交时间:</p>
+          <p class="label">
+            成交时间:
+          </p>
           <p class="value ellipsis">
             {{ data.s_rangeTime | formatTime('yyyy-MM-dd') }}
           </p>
         </div>
-        <div class="item" v-if="formatArea(data.s_area)">
-          <p class="label">项目地区:</p>
-          <p class="value ellipsis">{{ formatArea(data.s_area) }}</p>
+        <div v-if="formatArea(data.s_area)" class="item">
+          <p class="label">
+            项目地区:
+          </p>
+          <p class="value ellipsis">
+            {{ formatArea(data.s_area) }}
+          </p>
         </div>
-        <div class="item" v-if="formatIndustry(data.s_industry)">
-          <p class="label">行业:</p>
-          <p class="value ellipsis">{{ formatIndustry(data.s_industry) }}</p>
+        <div v-if="formatIndustry(data.s_industry)" class="item">
+          <p class="label">
+            行业:
+          </p>
+          <p class="value ellipsis">
+            {{ formatIndustry(data.s_industry) }}
+          </p>
         </div>
-        <div class="item" v-if="formatBuyerclass(data.s_buyerClass)">
-          <p class="label long">采购单位类型:</p>
+        <div v-if="formatBuyerclass(data.s_buyerClass)" class="item">
+          <p class="label long">
+            采购单位类型:
+          </p>
           <p class="value ellipsis">
             {{ formatBuyerclass(data.s_buyerClass) }}
           </p>
@@ -105,29 +197,17 @@
       </div>
     </div>
     <div class="foot_btn" @click="$emit('download', data)">
-      <span class="download_icon"></span>
+      <span class="download_icon" />
       <span class="download">下载</span>
     </div>
   </div>
 </template>
 
 <script>
-import { dateFormatter, FilterHistoryAjaxModel2ViewModel } from '@/utils/'
+import { FilterHistoryAjaxModel2ViewModel, dateFormatter } from '@/utils/'
+
 export default {
-  name: 'listItem',
-  data() {
-    return {}
-  },
-  props: {
-    data: {
-      type: Object,
-      default: () => {}
-    },
-    tagclass: {
-      type: String,
-      default: 'green'
-    }
-  },
+  name: 'ListItem',
   filters: {
     dateFilter(val) {
       return val ? dateFormatter(val * 1000, 'yyyy-MM-dd') : '-'
@@ -138,11 +218,16 @@ export default {
     typeFilter(val) {
       if (val === '1') {
         return '企业中标分析报告'
-      } else if (val === '2') {
+      }
+      else if (val === '2') {
         return '业主采购分析报告'
-      } else if (val === '3') {
+      }
+      else if (val === '3') {
         return '市场分析定制报告'
       }
+      else if (val === '4') {
+        return '投标企业信用报告'
+      }
     },
     timeRangeF(val) {
       return val ? val.replace('_', '至') : '-'
@@ -159,7 +244,6 @@ export default {
     },
     areaF(val) {
       return val ? val.replace(/,/g, ',') : ''
-
     },
     scopeClassF(val) {
       // if (val) {
@@ -178,41 +262,57 @@ export default {
       //   return '-'
       // }
       if (val) {
-        let text =
-          FilterHistoryAjaxModel2ViewModel.formatIndustry(
+        const text
+          = FilterHistoryAjaxModel2ViewModel.formatIndustry(
             val
           ).industryText.join(',')
         return text
-      } else {
+      }
+      else {
         return '-'
       }
     },
     buyerClassF(val) {
       if (val) {
-        let text =
-          FilterHistoryAjaxModel2ViewModel.formatBuyerClass(
+        const text
+          = FilterHistoryAjaxModel2ViewModel.formatBuyerClass(
             val
           ).buyerClassText.join(',')
         return text
-      } else {
+      }
+      else {
         return '-'
       }
     },
     formatTime(value, fmt) {
-      if (!value) return ''
+      if (!value)
+        return ''
       const rangeTimeArr = value.split('-')
       const start = new Date(rangeTimeArr[0] * 1000).getTime()
       const end = new Date(rangeTimeArr[1] * 1000).getTime()
       console.log(start)
-      return dateFormatter(start, fmt) + '至' + dateFormatter(end, fmt)
+      return `${dateFormatter(start, fmt)}至${dateFormatter(end, fmt)}`
+    }
+  },
+  props: {
+    data: {
+      type: Object,
+      default: () => {}
+    },
+    tagclass: {
+      type: String,
+      default: 'green'
     }
   },
+  data() {
+    return {}
+  },
   methods: {
     matchF(val, item) {
-      return item.exactMatch === '0' ? val + '(模糊)' : val + '(精准)'
+      return item.exactMatch === '0' ? `${val}(模糊)` : `${val}(精准)`
     },
     formatMatchWay(m) {
-      var map = {
+      const map = {
         title: '按标题匹配',
         content: '按全文匹配'
       }
@@ -220,13 +320,14 @@ export default {
       return text
     },
     formatKeys(keys) {
-      var tempStr = '-'
-      if (!keys) return tempStr
+      let tempStr = '-'
+      if (!keys)
+        return tempStr
       try {
-        var tempResult = []
-        var tempList = JSON.parse(keys)
-        tempList.forEach(function (v) {
-          v.a_key.forEach(function (k) {
+        const tempResult = []
+        const tempList = JSON.parse(keys)
+        tempList.forEach((v) => {
+          v.a_key.forEach((k) => {
             tempResult.push({
               key: [].concat(k.key, k.appendkey),
               type: k.matchway === 1 ? '模糊' : '精准'
@@ -234,59 +335,66 @@ export default {
           })
         })
         tempStr = tempResult
-          .map(function (v) {
+          .map((v) => {
             return `[${v.key.join(' ')}]-${v.type}`
           })
           .join('、')
-      } catch (e) {
+      }
+      catch (e) {
         console.log(e)
       }
       return tempStr
     },
     formatBuyerclass(value) {
-      if (!value) return ''
+      if (!value)
+        return ''
       return String(value).replace(/,/g, ',')
     },
     formatArea(value) {
-      if (!value) return '-'
+      if (!value)
+        return '-'
       value = JSON.parse(value)
 
       if (Object.keys(value).length === 0) {
         return ''
       }
 
-      var area = []
-      var citys = []
-      for (var key in value) {
+      const area = []
+      const citys = []
+      for (const key in value) {
         if (!value[key].length) {
           area.push(key)
-        } else {
+        }
+        else {
           citys.push(...value[key])
         }
       }
 
-      var concatList = area.concat(citys)
+      const concatList = area.concat(citys)
 
       if (concatList.length) {
         return concatList.join(',')
-      } else {
+      }
+      else {
         return ''
       }
     },
     formatIndustry(value) {
-      if (!value) return ''
+      if (!value)
+        return ''
       value = JSON.parse(value)
 
       if (Object.keys(value).length === 0) {
         return ''
       }
 
-      var keyArr = []
-      var valueArr = []
-      for (var key in value) {
+      const keyArr = []
+      const valueArr = []
+      for (const key in value) {
         if (!value[key].length) {
           keyArr.push(key)
-        } else {
+        }
+        else {
           valueArr.push(...value[key])
         }
       }
@@ -390,7 +498,7 @@ export default {
     background-color: #00d086;
   }
 
-  .blue {
+  .blue, .blue2 {
     background-color: #3399ff;
   }
 

+ 160 - 46
apps/mobile/src/views/reportAnalysis/reportDownload.vue

@@ -1,8 +1,12 @@
 <template>
   <div id="reportDownload">
     <div class="reportContent">
-      <div class="title">报告下载余额</div>
-      <div class="desc">注:请在有效期内使用,过期清零,不可转赠。</div>
+      <div class="title">
+        报告下载余额
+      </div>
+      <div class="desc">
+        注:请在有效期内使用,过期清零,不可转赠。
+      </div>
       <div class="box_content">
         <div class="item">
           <div class="line green" />
@@ -10,9 +14,7 @@
             <div class="left">
               <span class="count">{{ winner.total }}</span>
               <span class="unit">份</span>
-              <span class="textbtn" @click="goDetail('企业中标分析报告')"
-                >查明细</span
-              >
+              <span class="textbtn" @click="goDetail('企业中标分析报告')">查明细</span>
               <span class="texticon" />
             </div>
             <div class="right" @click="rechargeNow('企业中标分析报告')">
@@ -20,7 +22,9 @@
             </div>
           </div>
           <div class="textGroup">
-            <div class="left">企业中标分析报告下载余额</div>
+            <div class="left">
+              企业中标分析报告下载余额
+            </div>
             <div v-if="winner.minEndTime" class="right">
               最近有效期至:{{ winner.minEndTime }}
             </div>
@@ -32,9 +36,7 @@
             <div class="left">
               <span class="count">{{ buyer.total }}</span>
               <span class="unit">份</span>
-              <span class="textbtn" @click="goDetail('业主采购分析报告')"
-                >查明细</span
-              >
+              <span class="textbtn" @click="goDetail('业主采购分析报告')">查明细</span>
               <span class="texticon" />
             </div>
             <div class="right" @click="rechargeNow('业主采购分析报告')">
@@ -42,7 +44,9 @@
             </div>
           </div>
           <div class="textGroup">
-            <div class="left">业主采购分析报告下载余额</div>
+            <div class="left">
+              业主采购分析报告下载余额
+            </div>
             <div v-if="buyer.minEndTime" class="right">
               最近有效期至:{{ buyer.minEndTime }}
             </div>
@@ -54,9 +58,7 @@
             <div class="left">
               <span class="count">{{ market.total }}</span>
               <span class="unit">份</span>
-              <span class="textbtn" @click="goDetail('市场分析定制报告')"
-                >查明细</span
-              >
+              <span class="textbtn" @click="goDetail('市场分析定制报告')">查明细</span>
               <span class="texticon" />
             </div>
             <div class="right" @click="rechargeNow('市场分析定制报告')">
@@ -64,15 +66,39 @@
             </div>
           </div>
           <div class="textGroup">
-            <div class="left">市场分析定制报告下载余额</div>
+            <div class="left">
+              市场分析定制报告下载余额
+            </div>
             <div v-if="market.minEndTime" class="right">
               最近有效期至:{{ market.minEndTime }}
             </div>
           </div>
         </div>
       </div>
+      <!-- S 投标企业信用报告入口 S -->
+      <div class="credit_report">
+        <div class="credit_report_main">
+          <div class="credit_report_title">
+            <span>投标企业信用报告</span>
+            <div class="credit_report_action">
+              <div class="credit_report_example" @click="viewReportExample">
+                报告样例 <span class="texticon" />
+              </div>
+              <div class="credit_report_btn" @click="goBuy">
+                去购买
+              </div>
+            </div>
+          </div>
+          <div class="credit_report_content">
+            <span>信用报告通过信用背书、风险预警、政策适配,三大核心作用,成为投标企业参与市场竞争的关键工具‌。</span>
+          </div>
+        </div>
+      </div>
+      <!-- E 投标企业信用报告入口 E -->
       <div class="content_list">
-        <div class="title">报告下载记录</div>
+        <div class="title">
+          报告下载记录
+        </div>
         <div class="list_box">
           <van-list
             ref="vanList"
@@ -106,7 +132,9 @@
       :before-close="beforeEmailDialogClose"
     >
       <div class="attachment-content">
-        <div class="attachment-tip-text">附件将以邮件的形式发送至您的邮箱</div>
+        <div class="attachment-tip-text">
+          附件将以邮件的形式发送至您的邮箱
+        </div>
         <van-field
           v-model="attachment.email"
           class="attachment-email-input"
@@ -179,17 +207,32 @@ export default {
     colorFilter(val) {
       if (val === '1') {
         return 'green'
-      } else if (val === '2') {
+      }
+      else if (val === '2') {
         return 'yellow'
-      } else if (val === '3') {
+      }
+      else if (val === '3') {
         return 'blue'
       }
+      else if (val === '4') {
+        return 'blue2'
+      }
     }
   },
   created() {
     this.getcount()
   },
   methods: {
+    viewReportExample() {
+      this.$router.push({
+        path: '/common/pdfview'
+      })
+    },
+    goBuy() {
+      this.$router.push({
+        path: '/order/create/creditreport'
+      })
+    },
     async getcount() {
       const { data } = await pdfaccount({})
       if (data) {
@@ -216,13 +259,14 @@ export default {
         this.list.total = data.count
         // this.list.total = 10 //不支持分页可以写死
         this.list.value = this.list.value.concat(data.list)
-      } else {
+      }
+      else {
         this.list.finished = true
       }
       // 数据请求完成(根据页码计算,当前页是否是最后一页)
       // 请求完成后,页码就变为了下一页的页面,所以这里要-1
-      const isLastPage =
-        (this.list.pageNum - 1) * this.list.pageSize >= this.list.total
+      const isLastPage
+        = (this.list.pageNum - 1) * this.list.pageSize >= this.list.total
       if (isLastPage) {
         this.list.finished = true
       }
@@ -233,11 +277,13 @@ export default {
         this.$router.push({
           path: '/order/create/enterpriseanalysis'
         })
-      } else if (type === '业主采购分析报告') {
+      }
+      else if (type === '业主采购分析报告') {
         this.$router.push({
           path: '/order/create/owneranalysis'
         })
-      } else if (type === '市场分析定制报告') {
+      }
+      else if (type === '市场分析定制报告') {
         this.$router.push({
           path: '/order/create/marketanalysis'
         })
@@ -263,7 +309,8 @@ export default {
             eId: item.ent
           }
         })
-      } else {
+      }
+      else {
         // 采购单位画像
         // 跳转页面
         let goLink = ''
@@ -271,13 +318,15 @@ export default {
           goLink = `/big/wx/page/unit_portrayal?entName=${encodeURIComponent(
             item.entName
           )}`
-        } else {
+        }
+        else {
           // 新商机管理采购单位画像
           if (this.isNewBusiness) {
             goLink = `/jyapp/big/page/client_portrayal?entName=${encodeURIComponent(
               item.entName
             )}&from=client`
-          } else {
+          }
+          else {
             goLink = `/jyapp/big/page/unit_portrayal?entName=${encodeURIComponent(
               item.entName
             )}`
@@ -300,11 +349,16 @@ export default {
         let defaultName = '报告'
         if (item.type === '1') {
           defaultName = '企业中标分析报告'
-        } else if (item.type === '2') {
+        }
+        else if (item.type === '2') {
           defaultName = '业主采购分析报告'
-        } else if (item.type === '3') {
+        }
+        else if (item.type === '3') {
           defaultName = '市场分析定制报告'
         }
+        else if (item.type === '4') {
+          defaultName = '投标企业信用报告'
+        }
         if (newIOSApp) {
           const loading = this.$toast.loading({
             duration: 0,
@@ -316,11 +370,13 @@ export default {
             loading.clear()
             appDownLoadFile(name, types, fileUrl, size)
           })
-        } else {
+        }
+        else {
           location.href = fileUrl
           // window.open(fileUrl)
         }
-      } else {
+      }
+      else {
         // fileUrl: 下载地址
         if (fileUrl) {
           if (platform === 'wx') {
@@ -332,11 +388,13 @@ export default {
                 target: encodeURIComponent(fileUrl)
               }
             })
-          } else {
+          }
+          else {
             // window.open(fileUrl)
             location.href = fileUrl
           }
-        } else {
+        }
+        else {
           console.log('获取附件fid失败')
         }
       }
@@ -344,7 +402,8 @@ export default {
     viewReport() {
       if (this.$envs.inAppOrH5) {
         location.href = '/jyapp/big/page/report_analysis'
-      } else {
+      }
+      else {
         location.href = '/big/wx/page/report_analysis'
       }
     },
@@ -358,7 +417,8 @@ export default {
       if (code === 0) {
         done && done()
         this.$toast('已发送至邮箱')
-      } else {
+      }
+      else {
         done && done(false)
         this.$toast('发送失败')
       }
@@ -377,7 +437,8 @@ export default {
       if (!emailRegExp.test(email)) {
         done(false)
         return this.$toast('邮箱格式错误')
-      } else {
+      }
+      else {
         const { fileUrl } = this.attachment
 
         if (!fileUrl) {
@@ -396,7 +457,8 @@ export default {
           console.log(fileSize, '文件大小')
           try {
             callback(fileSize)
-          } catch (e) {
+          }
+          catch (e) {
             console.log(e)
           }
         }
@@ -407,7 +469,7 @@ export default {
 }
 </script>
 
-<style>
+<style lang="scss">
 #reportDownload {
   background-color: #f5f6f7;
 
@@ -475,14 +537,6 @@ export default {
               margin-left: 12px;
             }
 
-            .texticon {
-              width: 12px;
-              height: 12px;
-              display: inline-block;
-              background-image: url(@/assets/image/reportanalysis/icon_download.png);
-              background-size: contain;
-              background-repeat: no-repeat;
-            }
           }
 
           .right {
@@ -536,7 +590,67 @@ export default {
         margin-bottom: 0;
       }
     }
-
+    .texticon {
+      width: 12px;
+      height: 12px;
+      display: inline-block;
+      background-image: url(@/assets/image/reportanalysis/icon_download.png);
+      background-size: contain;
+      background-repeat: no-repeat;
+    }
+    .credit_report {
+      margin-top: 16px;
+      width: 100%;
+      background: linear-gradient(to right, #EFFDFF, #FFFFFF);
+      border: 1px solid #87DFEA;
+      box-shadow: 0px 2px 8px 0px rgba(54, 147, 179, 0.05);
+      border-radius: 8px;
+      .credit_report_main {
+        padding: 12px;
+        width: 100%;
+        height: 100%;
+        background: url(../../assets/image/reportanalysis/credit-corner-bg.png) no-repeat;
+        background-size: 58px 55px;
+        background-position: right bottom;
+      }
+      .credit_report_title {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        > span {
+          font-size: 16px;
+          line-height: 24px;
+          color: #171826;
+        }
+      }
+      .credit_report_action {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        .credit_report_example {
+          display: flex;
+          align-items: center;
+          margin-right: 10px;
+          font-size: 12px;
+          line-height: 18px;
+          color: #2ABED1;
+        }
+        .credit_report_btn {
+          padding: 2px 17px;
+          background: #2ABED1;
+          color: #fff;
+          font-size: 12px;
+          line-height: 18px;
+          border-radius: 4px;
+        }
+      }
+      .credit_report_content {
+        margin-top: 10px;
+        font-size: 12px;
+        line-height: 18px;
+        color: #5F5E64;
+      }
+    }
     .content_list {
       margin-top: 16px;
 

+ 6 - 6
apps/mobile/vite.config.js

@@ -128,22 +128,22 @@ export default defineConfig(({ mode, command }) => {
       proxy: {
         // 接口解密iframe
         '^/page_decrypt': {
-          target: 'https://jybx2-webtest.jydev.jianyu360.com',
+          target: 'https://jybx-webtest.jydev.jianyu360.com',
           changeOrigin: true
         },
         '/jyapi': {
-          target: 'https://jybx2-webtest.jydev.jianyu360.com',
+          target: 'https://jybx-webtest.jydev.jianyu360.com',
           changeOrigin: true,
           rewrite: path => path.replace(/^\/jyapi/, '')
         },
         '/api': {
-          target: 'https://jybx2-webtest.jydev.jianyu360.com',
+          target: 'https://jybx-webtest.jydev.jianyu360.com',
           changeOrigin: true,
           rewrite: path => path.replace(/^\/api/, '')
         },
-        '/aiChat': 'https://jybx2-webtest.jydev.jianyu360.com',
-        '/commonFunctions': 'https://jybx2-webtest.jydev.jianyu360.com',
-        '/common-module': 'https://jybx2-webtest.jydev.jianyu360.com'
+        '/aiChat': 'https://jybx-webtest.jydev.jianyu360.com',
+        '/commonFunctions': 'https://jybx-webtest.jydev.jianyu360.com',
+        '/common-module': 'https://jybx-webtest.jydev.jianyu360.com'
       }
     }
   }

+ 2 - 1
configs/proxy/dev-proxy.js

@@ -40,7 +40,8 @@ const ProxyPrefixes = [
   '/js',
   '/css',
   '/antiRes',
-  '/images/wx/'
+  '/images/wx/',
+  '/shareFile/'
 ]
 
 export function useServerProxy(domain, defaultProxy = {}) {

+ 13 - 13
package.json

@@ -1,7 +1,7 @@
 {
   "name": "jy-web",
-  "description": "剑鱼产品整体前端应用,基于 vite、pnpm 构建 monorepo 体系。",
   "private": true,
+  "description": "剑鱼产品整体前端应用,基于 vite、pnpm 构建 monorepo 体系。",
   "workspaces": [
     "packages/*",
     "data/*",
@@ -10,7 +10,14 @@
     "core/*",
     "docs/*"
   ],
+  "author": "",
+  "license": "ISC",
+  "keywords": [],
   "main": "index.js",
+  "engines": {
+    "node": ">=16",
+    "pnpm": ">=8"
+  },
   "scripts": {
     "preinstall": "npx only-allow pnpm",
     "postinstall": "simple-git-hooks",
@@ -30,9 +37,6 @@
     "dev:jy-pc": "pnpm --filter web-pc run dev",
     "build:jy-pc": "pnpm --filter web-pc run build"
   },
-  "keywords": [],
-  "author": "",
-  "license": "ISC",
   "dependencies": {
     "axios": "^1.6.7",
     "qs": "^6.11.2",
@@ -40,24 +44,20 @@
     "vue-router": "^3.6.5"
   },
   "devDependencies": {
+    "@antfu/eslint-config": "^2.25.1",
     "@babel/plugin-proposal-optional-chaining": "^7.21.0",
     "colorette": "^2.0.20",
     "cross-env": "^7.0.3",
+    "eslint": "^8.57.0",
+    "eslint-plugin-format": "^0.1.2",
     "execa": "^7.1.1",
     "inquirer": "^9.1.5",
-    "prettier": "^3.1.0",
     "lint-staged": "^14.0.1",
+    "prettier": "^3.1.0",
     "simple-git-hooks": "^2.11.1",
     "typescript": "^5.0.2",
     "vite": "^4.5.3",
-    "vite-plugin-html-redirect": "^1.0.4",
-    "eslint": "^8.57.0",
-    "@antfu/eslint-config": "^2.25.1",
-    "eslint-plugin-format": "^0.1.2"
-  },
-  "engines": {
-    "node": ">=16",
-    "pnpm": ">=8"
+    "vite-plugin-html-redirect": "^1.0.4"
   },
   "simple-git-hooks": {
     "pre-commit": "pnpm exec lint-staged --concurrent false"

+ 56 - 29
plugins/bind-phone-mobile/src/utils/appFn.js

@@ -7,7 +7,8 @@ import { copyText } from '@/utils'
 export function appCallPhone(phone) {
   try {
     JyObj.callPhone(phone)
-  } catch (e) {
+  }
+  catch (e) {
     console.warn('error: app call phone', e)
   }
 }
@@ -15,7 +16,8 @@ export function appCallPhone(phone) {
 export function appCallCopyText(text) {
   try {
     JyObj.wirteRight(text)
-  } catch (e) {
+  }
+  catch (e) {
     console.warn('error: app call copy text', e)
     copyText(text)
   }
@@ -29,7 +31,8 @@ export function appCallCopyText(text) {
 export function appCallOpenWindow(link, title = '剑鱼标讯') {
   try {
     JyObj.openExternalLink(link, title)
-  } catch (e) {
+  }
+  catch (e) {
     console.warn('error: app call openExternalLink', e)
   }
 }
@@ -41,7 +44,8 @@ export function appCallOpenWindow(link, title = '剑鱼标讯') {
 export function appCallChangeTab(name) {
   try {
     JyObj.skipAppointTab(name)
-  } catch (e) {
+  }
+  catch (e) {
     console.warn('error: app call skipAppointTab', e)
   }
 }
@@ -53,7 +57,8 @@ export function appCallChangeTab(name) {
 export function appCallReloadTab(name, status = 1) {
   try {
     JyObj.refreshAppointTab(name, status)
-  } catch (e) {
+  }
+  catch (e) {
     console.warn('error: app call refreshAppointTab', e)
   }
 }
@@ -67,7 +72,8 @@ export function appCallReloadTab(name, status = 1) {
 export function appCallBackTab(name) {
   try {
     JyObj.backUrl(name)
-  } catch (e) {
+  }
+  catch (e) {
     console.warn('error: app call backUrl', e)
   }
 }
@@ -79,7 +85,8 @@ export function appCallBackTab(name) {
 export function appCallHideTab(type) {
   try {
     JyObj.hiddenBottom(type)
-  } catch (e) {
+  }
+  catch (e) {
     console.warn('error: app call hiddenBottom', e)
   }
 }
@@ -91,7 +98,8 @@ export function appCallGetToken() {
   let result
   try {
     result = JyObj.getUserToken()
-  } catch (e) {
+  }
+  catch (e) {
     console.warn('error: app call getUserToken', e)
   }
   return result
@@ -107,7 +115,8 @@ export function savePic(
 ) {
   try {
     window.__compatibleAppFn(JyObj.savePic, imgbase64, tip)
-  } catch (e) {
+  }
+  catch (e) {
     console.warn('error: app call savePic', e)
   }
 }
@@ -117,7 +126,8 @@ export function checkNoticePermission() {
   let status
   try {
     status = JyObj.IosCall('checkNoticePermission')
-  } catch (e) {
+  }
+  catch (e) {
     console.warn('error: app call checkNoticePermission', e)
   }
   return status
@@ -127,7 +137,8 @@ export function checkNoticePermission() {
 export function openSystemNotification() {
   try {
     JyObj.openSystemNotification()
-  } catch (e) {
+  }
+  catch (e) {
     console.warn('error: app call openSystemNotification', e)
   }
 }
@@ -139,7 +150,8 @@ export function getAppVersion() {
   let version = ''
   try {
     version = JyObj.getVersion()
-  } catch (e) {
+  }
+  catch (e) {
     console.warn('error: get app version failed', e)
   }
   return version || ''
@@ -157,7 +169,8 @@ export function getAppVersion() {
 export function appDownLoadFile(filename, filetype, fileurl, filesize) {
   try {
     JyObj.downLoadFile(filename, filetype, fileurl, filesize)
-  } catch (e) {
+  }
+  catch (e) {
     console.warn('error: app ios download file failed', e)
   }
 }
@@ -172,7 +185,8 @@ export function appHideRedSpotOnMenu(menu) {
   }
   try {
     JyObj.hideRedSpotOnMenu(menu)
-  } catch (e) {
+  }
+  catch (e) {
     console.warn('error: app hideRedSpotOnMenu failed', e)
   }
 }
@@ -184,7 +198,8 @@ export function appHideRedSpotOnMenu(menu) {
 export function appSendMsgCount(num) {
   try {
     JyObj.sendMsgCount(num)
-  } catch (e) {
+  }
+  catch (e) {
     console.warn('error: app sendMsgCount failed', e)
   }
 }
@@ -195,7 +210,8 @@ export function appSendMsgCount(num) {
 export function appOpenWeChartScan() {
   try {
     JyObj.openWeChartScan()
-  } catch (e) {
+  }
+  catch (e) {
     console.warn('error: app openWeChartScan failed', e)
   }
 }
@@ -208,7 +224,8 @@ export function appOpenWeChartScan() {
 export function appClearHistory() {
   try {
     JyObj.clearHistory()
-  } catch (e) {
+  }
+  catch (e) {
     console.warn('error: app clearHistory failed', e)
   }
 }
@@ -219,7 +236,8 @@ export function appClearHistory() {
 export function appSideslipOpen() {
   try {
     JyObj.sideslipOpen()
-  } catch (e) {
+  }
+  catch (e) {
     console.warn('error: app sideslipOpen failed', e)
   }
 }
@@ -229,7 +247,8 @@ export function appSideslipOpen() {
 export function appSideslipClose() {
   try {
     JyObj.sideslipClose()
-  } catch (e) {
+  }
+  catch (e) {
     console.warn('error: app sideslipClose failed', e)
   }
 }
@@ -251,14 +270,16 @@ export function appShare(
 ) {
   try {
     if (
-      window.__checkAppVersionCanRunTips &&
-      window.__checkAppVersionCanRunTips()
+      window.__checkAppVersionCanRunTips
+      && window.__checkAppVersionCanRunTips()
     ) {
       JyObj.share(shareType, title, content, link, authTip)
-    } else {
+    }
+    else {
       JyObj.share(shareType, title, content, link)
     }
-  } catch (e) {
+  }
+  catch (e) {
     console.warn('error: app call share', e)
   }
 }
@@ -267,7 +288,8 @@ export function appShare(
 export function appGetPhoneBind() {
   try {
     JyObj.getPhoneBind()
-  } catch (e) {
+  }
+  catch (e) {
     console.warn('error: app call getPhoneBind', e)
   }
 }
@@ -276,7 +298,8 @@ export function appGetPhoneBind() {
 export function appGetPushRid() {
   try {
     JyObj.getPushRid()
-  } catch (e) {
+  }
+  catch (e) {
     console.warn('error: app call getPushRid', e)
   }
 }
@@ -285,7 +308,8 @@ export function appGetPushRid() {
 export function appGetOtherPushId() {
   try {
     JyObj.getOtherPushId()
-  } catch (e) {
+  }
+  catch (e) {
     console.warn('error: app call getOtherPushId', e)
   }
 }
@@ -294,7 +318,8 @@ export function appGetOtherPushId() {
 export function appGetPhoneType() {
   try {
     JyObj.getPhoneType()
-  } catch (e) {
+  }
+  catch (e) {
     console.warn('error: app call getPhoneType', e)
   }
 }
@@ -303,7 +328,8 @@ export function appGetPhoneType() {
 export function appGetChannel() {
   try {
     JyObj.getChannel()
-  } catch (e) {
+  }
+  catch (e) {
     console.warn('error: app call getChannel', e)
   }
 }
@@ -312,7 +338,8 @@ export function appGetChannel() {
 export function appGetDeviceId() {
   try {
     JyObj.getDeviceId()
-  } catch (e) {
+  }
+  catch (e) {
     console.warn('error: app call getDeviceId', e)
   }
 }

+ 0 - 8
plugins/gift-friends/src/entry.js

@@ -32,14 +32,6 @@ function install(Vue) {
     const element = document.querySelector(options.props.el) || document.body
     element.appendChild(instance.$el)
     instance.visible = true
-    // 弹框弹起时埋点abtest
-    try {
-      window.__EasyJTrack.addTrack(options.props.name, {
-        break_data: 'abtest',
-        source: options.props.name
-      })
-    }
-    catch (error) {}
     return instance
   }
 }

+ 0 - 8
plugins/gift-friends/src/utils/plugins/index.js

@@ -26,14 +26,6 @@ const GiftFriendsDialogPlugin = {
       console.log(element, 'element')
       element.appendChild(instance.$el)
       instance.visible = true
-      // 弹框弹起时埋点abtest
-      try {
-        window.__EasyJTrack.addTrack(options.props.name, {
-          break_data: 'abtest',
-          source: options.props.name
-        })
-      }
-      catch (error) {}
       return instance
     }
   }

+ 7 - 2
plugins/login-auth/src/module-model/wxQrcode.ts

@@ -1,5 +1,5 @@
 import { computed, ref } from 'vue'
-
+import { useCustomSpecialSource } from '@/utils/use'
 /**
  * 微信二维码相关
  */
@@ -10,7 +10,12 @@ const pageShareId = ref('')
 const pageKopShareId = ref('')
 
 const pageWechatQrcodeImgSrc = computed(() => {
-  return ImgBase + pageShareId.value
+  const source = useCustomSpecialSource()
+  if (source && source !== 'undefined' && source !== 'null') {
+    return ImgBase + pageShareId.value + '?source=' + source
+  } else {
+    return ImgBase + pageShareId.value
+  }
 })
 
 const pageKopQrcodeImgSrc = computed(() => {