zhongshujie
14 小时以前 ce7cf2f67ec29aef55a889574942c58c8d7737bd
学术成果详情
4个文件已修改
10256 ■■■■ 已修改文件
src/assets/js/config.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/achievements/details.vue 711 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/achievements/index.vue 79 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yarn.lock 9464 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/config.js
@@ -5,7 +5,7 @@
export const requestTimeOut = 300000; // 请求超时时间
export const tokenKey = "token";
export const userInfoKey = "userInfo"; // 用户信息key
export const appRefCode = "tourismWebsite";
export const appRefCode = "academicianWangYongyanDatabase";
export const goodsStore = `defaultGoodsStore${appId}`; // 默认商品库(书城)
export const publicStore = `defaultPublicStore${appId}`; // 默认资源开放仓储
export const publicRepository = `defaultPublicRepository${appId}`; // 默认资源开放库
src/views/achievements/details.vue
@@ -15,58 +15,62 @@
          <p>
            <span>{{ details.source }}</span>
            <span>{{ details.year }}</span>
            <span v-if="details.DOI">doi:{{ details.DOI }}</span>
          </p>
        </li>
        <li class="page-main-title">
          <p>
            <span v-for="(item, index) in details.characterList" :key="index">{{ item.name }}</span>
            <span v-for="(item, index) in details.author" :key="index">{{ item }}</span>
          </p>
          <p>
          <p v-if="details.abstract">
            <span>摘要:</span>
            <span class="page-main-abstract" v-html="details.abstract"></span>
          </p>
          <p>
          <p v-if="details.keyWords && details.keyWords.length > 0">
            <span>关键词:</span>
            <span class="page-main-keyword" v-for="(item, index) in details.keyWords" :key="index">{{ item
            }}</span>
          </p>
          <p v-if="!isDisplay">
            <el-button @click="isDisplay = !isDisplay">查看全文</el-button>
          <p v-if="details.cmsItemType != 'video' && details.cmsItemType != 'audio'">
            <el-button @click="openPdf(details.name)">查看全文</el-button>
          </p>
          <p class="page-main-video" v-if="isDisplay">
            <video :src="details.videoUrl" controls autoplay class="video" width="70%"></video>
          <p class="page-main-video" v-if="details.cmsItemType == 'video'">
            <video :src="details.src" controls autoplay class="video" width="70%"></video>
          </p>
          <p class="page-main-audio" v-if="isDisplay">
            <audio :src="details.videoUrl" controls autoplay class="video" width="100%"></audio>
          <p class="page-main-audio" v-if="details.cmsItemType == 'audio'">
            <audio :src="details.src" controls autoplay class="video" width="100%"></audio>
          </p>
        </li>
        <li class="page-main-literature">
          <p class="literature-header">相关文献</p>
          <div class="content-right">
          <div class="content-right" v-loading="loading" element-loading-text="检索结果加载中"
            element-loading-spinner="el-icon-loading" element-loading-background="rgba(0, 0, 0, 0)">
            <!-- 结果展示 -->
            <ul class="right-main" v-for="(item, index) in resultList" :key="index">
              <li class="main-name">
                <p>{{ item.name }}</p>
                <p>
                  <el-button @click="goPage(item)">详情</el-button>
                  <el-button @click="goPage(item.id)">详情</el-button>
                  <el-button>AI智能阅读</el-button>
                </p>
              </li>
              <li class="main-sources">
                <span>{{ item.type }}</span>
                <span>{{ item.sources }}</span>
                <span>{{ item.time }}</span>
                <span>{{ item.resourceTypeName }}</span>
                <span>{{ item.source }}</span>
                <span>{{ item.year }}</span>
                <span v-if="item.DOI">doi:{{ item.DOI }}</span>
              </li>
              <li class="main-author">
                {{ item.author }}
              </li>
              <li class="main-title" :title="item.title">
                <span>摘要: </span>{{ item.title }}
              <li class="main-title" :title="item.abstract" v-if="item.abstract">
                <span>摘要: </span>
                <span class="page-main-abstract" v-html="item.abstract"></span>
              </li>
              <li class="main-keyword">
              <li class="main-keyword" v-if="item.keyWords && item.keyWords.length > 0">
                <span>关键词:</span>
                <span class="keyWord" v-for="(citem, cindex) in item.keyword" :key="cindex">
                  {{ citem.name }}
                <span class="keyWord" v-for="(citem, cindex) in item.keyWords" :key="cindex">
                  {{ citem }}
                </span>
              </li>
            </ul>
@@ -74,182 +78,452 @@
        </li>
      </ul>
    </div>
    <el-dialog v-model="dialogVisible" :title="pdfName" width="60vw" top="2vh" bottom="2vh"
      :visible.sync="dialogVisible" class="custom-dialog">
      <div class="pdfInfoBox">
        <div v-for="(item, index) in pdfList" :key="index" class="pdfItem" :page="index + 1">
          <img :src="item.showSrc" alt="" style="min-height: 550px" loading="lazy" />
          <el-divider content-position="center"> 第 {{ index + 1 }} 页 </el-divider>
        </div>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import { requestCtx, appRefCode } from "@/assets/js/config";
import fileApi from "@/assets/js/middleGround/api/file";
import MG from "@/assets/js/middleGround/WebMiddleGroundApi.js";
import moment from "moment";
export default {
  data() {
    return {
      isDisplay: false,
      details: {
        name: "中药闸柜的历史传承与新时代发展思考",
        sources: "北京中医药大学学报",
        time: "2025-02-24",
        characterList: [
          {
            name: "杨浣菲",
          },
          {
            name: "杨浣菲",
          },
          {
            name: "杨浣菲",
          },
          {
            name: "杨浣菲",
          },
        ],
        title:
          "中药闸柜是传统中药调剂的高级管理人员,在'前店后厂式'中药房发挥重要作用和关键职能。传承中药闸柜的宝贵学术经验与优秀文化对厘清中药学学科发展脉络、规范中药调剂技术操作、促进老药工技艺'活态传承'具有重要科学价值和现实意义。面向新时代、开启新思维,本文对老字号中药铺的兴起和中药闸柜进行考证,分析中药闸柜的岗位责任、传承路径及未来发展,提出高素质中药闸柜人才培养策略,旨在培养符合当代社会需求的中药行业复合型创新人才。中药闸柜是传统中药调剂的高级管理人员,在'前店后厂式'中药房发挥重要作用和关键职能。传承中药闸柜的宝贵学术经验与优秀文化对厘清中药学学科发展脉络、规范中药调剂技术操作、促进老药工技艺'活态传承'具有重要科学价值和现实意义。面向新时代、开启新思维,本文对老字号中药铺的兴起和中药闸柜进行考证,分析中药闸柜的岗位责任、传承路径及未来发展,提出高素质中药闸柜人才培养策略,旨在培养符合当代社会需求的中药行业复合型创新人才。",
        keyword: [
          {
            name: "中药闸柜",
          },
          {
            name: "中药闸柜",
          },
          {
            name: "中药闸柜",
          },
          {
            name: "中药闸柜",
          },
        ],
        videoUrl: "https://www.w3schools.com/html/mov_bbb.mp4",
        audioMd5: "",
      },
      // 查询结果
      resultList: [
        {
          name: "中药闸柜的历史传承与新时代发展思考",
          sources: "北京中医药大学学报",
          type: "期刊",
          author: "杨浣菲  北京中医药大学中药学院;赵天成  北京师范大学",
          time: "2025-02-24 09:21",
          title:
            "中药闸柜是传统中药调剂的高级管理人员,在'前店后厂式'中药房发挥重要作用和关键职能。传承中药闸柜的宝贵学术经验与优秀文化对厘清中药学学科发展脉络、规范中药调剂技术操作、促进老药工技艺'活态传承'具有重要科学价值和现实意义。面向新时代、开启新思维,本文对老字号中药铺的兴起和中药闸柜进行考证,分析中药闸柜的岗位责任、传承路径及未来发展,提出高素质中药闸柜人才培养策略,旨在培养符合当代社会需求的中药行业复合型创新人才。",
          keyword: [
            {
              name: "中药闸柜",
            },
            {
              name: "中药闸柜",
            },
            {
              name: "中药闸柜",
            },
            {
              name: "中药闸柜",
            },
          ],
        },
        {
          name: "中药闸柜的历史传承与新时代发展思考",
          sources: "北京中医药大学学报",
          type: "期刊",
          author: "杨浣菲  北京中医药大学中药学院;赵天成  北京师范大学",
          time: "2025-02-24 09:21",
          title:
            "中药闸柜是传统中药调剂的高级管理人员,在'前店后厂式'中药房发挥重要作用和关键职能。传承中药闸柜的宝贵学术经验与优秀文化对厘清中药学学科发展脉络、规范中药调剂技术操作、促进老药工技艺'活态传承'具有重要科学价值和现实意义。面向新时代、开启新思维,本文对老字号中药铺的兴起和中药闸柜进行考证,分析中药闸柜的岗位责任、传承路径及未来发展,提出高素质中药闸柜人才培养策略,旨在培养符合当代社会需求的中药行业复合型创新人才。中药闸柜是传统中药调剂的高级管理人员,在'前店后厂式'中药房发挥重要作用和关键职能。传承中药闸柜的宝贵学术经验与优秀文化对厘清中药学学科发展脉络、规范中药调剂技术操作、促进老药工技艺'活态传承'具有重要科学价值和现实意义。面向新时代、开启新思维,本文对老字号中药铺的兴起和中药闸柜进行考证,分析中药闸柜的岗位责任、传承路径及未来发展,提出高素质中药闸柜人才培养策略,旨在培养符合当代社会需求的中药行业复合型创新人才。",
          keyword: [
            {
              name: "中药闸柜",
            },
            {
              name: "中药闸柜",
            },
            {
              name: "中药闸柜",
            },
            {
              name: "中药闸柜",
            },
          ],
        },
        {
          name: "中药闸柜的历史传承与新时代发展思考",
          sources: "北京中医药大学学报",
          type: "期刊",
          author: "杨浣菲  北京中医药大学中药学院;赵天成  北京师范大学",
          time: "2025-02-24 09:21",
          title:
            "中药闸柜是传统中药调剂的高级管理人员,在'前店后厂式'中药房发挥重要作用和关键职能。传承中药闸柜的宝贵学术经验与优秀文化对厘清中药学学科发展脉络、规范中药调剂技术操作、促进老药工技艺'活态传承'具有重要科学价值和现实意义。面向新时代、开启新思维,本文对老字号中药铺的兴起和中药闸柜进行考证,分析中药闸柜的岗位责任、传承路径及未来发展,提出高素质中药闸柜人才培养策略,旨在培养符合当代社会需求的中药行业复合型创新人才。中药闸柜是传统中药调剂的高级管理人员,在'前店后厂式'中药房发挥重要作用和关键职能。传承中药闸柜的宝贵学术经验与优秀文化对厘清中药学学科发展脉络、规范中药调剂技术操作、促进老药工技艺'活态传承'具有重要科学价值和现实意义。面向新时代、开启新思维,本文对老字号中药铺的兴起和中药闸柜进行考证,分析中药闸柜的岗位责任、传承路径及未来发展,提出高素质中药闸柜人才培养策略,旨在培养符合当代社会需求的中药行业复合型创新人才。",
          keyword: [
            {
              name: "中药闸柜",
            },
            {
              name: "中药闸柜",
            },
            {
              name: "中药闸柜",
            },
            {
              name: "中药闸柜",
            },
          ],
        },
        {
          name: "中药闸柜的历史传承与新时代发展思考",
          sources: "北京中医药大学学报",
          type: "期刊",
          author: "杨浣菲  北京中医药大学中药学院;赵天成  北京师范大学",
          time: "2025-02-24 09:21",
          title:
            "中药闸柜是传统中药调剂的高级管理人员,在'前店后厂式'中药房发挥重要作用和关键职能。传承中药闸柜的宝贵学术经验与优秀文化对厘清中药学学科发展脉络、规范中药调剂技术操作、促进老药工技艺'活态传承'具有重要科学价值和现实意义。面向新时代、开启新思维,本文对老字号中药铺的兴起和中药闸柜进行考证,分析中药闸柜的岗位责任、传承路径及未来发展,提出高素质中药闸柜人才培养策略,旨在培养符合当代社会需求的中药行业复合型创新人才。中药闸柜是传统中药调剂的高级管理人员,在'前店后厂式'中药房发挥重要作用和关键职能。传承中药闸柜的宝贵学术经验与优秀文化对厘清中药学学科发展脉络、规范中药调剂技术操作、促进老药工技艺'活态传承'具有重要科学价值和现实意义。面向新时代、开启新思维,本文对老字号中药铺的兴起和中药闸柜进行考证,分析中药闸柜的岗位责任、传承路径及未来发展,提出高素质中药闸柜人才培养策略,旨在培养符合当代社会需求的中药行业复合型创新人才。",
          keyword: [
            {
              name: "中药闸柜",
            },
            {
              name: "中药闸柜",
            },
            {
              name: "中药闸柜",
            },
            {
              name: "中药闸柜",
            },
          ],
        },
        {
          name: "中药闸柜的历史传承与新时代发展思考",
          sources: "北京中医药大学学报",
          type: "期刊",
          author: "杨浣菲  北京中医药大学中药学院;赵天成  北京师范大学",
          time: "2025-02-24 09:21",
          title:
            "中药闸柜是传统中药调剂的高级管理人员,在'前店后厂式'中药房发挥重要作用和关键职能。传承中药闸柜的宝贵学术经验与优秀文化对厘清中药学学科发展脉络、规范中药调剂技术操作、促进老药工技艺'活态传承'具有重要科学价值和现实意义。面向新时代、开启新思维,本文对老字号中药铺的兴起和中药闸柜进行考证,分析中药闸柜的岗位责任、传承路径及未来发展,提出高素质中药闸柜人才培养策略,旨在培养符合当代社会需求的中药行业复合型创新人才。中药闸柜是传统中药调剂的高级管理人员,在'前店后厂式'中药房发挥重要作用和关键职能。传承中药闸柜的宝贵学术经验与优秀文化对厘清中药学学科发展脉络、规范中药调剂技术操作、促进老药工技艺'活态传承'具有重要科学价值和现实意义。面向新时代、开启新思维,本文对老字号中药铺的兴起和中药闸柜进行考证,分析中药闸柜的岗位责任、传承路径及未来发展,提出高素质中药闸柜人才培养策略,旨在培养符合当代社会需求的中药行业复合型创新人才。",
          keyword: [
            {
              name: "中药闸柜",
            },
            {
              name: "中药闸柜",
            },
            {
              name: "中药闸柜",
            },
            {
              name: "中药闸柜",
            },
          ],
        },
      observer: null,
      pdfName: "",
      dialogVisible: false,
      pdfList: [],
      relatedList: [],
      // 输入框的内容
      inputValue: "",
      // 选择的类型
      inputType: "",
      //类型选择
      inputOptions: [
        { value: "all", label: "全部" },
        { value: "Name", label: "标题" },
        { value: "author", label: "作者" },
        { value: "keyWords", label: "关键词" },
        { value: "abstract", label: "摘要" },
        { value: "source", label: "来源" },
      ],
      isDisplay: false,
      details: {},
      // 类型
      category: {
        title: "类型",
        isDisplay: true,
        id: "",
        index: "",
        list: [
          {
            name: "期刊",
            num: 190,
            check: false,
          },
          {
            name: "图书",
            num: 190,
            check: false,
          },
          {
            name: "视频",
            num: 190,
            check: false,
          },
          {
            name: "音频",
            num: 190,
            check: false,
          },
        ],
      },
      resourceTypeRefCode: "resourceType",
      resourceTypeValueList: [],
      // 查询结果
      resultList: [],
      loading: false,
    };
  },
  mounted() {
    console.log(this.$route.params.key, "key001");
    this.details = this.$route.params.key;
  async mounted() {
    await this.getContent(this.$route.query.id);
    await this.getSelectData();
    console.log(this.details, "请求出来的数据");
    // 查找关键词相匹配的文章
    if (this.details.keyWords && this.details.keyWords.length) {
      for (let i = 0; i < this.details.keyWords.length; i++) {
        const item = this.details.keyWords[i];
        this.inputValue = item
        this.inputType = "keyWords"
        await this.getItemListOne()
      }
      console.log(this.resultList, "处理好的");
    } else {
      this.getItemList()
    }
    if (this.resultList.length == 0) {
      this.getItemList()
    }
    //处理文件
    if (this.details.cmsItemType == "video" || this.details.cmsItemType == "audio") {
      if (this.details.file != "") {
        this.details.src = await this.getResourcePath(this.details.file)
      }
    }
    this.observer = new IntersectionObserver(this.pageChangeCallback, {
      root: null, // 指定根元素,这里设为 null,表示选取整个视窗作为根元素。
      rootMargin: '0px', // 指定根元素的边界,这里设为 "0px",表示根元素的边界和视窗的边界重合
      threshold: 0.1 // 指定交叉比例,这里设为 0.5,表示当目标元素一半或更多显示在视窗中时触发回调函数。
    })
  },
  methods: {
    goPage(key) { },
    // 根据id请求该页面数据
    async getContent(id) {
      const res = await MG.resource
        .getItem({
          path: "*",
          queryType: "*",
          fields: {
            cmsType: ["cmsItem"],
            "Id=": [id + ""],
            source: [],
            year: [],
            abstract: [],
            keyWords: [],
            author: [],
            DOI: [],
            AIReading: [],
            file: [],
            IssueNumber: [],
          },
        })
      res.datas.forEach((item) => {
        item.year = moment(item.year).format("YYYY-MM-DD")
        if (typeof item.keyWords === 'string') {
          item.keyWords = item.keyWords.split(";;");
        } else {
          // 设置一个默认值或者进行其他错误处理
          item.keyWords = [];
        }
        if(item.author && item.author.length>0){
          item.author = item.author.split(";");
        }
        const foundItem = this.category.list.find((citem) => citem.value == item.cmsItemType);
        item.resourceTypeName = foundItem ? foundItem.name : '';
      })
      this.details = res.datas[0]
      this.loading = false;
    },
    // 在此点击详情
    async goPage(id) {
      await this.getContent(id);
      await this.getSelectData();
      this.resultList = [];
      // 查找关键词相匹配的文章
      if (this.details.keyWords && this.details.keyWords.length) {
        for (let i = 0; i < this.details.keyWords.length; i++) {
          const item = this.details.keyWords[i];
          this.inputValue = item
          this.inputType = "keyWords"
          this.getItemListOne()
        }
      } else {
        this.getItemList()
      }
      if (this.resultList.length == 0) {
        this.getItemList()
      }
      //处理文件
      if (this.details.cmsItemType == "video" || this.details.cmsItemType == "audio") {
        if (this.details.file != "") {
          this.details.src = await this.getResourcePath(this.details.file)
        }
      }
      // 滚动到页面顶部
      this.$nextTick(() => {
        const pageMain = document.querySelector('.page-main-father');
        if (pageMain) {
          pageMain.scrollTo({
            top: 0,
            behavior: 'smooth'
          });
        }
      });
    },
    goBack() {
      this.$router.go(-1);
    },
    // 获取阿里云加速地址 (视频,音频)
    async getResourcePath(md5) {
      try {
        // 调用 fileApi.getAliVod 方法获取资源路径
        const res = await fileApi.getAliVod({
          md5,
          appRefCode,
        });
        // 如果返回的数据不为空且定义明确,则直接返回 res.data
        if (res.data && res.data !== "") {
          return res.data;
        }
        // 如果返回的数据为空或未定义,则拼接默认下载路径
        return requestCtx + "/file/api/ApiDownload?md5=" + md5;
      } catch (error) {
        // 捕获异常并打印错误日志
        console.error("获取资源路径失败:", error);
        // 返回一个默认值或抛出错误(根据业务需求)
        return requestCtx + "/file/api/ApiDownload?md5=" + md5;
      }
    },
    // 获取相关资源
    async getPDFInfo(md5) {
      const res = await this.MG.file.getPdfInfo({
        md5
      })
      if (!res || !res.totalPages) return (this.pdfList = [])
      for (let index = 0; index < res.totalPages; index++) {
        const src =
          requestCtx + '/file/GetPdfPageImage?md5=' + md5 + '&index=' + (index + 1) + '&dpi=300' + '&width=800'
        this.pdfList.push({
          src,
          showSrc: ''
        })
      }
      // 启动页码观察
      setTimeout(() => {
        this.initObservation()
      }, 500)
    },
    initObservation() {
      const sections = document.querySelectorAll('.pdfItem')
      sections.forEach((section) => {
        // observer 观察每个元素,以便在它们进入或离开视窗时触发回调函数。
        const isObserver = section.getAttribute('observer')
        if (!isObserver) {
          this.observer.observe(section)
          section.setAttribute('observer', '1')
        }
      })
      // 预加载前几页资源
      const preloadPages = 3
      for (let i = 0; i < Math.min(preloadPages, sections.length); i++) {
        const section = sections[i]
        const page = section.getAttribute('page')
        if (this.pdfList[page - 1].showSrc == '') {
          this.pdfList[page - 1].showSrc = this.pdfList[page - 1].src
        }
      }
    },
    pageChangeCallback(entries, observer) {
      //entries:代表观察到的目标元素的集合。 observer:代表观察者对象。
      entries.forEach((entry) => {
        //entry.isIntersecting:检查当前目标元素是否与根元素相交。
        if (entry.isIntersecting) {
          const target = entry.target
          //entry.target:获取当前目标元素
          const page = target.getAttribute('page')
          if (this.pdfList[page - 1].showSrc == '') {
            this.pdfList[page - 1].showSrc = this.pdfList[page - 1].src
          }
        }
      })
    },
    //获取下拉选择框的内容
    async getSelectData() {
      this.loading = true;
      try {
        // 同时发起两个异步请求,并等待它们的结果
        const [resourceListResult] = await Promise.all([
          this.getSelectContent(this.resourceTypeRefCode),
        ]);
        this.category.list = resourceListResult.option;
        if (this.category.list && this.category.list.length) {
          this.category.list.forEach((item) => {
            this.resourceTypeValueList.push(item.value)
          });
        }
      } catch (error) {
        console.error("获取下拉框数据失败:", error);
      }
    },
    //获取选择内容
    getSelectContent(refCode) {
      let requestData = { refCodes: [refCode] };
      return MG.store
        .getProductTypeField(requestData)
        .then((res) => {
          const selestList = JSON.parse(res[0].config);
          return selestList;
        }).catch((error) => {
          console.error("获取选择内容失败:", error);
          return null;
        });
    },
    // 复制一份
    async getItemListOne() {
      let searchData = {}; // 初始化一个空对象来存储搜索数据
      if (this.inputValue) { // 如果输入值存在
        if (this.inputType != "all") { // 如果输入类型不是"all"
          // 将输入值与输入类型关联,并添加一个星号(*)作为后缀
          searchData[this.inputType + "*"] = this.inputValue;
        } else { // 如果输入类型是"all"
          // 遍历输入选项
          for (let index = 0; index < this.inputOptions.length; index++) {
            const item = this.inputOptions[index]; // 获取当前选项
            if (item.value !== "all") { // 如果当前选项的值不是"all"
              if (!Object.keys(searchData).length) { // 如果searchData是空的
                // 将第一个选项的值与输入值关联,并添加一个星号(*)作为后缀
                searchData[item.value + "*"] = this.inputValue;
              } else { // 如果searchData不是空的
                // 使用"||"作为前缀,将后续选项的值与输入值关联,并添加一个星号(*)作为后缀
                // 这通常用于构建一个逻辑或(OR)查询
                searchData["||" + item.value + "*"] = this.inputValue;
              }
            }
          }
        }
      }
      const res = await MG.resource
        .getItem({
          path: "*",
          queryType: "*",
          paging: {
            size: 99999
          },
          fields: {
            cmsType: ["cmsItem"],
            // 'id=':[this.$route.params.key],
            "resourceType*": this.resourceTypeValueList,
            source: [],
            year: [],
            abstract: [],
            keyWords: [],
            author: [],
            DOI: [],
            AIReading: [],
            file: [],
            IssueNumber: [],
            ...searchData,
          },
        })
      res.datas.forEach((item) => {
        item.year = moment(item.year).format("YYYY-MM-DD")
        if (typeof item.keyWords === 'string') {
          item.keyWords = item.keyWords.split(";;");
        } else {
          // 设置一个默认值或者进行其他错误处理
          item.keyWords = [];
        }
        const foundItem = this.category.list.find((citem) => citem.value == item.cmsItemType);
        item.resourceTypeName = foundItem ? foundItem.name : '';
        console.log(this.details.id, "");
        if (!this.resultList.find(citem => citem.id === item.id) && item.id != this.details.id && this.resultList.length < 11) {
          this.resultList.push(item);
        }
      });
      // 排除自身且去重
      // const relatedList = res.datas.filter((item) => {
      //   return item.id !== this.details.id;
      // });
      // this.resultList.push(...relatedList)
      // // 根据id去重
      // this.resultList = this.uniqueById(this.resultList);
      // //最多显示10条
      // if (this.resultList.length > 10) {
      //   this.resultList = this.resultList.slice(0, 10);
      // }
      this.loading = false;
    },
    async openPdf(name) {
      this.pdfList = []
      this.pdfName = name;
      this.dialogVisible = true;
      await this.getPDFInfo(this.details.file);
    },
    // 请求所有的数据
    getItemList() {
      MG.resource
        .getItem({
          path: "*",
          queryType: "*",
          paging: {
            size: 5
          },
          fields: {
            cmsType: ["cmsItem"],
            "resourceType*": this.resourceTypeValueList,
            source: [],
            year: [],
            abstract: [],
            keyWords: [],
            author: [],
            DOI: [],
            AIReading: [],
            file: [],
            IssueNumber: [],
          },
        })
        .then((res) => {
          res.datas.forEach((item) => {
            item.year = moment(item.year).format("YYYY-MM-DD")
            if (typeof item.keyWords === 'string') {
              item.keyWords = item.keyWords.split(";;");
            } else {
              // 设置一个默认值或者进行其他错误处理
              item.keyWords = [];
            }
            const foundItem = this.category.list.find((citem) => citem.value == item.cmsItemType);
            item.resourceTypeName = foundItem ? foundItem.name : '';
          })
          this.resultList = res.datas
          this.loading = false;
        }).catch((err) => {
          console.log("替换数据请求失败");
        });
    },
    //去重
    uniqueById(array) {
      const uniqueItems = new Map();
      array.forEach(item => {
        if (!uniqueItems.has(item.id)) {
          uniqueItems.set(item.id, item);
        }
      });
      return Array.from(uniqueItems.values());
    }
  },
};
</script>
@@ -292,6 +566,7 @@
  flex: 1;
  width: 100%;
  height: 100%;
  min-width: 1200px;
  overflow: auto;
  padding-top: 2%;
  padding-bottom: 2%;
@@ -428,7 +703,6 @@
      }
      .page-main-keyword {
        cursor: pointer;
        padding: 5px 10px;
        color: #937950;
        border: 1px solid #937950;
@@ -474,6 +748,7 @@
    }
    .content-right {
      min-height: 600px;
      padding: 14px 20px 20px 14px;
      .right-header {
@@ -534,6 +809,7 @@
        }
      }
      .right-main {
        margin-bottom: 20px;
        padding: 19px 30px 15px 30px;
@@ -568,6 +844,7 @@
            background-color: #87a8b9;
            color: #fff;
            margin-right: 10px;
          }
          span:nth-child(2) {
@@ -575,8 +852,8 @@
            font-size: 12px;
            font-weight: 350;
            padding-right: 10px;
            border-right: 1px solid #2c2c2c;
            color: #333;
          }
          span:nth-child(3) {
@@ -584,8 +861,21 @@
            font-size: 12px;
            font-weight: 350;
            padding-left: 10px;
            padding-right: 10px;
            color: #333;
            border-left: 1px solid #2c2c2c;
          }
          span:nth-child(4) {
            font-family: Source Han Sans;
            font-size: 12px;
            font-weight: 350;
            padding-left: 10px;
            color: #333;
            border-left: 1px solid #2c2c2c;
          }
          margin-bottom: 10px;
        }
@@ -617,6 +907,14 @@
          }
        }
        .page-main-abstract {
          font-family: Source Han Sans !important;
          font-size: 14px !important;
          font-weight: 350 !important;
          line-height: 26px !important;
          color: #333333 !important;
        }
        .main-keyword {
          span:nth-child(1) {
            font-family: Source Han Sans;
@@ -640,4 +938,55 @@
    }
  }
}
.pdfInfoBox {
  height: 85vh;
  margin-top: 20px;
  overflow: auto;
  width: 100%;
  img {
    display: block;
    margin: 0 auto;
    width: 70%;
    box-shadow: 0px 0px 10px 1px rgba(0, 0, 0, 0.1);
    object-fit: contain;
  }
}
</style>
<style lang="less">
.custom-dialog {
  overflow: hidden !important;
  .el-dialog__body {
    padding: 0;
  }
  .el-dialog__header {
    background-color: #937950;
    .el-dialog__title {
      display: flex;
      justify-content: space-between;
      align-items: center;
      color: #fff;
      font-weight: 900;
      font-size: 16px;
      span:nth-child(2):hover {
        cursor: pointer;
      }
    }
    .el-dialog__title,
    .el-dialog__headerbtn .el-dialog__close {
      color: #fff;
      font-weight: 900;
      font-size: 16px;
    }
  }
}
</style>
src/views/achievements/index.vue
@@ -144,7 +144,7 @@
              <li class="main-name">
                <p>{{ item.name }}</p>
                <p>
                  <el-button @click="goPage(item)">详情</el-button>
                  <el-button @click="goPage(item.id)">详情</el-button>
                  <el-button>AI智能阅读</el-button>
                </p>
              </li>
@@ -157,11 +157,11 @@
              <li class="main-author">
                {{ item.author }}
              </li>
              <li class="main-title" :title="item.abstract">
              <li class="main-title" :title="item.cleanAbstract" v-if="item.abstract">
                <span>摘要: </span>
                <span class="page-main-abstract" v-html="item.abstract"></span>
              </li>
              <li class="main-keyword">
              <li class="main-keyword" v-if="item.keyWords && item.keyWords.length > 0">
                <span>关键词:</span>
                <span class="keyWord" v-for="(citem, cindex) in item.keyWords" :key="cindex">
                  {{ citem }}
@@ -175,6 +175,7 @@
              </el-pagination>
            </div>
          </div>
        </div>
      </div>
    </div>
@@ -195,6 +196,7 @@
  },
  data() {
    return {
      relatedList: [],
      // 输入框的内容
      inputValue: "",
      // 选择的类型
@@ -446,8 +448,6 @@
    };
  },
  mounted() {
    this.getSelectContent();
    this.getLeftCheckbox()
    this.getSelectData();
  },
@@ -458,9 +458,8 @@
      // this.onSearch("");
    },
    // 页面跳转
    goPage(key) {
      console.log(key, "key");
      this.$router.push({ name: "details", params: { key: key } });
    goPage(id) {
      this.$router.push({ name: "details", query: { id } });
    },
    // 收起和展示
    shrinkClick(key, name) {
@@ -479,11 +478,6 @@
        this.professionIndex = 4;
        this.activeBox = this.activeBox === "b" ? null : "b";
      }
    },
    // 获取左侧checkbox数据
    getLeftCheckbox() {
    },
    //获取下拉选择框的内容
@@ -515,7 +509,6 @@
        .getProductTypeField(requestData)
        .then((res) => {
          const selestList = JSON.parse(res[0].config);
          console.log(selestList, "下拉框数据");
          return selestList;
        })
        .catch((error) => {
@@ -530,13 +523,13 @@
        (item) => item.content !== value
      );
      this.inputValue = "";
      // 通知父组件数据已改变
      this.getItemList()
    },
    // 搜索
    handleSearch(isText) {
      console.log(1234);
      console.log(isText, "搜索123");
      this.associationList = []
      if (isText.text != "") {
        this.inputValue = isText.text
        this.inputType = isText.type
@@ -548,29 +541,30 @@
      }
    },
    // getTtem
    // 请求数据
    getItemList() {
      let searchData = {};
      if (this.inputValue) {
        if (this.inputType != "all") {
      let searchData = {}; // 初始化一个空对象来存储搜索数据
      if (this.inputValue) { // 如果输入值存在
        if (this.inputType != "all") { // 如果输入类型不是"all"
          // 将输入值与输入类型关联,并添加一个星号(*)作为后缀
          searchData[this.inputType + "*"] = this.inputValue;
        } else {
        } else { // 如果输入类型是"all"
          // 遍历输入选项
          for (let index = 0; index < this.inputOptions.length; index++) {
            const item = this.inputOptions[index];
            if (item.value !== "all" ) {
              console.log(item.value, "987");
              if (!Object.keys(searchData).length) {
                searchData[item.value + "*"] = this.inputValue
              } else {
                searchData["||" + item.value + "*"] = this.inputValue
            const item = this.inputOptions[index]; // 获取当前选项
            if (item.value !== "all") { // 如果当前选项的值不是"all"
              if (!Object.keys(searchData).length) { // 如果searchData是空的
                // 将第一个选项的值与输入值关联,并添加一个星号(*)作为后缀
                searchData[item.value + "*"] = this.inputValue;
              } else { // 如果searchData不是空的
                // 使用"||"作为前缀,将后续选项的值与输入值关联,并添加一个星号(*)作为后缀
                // 这通常用于构建一个逻辑或(OR)查询
                searchData["||" + item.value + "*"] = this.inputValue;
              }
            }
          }
        }
        console.log(searchData, "搜索数据123");
      }
      debugger
      MG.resource
        .getItem({
          path: "*",
@@ -595,7 +589,8 @@
          },
        })
        .then((res) => {
          console.log(res, "全部数据");
          console.log(res, "全部内容");
          res.datas.forEach((item) => {
            item.year = moment(item.year).format("YYYY-MM-DD")
            if (typeof item.keyWords === 'string') {
@@ -604,18 +599,29 @@
              // 设置一个默认值或者进行其他错误处理
              item.keyWords = [];
            }
            item.resourceTypeName = this.category.list.find((citem) => citem.value == item.cmsItemType).name
            // item.cleanAbstract = item.abstract.replace(/<[^>]+>/g, "");
            const foundItem = this.category.list.find((citem) => citem.value == item.cmsItemType);
            item.resourceTypeName = foundItem ? foundItem.name : '';
          })
          this.resultList = res.datas
          this.total = res.total;
          this.loading = false;
        })
    },
    // 处理页码变化
    handleCurrentChange(newPage) {
      this.paginationPage = newPage;
      this.getItemList(); // 重新获取数据
      // 滚动到页面顶部
      this.$nextTick(() => {
        const pageMain = document.querySelector('.page-main-father');
        if (pageMain) {
          pageMain.scrollTo({
            top: 0,
            behavior: 'smooth'
          });
        }
      });
    },
  },
@@ -660,7 +666,7 @@
  flex: 1;
  width: 100%;
  height: 100%;
  min-width: 1292px;
  min-width: 1250px;
  overflow: auto;
  padding-top: 1%;
  padding-bottom: 2%;
@@ -741,6 +747,7 @@
        background-color: transparent;
        color: #937950;
        border: 1px solid #6f5a3a;
        cursor: pointer;
        &:hover {
          background-color: #6f5a3a;
@@ -1132,4 +1139,4 @@
  border-radius: 5px;
  border: 1px solid #cccccc;
}
</style>
</style>
yarn.lock
Diff too large