feat: 统一账户角色展示并优化资源页面

This commit is contained in:
czl231
2026-08-11 02:01:00 +08:00
parent 9cf16ccb3c
commit ff345dc42a
28 changed files with 555 additions and 76 deletions

View File

@@ -1,11 +1,11 @@
<!--
功能展示账户类资源的头像用户名唯一标识和创建时间摘要
版本v1.0.0
版本v1.1.0
-->
<template>
<a-card class="account-card" :bordered="false">
<div class="account-summary">
<div class="avatar-column">
<div class="account-summary" :class="{ 'account-summary-text': !avatarEnabled }">
<div v-if="avatarEnabled" class="avatar-column">
<button
class="avatar-button"
type="button"
@@ -106,6 +106,15 @@ function onAvatarSelected(event: Event) {
min-height: 168px;
padding: 18px 32px;
}
.account-summary-text {
grid-template-columns: minmax(420px, 720px);
justify-content: start;
min-height: 116px;
padding: 14px 32px;
}
.account-summary-text .identity-summary {
width: 100%;
}
.avatar-column {
display: flex;
flex-direction: column;
@@ -188,5 +197,10 @@ function onAvatarSelected(event: Event) {
width: min(100%, 440px);
margin: 0 auto;
}
.account-summary-text {
grid-template-columns: 1fr;
min-height: auto;
padding: 14px 8px;
}
}
</style>

View File

@@ -1,6 +1,6 @@
<!--
功能以响应式信息卡和子表页签展示标准资源详情
版本v1.1.0
版本v1.2.0
-->
<template>
<div class="detail-stack">
@@ -58,6 +58,10 @@ const props = defineProps<{
definition: ResourceUiDefinition;
detail: ResourceRow;
relationOptions: Record<string, ResourceRow[]>;
fieldOptions?: Record<
string,
Array<{ label: string; value: string | number }>
>;
accountSummary: boolean;
}>();
@@ -97,7 +101,12 @@ const entries = computed<DetailEntry[]>(() => {
return [];
const field = props.definition.fields.find((item) => item.key === key);
const display = field
? displayResourceField(field, row, props.relationOptions)
? displayResourceField(
field,
row,
props.relationOptions,
props.fieldOptions,
)
: displayRawValue(actualKey, value);
const objectValue = typeof value === 'object' && value !== null;
return [
@@ -161,7 +170,8 @@ const collections = computed(() =>
}
.detail-item {
display: grid;
grid-template-columns: 120px minmax(0, 1fr);
grid-template-columns: max-content minmax(0, 1fr);
column-gap: 12px;
align-items: start;
min-height: 38px;
padding: 8px 0;
@@ -172,8 +182,7 @@ const collections = computed(() =>
}
.detail-label {
color: var(--color-text-3);
text-align: right;
padding-right: 18px;
white-space: nowrap;
}
.detail-value {
color: var(--color-text-1);
@@ -208,7 +217,6 @@ const collections = computed(() =>
.detail-item,
.detail-item-wide {
grid-column: auto;
grid-template-columns: 100px minmax(0, 1fr);
}
}
</style>

View File

@@ -1,6 +1,6 @@
<!--
功能渲染标准资源的新建编辑和业务动作字段控件
版本v1.0.0
版本v1.1.0
-->
<template>
<div class="field-grid">
@@ -63,7 +63,7 @@
:disabled="disabledSet.has(field.key)"
allow-clear
>
<a-option v-for="option in field.options" :key="option.value" :value="option.value">
<a-option v-for="option in selectOptions(field)" :key="option.value" :value="option.value">
{{ option.label }}
</a-option>
</a-select>
@@ -90,9 +90,8 @@
v-else
v-model="model[field.key]"
:disabled="disabledSet.has(field.key)"
:placeholder="disabledSet.has(field.key) ? '创建后不可修改' : `请输入${field.label}`"
:placeholder="disabledSet.has(field.key) ? '' : `请输入${field.label}`"
/>
<div v-if="disabledSet.has(field.key)" class="readonly-hint">创建后不可修改</div>
</a-form-item>
</div>
</template>
@@ -135,6 +134,24 @@ function isWide(field: ResourceField) {
/(address|terms|content|body|remark|reason|params|args)$/.test(field.key)
);
}
/** 为历史未知编码补充只读选项,避免下拉框退回显示原始值。 */
function selectOptions(field: ResourceField) {
const options = [...(field.options ?? [])];
const value = model.value[field.key];
if (
field.unknownValueLabel &&
value != null &&
value !== '' &&
!options.some((option) => String(option.value) === String(value))
) {
options.push({
label: `${field.unknownValueLabel}${String(value)}`,
value,
});
}
return options;
}
</script>
<style scoped lang="less">
@@ -152,11 +169,6 @@ function isWide(field: ResourceField) {
.field-readonly :deep(.arco-input-number) {
background: var(--color-fill-1);
}
.readonly-hint {
margin-top: 4px;
color: var(--color-text-3);
font-size: 12px;
}
:deep(.arco-input-number),
:deep(.arco-picker) {
width: 100%;

View File

@@ -1,6 +1,6 @@
/*
* 功能:定义标准资源独立页面的布局、卡片和响应式样式。
* 版本v1.2.0
* 版本v1.3.0
*/
.record-page {
display: grid;
@@ -52,7 +52,6 @@
.form-content {
container: record-form / inline-size;
}
.form-alert,
.workflow-alert {
margin-bottom: 18px;
}

View File

@@ -1,6 +1,6 @@
<!--
功能承载平台总后台全部标准资源的新建详情和编辑独立页面
版本v1.2.0
版本v1.3.0
-->
<template>
<div class="record-page">
@@ -33,7 +33,7 @@
<template v-else>
<ResourceAccountSummary
v-if="accountSummary"
v-if="accountSummaryVisible"
:mode="mode"
:title="definition.title"
:record="summaryRecord"
@@ -49,6 +49,7 @@
:definition="definition"
:detail="detail"
:relation-options="relations.options"
:field-options="fieldOptions"
:account-summary="accountSummary"
/>
<ResourceWalletSummary
@@ -93,9 +94,6 @@
<div class="form-shell">基本信息</div>
</template>
<div class="form-shell form-content">
<a-alert v-if="mode === 'edit' && readonlyKeys.length" class="form-alert" type="info" show-icon>
灰色字段为创建后不可修改的信息不会提交到更新接口
</a-alert>
<a-form :model="form" layout="vertical">
<ResourceFieldForm
v-model="form"
@@ -196,6 +194,9 @@ const errorMessage = ref('');
const errorStatus = ref<'403' | '404' | 'error'>('error');
const wallet = ref<ResourceRow>();
const roleOptions = ref<PlatformRole[]>([]);
const fieldOptions = reactive<
Record<string, Array<{ label: string; value: string | number }>>
>({});
const relations = useResourceRelations();
const actionVisible = ref(false);
const activeAction = ref<DetailAction>();
@@ -206,6 +207,11 @@ const selectAvatar = avatar.select;
const clearAvatar = avatar.clear;
const accountSummary = computed(() => usesAccountSummary(definition.value));
const accountSummaryVisible = computed(
() =>
accountSummary.value &&
(mode.value !== 'create' || hasAvatarField.value),
);
const hasAvatarField = computed(() =>
definition.value.fields.some((field) => field.key === 'avatar'),
);
@@ -235,11 +241,15 @@ const editableKeySet = computed(
),
);
const readonlyKeys = computed(() =>
mode.value === 'edit'
mode.value === 'create'
? formFields.value
.filter((field) => field.readonlyOnCreate)
.map((field) => field.key)
: mode.value === 'edit'
? formFields.value
.filter((field) => !editableKeySet.value.has(field.key))
.map((field) => field.key)
: [],
: [],
);
const requiredKeys = computed(() =>
payloadFields.value
@@ -353,9 +363,19 @@ async function loadRelationsAndRoles() {
if (
definition.value.fields.some((field) => field.key === 'platform_role_code')
) {
roleOptions.value = (await platformApi.listRole()).list.filter(
(role) => !role.is_system && role.status === 1,
);
try {
const roles = (await platformApi.listRole()).list;
fieldOptions.platform_role_code = roles.map((role) => ({
label: role.name,
value: role.role_code,
}));
roleOptions.value = roles.filter(
(role) => !role.is_system && role.status === 1,
);
} catch (error) {
fieldOptions.platform_role_code = [];
Message.warning(`平台角色加载失败:${(error as Error).message}`);
}
}
}