RoleRepository.vue 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. <!-- chat 角色仓库 -->
  2. <template>
  3. <el-container
  4. class="role-container absolute w-full h-full m-0 p-0 left-0 right-0 top-0 bottom-0 bg-[var(--el-bg-color)] overflow-hidden flex !flex-col"
  5. >
  6. <ChatRoleForm ref="formRef" @success="handlerAddRoleSuccess" />
  7. <!-- header -->
  8. <RoleHeader title="角色仓库" class="relative" />
  9. <!-- main -->
  10. <el-main class="flex-1 overflow-hidden m-0 !p-0 relative">
  11. <div class="mx-5 mt-5 mb-0 absolute right-0 -top-1.25 z-100">
  12. <!-- 搜索按钮 -->
  13. <el-input
  14. :loading="loading"
  15. v-model="search"
  16. class="!w-60"
  17. size="default"
  18. placeholder="请输入搜索的内容"
  19. :suffix-icon="Search"
  20. @change="getActiveTabsRole"
  21. />
  22. <el-button
  23. v-if="activeTab == 'my-role'"
  24. type="primary"
  25. @click="handlerAddRole"
  26. class="ml-20px"
  27. >
  28. <Icon icon="ep:user" class="mr-1.25" />
  29. 添加角色
  30. </el-button>
  31. </div>
  32. <!-- tabs -->
  33. <el-tabs
  34. v-model="activeTab"
  35. @tab-click="handleTabsClick"
  36. class="relative h-full [&_.el-tabs__nav-scroll]:my-2.5 [&_.el-tabs__nav-scroll]:mx-5"
  37. >
  38. <el-tab-pane
  39. label="我的角色"
  40. name="my-role"
  41. class="flex flex-col h-full overflow-y-auto relative"
  42. >
  43. <RoleList
  44. :loading="loading"
  45. :role-list="myRoleList"
  46. :show-more="true"
  47. @on-delete="handlerCardDelete"
  48. @on-edit="handlerCardEdit"
  49. @on-use="handlerCardUse"
  50. @on-page="handlerCardPage('my')"
  51. class="mt-20px"
  52. />
  53. </el-tab-pane>
  54. <el-tab-pane label="公共角色" name="public-role">
  55. <RoleCategoryList
  56. class="mx-6.75"
  57. :category-list="categoryList"
  58. :active="activeCategory"
  59. @on-category-click="handlerCategoryClick"
  60. />
  61. <RoleList
  62. :role-list="publicRoleList"
  63. @on-delete="handlerCardDelete"
  64. @on-edit="handlerCardEdit"
  65. @on-use="handlerCardUse"
  66. @on-page="handlerCardPage('public')"
  67. class="mt-20px"
  68. loading
  69. />
  70. </el-tab-pane>
  71. </el-tabs>
  72. </el-main>
  73. </el-container>
  74. </template>
  75. <script setup lang="ts">
  76. import { ref } from 'vue'
  77. import RoleHeader from './RoleHeader.vue'
  78. import RoleList from './RoleList.vue'
  79. import ChatRoleForm from '@/views/ai/model/chatRole/ChatRoleForm.vue'
  80. import RoleCategoryList from './RoleCategoryList.vue'
  81. import { ChatRoleApi, ChatRolePageReqVO, ChatRoleVO } from '@/api/ai/model/chatRole'
  82. import { ChatConversationApi, ChatConversationVO } from '@/api/ai/chat/conversation'
  83. import { Search } from '@element-plus/icons-vue'
  84. import { TabsPaneContext } from 'element-plus'
  85. const router = useRouter() // 路由对象
  86. // 属性定义
  87. const loading = ref<boolean>(false) // 加载中
  88. const activeTab = ref<string>('my-role') // 选中的角色 Tab
  89. const search = ref<string>('') // 加载中
  90. const myRoleParams = reactive({
  91. pageNo: 1,
  92. pageSize: 50
  93. })
  94. const myRoleList = ref<ChatRoleVO[]>([]) // my 分页大小
  95. const publicRoleParams = reactive({
  96. pageNo: 1,
  97. pageSize: 50
  98. })
  99. const publicRoleList = ref<ChatRoleVO[]>([]) // public 分页大小
  100. const activeCategory = ref<string>('全部') // 选择中的分类
  101. const categoryList = ref<string[]>([]) // 角色分类类别
  102. /** tabs 点击 */
  103. const handleTabsClick = async (tab: TabsPaneContext) => {
  104. // 设置切换状态
  105. activeTab.value = tab.paneName + ''
  106. // 切换的时候重新加载数据
  107. await getActiveTabsRole()
  108. }
  109. /** 获取 my role 我的角色 */
  110. const getMyRole = async (append?: boolean) => {
  111. const params: ChatRolePageReqVO = {
  112. ...myRoleParams,
  113. name: search.value,
  114. publicStatus: false
  115. }
  116. const { list } = await ChatRoleApi.getMyPage(params)
  117. if (append) {
  118. myRoleList.value.push.apply(myRoleList.value, list)
  119. } else {
  120. myRoleList.value = list
  121. }
  122. }
  123. /** 获取 public role 公共角色 */
  124. const getPublicRole = async (append?: boolean) => {
  125. const params: ChatRolePageReqVO = {
  126. ...publicRoleParams,
  127. category: activeCategory.value === '全部' ? '' : activeCategory.value,
  128. name: search.value,
  129. publicStatus: true
  130. }
  131. const { total, list } = await ChatRoleApi.getMyPage(params)
  132. if (append) {
  133. publicRoleList.value.push.apply(publicRoleList.value, list)
  134. } else {
  135. publicRoleList.value = list
  136. }
  137. }
  138. /** 获取选中的 tabs 角色 */
  139. const getActiveTabsRole = async () => {
  140. if (activeTab.value === 'my-role') {
  141. myRoleParams.pageNo = 1
  142. await getMyRole()
  143. } else {
  144. publicRoleParams.pageNo = 1
  145. await getPublicRole()
  146. }
  147. }
  148. /** 获取角色分类列表 */
  149. const getRoleCategoryList = async () => {
  150. categoryList.value = ['全部', ...(await ChatRoleApi.getCategoryList())]
  151. }
  152. /** 处理分类点击 */
  153. const handlerCategoryClick = async (category: string) => {
  154. // 切换选择的分类
  155. activeCategory.value = category
  156. // 筛选
  157. await getActiveTabsRole()
  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. const handlerAddRoleSuccess = async (e) => {
  170. // 刷新数据
  171. await getActiveTabsRole()
  172. }
  173. /** 删除角色 */
  174. const handlerCardDelete = async (role) => {
  175. await ChatRoleApi.deleteMy(role.id)
  176. // 刷新数据
  177. await getActiveTabsRole()
  178. }
  179. /** 角色分页:获取下一页 */
  180. const handlerCardPage = async (type) => {
  181. try {
  182. loading.value = true
  183. if (type === 'public') {
  184. publicRoleParams.pageNo++
  185. await getPublicRole(true)
  186. } else {
  187. myRoleParams.pageNo++
  188. await getMyRole(true)
  189. }
  190. } finally {
  191. loading.value = false
  192. }
  193. }
  194. /** 选择 card 角色:新建聊天对话 */
  195. const handlerCardUse = async (role) => {
  196. // 1. 创建对话
  197. const data: ChatConversationVO = {
  198. roleId: role.id
  199. } as unknown as ChatConversationVO
  200. const conversationId = await ChatConversationApi.createChatConversationMy(data)
  201. // 2. 跳转页面
  202. await router.push({
  203. name: 'AiChat',
  204. query: {
  205. conversationId: conversationId
  206. }
  207. })
  208. }
  209. /** 初始化 **/
  210. onMounted(async () => {
  211. // 获取分类
  212. await getRoleCategoryList()
  213. // 获取 role 数据
  214. await getActiveTabsRole()
  215. })
  216. </script>
  217. <!-- 覆盖 element plus css -->
  218. <style lang="scss">
  219. .el-tabs__nav-scroll {
  220. margin: 10px 20px;
  221. }
  222. </style>