账号支持只看本账号看板;模板重新解析改为保留原映射并多轮补缺。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -31,6 +31,10 @@ export type AccountRow = {
|
||||
phoneMasked: string;
|
||||
lastLogin: string;
|
||||
status: 'active' | 'disabled';
|
||||
/** 只看本账号看板数据 */
|
||||
dashboardSelfOnly: boolean;
|
||||
/** 内置超管:列表禁编、展示固定为超级管理员 */
|
||||
isSuperAdmin: boolean;
|
||||
};
|
||||
|
||||
const ROLE_TAG_CYCLE = ['tag-violet', 'tag-blue', 'tag-teal', 'tag-amber'];
|
||||
@@ -39,6 +43,16 @@ export function roleTagFor(index: number) {
|
||||
return ROLE_TAG_CYCLE[index % ROLE_TAG_CYCLE.length];
|
||||
}
|
||||
|
||||
/** username=admin 或角色码/名含超级管理员 → 内置超管 */
|
||||
export function isSuperAdminUser(u: { username?: string; roleLabel?: string; roleCode?: string }) {
|
||||
const name = String(u.username || '').trim().toLowerCase();
|
||||
if (name === 'admin') return true;
|
||||
const code = String(u.roleCode || '').trim().toLowerCase();
|
||||
if (code === 'admin') return true;
|
||||
const label = String(u.roleLabel || '');
|
||||
return label.includes('超级管理员');
|
||||
}
|
||||
|
||||
/** Jeecg status:1 正常 → active;其余视为禁用。 */
|
||||
export function mapUserToAccount(
|
||||
u: any,
|
||||
@@ -46,16 +60,20 @@ export function mapUserToAccount(
|
||||
roleLabel = '未绑定角色',
|
||||
roleTag = 'tag-blue',
|
||||
): AccountRow {
|
||||
const username = u.username || '';
|
||||
const superAdmin = isSuperAdminUser({ username, roleLabel });
|
||||
return {
|
||||
id: String(u.id || ''),
|
||||
username: u.username || '',
|
||||
username,
|
||||
name: u.realname || u.username || '',
|
||||
wecomUserId: u.workNo || u.wecomId || u.thirdId || '',
|
||||
roleId,
|
||||
roleLabel,
|
||||
roleTag,
|
||||
roleLabel: superAdmin ? '超级管理员' : roleLabel,
|
||||
roleTag: superAdmin ? 'tag-violet' : roleTag,
|
||||
phoneMasked: u.phone || '未填写',
|
||||
lastLogin: u.lastLoginTime || u.createTime || '—',
|
||||
status: Number(u.status) === 1 ? 'active' : 'disabled',
|
||||
dashboardSelfOnly: Boolean(u.dashboardSelfOnly === true || u.dashboardSelfOnly === 1),
|
||||
isSuperAdmin: superAdmin,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ const loading = ref(false);
|
||||
const total = ref(0);
|
||||
const pageNo = ref(1);
|
||||
const pageSize = ref(10);
|
||||
const roleOptions = ref<{ value: string; label: string; tag: string }[]>([]);
|
||||
const roleOptions = ref<{ value: string; label: string; tag: string; roleCode?: string }[]>([]);
|
||||
const filters = reactive({ keyword: "", status: "" as "" | "active" | "disabled" });
|
||||
const modalOpen = ref(false);
|
||||
const editing = ref<AccountRow | null>(null);
|
||||
@@ -37,6 +37,8 @@ const form = reactive({
|
||||
phone: "",
|
||||
status: "active" as AccountRow["status"],
|
||||
password: "",
|
||||
/** 只看本账号看板数据(对齐原项目 dashboardSelfOnly) */
|
||||
dashboardSelfOnly: false,
|
||||
});
|
||||
|
||||
const modalTitle = computed(() => (editing.value ? "编辑账号" : "新建账号"));
|
||||
@@ -52,9 +54,11 @@ async function loadRoles() {
|
||||
value: String(r.id),
|
||||
label: r.roleName || r.roleCode || r.id,
|
||||
tag: roleTagFor(i),
|
||||
roleCode: String(r.roleCode || ""),
|
||||
}));
|
||||
if (!form.roleId && roleOptions.value.length) {
|
||||
form.roleId = roleOptions.value.find((r) => r.label.includes("运营"))?.value || roleOptions.value[0].value;
|
||||
form.roleId =
|
||||
roleOptions.value.find((r) => r.label.includes("运营"))?.value || roleOptions.value[0].value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,6 +101,23 @@ async function loadList() {
|
||||
const hit = roleOptions.value.find((r) => r.value === roleId);
|
||||
roleLabel = hit?.label || roleLabel;
|
||||
roleTag = hit?.tag || roleTag;
|
||||
// 用角色码辅助识别超管
|
||||
if (hit?.roleCode === "admin" || (hit?.label || "").includes("超级管理员")) {
|
||||
roleLabel = hit?.label || "超级管理员";
|
||||
}
|
||||
} else if (String(u.username || "").toLowerCase() === "admin") {
|
||||
// 库里未绑角色时仍展示超管,并尝试选中 admin 角色以便保存时能补绑
|
||||
const adminRole = roleOptions.value.find(
|
||||
(r) => r.roleCode === "admin" || r.label.includes("超级管理员"),
|
||||
);
|
||||
if (adminRole) {
|
||||
roleId = adminRole.value;
|
||||
roleLabel = adminRole.label || "超级管理员";
|
||||
roleTag = adminRole.tag;
|
||||
} else {
|
||||
roleLabel = "超级管理员";
|
||||
roleTag = "tag-violet";
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
/* 无角色仍展示账号 */
|
||||
@@ -142,11 +163,16 @@ function openCreate() {
|
||||
phone: "",
|
||||
status: "active",
|
||||
password: "",
|
||||
dashboardSelfOnly: false,
|
||||
});
|
||||
modalOpen.value = true;
|
||||
}
|
||||
|
||||
function openEdit(row: AccountRow) {
|
||||
if (row.isSuperAdmin) {
|
||||
message.warning("超级管理员不可在后台编辑");
|
||||
return;
|
||||
}
|
||||
editing.value = row;
|
||||
Object.assign(form, {
|
||||
username: row.username,
|
||||
@@ -156,11 +182,16 @@ function openEdit(row: AccountRow) {
|
||||
phone: row.phoneMasked === "未填写" ? "" : row.phoneMasked,
|
||||
status: row.status,
|
||||
password: "",
|
||||
dashboardSelfOnly: Boolean(row.dashboardSelfOnly),
|
||||
});
|
||||
modalOpen.value = true;
|
||||
}
|
||||
|
||||
async function save() {
|
||||
if (editing.value?.isSuperAdmin) {
|
||||
message.warning("超级管理员不可在后台编辑");
|
||||
return;
|
||||
}
|
||||
if (!form.username.trim() || !form.name.trim()) {
|
||||
message.warning("请填写账号与姓名");
|
||||
return;
|
||||
@@ -185,6 +216,7 @@ async function save() {
|
||||
phone: form.phone.trim() || undefined,
|
||||
status: form.status === "active" ? 1 : 2,
|
||||
selectedroles: form.roleId,
|
||||
dashboardSelfOnly: form.dashboardSelfOnly ? 1 : 0,
|
||||
};
|
||||
if (!editing.value) payload.password = form.password;
|
||||
try {
|
||||
@@ -321,12 +353,25 @@ function removeAccount(row: AccountRow) {
|
||||
</td>
|
||||
<td>
|
||||
<div class="account-row-actions">
|
||||
<button class="link-action" type="button" @click="openEdit(row)">编辑</button>
|
||||
<button class="link-action link-muted" type="button" @click="resetPassword(row)">
|
||||
<button
|
||||
v-if="!row.isSuperAdmin"
|
||||
class="link-action"
|
||||
type="button"
|
||||
@click="openEdit(row)"
|
||||
>
|
||||
编辑
|
||||
</button>
|
||||
<span v-else class="account-locked" title="超级管理员不可在后台编辑">不可编辑</span>
|
||||
<button
|
||||
v-if="!row.isSuperAdmin"
|
||||
class="link-action link-muted"
|
||||
type="button"
|
||||
@click="resetPassword(row)"
|
||||
>
|
||||
重置密码
|
||||
</button>
|
||||
<button
|
||||
v-if="row.username !== 'admin'"
|
||||
v-if="!row.isSuperAdmin"
|
||||
class="link-action link-danger"
|
||||
type="button"
|
||||
@click="removeAccount(row)"
|
||||
@@ -400,6 +445,14 @@ function removeAccount(row: AccountRow) {
|
||||
<option v-for="r in roleOptions" :key="r.value" :value="r.value">{{ r.label }}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label class="lbl">数据范围</label>
|
||||
<label class="account-self-only">
|
||||
<input v-model="form.dashboardSelfOnly" type="checkbox" />
|
||||
<span>只看自己数据</span>
|
||||
<em>勾选后,分析看板仅统计本账号企微归属的工单</em>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label class="lbl">状态</label>
|
||||
<div class="status-toggle">
|
||||
@@ -466,4 +519,26 @@ function removeAccount(row: AccountRow) {
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.account-locked {
|
||||
color: #94a3b8;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.account-self-only {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 13px;
|
||||
color: #0f172a;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.account-self-only em {
|
||||
flex: 1 1 100%;
|
||||
font-style: normal;
|
||||
font-size: 12px;
|
||||
color: #64748b;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user