index.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. <script setup lang="ts">
  2. defineOptions({
  3. name: 'Role Management',
  4. })
  5. import { Plus } from '@element-plus/icons-vue'
  6. import { ElButton, ElDialog, ElEmpty, ElInput, ElOption, ElPagination, ElSelect, ElTable, ElTableColumn, ElTag } from 'element-plus'
  7. // import SearchForm from './components/SearchForm.vue'
  8. import type { TAgent } from '@/types/role'
  9. import { anycallPage } from '@/api/modules/anycallService'
  10. import { formatDateGeneral } from '@/utils'
  11. const tableRef = ref()
  12. const loading = ref(false)
  13. const router = useRouter()
  14. const route = useRoute()
  15. // 搜索参数
  16. const searchParams = ref({
  17. name: '',
  18. })
  19. const dataList = ref<TAgent[]>([]);
  20. // 从URL获取初始分页参数
  21. const getInitialPagination = () => {
  22. const page = Number(route.query.page) || 1
  23. const size = Number(route.query.size) || 20
  24. return {
  25. total: 0,
  26. page: page > 0 ? page : 1,
  27. size: [10, 20, 50, 100].includes(size) ? size : 20,
  28. }
  29. }
  30. // 分页信息
  31. const pagination = ref(getInitialPagination())
  32. // 更新URL中的分页参数
  33. const updateUrlParams = (page: number, size: number) => {
  34. const query = {
  35. ...route.query,
  36. page: page.toString(),
  37. size: size.toString(),
  38. }
  39. // 使用replace模式更新URL,避免产生历史记录
  40. router.replace({
  41. path: route.path,
  42. query
  43. })
  44. }
  45. const handleRecommend = (id: string) => {
  46. }
  47. async function fetchData() {
  48. loading.value = true
  49. const res = await anycallPage({
  50. name: searchParams.value.name,
  51. page: pagination.value.page,
  52. size: pagination.value.size,
  53. })
  54. if(res.code === 0){
  55. dataList.value = res.data.content
  56. pagination.value.total = res.data.total
  57. }
  58. loading.value = false
  59. }
  60. function handlePageChange(page: number) {
  61. pagination.value.page = page
  62. updateUrlParams(page, pagination.value.size)
  63. fetchData()
  64. }
  65. function handleSizeChange(size: number) {
  66. pagination.value.size = size
  67. pagination.value.page = 1
  68. updateUrlParams(1, size)
  69. fetchData()
  70. }
  71. function handleSearch () {
  72. pagination.value.page = 1 // 搜索时重置到第一页
  73. updateUrlParams(1, pagination.value.size)
  74. fetchData()
  75. }
  76. function handleReset () {
  77. searchParams.value = {
  78. name: '',
  79. }
  80. pagination.value.page = 1 // 重置时重置到第一页
  81. updateUrlParams(1, pagination.value.size)
  82. fetchData()
  83. }
  84. // 监听URL参数变化,用于处理浏览器后退/前进
  85. watch(
  86. () => route.query,
  87. (newQuery) => {
  88. const newPage = Number(newQuery.page) || 1
  89. const newSize = Number(newQuery.size) || 20
  90. // 只有当参数真正发生变化时才更新
  91. if (newPage !== pagination.value.page || newSize !== pagination.value.size) {
  92. pagination.value.page = newPage > 0 ? newPage : 1
  93. pagination.value.size = [10, 20, 50, 100].includes(newSize) ? newSize : 20
  94. fetchData()
  95. }
  96. },
  97. { deep: true }
  98. )
  99. onMounted(async () => {
  100. await fetchData()
  101. })
  102. </script>
  103. <template>
  104. <div class="absolute-container">
  105. <FaPageHeader title="Role Management" />
  106. <FaPageMain class="flex-1 overflow-auto" main-class="flex-1 flex flex-col overflow-auto">
  107. <ElTable
  108. ref="tableRef" :data="dataList" stripe highlight-current-row border height="100%"
  109. >
  110. <ElTableColumn label="Role Name" prop="name" />
  111. <ElTableColumn label="Avatar" prop="photo">
  112. <template #default="{row}">
  113. <ElImage :src="row.photo" fit="cover" class="w-12 h-12 rounded" />
  114. </template>
  115. </ElTableColumn>
  116. <ElTableColumn label="callings" prop="callings" />
  117. <ElTableColumn label="prompt" prop="prompt" min-width="340">
  118. <template #default="{row}">
  119. <ElTag type="info" v-for="(tag, index) in row.prompt.split(/\,|\,/)" :key="index" class="mb-1 mr-1">
  120. <div :title="tag">{{ tag }}</div>
  121. </ElTag>
  122. </template>
  123. </ElTableColumn>
  124. <ElTableColumn label="Language" prop="language" />
  125. <ElTableColumn label="voiceName" prop="voiceName" />
  126. <ElTableColumn fixed="right" label="操作" min-width="200">
  127. <template #default="{row}">
  128. <ElButton link type="primary" size="small" @click="()=> handleRecommend(row.id)">
  129. 推荐
  130. </ElButton>
  131. </template>
  132. </ElTableColumn>
  133. </ElTable>
  134. <div class="p-4">
  135. <ElPagination
  136. v-model:current-page="pagination.page"
  137. v-model:page-size="pagination.size"
  138. :total="pagination.total"
  139. :page-sizes="[10, 20, 50, 100]"
  140. layout="total, sizes, prev, pager, next, jumper"
  141. @size-change="handleSizeChange"
  142. @current-change="handlePageChange"
  143. />
  144. </div>
  145. </FaPageMain>
  146. </div>
  147. </template>
  148. <style scoped>
  149. .absolute-container {
  150. position: absolute;
  151. display: flex;
  152. flex-direction: column;
  153. width: 100%;
  154. height: 100%;
  155. }
  156. </style>