本地 RAG 知识库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

59 lines
3.1 KiB

<template>
<t-card title="👤 账号管理" :bordered="false">
<p class="desc-text">管理外部对接账号,为账号绑定客服角色以控制使用权限。</p>
<div class="toolbar">
<t-button theme="primary" size="small" @click="openCreate">+ 新建账号</t-button>
<t-button variant="outline" size="small" @click="loadList">🔄 刷新</t-button>
</div>
<BaseTable :data="accounts" :columns="columns" row-key="id" :loading="loading">
<template #roles="{row}"><t-tag v-for="r in (row.roleNames||[])" :key="r" size="small" variant="light" theme="primary" style="margin-right:4px;">{{ r }}</t-tag></template>
<template #op="{row}">
<t-space :size="4">
<t-button size="small" variant="text" @click="openEdit(row)">编辑</t-button>
<t-button size="small" variant="text" theme="danger" @click="doDelete(row.id)">删除</t-button>
</t-space>
</template>
</BaseTable>
<t-dialog v-model:visible="modal.visible" :header="modal.isEdit?'编辑账号':'新建账号'" width="480px" :footer="false">
<t-form label-align="top">
<t-form-item label="账号名称 *"><t-input v-model="modal.name" :disabled="modal.isEdit" placeholder="外部账号标识" /></t-form-item>
</t-form>
<div class="dialog-footer">
<t-button variant="outline" @click="modal.visible=false">取消</t-button>
<t-button theme="primary" @click="handleSave">保存</t-button>
</div>
</t-dialog>
</t-card>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { getAccountList, createAccount, updateAccount, deleteAccount } from '@/api/account'
import { toast } from '@/utils/toast'
import { useConfirm } from '@/composables/useConfirm'
const { confirm } = useConfirm()
const accounts=ref<any[]>([]); const loading=ref(false)
const columns=[{colKey:'name',title:'账号名称',width:160,sorter:true},{colKey:'roles',title:'绑定角色',width:240,sorter:true},{colKey:'op',title:'操作',width:120}]
const modal=reactive({visible:false,isEdit:false,id:null as any,name:''})
onMounted(()=>loadList())
async function loadList(){loading.value=true
try{const r=await getAccountList();if(r.success)accounts.value=r.data||[]}catch(e:any){toast('加载失败:'+e.message,'error')}finally{loading.value=false}}
function openCreate(){Object.assign(modal,{visible:true,isEdit:false,id:null,name:''})}
function openEdit(a:any){Object.assign(modal,{visible:true,isEdit:true,id:a.id,name:a.name||''})}
async function handleSave(){
try{let r;if(modal.isEdit)r=await updateAccount(modal.id,{name:modal.name});else r=await createAccount({name:modal.name})
if(r.success){toast('保存成功','success');modal.visible=false;loadList()}else toast(r.message||'操作失败','error')}catch(e:any){toast('操作失败:'+e.message,'error')}}
async function doDelete(id:string){if(!await confirm('确定删除?'))return
try{const r=await deleteAccount(id);if(r.success){toast('删除成功','success');loadList()}else toast(r.message||'删除失败','error')}catch(e:any){toast('删除失败:'+e.message,'error')}}
</script>
<style scoped></style>