|
45 | 45 |
|
46 | 46 | <!-- 图片消息 --> |
47 | 47 | <div v-if="message.hasImage" class="message-image"> |
48 | | - <img |
49 | | - :src="message.image" |
50 | | - alt="用户上传图片" |
51 | | - @click="message.image && selectExistingImage(message.image)" |
52 | | - class="clickable-image" |
53 | | - /> |
| 48 | + <div class="image-container"> |
| 49 | + <img |
| 50 | + :src="message.image" |
| 51 | + alt="用户上传图片" |
| 52 | + class="message-img" |
| 53 | + /> |
| 54 | + <div class="image-overlay"> |
| 55 | + <button class="image-action-btn expand-btn" @click="expandImage(message.image)" title="查看大图"> |
| 56 | + <svg t="1752053278648" fill="white" width="24" height="24" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2363" ><path d="M919.920093 725.414549q3.014188 26.122962 7.033105 58.776664t7.53547 66.814498 7.53547 67.819227 7.033105 60.786122q6.028376 47.222277-41.193901 44.208089-25.118232-2.009459-56.767205-5.526011t-64.805039-7.53547-65.809769-8.037834-59.781393-7.033105q-29.137149-3.014188-37.174984-16.578033t9.042564-30.644243q11.052022-10.047293 27.127691-27.630056t27.127691-28.634785q11.052022-12.056752 7.033105-22.104044t-16.075669-23.108774q-28.13242-27.127691-51.241194-49.231735t-51.241194-51.241194q-6.028376-6.028376-12.056752-13.061481t-9.042564-15.573304-1.004729-18.085127 13.061481-20.59695q6.028376-6.028376 10.047293-10.549658t8.037834-8.037834 8.540199-8.037834 11.554387-12.559116q20.094586-20.094586 37.174984-17.080398t37.174984 23.108774 41.193901 40.691536 47.222277 46.719912q19.089857 18.085127 32.653702 25.118232t26.625326-6.028376q9.042564-9.042564 22.606409-21.60168t23.611138-22.606409q17.080398-17.080398 30.644243-13.061481t16.578033 30.141879zM43.79615 383.80659q-3.014188-26.122962-7.033105-58.776664t-7.53547-66.814498-7.53547-67.819227-7.033105-60.786122q-3.014188-26.122962 6.53074-36.170255t33.658431-8.037834q25.118232 2.009459 56.767205 5.526011t64.805039 7.53547 65.809769 8.037834 59.781393 7.033105q30.141879 3.014188 37.677348 16.578033t-9.544928 30.644243q-10.047293 10.047293-24.615868 26.122962t-25.620597 27.127691q-12.056752 12.056752-8.037834 22.104044t17.080398 23.108774q13.061481 14.06621 24.615868 24.615868t22.606409 21.099315 23.108774 22.606409l25.118232 25.118232q6.028376 6.028376 11.554387 14.06621t8.037834 17.080398-0.502365 19.089857-13.061481 20.094586l-11.052022 11.052022q-4.018917 4.018917-7.53547 8.037834t-8.540199 8.037834l-11.052022 12.056752q-20.094586 20.094586-34.663161 15.070939t-34.663161-25.118232-38.179713-37.677348-44.208089-43.705724q-18.085127-18.085127-32.151337-25.118232t-27.127691 6.028376q-9.042564 10.047293-25.118232 24.615868t-26.122962 24.615868q-17.080398 17.080398-30.141879 13.061481t-16.075669-30.141879zM905.853883 84.397261q26.122962-3.014188 36.170255 6.53074t8.037834 34.663161-5.526011 56.767205-7.53547 64.805039-8.037834 65.809769-7.033105 59.781393q-3.014188 29.137149-16.578033 37.174984t-30.644243-10.047293q-10.047293-10.047293-26.122962-24.615868t-27.127691-25.620597q-12.056752-11.052022-22.104044-7.53547t-23.108774 16.578033q-27.127691 27.127691-47.724641 49.231735t-48.729371 50.236465q-6.028376 6.028376-14.06621 11.554387t-17.080398 8.037834-19.089857-0.502365-20.094586-14.06621q-6.028376-6.028376-10.549658-10.047293t-8.540199-8.037834-8.540199-8.037834-11.554387-12.056752q-20.094586-20.094586-16.075669-35.165525t25.118232-35.165525l38.179713-40.189172q19.089857-20.094586 45.212818-46.217547 19.089857-18.085127 26.122962-32.151337t-7.033105-26.122962q-9.042564-9.042564-23.108774-24.615868t-24.113503-25.620597q-17.080398-17.080398-13.061481-30.141879t30.141879-16.075669 58.776664-7.033105 67.316863-7.53547 67.819227-7.53547 60.283758-7.033105zM350.238584 640.012559q6.028376 6.028376 10.549658 10.047293t8.540199 8.037834l8.037834 9.042564 12.056752 11.052022q20.094586 20.094586 17.582763 36.672619t-23.611138 37.677348q-19.089857 19.089857-40.189172 40.691536t-47.222277 47.724641q-18.085127 18.085127-22.606409 29.639514t8.540199 24.615868q10.047293 9.042564 22.606409 22.606409t22.606409 23.611138q17.080398 17.080398 12.559116 30.141879t-30.644243 16.075669-58.274299 7.033105-66.814498 8.037834-68.321592 8.037834-60.786122 7.033105q-25.118232 2.009459-35.66789-7.53547t-8.540199-33.658431q2.009459-25.118232 5.526011-56.767205t7.53547-64.805039 8.037834-65.809769 7.033105-59.781393q3.014188-30.141879 16.578033-37.677348t30.644243 9.544928q10.047293 10.047293 27.630056 26.122962t28.634785 27.127691q12.056752 12.056752 20.094586 10.549658t20.094586-14.568575q13.061481-13.061481 25.118232-25.620597t24.113503-24.615868 24.615868-25.118232 26.625326-27.127691q6.028376-6.028376 13.061481-12.056752t15.573304-9.042564 18.085127-0.502365 20.59695 13.563845z" p-id="2364"></path></svg> |
| 57 | + </button> |
| 58 | + <div class="top-right-actions"> |
| 59 | + <button class="image-action-btn" @click="selectExistingImage(message.image||'')" title="添加到输入"> |
| 60 | + <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24"> |
| 61 | + <path fill="currentColor" d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/> |
| 62 | + </svg> |
| 63 | + </button> |
| 64 | + <button class="image-action-btn" @click="downloadImage(message.image||'')" title="下载图片"> |
| 65 | + <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24"> |
| 66 | + <path fill="currentColor" d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/> |
| 67 | + </svg> |
| 68 | + </button> |
| 69 | + </div> |
| 70 | + </div> |
| 71 | + </div> |
54 | 72 | <div |
55 | 73 | v-if=" |
56 | 74 | message.role === 'assistant' && |
|
163 | 181 | </div> |
164 | 182 | </div> |
165 | 183 | </div> |
| 184 | + |
| 185 | + <!-- 图片查看弹窗 --> |
| 186 | + <div class="image-modal" v-if="showImageModal" @click="closeImageModal"> |
| 187 | + <div class="modal-content" @click.stop> |
| 188 | + <img :src="modalImageSrc" alt="大图查看" class="modal-image" /> |
| 189 | + <button class="modal-close-btn" @click="closeImageModal">×</button> |
| 190 | + </div> |
| 191 | + </div> |
166 | 192 | </Teleport> |
167 | 193 | </template> |
168 | 194 |
|
|
178 | 204 | import { useI18n } from 'vue-i18n' |
179 | 205 | import { useToaster } from '@/components/modules/toats/index' |
180 | 206 | import { v4 as uuidv4 } from 'uuid' |
181 | | -
|
| 207 | + import {downloadImage} from '@/utils/tool' |
182 | 208 | const { t } = useI18n() |
183 | 209 | const sidebarStore = useSidebarStore() |
184 | 210 |
|
|
801 | 827 | }, 0) |
802 | 828 | } |
803 | 829 |
|
| 830 | + // 图片弹窗相关状态 |
| 831 | + const showImageModal = ref(false) |
| 832 | + const modalImageSrc = ref('') |
| 833 | + |
| 834 | + // 放大查看图片 |
| 835 | + const expandImage = (imageSrc: string | undefined) => { |
| 836 | + if (!imageSrc) return |
| 837 | + modalImageSrc.value = imageSrc |
| 838 | + showImageModal.value = true |
| 839 | + } |
| 840 | + |
| 841 | + // 关闭图片弹窗 |
| 842 | + const closeImageModal = () => { |
| 843 | + showImageModal.value = false |
| 844 | + } |
| 845 | + |
| 846 | +
|
| 847 | +
|
804 | 848 | onMounted(() => { |
805 | 849 | // 从本地存储加载宽度设置 |
806 | 850 | const savedWidth = localStorage.getItem('bizyair-sidebar-width') |
|
1128 | 1172 | .message-image { |
1129 | 1173 | margin-bottom: 8px; |
1130 | 1174 | } |
1131 | | -
|
1132 | | - .message-image img { |
| 1175 | + |
| 1176 | + .image-container { |
| 1177 | + position: relative; |
| 1178 | + display: inline-block; |
| 1179 | + overflow: hidden; |
| 1180 | + border-radius: 6px; |
| 1181 | + } |
| 1182 | + |
| 1183 | + .message-img { |
1133 | 1184 | max-width: 100%; |
1134 | 1185 | max-height: 200px; |
1135 | 1186 | border-radius: 6px; |
| 1187 | + display: block; |
| 1188 | + } |
| 1189 | + |
| 1190 | + .image-overlay { |
| 1191 | + position: absolute; |
| 1192 | + top: 0; |
| 1193 | + left: 0; |
| 1194 | + width: 100%; |
| 1195 | + height: 100%; |
| 1196 | + background: rgba(0, 0, 0, 0.5); |
| 1197 | + display: flex; |
| 1198 | + align-items: center; |
| 1199 | + justify-content: center; |
| 1200 | + opacity: 0; |
| 1201 | + transition: opacity 0.2s ease; |
| 1202 | + } |
| 1203 | + |
| 1204 | + .image-container:hover .image-overlay { |
| 1205 | + opacity: 1; |
| 1206 | + } |
| 1207 | + |
| 1208 | + .image-action-btn { |
| 1209 | + background: rgba(0, 0, 0, 0.6); |
| 1210 | + border: none; |
| 1211 | + color: white; |
| 1212 | + width: 36px; |
| 1213 | + height: 36px; |
| 1214 | + border-radius: 50%; |
| 1215 | + display: flex; |
| 1216 | + align-items: center; |
| 1217 | + justify-content: center; |
| 1218 | + cursor: pointer; |
| 1219 | + transition: background-color 0.2s; |
| 1220 | + margin: 0 4px; |
| 1221 | + } |
| 1222 | + |
| 1223 | + .image-action-btn:hover { |
| 1224 | + background: rgba(0, 0, 0, 0.8); |
| 1225 | + } |
| 1226 | + |
| 1227 | + .expand-btn { |
| 1228 | + width: 48px; |
| 1229 | + height: 48px; |
| 1230 | + } |
| 1231 | + |
| 1232 | + .top-right-actions { |
| 1233 | + position: absolute; |
| 1234 | + top: 8px; |
| 1235 | + right: 8px; |
| 1236 | + display: flex; |
| 1237 | + gap: 8px; |
| 1238 | + } |
| 1239 | + |
| 1240 | + /* 弹窗样式 */ |
| 1241 | + .image-modal { |
| 1242 | + position: fixed; |
| 1243 | + top: 0; |
| 1244 | + left: 0; |
| 1245 | + width: 100%; |
| 1246 | + height: 100%; |
| 1247 | + background: rgba(0, 0, 0, 0.8); |
| 1248 | + display: flex; |
| 1249 | + align-items: center; |
| 1250 | + justify-content: center; |
| 1251 | + z-index: 100000; |
| 1252 | + } |
| 1253 | + |
| 1254 | + .modal-content { |
| 1255 | + position: relative; |
| 1256 | + max-width: 90%; |
| 1257 | + max-height: 90%; |
| 1258 | + } |
| 1259 | + |
| 1260 | + .modal-image { |
| 1261 | + max-width: 100%; |
| 1262 | + max-height: 90vh; |
| 1263 | + border-radius: 8px; |
| 1264 | + } |
| 1265 | + |
| 1266 | + .modal-close-btn { |
| 1267 | + position: absolute; |
| 1268 | + top: -20px; |
| 1269 | + right: -20px; |
| 1270 | + background: rgba(0, 0, 0, 0.7); |
| 1271 | + color: white; |
| 1272 | + border: none; |
| 1273 | + width: 32px; |
| 1274 | + height: 32px; |
| 1275 | + border-radius: 50%; |
| 1276 | + font-size: 18px; |
| 1277 | + cursor: pointer; |
| 1278 | + display: flex; |
| 1279 | + align-items: center; |
| 1280 | + justify-content: center; |
| 1281 | + } |
| 1282 | + |
| 1283 | + .clickable-image { |
| 1284 | + cursor: pointer; |
| 1285 | + transition: |
| 1286 | + transform 0.2s, |
| 1287 | + box-shadow 0.2s; |
| 1288 | + } |
| 1289 | +
|
| 1290 | + .clickable-image:hover { |
| 1291 | + transform: scale(1.02); |
| 1292 | + box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3); |
| 1293 | + } |
| 1294 | +
|
| 1295 | + .clickable-image::after { |
| 1296 | + content: '点击复用此图片'; |
| 1297 | + position: absolute; |
| 1298 | + bottom: 8px; |
| 1299 | + left: 50%; |
| 1300 | + transform: translateX(-50%); |
| 1301 | + background-color: rgba(0, 0, 0, 0.7); |
| 1302 | + color: white; |
| 1303 | + padding: 4px 8px; |
| 1304 | + border-radius: 4px; |
| 1305 | + font-size: 12px; |
| 1306 | + opacity: 0; |
| 1307 | + transition: opacity 0.2s; |
| 1308 | + pointer-events: none; |
| 1309 | + } |
| 1310 | + .clickable-image:hover::after { |
| 1311 | + opacity: 1; |
1136 | 1312 | } |
1137 | 1313 |
|
1138 | 1314 | .chat-input-area { |
|
1149 | 1325 | display: flex; |
1150 | 1326 | align-items: center; |
1151 | 1327 | gap: 8px; |
| 1328 | + width: 100%; |
| 1329 | + margin-top: 8px; |
1152 | 1330 | } |
1153 | 1331 |
|
1154 | 1332 | .textarea-container { |
1155 | 1333 | flex: 1; |
1156 | 1334 | position: relative; |
| 1335 | + height: 40px; |
| 1336 | + display: flex; |
| 1337 | + align-items: center; |
1157 | 1338 | } |
1158 | 1339 |
|
1159 | 1340 | .textarea-container textarea { |
1160 | 1341 | width: 100%; |
1161 | | - padding: 10px 12px; |
| 1342 | + padding: 8px 12px; |
1162 | 1343 | border-radius: 18px; |
1163 | 1344 | background-color: #444; |
1164 | 1345 | border: 1px solid #555; |
|
1168 | 1349 | line-height: 20px; |
1169 | 1350 | outline: none; |
1170 | 1351 | transition: border-color 0.2s; |
| 1352 | + box-sizing: border-box; |
1171 | 1353 | } |
1172 | 1354 |
|
1173 | 1355 | .textarea-container textarea:focus { |
1174 | 1356 | border-color: #7c3aed; |
1175 | 1357 | } |
1176 | 1358 |
|
1177 | | - .upload-image-btn { |
1178 | | - width: 40px; |
| 1359 | + .upload-image-btn, .send-message-btn, .control-btn { |
| 1360 | + min-width: 40px; |
1179 | 1361 | height: 40px; |
1180 | 1362 | border-radius: 50%; |
1181 | 1363 | display: flex; |
1182 | 1364 | justify-content: center; |
1183 | 1365 | align-items: center; |
1184 | 1366 | cursor: pointer; |
1185 | | - background-color: #444; |
1186 | 1367 | border: none; |
1187 | 1368 | color: white; |
| 1369 | + flex-shrink: 0; |
| 1370 | + } |
| 1371 | +
|
| 1372 | + .upload-image-btn { |
| 1373 | + background-color: #444; |
1188 | 1374 | transition: background-color 0.2s; |
1189 | 1375 | } |
1190 | 1376 |
|
|
1199 | 1385 | } |
1200 | 1386 |
|
1201 | 1387 | .send-message-btn { |
1202 | | - width: 40px; |
1203 | | - height: 40px; |
1204 | | - border-radius: 50%; |
1205 | | - display: flex; |
1206 | | - justify-content: center; |
1207 | | - align-items: center; |
1208 | | - cursor: pointer; |
1209 | 1388 | background-color: #7c3aed; |
1210 | | - border: none; |
1211 | | - color: white; |
1212 | 1389 | transition: background-color 0.2s; |
1213 | 1390 | } |
1214 | 1391 |
|
|
1244 | 1421 | } |
1245 | 1422 |
|
1246 | 1423 | .image-preview-area { |
1247 | | - margin-bottom: 12px; |
| 1424 | + margin-bottom: 8px; |
1248 | 1425 | flex-shrink: 0; |
| 1426 | + display: flex; |
| 1427 | + align-items: center; |
1249 | 1428 | } |
1250 | 1429 |
|
1251 | 1430 | .preview-image-container { |
|
0 commit comments