修复气站合同用户权限与服务关系边界

This commit is contained in:
czl231
2026-08-18 22:49:14 +08:00
parent 61a61f916b
commit 9a31cadf5f
27 changed files with 635 additions and 59 deletions

View File

@@ -1,6 +1,6 @@
/**
* 功能:统一资源列表与详情页面的字段名称、关系、金额、状态和时间展示。
* 版本v1.8.0
* 版本v1.9.0
*/
import dayjs from 'dayjs';
import type { RecordPageMode, ResourceRow } from './resource-page-rules';
@@ -36,6 +36,8 @@ const aliases: Record<string, string> = {
delivery_basic_display_name: '配送点',
staff_account_display_name: '工作人员',
user_account_display_name: '用户',
user_service_active: '签约用户仍属当前气站',
contract_readonly: '账户权限',
creator_display_name: '创建方',
contract_display_name: '配送合同',
assigner_name: '分配人',
@@ -375,6 +377,8 @@ export function displayRawValue(key: string, value: unknown) {
if (key === 'staff_account_identity' && (value == null || value === ''))
return '暂未分配';
if (value == null || value === '') return '-';
if (key === 'contract_readonly' && value === true)
return '仅查看当前合同关联资料';
if (typeof value === 'boolean') return value ? '是' : '否';
if (key === 'status') return recordStatusLabel(Number(value));
if (key === 'contract_status') return contractStatusLabel(Number(value));

View File

@@ -1,6 +1,6 @@
/**
* 功能:定义标准资源在新建、详情和编辑页面中的字段能力与动态编辑限制。
* 版本v1.0.0
* 版本v1.1.0
*/
import type { ResourceField, ResourceUiDefinition } from './resources';
@@ -325,7 +325,14 @@ export function editBlockedReason(
context: ResourcePageContext,
) {
if (!definition.canEdit) return '当前资源不支持编辑';
if (
definition.name === 'user_account' &&
row.contract_readonly === true
)
return '该用户仅因本站合同可见,不能在当前气站编辑';
if (definition.name === 'gasorder_contract') {
if (row.user_service_active === false)
return '签约用户已不属于当前气站,只允许查看或终止合同';
if (Number(row.contract_status) !== 0)
return '只有草稿状态的合同可以编辑';
if (![0, 1].includes(Number(row.status)))

View File

@@ -1,3 +1,7 @@
/**
* 功能:封装标准资源列表、详情、新建、编辑和业务动作请求。
* 版本v1.1.0
*/
import { request, type PageResult } from './http';
/** 所有标准 CRUD 资源共享的调用方法。 */
@@ -6,7 +10,10 @@ export const resourceApi = {
const query = new URLSearchParams({ page: String(page), size: String(size), ...filters });
return request<PageResult<T>>(`${resource}?${query.toString()}`);
},
detail: <T>(resource: string, identity: string) => request<T>(`${resource}/${identity}`),
detail: <T>(resource: string, identity: string, filters: Record<string, string> = {}) => {
const query = new URLSearchParams(filters).toString();
return request<T>(`${resource}/${identity}${query ? `?${query}` : ''}`);
},
create: <T>(resource: string, data: Record<string, unknown>) => request<T>(resource, { method: 'POST', body: JSON.stringify(data) }),
update: <T>(resource: string, identity: string, data: Record<string, unknown>) => request<T>(`${resource}/${identity}`, { method: 'PUT', body: JSON.stringify(data) }),
updateStatus: (resource: string, identity: string, status: number) => request<{ updated: boolean }>(`${resource}/${identity}/status`, { method: 'PATCH', body: JSON.stringify({ status }) }),