houzhongjian
2024-08-08 820397e43a0b64d35c6d31d2a55475061438593b
提交 | 用户 | 时间
820397 1 <!-- chat 角色仓库 -->
H 2 <template>
3   <el-container class="role-container">
4     <ChatRoleForm ref="formRef" @success="handlerAddRoleSuccess" />
5     <!-- header  -->
6     <RoleHeader title="角色仓库" class="relative" />
7     <!--  main  -->
8     <el-main class="role-main">
9       <div class="search-container">
10         <!-- 搜索按钮 -->
11         <el-input
12           :loading="loading"
13           v-model="search"
14           class="search-input"
15           size="default"
16           placeholder="请输入搜索的内容"
17           :suffix-icon="Search"
18           @change="getActiveTabsRole"
19         />
20         <el-button
21           v-if="activeTab == 'my-role'"
22           type="primary"
23           @click="handlerAddRole"
24           class="ml-20px"
25         >
26           <Icon icon="ep:user" style="margin-right: 5px;" />
27           添加角色
28         </el-button>
29       </div>
30       <!-- tabs -->
31       <el-tabs v-model="activeTab" class="tabs" @tab-click="handleTabsClick">
32         <el-tab-pane class="role-pane" label="我的角色" name="my-role">
33           <RoleList
34             :loading="loading"
35             :role-list="myRoleList"
36             :show-more="true"
37             @on-delete="handlerCardDelete"
38             @on-edit="handlerCardEdit"
39             @on-use="handlerCardUse"
40             @on-page="handlerCardPage('my')"
41             class="mt-20px"
42           />
43         </el-tab-pane>
44         <el-tab-pane label="公共角色" name="public-role">
45           <RoleCategoryList
46             class="role-category-list"
47             :category-list="categoryList"
48             :active="activeCategory"
49             @on-category-click="handlerCategoryClick"
50           />
51           <RoleList
52             :role-list="publicRoleList"
53             @on-delete="handlerCardDelete"
54             @on-edit="handlerCardEdit"
55             @on-use="handlerCardUse"
56             @on-page="handlerCardPage('public')"
57             class="mt-20px"
58             loading
59           />
60         </el-tab-pane>
61       </el-tabs>
62     </el-main>
63   </el-container>
64 </template>
65
66 <script setup lang="ts">
67 import {ref} from 'vue'
68 import RoleHeader from './RoleHeader.vue'
69 import RoleList from './RoleList.vue'
70 import ChatRoleForm from '@/views/ai/model/chatRole/ChatRoleForm.vue'
71 import RoleCategoryList from './RoleCategoryList.vue'
72 import {ChatRoleApi, ChatRolePageReqVO, ChatRoleVO} from '@/api/ai/model/chatRole'
73 import {ChatConversationApi, ChatConversationVO} from '@/api/ai/chat/conversation'
74 import {Search} from '@element-plus/icons-vue'
75 import {TabsPaneContext} from 'element-plus'
76
77 const router = useRouter() // 路由对象
78
79 // 属性定义
80 const loading = ref<boolean>(false) // 加载中
81 const activeTab = ref<string>('my-role') // 选中的角色 Tab
82 const search = ref<string>('') // 加载中
83 const myRoleParams = reactive({
84   pageNo: 1,
85   pageSize: 50
86 })
87 const myRoleList = ref<ChatRoleVO[]>([]) // my 分页大小
88 const publicRoleParams = reactive({
89   pageNo: 1,
90   pageSize: 50
91 })
92 const publicRoleList = ref<ChatRoleVO[]>([]) // public 分页大小
93 const activeCategory = ref<string>('全部') // 选择中的分类
94 const categoryList = ref<string[]>([]) // 角色分类类别
95
96 /** tabs 点击 */
97 const handleTabsClick = async (tab: TabsPaneContext) => {
98   // 设置切换状态
99   activeTab.value = tab.paneName + ''
100   // 切换的时候重新加载数据
101   await getActiveTabsRole()
102 }
103
104 /** 获取 my role 我的角色 */
105 const getMyRole = async (append?: boolean) => {
106   const params: ChatRolePageReqVO = {
107     ...myRoleParams,
108     name: search.value,
109     publicStatus: false
110   }
111   const { list } = await ChatRoleApi.getMyPage(params)
112   if (append) {
113     myRoleList.value.push.apply(myRoleList.value, list)
114   } else {
115     myRoleList.value = list
116   }
117 }
118
119 /** 获取 public role 公共角色 */
120 const getPublicRole = async (append?: boolean) => {
121   const params: ChatRolePageReqVO = {
122     ...publicRoleParams,
123     category: activeCategory.value === '全部' ? '' : activeCategory.value,
124     name: search.value,
125     publicStatus: true
126   }
127   const { total, list } = await ChatRoleApi.getMyPage(params)
128   if (append) {
129     publicRoleList.value.push.apply(publicRoleList.value, list)
130   } else {
131     publicRoleList.value = list
132   }
133 }
134
135 /** 获取选中的 tabs 角色 */
136 const getActiveTabsRole = async () => {
137   if (activeTab.value === 'my-role') {
138     myRoleParams.pageNo = 1
139     await getMyRole()
140   } else {
141     publicRoleParams.pageNo = 1
142     await getPublicRole()
143   }
144 }
145
146 /** 获取角色分类列表 */
147 const getRoleCategoryList = async () => {
148   categoryList.value = ['全部', ...(await ChatRoleApi.getCategoryList())]
149 }
150
151 /** 处理分类点击 */
152 const handlerCategoryClick = async (category: string) => {
153   // 切换选择的分类
154   activeCategory.value = category
155   // 筛选
156   await getActiveTabsRole()
157 }
158
159 /** 添加/修改操作 */
160 const formRef = ref()
161 const handlerAddRole = async () => {
162   formRef.value.open('my-create', null, '添加角色')
163 }
164 /** 编辑角色 */
165 const handlerCardEdit = async (role) => {
166   formRef.value.open('my-update', role.id, '编辑角色')
167 }
168
169 /** 添加角色成功 */
170 const handlerAddRoleSuccess = async (e) => {
171   // 刷新数据
172   await getActiveTabsRole()
173 }
174
175 /** 删除角色 */
176 const handlerCardDelete = async (role) => {
177   await ChatRoleApi.deleteMy(role.id)
178   // 刷新数据
179   await getActiveTabsRole()
180 }
181
182 /** 角色分页:获取下一页 */
183 const handlerCardPage = async (type) => {
184   try {
185     loading.value = true
186     if (type === 'public') {
187       publicRoleParams.pageNo++
188       await getPublicRole(true)
189     } else {
190       myRoleParams.pageNo++
191       await getMyRole(true)
192     }
193   } finally {
194     loading.value = false
195   }
196 }
197
198 /** 选择 card 角色:新建聊天对话 */
199 const handlerCardUse = async (role) => {
200   // 1. 创建对话
201   const data: ChatConversationVO = {
202     roleId: role.id
203   } as unknown as ChatConversationVO
204   const conversationId = await ChatConversationApi.createChatConversationMy(data)
205
206   // 2. 跳转页面
207   await router.push({
208     name: 'AiChat',
209     query: {
210       conversationId: conversationId
211     }
212   })
213 }
214
215 /** 初始化 **/
216 onMounted(async () => {
217   // 获取分类
218   await getRoleCategoryList()
219   // 获取 role 数据
220   await getActiveTabsRole()
221 })
222 </script>
223 <!-- 覆盖 element ui css -->
224 <style lang="scss">
225 .el-tabs__content {
226   position: relative;
227   height: 100%;
228   overflow: hidden;
229 }
230 .el-tabs__nav-scroll {
231   margin: 10px 20px;
232 }
233 </style>
234 <!-- 样式 -->
235 <style scoped lang="scss">
236 // 跟容器
237 .role-container {
238   position: absolute;
239   width: 100%;
240   height: 100%;
241   margin: 0;
242   padding: 0;
243   left: 0;
244   right: 0;
245   top: 0;
246   bottom: 0;
247   background-color: #ffffff;
248   overflow: hidden;
249   display: flex;
250   flex-direction: column;
251
252   .role-main {
253     flex: 1;
254     overflow: hidden;
255     margin: 0;
256     padding: 0;
257     position: relative;
258
259     .search-container {
260       margin: 20px 20px 0px 20px;
261       position: absolute;
262       right: 0;
263       top: -5px;
264       z-index: 100;
265     }
266
267     .search-input {
268       width: 240px;
269     }
270
271     .tabs {
272       position: relative;
273       height: 100%;
274
275       .role-category-list {
276         margin: 0 27px;
277       }
278     }
279
280     .role-pane {
281       display: flex;
282       flex-direction: column;
283       height: 100%;
284       overflow-y: auto;
285       position: relative;
286     }
287   }
288 }
289 </style>