zhongshujie
4 天以前 90675cb210f5a2afc4766e6fd091776a14397d48
最新版
11个文件已修改
5个文件已添加
1 文件已重命名
3700 ■■■■ 已修改文件
dist.zip 补丁 | 查看 | 原始文档 | blame | 历史
index.html 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
package-lock.json 256 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/favicon.ico 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/images/book-mr.jpg 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/images/table-title-bj.jpg 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/images/userIcon.jpg 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/config.ts 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main.ts 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/plugin/axios/index.ts 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/types/start.d.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/HomeView.vue 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/Start.vue 1086 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
tsconfig.json 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
vite.config.ts 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yarn.lock 2181 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dist.zip
Binary files differ
index.html
@@ -4,7 +4,7 @@
    <meta charset="UTF-8" />
    <link rel="icon" href="/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Library</title>
    <title>AI智能图书检索助手</title>
  </head>
  <body>
    <div id="app"></div>
package-lock.json
@@ -8,6 +8,7 @@
      "name": "vue01",
      "version": "0.0.0",
      "dependencies": {
        "axios": "^1.8.4",
        "element-plus": "^2.9.7",
        "vue": "^3.5.13",
        "vue-router": "^4.5.0"
@@ -2302,6 +2303,21 @@
      "resolved": "https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz",
      "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg=="
    },
    "node_modules/asynckit": {
      "version": "0.4.0",
      "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
    },
    "node_modules/axios": {
      "version": "1.8.4",
      "resolved": "https://registry.npmmirror.com/axios/-/axios-1.8.4.tgz",
      "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==",
      "dependencies": {
        "follow-redirects": "^1.15.6",
        "form-data": "^4.0.0",
        "proxy-from-env": "^1.1.0"
      }
    },
    "node_modules/balanced-match": {
      "version": "1.0.2",
      "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -2391,6 +2407,18 @@
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/call-bind-apply-helpers": {
      "version": "1.0.2",
      "resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
      "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
      "dependencies": {
        "es-errors": "^1.3.0",
        "function-bind": "^1.1.2"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/callsites": {
      "version": "3.1.0",
      "resolved": "https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz",
@@ -2453,6 +2481,17 @@
      "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
      "dev": true
    },
    "node_modules/combined-stream": {
      "version": "1.0.8",
      "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
      "dependencies": {
        "delayed-stream": "~1.0.0"
      },
      "engines": {
        "node": ">= 0.8"
      }
    },
    "node_modules/concat-map": {
      "version": "0.0.1",
@@ -2586,6 +2625,27 @@
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/delayed-stream": {
      "version": "1.0.0",
      "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
      "engines": {
        "node": ">=0.4.0"
      }
    },
    "node_modules/dunder-proto": {
      "version": "1.0.1",
      "resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz",
      "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
      "dependencies": {
        "call-bind-apply-helpers": "^1.0.1",
        "es-errors": "^1.3.0",
        "gopd": "^1.2.0"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/electron-to-chromium": {
      "version": "1.5.126",
      "resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.126.tgz",
@@ -2648,6 +2708,47 @@
      "dev": true,
      "funding": {
        "url": "https://github.com/sponsors/antfu"
      }
    },
    "node_modules/es-define-property": {
      "version": "1.0.1",
      "resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz",
      "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/es-errors": {
      "version": "1.3.0",
      "resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz",
      "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/es-object-atoms": {
      "version": "1.1.1",
      "resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
      "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
      "dependencies": {
        "es-errors": "^1.3.0"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/es-set-tostringtag": {
      "version": "2.1.0",
      "resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
      "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
      "dependencies": {
        "es-errors": "^1.3.0",
        "get-intrinsic": "^1.2.6",
        "has-tostringtag": "^1.0.2",
        "hasown": "^2.0.2"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/esbuild": {
@@ -3138,6 +3239,39 @@
      "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
      "dev": true
    },
    "node_modules/follow-redirects": {
      "version": "1.15.9",
      "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.9.tgz",
      "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
      "funding": [
        {
          "type": "individual",
          "url": "https://github.com/sponsors/RubenVerborgh"
        }
      ],
      "engines": {
        "node": ">=4.0"
      },
      "peerDependenciesMeta": {
        "debug": {
          "optional": true
        }
      }
    },
    "node_modules/form-data": {
      "version": "4.0.2",
      "resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.2.tgz",
      "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==",
      "dependencies": {
        "asynckit": "^0.4.0",
        "combined-stream": "^1.0.8",
        "es-set-tostringtag": "^2.1.0",
        "mime-types": "^2.1.12"
      },
      "engines": {
        "node": ">= 6"
      }
    },
    "node_modules/fs-extra": {
      "version": "11.3.0",
      "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-11.3.0.tgz",
@@ -3166,6 +3300,14 @@
        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
      }
    },
    "node_modules/function-bind": {
      "version": "1.1.2",
      "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
      "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/gensync": {
      "version": "1.0.0-beta.2",
      "resolved": "https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -3173,6 +3315,41 @@
      "dev": true,
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/get-intrinsic": {
      "version": "1.3.0",
      "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
      "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
      "dependencies": {
        "call-bind-apply-helpers": "^1.0.2",
        "es-define-property": "^1.0.1",
        "es-errors": "^1.3.0",
        "es-object-atoms": "^1.1.1",
        "function-bind": "^1.1.2",
        "get-proto": "^1.0.1",
        "gopd": "^1.2.0",
        "has-symbols": "^1.1.0",
        "hasown": "^2.0.2",
        "math-intrinsics": "^1.1.0"
      },
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/get-proto": {
      "version": "1.0.1",
      "resolved": "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz",
      "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
      "dependencies": {
        "dunder-proto": "^1.0.1",
        "es-object-atoms": "^1.0.0"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/get-stream": {
@@ -3215,6 +3392,17 @@
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/gopd": {
      "version": "1.2.0",
      "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz",
      "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/graceful-fs": {
      "version": "4.2.11",
      "resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz",
@@ -3234,6 +3422,42 @@
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/has-symbols": {
      "version": "1.1.0",
      "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz",
      "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/has-tostringtag": {
      "version": "1.0.2",
      "resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
      "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
      "dependencies": {
        "has-symbols": "^1.0.3"
      },
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/hasown": {
      "version": "2.0.2",
      "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz",
      "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
      "dependencies": {
        "function-bind": "^1.1.2"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/he": {
@@ -3696,6 +3920,14 @@
        "semver": "bin/semver"
      }
    },
    "node_modules/math-intrinsics": {
      "version": "1.1.0",
      "resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
      "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/memoize-one": {
      "version": "6.0.0",
      "resolved": "https://registry.npmmirror.com/memoize-one/-/memoize-one-6.0.0.tgz",
@@ -3743,6 +3975,25 @@
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/mime-db": {
      "version": "1.52.0",
      "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/mime-types": {
      "version": "2.1.35",
      "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
      "dependencies": {
        "mime-db": "1.52.0"
      },
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/minimatch": {
@@ -4213,6 +4464,11 @@
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/proxy-from-env": {
      "version": "1.1.0",
      "resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
    },
    "node_modules/prr": {
      "version": "1.0.1",
      "resolved": "https://registry.npmmirror.com/prr/-/prr-1.0.1.tgz",
package.json
@@ -14,6 +14,7 @@
  },
  "dependencies": {
    "axios": "^1.8.4",
    "dayjs": "^1.11.13",
    "element-plus": "^2.9.7",
    "vue": "^3.5.13",
    "vue-router": "^4.5.0"
@@ -21,6 +22,7 @@
  "devDependencies": {
    "@tsconfig/node22": "^22.0.0",
    "@types/node": "^22.13.9",
    "@vitejs/plugin-legacy": "^5.4.0",
    "@vitejs/plugin-vue": "^5.2.1",
    "@vue/eslint-config-prettier": "^10.2.0",
    "@vue/eslint-config-typescript": "^14.5.0",
@@ -31,6 +33,7 @@
    "less": "^4.2.2",
    "npm-run-all2": "^7.0.2",
    "prettier": "3.5.3",
    "terser": "^5.31.0",
    "typescript": "~5.8.0",
    "vite": "^6.2.1",
    "vite-plugin-vue-devtools": "^7.7.2",
public/favicon.ico

src/assets/images/book-mr.jpg
src/assets/images/table-title-bj.jpg
src/assets/images/userIcon.jpg
src/assets/js/config.ts
File was renamed from src/assets/js/config.js
@@ -1,4 +1,4 @@
export const requestCtx = 'http://192.168.1.14/v1' // 请求地址
export const requestCtx = '/v1' // 请求地址
export const requestTimeOut = 300000 // 请求地址
const config = {
src/main.ts
@@ -3,12 +3,19 @@
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import zhCn from 'element-plus/es/locale/lang/zh-cn'
import App from './App.vue'
import router from './router'
import request from '@/plugin/axios/index.ts'
const app = createApp(App)
// 全局注册element icon
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
  app.component(key, component)
}
app.use(ElementPlus, {
src/plugin/axios/index.ts
@@ -1,56 +1,42 @@
import axios from 'axios'
import myConfig from '@/assets/js/config.js'
import myConfig from '@/assets/js/config.ts'
// 创建 axios 实例
const service = axios.create({
  baseURL: myConfig.requestCtx,
  timeout: myConfig.requestTimeOut // 请求超时时间
    baseURL: myConfig.requestCtx,
    timeout: myConfig.requestTimeOut, // 请求超时时间
})
// 请求拦截器
// app-6MPX5Fr97eK6BWHpy8g7vddd
service.interceptors.request.use(
  (config) => {
    const token = "app-6MPX5Fr97eK6BWHpy8g7vddd"
    if (token) config.headers['Authorization'] = `Bearer ${token}`
    return config
  },
  (error) => {
    // 发送失败
    Promise.reject(error)
  }
    (config) => {
        const token = 'app-TmoRR8VCs9nNEb9CxVpyIDcb'
        if (token) config.headers['Authorization'] = `Bearer ${token}`
        config.headers['Content-Type'] = 'application/json;charset=utf-8'
        return config
    },
    (error) => {
        // 发送失败
        Promise.reject(error)
    },
)
// 响应拦截器
service.interceptors.response.use(
  (response) => {
    // dataAxios 是 axios 返回数据中的 data
    const dataAxios = response.data
    if (typeof dataAxios.data === 'boolean') {
      return dataAxios.data
    }
    if (response.config.responseType == 'blob') {
      return dataAxios
    }
    const { success } = dataAxios
    if (dataAxios.currentDate) {
      sessionStorage.currentDate = new Date(dataAxios.currentDate).getTime()
    }
    // 根据 code 进行判断
    if (success) {
      return dataAxios.data ? dataAxios.data : dataAxios
    } else {
      // 提示错误
    }
  },
  (error) => {
    if (error.response && error.response.data && error.response.data.error) {
      console.error(error.response.data.error.msg)
    } else {
      console.error('请求发生错误')
    }
    return Promise.reject(error)
  }
    (response) => {
        if (response.status == 200 && response.statusText == 'OK') {
            return response.data
        }
    },
    (error) => {
        if (error.response && error.response.data && error.response.data.error) {
            console.error(error.response.data.error.msg)
        } else {
            console.error('请求发生错误')
        }
        return Promise.reject(error)
    },
)
export default service
src/types/start.d.ts
New file
@@ -0,0 +1,4 @@
export type Start = {
    inputValue:any,
    questionList:any[]
  }
src/views/HomeView.vue
@@ -3,23 +3,21 @@
    <div class="logo">
      <img src="../assets/images/logo.png" alt="" />
    </div>
    <div class="title">欢迎来到陕西省图书馆</div>
    <div class="function-btn">
      <img class="function-icon" src="../assets/images/image.png" alt="" />
      <div class="function-content-box">
        <div class="function-title">我是你专属的AI智能图书检索助手</div>
        <el-button
          :color="screenWidth > 375 ? '#6e3d3c' : '#af8c56'"
          style="padding: 8px 20px"
          :size="screenWidth > 375 ? 'large' : ''"
          round
          @click="handleChat"
        >
          <span class="btn-text">AI问答</span>
          <img style="margin-left: 5px" src="../assets/images/zuo.png" alt="" />
        </el-button>
    <div class="main">
      <div class="title">欢迎来到陕图高新馆区</div>
      <div class="function-btn">
        <img class="function-icon" src="../assets/images/image.png" alt="" />
        <div class="function-content-box">
          <div class="function-title">我是你专属的AI智能图书检索助手</div>
          <el-button :color="screenWidth > 375 ? '#6e3d3c' : '#af8c56'" style="padding: 8px 20px"
            :size="screenWidth > 375 ? 'large' : ''" round @click="handleChat">
            <span class="btn-text">AI找书</span>
            <img style="margin-left: 5px" src="../assets/images/zuo.png" alt="" />
          </el-button>
        </div>
      </div>
    </div>
  </div>
</template>
@@ -46,45 +44,64 @@
    background-size: cover;
    overflow: hidden;
    position: relative;
    .logo {
      position: absolute;
      width: 200px;
      height: 32px;
      width: 120px;
      bottom: 0;
      left: 0;
      right: 0;
      height: auto;
      margin: auto;
      margin-bottom: 10px;
      img {
        width: 100%;
      }
    }
    .main{
      height: calc(100% - 100px);
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
    }
    .title {
      width: 20px;
      width: 45px;
      height: auto;
      margin: auto;
      text-align: center;
      font-size: 28px;
      font-size: 45px;
      font-family: 'FZZHAOM';
      font-weight: 700;
      font-weight: 400;
      color: #fff;
      margin-bottom: 30px;
      line-height: 38px;
    }
    .function-btn {
      margin: auto;
      width: 100%;
      display: flex;
      justify-content: center;
      align-items: center;
      .function-icon {
        width: 75px;
        margin-right: 10px;
      }
      .function-content-box {
        .function-title {
          margin-bottom: 10px;
          margin-bottom: 15px;
          font-size: 16px;
          font-weight: 700;
          color: #764418;
        }
        .btn-text {
          color: #fff;
        }
@@ -92,6 +109,7 @@
    }
  }
}
@media screen and (min-width: 750px) {
  .home-box {
    width: 100%;
@@ -106,32 +124,37 @@
    flex-direction: column;
    justify-content: flex-start;
    align-items: center;
    .logo {
      width: 1200px;
      min-width: 1200px;
      margin-bottom: 60px;
    }
    .title {
      width: 100%;
      text-align: center;
      font-size: 100px;
      font-family: 'FZZHAOM';
      font-weight: 700;
      font-weight: 400;
      color: #fff;
      letter-spacing: 5px;
      min-width: 1200px;
    }
    .function-btn {
      width: 100%;
      min-width: 1200px;
      display: flex;
      justify-content: center;
      align-items: center;
      .function-icon {
        width: 170px;
        height: 170px;
        margin-right: 50px;
      }
      .function-content-box {
        height: 140px;
        display: flex;
@@ -139,10 +162,12 @@
        justify-content: space-between;
        align-items: flex-start;
        margin-left: 5px;
        .function-title {
          font-size: 35px;
          color: #77471f;
        }
        .btn-text {
          margin-right: 5px;
          font-size: 18px;
src/views/Start.vue
@@ -1,183 +1,446 @@
<template>
  <div class="chat-box">
    <!-- 返回首页标签 -->
    <div class="chat-back-icon" >
      <el-icon :size="25" color="#6e3d3c" @click="handleBackClick()" style="cursor: pointer;">
        <Back />
      </el-icon>
    </div>
    <!-- 聊天框内容容器 -->
    <div class="chat-box-content" ref="messagesContainer">
      <div class="chat-date">03/15 13:10:00</div>
      <!-- 当前时间显示 -->
      <div class="chat-date">{{ currentTime }}</div>
      <!-- 底部信息展示 -->
      <div class="chat-back-info">
        <!-- 头像 -->
        <div class="back-avator">
          <img src="../assets/images/image2.png" alt="" />
        </div>
        <!-- 基础图书信息 -->
        <div class="base-book-box">
          Hi,我是****图书馆AI智能图书检索助手,帮你轻松检索书籍!试试问我:'有没有关于XX的书?"或“推荐一本XX领域的书'吧!
          Hi,我是陕西省高新区图书馆AI智能图书检索助手,帮你轻松检索书籍!试试问我:“有没有关于XX的书?”或“推荐一本XX领域的书”吧!
        </div>
      </div>
      <!-- 热门问题列表 -->
      <div class="back-item">
        <!-- 热门问题标题 -->
        <div class="back-item-title">
          <img src="../assets/images/redian.png" alt="" />
          <span>热门问题</span>
        </div>
        <!-- 热门问题项 -->
        <ul>
          <li>
          <li class="hot-question" v-for="(item, index) in limitedQuestionList" :key="index"
            @click="handleQuestionClick(item.question)">
            <img src="../assets/images/wenti.png" alt="" />
            <span>图书馆的开闭馆时问是什么?</span>
          </li>
          <li>
            <img src="../assets/images/wenti.png" alt="" />
            <span>超期还书如何处理?</span>
          </li>
          <li>
            <img src="../assets/images/wenti.png" alt="" />
            <span>什么是图书馆罚款?</span>
          </li>
          <li>
            <img src="../assets/images/wenti.png" alt="" />
            <span>借阋图书遗失如何处理?</span>
          </li>
          <li>
            <img src="../assets/images/wenti.png" alt="" />
            <span>如何借阅馆藏图书和期刊?</span>
          </li>
          <li>
            <img src="../assets/images/wenti.png" alt="" />
            <span>读者的借阅期限是多久?</span>
            <span>{{ item.question }}</span>
          </li>
        </ul>
        <div class="chat-change">
        <!-- 换一换按钮 -->
        <div class="chat-change" @click="shuffleQuestions()">
          <img src="../assets/images/shuxin1.png" alt="" />
          <span>换一换</span>
        </div>
      </div>
      <div
        v-for="(item, index) in message"
        :key="index"
        :class="['message', item.type === 'user' ? 'user-message' : 'assistant-message']"
      >
        <el-avatar
          style="min-width: 40px"
          :size="screenWidth > 375 ? 60 : 40"
          v-if="item.type != 'user'"
          :src="assistantAvatar"
        />
        <div :class="['message-content', item.type === 'user' ? 'user-message-content' : '']">
          <div class="message-text" v-html="item.content"></div>
          <div class="message-footer" v-if="item.type != 'user'">
            <span class="message-time">{{ item.time }}</span>
      <!-- 消息列表 -->
      <div v-for="(item, index) in message" :key="index" class="chat-box-content-item">
        <div v-if="item.type === 'user'" class="chat-date">{{ item.time }}</div>
        <div :class="['message', item.type === 'user' ? 'user-message' : 'assistant-message']">
          <!-- 助手头像 -->
          <el-avatar class="assistant-avatar" :size="screenWidth > 375 ? 60 : 30"
            :src="[item.type === 'user' ? userProfilePicture : assistantAvatar]" />
          <!-- 消息内容 -->
          <div :class="['message-content', item.type === 'user' ? 'user-message-content' : '']">
            <!-- 用户消息 -->
            <div class="user-message-text" v-if="item.type === 'user'" v-html="item.content"></div>
            <!-- AI List消息 -->
            <div :class="['message-text', 'requestText' + index].join(' ')"
              v-if="item.type != 'user' && item.txtType !== 'txt'">
              <p class="message-text-title">AI智能图书检索助手为您找到以下{{ pageData.inputValue }}的书,馆藏资源如下:</p>
              <div v-for="(citem, cindex) in getDisplayedBooks(item)" :key="cindex">
                <div class="message-text-header">
                  <div class="header-img">
                    <img src="../assets/images/book-mr.jpg" alt="" />
                  </div>
                  <ul class="header-main">
                    <li class="main-name">《{{ citem.name }}》</li>
                    <li class="header-main-flex">
                      <p>
                        <span class="main-title">责任者</span><span class="main-title-colon">:</span><span
                          class="main-content">{{
                            citem.author }}</span>
                      </p>
                      <p>
                        <span class="main-title">出版社</span><span class="main-title-colon">:</span><span
                          class="main-content">{{
                            citem.publisher
                          }}</span>
                      </p>
                    </li>
                    <li class="header-main-flex">
                      <p>
                        <span class="main-title">ISBN号</span><span class="main-title-colon">:</span><span
                          class="main-content">{{ citem.isbn
                          }}</span>
                      </p>
                      <p>
                        <span class="main-title">主题词</span><span class="main-title-colon">:</span><span
                          class="main-content">{{ citem.subject
                          }}</span>
                      </p>
                    </li>
                  </ul>
                </div>
                <div class="message-text-main">
                  <p class="text-main-title">
                    图书简介:</p>
                  <p class="text-main-main">{{ citem.brief }}</p>
                </div>
                <div class="message-text-footer" v-if="
                  citem.books && citem.books.length > 0
                " :class="{ 'no-border': cindex == getDisplayedBooks(item).length - 1 }">
                  <p class="text-footer-title">
                    <img src='../assets/images/table-title-bj.jpg' alt="">
                    <span>馆藏信息:</span>
                  </p>
                  <div class="text-footer-table">
                    <table cellpadding="10">
                      <tr class="table-header">
                        <th>序号</th>
                        <th>索书号</th>
                        <th>条形码</th>
                        <th>馆藏地</th>
                        <th>入档时间</th>
                        <th>书刊状态</th>
                      </tr>
                      <tr v-for="(ditem, dindex) in citem.books" :key="dindex">
                        <td>
                          {{ dindex + 1 }}
                        </td>
                        <td>
                          {{ ditem.indexNum }}
                        </td>
                        <td>{{ ditem.barcode }}</td>
                        <td>{{ ditem.libLoc }}</td>
                        <td>{{ ditem.filingDate }}</td>
                        <td>{{ ditem.collectionStatus }}</td>
                      </tr>
                    </table>
                  </div>
                </div>
              </div>
              <p class="message-text-titleOne">以上内容由AI生成,仅供参考。</p>
              <div class="message-text-change" @click="switchBooks(item)" v-if="!item.isEnd">
                <img src="../assets/images/shuxin1.png" alt="" />
                <span>换一换</span>
              </div>
              <div class="message-text-changeOne" v-else>
                <span>数据完结</span>
              </div>
            </div>
            <!-- AI 文本消息 -->
            <div :class="['Ai-message-text', 'requestText' + index].join(' ')"
              v-if="item.type != 'user' && item.txtType == 'txt'">
              <div v-html="item.content"></div>
            </div>
            <!-- 消息底部时间 -->
            <div class="message-footer" v-if="item.type != 'user'">
              <span class="message-time">{{ item.time }}</span>
            </div>
          </div>
        </div>
        <div v-if="loading" class="message assistant-message loading-message">
          <el-avatar :size="40" :src="assistantAvatar" />
        <!-- 加载中状态 -->
        <div v-if="loading && index == message.length - 1" class="message assistant-message loading-message">
          <el-avatar class="assistant-avatar" :size="screenWidth > 375 ? 60 : 30" :src="assistantAvatar" />
          <div :class="['message-content', item.type === 'user' ? 'user-message-content' : '']">
            <div class="message-text">
              <span class="dot-loading">思考中</span>
            <div class="message-text-loading">
              <span class="dot-loading">思考中...</span>
            </div>
          </div>
        </div>
      </div>
    </div>
    <!-- 聊天底部输入区域 -->
    <div class="chat-footer">
      <div class="icon-list">
        <img src="../assets/images/liebiao1.png" alt="" />
        <img src="../assets/images/tianjia2.png" alt="" />
      </div>
      <!-- 输入框 -->
      <div class="chat-text">
        <el-input
          type="textarea"
          :autosize="{ minRows: 2, maxRows: 10 }"
          placeholder="请输入您的问题"
          v-model="inputValue"
        />
        <el-input type="textarea" :autosize="{ minRows: 3, maxRows: 3 }" placeholder="请输入您的问题" v-model="inputValue"
          @keyup.enter.native="handleEnter($event)" />
        <!-- 发送按钮 -->
        <div class="select-item">
          <img @click="sendMsg()" src="../assets/images/shangchuan2.png" alt="" />
        </div>
      </div>
      <!-- 功能选择区域 -->
      <div class="select">
        <div class="select-left">
          <div class="select-item">
            <img src="../assets/images/sikao.png" alt="" />
            <span>深度思考(R1)</span>
          </div>
          <div class="select-item">
            <img src="../assets/images/lianwang.png" alt="" />
            <span>联网搜索</span>
          </div>
        </div>
        <div class="select-right">
          <div class="select-item">
            <img src="../assets/images/fujian1.png" alt="" />
          </div>
          <div class="select-item">
            <img @click="sendMsg()" src="../assets/images/shangchuan2.png" alt="" />
          </div>
        </div>
        <div class="select-right"></div>
      </div>
    </div>
  </div>
</template>
<script lang="ts" setup>
import { nextTick, onMounted, ref, watch } from 'vue'
import { reactive, nextTick, onMounted, ref, watch, computed } from 'vue'
import type { Start } from '@/types/start'
import router from '@/router/index'
import request from '@/plugin/axios/index' // 引入axios
import defaultImg from '../assets/images/image2.png'
import userIcon from '../assets/images/userIcon.jpg'
import dayjs from 'dayjs'
const inputValue = ref('')
const message = ref<any>([])
const loading = ref(false)
const autoScroll = ref(true)
const messagesContainer = ref<HTMLElement | null>(null)
const assistantAvatar = defaultImg
const userProfilePicture = userIcon
const screenWidth = ref(window.innerWidth)
const pageData = reactive<Start>({
  inputValue: "",
  questionList: [
    {
      question: "第一次来图书馆怎么借书回家看",
    },
    {
      question: "每次都是带孩子看看少儿书籍,其他书籍在哪看呢?",
    },
    {
      question: "我该怎么找我想要的书?",
    },
    {
      question: "书籍怎么检索?",
    },
    {
      question: "三楼和四楼的图书有什么不一样?",
    },
  ]
})
//返回首页
const handleBackClick = () => {
  router.push('/')
}
const scrollToBottom = async () => {
  if (!autoScroll.value) return
  await nextTick()
  if (messagesContainer.value) {
    messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight
    const dom1 = document.querySelector('.dot-loading')
    const dom = document.querySelector('.requestText' + (message.value.length - 1))
    dom1?.scrollIntoView({ behavior: 'smooth', block: 'center' })
    dom?.scrollIntoView({ behavior: 'smooth', block: 'start' })
  }
}
const formatMessage = (content: string) => {
  return content.replace(/\n/g, '<br>')
}
interface ChatMessage {
  content: string
  type: 'user' | 'assistant'
  time: string
  txtType: 'txt' | 'List'
  currentContentIndex: 0
  isEnd: boolean
}
// 换一换
const shuffleQuestions = () => {
  for (let i = pageData.questionList.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [pageData.questionList[i], pageData.questionList[j]] = [pageData.questionList[j], pageData.questionList[i]];
  }
};
//热门问题
const handleQuestionClick = (question: string) => {
  inputValue.value = question
  sendMsg()
}
const handleEnter = (event: any) => {
  event.preventDefault();
  inputValue.value = inputValue.value.replace(/\n/g, "")
  // 调用发送消息的方法
  sendMsg();
}
// 发送消息
const sendMsg = async () => {
  if (!inputValue.value.trim() || loading.value) return
  const userMessage: ChatMessage = {
    content: inputValue.value,
    type: 'user',
    time: new Date().toLocaleTimeString(),
    txtType: 'txt',
    currentContentIndex: 0,
    isEnd: false,
  }
  message.value.push(userMessage)
  message.value.push(userMessage)
  const messageToSend = inputValue.value
  inputValue.value = ''
  loading.value = true
  try {
    setTimeout(() => {
    await getData(messageToSend) // 使用 await 等待 getData 完成
  } catch (error) {
    console.error('发送消息失败', error)
  }
}
// 获取热门问题
const getCommonQyestuion = async () => {
  try {
    const response = await request({
      url: '/chat-messages',
      method: 'post',
      data: {
        inputs: {},
        query: "常见问题列表",
        parent_message_id: null,
        response_mode: 'blocking',
        conversation_id: '',
        user: 'abc-123',
        files: [],
      },
    })
    const answerAgain = JSON.parse((response as any).answer)
    const answerAgains = Object.keys(answerAgain.data);
    pageData.questionList = answerAgains.map((item: any) => {
      return {
        question: item
      }
    })
    // pageData.questionList = response.data
  } catch (error) {
    console.error('获取热门问题失败', error)
  }
}
// 再次回答
// const answerAgain = async (index: number) => {
//   let messageToSend = ""
//   for (let i = index - 1; i >= 0; i--) {
//     if (message.value[i].type == 'user') {
//       messageToSend = message.value[i].content;
//       break;
//     }
//   }
//   // 如果找到了用户消息内容,则调用 getData 方法
//   if (messageToSend) {
//     try {
//       console.log(messageToSend, "messageToSend");
//       await getData(messageToSend); // 使用 await 等待 getData 完成
//     } catch (error) {
//       console.error('发送消息失败', error);
//     }
//   } else {
//     console.error('未找到用户消息内容');
//   }
// }
// 获取数据
const getData = async (messageToSend: any) => {
  loading.value = true
  try {
    const response = await request({
      url: '/chat-messages',
      method: 'post',
      data: {
        inputs: {},
        query: messageToSend,
        parent_message_id: null,
        response_mode: 'blocking',
        conversation_id: '',
        user: 'abc-123',
        files: [],
      },
    })
    // response.answer = response.answer.replace(/\n/g, "<br>")
    const answerAgain = JSON.parse((response as any).answer)
    answerAgain.msg = answerAgain.msg.replace(/\n/g, "<br>")
    if (answerAgain.code == 1) {
      const assistantMessage: ChatMessage = {
        content:
          '你好,十大杀个大傻瓜大厦提高党员湿地公园大刚刚撒反对哈挂号费哀伤的歌返回给法撒旦等哈的地方发生菲大使馆的撒',
        content: answerAgain.data,
        type: 'assistant',
        time: new Date().toLocaleTimeString(),
        txtType: 'List',
        currentContentIndex: 0,
        isEnd: false,
      }
      message.value.push(assistantMessage)
      loading.value = false
      console.log(message, 'dasdas')
    }, 1000)
    } else if (answerAgain.code == 2 || answerAgain.code == 3) {
      const assistantMessage: ChatMessage = {
        content: answerAgain.msg,
        type: 'assistant',
        time: new Date().toLocaleTimeString(),
        txtType: 'txt',
        currentContentIndex: 0,
        isEnd: false,
      }
      message.value.push(assistantMessage)
    }
    loading.value = false
    // 保存消息到本地存储
    localStorage.setItem('chatMessages', JSON.stringify(message.value))
  } catch (error) {
    const assistantMessage: ChatMessage = {
      content: "当前操作遇到一些问题,请稍后再试。",
      type: 'assistant',
      time: new Date().toLocaleTimeString(),
      txtType: 'txt',
      currentContentIndex: 0,
      isEnd: false,
    }
    message.value.push(assistantMessage)
    console.error('发送消息失败', error)
  } finally {
    loading.value = false
  }
}
// 监听消息变化,自动滚动
watch(message.value, () => {
  scrollToBottom()
})
// 定义一个响应式的时间变量
const currentTime = ref(dayjs(new Date()).format('MM/DD HH:mm:ss'))
// 只返回前五个元素
const limitedQuestionList = computed(() => {
  return pageData.questionList.slice(0, 5);
});
const booksPerPage = 3;
// 计算当前应该显示的书籍集合
const getDisplayedBooks = (item: any) => {
  const start = item.currentContentIndex;
  return item.content.slice(start, start + booksPerPage);
};
// “换一换”按钮点击事件处理方法
const switchBooks = (item: any) => {
  const remainingItems = item.content.length - item.currentContentIndex - 3;
  // 检查剩余的数据量是否足够显示下一页
  if (remainingItems > booksPerPage) {
    // 如果足够,移动到下一组数据
    item.currentContentIndex += booksPerPage;
  } else if (remainingItems > 0 && remainingItems <= booksPerPage) {
    // 如果不足一整页但还有剩余数据,显示剩余的所有数据
    item.currentContentIndex += remainingItems;
    item.isEnd = true;
  }
};
// 从本地存储加载消息
onMounted(() => {
  getCommonQyestuion()
  // 删除本地缓存
  localStorage.removeItem('chatMessages');
  const savedMessages = localStorage.getItem('chatMessages')
  if (savedMessages) {
    message.value = JSON.parse(savedMessages)
@@ -194,10 +457,25 @@
    background-image: url('@/assets/images/beijing2.png');
    background-position: center;
    background-size: cover;
    padding-top: 40px;
    position: relative;
    .chat-back-icon {
      position: absolute;
      top: 10px;
      left: 10px;
      text-align: left;
      display: flex;
      el-icon{
        cursor: pointer;
      }
    }
    .chat-box-content {
      width: 100%;
      height: calc(100vh - 170px);
      height: calc(100vh - 153px);
      display: flex;
      flex-direction: column;
      overflow: auto;
@@ -205,9 +483,11 @@
      align-items: flex-start;
      .chat-date {
        color: #999;
        width: 100%;
        text-align: center;
        margin-bottom: 30px;
        margin-bottom: 10px;
        margin-top: 10px;
      }
      .chat-send {
@@ -231,7 +511,7 @@
        margin-bottom: 20px;
        display: flex;
        justify-content: flex-start;
        min-height: 92px;
        .back-avator {
          margin-right: 10px;
@@ -241,6 +521,7 @@
        }
        .base-book-box {
          display: inline-block;
          width: 80%;
          padding: 15px;
          box-sizing: border-box;
@@ -268,6 +549,15 @@
          border-bottom: 1px solid #e9d8bf;
        }
        .hot-question {
          cursor: pointer;
          &:hover {
            color: #d2a25b;
          }
        }
        img {
          margin-right: 10px;
        }
@@ -290,13 +580,21 @@
          align-items: center;
          padding: 10px 20px;
          color: #d2a25b;
          cursor: pointer;
          img {
            cursor: pointer;
          }
        }
      }
      .chat-box-content-item {
        width: 100%;
      }
    }
    .chat-footer {
      width: 90%;
      margin: auto;
@@ -313,6 +611,9 @@
      ::v-deep(.chat-text) {
        margin-bottom: 10px;
        height: 100%;
        display: flex;
        align-items: center;
        .el-textarea__inner {
          border: none !important;
@@ -349,6 +650,7 @@
            color: #e1c49a;
            img {
              height: auto;
              margin-right: 5px;
              cursor: pointer;
            }
@@ -375,29 +677,45 @@
        }
      }
    }
    .message {
      width: 100%;
      display: flex;
      margin-bottom: 24px;
      align-items: flex-start;
      animation: slideIn 0.3s ease;
      animation-fill-mode: forwards;
      max-width: 85%;
      max-width: 90%;
      border-radius: 12px;
      // box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
      padding: 16px;
      padding-left: 3px;
    }
    .assistant-avatar {
      min-width: 40px;
      max-width: 40px;
      height: auto;
    }
    .message-content {
      display: inline-block;
      max-width: 80%;
      background: #fff;
      margin-left: 10px;
      border-radius: 20px;
      min-width: 200px;
      padding: 5px;
      padding: 3px 10px;
      margin-top: 5px;
      margin-right: 10px;
    }
    .user-message-text {
      color: #fff;
    }
    .message-text {
      padding: 12px 16px;
      width: 100%;
      padding: 6px 8px;
      border-radius: 12px;
      word-wrap: break-word;
      line-height: 1.6;
@@ -405,6 +723,265 @@
      transition: all 0.3s ease;
      white-space: pre-wrap;
      color: #333;
      .message-text-title {
        font-size: 14px;
        color: #999;
        line-height: 20px;
        padding: 10px 0 20px 0;
      }
      .message-text-header {
        ul {
          list-style-type: none;
        }
        li {
          list-style-type: none;
        }
        .header-img {
          display: flex;
          justify-content: center;
          img {
            width: 65%;
          }
        }
        .header-main {
          padding: 10px 0;
          .main-name {
            width: 100%;
            font-size: 18px;
            font-family: Microsoft YaHei, Microsoft YaHei-Bold;
            font-weight: 700;
            text-align: center;
            color: #333333;
            margin-bottom: 20px
          }
          .header-main-flex {
            padding: 0 10px;
            .main-title {
              font-size: 14px;
              display: inline-block;
              width: 28.5%;
              text-wrap: nowrap;
              color: #000;
              text-align: justify;
              letter-spacing: 0.1em;
              /* 调整字母间距 */
              text-align-last: justify;
              /* 确保最后一行文本也均匀分布 */
              display: inline-block;
              /* 设置为行内块元素 */
              vertical-align: top;
              /* 顶部对齐 */
            }
            .main-title-colon {
              color: #000;
              margin-right: 3px;
              margin-left: 1px;
              display: inline-block;
              /* 设置为行内块元素 */
              vertical-align: top;
              /* 顶部对齐 */
            }
            .main-content {
              font-size: 14px;
              display: inline-block;
              /* 设置为行内块元素 */
              /* 顶部对齐 */
              max-width: calc(72.5% - 15px);
              /* 减去.main-title宽度和.main-title-colon的margin-right */
              word-wrap: break-word;
              /* 允许在长单词或无空格字符串内部进行换行 */
            }
            p {
              width: 100%;
              overflow: hidden;
              font-size: 14px;
              margin: 2px 0;
              color: #a5a5a5;
            }
            span {
              font-size: 14px;
            }
          }
        }
      }
      .message-text-main {
        padding: 10px 0;
        .text-main-title {
          font-size: 15px;
          font-weight: bold;
          color: #a88868;
          margin: 3px 0;
        }
        .text-main-main {
          margin-top: 5px;
          max-height: 150px;
          min-height: 150px;
          overflow: auto;
          font-size: 14px;
          line-height: 26px;
          text-align: justify;
          color: #6d6d6d;
        }
      }
      .no-border {
        border-bottom: none !important;
      }
      .message-text-footer {
        width: 100%;
        margin-top: 10px;
        margin-bottom: 10px;
        padding-bottom: 20px;
        border-bottom: 1px solid #e9d8bf;
        .text-main-footer {
          width: 100%;
        }
        .text-footer-title {
          position: relative;
          img {
            max-width: 50%;
            margin-bottom: 10px;
          }
          span {
            font-size: 15px;
            font-weight: bold;
            color: #fff;
            position: absolute;
            left: 2%;
            top: 3.5%;
          }
        }
        .text-footer-table {
          width: 100%;
          overflow-x: auto;
        }
        table {
          width: 100%;
          border-collapse: collapse;
        }
        th {
          text-wrap: nowrap;
          background-color: #f9ecd8;
          color: #b3b3b3 !important;
        }
        tr {
          width: 5%;
        }
        td {
          text-wrap: nowrap;
          text-align: center;
        }
        tr:nth-child(odd) {
          background-color: #f9ecd8;
          /* 奇数行背景颜色 */
        }
        tr:nth-child(even) {
          background-color: #fff7eb;
          /* 偶数行背景颜色 */
        }
      }
      .message-text-titleOne {
        text-align: right;
        color: #fe7313;
        font-size: 10px;
        padding-bottom: 5px;
        border-bottom: 1px solid #e9d8bf;
      }
      .message-text-change {
        display: flex;
        align-items: center;
        justify-content: flex-end;
        padding: 10px 0 0 0;
        cursor: pointer;
        img {
          margin-right: 10px;
        }
        span {
          font-size: 14px;
          font-family: Microsoft YaHei, Microsoft YaHei-Regular;
          font-weight: 400;
          text-align: left;
          color: #d2a25b;
          line-height: 35px;
        }
      }
      .message-text-changeOne {
        display: flex;
        align-items: center;
        justify-content: flex-end;
        padding: 10px 0 0 0;
        span {
          font-size: 14px;
          font-family: Microsoft YaHei, Microsoft YaHei-Regular;
          font-weight: 400;
          text-align: left;
          color: #d2a25b;
          line-height: 35px;
        }
      }
    }
    .message-text-loading {
      padding: 0px 10px;
      border-radius: 10px;
      word-wrap: break-word;
      line-height: 1.6;
      font-size: 0.95rem;
      transition: all 0.3s ease;
      white-space: pre-wrap;
      color: #333;
    }
    .Ai-message-text {
      div {
        font-size: 16px;
        text-indent: 1em;
      }
    }
    .user-message {
@@ -426,7 +1003,7 @@
    }
    .message-time {
      font-size: 0.85rem;
      font-size: 0.70rem;
      color: #999;
      margin-left: 10px;
    }
@@ -446,10 +1023,23 @@
    justify-content: flex-start;
    align-items: center;
    padding-bottom: 10px;
    position: relative;
    .chat-back-icon {
      position: absolute;
      top: 30px;
      width: 80%;
      text-align: left;
      display: flex;
      el-icon{
        cursor: pointer;
      }
    }
    .chat-box-content {
      width: 1200px;
      height: calc(100vh - 180px);
      min-width: 1200px;
      height: calc(100vh - 100px);
      display: flex;
      flex-direction: column;
      justify-content: flex-start;
@@ -486,9 +1076,11 @@
      }
      .chat-date {
        color: #999;
        width: 100%;
        text-align: center;
        margin-bottom: 30px;
        margin-top: 30px;
      }
      .chat-send {
@@ -512,6 +1104,7 @@
        margin-bottom: 20px;
        display: flex;
        justify-content: flex-start;
        min-height: 90px;
        .back-avator {
          margin-right: 37px;
@@ -522,6 +1115,7 @@
        }
        .base-book-box {
          display: flex;
          width: 800px;
          padding: 20px 47px;
          box-sizing: border-box;
@@ -532,7 +1126,7 @@
      .back-item {
        width: 349px;
        height: 391px;
        height: auto;
        background: #ffffff;
        border-radius: 20px;
        margin-left: 100px;
@@ -547,6 +1141,15 @@
          margin: auto;
          border-bottom: 1px solid #e9d8bf;
        }
        .hot-question {
          cursor: pointer;
          &:hover {
            color: #d2a25b;
          }
        }
        img {
          margin-right: 10px;
@@ -566,11 +1169,17 @@
          align-items: center;
          padding: 0 20px;
          color: #d2a25b;
          margin-bottom: 10px;
          cursor: pointer;
          img {
            cursor: pointer;
          }
        }
      }
      .chat-box-content-item {
        width: 100%;
      }
    }
@@ -585,7 +1194,7 @@
    .chat-footer {
      width: 1200px;
      height: 170px;
      height: 100px;
      background-color: #fff;
      border-radius: 20px;
      padding: 20px;
@@ -597,14 +1206,24 @@
      }
      ::v-deep(.chat-text) {
        height: 100%;
        display: flex;
        align-items: center;
        margin-bottom: 10px;
        .el-textarea__inner {
          overflow: auto;
          height: 100% !important;
          border: none !important;
          outline: none !important;
          box-shadow: none !important;
          background-color: transparent !important;
          resize: none !important;
        }
        img {
          cursor: pointer;
          min-height: 25px;
        }
      }
@@ -661,23 +1280,273 @@
      align-items: flex-start;
      animation: slideIn 0.3s ease;
      animation-fill-mode: forwards;
      max-width: 95%;
      max-width: 85%;
      border-radius: 12px;
      // box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
      padding: 16px;
    }
    .assistant-avatar {
      min-width: 60px;
      max-width: 60px;
      height: auto;
    }
    .message-content {
      display: inline-block;
      margin-top: 10px;
      max-width: 85%;
      background: #fff;
      margin-left: 20px;
      margin-right: 20px;
      border-radius: 20px;
      min-width: 200px;
      padding: 5px;
      padding: 10px 10px;
    }
    .user-message-text {
      // text-indent: 1em;
      color: #fff;
    }
    .message-text {
      padding: 12px 16px;
      min-width: 800px;
      padding: 0px 40px;
      border-radius: 12px;
      word-wrap: break-word;
      line-height: 1.6;
      font-size: 0.95rem;
      transition: all 0.3s ease;
      white-space: pre-wrap;
      color: #333;
      .message-text-title {
        font-size: 16px;
        color: #999;
        line-height: 35px;
        padding: 20px 0 30px 0;
      }
      .message-text-header {
        display: flex;
        ul {
          list-style-type: none;
        }
        li {
          list-style-type: none;
        }
        .header-img {
          width: 20%;
          margin-right: 20px;
          display: flex;
          align-items: center;
          img {
            width: 100%;
          }
        }
        .header-main {
          width: 80%;
          padding: 10px 0;
          .header-main-flex {
            display: flex;
            p {
              width: 50%;
              overflow: hidden;
              font-size: 16px;
              margin: 2px 0;
              color: #a5a5a5;
            }
          }
        }
        .main-name {
          font-size: 18px;
          margin-bottom: 10px;
        }
        .main-title {
          display: inline-block;
          width: 25%;
          text-wrap: nowrap;
          color: #000;
          text-align: justify;
          letter-spacing: 0.1em;
          /* 调整字母间距 */
          text-align-last: justify;
          /* 确保最后一行文本也均匀分布 */
          display: inline-block;
          /* 设置为行内块元素 */
          vertical-align: top;
          /* 顶部对齐 */
        }
        .main-title-colon {
          color: #000;
          margin-right: 5px;
          display: inline-block;
          /* 设置为行内块元素 */
          vertical-align: top;
          /* 顶部对齐 */
        }
        .main-content {
          font-size: 14px;
          display: inline-block;
          /* 设置为行内块元素 */
          vertical-align: top;
          /* 顶部对齐 */
          max-width: calc(75% - 15px);
          /* 减去.main-title宽度和.main-title-colon的margin-right */
          word-wrap: break-word;
          /* 允许在长单词或无空格字符串内部进行换行 */
        }
      }
      .message-text-main {
        padding: 10px 10px;
        .text-main-title {
          font-size: 16px;
          font-weight: bold;
          color: #a88868;
          margin: 5px 0;
        }
        .text-main-main {
          margin-top: 10px;
          max-height: 92px;
          min-height: 92px;
          overflow: auto;
          font-size: 14px;
          line-height: 26px;
          text-align: justify;
          color: #6d6d6d;
        }
      }
      .no-border {
        border-bottom: none !important;
      }
      .message-text-footer {
        margin-top: 30px;
        margin-bottom: 20px;
        padding-bottom: 30px;
        border-bottom: 1px solid #e9d8bf;
        .text-main-footer {
          width: 100%;
        }
        .text-footer-title {
          position: relative;
          img {
            max-width: 18%;
            margin-bottom: 20px;
          }
          span {
            font-size: 19px;
            font-weight: bold;
            color: #fff;
            position: absolute;
            left: 2%;
          }
        }
        table {
          width: 100%;
          border-collapse: collapse;
        }
        th {
          background-color: #f9ecd8;
          color: #b3b3b3 !important;
        }
        tr {
          width: 100%;
        }
        td {
          text-align: center;
        }
        tr:nth-child(odd) {
          background-color: #f9ecd8;
          /* 奇数行背景颜色 */
        }
        tr:nth-child(even) {
          background-color: #fff7eb;
          /* 偶数行背景颜色 */
        }
      }
      .message-text-titleOne {
        text-align: right;
        color: #fe7313;
        font-size: 10px;
        padding-bottom: 5px;
        border-bottom: 1px solid #e9d8bf;
      }
      .message-text-change {
        display: flex;
        align-items: center;
        padding: 10px 0 0 0;
        cursor: pointer;
        img {
          margin-right: 10px;
        }
        span {
          font-size: 14px;
          font-family: Microsoft YaHei, Microsoft YaHei-Regular;
          font-weight: 400;
          text-align: left;
          color: #d2a25b;
          line-height: 35px;
        }
      }
      .message-text-changeOne {
        display: flex;
        align-items: center;
        justify-content: flex-end;
        padding: 10px 0 0 0;
        span {
          font-size: 14px;
          font-family: Microsoft YaHei, Microsoft YaHei-Regular;
          font-weight: 400;
          text-align: left;
          color: #d2a25b;
          line-height: 35px;
        }
      }
    }
    .message-text-loading {
      padding: 0px 10px;
      border-radius: 10px;
      word-wrap: break-word;
      line-height: 1.6;
      font-size: 0.95rem;
@@ -686,12 +1555,20 @@
      color: #333;
    }
    .Ai-message-text {
      div {
        font-size: 16px;
      }
    }
    .user-message {
      flex-direction: row-reverse;
      margin-left: auto;
    }
    .user-message .message-text {
      justify-content: center;
      color: #8b6e47;
    }
@@ -699,13 +1576,13 @@
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-top: 8px;
      margin-top: 5px;
      padding: 0 4px;
      color: #999;
    }
    .message-time {
      font-size: 0.85rem;
      font-size: 0.75rem;
      color: #999;
      margin-left: 10px;
    }
@@ -714,6 +1591,7 @@
.user-message-content {
  background: #af8b56 !important;
  .message-text {
    color: #fff !important;
    padding: 5px 10px;
tsconfig.json
@@ -7,5 +7,9 @@
    {
      "path": "./tsconfig.app.json"
    }
  ]
  ],
  "compilerOptions": {
   "noImplicitAny": false,
"allowJs": true,
  }
}
vite.config.ts
@@ -1,14 +1,26 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
import legacyPlugin from '@vitejs/plugin-legacy'
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  plugins: [
    vue(),
    legacyPlugin({
      targets: ['defaults', 'chrome 52', 'ie >= 11','Safari >= 8'],  // 需要兼容的目标列表,可以设置多个
      additionalLegacyPolyfills: ['regenerator-runtime/runtime'], // 面向IE11时需要此插件
      renderLegacyChunks: true,
      polyfills: true,
      modernPolyfills: true,
    })
  ],
  build:{target: ['ios8', 'edge90', 'chrome52', 'firefox90', 'safari8']},
  server: {
    host: true, // Expose to all network interfaces
    port: 5174, // Default Vite port
    host: '0.0.0.0' // Expose to all network interfaces
    // port: 5174, // Default Vite port
  },
  base: "./",
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src')
yarn.lock
Diff too large