From ff2d01588d4e69d3bf1ad856e8e225b7f6a3c0f2 Mon Sep 17 00:00:00 2001
From: zhaowei <zhaowei>
Date: 星期一, 26 八月 2024 11:01:48 +0800
Subject: [PATCH] 1、基本实现电子说明书页面布局及功能 2、基本实现语言大模型页面与后端数据联动

---
 src/views/ai/ElectronicManual.vue |  826 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 805 insertions(+), 21 deletions(-)

diff --git a/src/views/ai/ElectronicManual.vue b/src/views/ai/ElectronicManual.vue
index 86e9525..8fff29b 100644
--- a/src/views/ai/ElectronicManual.vue
+++ b/src/views/ai/ElectronicManual.vue
@@ -1,48 +1,832 @@
 <template>
-  <div>
-    鐢靛瓙璇存槑涔�
-    <a-card>
-      {{answer}}
-    </a-card>
-    <a-input-search placeholder="input search text" enter-button @search="onSearch"/>
+  <div class="page-container">
+    <!--鐢靛瓙璇存槑涔�-->
+    <div class="outer-container">
+      <!--宸︿晶闃呰妯″紡缂╃暐鍥惧尯鍩�-->
+      <div class="left-spin-container">
+        <a-spin :spinning="thumbnailSpinning" :delay="spinningDelayTime">
+          <a-icon slot="indicator" type="loading" spin/>
+        </a-spin>
+
+        <div class="left-container">
+          <div v-for="item in imgListConfig.records" :key="item.id" class="single-thumbnail-container"
+               :class="[item.id===activeImageId?'single-thumbnail-active':'']" :id="'thumbnail-container-'+item.id"
+               @click="activeCurrentThumbnail(item.id)">
+            <!--<img src="@/assets/page/electronicManual/document.png">-->
+            <div class="thumbnail-image-container">
+              <a-skeleton :loading="item.loading" :avatar="{shape:'square'}" :title="false" :paragraph="false" active/>
+              <img :id="'thumbnail-image-'+item.id" :data-src="getImgView(item.imgPath+item.imgEncodeName)"
+                   @load="imageLoadDone(item)" :style="{opacity:item.loading?0:1}">
+            </div>
+            <div>-{{item.pageNumber}}-</div>
+          </div>
+        </div>
+      </div>
+
+      <!--鍙充晶鍖哄煙-->
+      <div class="right-container">
+        <div class="right-top-container">
+          <div class="document-spin-container">
+            <a-spin :spinning="documentSpinning" :delay="spinningDelayTime">
+              <a-icon slot="indicator" type="loading" spin/>
+            </a-spin>
+
+            <!--鍙充笂鏂囨。鍖哄煙-->
+            <div class="document-container" @wheel="horizontalScroll">
+              <div v-for="item in documentList" :key="item.id" class="single-document-container"
+                   @click="activeCurrentDocument(item.id)"
+                   :class="[item.id===activeDocumentId?'single-document-active':'']">
+                <div><img src="@/assets/page/electronicManual/document.png"></div>
+                <div class="single-document-name">
+                  {{item.fileName?item.fileName.length>20?item.fileName.slice(0,20)+'..':item.fileName:'鏈懡鍚嶈鏄庝功'}}
+                </div>
+              </div>
+            </div>
+          </div>
+
+          <!--鍙充笂杈撳叆鏌ヨ鍖哄煙-->
+          <div class="search-container">
+            <div>鎮ㄥ綋鍓嶉�夋嫨鐨勭數鎺х郴缁熶负锛歺xx-xxxx-xxxxx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;鏈哄簥鍨嬪彿涓�:xxx-xx</div>
+            <div class="input-container">
+              <input @keydown.enter="furtherFilter" placeholder="璇风敤涓�鍙ヨ瘽鎻忚堪鎮ㄥ綋鍓嶉亣鍒扮殑闂" v-model="inputQuestion"/>
+              <img src="@/assets/page/electronicManual/search.png" @click="furtherFilter"
+                   :style="{cursor:!thumbnailSpinning?'pointer':'not-allowed'}">
+            </div>
+          </div>
+        </div>
+
+        <!--鍙充笅鍖哄煙-->
+        <div class="right-bottom-spin-container">
+          <a-spin :spinning="largeImageSpinning" :delay="spinningDelayTime">
+            <a-icon slot="indicator" type="loading" spin/>
+          </a-spin>
+
+          <!--鍙充笅闃呰妯″紡鍖哄煙-->
+          <div class="right-bottom-container" :class="[isFurtherFilter?'further-filter-container':'']">
+            <template v-if="!isFurtherFilter">
+              <div v-for="item in imgListConfig.records" :key="item.id" class="single-largeImg-container"
+                   :id="'large-image-container-'+item.id">
+                <a-skeleton :loading="item.loading" :avatar="{shape:'square'}" :title="false"
+                            :paragraph="false" active/>
+                <img :id="'large-image-'+item.id" :data-src="getImgView(item.imgPath+item.imgEncodeName)"
+                     @load="imageLoadDone(item)" :style="{opacity:item.loading?0:1}">
+                <!--<img src="@/assets/page/electronicManual/document.png">-->
+              </div>
+            </template>
+
+            <!--鍙充笅娣卞眰杩囨护鍖哄煙-->
+            <template v-else>
+              <div v-for="item in furtherFilterImgList" :key="item.id" class="single-filterImg-container"
+                   @click="locateToDocument(item)">
+                <!--<img src="@/assets/page/electronicManual/document.png">-->
+                <a-skeleton :loading="item.loading" :avatar="{shape:'square'}" :title="false"
+                            :paragraph="false" active/>
+                <img :id="'filter-image-'+item.id" :data-src="getImgView(item.imgPath+item.imgEncodeName)"
+                     @load="imageLoadDone(item)" :style="{opacity:item.loading?0:1}"
+                >
+              </div>
+              <img src="@/assets/page/electronicManual/back.png" id="back-to-largeImg" @click="cancelFurtherFilter"
+                   v-if="!largeImageSpinning">
+            </template>
+          </div>
+        </div>
+
+      </div>
+    </div>
   </div>
 </template>
 
 <script>
-  import { getDataAfterSearchByApi } from '@/api/AI'
+  import { getPdfImgApi, getPdfDocumentApi, getFurtherFilterImgApi } from '@/api/ai'
+  import { getFileAccessHttpUrl } from '@/api/manage'
+  import { message } from 'ant-design-vue'
+
+  message.config({
+    maxCount: 1,
+    duration: 2
+  })
 
   export default {
     name: 'ElectronicManual',
     components: {},
     data() {
       return {
-        answer:''
+        rightBottomContainer: null,
+        activeDocumentId: null,
+        activeImageId: null,
+        inputQuestion: '',
+        isFurtherFilter: false,
+        beforeFilterActiveDocumentId: null,
+        beforeFilterActiveImageId: null,
+        documentList: [],
+        // documentList: [
+        //   {
+        //     id: 1,
+        //     fileName: '鏈哄簥鎵嬪唽1'
+        //   },
+        //   {
+        //     id: 2,
+        //     fileName: '鏈哄簥鎵嬪唽2'
+        //   },
+        //   {
+        //     id: 3,
+        //     fileName: '鏈哄簥鎵嬪唽3'
+        //   },
+        //   {
+        //     id: 4,
+        //     fileName: '鏈哄簥鎵嬪唽4'
+        //   },
+        //   {
+        //     id: 5,
+        //     fileName: '鏈哄簥鎵嬪唽5'
+        //   },
+        //   {
+        //     id: 6,
+        //     fileName: '鏈哄簥鎵嬪唽6'
+        //   },
+        //   {
+        //     id: 7,
+        //     fileName: '鏈哄簥鎵嬪唽7'
+        //   },
+        //   {
+        //     id: 8,
+        //     fileName: '鏈哄簥鎵嬪唽8'
+        //   },
+        //   {
+        //     id: 9,
+        //     fileName: '鏈哄簥鎵嬪唽9'
+        //   },
+        //   {
+        //     id: 10,
+        //     fileName: '鏈哄簥鎵嬪唽10'
+        //   }
+        // ],
+        imgListParams: {
+          pageNo: 1,
+          pageSize: 20
+        },
+        imgListConfig: {
+          records: []
+        },
+        scrollToMarginConfig: {
+          hasScrollToTopCount: 0,
+          hasScrollToBottomCount: 0
+        },
+        thumbnailSpinning: false,
+        documentSpinning: false,
+        largeImageSpinning: false,
+        spinningDelayTime: 500,
+        furtherFilterImgListParams: {},
+        furtherFilterImgList: []
       }
     },
+    created() {
+      this.getPdfDocumentByApi()
+    },
+    mounted() {
+      this.leftContainer = document.querySelector('.left-container')
+      this.rightBottomContainer = document.querySelector('.right-bottom-container')
+      this.handleScrollEventSwitch(true)
+    },
     methods: {
-      onSearch() {
-        const param = {
-          'id': '683a65fd-8feb-4446-ad32-714c4785f667',
-          'messages': [
-            {
-              'role': 'user',
-              'content': '缁欐垜璁蹭釜鏁呬簨锛�'
+      /* 璋冪敤鎺ュ彛鑾峰彇pdf鏂囨。 */
+      getPdfDocumentByApi() {
+        this.documentSpinning = true
+        getPdfDocumentApi()
+          .then(res => {
+            if (res.success) {
+              this.documentList = res.result
+              this.documentSpinning = false
+              this.activeCurrentDocument(res.result[0].id)
             }
-          ],
-          'stream': false,
-          'max_tokens': 500
+          })
+      },
+
+      /**
+       * 鐐瑰嚮鏂囨。鍚庤Е鍙�
+       * @param pdfFileId 鏂囨。Id
+       * @param furtherFilterImageId 娣卞眰杩囨护妯″紡涓偣鍑荤殑鍥剧墖Id
+       */
+      activeCurrentDocument(pdfFileId, furtherFilterImageId = null, furtherFilterImagePageNumber = null) {
+        if (pdfFileId === this.activeDocumentId && !furtherFilterImageId) return
+        if (this.isFurtherFilter) {
+          this.isFurtherFilter = false
+          this.handleScrollEventSwitch(true)
         }
-        getDataAfterSearchByApi()
+        if (!furtherFilterImageId) this.scrollToTop()
+        this.imgListConfig = {}
+        this.activeDocumentId = pdfFileId
+
+        this.imgListParams.pageNo = 1
+        this.resetImgListScrollConfig()
+        if (furtherFilterImagePageNumber && furtherFilterImagePageNumber > this.imgListParams.pageSize) this.computeImgListPageNo(furtherFilterImagePageNumber)
+
+        const params = Object.assign({ pdfFileId }, this.imgListParams)
+        this.thumbnailSpinning = true
+        this.largeImageSpinning = true
+
+        getPdfImgApi(params)
+          .then(res => {
+            if (res.success) {
+              this.imgListConfig = res.result
+              this.imgListConfig.records = this.imgListConfig.records.map(item => {
+                return {
+                  ...item,
+                  loading: true
+                }
+              })
+              this.activeImageId = res.result.records[0].id
+              this.$nextTick(() => {
+                this.lazyLoadImgByIntersectionObserver(res.result.records, 'thumbnail-image', 4, furtherFilterImageId)
+                this.lazyLoadImgByIntersectionObserver(res.result.records, 'large-image', 1, furtherFilterImageId)
+              })
+              this.thumbnailSpinning = false
+              this.largeImageSpinning = false
+              // 濡傛灉鐐瑰嚮鐨勬槸娣卞眰杩囨护鐨勫浘鐗囧垯杩斿洖闃呰妯″紡骞舵斁澶ч�変腑鐨勫浘鐗�
+              if (furtherFilterImageId) this.$nextTick(() => this.activeCurrentThumbnail(furtherFilterImageId, true))
+            }
+          })
+      },
+
+      /**
+       * 鐐瑰嚮缂╃暐鍥惧悗瑙﹀彂鍦ㄥ彸渚ф斁澶х缉鐣ュ浘
+       * @param id 缂╃暐鍥綢d
+       * @param isFromFurtherFilter 鏄惁閫氳繃娣卞眰杩囨护妯″紡瑙﹀彂
+       */
+      activeCurrentThumbnail(id, isFromFurtherFilter = false) {
+        if (id === this.activeImageId && !isFromFurtherFilter) return
+        this.activeImageId = id
+        if (isFromFurtherFilter) this.scrollToImagePosition('thumbnail-container', true, 'left', 0)
+        this.scrollToImagePosition()
+      },
+
+      computeImgListPageNo(furtherFilterImagePageNumber) {
+        const integer = Math.floor(furtherFilterImagePageNumber / this.imgListParams.pageSize)
+        const remainder = furtherFilterImagePageNumber % this.imgListParams.pageSize
+        if (remainder !== 0) {
+          // 涓嶄负鏁存暟
+          this.imgListParams.pageNo = integer + 1
+        } else {
+          // 涓烘暣鏁�
+          this.imgListParams.pageNo = integer
+        }
+      },
+
+      /* 闃呰妯″紡涓嬬殑婊氬姩瑙﹂《搴曞埛鏂� */
+      lazyLoadData(event) {
+        if (this.thumbnailSpinning && this.largeImageSpinning) return // 鍔犺浇涓椂鍙栨秷璋冪敤
+        const containerScrollTop = event.target.scrollTop
+        const containerClientHeight = event.target.clientHeight
+        const containerScrollHeight = event.target.scrollHeight
+
+        if (containerScrollTop + containerClientHeight >= containerScrollHeight) {
+          console.log('瑙﹀簳')
+          this.scrollToMarginConfig.hasScrollToBottomCount++
+          const params = Object.assign({ pdfFileId: this.activeDocumentId }, this.imgListParams)
+          params.pageNo = params.pageNo + this.scrollToMarginConfig.hasScrollToBottomCount
+          this.thumbnailSpinning = true
+          this.largeImageSpinning = true
+          getPdfImgApi(params)
+            .then(res => {
+              if (res.success) {
+                const newImgList = res.result.records.map(item => {
+                  return {
+                    ...item,
+                    loading: true
+                  }
+                })
+                this.imgListConfig.records.push(...newImgList)
+                this.$nextTick(() => {
+                  this.lazyLoadImgByIntersectionObserver(newImgList, 'thumbnail-image', 4)
+                  this.lazyLoadImgByIntersectionObserver(newImgList, 'large-image', 1)
+                })
+                this.thumbnailSpinning = false
+                this.largeImageSpinning = false
+              }
+            })
+        } else if (containerScrollTop <= 0 && this.imgListConfig.records[0].pageNumber !== 1) {
+          console.log('瑙﹂《')
+          this.scrollToMarginConfig.hasScrollToTopCount++
+          const params = Object.assign({ pdfFileId: this.activeDocumentId }, this.imgListParams)
+          params.pageNo = params.pageNo - this.scrollToMarginConfig.hasScrollToTopCount
+          this.thumbnailSpinning = true
+          this.largeImageSpinning = true
+          getPdfImgApi(params)
+            .then(res => {
+              if (res.success) {
+                const newImgList = res.result.records.map(item => {
+                  return {
+                    ...item,
+                    loading: true
+                  }
+                })
+                this.imgListConfig.records.unshift(...newImgList)
+                this.$nextTick(() => {
+                  this.lazyLoadImgByIntersectionObserver(newImgList, 'thumbnail-image', 4)
+                  this.lazyLoadImgByIntersectionObserver(newImgList, 'large-image', 1)
+                })
+                event.target.scrollTo({ top: 1 }) // 瑙e喅瑙﹂《鍒锋柊鏁版嵁鍚庢粴鍔ㄦ潯鑷虫渶椤堕儴闂锛屼絾涓嶇煡閬撲负浠�涔�
+                this.thumbnailSpinning = false
+                this.largeImageSpinning = false
+              }
+            })
+        }
+      },
+
+      /* 寮�鍚繁灞傝繃婊ゆā寮� */
+      furtherFilter() {
+        if (this.thumbnailSpinning) return
+        if (!this.inputQuestion) {
+          this.$message.error('浣犳病鏈夎緭鍏ュ唴瀹瑰摝')
+          return
+        }
+
+        this.furtherFilterImgList = []
+        this.isFurtherFilter = true
+
+        // 寮�鍚繁灞傝繃婊ゆ椂鍙栨秷鏂囦欢閫変腑骞剁Щ闄ゆ粴鍔ㄥ埛鏂颁簨浠�
+        this.beforeFilterActiveDocumentId = this.activeDocumentId
+        this.activeDocumentId = null
+        this.imgListConfig = {}
+        this.handleScrollEventSwitch(false)
+
+        const params = Object.assign({}, this.furtherFilterImgListParams)
+        params.pdfFileId = '1823231131943862273'
+        params.pdfContent = this.inputQuestion
+        this.largeImageSpinning = true
+
+        getFurtherFilterImgApi(params)
           .then(res => {
             console.log('res', res)
-            this.answer = res.result
+            if (res.success) {
+              this.furtherFilterImgList = res.result.map(item => {
+                return {
+                  ...item,
+                  loading: true
+                }
+              })
+              this.largeImageSpinning = false
+              this.$nextTick(() => this.lazyLoadImgByIntersectionObserver(res.result, 'filter-image', 2))
+            }
           })
+      },
 
+      /* 鐐瑰嚮娣卞眰杩囨护涓殑鍥剧墖鍚庡畾浣嶈嚦鏂囦欢 */
+      locateToDocument(record) {
+        this.isFurtherFilter = false
+        this.handleScrollEventSwitch(true)
+        this.$nextTick(() => this.activeCurrentDocument(record.fileId, record.id, record.pageNumber))
+      },
+
+      /* 鐐瑰嚮杩斿洖鎸夐挳閫�鍑烘繁灞傝繃婊ゆā寮� */
+      cancelFurtherFilter() {
+        const beforeFilterActiveRecord = { fileId: this.beforeFilterActiveDocumentId, id: this.activeImageId }
+        this.locateToDocument(beforeFilterActiveRecord)
+        this.inputQuestion = ''
+      },
+
+      /**
+       * 婊氬姩鑷冲浘鐗囩浉搴斾綅缃《閮�
+       * @param activePreId 婊氬姩鑷虫煇鍏冪礌鐨処d鍓嶇紑
+       * @param isParentNodeOpenPosition 鐖跺厓绱犳槸鍚﹀紑鍚畾浣�
+       * @param parentNodePreClass 鐖跺厓绱犵被鍚嶅墠缂�
+       * @param marginValue 杈硅窛鍊� 姝e�间负top锛岃礋鍊间负bottom
+       */
+      scrollToImagePosition(activePreId = 'large-image-container', isParentNodeOpenPosition = true, parentNodePreClass = 'rightBottom', marginValue = 25) {
+        console.log(activePreId + '-' + this.activeImageId)
+        const activeLargeImageContainer = document.getElementById(activePreId + '-' + this.activeImageId)
+        console.log('activeLargeImageContainer', activeLargeImageContainer)
+        let scrollTop
+        if (isParentNodeOpenPosition) {
+          console.log('鐖跺厓绱犲紑鍚畾浣�')
+          scrollTop = activeLargeImageContainer.offsetTop - marginValue
+        } else {
+          console.log('鐖跺厓绱犳湭寮�鍚畾浣�')
+          scrollTop = activeLargeImageContainer.offsetTop - this[parentNodePreClass + 'Container'].offsetTop - marginValue
+        }
+
+        this[parentNodePreClass + 'Container'].scrollTo({ top: scrollTop })
+      },
+
+      /**
+       * 閲囩敤娴忚鍣ㄧ洃娴嬭�匒PI瀹炵幇鍥剧墖鎳掑姞杞�
+       * @param dataList 鍏冪礌瀵瑰簲鏁版嵁闆嗗悎鐢ㄦ潵鏄犲皠瀵瑰簲鍏冪礌
+       * @param targetPreClass 鐩爣鍏冪礌绫诲悕鍓嶇紑
+       * @param loadCount 鍔犺浇鏁伴噺
+       * @param furtherFilterImageId 娣卞眰杩囨护妯″紡涓偣鍑荤殑鍥剧墖Id
+       */
+      lazyLoadImgByIntersectionObserver(dataList, targetPreClass, loadCount, furtherFilterImageId = null) {
+        let hasLoadImageCount = 0
+        let observer = new IntersectionObserver(entries => {
+          const furtherFilterImageIndex = entries.findIndex(item => item.target.id === targetPreClass + '-' + furtherFilterImageId)
+          // 娣卞眰杩囨护閫変腑鍥剧墖鍚庡噺灏戞暟缁勫惊鐜鏁帮紝浠呭姞杞藉寘鍚�変腑鍥剧墖鐨勫彲瑙嗗浘鐗囨暟閲�
+          if (furtherFilterImageIndex > 0) entries = entries.slice(furtherFilterImageIndex)
+          entries = entries.slice(0, loadCount)
+          entries.forEach(item => {
+            if (item.isIntersecting) {
+              item.target.src = item.target.dataset.src
+              hasLoadImageCount++
+              observer.unobserve(item.target)
+            }
+          })
+          if (hasLoadImageCount === dataList.length) {
+            observer.disconnect()
+            observer = null
+          }
+        })
+        dataList.forEach(item => observer.observe(document.getElementById(targetPreClass + '-' + item.id)))
+      },
+
+      horizontalScroll(event) {
+        event.preventDefault()
+        const documentContainer = document.querySelector('.document-container')
+        // deltaY灞炴�ф槸榧犳爣婊氬姩婊氳疆婊氬姩涓�涓嬶紝椤甸潰婊氬姩鐨勮窛绂�
+        // Y鏄瀭鐩存柟鍚�
+        // 榧犳爣婊氳疆鍚戝墠婊氬姩涓�杞紝deltaY=-100锛涘悜鍚庢粴鍔ㄤ竴杞紝deltaY=100;
+        // deltaY鐨勫唴閮ㄥ疄鐜拌偗瀹氭槸鐩戝惉榧犳爣婊氳疆鏄悜鍓嶆粴鍔ㄨ繕鏄悜鍚庢粴鍔ㄤ簨浠讹紝鐒跺悗鏇存敼deltaY鐨勫�间负姝f垨鑰呰礋銆�
+        // 姘村钩婊氬姩涔熼渶瑕佹湁绫讳技deltaY杩欐牱鐨勭姸鎬侊紝鎵�浠ョ洿鎺ヤ娇鐢╠eltaY灏卞彲浠ヤ簡锛岃櫧鐒禮琛ㄧず鐨勬槸鍨傜洿鏂瑰悜鐨勬粴鍔ㄣ��
+        const deltaY = event.deltaY
+        // scrollLeft灞炴�ф槸鍏冪礌宸︿晶鐨勬粴鍔ㄨ窛绂伙紝閫氳繃鏀瑰彉杩欎釜灞炴�х殑鍊硷紝瀹炵幇姘村钩婊氬姩鐨勬晥鏋溿��
+        documentContainer.scrollLeft += deltaY
+      },
+
+      imageLoadDone(record) {
+        console.log('鍥剧墖鍔犺浇瀹屾垚')
+        record.loading = false
+      },
+
+      scrollToTop() {
+        console.log('瑙﹀彂鍥炲埌椤堕儴')
+        this.leftContainer.scrollTo({ top: 0 })
+        this.rightBottomContainer.scrollTo({ top: 0 })
+      },
+
+      /**
+       * 鍥剧墖棰勮
+       * @param text 鍥剧墖鍦板潃
+       */
+      getImgView(text) {
+        if (text && text.indexOf(',') > 0) {
+          text = text.substring(0, text.indexOf(','))
+        }
+        return getFileAccessHttpUrl(text)
+      },
+
+      handleScrollEventSwitch(isAddEvent) {
+        if (isAddEvent) {
+          this.leftContainer.addEventListener('scroll', this.lazyLoadData)
+          this.rightBottomContainer.addEventListener('scroll', this.lazyLoadData)
+        } else {
+          this.leftContainer.removeEventListener('scroll', this.lazyLoadData)
+          this.rightBottomContainer.removeEventListener('scroll', this.lazyLoadData)
+        }
+      },
+
+      resetImgListScrollConfig() {
+        this.scrollToMarginConfig.hasScrollToTopCount = 0
+        this.scrollToMarginConfig.hasScrollToBottomCount = 0
       }
+    },
+    beforeDestroy() {
+      this.handleScrollEventSwitch(false)
     }
   }
 </script>
 
-<style scoped>
+<style scoped lang="less">
+  @main-container-background: rgba(255, 255, 255, .7);
+  @container-border-radius: 12px;
+  @container-padding: 10px;
+  @single-history-edit-border: 3px solid #ABC0CC;
+  @single-history-hover-background: #f1f1f1;
+  @single-history-active-background: #e5ebed;
+  @input-container-border: 3px solid #B8CAD5;
+  @user-question-background: #e5ebed;
+  @assistant-answer-background: #F0F5F5;
+  @conversation-content-container-box-shadow: 2px 2px 10px 0px #ddd;
+  @input-container-box-shadow: 2px 2px 10px 0px #ABC0CC;
+  @largeImg-container-box-shadow: 0 -3px 10px 0px #ddd;
+  @scrollbar-track-background: #f6f6f6;
+  @scrollbar-thumb-background: #e9e9e9;
+  @scrollbar-thumb-hover-background: #cfcfcf;
+  @scrollbar-corner-background: #f6f6f6;
 
+  .page-container {
+    display: flex;
+    justify-content: flex-end;
+    -webkit-justify-content: flex-end;
+    flex-direction: column;
+    align-items: center;
+    font-size: 18px;
+    height: 100%;
+    font-family: ali_r_main;
+
+    .outer-container {
+      width: 100%;
+      height: 850px;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+
+      .left-spin-container {
+        width: 10%;
+        height: 100%;
+        background-color: @main-container-background;
+        border-radius: @container-border-radius;
+        margin-right: 25px;
+        font-size: 16px;
+        position: relative;
+
+        .left-container {
+          width: 100%;
+          height: 100%;
+          padding: @container-padding;
+          display: flex;
+          flex-direction: column;
+          justify-content: space-between;
+          overflow: auto;
+
+          &::-webkit-scrollbar {
+            width: 8px;
+            height: 0;
+          }
+
+          .single-thumbnail-container {
+            padding: @container-padding;
+            cursor: pointer;
+            border-radius: @container-border-radius;
+
+            &:not(:last-child) {
+              margin-bottom: 20px;
+            }
+
+            img {
+              width: 100%;
+              height: 189px;
+            }
+
+            & > div:last-child {
+              margin-top: 10px;
+              text-align: center;
+            }
+
+            .thumbnail-image-container {
+              position: relative;
+            }
+
+            &:hover {
+              background-color: @single-history-hover-background;
+            }
+
+            &.single-thumbnail-active {
+              background-color: @single-history-active-background;
+            }
+
+            /deep/ .ant-skeleton {
+              margin: 0;
+              position: absolute;
+              width: 100%;
+              height: 189px;
+              .ant-skeleton-header {
+                padding: 0;
+                .ant-skeleton-avatar-lg {
+                  width: 100%;
+                  height: 189px;
+                  border-radius: @container-border-radius;
+                }
+              }
+            }
+          }
+
+        }
+      }
+
+      .right-container {
+        width: 80%;
+        height: 100%;
+        border-radius: @container-border-radius;
+        display: flex;
+        flex-direction: column;
+        justify-content: space-between;
+
+        .right-top-container {
+          height: 120px;
+          margin-bottom: 25px;
+          display: flex;
+          justify-content: center;
+
+          .document-spin-container {
+            width: 50%;
+            height: 100%;
+            font-size: 14px;
+            background-color: @main-container-background;
+            border-radius: @container-border-radius;
+            margin-right: 25px;
+            position: relative;
+
+            .document-container {
+              overflow-y: hidden;
+              overflow-x: auto;
+              display: flex;
+              align-items: center;
+              padding: @container-padding;
+
+              &::-webkit-scrollbar {
+                width: 0;
+                height: 8px;
+              }
+
+              .single-document-container {
+                width: 22%;
+                height: 100%;
+                cursor: pointer;
+                display: flex;
+                flex-direction: column;
+                justify-content: space-evenly;
+                align-items: center;
+                flex-shrink: 0;
+                border-radius: @container-border-radius;
+                padding: @container-padding;
+
+                img {
+                  width: 40px;
+                }
+
+                .single-document-name {
+                  width: 100%;
+                  text-align: center;
+                  /*overflow: hidden;*/
+                  /*white-space: nowrap;*/
+                  /*text-overflow: ellipsis;*/
+                }
+
+                &:not(:last-child) {
+                  margin-right: 4%;
+                }
+
+                &:hover {
+                  background-color: @single-history-hover-background;
+                }
+
+                &.single-document-active {
+                  background-color: @single-history-active-background;
+                }
+              }
+            }
+          }
+
+          .search-container {
+            flex: 1;
+            display: flex;
+            flex-direction: column;
+            justify-content: space-evenly;
+            align-items: center;
+
+            .input-container {
+              width: 100%;
+              display: flex;
+              background-color: transparent;
+              border: @single-history-edit-border;
+              border-radius: @container-border-radius;
+              padding: @container-padding;
+
+              input {
+                flex: 1;
+                outline: none;
+                background-color: transparent;
+                letter-spacing: 1px;
+                border: none;
+
+                &::placeholder {
+                  color: #9A9C9C;
+                }
+              }
+
+              img {
+                width: 32px;
+                cursor: pointer;
+              }
+            }
+          }
+        }
+
+        .right-bottom-spin-container {
+          width: 100%;
+          flex: 1;
+          background-color: @main-container-background;
+          border-radius: @container-border-radius;
+          position: relative;
+          overflow: hidden;
+
+          .right-bottom-container {
+            height: 100%;
+            background-color: @main-container-background;
+            border-radius: @container-border-radius;
+            overflow: auto;
+            text-align: center;
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+
+            .single-largeImg-container {
+              box-shadow: @largeImg-container-box-shadow;
+              width: 70%;
+              margin-top: 25px;
+              position: relative;
+            }
+
+            &.further-filter-container {
+              flex-direction: row;
+              justify-content: left;
+              flex-wrap: wrap;
+              padding: 12px 0;
+
+              .single-filterImg-container {
+                box-shadow: @largeImg-container-box-shadow;
+                width: 45%;
+                margin-top: 12px;
+                margin-bottom: 12px;
+                cursor: pointer;
+                position: relative;
+
+                &:nth-child(odd) {
+                  margin-left: 2%;
+                  margin-right: 2%;
+                }
+              }
+            }
+
+            /deep/ .ant-skeleton {
+              position: absolute;
+              top: 0;
+              left: 0;
+              right: 0;
+              bottom: 0;
+              margin: 0;
+              .ant-skeleton-header {
+                padding: 0;
+                .ant-skeleton-avatar-lg {
+                  width: 100%;
+                  height: 1640px;
+                }
+              }
+            }
+
+            img {
+              width: 100%;
+              height: 1640px;
+            }
+
+            #back-to-largeImg {
+              width: 3%;
+              height: auto;
+              position: absolute;
+              right: 2%;
+              top: auto;
+              cursor: pointer;
+            }
+
+            &::-webkit-scrollbar {
+              width: 8px;
+              height: 0;
+            }
+          }
+        }
+      }
+
+      .left-container, .document-container, .right-bottom-container {
+        &:hover {
+          &::-webkit-scrollbar-track {
+            background: @scrollbar-track-background;
+          }
+          &::-webkit-scrollbar-thumb {
+            background: @scrollbar-thumb-background;
+          }
+          &::-webkit-scrollbar-thumb:hover {
+            background: @scrollbar-thumb-hover-background;
+          }
+          &::-webkit-scrollbar-corner {
+            background: @scrollbar-corner-background;
+          }
+        }
+      }
+
+      /deep/ .ant-spin {
+        position: absolute;
+        top: 0;
+        left: 0;
+        right: 0;
+        bottom: 0;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        pointer-events: none;
+        z-index: 999;
+
+        .anticon {
+          font-size: 24px;
+        }
+      }
+    }
+  }
 </style>
\ No newline at end of file

--
Gitblit v1.9.3