111
This commit is contained in:
72
src/api/agentCardKeys.js
Normal file
72
src/api/agentCardKeys.js
Normal file
@@ -0,0 +1,72 @@
|
||||
import { apiRequest } from "./client.js";
|
||||
|
||||
/**
|
||||
* @param {string} token
|
||||
* @param {RequestInit} [options]
|
||||
*/
|
||||
function agentRequest(token, path, options = {}) {
|
||||
return apiRequest(path, {
|
||||
...options,
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
...options.headers,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} token
|
||||
* @param {{
|
||||
* page?: number,
|
||||
* pageSize?: number,
|
||||
* status?: string,
|
||||
* username?: string,
|
||||
* oemId?: number | null,
|
||||
* agentId?: number | null,
|
||||
* }} [params]
|
||||
*/
|
||||
export function listAgentCardKeysApi(
|
||||
token,
|
||||
{ page = 1, pageSize = 20, status = "all", username, oemId, agentId } = {},
|
||||
) {
|
||||
const query = new URLSearchParams({
|
||||
page: String(page),
|
||||
page_size: String(pageSize),
|
||||
status,
|
||||
});
|
||||
const trimmed = username?.trim();
|
||||
if (trimmed) query.set("username", trimmed);
|
||||
if (oemId != null) query.set("oem_id", String(oemId));
|
||||
if (agentId != null) query.set("agent_id", String(agentId));
|
||||
return agentRequest(token, `/agent/card-keys?${query}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} token
|
||||
* @param {object} payload
|
||||
*/
|
||||
export function createAgentCardKeysApi(token, payload) {
|
||||
return agentRequest(token, "/agent/card-keys", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} token
|
||||
* @param {number} cardId
|
||||
* @param {object} payload
|
||||
*/
|
||||
export function updateAgentCardKeyApi(token, cardId, payload) {
|
||||
return agentRequest(token, `/agent/card-keys/${cardId}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
}
|
||||
|
||||
/** @param {string} token @param {number} cardId */
|
||||
export function deleteAgentCardKeyApi(token, cardId) {
|
||||
return agentRequest(token, `/agent/card-keys/${cardId}`, {
|
||||
method: "DELETE",
|
||||
});
|
||||
}
|
||||
72
src/api/agentUsers.js
Normal file
72
src/api/agentUsers.js
Normal file
@@ -0,0 +1,72 @@
|
||||
import { apiRequest } from "./client.js";
|
||||
|
||||
/**
|
||||
* @param {string} token
|
||||
* @param {RequestInit} [options]
|
||||
*/
|
||||
function agentRequest(token, path, options = {}) {
|
||||
return apiRequest(path, {
|
||||
...options,
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
...options.headers,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} token
|
||||
* @param {{
|
||||
* page?: number,
|
||||
* pageSize?: number,
|
||||
* username?: string,
|
||||
* oemId?: number | null,
|
||||
* agentId?: number | null,
|
||||
* roleId?: number | null,
|
||||
* }} [params]
|
||||
*/
|
||||
export function listAgentUsersApi(
|
||||
token,
|
||||
{ page = 1, pageSize = 20, username, oemId, agentId, roleId } = {},
|
||||
) {
|
||||
const query = new URLSearchParams({
|
||||
page: String(page),
|
||||
page_size: String(pageSize),
|
||||
});
|
||||
const trimmed = username?.trim();
|
||||
if (trimmed) query.set("username", trimmed);
|
||||
if (oemId != null) query.set("oem_id", String(oemId));
|
||||
if (agentId != null) query.set("agent_id", String(agentId));
|
||||
if (roleId != null) query.set("role_id", String(roleId));
|
||||
return agentRequest(token, `/agent/users?${query}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} token
|
||||
* @param {object} payload
|
||||
*/
|
||||
export function createAgentUserApi(token, payload) {
|
||||
return agentRequest(token, "/agent/users", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} token
|
||||
* @param {number} userId
|
||||
* @param {object} payload
|
||||
*/
|
||||
export function updateAgentUserApi(token, userId, payload) {
|
||||
return agentRequest(token, `/agent/users/${userId}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
}
|
||||
|
||||
/** @param {string} token @param {number} userId */
|
||||
export function deleteAgentUserApi(token, userId) {
|
||||
return agentRequest(token, `/agent/users/${userId}`, {
|
||||
method: "DELETE",
|
||||
});
|
||||
}
|
||||
@@ -6,10 +6,9 @@ const route = useRoute();
|
||||
|
||||
const menuItems = [
|
||||
|
||||
{ name: "admin-users", label: "用户管理", to: "/admin/users" },
|
||||
{ name: "admin-card-keys", label: "卡密管理", to: "/admin/card-keys" },
|
||||
{ name: "admin-desktop-config", label: "桌面配置", to: "/admin/desktop-config" },
|
||||
{ name: "admin-overview", label: "软件配置", to: "/admin" },
|
||||
{ name: "agent-users", label: "用户管理", to: "/agent/users" },
|
||||
{ name: "agent-card-keys", label: "卡密管理", to: "/agent/card-keys" },
|
||||
|
||||
];
|
||||
|
||||
const activeName = computed(() => route.name);
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
<script setup>
|
||||
import { useAuthStore } from "../stores/auth";
|
||||
|
||||
const auth = useAuthStore();
|
||||
import AgentSubNav from "../components/agent/AgentSubNav.vue";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex h-full flex-col items-center justify-center gap-3 p-8">
|
||||
<h1 class="gradient-text text-xl font-semibold">代理工作台</h1>
|
||||
<p class="text-sm text-text-muted">
|
||||
当前用户:{{ auth.currentUser?.username }}(代理)
|
||||
</p>
|
||||
<div class="admin-layout">
|
||||
<AgentSubNav />
|
||||
<div class="admin-layout__content custom-scrollbar">
|
||||
<RouterView />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
import { computed, onMounted, ref, watch } from "vue";
|
||||
import { useAuthStore, ROLE_AGENT, ROLE_OEM } from "../../stores/auth.js";
|
||||
import {
|
||||
listAdminCardKeysApi,
|
||||
createAdminCardKeysApi,
|
||||
updateAdminCardKeyApi,
|
||||
deleteAdminCardKeyApi,
|
||||
} from "../../api/adminCardKeys.js";
|
||||
import { listAdminUsersApi } from "../../api/adminUsers.js";
|
||||
listAgentCardKeysApi,
|
||||
createAgentCardKeysApi,
|
||||
updateAgentCardKeyApi,
|
||||
deleteAgentCardKeyApi,
|
||||
} from "../../api/agentCardKeys.js";
|
||||
import { listAgentUsersApi } from "../../api/agentUsers.js";
|
||||
|
||||
const auth = useAuthStore();
|
||||
|
||||
@@ -92,8 +92,8 @@ function showMessage(severity, message) {
|
||||
|
||||
async function loadFilterOptions() {
|
||||
const [oemRes, agentRes] = await Promise.all([
|
||||
listAdminUsersApi(auth.token, { page: 1, pageSize: 200, roleId: ROLE_OEM }),
|
||||
listAdminUsersApi(auth.token, { page: 1, pageSize: 200, roleId: ROLE_AGENT }),
|
||||
listAgentUsersApi(auth.token, { page: 1, pageSize: 200, roleId: ROLE_OEM }),
|
||||
listAgentUsersApi(auth.token, { page: 1, pageSize: 200, roleId: ROLE_AGENT }),
|
||||
]);
|
||||
if (oemRes.ok && Array.isArray(oemRes.data?.items)) {
|
||||
oemOptions.value = oemRes.data.items;
|
||||
@@ -106,7 +106,7 @@ async function loadFilterOptions() {
|
||||
async function loadCards() {
|
||||
loading.value = true;
|
||||
feedback.value = { severity: "", message: "" };
|
||||
const res = await listAdminCardKeysApi(auth.token, {
|
||||
const res = await listAgentCardKeysApi(auth.token, {
|
||||
page: page.value,
|
||||
pageSize: pageSize.value,
|
||||
status: statusFilter.value,
|
||||
@@ -223,9 +223,9 @@ async function saveCard() {
|
||||
}
|
||||
payload.serial_number = serial.toUpperCase();
|
||||
}
|
||||
res = await createAdminCardKeysApi(auth.token, payload);
|
||||
res = await createAgentCardKeysApi(auth.token, payload);
|
||||
} else {
|
||||
res = await updateAdminCardKeyApi(auth.token, editingId.value, {
|
||||
res = await updateAgentCardKeyApi(auth.token, editingId.value, {
|
||||
duration_days: isActivated.value ? undefined : form.value.duration_days,
|
||||
remark: form.value.remark.trim() || null,
|
||||
});
|
||||
@@ -252,7 +252,7 @@ async function removeCard(row) {
|
||||
const ok = window.confirm(`确定删除卡密「${row.serial_number}」?`);
|
||||
if (!ok) return;
|
||||
|
||||
const res = await deleteAdminCardKeyApi(auth.token, row.id);
|
||||
const res = await deleteAgentCardKeyApi(auth.token, row.id);
|
||||
if (!res.ok) {
|
||||
showMessage("error", res.message || "删除失败");
|
||||
return;
|
||||
@@ -286,7 +286,7 @@ onMounted(async () => {
|
||||
<div>
|
||||
<h1 class="admin-page__title gradient-text">卡密管理</h1>
|
||||
</div>
|
||||
<Button label="生成卡密" @click="openCreateDialog" />
|
||||
|
||||
</div>
|
||||
|
||||
<Message
|
||||
@@ -306,26 +306,8 @@ onMounted(async () => {
|
||||
class="admin-users__search"
|
||||
@keyup.enter="applyFilters"
|
||||
/>
|
||||
<Select
|
||||
v-model="filters.oem_id"
|
||||
:options="oemOptions"
|
||||
option-label="username"
|
||||
option-value="id"
|
||||
placeholder="全部 OEM"
|
||||
show-clear
|
||||
filter
|
||||
class="admin-users__filter-select"
|
||||
/>
|
||||
<Select
|
||||
v-model="filters.agent_id"
|
||||
:options="agentOptions"
|
||||
option-label="username"
|
||||
option-value="id"
|
||||
placeholder="全部代理"
|
||||
show-clear
|
||||
filter
|
||||
class="admin-users__filter-select"
|
||||
/>
|
||||
|
||||
|
||||
<label class="text-sm text-text-muted">状态</label>
|
||||
<Select
|
||||
v-model="statusFilter"
|
||||
@@ -405,27 +387,7 @@ onMounted(async () => {
|
||||
{{ data.remark || "—" }}
|
||||
</template>
|
||||
</Column>
|
||||
<Column header="操作" style="width: 9rem">
|
||||
<template #body="{ data }">
|
||||
<div class="admin-users__actions">
|
||||
<Button
|
||||
label="编辑"
|
||||
size="small"
|
||||
severity="secondary"
|
||||
text
|
||||
@click="openEditDialog(data)"
|
||||
/>
|
||||
<Button
|
||||
label="删除"
|
||||
size="small"
|
||||
severity="danger"
|
||||
text
|
||||
:disabled="!!data.activated_at"
|
||||
@click="removeCard(data)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</Column>
|
||||
|
||||
<template #empty>
|
||||
<p class="py-6 text-center text-sm text-text-muted">暂无卡密</p>
|
||||
</template>
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
import { computed, onMounted, ref } from "vue";
|
||||
import { useAuthStore, ROLE_ADMIN, ROLE_AGENT,ROLE_OEM } from "../../stores/auth.js";
|
||||
import {
|
||||
listAdminUsersApi,
|
||||
createAdminUserApi,
|
||||
updateAdminUserApi,
|
||||
deleteAdminUserApi,
|
||||
} from "../../api/adminUsers.js";
|
||||
listAgentUsersApi,
|
||||
createAgentUserApi,
|
||||
updateAgentUserApi,
|
||||
deleteAgentUserApi,
|
||||
} from "../../api/agentUsers.js";
|
||||
|
||||
const auth = useAuthStore();
|
||||
|
||||
@@ -103,8 +103,8 @@ function showMessage(severity, message) {
|
||||
|
||||
async function loadFilterOptions() {
|
||||
const [oemRes, agentRes] = await Promise.all([
|
||||
listAdminUsersApi(auth.token, { page: 1, pageSize: 200, roleId: ROLE_OEM }),
|
||||
listAdminUsersApi(auth.token, { page: 1, pageSize: 200, roleId: ROLE_AGENT }),
|
||||
listAgentUsersApi(auth.token, { page: 1, pageSize: 200, roleId: ROLE_OEM }),
|
||||
listAgentUsersApi(auth.token, { page: 1, pageSize: 200, roleId: ROLE_AGENT }),
|
||||
]);
|
||||
if (oemRes.ok && Array.isArray(oemRes.data?.items)) {
|
||||
oemOptions.value = oemRes.data.items;
|
||||
@@ -117,7 +117,7 @@ async function loadFilterOptions() {
|
||||
async function loadUsers() {
|
||||
loading.value = true;
|
||||
feedback.value = { severity: "", message: "" };
|
||||
const res = await listAdminUsersApi(auth.token, {
|
||||
const res = await listAgentUsersApi(auth.token, {
|
||||
page: page.value,
|
||||
pageSize: pageSize.value,
|
||||
username: filters.value.username,
|
||||
@@ -218,9 +218,9 @@ async function saveUser() {
|
||||
showMessage("warn", "请设置初始密码");
|
||||
return;
|
||||
}
|
||||
res = await createAdminUserApi(auth.token, payload);
|
||||
res = await createAgentUserApi(auth.token, payload);
|
||||
} else {
|
||||
res = await updateAdminUserApi(auth.token, editingId.value, payload);
|
||||
res = await updateAgentUserApi(auth.token, editingId.value, payload);
|
||||
}
|
||||
|
||||
saving.value = false;
|
||||
@@ -244,7 +244,7 @@ async function removeUser(row) {
|
||||
const ok = window.confirm(`确定删除用户「${row.username}」?此操作不可恢复。`);
|
||||
if (!ok) return;
|
||||
|
||||
const res = await deleteAdminUserApi(auth.token, row.id);
|
||||
const res = await deleteAgentUserApi(auth.token, row.id);
|
||||
if (!res.ok) {
|
||||
showMessage("error", res.message || "删除失败");
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user