feat: 首页调整
This commit is contained in:
@ -25,6 +25,7 @@
|
|||||||
"html2canvas": "^1.4.1",
|
"html2canvas": "^1.4.1",
|
||||||
"jspdf": "^3.0.1",
|
"jspdf": "^3.0.1",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
|
"markdown-it": "^14.1.0",
|
||||||
"marked": "^16.1.1",
|
"marked": "^16.1.1",
|
||||||
"mitt": "^3.0.0",
|
"mitt": "^3.0.0",
|
||||||
"normalize.css": "^8.0.1",
|
"normalize.css": "^8.0.1",
|
||||||
|
|||||||
39
pnpm-lock.yaml
generated
39
pnpm-lock.yaml
generated
@ -50,6 +50,9 @@ importers:
|
|||||||
lodash-es:
|
lodash-es:
|
||||||
specifier: ^4.17.21
|
specifier: ^4.17.21
|
||||||
version: 4.17.21
|
version: 4.17.21
|
||||||
|
markdown-it:
|
||||||
|
specifier: ^14.1.0
|
||||||
|
version: 14.1.0
|
||||||
marked:
|
marked:
|
||||||
specifier: ^16.1.1
|
specifier: ^16.1.1
|
||||||
version: 16.1.2
|
version: 16.1.2
|
||||||
@ -3489,6 +3492,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==}
|
resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
linkify-it@5.0.0:
|
||||||
|
resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==}
|
||||||
|
|
||||||
lint-staged@13.1.0:
|
lint-staged@13.1.0:
|
||||||
resolution: {integrity: sha512-pn/sR8IrcF/T0vpWLilih8jmVouMlxqXxKuAojmbiGX5n/gDnz+abdPptlj0vYnbfE0SQNl3CY/HwtM0+yfOVQ==}
|
resolution: {integrity: sha512-pn/sR8IrcF/T0vpWLilih8jmVouMlxqXxKuAojmbiGX5n/gDnz+abdPptlj0vYnbfE0SQNl3CY/HwtM0+yfOVQ==}
|
||||||
engines: {node: ^14.13.1 || >=16.0.0}
|
engines: {node: ^14.13.1 || >=16.0.0}
|
||||||
@ -3722,6 +3728,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==}
|
resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
markdown-it@14.1.0:
|
||||||
|
resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
marked@16.1.2:
|
marked@16.1.2:
|
||||||
resolution: {integrity: sha512-rNQt5EvRinalby7zJZu/mB+BvaAY2oz3wCuCjt1RDrWNpS1Pdf9xqMOeC9Hm5adBdcV/3XZPJpG58eT+WBc0XQ==}
|
resolution: {integrity: sha512-rNQt5EvRinalby7zJZu/mB+BvaAY2oz3wCuCjt1RDrWNpS1Pdf9xqMOeC9Hm5adBdcV/3XZPJpG58eT+WBc0XQ==}
|
||||||
engines: {node: '>= 20'}
|
engines: {node: '>= 20'}
|
||||||
@ -3752,6 +3762,9 @@ packages:
|
|||||||
mdn-data@2.0.30:
|
mdn-data@2.0.30:
|
||||||
resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==}
|
resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==}
|
||||||
|
|
||||||
|
mdurl@2.0.0:
|
||||||
|
resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==}
|
||||||
|
|
||||||
memory-fs@0.5.0:
|
memory-fs@0.5.0:
|
||||||
resolution: {integrity: sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==}
|
resolution: {integrity: sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==}
|
||||||
engines: {node: '>=4.3.0 <5.0.0 || >=5.10'}
|
engines: {node: '>=4.3.0 <5.0.0 || >=5.10'}
|
||||||
@ -4384,6 +4397,10 @@ packages:
|
|||||||
pump@3.0.0:
|
pump@3.0.0:
|
||||||
resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==}
|
resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==}
|
||||||
|
|
||||||
|
punycode.js@2.3.1:
|
||||||
|
resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
punycode@2.3.0:
|
punycode@2.3.0:
|
||||||
resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==}
|
resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
@ -5236,6 +5253,9 @@ packages:
|
|||||||
engines: {node: '>=4.2.0'}
|
engines: {node: '>=4.2.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
uc.micro@2.1.0:
|
||||||
|
resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==}
|
||||||
|
|
||||||
ufo@1.0.1:
|
ufo@1.0.1:
|
||||||
resolution: {integrity: sha512-boAm74ubXHY7KJQZLlXrtMz52qFvpsbOxDcZOnw/Wf+LS4Mmyu7JxmzD4tDLtUQtmZECypJ0FrCz4QIe6dvKRA==}
|
resolution: {integrity: sha512-boAm74ubXHY7KJQZLlXrtMz52qFvpsbOxDcZOnw/Wf+LS4Mmyu7JxmzD4tDLtUQtmZECypJ0FrCz4QIe6dvKRA==}
|
||||||
|
|
||||||
@ -9818,6 +9838,10 @@ snapshots:
|
|||||||
|
|
||||||
lilconfig@2.0.6: {}
|
lilconfig@2.0.6: {}
|
||||||
|
|
||||||
|
linkify-it@5.0.0:
|
||||||
|
dependencies:
|
||||||
|
uc.micro: 2.1.0
|
||||||
|
|
||||||
lint-staged@13.1.0:
|
lint-staged@13.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
cli-truncate: 3.1.0
|
cli-truncate: 3.1.0
|
||||||
@ -10134,6 +10158,15 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
object-visit: 1.0.1
|
object-visit: 1.0.1
|
||||||
|
|
||||||
|
markdown-it@14.1.0:
|
||||||
|
dependencies:
|
||||||
|
argparse: 2.0.1
|
||||||
|
entities: 4.5.0
|
||||||
|
linkify-it: 5.0.0
|
||||||
|
mdurl: 2.0.0
|
||||||
|
punycode.js: 2.3.1
|
||||||
|
uc.micro: 2.1.0
|
||||||
|
|
||||||
marked@16.1.2: {}
|
marked@16.1.2: {}
|
||||||
|
|
||||||
match-file@0.2.2:
|
match-file@0.2.2:
|
||||||
@ -10171,6 +10204,8 @@ snapshots:
|
|||||||
|
|
||||||
mdn-data@2.0.30: {}
|
mdn-data@2.0.30: {}
|
||||||
|
|
||||||
|
mdurl@2.0.0: {}
|
||||||
|
|
||||||
memory-fs@0.5.0:
|
memory-fs@0.5.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
errno: 0.1.8
|
errno: 0.1.8
|
||||||
@ -10850,6 +10885,8 @@ snapshots:
|
|||||||
end-of-stream: 1.4.4
|
end-of-stream: 1.4.4
|
||||||
once: 1.4.0
|
once: 1.4.0
|
||||||
|
|
||||||
|
punycode.js@2.3.1: {}
|
||||||
|
|
||||||
punycode@2.3.0: {}
|
punycode@2.3.0: {}
|
||||||
|
|
||||||
qs@6.12.1:
|
qs@6.12.1:
|
||||||
@ -11925,6 +11962,8 @@ snapshots:
|
|||||||
|
|
||||||
typescript@4.9.5: {}
|
typescript@4.9.5: {}
|
||||||
|
|
||||||
|
uc.micro@2.1.0: {}
|
||||||
|
|
||||||
ufo@1.0.1: {}
|
ufo@1.0.1: {}
|
||||||
|
|
||||||
ufo@1.5.3: {}
|
ufo@1.5.3: {}
|
||||||
|
|||||||
@ -4,8 +4,8 @@ import { Input, Dropdown, Menu } from 'ant-design-vue';
|
|||||||
import type { MenuProps } from 'ant-design-vue';
|
import type { MenuProps } from 'ant-design-vue';
|
||||||
|
|
||||||
import type { VNode } from 'vue';
|
import type { VNode } from 'vue';
|
||||||
import SvgIcon from '@/components/svg-icon';
|
import SvgIcon from '@/components/svg-icon/index.vue';
|
||||||
import TextoverTips from '@/components/text-over-tips';
|
import TextoverTips from '@/components/text-over-tips/index.vue';
|
||||||
|
|
||||||
// 定义对话项类型
|
// 定义对话项类型
|
||||||
interface ConversationItem {
|
interface ConversationItem {
|
||||||
@ -63,10 +63,11 @@ export default defineComponent({
|
|||||||
const menuConfigs = ref<ConversationItem[]>(props.menu ?? DEFAULT_MENU_CONFIG);
|
const menuConfigs = ref<ConversationItem[]>(props.menu ?? DEFAULT_MENU_CONFIG);
|
||||||
|
|
||||||
// 处理选中变更
|
// 处理选中变更
|
||||||
const handleActiveChange = (value: string) => {
|
const handleActiveChange = (item: ConversationItem) => {
|
||||||
|
const { value } = item;
|
||||||
activeKey.value = value;
|
activeKey.value = value;
|
||||||
emit('update:modelValue', value);
|
emit('update:modelValue', value);
|
||||||
emit('activeChange', value);
|
emit('activeChange', item);
|
||||||
};
|
};
|
||||||
const onMenuItemClick = ({ menuInfo, item }) => {
|
const onMenuItemClick = ({ menuInfo, item }) => {
|
||||||
const { key } = menuInfo;
|
const { key } = menuInfo;
|
||||||
@ -102,7 +103,7 @@ export default defineComponent({
|
|||||||
class={`group flex justify-between cursor-pointer items-center p-8px h-40px rounded-8px hover:bg-#F2F3F5 ${
|
class={`group flex justify-between cursor-pointer items-center p-8px h-40px rounded-8px hover:bg-#F2F3F5 ${
|
||||||
activeKey.value === item.key ? 'bg-#F2F3F5' : ''
|
activeKey.value === item.key ? 'bg-#F2F3F5' : ''
|
||||||
}`}
|
}`}
|
||||||
onClick={() => handleActiveChange(item.key)}
|
onClick={() => handleActiveChange(item)}
|
||||||
>
|
>
|
||||||
{item.editing ? (
|
{item.editing ? (
|
||||||
<Input
|
<Input
|
||||||
|
|||||||
@ -108,7 +108,7 @@ const checkHasInviteCode = () => {
|
|||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
z-index: 999;
|
z-index: 9999;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
.layout-content-wrap {
|
.layout-content-wrap {
|
||||||
|
|||||||
@ -1,13 +1,16 @@
|
|||||||
<script lang="jsx">
|
<script lang="jsx">
|
||||||
import { Input } from 'ant-design-vue';
|
import { Input } from 'ant-design-vue';
|
||||||
import { handleUserHome } from '@/utils/user.ts';
|
import { handleUserHome } from '@/utils/user.ts';
|
||||||
|
import { useSharedDataStore } from '@/stores/modules/share-data';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
setup(props, { emit, expose }) {
|
setup(props, { emit, expose }) {
|
||||||
|
const sharedDataStore = useSharedDataStore();
|
||||||
const keyWord = ref('');
|
const keyWord = ref('');
|
||||||
|
|
||||||
const handleSearch = () => {
|
const handleSearch = () => {
|
||||||
handleUserHome({ keyWord: keyWord.value });
|
sharedDataStore.setRouteParams({ keyWord: keyWord.value });
|
||||||
|
handleUserHome();
|
||||||
keyWord.value = '';
|
keyWord.value = '';
|
||||||
};
|
};
|
||||||
return () => (
|
return () => (
|
||||||
|
|||||||
@ -24,7 +24,7 @@ export const router = createRouter({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/chat/:conversationId?',
|
||||||
name: 'Home',
|
name: 'Home',
|
||||||
component: () => import('@/views/home/index.vue'),
|
component: () => import('@/views/home/index.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
|
|||||||
21
src/styles/components/chat-bubble.scss
Normal file
21
src/styles/components/chat-bubble.scss
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
.ant-bubble-list {
|
||||||
|
gap: 8px;
|
||||||
|
.ant-bubble {
|
||||||
|
.ant-bubble-content {
|
||||||
|
color: var(--Text-1, #211f24);
|
||||||
|
font-family: $font-family-regular;
|
||||||
|
font-size: 14px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 22px;
|
||||||
|
&.ant-bubble-content-round {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
border-radius: 50px;
|
||||||
|
background: var(--BG-200, #f2f3f5);
|
||||||
|
padding-inline: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -11,3 +11,4 @@
|
|||||||
@import "./steps.scss";
|
@import "./steps.scss";
|
||||||
@import "./form.scss";
|
@import "./form.scss";
|
||||||
@import "./chat-sender.scss";
|
@import "./chat-sender.scss";
|
||||||
|
@import "./chat-bubble.scss";
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import router from '@/router';
|
|||||||
import { useUserStore } from '@/stores';
|
import { useUserStore } from '@/stores';
|
||||||
import { useEnterpriseStore } from '@/stores/modules/enterprise';
|
import { useEnterpriseStore } from '@/stores/modules/enterprise';
|
||||||
import { useSidebarStore } from '@/stores/modules/side-bar';
|
import { useSidebarStore } from '@/stores/modules/side-bar';
|
||||||
import { useSharedDataStore } from '@/stores/modules/share-data';
|
|
||||||
|
|
||||||
// 登录
|
// 登录
|
||||||
export function goUserLogin(query?: any) {
|
export function goUserLogin(query?: any) {
|
||||||
@ -38,11 +37,8 @@ export async function handleUserLogin() {
|
|||||||
|
|
||||||
// 首页
|
// 首页
|
||||||
export function handleUserHome(params?: any) {
|
export function handleUserHome(params?: any) {
|
||||||
if (params) {
|
|
||||||
const sharedDataStore = useSharedDataStore();
|
router.push({ name: 'Home' });
|
||||||
sharedDataStore.setRouteParams(params);
|
|
||||||
}
|
|
||||||
router.push({ name: 'Home', params });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 登出处理
|
// 登出处理
|
||||||
|
|||||||
112
src/views/home/components/conversation-detail/index.vue
Normal file
112
src/views/home/components/conversation-detail/index.vue
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
<script lang="tsx">
|
||||||
|
import { message } from 'ant-design-vue';
|
||||||
|
import { BubbleList } from 'ant-design-x-vue';
|
||||||
|
import type { BubbleListProps } from 'ant-design-x-vue';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
import SenderInput from '../sender-input/index.vue';
|
||||||
|
import markdownit from 'markdown-it';
|
||||||
|
import { Typography } from 'ant-design-vue';
|
||||||
|
|
||||||
|
const QUESTION_ROLE = 'question';
|
||||||
|
const ANSWER_ROLE = 'text';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setup(props, { emit, expose }) {
|
||||||
|
const route = useRoute();
|
||||||
|
const senderRef = ref(null);
|
||||||
|
const searchValue = ref('');
|
||||||
|
const generateLoading = ref(false);
|
||||||
|
const conversationList = ref([]);
|
||||||
|
const md = markdownit({ html: true, breaks: true });
|
||||||
|
|
||||||
|
const conversationId = computed(() => {
|
||||||
|
return route.params.conversationId;
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
generateLoading.value = true;
|
||||||
|
conversationList.value.push({
|
||||||
|
role: QUESTION_ROLE,
|
||||||
|
content: searchValue.value,
|
||||||
|
});
|
||||||
|
|
||||||
|
const tempId = Date.now();
|
||||||
|
const tempIndex = conversationList.value.length;
|
||||||
|
conversationList.value.push({
|
||||||
|
id: tempId,
|
||||||
|
loading: true,
|
||||||
|
role: ANSWER_ROLE
|
||||||
|
});
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
const content = `> Render as markdown content to show rich text!
|
||||||
|
Link: [Ant Design X](https://x.ant.design)
|
||||||
|
`;
|
||||||
|
searchValue.value = '';
|
||||||
|
conversationList.value.splice(tempIndex, 1, {
|
||||||
|
id: tempId,
|
||||||
|
loading: false,
|
||||||
|
role: ANSWER_ROLE,
|
||||||
|
content,
|
||||||
|
messageRender: (content) => (
|
||||||
|
<Typography>
|
||||||
|
<div v-html={md.render(content)}></div>
|
||||||
|
</Typography>
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}, 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCancel = () => {
|
||||||
|
generateLoading.value = false;
|
||||||
|
message.info('取消生成');
|
||||||
|
};
|
||||||
|
|
||||||
|
const roles: BubbleListProps['roles'] = {
|
||||||
|
[ANSWER_ROLE]: {
|
||||||
|
placement: 'start',
|
||||||
|
variant: 'borderless',
|
||||||
|
typing: { step: 2, interval: 100 },
|
||||||
|
onTypingComplete: () => {
|
||||||
|
generateLoading.value = false;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[QUESTION_ROLE]: {
|
||||||
|
placement: 'end',
|
||||||
|
shape: 'round',
|
||||||
|
styles: {
|
||||||
|
content: {
|
||||||
|
padding: '6px 12px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return () => (
|
||||||
|
<div class="conversation-detail-wrap w-full h-full flex">
|
||||||
|
<div class="flex-1 flex justify-center">
|
||||||
|
<section class="main w-600px h-full relative flex flex-col pt-20px">
|
||||||
|
<BubbleList class="flex-1" roles={roles} items={conversationList.value} />
|
||||||
|
<div class="w-full flex flex-col justify-center items-center">
|
||||||
|
<SenderInput
|
||||||
|
class="w-full"
|
||||||
|
ref={senderRef}
|
||||||
|
placeholder="继续追问..."
|
||||||
|
v-model={searchValue.value}
|
||||||
|
loading={generateLoading.value}
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
onCancel={handleCancel}
|
||||||
|
/>
|
||||||
|
<p class="cts !color-#939499 text-12px !lh-20px my-4px">内容由AI生成,仅供参考</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import './style.scss';
|
||||||
|
</style>
|
||||||
9
src/views/home/components/conversation-detail/style.scss
Normal file
9
src/views/home/components/conversation-detail/style.scss
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
.conversation-detail-wrap {
|
||||||
|
.cts {
|
||||||
|
color: var(--Text-1, #737478);
|
||||||
|
font-size: 14px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 22px;
|
||||||
|
}
|
||||||
|
}
|
||||||
85
src/views/home/components/created/index.vue
Normal file
85
src/views/home/components/created/index.vue
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
<script lang="tsx">
|
||||||
|
import { message } from 'ant-design-vue';
|
||||||
|
import ExpandableTags from '@/components/expandable-tags/index.vue';
|
||||||
|
import SenderInput from '../sender-input/index.vue';
|
||||||
|
|
||||||
|
import { useSharedDataStore } from '@/stores/modules/share-data';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setup(props, { emit, expose }) {
|
||||||
|
const router = useRouter();
|
||||||
|
const senderRef = ref(null);
|
||||||
|
const searchValue = ref('');
|
||||||
|
const sharedDataStore = useSharedDataStore();
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
handleSearch();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSearch = () => {
|
||||||
|
console.log('searchValue.value', searchValue.value);
|
||||||
|
// const conversationId = searchValue.value;
|
||||||
|
// router.push({
|
||||||
|
// name: 'Home',
|
||||||
|
// params: {
|
||||||
|
// conversationId,
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
};
|
||||||
|
|
||||||
|
const tagList = [
|
||||||
|
'人工智能',
|
||||||
|
'人工智能与应用',
|
||||||
|
'行业分析与市场数据',
|
||||||
|
'标签标签标签标签标签标签标签',
|
||||||
|
'标签标签标签标签标签标签标签',
|
||||||
|
'标签标签标签标签标签标签标签',
|
||||||
|
'标签标签标签标签标签标签标签',
|
||||||
|
'标签A',
|
||||||
|
'啊啊啊',
|
||||||
|
'宝宝贝贝',
|
||||||
|
'微信',
|
||||||
|
'吧啊啊',
|
||||||
|
'哦哦哦哦哦哦哦哦',
|
||||||
|
'人工智能',
|
||||||
|
'人工智能与应用',
|
||||||
|
];
|
||||||
|
|
||||||
|
const handleTagClick = (tag: string) => {
|
||||||
|
searchValue.value = tag;
|
||||||
|
senderRef.value?.focus();
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
const params = sharedDataStore.routeParams;
|
||||||
|
if (params) {
|
||||||
|
searchValue.value = params.keyWord;
|
||||||
|
sharedDataStore.clearRouteParams();
|
||||||
|
|
||||||
|
handleSearch();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => (
|
||||||
|
<div class="create-conversation-wrap w-full h-full flex justify-center">
|
||||||
|
<div class="main w-600px pt-120px">
|
||||||
|
<p class="title mb-16px">
|
||||||
|
<span>营小智,7x24小时</span>
|
||||||
|
<span class="s1">AI营销</span>
|
||||||
|
<span>团队</span>
|
||||||
|
</p>
|
||||||
|
<p class="cts text-center mb-104px">AI 辅助账号托管账号 | 自动生成爆款内容 | 定时任务发布</p>
|
||||||
|
<SenderInput ref={senderRef} v-model={searchValue.value} onSubmit={handleSubmit} class="mb-24px" />
|
||||||
|
<p class="cts mb-6px">可以试试这样下发任务:</p>
|
||||||
|
<ExpandableTags tags={tagList} clickable onTagClick={handleTagClick} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import './style.scss';
|
||||||
|
</style>
|
||||||
32
src/views/home/components/created/style.scss
Normal file
32
src/views/home/components/created/style.scss
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
.create-conversation-wrap {
|
||||||
|
.cts {
|
||||||
|
color: var(--Text-1, #737478);
|
||||||
|
font-size: 14px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 22px;
|
||||||
|
}
|
||||||
|
.main {
|
||||||
|
.title {
|
||||||
|
color: var(--Text-1, #211f24);
|
||||||
|
text-align: center;
|
||||||
|
font-family: $font-family-medium;
|
||||||
|
font-size: 32px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 48px;
|
||||||
|
.s1 {
|
||||||
|
background: linear-gradient(90deg, #6d4cfe 38.12%, #b93bf0 100%);
|
||||||
|
background-clip: text;
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
:deep(.expandable-tags-container) {
|
||||||
|
.tag-list {
|
||||||
|
row-gap: 6px;
|
||||||
|
column-gap: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,9 +5,11 @@ import Conversations from '@/components/xt-chat/conversations';
|
|||||||
import SvgIcon from '@/components/svg-icon';
|
import SvgIcon from '@/components/svg-icon';
|
||||||
import { Button, Flex, Input } from 'ant-design-vue';
|
import { Button, Flex, Input } from 'ant-design-vue';
|
||||||
import DeleteChatModal from './delete-chat-modal.vue';
|
import DeleteChatModal from './delete-chat-modal.vue';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
setup(props, { emit, expose }) {
|
setup(props, { emit, expose }) {
|
||||||
|
const router = useRouter();
|
||||||
const open = ref(false);
|
const open = ref(false);
|
||||||
const dataSource = ref([]);
|
const dataSource = ref([]);
|
||||||
const activeKey = ref('');
|
const activeKey = ref('');
|
||||||
@ -19,6 +21,7 @@ export default {
|
|||||||
};
|
};
|
||||||
const getData = () => {
|
const getData = () => {
|
||||||
dataSource.value = Array.from({ length: 4 }).map((conversation, index) => ({
|
dataSource.value = Array.from({ length: 4 }).map((conversation, index) => ({
|
||||||
|
id: `${index + 1}`,
|
||||||
key: `item${index + 1}`,
|
key: `item${index + 1}`,
|
||||||
label: `Conversation Item ${index + 1}Conversation Item 1`,
|
label: `Conversation Item ${index + 1}Conversation Item 1`,
|
||||||
}));
|
}));
|
||||||
@ -43,6 +46,15 @@ export default {
|
|||||||
const handleRename = (item) => {
|
const handleRename = (item) => {
|
||||||
console.log('handleRename', item);
|
console.log('handleRename', item);
|
||||||
};
|
};
|
||||||
|
const handleActiveChange = (item) => {
|
||||||
|
const { id } = item;
|
||||||
|
router.push({
|
||||||
|
name: 'Home',
|
||||||
|
params: {
|
||||||
|
conversationId: id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
expose({
|
expose({
|
||||||
showDrawer,
|
showDrawer,
|
||||||
@ -60,6 +72,7 @@ export default {
|
|||||||
dataSource={dataSource.value}
|
dataSource={dataSource.value}
|
||||||
onMenuClick={handleMenuClick}
|
onMenuClick={handleMenuClick}
|
||||||
onRename={handleRename}
|
onRename={handleRename}
|
||||||
|
onActiveChange={handleActiveChange}
|
||||||
/>
|
/>
|
||||||
</section>
|
</section>
|
||||||
<DeleteChatModal ref={deleteChatModalRef} />
|
<DeleteChatModal ref={deleteChatModalRef} />
|
||||||
|
|||||||
107
src/views/home/components/sender-input/index.vue
Normal file
107
src/views/home/components/sender-input/index.vue
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
<script lang="tsx">
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { Sender } from 'ant-design-x-vue';
|
||||||
|
import { Tooltip } from 'ant-design-vue';
|
||||||
|
|
||||||
|
interface SenderInputProps {
|
||||||
|
modelValue?: string;
|
||||||
|
loading?: boolean;
|
||||||
|
placeholder?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'SenderInput',
|
||||||
|
props: {
|
||||||
|
modelValue: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: '随时告诉我你想做什么,比如查数据、发任务、写内容,我会立刻帮你完成。',
|
||||||
|
},
|
||||||
|
loading: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
emits: ['update:modelValue', 'submit', 'cancel'],
|
||||||
|
setup(props: SenderInputProps, { emit, expose }) {
|
||||||
|
const senderRef = ref(null);
|
||||||
|
const localSearchValue = ref(props.modelValue);
|
||||||
|
|
||||||
|
// 监听外部value变化
|
||||||
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
(newValue) => {
|
||||||
|
localSearchValue.value = newValue || '';
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
if (!props.loading) {
|
||||||
|
emit('submit', localSearchValue.value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleCancel = () => {
|
||||||
|
emit('cancel');
|
||||||
|
};
|
||||||
|
|
||||||
|
const focus = () => {
|
||||||
|
senderRef.value?.focus?.();
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderActions = () => {
|
||||||
|
if (props.loading) {
|
||||||
|
return (
|
||||||
|
<Tooltip title="停止生成" onClick={handleCancel}>
|
||||||
|
<div class="w-32px h-32px p-6px flex justify-center items-center rounded-50% bg-#6D4CFE cursor-pointer">
|
||||||
|
<div class="w-12px h-12px rounded-2px bg-#FFF"></div>
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
onClick={handleSubmit}
|
||||||
|
class={`submit-btn w-32px h-32px p-6px flex justify-center items-center rounded-50% cursor-pointer ${
|
||||||
|
!localSearchValue.value ? 'opacity-50' : ''
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<icon-arrow-right size={20} class="color-#FFFFFF" />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
expose({
|
||||||
|
focus,
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => (
|
||||||
|
<div class="sender-input-wrap full h-120px">
|
||||||
|
<Sender
|
||||||
|
v-model:value={localSearchValue.value}
|
||||||
|
ref={senderRef}
|
||||||
|
onChange={(value: string) => emit('update:modelValue', value)}
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
class="h-full w-full mb-24px"
|
||||||
|
placeholder={props.placeholder}
|
||||||
|
actions={() => renderActions()}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.sender-input-wrap {
|
||||||
|
:deep(.ant-sender) {
|
||||||
|
.submit-btn {
|
||||||
|
background: linear-gradient(125deg, #6d4cfe 32.25%, #3ba1f0 72.31%),
|
||||||
|
linear-gradient(113deg, #6d4cfe 0%, #b93bf0 100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -1,93 +1,24 @@
|
|||||||
<script lang="tsx">
|
<script lang="tsx">
|
||||||
import HistoryConversationDrawer from './components/history-conversation-drawer';
|
import { useRoute } from 'vue-router';
|
||||||
import { Sender } from 'ant-design-x-vue';
|
import { ref, computed } from 'vue';
|
||||||
import { message } from 'ant-design-vue';
|
|
||||||
import ExpandableTags from '@/components/expandable-tags';
|
|
||||||
|
|
||||||
import { useSharedDataStore } from '@/stores/modules/share-data';
|
import HistoryConversationDrawer from './components/history-conversation-drawer/index.vue';
|
||||||
|
import ConversationDetail from './components/conversation-detail/index.vue';
|
||||||
|
import ConversationCreate from './components/created/index.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
setup(props, { emit, expose }) {
|
setup(props, { emit, expose }) {
|
||||||
|
const route = useRoute();
|
||||||
|
|
||||||
const historyConversationDrawerRef = ref(null);
|
const historyConversationDrawerRef = ref(null);
|
||||||
const senderRef = ref(null);
|
|
||||||
const searchValue = ref('');
|
|
||||||
const sharedDataStore = useSharedDataStore();
|
|
||||||
|
|
||||||
const handleSubmit = () => {
|
const conversationId = computed(() => {
|
||||||
handleSearch();
|
return route.params.conversationId;
|
||||||
searchValue.value = '';
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSearch = () => {
|
|
||||||
message.info('handleSearch----' + searchValue.value);
|
|
||||||
};
|
|
||||||
|
|
||||||
const tagList = [
|
|
||||||
'人工智能',
|
|
||||||
'人工智能与应用',
|
|
||||||
'行业分析与市场数据',
|
|
||||||
'标签标签标签标签标签标签标签',
|
|
||||||
'标签标签标签标签标签标签标签',
|
|
||||||
'标签标签标签标签标签标签标签',
|
|
||||||
'标签标签标签标签标签标签标签',
|
|
||||||
'标签A',
|
|
||||||
'啊啊啊',
|
|
||||||
'宝宝贝贝',
|
|
||||||
'微信',
|
|
||||||
'吧啊啊',
|
|
||||||
'哦哦哦哦哦哦哦哦',
|
|
||||||
'人工智能',
|
|
||||||
'人工智能与应用',
|
|
||||||
];
|
|
||||||
|
|
||||||
const handleTagClick = (tag: string) => {
|
|
||||||
searchValue.value = tag;
|
|
||||||
handleSearch();
|
|
||||||
senderRef.value?.focus();
|
|
||||||
};
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
const params = sharedDataStore.routeParams;
|
|
||||||
if (params) {
|
|
||||||
searchValue.value = params.keyWord;
|
|
||||||
sharedDataStore.clearRouteParams();
|
|
||||||
|
|
||||||
handleSearch();
|
|
||||||
senderRef.value?.focus();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return () => (
|
return () => (
|
||||||
<div class="home-wrap rounded-12px w-full h-full">
|
<div class="chat-wrap rounded-12px w-full h-full">
|
||||||
<div class="w-full h-full flex justify-center ">
|
{conversationId.value ? <ConversationDetail /> : <ConversationCreate />}
|
||||||
<div class="main-chat-wrap w-600px pt-120px">
|
|
||||||
<p class="title mb-16px">
|
|
||||||
<span>营小智,7x24小时</span>
|
|
||||||
<span class="s1">AI营销</span>
|
|
||||||
<span>团队</span>
|
|
||||||
</p>
|
|
||||||
<p class="cts text-center mb-104px">AI 辅助账号托管账号 | 自动生成爆款内容 | 定时任务发布</p>
|
|
||||||
<Sender
|
|
||||||
v-model:value={searchValue.value}
|
|
||||||
ref={senderRef}
|
|
||||||
onSubmit={handleSubmit}
|
|
||||||
class="h-120px w-full mb-24px"
|
|
||||||
placeholder="随时告诉我你想做什么,比如查数据、发任务、写内容,我会立刻帮你完成。"
|
|
||||||
actions={() => (
|
|
||||||
<div
|
|
||||||
onClick={handleSubmit}
|
|
||||||
class={`submit-btn w-32px h-32px p-6px flex justify-center items-center rounded-50% cursor-pointer ${
|
|
||||||
!searchValue.value ? 'opacity-50' : ''
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
<icon-arrow-right size={20} class="color-#FFFFFF" />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<p class="cts mb-6px">可以试试这样下发任务:</p>
|
|
||||||
<ExpandableTags tags={tagList} clickable onTagClick={handleTagClick} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/**历史对话入口 */}
|
{/**历史对话入口 */}
|
||||||
<div
|
<div
|
||||||
|
|||||||
@ -1,43 +1,7 @@
|
|||||||
.home-wrap {
|
.chat-wrap {
|
||||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
backdrop-filter: blur(20px);
|
backdrop-filter: blur(20px);
|
||||||
background: rgba(255, 255, 255, 0.9);
|
background: rgba(255, 255, 255, 0.9);
|
||||||
.cts {
|
|
||||||
color: var(--Text-1, #737478);
|
|
||||||
font-size: 14px;
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 400;
|
|
||||||
line-height: 22px;
|
|
||||||
}
|
|
||||||
.main-chat-wrap {
|
|
||||||
.title {
|
|
||||||
color: var(--Text-1, #211f24);
|
|
||||||
text-align: center;
|
|
||||||
font-family: $font-family-medium;
|
|
||||||
font-size: 32px;
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 700;
|
|
||||||
line-height: 48px;
|
|
||||||
.s1 {
|
|
||||||
background: linear-gradient(90deg, #6d4cfe 38.12%, #b93bf0 100%);
|
|
||||||
background-clip: text;
|
|
||||||
-webkit-background-clip: text;
|
|
||||||
-webkit-text-fill-color: transparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
:deep(.ant-sender) {
|
|
||||||
.submit-btn {
|
|
||||||
background: linear-gradient(125deg, #6d4cfe 32.25%, #3ba1f0 72.31%),
|
|
||||||
linear-gradient(113deg, #6d4cfe 0%, #b93bf0 100%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
:deep(.expandable-tags-container) {
|
|
||||||
.tag-list {
|
|
||||||
row-gap: 6px;
|
|
||||||
column-gap: 12px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.history-conversation-btn {
|
.history-conversation-btn {
|
||||||
border-radius: 8px 0 0 8px;
|
border-radius: 8px 0 0 8px;
|
||||||
border-top: 1px solid #eabaff;
|
border-top: 1px solid #eabaff;
|
||||||
|
|||||||
Reference in New Issue
Block a user