style(ops-web): unify table actions as circular icon buttons

Replace the mixed text-link / button action lists in Accounts,
AdminUsers, and SiteDomainMappings with a shared .table-actions-row +
.action-* class set in styles.css. Each row now renders compact icon
buttons (edit/delete/approve/revoke/key/kol/reset/play) tinted by intent,
matching the new KolSubscriptions console look.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-29 22:07:55 +08:00
parent 73fd7db21a
commit 0729b76cc7
4 changed files with 150 additions and 40 deletions
+56
View File
@@ -48,3 +48,59 @@ body {
font-weight: 600;
border-bottom: 1px solid #e2e8f0;
}
/* Table action buttons */
.table-actions-row {
display: flex;
align-items: center;
gap: 4px;
}
.action-btn.ant-btn {
color: #64748b;
}
.action-btn.ant-btn:hover:not(:disabled) {
color: #334155;
background: #f1f5f9;
}
.action-edit.ant-btn:hover:not(:disabled) {
color: #1677ff;
background: #e6f4ff;
}
.action-delete.ant-btn:hover:not(:disabled) {
color: #ff4d4f;
background: #fff2f0;
}
.action-approve.ant-btn:hover:not(:disabled) {
color: #52c41a;
background: #f6ffed;
}
.action-revoke.ant-btn:hover:not(:disabled) {
color: #faad14;
background: #fffbe6;
}
.action-key.ant-btn:hover:not(:disabled) {
color: #722ed1;
background: #f9f0ff;
}
.action-kol.ant-btn:hover:not(:disabled) {
color: #fa8c16;
background: #fff2e8;
}
.action-reset.ant-btn:hover:not(:disabled) {
color: #13c2c2;
background: #e6fffb;
}
.action-play.ant-btn:hover:not(:disabled) {
color: #52c41a;
background: #f6ffed;
}
+33 -12
View File
@@ -45,18 +45,38 @@
{{ formatDate(record.created_at) }}
</template>
<template v-else-if="column.key === 'actions'">
<a-space>
<a @click="openResetPassword(record)">重置密码</a>
<a-popconfirm
:title="record.status === 'active' ? '确认停用该账号?' : '确认启用该账号?'"
:disabled="record.id === auth.operator?.id"
@confirm="toggleStatus(record)"
>
<a :class="{ disabled: record.id === auth.operator?.id }">
{{ record.status === "active" ? "停用" : "启用" }}
</a>
</a-popconfirm>
</a-space>
<div class="table-actions-row">
<a-tooltip title="重置密码">
<a-button
type="text"
shape="circle"
size="small"
class="action-btn action-key"
@click="openResetPassword(record)"
>
<KeyOutlined />
</a-button>
</a-tooltip>
<a-tooltip :title="record.status === 'active' ? '停用账号' : '启用账号'">
<a-popconfirm
:title="record.status === 'active' ? '确认停用该账号?' : '确认启用该账号?'"
:disabled="record.id === auth.operator?.id"
@confirm="toggleStatus(record)"
>
<a-button
type="text"
shape="circle"
size="small"
:class="['action-btn', record.status === 'active' ? 'action-revoke' : 'action-play']"
:disabled="record.id === auth.operator?.id"
>
<StopOutlined v-if="record.status === 'active'" />
<PlayCircleOutlined v-else />
</a-button>
</a-popconfirm>
</a-tooltip>
</div>
</template>
</template>
</a-table>
@@ -101,6 +121,7 @@
</template>
<script setup lang="ts">
import { KeyOutlined, StopOutlined, PlayCircleOutlined } from "@ant-design/icons-vue";
import type { TablePaginationConfig } from "ant-design-vue";
import { message } from "ant-design-vue";
import dayjs from "dayjs";
+51 -18
View File
@@ -84,24 +84,49 @@
{{ formatDate(record.created_at) }}
</template>
<template v-else-if="column.key === 'actions'">
<a-space>
<a @click="openEdit(record)">编辑</a>
<a @click="openKol(record)">KOL身份</a>
<a-popconfirm
title="确认恢复当前套餐默认额度?文章生成次数和 AI 点数会恢复到套餐默认值。"
:ok-button-props="{ danger: true, loading: resetUsageLoadingId === record.id }"
@confirm="resetPlanUsage(record)"
>
<a>恢复额度</a>
</a-popconfirm>
<a @click="openResetPassword(record)">重置密码</a>
<a-popconfirm
:title="record.status === 'active' ? '确认停用该用户?' : '确认启用该用户?'"
@confirm="toggleStatus(record)"
>
<a>{{ record.status === "active" ? "停用" : "启用" }}</a>
</a-popconfirm>
</a-space>
<div class="table-actions-row">
<a-tooltip title="编辑">
<a-button type="text" shape="circle" size="small" class="action-btn action-edit" @click="openEdit(record)">
<EditOutlined />
</a-button>
</a-tooltip>
<a-tooltip title="KOL身份">
<a-button type="text" shape="circle" size="small" class="action-btn action-kol" @click="openKol(record)">
<IdcardOutlined />
</a-button>
</a-tooltip>
<a-tooltip title="恢复套餐默认额度">
<a-popconfirm
title="确认恢复当前套餐默认额度?文章生成次数和 AI 点数会恢复到套餐默认值。"
:ok-button-props="{ danger: true, loading: resetUsageLoadingId === record.id }"
@confirm="resetPlanUsage(record)"
>
<a-button type="text" shape="circle" size="small" class="action-btn action-reset">
<ReloadOutlined />
</a-button>
</a-popconfirm>
</a-tooltip>
<a-tooltip title="重置密码">
<a-button type="text" shape="circle" size="small" class="action-btn action-key" @click="openResetPassword(record)">
<KeyOutlined />
</a-button>
</a-tooltip>
<a-tooltip :title="record.status === 'active' ? '停用用户' : '启用用户'">
<a-popconfirm
:title="record.status === 'active' ? '确认停用该用户?' : '确认启用该用户?'"
@confirm="toggleStatus(record)"
>
<a-button type="text" shape="circle" size="small" :class="['action-btn', record.status === 'active' ? 'action-revoke' : 'action-play']">
<StopOutlined v-if="record.status === 'active'" />
<PlayCircleOutlined v-else />
</a-button>
</a-popconfirm>
</a-tooltip>
</div>
</template>
</template>
</a-table>
@@ -212,6 +237,14 @@
</template>
<script setup lang="ts">
import {
EditOutlined,
IdcardOutlined,
ReloadOutlined,
KeyOutlined,
StopOutlined,
PlayCircleOutlined,
} from "@ant-design/icons-vue";
import type { TableColumnsType, TablePaginationConfig } from "ant-design-vue";
import { message } from "ant-design-vue";
import dayjs from "dayjs";
@@ -70,20 +70,20 @@
{{ formatDate(record.updated_at) }}
</template>
<template v-else-if="column.key === 'actions'">
<a-space :size="4">
<div class="table-actions-row" style="justify-content: flex-end;">
<a-tooltip title="编辑">
<a-button type="text" size="small" @click="openEdit(record)">
<template #icon><EditOutlined /></template>
<a-button type="text" shape="circle" size="small" class="action-btn action-edit" @click="openEdit(record)">
<EditOutlined />
</a-button>
</a-tooltip>
<a-popconfirm title="确认删除该映射?" @confirm="deleteMapping(record)">
<a-tooltip title="删除">
<a-button type="text" danger size="small">
<template #icon><DeleteOutlined /></template>
<a-tooltip title="删除">
<a-popconfirm title="确认删除该映射?" @confirm="deleteMapping(record)">
<a-button type="text" shape="circle" size="small" class="action-btn action-delete">
<DeleteOutlined />
</a-button>
</a-tooltip>
</a-popconfirm>
</a-space>
</a-popconfirm>
</a-tooltip>
</div>
</template>
</template>
</a-table>