feat: 添加微信按钮组件及优化AI聊天功能
refactor: 移除未使用的circle-btn组件引用 style: 更新图片资源路径及样式 fix: 修复axios请求配置及类型定义 docs: 添加mock-api.js模拟接口文件
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
6
dist/img/arrow-circular-orange-red.2f945218.svg
vendored
Normal file
6
dist/img/arrow-circular-orange-red.2f945218.svg
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="10px" height="10px" xmlns="http://www.w3.org/2000/svg">
|
||||
<g transform="matrix(1 0 0 1 -2066 -660 )">
|
||||
<path d="M 4.375 8.37239583333333 C 4.48784722222222 8.37239583333333 4.58550347222222 8.33116319444444 4.66796875 8.24869791666667 L 7.62369791666667 5.29296875 C 7.70616319444445 5.21050347222222 7.74739583333333 5.11284722222222 7.74739583333333 5 C 7.74739583333333 4.88715277777778 7.70616319444445 4.78949652777778 7.62369791666667 4.70703125 L 4.66796875 1.75130208333333 C 4.58550347222222 1.66883680555555 4.48784722222222 1.62760416666667 4.375 1.62760416666667 C 4.26215277777778 1.62760416666667 4.16449652777778 1.66883680555555 4.08203125 1.75130208333333 L 3.41796875 2.41536458333333 C 3.33550347222222 2.49782986111111 3.29427083333333 2.59548611111111 3.29427083333333 2.70833333333333 C 3.29427083333333 2.82118055555555 3.33550347222222 2.91883680555555 3.41796875 3.00130208333333 L 5.41666666666667 5 L 3.41796875 6.99869791666667 C 3.33550347222222 7.08116319444444 3.29427083333333 7.17881944444444 3.29427083333333 7.29166666666667 C 3.29427083333333 7.40451388888889 3.33550347222222 7.50217013888889 3.41796875 7.58463541666667 L 4.08203125 8.24869791666667 C 4.16449652777778 8.33116319444444 4.26215277777778 8.37239583333333 4.375 8.37239583333333 Z M 9.32942708333333 2.490234375 C 9.77647569444444 3.25629340277778 10 4.09288194444444 10 5 C 10 5.90711805555556 9.77647569444444 6.74370659722222 9.32942708333333 7.509765625 C 8.88237847222222 8.27582465277778 8.27582465277778 8.88237847222222 7.509765625 9.32942708333333 C 6.74370659722222 9.77647569444444 5.90711805555556 10 5 10 C 4.09288194444444 10 3.25629340277778 9.77647569444444 2.490234375 9.32942708333333 C 1.72417534722222 8.88237847222222 1.11762152777778 8.27582465277778 0.670572916666667 7.509765625 C 0.223524305555556 6.74370659722222 0 5.90711805555556 0 5 C 0 4.09288194444444 0.223524305555556 3.25629340277778 0.670572916666667 2.490234375 C 1.11762152777778 1.72417534722222 1.72417534722222 1.11762152777778 2.490234375 0.670572916666666 C 3.25629340277778 0.223524305555555 4.09288194444444 0 5 0 C 5.90711805555556 0 6.74370659722222 0.223524305555555 7.509765625 0.670572916666666 C 8.27582465277778 1.11762152777778 8.88237847222222 1.72417534722222 9.32942708333333 2.490234375 Z " fill-rule="nonzero" fill="#d35110" stroke="none" transform="matrix(1 0 0 1 2066 660 )" />
|
||||
</g>
|
||||
</svg>
|
||||
6
dist/img/arrows-deep-white.a1b5db4f.svg
vendored
Normal file
6
dist/img/arrows-deep-white.a1b5db4f.svg
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="16px" height="17px" xmlns="http://www.w3.org/2000/svg">
|
||||
<g transform="matrix(1 0 0 1 -3899 -1199 )">
|
||||
<path d="M 15.5978260869565 7.51797175866495 C 15.8659420289855 7.77257167308515 16 8.09991442019683 16 8.5 C 16 8.89281129653402 15.8659420289855 9.22379118528027 15.5978260869565 9.49293966623877 L 8.52173913043478 16.5962772785623 C 8.23913043478261 16.8654257595208 7.90942028985507 17 7.53260869565217 17 C 7.16304347826087 17 6.83695652173913 16.8654257595208 6.55434782608696 16.5962772785623 L 5.73913043478261 15.7779204107831 C 5.46376811594203 15.5014976465554 5.32608695652174 15.1705177578092 5.32608695652174 14.7849807445443 C 5.32608695652174 14.3994437312794 5.46376811594203 14.0684638425332 5.73913043478261 13.7920410783055 L 8.92391304347826 10.5949935815148 L 1.27173913043478 10.5949935815148 C 0.894927536231884 10.5949935815148 0.588768115942029 10.4586007702182 0.353260869565217 10.1858151476252 C 0.117753623188406 9.91302952503209 0 9.58386820710312 0 9.19833119383826 L 0 7.80166880616175 C 0 7.41613179289688 0.117753623188406 7.08697047496791 0.353260869565217 6.81418485237484 C 0.588768115942029 6.54139922978177 0.894927536231884 6.40500641848524 1.27173913043478 6.40500641848524 L 8.92391304347826 6.40500641848524 L 5.73913043478261 3.19704749679076 C 5.46376811594203 2.93517329910141 5.32608695652174 2.60783055198973 5.32608695652174 2.21501925545571 C 5.32608695652174 1.8222079589217 5.46376811594203 1.49486521181001 5.73913043478261 1.23299101412067 L 6.55434782608696 0.414634146341464 C 6.82971014492754 0.13821138211382 7.15579710144928 0 7.53260869565217 0 C 7.91666666666667 0 8.2463768115942 0.13821138211382 8.52173913043478 0.414634146341464 L 15.5978260869565 7.51797175866495 Z " fill-rule="nonzero" fill="#ffffff" stroke="none" transform="matrix(1 0 0 1 3899 1199 )" />
|
||||
</g>
|
||||
</svg>
|
||||
BIN
dist/img/round-icon.5c96c0c8.gif
vendored
Normal file
BIN
dist/img/round-icon.5c96c0c8.gif
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
6
dist/img/star-half.a681992c.svg
vendored
Normal file
6
dist/img/star-half.a681992c.svg
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="18px" height="18px" xmlns="http://www.w3.org/2000/svg">
|
||||
<g transform="matrix(1 0 0 1 -1980 -943 )">
|
||||
<path d="M 12.2992788461538 11.0245746691871 L 12.8293269230769 10.4914933837429 L 15.609375 7.65595463137996 L 11.7584134615385 7.06616257088847 L 11.0444711538462 6.95274102079395 L 10.7199519230769 6.27221172022684 L 9 2.62003780718336 L 9 13.5425330812854 L 9.63822115384615 13.8941398865785 L 13.078125 15.7996219281664 L 12.4290865384615 11.773156899811 L 12.2992788461538 11.0245746691871 Z M 17.9783653846154 6.84499054820416 C 18.0432692307692 7.05293005671077 17.9567307692308 7.27788279773157 17.71875 7.51984877126654 L 13.7920673076923 11.5349716446125 L 14.7223557692308 17.2060491493384 C 14.7584134615385 17.4555765595463 14.7367788461538 17.6502835538752 14.6574519230769 17.7901701323251 C 14.578125 17.930056710775 14.4555288461538 18 14.2896634615385 18 C 14.1670673076923 18 14.0228365384615 17.9546313799622 13.8569711538462 17.8638941398866 L 9 15.187145557656 L 4.14302884615385 17.8638941398866 C 3.97716346153846 17.9546313799622 3.83293269230769 18 3.71033653846154 18 C 3.54447115384615 18 3.421875 17.930056710775 3.34254807692308 17.7901701323251 C 3.26322115384615 17.6502835538752 3.24158653846154 17.4555765595463 3.27764423076923 17.2060491493384 L 4.20793269230769 11.5349716446125 L 0.270432692307692 7.51984877126654 C 0.0396634615384615 7.27788279773157 -0.0432692307692308 7.05293005671077 0.0216346153846154 6.84499054820416 C 0.0865384615384615 6.63705103969754 0.28125 6.50661625708885 0.605769230769231 6.45368620037807 L 6.03605769230769 5.62570888468809 L 8.46995192307692 0.465028355387523 C 8.61418269230769 0.15500945179584 8.79086538461539 0 9 0 C 9.20192307692308 0 9.37860576923077 0.15500945179584 9.53004807692308 0.465028355387523 L 11.9639423076923 5.62570888468809 L 17.3942307692308 6.45368620037807 C 17.71875 6.50661625708885 17.9134615384615 6.63705103969754 17.9783653846154 6.84499054820416 Z " fill-rule="nonzero" fill="#fddf6d" stroke="none" transform="matrix(1 0 0 1 1980 943 )" />
|
||||
</g>
|
||||
</svg>
|
||||
6
dist/img/star-icon.c2e6113d.svg
vendored
Normal file
6
dist/img/star-icon.c2e6113d.svg
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="18px" height="18px" xmlns="http://www.w3.org/2000/svg">
|
||||
<g transform="matrix(1 0 0 1 -1957 -943 )">
|
||||
<path d="M 17.3942307692308 6.45368620037807 C 17.7980769230769 6.52173913043478 18 6.69565217391304 18 6.97542533081285 C 18 7.14177693761815 17.90625 7.32325141776937 17.71875 7.51984877126654 L 13.7920673076923 11.5349716446125 L 14.7223557692308 17.2060491493384 C 14.7295673076923 17.2589792060492 14.7331730769231 17.3345935727788 14.7331730769231 17.4328922495274 C 14.7331730769231 17.5916824196597 14.6953125 17.7258979206049 14.6195913461538 17.8355387523629 C 14.5438701923077 17.945179584121 14.4338942307692 18 14.2896634615385 18 C 14.1526442307692 18 14.0084134615385 17.9546313799622 13.8569711538462 17.8638941398866 L 9 15.187145557656 L 4.14302884615385 17.8638941398866 C 3.984375 17.9546313799622 3.84014423076923 18 3.71033653846154 18 C 3.55889423076923 18 3.4453125 17.945179584121 3.36959134615385 17.8355387523629 C 3.29387019230769 17.7258979206049 3.25600961538462 17.5916824196597 3.25600961538462 17.4328922495274 C 3.25600961538462 17.3875236294896 3.26322115384615 17.3119092627599 3.27764423076923 17.2060491493384 L 4.20793269230769 11.5349716446125 L 0.270432692307692 7.51984877126654 C 0.0901442307692308 7.31568998109641 0 7.13421550094518 0 6.97542533081285 C 0 6.69565217391304 0.201923076923077 6.52173913043478 0.605769230769231 6.45368620037807 L 6.03605769230769 5.62570888468809 L 8.46995192307692 0.465028355387523 C 8.60697115384616 0.15500945179584 8.78365384615385 0 9 0 C 9.21634615384615 0 9.39302884615385 0.15500945179584 9.53004807692308 0.465028355387523 L 11.9639423076923 5.62570888468809 L 17.3942307692308 6.45368620037807 Z " fill-rule="nonzero" fill="#fddf6d" stroke="none" transform="matrix(1 0 0 1 1957 943 )" />
|
||||
</g>
|
||||
</svg>
|
||||
16
dist/img/wechat-pop-green.1aaa230b.svg
vendored
Normal file
16
dist/img/wechat-pop-green.1aaa230b.svg
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" version="1.1" width="292px" height="149px">
|
||||
<defs>
|
||||
<linearGradient gradientUnits="userSpaceOnUse" x1="150" y1="0" x2="150" y2="160" id="LinearGradient1149">
|
||||
<stop id="Stop1150" stop-color="#50e3c2" stop-opacity="0.498039215686275" offset="0"/>
|
||||
<stop id="Stop1151" stop-color="#ffffff" offset="1"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g transform="matrix(1 0 0 1 0 -150)">
|
||||
<!-- 白色箭头(置于下层) -->
|
||||
<path d="M 0 0 L 10 10 L 20 0 Z" fill="#ffffff" transform="translate(140, 289)"/>
|
||||
<!-- 原有渐变图形(置于上层,覆盖下层箭头重合部分) -->
|
||||
<path d="M 292 19 L 292 132 C 292 136.48 288.48 140 284 140 L 160 140 L 150 150 L 140 140 L 8 140 C 3.52 140 0 136.48 0 132 L 0 19 C 0 19 65.55 1.07 149 1 C 233.55 0.93 292 19 292 19 Z" fill-rule="nonzero" fill="url(#LinearGradient1149)" stroke="none" transform="matrix(1 0 0 1 0 150)"/>
|
||||
<!-- 底部箭头(置于最上层,避免被覆盖) -->
|
||||
|
||||
</g>
|
||||
</svg>
|
||||
2
dist/index.html
vendored
2
dist/index.html
vendored
@@ -1,4 +1,4 @@
|
||||
<!doctype html><html lang=""><head><meta charset="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><meta name="viewport" content="width=device-width,initial-scale=1"/><link rel="icon" href="https://ansnid.oss-cn-shenzhen.aliyuncs.com/fang/favicon.ico"/><title>港校租房</title><script defer="defer" src="https://ansnid.oss-cn-shenzhen.aliyuncs.com/fang/js/chunk-vendors.5bed831c.js"></script><script defer="defer" src="https://ansnid.oss-cn-shenzhen.aliyuncs.com/fang/js/app.a231ac01.js"></script><link href="https://ansnid.oss-cn-shenzhen.aliyuncs.com/fang/css/chunk-vendors.7885d77e.css" rel="stylesheet"><link href="https://ansnid.oss-cn-shenzhen.aliyuncs.com/fang/css/app.2c489303.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but zufang doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><script src="https://app.gter.net/bottom?tpl=header&menukey=fang"></script><div id="app"></div><div style="display: none;"><script>var _hmt = _hmt || []
|
||||
<!doctype html><html lang=""><head><meta charset="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><meta name="viewport" content="width=device-width,initial-scale=1"/><link rel="icon" href="https://ansnid.oss-cn-shenzhen.aliyuncs.com/fang/favicon.ico"/><title>港校租房</title><script defer="defer" src="https://ansnid.oss-cn-shenzhen.aliyuncs.com/fang/js/chunk-vendors.65a8ec5d.js"></script><script defer="defer" src="https://ansnid.oss-cn-shenzhen.aliyuncs.com/fang/js/app.68a5a4ab.js"></script><link href="https://ansnid.oss-cn-shenzhen.aliyuncs.com/fang/css/chunk-vendors.7885d77e.css" rel="stylesheet"><link href="https://ansnid.oss-cn-shenzhen.aliyuncs.com/fang/css/app.e162f837.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but zufang doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><script src="https://app.gter.net/bottom?tpl=header&menukey=fang"></script><div id="app"></div><div style="display: none;"><script>var _hmt = _hmt || []
|
||||
;(function () {
|
||||
var hm = document.createElement("script")
|
||||
hm.src = "//hm.baidu.com/hm.js?4bd66cbe45a640b607fe46c48f658746"
|
||||
|
||||
1
dist/js/818.48ffaa55.js
vendored
Normal file
1
dist/js/818.48ffaa55.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/js/app.68a5a4ab.js
vendored
Normal file
1
dist/js/app.68a5a4ab.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/js/app.a231ac01.js
vendored
1
dist/js/app.a231ac01.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
dist/js/housing.2b5362f1.js
vendored
Normal file
1
dist/js/housing.2b5362f1.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/js/housing.6670a8e9.js
vendored
1
dist/js/housing.6670a8e9.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
dist/js/user.84392502.js
vendored
Normal file
1
dist/js/user.84392502.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/js/user.fbfcdcc6.js
vendored
1
dist/js/user.fbfcdcc6.js
vendored
File diff suppressed because one or more lines are too long
6
src/assets/img/publicImage/arrow-circular-orange-red.svg
Normal file
6
src/assets/img/publicImage/arrow-circular-orange-red.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="10px" height="10px" xmlns="http://www.w3.org/2000/svg">
|
||||
<g transform="matrix(1 0 0 1 -2066 -660 )">
|
||||
<path d="M 4.375 8.37239583333333 C 4.48784722222222 8.37239583333333 4.58550347222222 8.33116319444444 4.66796875 8.24869791666667 L 7.62369791666667 5.29296875 C 7.70616319444445 5.21050347222222 7.74739583333333 5.11284722222222 7.74739583333333 5 C 7.74739583333333 4.88715277777778 7.70616319444445 4.78949652777778 7.62369791666667 4.70703125 L 4.66796875 1.75130208333333 C 4.58550347222222 1.66883680555555 4.48784722222222 1.62760416666667 4.375 1.62760416666667 C 4.26215277777778 1.62760416666667 4.16449652777778 1.66883680555555 4.08203125 1.75130208333333 L 3.41796875 2.41536458333333 C 3.33550347222222 2.49782986111111 3.29427083333333 2.59548611111111 3.29427083333333 2.70833333333333 C 3.29427083333333 2.82118055555555 3.33550347222222 2.91883680555555 3.41796875 3.00130208333333 L 5.41666666666667 5 L 3.41796875 6.99869791666667 C 3.33550347222222 7.08116319444444 3.29427083333333 7.17881944444444 3.29427083333333 7.29166666666667 C 3.29427083333333 7.40451388888889 3.33550347222222 7.50217013888889 3.41796875 7.58463541666667 L 4.08203125 8.24869791666667 C 4.16449652777778 8.33116319444444 4.26215277777778 8.37239583333333 4.375 8.37239583333333 Z M 9.32942708333333 2.490234375 C 9.77647569444444 3.25629340277778 10 4.09288194444444 10 5 C 10 5.90711805555556 9.77647569444444 6.74370659722222 9.32942708333333 7.509765625 C 8.88237847222222 8.27582465277778 8.27582465277778 8.88237847222222 7.509765625 9.32942708333333 C 6.74370659722222 9.77647569444444 5.90711805555556 10 5 10 C 4.09288194444444 10 3.25629340277778 9.77647569444444 2.490234375 9.32942708333333 C 1.72417534722222 8.88237847222222 1.11762152777778 8.27582465277778 0.670572916666667 7.509765625 C 0.223524305555556 6.74370659722222 0 5.90711805555556 0 5 C 0 4.09288194444444 0.223524305555556 3.25629340277778 0.670572916666667 2.490234375 C 1.11762152777778 1.72417534722222 1.72417534722222 1.11762152777778 2.490234375 0.670572916666666 C 3.25629340277778 0.223524305555555 4.09288194444444 0 5 0 C 5.90711805555556 0 6.74370659722222 0.223524305555555 7.509765625 0.670572916666666 C 8.27582465277778 1.11762152777778 8.88237847222222 1.72417534722222 9.32942708333333 2.490234375 Z " fill-rule="nonzero" fill="#d35110" stroke="none" transform="matrix(1 0 0 1 2066 660 )" />
|
||||
</g>
|
||||
</svg>
|
||||
BIN
src/assets/img/publicImage/reopen-icon.png
Normal file
BIN
src/assets/img/publicImage/reopen-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.3 KiB |
6
src/assets/img/publicImage/star-half.svg
Normal file
6
src/assets/img/publicImage/star-half.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="18px" height="18px" xmlns="http://www.w3.org/2000/svg">
|
||||
<g transform="matrix(1 0 0 1 -1980 -943 )">
|
||||
<path d="M 12.2992788461538 11.0245746691871 L 12.8293269230769 10.4914933837429 L 15.609375 7.65595463137996 L 11.7584134615385 7.06616257088847 L 11.0444711538462 6.95274102079395 L 10.7199519230769 6.27221172022684 L 9 2.62003780718336 L 9 13.5425330812854 L 9.63822115384615 13.8941398865785 L 13.078125 15.7996219281664 L 12.4290865384615 11.773156899811 L 12.2992788461538 11.0245746691871 Z M 17.9783653846154 6.84499054820416 C 18.0432692307692 7.05293005671077 17.9567307692308 7.27788279773157 17.71875 7.51984877126654 L 13.7920673076923 11.5349716446125 L 14.7223557692308 17.2060491493384 C 14.7584134615385 17.4555765595463 14.7367788461538 17.6502835538752 14.6574519230769 17.7901701323251 C 14.578125 17.930056710775 14.4555288461538 18 14.2896634615385 18 C 14.1670673076923 18 14.0228365384615 17.9546313799622 13.8569711538462 17.8638941398866 L 9 15.187145557656 L 4.14302884615385 17.8638941398866 C 3.97716346153846 17.9546313799622 3.83293269230769 18 3.71033653846154 18 C 3.54447115384615 18 3.421875 17.930056710775 3.34254807692308 17.7901701323251 C 3.26322115384615 17.6502835538752 3.24158653846154 17.4555765595463 3.27764423076923 17.2060491493384 L 4.20793269230769 11.5349716446125 L 0.270432692307692 7.51984877126654 C 0.0396634615384615 7.27788279773157 -0.0432692307692308 7.05293005671077 0.0216346153846154 6.84499054820416 C 0.0865384615384615 6.63705103969754 0.28125 6.50661625708885 0.605769230769231 6.45368620037807 L 6.03605769230769 5.62570888468809 L 8.46995192307692 0.465028355387523 C 8.61418269230769 0.15500945179584 8.79086538461539 0 9 0 C 9.20192307692308 0 9.37860576923077 0.15500945179584 9.53004807692308 0.465028355387523 L 11.9639423076923 5.62570888468809 L 17.3942307692308 6.45368620037807 C 17.71875 6.50661625708885 17.9134615384615 6.63705103969754 17.9783653846154 6.84499054820416 Z " fill-rule="nonzero" fill="#fddf6d" stroke="none" transform="matrix(1 0 0 1 1980 943 )" />
|
||||
</g>
|
||||
</svg>
|
||||
6
src/assets/img/publicImage/star-icon.svg
Normal file
6
src/assets/img/publicImage/star-icon.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="18px" height="18px" xmlns="http://www.w3.org/2000/svg">
|
||||
<g transform="matrix(1 0 0 1 -1957 -943 )">
|
||||
<path d="M 17.3942307692308 6.45368620037807 C 17.7980769230769 6.52173913043478 18 6.69565217391304 18 6.97542533081285 C 18 7.14177693761815 17.90625 7.32325141776937 17.71875 7.51984877126654 L 13.7920673076923 11.5349716446125 L 14.7223557692308 17.2060491493384 C 14.7295673076923 17.2589792060492 14.7331730769231 17.3345935727788 14.7331730769231 17.4328922495274 C 14.7331730769231 17.5916824196597 14.6953125 17.7258979206049 14.6195913461538 17.8355387523629 C 14.5438701923077 17.945179584121 14.4338942307692 18 14.2896634615385 18 C 14.1526442307692 18 14.0084134615385 17.9546313799622 13.8569711538462 17.8638941398866 L 9 15.187145557656 L 4.14302884615385 17.8638941398866 C 3.984375 17.9546313799622 3.84014423076923 18 3.71033653846154 18 C 3.55889423076923 18 3.4453125 17.945179584121 3.36959134615385 17.8355387523629 C 3.29387019230769 17.7258979206049 3.25600961538462 17.5916824196597 3.25600961538462 17.4328922495274 C 3.25600961538462 17.3875236294896 3.26322115384615 17.3119092627599 3.27764423076923 17.2060491493384 L 4.20793269230769 11.5349716446125 L 0.270432692307692 7.51984877126654 C 0.0901442307692308 7.31568998109641 0 7.13421550094518 0 6.97542533081285 C 0 6.69565217391304 0.201923076923077 6.52173913043478 0.605769230769231 6.45368620037807 L 6.03605769230769 5.62570888468809 L 8.46995192307692 0.465028355387523 C 8.60697115384616 0.15500945179584 8.78365384615385 0 9 0 C 9.21634615384615 0 9.39302884615385 0.15500945179584 9.53004807692308 0.465028355387523 L 11.9639423076923 5.62570888468809 L 17.3942307692308 6.45368620037807 Z " fill-rule="nonzero" fill="#fddf6d" stroke="none" transform="matrix(1 0 0 1 1957 943 )" />
|
||||
</g>
|
||||
</svg>
|
||||
16
src/assets/img/publicImage/wechat-pop-green.svg
Normal file
16
src/assets/img/publicImage/wechat-pop-green.svg
Normal file
@@ -0,0 +1,16 @@
|
||||
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" version="1.1" width="292px" height="149px">
|
||||
<defs>
|
||||
<linearGradient gradientUnits="userSpaceOnUse" x1="150" y1="0" x2="150" y2="160" id="LinearGradient1149">
|
||||
<stop id="Stop1150" stop-color="#50e3c2" stop-opacity="0.498039215686275" offset="0"/>
|
||||
<stop id="Stop1151" stop-color="#ffffff" offset="1"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g transform="matrix(1 0 0 1 0 -150)">
|
||||
<!-- 白色箭头(置于下层) -->
|
||||
<path d="M 0 0 L 10 10 L 20 0 Z" fill="#ffffff" transform="translate(140, 289)"/>
|
||||
<!-- 原有渐变图形(置于上层,覆盖下层箭头重合部分) -->
|
||||
<path d="M 292 19 L 292 132 C 292 136.48 288.48 140 284 140 L 160 140 L 150 150 L 140 140 L 8 140 C 3.52 140 0 136.48 0 132 L 0 19 C 0 19 65.55 1.07 149 1 C 233.55 0.93 292 19 292 19 Z" fill-rule="nonzero" fill="url(#LinearGradient1149)" stroke="none" transform="matrix(1 0 0 1 0 150)"/>
|
||||
<!-- 底部箭头(置于最上层,避免被覆盖) -->
|
||||
|
||||
</g>
|
||||
</svg>
|
||||
@@ -1,7 +1,8 @@
|
||||
<template>
|
||||
<div class="date" v-if="item.timeText">{{ item.timeText }}</div>
|
||||
<div class="right message" v-if="item.role == 'user'">{{ item.content }}</div>
|
||||
<div class="left" :class="{ error: item.iserror }" v-if="item.role == 'assistant'">
|
||||
<div class="right message" :id="`item${item.id}`" v-if="item.role == 'user'">{{ item.content }}</div>
|
||||
|
||||
<div class="left" :id="`item${item.id}`" :class="{ error: item.iserror }" v-if="item.role == 'assistant'">
|
||||
<div class="loading-container" v-if="item.loading">
|
||||
<div class="loading-item" style="--i: 0"></div>
|
||||
<div class="loading-item" style="--i: 1"></div>
|
||||
@@ -11,15 +12,15 @@
|
||||
<div class="loading-item" style="--i: 5"></div>
|
||||
<span class="text">圆同学正为您努力找房中</span>
|
||||
</div>
|
||||
<template v-if="item.payload.type == 'recommendation'">
|
||||
<template v-if="item?.payload?.type == 'recommendation'">
|
||||
<div class="intro">{{ item.payload.intro }}</div>
|
||||
<div class="point">一、推荐房源</div>
|
||||
<div class="point-item" v-for="(item, ii) in item.payload.recommendations" :key="ii">
|
||||
<a class="title flexacenter" url="{{ item.url }}">
|
||||
<a class="title flexacenter" :href="item.listing_url" target="_blank">
|
||||
<div class="serial flexcenter">{{ ii + 1 }}</div>
|
||||
<div class="name one-line-display">{{ item.name }}</div>
|
||||
<div class="full">已租满</div>
|
||||
<img class="arrows" src="https://app.gter.net/image/miniApp/HKRenting/arrow-circular-orange-red.svg" />
|
||||
<div class="full" v-if="!item.is_rentable">已租满</div>
|
||||
<img class="arrows" src="@/assets/img/publicImage/arrow-circular-orange-red.svg" />
|
||||
</a>
|
||||
<div class="spot flexflex">
|
||||
<div class="dot"></div>
|
||||
@@ -45,8 +46,9 @@
|
||||
<div class="dot"></div>
|
||||
<div class="star-box flex1 flexacenter">
|
||||
<span class="spot-title">推荐星级:</span>
|
||||
<img v-for="item in item.score" :key="item" class="star-item" src="https://app.gter.net/image/miniApp/HKRenting/star-icon.svg" />
|
||||
<img v-if="item.scoreHalf" class="star-item" src="https://app.gter.net/image/miniApp/HKRenting/star-half.svg" />
|
||||
<img v-for="item in item.score" :key="item" class="star-item" src="@/assets/img/publicImage/star-icon.svg" />
|
||||
|
||||
<img v-if="item.scoreHalf" class="star-item" src="@/assets/img/publicImage//star-half.svg" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="spot flexflex" wx:if="{{ item.recommendation_reason }}">
|
||||
@@ -55,7 +57,7 @@
|
||||
</div>
|
||||
<div class="spot" v-if="item.images.length > 0">
|
||||
<div class="scroll-view">
|
||||
<img class="img" v-for="(source, index) in item.images" :key="index" :src="source" />
|
||||
<img class="img" @click="openImageShow(item.images, index)" v-for="(source, index) in item.images" :key="index" :src="source" alt="图片" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -75,18 +77,24 @@
|
||||
</template>
|
||||
<div class="ai-hint">内容由AI生成,请审慎参考</div>
|
||||
</template>
|
||||
<div v-else-if="item.payload.type == 'text' && item.payload.message.before">
|
||||
{{ item.payload.message.before }}<span class="text link" bind:tap="consultStateCut" v-if="item.payload.message.wechat">{{ item.payload.message.wechat }}</span
|
||||
>{{ item.payload.message.after }}
|
||||
<div v-else-if="item?.payload?.type == 'text' && item?.payload?.message?.before">
|
||||
{{ item.payload.message.before }}<span class="text link" bind:tap="consultStateCut" v-if="item.payload.message.wechat">
|
||||
<wechat-btn>{{ item.payload.message.wechat }}</wechat-btn>
|
||||
</span>{{ item.payload.message.after }}
|
||||
</div>
|
||||
<div v-else>{{ item.payload.message || item.message }}</div>
|
||||
<div v-else>{{ item?.payload?.message || item.message }}</div>
|
||||
</div>
|
||||
<Contacts v-if="item.role == 'contacts'"></Contacts>
|
||||
|
||||
<image-watch arrow="never" :index="imageIndex" v-if="imageShow" :close="cloaseImageShow" :list="imageList"></image-watch>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, onMounted, ref, nextTick, onBeforeUnmount, watch } from "vue";
|
||||
import Contacts from "./contacts.vue";
|
||||
import imageWatch from "@/components/detail/imageWatch.vue";
|
||||
import wechatBtn from "@/components/ai/wechat-btn.vue";
|
||||
|
||||
|
||||
const props = defineProps({
|
||||
item: {
|
||||
@@ -94,6 +102,30 @@ const props = defineProps({
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
|
||||
let imageShow = ref(false); // 查看大图弹窗的状态
|
||||
let imageList = ref([]); // 查看大图弹窗的状态
|
||||
let imageIndex = ref(0); // 查看大图弹窗的状态
|
||||
const openImageShow = (list, index) => {
|
||||
console.log("list", list);
|
||||
let arr = [];
|
||||
list.forEach((item) => {
|
||||
arr.push({
|
||||
imageurl: item,
|
||||
thumbnail: item,
|
||||
type: "attachment",
|
||||
});
|
||||
});
|
||||
imageList.value = arr;
|
||||
imageIndex.value = index;
|
||||
|
||||
imageShow.value = !imageShow.value;
|
||||
};
|
||||
|
||||
const cloaseImageShow = () => {
|
||||
imageShow.value = false;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@@ -114,6 +146,7 @@ const props = defineProps({
|
||||
margin-left: auto;
|
||||
margin-bottom: 30px;
|
||||
font-family: "PingFangSC-Regular", "PingFang SC", sans-serif;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.left {
|
||||
@@ -122,6 +155,12 @@ const props = defineProps({
|
||||
font-size: 16px;
|
||||
line-height: 26px;
|
||||
font-family: "PingFangSC-Regular", "PingFang SC", sans-serif;
|
||||
word-break: break-word;
|
||||
&.error {
|
||||
color: #f84b37;
|
||||
// border: 1rpx solid rgba(255, 204, 198, 1);
|
||||
// background-color: rgba(255, 242, 240, 1);
|
||||
}
|
||||
|
||||
.loading-container {
|
||||
display: inline-flex;
|
||||
@@ -322,6 +361,7 @@ const props = defineProps({
|
||||
border-radius: 10px;
|
||||
object-fit: cover;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
<template>
|
||||
<div class="contacts">
|
||||
如需进一步了解具体房源信息,或香港租房生活相关问题,请添加方同学微信:
|
||||
<div class="text link" bind:tap="consultStateCut">gternet2</div>
|
||||
<div class="text link">
|
||||
<wechat-btn>gternet2</wechat-btn>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import wechatBtn from "@/components/ai/wechat-btn.vue";
|
||||
|
||||
const consultState = ref(false);
|
||||
|
||||
const consultStateCut = () => {
|
||||
consultState.value = true;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
167
src/components/ai/wechat-btn.vue
Normal file
167
src/components/ai/wechat-btn.vue
Normal file
@@ -0,0 +1,167 @@
|
||||
<template>
|
||||
<div class="circle-btn flexcenter">
|
||||
<div @click="circleState = !circleState">
|
||||
<slot></slot>
|
||||
</div>
|
||||
<div class="circle-pop flexacenter" v-if="circleState">
|
||||
<img class="close-icon" src="@/assets/img/publicImage/circle-close.png" alt="" @click.stop="circleState = !circleState" />
|
||||
<!-- <img class="circle-bj" src="@/assets/img/publicImage/circle-pop-bj.svg"> -->
|
||||
<img class="circle-bj-green" src="@/assets/img/publicImage/wechat-pop-green.svg" />
|
||||
<div class="circle-title flexacenter">
|
||||
欢迎联系 <b>{{ wechat["nickname"] }}</b> 咨询公寓
|
||||
</div>
|
||||
<div class="circle-QRcode flexcenter">
|
||||
<img class="circle-QRcode-img" :src="wechat['personalqrcode']" />
|
||||
</div>
|
||||
<div class="circle-hint">微信扫码添加好友</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, toRefs } from "vue";
|
||||
import { useStore } from "vuex";
|
||||
const store = useStore();
|
||||
const { wechat } = toRefs(store.state);
|
||||
|
||||
let circleState = ref(false);
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
// @media screen and (max-width: 1360px) {
|
||||
// .circle-btn {
|
||||
// right: 20px !important;
|
||||
// }
|
||||
// }
|
||||
|
||||
.circle-btn {
|
||||
position: relative;
|
||||
// position: fixed;
|
||||
// bottom: 158px;
|
||||
// right: calc((100vw - 1200px) / 2 - 75px);
|
||||
|
||||
// width: 60px;
|
||||
// height: 60px;
|
||||
// background-color: #50e3c2;
|
||||
// border-radius: 50%;
|
||||
// cursor: pointer;
|
||||
// z-index: 10000;
|
||||
|
||||
.circle-inside {
|
||||
flex-direction: column;
|
||||
background-color: #cbf7ed;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
color: #000;
|
||||
font-size: 14px;
|
||||
|
||||
.circle-bj {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.circle-icon {
|
||||
width: 20px;
|
||||
height: 17px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.circle-pop {
|
||||
position: absolute;
|
||||
bottom: 45px;
|
||||
// right: 65px;
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
border-radius: 10px;
|
||||
flex-direction: column;
|
||||
z-index: 1100;
|
||||
padding-top: 45px;
|
||||
font-family: "PingFangSC-Regular", "PingFang SC", sans-serif;
|
||||
// -moz-box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.101960784313725);
|
||||
// -webkit-box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.101960784313725);
|
||||
// box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.101960784313725);
|
||||
background-color: #fff;
|
||||
filter: drop-shadow(0px 0px 10px rgba(0, 0, 0, 0.50196078));
|
||||
.close-icon {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 10px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.circle-bj {
|
||||
position: absolute;
|
||||
top: -15px;
|
||||
left: -15px;
|
||||
width: 341px;
|
||||
height: 336px;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.circle-bj-green {
|
||||
width: 300px;
|
||||
// height: 156px;
|
||||
position: absolute;
|
||||
bottom: -9.5px;
|
||||
left: 0;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.circle-title {
|
||||
font-size: 15px;
|
||||
color: #555555;
|
||||
margin-bottom: 24px;
|
||||
|
||||
b {
|
||||
color: #000;
|
||||
font-weight: 650;
|
||||
margin: 0 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.circle-QRcode {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
border-radius: 20px;
|
||||
-moz-box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.101960784313725);
|
||||
-webkit-box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.101960784313725);
|
||||
box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.101960784313725);
|
||||
margin-bottom: 20px;
|
||||
background: #fff;
|
||||
|
||||
.circle-QRcode-img {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
.circle-hint {
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.circle-hint,
|
||||
.circle-remark {
|
||||
font-size: 13px;
|
||||
color: #555555;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.circle-remark {
|
||||
b {
|
||||
font-weight: 650;
|
||||
color: #000000;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -90,21 +90,21 @@ watchEffect(() => {
|
||||
user.data = store.state.user;
|
||||
// bannerLists.data = props.bannerList
|
||||
if (!store.state.indexData.menu) return;
|
||||
store.state.indexData.menu.map((res) => {
|
||||
if (res.name === "首页") {
|
||||
res.path = "/";
|
||||
} else if (res.name === "个人房源") {
|
||||
res.path = "/personHousing";
|
||||
} else if (res.name === "中介房源") {
|
||||
res.path = "/intermediaryHousing";
|
||||
} else if (res.name === "品牌公寓") {
|
||||
res.path = "/apartment";
|
||||
} else if (res.name === "求房源") {
|
||||
res.path = "/needHousing";
|
||||
} else if (res.name === "我的") {
|
||||
res.path = "/user";
|
||||
}
|
||||
});
|
||||
// store.state.indexData.menu.map((res) => {
|
||||
// if (res.name === "首页") {
|
||||
// res.path = "/";
|
||||
// } else if (res.name === "个人房源") {
|
||||
// res.path = "/personHousing";
|
||||
// } else if (res.name === "中介房源") {
|
||||
// res.path = "/intermediaryHousing";
|
||||
// } else if (res.name === "品牌公寓") {
|
||||
// res.path = "/apartment";
|
||||
// } else if (res.name === "求房源") {
|
||||
// res.path = "/needHousing";
|
||||
// } else if (res.name === "我的") {
|
||||
// res.path = "/user";
|
||||
// }
|
||||
// });
|
||||
seachTab.data = store.state.indexData.menu;
|
||||
topTab.data = store.state.indexData.nav;
|
||||
});
|
||||
|
||||
40
src/mock/mock-api.js
Normal file
40
src/mock/mock-api.js
Normal file
@@ -0,0 +1,40 @@
|
||||
const express = require("express");
|
||||
const app = express();
|
||||
app.use(express.json());
|
||||
|
||||
// 模拟POST请求接口/api/v1/chat
|
||||
app.post("/api/v1/chat", (req, res) => {
|
||||
res.json({
|
||||
history: [
|
||||
{
|
||||
content: "您好啊!我是寄托香港租房的AI找房助手圆同学,只要您告诉我以下信息中的任意两样:预算范围、位置(比如哪所学校附近)、房间类型(比如单人间、双人间等),我就可以为您找房啦!因为我还是初代智能体,只能根据上述要求提供找房服务哦。",
|
||||
id: "812ede61-1524-440a-9035-356e3dd94c95",
|
||||
payload: {
|
||||
message: "您好啊!我是寄托香港租房的AI找房助手圆同学,只要您告诉我以下信息中的任意两样:预算范围、位置(比如哪所学校附近)、房间类型(比如单人间、双人间等),我就可以为您找房啦!因为我还是初代智能体,只能根据上述要求提供找房服务哦。",
|
||||
type: "text",
|
||||
},
|
||||
role: "assistant",
|
||||
timestamp: "2025-08-25T10:40:21.445827+08:00",
|
||||
},
|
||||
{ content: "ffffff", id: "4856fc38-3489-4478-9577-7d9bfc9d43f8", payload: null, role: "user", timestamp: "2025-08-25T10:49:13.557769+08:00" },
|
||||
{
|
||||
content: "目前我只能提供找房服务,只要您告诉我以下信息中的任意两样:预算范围、位置(比如哪所学校附近)、房间类型(比如单人间、双人间等),我就可以为您找房啦!其他问题可以找方同学:<wechat>gternet2</wechat>。",
|
||||
id: "37d0b325-a3dd-4cf1-8989-59f76180761b",
|
||||
payload: {
|
||||
message: "目前我只能提供找房服务,只要您告诉我以下信息中的任意两样:预算范围、位置(比如哪所学校附近)、房间类型(比如单人间、双人间等),我就可以为您找房啦!其他问题可以找方同学:<wechat>gternet2</wechat>。",
|
||||
type: "text",
|
||||
},
|
||||
role: "assistant",
|
||||
timestamp: "2025-08-25T10:49:13.558771+08:00",
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
// 启动服务器
|
||||
const PORT = 3000;
|
||||
app.listen(PORT, () => {
|
||||
console.log(`Mock server running on port ${PORT}`);
|
||||
});
|
||||
|
||||
// 提示:需要先安装express依赖,运行npm install express
|
||||
@@ -53,10 +53,10 @@ export default{
|
||||
return axios.post('https://api.gter.net/v1/chat/history',params)
|
||||
},
|
||||
alChat:(params={})=>{// AI 发送信息
|
||||
return axios.post('https://fangchat.x-php.com/api/v1/chat',params)
|
||||
return axios.postV2('https://fangchat.x-php.com/api/v1/chat',params)
|
||||
},
|
||||
alResume:(params={})=>{// AI 恢复会话
|
||||
return axios.post('https://fangchat.x-php.com/api/v1/chat/resume',params)
|
||||
return axios.postV2('https://fangchat.x-php.com/api/v1/chat/resume',params)
|
||||
},
|
||||
alEnd:(params={})=>{// AI 结束会话
|
||||
return axios.post('https://api.gter.net/v1/chat/end',params)
|
||||
|
||||
@@ -1,69 +1,68 @@
|
||||
import axios from "axios"
|
||||
import QS from "qs"
|
||||
import { goTologin } from "@/utils/util.js"
|
||||
import { showFullScreenLoading, tryHideFullScreenLoading } from "./loading"
|
||||
import store from "@/store/index"
|
||||
import axios from "axios";
|
||||
import QS from "qs";
|
||||
import { goTologin } from "@/utils/util.js";
|
||||
import { showFullScreenLoading, tryHideFullScreenLoading } from "./loading";
|
||||
import store from "@/store/index";
|
||||
|
||||
axios.defaults.baseURL = "https://app.gter.net"
|
||||
axios.defaults.emulateJSON = true
|
||||
axios.defaults.withCredentials = true
|
||||
// content-type 为 multipart/form-data
|
||||
axios.defaults.baseURL = "https://app.gter.net";
|
||||
axios.defaults.emulateJSON = true;
|
||||
axios.defaults.withCredentials = true;
|
||||
// axios.defaults.headers["Content-Type"] = "application/json";
|
||||
axios.interceptors.request.use(
|
||||
//响应拦截
|
||||
async config => {
|
||||
async (config) => {
|
||||
// 不需要遮罩
|
||||
let noMask = false
|
||||
let noMask = false;
|
||||
|
||||
|
||||
if (config.method == "get") noMask = config.params?.noMask || false
|
||||
noMask = config.params?.noMask || config.noMask || false;
|
||||
|
||||
if (config.url != "/tenement/pc/api/user/operation" && !noMask) showFullScreenLoading()
|
||||
if (config.url != "/tenement/pc/api/user/operation" && !noMask) showFullScreenLoading();
|
||||
// 开发时登录用的,可以直接替换小程序的 authorization
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
const miucms_session = "01346a38444d71aaadb3adad52b52c39";
|
||||
document.cookie = "miucms_session=" + miucms_session;
|
||||
config["headers"]["authorization"] = miucms_session;
|
||||
}
|
||||
|
||||
// 当 noMask == true 和 confing.method == 'get' 时,删除 config.params['noMask']
|
||||
if (noMask && config.method == "get") delete config.params["noMask"]
|
||||
|
||||
return config
|
||||
// 当 noMask == true 和 confing.method == 'get' 时,删除 config.params['noMask']
|
||||
if (noMask && config.params) delete config.params["noMask"];
|
||||
|
||||
return config;
|
||||
},
|
||||
error => {
|
||||
return Promise.error(error)
|
||||
(error) => {
|
||||
return Promise.error(error);
|
||||
}
|
||||
)
|
||||
);
|
||||
// 响应拦截器
|
||||
axios.interceptors.response.use(
|
||||
response => {
|
||||
tryHideFullScreenLoading()
|
||||
if (response.status === 200) return Promise.resolve(response) //进行中
|
||||
else return Promise.reject(response) //失败
|
||||
(response) => {
|
||||
tryHideFullScreenLoading();
|
||||
if (response.status === 200) return Promise.resolve(response); //进行中
|
||||
else return Promise.reject(response); //失败
|
||||
},
|
||||
// 服务器状态码不是200的情况
|
||||
error => {
|
||||
tryHideFullScreenLoading()
|
||||
(error) => {
|
||||
tryHideFullScreenLoading();
|
||||
if (error.response.status) {
|
||||
switch (error.response.status) {
|
||||
// 401: 未登录
|
||||
case 401:
|
||||
// goTologin() // 跳转登录页面
|
||||
store.state.showloginmodal = true
|
||||
break
|
||||
store.state.showloginmodal = true;
|
||||
break;
|
||||
case 403:
|
||||
// router.push('/login')
|
||||
break
|
||||
break;
|
||||
// 404请求不存在
|
||||
case 404:
|
||||
break
|
||||
break;
|
||||
// 其他错误,直接抛出错误提示
|
||||
default:
|
||||
}
|
||||
return Promise.reject(error.response)
|
||||
return Promise.reject(error.response);
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
/**
|
||||
* get方法,对应get请求
|
||||
* @param {String} url [请求的url地址]
|
||||
@@ -75,14 +74,14 @@ const $get = (url, params) => {
|
||||
.get(url, {
|
||||
params: params,
|
||||
})
|
||||
.then(res => {
|
||||
resolve(res.data)
|
||||
.then((res) => {
|
||||
resolve(res.data);
|
||||
})
|
||||
.catch(err => {
|
||||
reject(err.data)
|
||||
})
|
||||
})
|
||||
}
|
||||
.catch((err) => {
|
||||
reject(err.data);
|
||||
});
|
||||
});
|
||||
};
|
||||
/**
|
||||
* post方法,对应post请求
|
||||
* @param {String} url [请求的url地址]
|
||||
@@ -93,23 +92,40 @@ const $post = (url, params) => {
|
||||
//是将对象 序列化成URL的形式,以&进行拼接
|
||||
axios
|
||||
.post(url, QS.stringify(params))
|
||||
.then(res => {
|
||||
resolve(res.data)
|
||||
.then((res) => {
|
||||
resolve(res.data);
|
||||
})
|
||||
.catch(err => {
|
||||
if (err.data.code == 401) resolve(err.data)
|
||||
else reject(err.data)
|
||||
.catch((err) => {
|
||||
if (err.data.code == 401) resolve(err.data);
|
||||
else reject(err.data);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const $postV2 = (url, params) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
console.log("params", params);
|
||||
|
||||
axios
|
||||
.post(url, JSON.stringify(params), { headers: { "Content-Type": "application/json" }, timeout: 100000, ...(params.noMask !== undefined ? { noMask: params.noMask } : {}) })
|
||||
.then((res) => {
|
||||
resolve(res.data);
|
||||
})
|
||||
})
|
||||
}
|
||||
.catch((err) => {
|
||||
if (err.data.code == 401) resolve(err.data);
|
||||
else reject(err.data);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
//下面是vue3必须加的,vue2不需要,只需要暴露出去get,post方法就可以
|
||||
export default {
|
||||
get: $get,
|
||||
post: $post,
|
||||
install: app => {
|
||||
app.config.globalProperties["$get"] = $get
|
||||
app.config.globalProperties["$post"] = $post
|
||||
app.config.globalProperties["$axios"] = axios
|
||||
postV2: $postV2,
|
||||
install: (app) => {
|
||||
app.config.globalProperties["$get"] = $get;
|
||||
app.config.globalProperties["$post"] = $post;
|
||||
app.config.globalProperties["$axios"] = axios;
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
487
src/views/ai.vue
487
src/views/ai.vue
@@ -2,7 +2,7 @@
|
||||
<div class="main">
|
||||
<header class="header flexacenter">
|
||||
<div class="title">寄托AI找房</div>
|
||||
<div class="logo flex1 flexacenter">
|
||||
<div class="logo flexacenter">
|
||||
<img class="icon" src="../assets/img/publicImage/round-icon.gif" />
|
||||
圆同学
|
||||
</div>
|
||||
@@ -24,14 +24,20 @@
|
||||
<div class="history-line history-right"></div>
|
||||
</div>
|
||||
|
||||
<AiItem v-for="(item, index) in list" :key="index" :item="item"></AiItem>
|
||||
<AiItem v-for="(item, index) in list" :key="item.id" :item="item"></AiItem>
|
||||
|
||||
<!-- fixed -->
|
||||
<div class="input-box fixed">
|
||||
<div class="input">
|
||||
<textarea class="input-text" placeholder="请输入" @input="autoResize"></textarea>
|
||||
<div class="send pitch flexcenter">
|
||||
<img class="icon" src="../assets/img/publicImage/arrows-deep-white.svg" />
|
||||
<textarea class="input-text" placeholder="请输入" @input="handleInput" v-model="input" @keyup.enter.prevent="send()" ref="inputRef" maxlength="100"></textarea>
|
||||
<div class="input-bottom flexacenter">
|
||||
<div class="restart flexcenter" @click="restartAffirm">
|
||||
<img class="icon" src="@/assets/img/publicImage/reopen-icon.png" />
|
||||
<div class="text">新开会话</div>
|
||||
</div>
|
||||
<div class="send flexcenter" :class="{ pitch: input.length > 0 }" @click="send()">
|
||||
<img class="icon" src="../assets/img/publicImage/arrows-deep-white.svg" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -40,15 +46,45 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, onMounted, ref, nextTick, onBeforeUnmount, watch } from "vue";
|
||||
import { reactive, onMounted, ref, nextTick, onBeforeUnmount, watch, getCurrentInstance, onUnmounted } from "vue";
|
||||
import api from "../utils/api";
|
||||
import store from "@/store/index";
|
||||
import AiItem from "../components/ai/aiItem.vue";
|
||||
import Contacts from "../components/ai/contacts.vue";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
// 处理输入内容,去除末尾换行符
|
||||
const handleInput = (e) => {
|
||||
input.value = input.value.replace(/\n+$/, "");
|
||||
autoResize();
|
||||
};
|
||||
|
||||
// 全局滚动到顶部监听函数
|
||||
const handleScrollToTop = () => {
|
||||
const isAtTop = window.scrollY === 0;
|
||||
if (isAtTop) {
|
||||
console.log("页面已滚动到顶部");
|
||||
// 这里可以添加滚动到顶部后的业务逻辑
|
||||
getHistory();
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
console.log("onMounted");
|
||||
init();
|
||||
|
||||
document.addEventListener("visibilitychange", handleVisibilityChange);
|
||||
window.addEventListener("beforeunload", endChat);
|
||||
window.addEventListener("scroll", handleScrollToTop);
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
// 移除全局滚动事件监听
|
||||
window.removeEventListener("scroll", handleScrollToTop);
|
||||
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
||||
window.removeEventListener("beforeunload", endChat);
|
||||
});
|
||||
|
||||
let initState = false;
|
||||
@@ -94,21 +130,26 @@ const scrollEnd = async () => {
|
||||
// 1. 获取当前水平滚动位置
|
||||
const currentX = window.pageXOffset;
|
||||
// 2. 设置新的滚动位置:水平位置不变,垂直滚动到 500px 处
|
||||
window.scrollTo(currentX, 100000);
|
||||
window.scrollTo(currentX, 1000000);
|
||||
});
|
||||
};
|
||||
|
||||
// 滚动到指定位置
|
||||
const scrollItem = (id) => {
|
||||
nextTick(() => {
|
||||
const element = contentRef.value.querySelector(`[data-id="${id}"]`);
|
||||
if (element) {
|
||||
element.scrollIntoView({
|
||||
behavior: "smooth",
|
||||
block: "center",
|
||||
});
|
||||
}
|
||||
});
|
||||
console.log("id", id);
|
||||
|
||||
const element = contentRef.value.querySelector(`#item${id}`);
|
||||
console.log("element", element);
|
||||
|
||||
if (element) {
|
||||
// 计算元素顶部位置并减去50px偏移
|
||||
const rect = element.getBoundingClientRect();
|
||||
const top = rect.top + window.pageYOffset - 60;
|
||||
window.scrollTo({
|
||||
top: top,
|
||||
behavior: "smooth",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
let page = 1;
|
||||
@@ -128,34 +169,53 @@ const getHistory = () => {
|
||||
api.alHistory({
|
||||
page,
|
||||
limit,
|
||||
}).then((res) => {
|
||||
console.log(res);
|
||||
if (res.code != 200) return;
|
||||
let data = res.data || {};
|
||||
// data.count = 0
|
||||
// data.history = []
|
||||
let history = data.history || [];
|
||||
history.reverse();
|
||||
})
|
||||
.then((res) => {
|
||||
console.log(res);
|
||||
if (res.code != 200) return;
|
||||
let data = res.data || {};
|
||||
// data.count = 0
|
||||
// data.history = []
|
||||
let history = data.history || [];
|
||||
history.reverse();
|
||||
|
||||
history = history.concat(historyList.value);
|
||||
history = history.concat(historyList.value);
|
||||
|
||||
history = calculateRecordTimeText(history);
|
||||
history = calculateRecordTimeText(history);
|
||||
|
||||
if (history.length > 0 && page == 1) {
|
||||
let obj = historyObj || {};
|
||||
list.value.push(obj);
|
||||
}
|
||||
if (history.length > 0 && page == 1) {
|
||||
let obj = historyObj || {};
|
||||
list.value.push(obj);
|
||||
}
|
||||
|
||||
console.log("history", history);
|
||||
console.log("history", history);
|
||||
|
||||
historyList.value = history;
|
||||
isLogo.value = history.length == 0 ? true : false;
|
||||
historyList.value = history;
|
||||
isLogo.value = history.length == 0 ? true : false;
|
||||
|
||||
if (page > 1) scrollItem(aiId);
|
||||
else scrollEnd();
|
||||
if (page > 1) {
|
||||
// scrollItem(aiId);
|
||||
const beforeScrollHeight = document.body.scrollHeight; // 加载前的总高度
|
||||
|
||||
page = data.page * limit >= data.count ? 0 : data.page + 1;
|
||||
});
|
||||
nextTick(() => {
|
||||
const afterScrollHeight = document.body.scrollHeight; // 加载后的总高度
|
||||
const heightDiff = afterScrollHeight - beforeScrollHeight;
|
||||
// container.scrollTop = heightDiff; // 关键:通过设置scrollTop抵消高度变化
|
||||
|
||||
window.scrollTo({
|
||||
top: heightDiff,
|
||||
// behavior: "smooth",
|
||||
});
|
||||
});
|
||||
} else scrollEnd();
|
||||
|
||||
data.page = data.page * 1;
|
||||
|
||||
page = data.page * limit >= data.count ? 0 : data.page + 1;
|
||||
})
|
||||
.finally(() => {
|
||||
loading = false;
|
||||
});
|
||||
};
|
||||
|
||||
let firstTimeStamp = null;
|
||||
@@ -182,10 +242,201 @@ const calculateRecordTimeText = (list = []) => {
|
||||
return list;
|
||||
};
|
||||
|
||||
let generateState = false;
|
||||
let input = ref("");
|
||||
|
||||
const send = () => {
|
||||
console.log("send");
|
||||
if (generateState) {
|
||||
ElMessage.error("生成中,请等待!");
|
||||
return;
|
||||
}
|
||||
|
||||
const inputValue = input.value;
|
||||
console.log("inputValue", inputValue);
|
||||
|
||||
if (!inputValue) {
|
||||
ElMessage.error("请输入内容");
|
||||
return;
|
||||
}
|
||||
|
||||
let listValue = list.value || [];
|
||||
|
||||
const arr = [
|
||||
{
|
||||
content: inputValue,
|
||||
role: "user",
|
||||
timestamp: getFormattedTime(),
|
||||
id: randomString(),
|
||||
},
|
||||
{
|
||||
role: "assistant",
|
||||
loading: true,
|
||||
timestamp: getFormattedTime(),
|
||||
id: randomString(),
|
||||
},
|
||||
];
|
||||
|
||||
listValue = listValue.concat(arr);
|
||||
listValue = calculateRecordTimeText(listValue);
|
||||
list.value = listValue;
|
||||
input.value = "";
|
||||
nextTick(() => autoResize());
|
||||
generateState = true;
|
||||
nextTick(() => scrollEnd());
|
||||
|
||||
api.alChat({
|
||||
session_id,
|
||||
message: inputValue,
|
||||
noMask: true,
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.detail) {
|
||||
chatError(listValue, inputValue, res.detail);
|
||||
return;
|
||||
}
|
||||
|
||||
let history = res.history || [];
|
||||
|
||||
let itemUser = history.findLast((item) => item.role === "user");
|
||||
listValue[listValue.length - 2] = Object.assign(listValue[listValue.length - 2], itemUser);
|
||||
|
||||
let itemAssis = history.findLast((item) => item.role === "assistant");
|
||||
console.log("history", history);
|
||||
|
||||
itemAssis = handleData(itemAssis);
|
||||
|
||||
let target = listValue.findLast((item) => item.role === "assistant");
|
||||
target = Object.assign(target, itemAssis);
|
||||
target["loading"] = false;
|
||||
|
||||
if (itemAssis?.payload?.type == "text") {
|
||||
let message = itemAssis?.payload?.message || "";
|
||||
if (message.includes("<wechat>")) {
|
||||
const startTag = "<wechat>";
|
||||
const endTag = "</wechat>";
|
||||
const startIndex = message.indexOf(startTag);
|
||||
const endIndex = message.indexOf(endTag);
|
||||
itemAssis.payload.message = {
|
||||
before: message.substring(0, startIndex),
|
||||
wechat: message.substring(startIndex + startTag.length, endIndex),
|
||||
after: message.substring(endIndex + endTag.length),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
listValue[listValue.length - 1] = target;
|
||||
|
||||
if (itemAssis?.payload?.type == "recommendation") {
|
||||
listValue.push({
|
||||
role: "contacts",
|
||||
timestamp: getFormattedTime(),
|
||||
});
|
||||
}
|
||||
|
||||
generateState = false;
|
||||
list.value = listValue;
|
||||
|
||||
// 强制更新组件
|
||||
// const instance = getCurrentInstance();
|
||||
|
||||
proxy.$forceUpdate();
|
||||
nextTick(() => scrollItem(itemUser.id));
|
||||
})
|
||||
.catch((err) => {
|
||||
chatError(listValue, inputValue);
|
||||
});
|
||||
};
|
||||
|
||||
// 处理数据
|
||||
const handleData = (obj) => {
|
||||
// 通用处理函数:检查数组每项是否有句号,无则补充,再用逗号连接
|
||||
const processArrayField = (array) => {
|
||||
if (!Array.isArray(array)) return array;
|
||||
return array
|
||||
.map((item) => {
|
||||
let trimmed = item.trim();
|
||||
if (!trimmed) return trimmed;
|
||||
if (trimmed.endsWith(";")) trimmed = trimmed.slice(0, -1) + "。";
|
||||
else if (!trimmed.endsWith("。")) trimmed += "。";
|
||||
return trimmed;
|
||||
})
|
||||
.join("");
|
||||
};
|
||||
|
||||
if (obj.payload?.recommendations?.length > 0) {
|
||||
const recommendations = obj.payload.recommendations;
|
||||
recommendations.forEach((element) => {
|
||||
element.advantages = processArrayField(element.advantages);
|
||||
element.disadvantages = processArrayField(element.disadvantages);
|
||||
|
||||
if (Array.isArray(element.district)) element.district = element.district.join("、");
|
||||
let url = `/apartmentDetail?uniqid=${element.uniqid}`;
|
||||
if (["person", "agent"].includes(element.type)) url = `/detail?id=${element.uniqid}`;
|
||||
console.log("url", url);
|
||||
|
||||
element["url"] = url;
|
||||
element["score"] = Math.floor(element.recommendation_score);
|
||||
element["scoreHalf"] = element.recommendation_score % 1 >= 0.5;
|
||||
if (element.images?.length > 0) element.images.forEach((ele, index) => (element.images[index] = `https://oss.x-php.com/${ele}`));
|
||||
});
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
|
||||
const chatError = (listValue, inputValue, hint) => {
|
||||
let target = listValue[listValue.length - 1];
|
||||
const obj = {
|
||||
type: "text",
|
||||
message: hint || "网络开小差了,圆同学现在很方,麻烦你再说一次吧",
|
||||
loading: false,
|
||||
iserror: true,
|
||||
id: randomString(),
|
||||
};
|
||||
|
||||
target = Object.assign(target, obj);
|
||||
|
||||
listValue[listValue.length - 1] = target;
|
||||
console.log("target", listValue);
|
||||
|
||||
generateState = false;
|
||||
list.value = [...listValue];
|
||||
input.value = inputValue;
|
||||
console.log(list.value);
|
||||
nextTick(() => autoResize());
|
||||
};
|
||||
|
||||
// 恢复会话
|
||||
const handleResume = () => {
|
||||
if (!session_id || !initState) return;
|
||||
api.alResume({ session_id }).then((res) => {
|
||||
console.log("res", res);
|
||||
});
|
||||
};
|
||||
|
||||
// 结束对话 上报历史
|
||||
const endChat = () => {
|
||||
let listValue = [...list.value];
|
||||
listValue = listValue.filter((item) => {
|
||||
return !("isHistory" in item) && item.role !== "contacts";
|
||||
});
|
||||
|
||||
api.alEnd({
|
||||
session_id,
|
||||
history: listValue,
|
||||
}).then((res) => {
|
||||
console.log("res", res);
|
||||
});
|
||||
};
|
||||
|
||||
let inputRef = ref(null);
|
||||
|
||||
// 自动输入框增高
|
||||
const autoResize = (e) => {
|
||||
e.target.style.height = "auto"; // 重置高度
|
||||
e.target.style.height = `${e.target.scrollHeight}px`; // 设置为内容高度
|
||||
console.log("inputRef", inputRef.value);
|
||||
|
||||
inputRef.value.style.height = "auto"; // 重置高度
|
||||
inputRef.value.style.height = `${inputRef.value.scrollHeight + 1}px`; // 设置为内容高度
|
||||
};
|
||||
|
||||
const getTimestamp = (time) => {
|
||||
@@ -193,6 +444,30 @@ const getTimestamp = (time) => {
|
||||
return new Date(time.replace(" ", "T")).getTime();
|
||||
};
|
||||
|
||||
// 输出类似 "2025-08-04T10:38:23.095600+08:00" 的字符串
|
||||
const getFormattedTime = () => {
|
||||
const date = new Date(); // 获取当前时间,也可传入时间戳指定时间
|
||||
|
||||
// 手动拼接带时区的ISO格式(保留6位毫秒)
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, "0"); // 月份从0开始
|
||||
const day = String(date.getDate()).padStart(2, "0");
|
||||
const hours = String(date.getHours()).padStart(2, "0");
|
||||
const minutes = String(date.getMinutes()).padStart(2, "0");
|
||||
const seconds = String(date.getSeconds()).padStart(2, "0");
|
||||
const milliseconds = String(date.getMilliseconds()).padStart(3, "0").padEnd(6, "0"); // 补全6位
|
||||
|
||||
// 获取时区偏移(分钟)并转换为 ±HH:MM 格式
|
||||
const timeZoneOffset = date.getTimezoneOffset();
|
||||
const offsetHours = Math.abs(Math.floor(timeZoneOffset / 60));
|
||||
const offsetMinutes = Math.abs(timeZoneOffset % 60);
|
||||
const offsetSign = timeZoneOffset > 0 ? "-" : "+";
|
||||
const formattedOffset = `${offsetSign}${String(offsetHours).padStart(2, "0")}:${String(offsetMinutes).padStart(2, "0")}`;
|
||||
|
||||
// 拼接最终格式
|
||||
return `${year}-${month}-${day}T${hours}:${minutes}:${seconds}.${milliseconds}${formattedOffset}`;
|
||||
};
|
||||
|
||||
// 加载历史消息(插入到列表顶部)
|
||||
const loadHistory = async () => {
|
||||
isLoading.value = true;
|
||||
@@ -251,6 +526,87 @@ const formatTimestamp = (timestamp) => {
|
||||
|
||||
return str;
|
||||
};
|
||||
|
||||
// 页面可见性状态(visible: 显示, hidden: 隐藏)
|
||||
const visibilityState = ref(document.visibilityState);
|
||||
// 上次状态变化时间
|
||||
const lastChangeTime = ref("");
|
||||
|
||||
// 处理可见性变化的函数
|
||||
const handleVisibilityChange = () => {
|
||||
// 更新状态
|
||||
visibilityState.value = document.visibilityState;
|
||||
// 记录时间
|
||||
lastChangeTime.value = new Date().toLocaleTimeString();
|
||||
|
||||
// 根据状态执行不同操作
|
||||
if (document.visibilityState === "visible") {
|
||||
console.log("页面已显示(用户切回标签页/窗口)");
|
||||
// 可执行恢复操作:如重新请求数据、播放视频等
|
||||
handleResume();
|
||||
} else {
|
||||
console.log("页面已隐藏(用户切换标签页/最小化窗口)");
|
||||
// 可执行暂停操作:如暂停视频、保存临时数据等
|
||||
endChat();
|
||||
}
|
||||
};
|
||||
|
||||
const randomString = () => {
|
||||
const random = Math.random().toString(36).substring(2);
|
||||
const timestamp = Date.now().toString(36);
|
||||
return random + timestamp;
|
||||
};
|
||||
|
||||
onUnmounted(() => {
|
||||
// 组件卸载时移除事件监听(避免内存泄漏)
|
||||
window.removeEventListener("beforeunload", endChat);
|
||||
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
||||
});
|
||||
|
||||
// 新开会话 确认
|
||||
const restartAffirm = () => {
|
||||
if (generateState) {
|
||||
ElMessage.error("生成中,请等待!");
|
||||
return;
|
||||
}
|
||||
ElMessageBox.confirm("您是否希望离开当前对话,并开始新的聊天?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
}).then(() => {
|
||||
endChat();
|
||||
restart();
|
||||
});
|
||||
};
|
||||
|
||||
// 新开会话
|
||||
const restart = () => {
|
||||
api.alNew().then((res) => {
|
||||
const data = res.data;
|
||||
let history = data.history || [];
|
||||
session_id = data.session_id;
|
||||
|
||||
let listValue = [...list.value] || [];
|
||||
|
||||
listValue = listValue.filter((item) => {
|
||||
return !("isHistory" in item) && item.role !== "contacts";
|
||||
});
|
||||
|
||||
historyList.value = historyList.value.concat(listValue);
|
||||
|
||||
let obj = historyObj || {};
|
||||
const target = history[0] || {};
|
||||
|
||||
obj["payload"] = target["payload"];
|
||||
obj["timestamp"] = target["timestamp"];
|
||||
obj["timeText"] = formatTimestamp(getTimestamp(target["timestamp"])) || "";
|
||||
|
||||
isLogo.value = false;
|
||||
list.value = [obj];
|
||||
|
||||
nextTick(() => scrollEnd());
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
@@ -267,6 +623,7 @@ const formatTimestamp = (timestamp) => {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
|
||||
.title {
|
||||
font-family: "PingFangSC-Semibold", "PingFang SC Semibold", "PingFang SC", sans-serif;
|
||||
@@ -303,7 +660,7 @@ const formatTimestamp = (timestamp) => {
|
||||
flex: 1;
|
||||
// background: aqua;
|
||||
flex-direction: column;
|
||||
padding-top: 50px;
|
||||
padding-top: 60px;
|
||||
padding-bottom: 150px;
|
||||
.logo {
|
||||
width: 110px;
|
||||
@@ -351,31 +708,47 @@ const formatTimestamp = (timestamp) => {
|
||||
max-height: 230px;
|
||||
}
|
||||
|
||||
.send {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
background-color: #d7d7d7;
|
||||
margin-left: auto;
|
||||
.input-bottom {
|
||||
margin-left: 10px;
|
||||
margin-right: 20px;
|
||||
margin-bottom: 15px;
|
||||
cursor: not-allowed;
|
||||
&.pitch {
|
||||
background-color: #7fddff;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
transform: rotate(270deg);
|
||||
margin-bottom: 15px;
|
||||
.restart {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
cursor: pointer;
|
||||
font-size: 10px;
|
||||
|
||||
.icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
}
|
||||
.send {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
background-color: #d7d7d7;
|
||||
margin-left: auto;
|
||||
cursor: not-allowed;
|
||||
&.pitch {
|
||||
background-color: #7fddff;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
transform: rotate(270deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.history-hint {
|
||||
font-size: 16px;
|
||||
font-size: 14px;
|
||||
line-height: 26px;
|
||||
color: #7f7f7f;
|
||||
text-align: center;
|
||||
|
||||
@@ -832,6 +832,8 @@ const cloaseImageShow = (list, index, type) => {
|
||||
imageIndex.value = index;
|
||||
imageType = type;
|
||||
}
|
||||
console.log(imageList.value);
|
||||
|
||||
imageShow.value = !imageShow.value;
|
||||
};
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@ import seachModule from "../../components/seachModule/seachModule1.vue"
|
||||
import biserialItem from "../../components/biserialListItem/biserialListItem.vue"
|
||||
import listBtmPrompt from "../../components/public/have-questions.vue"
|
||||
import noList from "../../components/public/empty-duck.vue"
|
||||
import circleBtn from "@/components/public/circle-btn.vue"
|
||||
import api from "../../utils/api"
|
||||
import tool from "../../toolJs/downLoadMore"
|
||||
import { ElMessage } from "element-plus"
|
||||
|
||||
@@ -33,7 +33,6 @@ import seachModule from "../../components/seachModule/seachModule1.vue"
|
||||
import biserialItem from "../../components/biserialListItem/biserialListItem.vue"
|
||||
import listBtmPrompt from "../../components/public/have-questions.vue"
|
||||
import noList from "../../components/public/empty-duck.vue"
|
||||
import circleBtn from "@/components/public/circle-btn.vue"
|
||||
import api from "../../utils/api"
|
||||
import tool from "../../toolJs/downLoadMore"
|
||||
import { ElMessage } from "element-plus"
|
||||
|
||||
@@ -34,7 +34,6 @@ import seachModule from "../../components/seachModule/seachModule1.vue"
|
||||
import biserialItem from "../../components/biserialListItem/biserialListItem.vue"
|
||||
import listBtmPrompt from "../../components/public/have-questions.vue"
|
||||
import noList from "../../components/public/empty-duck.vue"
|
||||
import circleBtn from "@/components/public/circle-btn.vue"
|
||||
import api from "../../utils/api"
|
||||
import tool from "../../toolJs/downLoadMore"
|
||||
import { useRouter } from "vue-router"
|
||||
|
||||
Reference in New Issue
Block a user