完善配送合同关联信息展示与归属校验
三端合同页面改为优先显示用户、气站和配送点业务名称,并保留标识与合同编号复制能力。 平台端增加气站与直属配送点联动,后端禁止平台主管及跨气站配送点绑定合同,同时补充测试和中文文档。
This commit is contained in:
@@ -739,7 +739,12 @@ func deliveryBelongsToGas(deliveryID, gasID uint64) bool {
|
|||||||
}
|
}
|
||||||
var delivery models.DeliveryBasic
|
var delivery models.DeliveryBasic
|
||||||
return impl.DBService.Select("gas_basic_id").First(&delivery, deliveryID).Error == nil &&
|
return impl.DBService.Select("gas_basic_id").First(&delivery, deliveryID).Error == nil &&
|
||||||
(delivery.GasBasicID == 0 || delivery.GasBasicID == gasID)
|
contractDeliveryMatchesGas(delivery.GasBasicID, gasID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// contractDeliveryMatchesGas 校验合同配送点必须直属于合同气站;平台主管配送点不能绑定到气站合同。
|
||||||
|
func contractDeliveryMatchesGas(deliveryGasID, contractGasID uint64) bool {
|
||||||
|
return deliveryGasID != 0 && deliveryGasID == contractGasID
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasorderStatusRecord(orderID uint64, from, to int, reason, operatorIdentity, operatorName string) *models.GasorderStatus {
|
func gasorderStatusRecord(orderID uint64, from, to int, reason, operatorIdentity, operatorName string) *models.GasorderStatus {
|
||||||
|
|||||||
@@ -106,6 +106,18 @@ func TestContractRevisionKeepsSingleContractHistory(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestContractDeliveryRequiresDirectGasOwnership(t *testing.T) {
|
||||||
|
if !contractDeliveryMatchesGas(10, 10) {
|
||||||
|
t.Fatal("合同气站的直属配送点被错误拒绝")
|
||||||
|
}
|
||||||
|
if contractDeliveryMatchesGas(0, 10) {
|
||||||
|
t.Fatal("平台主管配送点不应绑定到气站合同")
|
||||||
|
}
|
||||||
|
if contractDeliveryMatchesGas(11, 10) {
|
||||||
|
t.Fatal("其他气站配送点不应绑定到当前气站合同")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestGasorderSensitiveContactsAreMasked(t *testing.T) {
|
func TestGasorderSensitiveContactsAreMasked(t *testing.T) {
|
||||||
value := map[string]any{
|
value := map[string]any{
|
||||||
"contact_name": "张三",
|
"contact_name": "张三",
|
||||||
|
|||||||
47
docs/操作日志_配送合同关联信息展示_20260812.md
Normal file
47
docs/操作日志_配送合同关联信息展示_20260812.md
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
# 配送合同关联信息展示操作日志
|
||||||
|
|
||||||
|
操作时间:2026-08-12
|
||||||
|
|
||||||
|
操作类型:修改、扩展
|
||||||
|
|
||||||
|
影响模块:平台总后台、气站后台、配送点后台、配送合同后端逻辑
|
||||||
|
|
||||||
|
## 操作前状态
|
||||||
|
|
||||||
|
合同列表直接展示用户、气站和配送点唯一标识,业务人员难以辨认;平台合同后端允许将平台主管配送点绑定到必填气站,与气站需求中的直属配送点规则不一致。
|
||||||
|
|
||||||
|
## 具体操作
|
||||||
|
|
||||||
|
- 三端合同资源定义增加业务名称列表标签、关系名称展示、标识复制及空值文案。
|
||||||
|
- 平台端为气站与默认配送点增加父子联动,按所选气站查询直属配送点。
|
||||||
|
- 合同编号使用可复制紧凑文本,悬浮可查看完整值。
|
||||||
|
- 气站端和配送点端详情复用关系名称组件展示关联对象。
|
||||||
|
- 后端新增合同配送点直属归属判定,排除平台主管配送点和跨气站配送点。
|
||||||
|
- 增加后端边界测试,并更新前端联动配置检查数量。
|
||||||
|
|
||||||
|
## 行为变化
|
||||||
|
|
||||||
|
- 变更前:关联列主显唯一标识;平台 API 接受平台主管配送点。
|
||||||
|
- 变更后:关联列主显业务名称并可复制标识;平台 API 仅接受合同气站直属配送点或空配送点。
|
||||||
|
|
||||||
|
## 代码变更
|
||||||
|
|
||||||
|
- `frontend/platform_admin/src/api/resources.ts`:合同字段展示及配送点联动配置。
|
||||||
|
- `frontend/platform_admin/src/views/shared/CrudListPage.vue`:普通字段可复制列表展示。
|
||||||
|
- `frontend/gas_admin/src/api/resources.ts`、`frontend/delivery_admin/src/api/resources.ts`:各自可见合同关联字段配置。
|
||||||
|
- `frontend/gas_admin/src/views/shared/CrudListPage.vue`、`frontend/delivery_admin/src/views/shared/CrudListPage.vue`:详情关系名称展示。
|
||||||
|
- `backend/api/internal/logic/platform/gasorder/gasorder.go`:合同配送点直属归属校验。
|
||||||
|
- `backend/api/internal/logic/platform/gasorder/gasorder_test.go`:直属、平台主管和跨气站边界测试。
|
||||||
|
|
||||||
|
## 验证结果
|
||||||
|
|
||||||
|
- 平台、气站、配送点前端 `type:check` 均通过。
|
||||||
|
- 三个 Web 前端生产构建均通过。
|
||||||
|
- 平台工作人员/服务关系/合同组织联动检查通过。
|
||||||
|
- 平台标准资源独立页面检查通过:详情 46 类、新建 25 类、编辑 23 类。
|
||||||
|
- 后端 `go test ./internal/logic/platform/gasorder` 通过,覆盖直属、平台主管和跨气站配送点边界。
|
||||||
|
|
||||||
|
## 风险评估
|
||||||
|
|
||||||
|
- 历史不合规合同仍可查看,但编辑保存时会被新规则拦截;处理方式是清空默认配送点或选择合同气站直属配送点。
|
||||||
|
- 校验只收紧合同场景,不改变订单分配等其他业务的平台主管组织规则。
|
||||||
41
docs/项目文档_配送合同关联信息展示_v1.0.md
Normal file
41
docs/项目文档_配送合同关联信息展示_v1.0.md
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
# 配送合同关联信息展示项目文档 v1.0
|
||||||
|
|
||||||
|
## 项目概述
|
||||||
|
|
||||||
|
本次调整统一平台总后台、气站后台和配送点后台的配送合同关联信息展示。用户、气站和配送点以业务名称为主,唯一标识保留为悬浮查看与点击复制能力。平台总后台创建或编辑合同时,默认配送点只能选择合同气站的直属配送点。
|
||||||
|
|
||||||
|
## 主要功能
|
||||||
|
|
||||||
|
- 合同列表、详情、新建及编辑场景优先展示用户、气站、配送点业务名称。
|
||||||
|
- 合同唯一标识继续保留;合同编号支持悬浮查看完整值并点击复制。
|
||||||
|
- 平台端“所属气站”联动筛选“所属配送点”,配送点允许留空并显示“暂未指定”。
|
||||||
|
- 用户和气站作为合同不可变归属,编辑页以只读名称展示并保留标识复制。
|
||||||
|
- 平台直属配送点和其他气站配送点不能绑定到气站合同。
|
||||||
|
|
||||||
|
## 目录与核心文件
|
||||||
|
|
||||||
|
```text
|
||||||
|
platforms/
|
||||||
|
├── frontend/platform_admin/src/api/resources.ts # 平台合同字段展示与组织联动配置
|
||||||
|
├── frontend/gas_admin/src/api/resources.ts # 气站合同可见关联字段配置
|
||||||
|
├── frontend/delivery_admin/src/api/resources.ts # 配送点合同用户字段配置
|
||||||
|
├── backend/api/internal/logic/platform/gasorder/ # 合同配送点归属校验及测试
|
||||||
|
└── docs/ # 项目文档与操作日志
|
||||||
|
```
|
||||||
|
|
||||||
|
## 行为规则
|
||||||
|
|
||||||
|
1. 平台合同必须选择用户和气站,默认配送点可留空。
|
||||||
|
2. 选择默认配送点时,该配送点的 `gas_basic_id` 必须等于合同气站 ID。
|
||||||
|
3. `gas_basic_id = 0` 的平台主管配送点不属于具体气站,因此不能用于气站合同。
|
||||||
|
4. 历史记录仍可查看;若历史合同保存了不合规配送点,再次编辑保存前必须清空或改选直属配送点。
|
||||||
|
|
||||||
|
## 维护与验证
|
||||||
|
|
||||||
|
- 修改关联展示时优先复用 `RelationNameText` 和资源字段配置,避免为单一页面硬编码。
|
||||||
|
- 修改组织归属规则时同步运行平台前端联动检查、三端构建和后端 `gasorder` 单元测试。
|
||||||
|
- 后端仍接受空配送点,保持原有“默认配送点可选”接口兼容性。
|
||||||
|
|
||||||
|
## 变更记录
|
||||||
|
|
||||||
|
- v1.0(2026-08-12):完成三端合同名称展示、标识复制、平台组织联动及后端直属归属校验。
|
||||||
@@ -30,6 +30,8 @@ export type ResourceField = {
|
|||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
showIdentityCopy?: boolean;
|
showIdentityCopy?: boolean;
|
||||||
readonlyRelationText?: boolean;
|
readonlyRelationText?: boolean;
|
||||||
|
/** 列表中以可悬浮、可复制的紧凑文本展示普通字段。 */
|
||||||
|
listCopyable?: boolean;
|
||||||
options?: Array<{ label: string; value: string | number }>;
|
options?: Array<{ label: string; value: string | number }>;
|
||||||
defaultValue?: string | number | boolean;
|
defaultValue?: string | number | boolean;
|
||||||
readonly?: boolean;
|
readonly?: boolean;
|
||||||
@@ -490,7 +492,7 @@ const deliveryOverrides: ResourceUiDefinition[] = [
|
|||||||
{ name: '重置密码', resource: '/user_account/:identity/password', method: 'PUT', fields: [f('password', { required: true })] },
|
{ name: '重置密码', resource: '/user_account/:identity/password', method: 'PUT', fields: [f('password', { required: true })] },
|
||||||
]),
|
]),
|
||||||
define('user_address', '用户地址', 'writable', [relation('user_account_identity', '/user_account', true), f('address', { required: true }), f('longitude'), f('latitude'), f('is_default')]),
|
define('user_address', '用户地址', 'writable', [relation('user_account_identity', '/user_account', true), f('address', { required: true }), f('longitude'), f('latitude'), f('is_default')]),
|
||||||
define('gasorder_contract', '配送合同', 'managed', [f('contract_no', { required: true }), relation('user_account_identity', '/user_account', true), f('title', { required: true }), f('terms'), f('file_uri'), f('default_delivery_fee'), f('signed_at', { required: true }), f('effective_at', { required: true }), f('expired_at')], 'list', [
|
define('gasorder_contract', '配送合同', 'managed', [f('contract_no', { required: true, listCopyable: true }), relation('user_account_identity', '/user_account', true, { label: '用户账户', listLabel: '用户账户', listRelationNameOnly: true, showIdentityCopy: true, readonlyRelationText: true }), f('title', { required: true }), f('terms'), f('file_uri'), f('default_delivery_fee'), f('signed_at', { required: true }), f('effective_at', { required: true }), f('expired_at')], 'list', [
|
||||||
{ name: '启用合同', resource: '/gasorder_contract/:identity/activate', fields: reason, visibleFor: { field: 'contract_status', values: [10] } },
|
{ name: '启用合同', resource: '/gasorder_contract/:identity/activate', fields: reason, visibleFor: { field: 'contract_status', values: [10] } },
|
||||||
{ name: '续签合同', resource: '/gasorder_contract/:identity/renew', fields: [f('effective_at', { required: true }), f('expired_at'), ...reason], visibleFor: { field: 'contract_status', values: [11, 12, 13] } },
|
{ name: '续签合同', resource: '/gasorder_contract/:identity/renew', fields: [f('effective_at', { required: true }), f('expired_at'), ...reason], visibleFor: { field: 'contract_status', values: [11, 12, 13] } },
|
||||||
{ name: '终止合同', resource: '/gasorder_contract/:identity/terminate', danger: true, fields: reason, visibleFor: { field: 'contract_status', values: [11] } },
|
{ name: '终止合同', resource: '/gasorder_contract/:identity/terminate', danger: true, fields: reason, visibleFor: { field: 'contract_status', values: [11] } },
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
<template #cell="{ record }">
|
<template #cell="{ record }">
|
||||||
<RelationNameText v-if="field.listRelationNameOnly && identityFieldValue(field, record)" :name="relationListName(field, record)" :identity="identityFieldValue(field, record)" :identity-label="field.label" />
|
<RelationNameText v-if="field.listRelationNameOnly && identityFieldValue(field, record)" :name="relationListName(field, record)" :identity="identityFieldValue(field, record)" :identity-label="field.label" />
|
||||||
<IdentityText v-else-if="field.type === 'identity' && identityFieldValue(field, record)" :value="identityFieldValue(field, record)" />
|
<IdentityText v-else-if="field.type === 'identity' && identityFieldValue(field, record)" :value="identityFieldValue(field, record)" />
|
||||||
|
<IdentityText v-else-if="field.listCopyable && record[field.key]" :value="String(record[field.key])" />
|
||||||
<template v-else>{{ displayFieldValue(field, record) }}</template>
|
<template v-else>{{ displayFieldValue(field, record) }}</template>
|
||||||
</template>
|
</template>
|
||||||
</a-table-column>
|
</a-table-column>
|
||||||
@@ -189,6 +190,7 @@
|
|||||||
<a-descriptions :column="1" bordered>
|
<a-descriptions :column="1" bordered>
|
||||||
<a-descriptions-item v-for="[key, value] in detailEntries" :key="key" :label="fieldLabel(key)">
|
<a-descriptions-item v-for="[key, value] in detailEntries" :key="key" :label="fieldLabel(key)">
|
||||||
<pre v-if="typeof value === 'object'" class="json-value">{{ formatValue(value) }}</pre>
|
<pre v-if="typeof value === 'object'" class="json-value">{{ formatValue(value) }}</pre>
|
||||||
|
<RelationNameText v-else-if="relationDetailField(key) && value" :name="relationListName(relationDetailField(key)!, detail)" :identity="String(value)" :identity-label="relationDetailField(key)!.label" />
|
||||||
<template v-else>{{ displayValue(key, value) }}</template>
|
<template v-else>{{ displayValue(key, value) }}</template>
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
</a-descriptions>
|
</a-descriptions>
|
||||||
@@ -1052,6 +1054,11 @@ function displayValue(key: string, value: unknown) {
|
|||||||
return String(value);
|
return String(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// relationDetailField 将详情中的关联标识映射回资源字段,以复用业务名称展示和标识复制。
|
||||||
|
function relationDetailField(key: string) {
|
||||||
|
return props.definition.fields.find((field) => field.key === key && field.relation);
|
||||||
|
}
|
||||||
|
|
||||||
/** 将各管理端稳定角色编码转换为中文名称,未知编码保留审计线索。 */
|
/** 将各管理端稳定角色编码转换为中文名称,未知编码保留审计线索。 */
|
||||||
function accountRoleLabel(resource: string | undefined, value: unknown) {
|
function accountRoleLabel(resource: string | undefined, value: unknown) {
|
||||||
const code = String(value ?? '');
|
const code = String(value ?? '');
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ export type ResourceField = {
|
|||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
showIdentityCopy?: boolean;
|
showIdentityCopy?: boolean;
|
||||||
readonlyRelationText?: boolean;
|
readonlyRelationText?: boolean;
|
||||||
|
/** 列表中以可悬浮、可复制的紧凑文本展示普通字段。 */
|
||||||
|
listCopyable?: boolean;
|
||||||
options?: Array<{ label: string; value: string | number }>;
|
options?: Array<{ label: string; value: string | number }>;
|
||||||
defaultValue?: string | number | boolean;
|
defaultValue?: string | number | boolean;
|
||||||
readonly?: boolean;
|
readonly?: boolean;
|
||||||
@@ -451,7 +453,7 @@ const gasOverrides: ResourceUiDefinition[] = [
|
|||||||
{ name: '重置密码', resource: '/user_account/:identity/password', method: 'PUT', fields: [f('password', { required: true })] },
|
{ name: '重置密码', resource: '/user_account/:identity/password', method: 'PUT', fields: [f('password', { required: true })] },
|
||||||
]),
|
]),
|
||||||
define('user_address', '用户地址', 'writable', [relation('user_account_identity', '/user_account', true), f('address', { required: true }), f('longitude'), f('latitude'), f('is_default')]),
|
define('user_address', '用户地址', 'writable', [relation('user_account_identity', '/user_account', true), f('address', { required: true }), f('longitude'), f('latitude'), f('is_default')]),
|
||||||
define('gasorder_contract', '配送合同', 'managed', [f('contract_no', { required: true }), relation('user_account_identity', '/user_account', true), relation('delivery_basic_identity', '/delivery_basic'), f('title', { required: true }), f('terms'), f('file_uri'), f('default_delivery_fee'), f('signed_at', { required: true }), f('effective_at', { required: true }), f('expired_at')], 'list', [
|
define('gasorder_contract', '配送合同', 'managed', [f('contract_no', { required: true, listCopyable: true }), relation('user_account_identity', '/user_account', true, { label: '用户账户', listLabel: '用户账户', listRelationNameOnly: true, showIdentityCopy: true, readonlyRelationText: true }), relation('delivery_basic_identity', '/delivery_basic', false, { label: '所属配送点', listLabel: '所属配送点', listRelationNameOnly: true, emptyText: '暂未指定', placeholder: '请选择默认配送点,可留空', showIdentityCopy: true }), f('title', { required: true }), f('terms'), f('file_uri'), f('default_delivery_fee'), f('signed_at', { required: true }), f('effective_at', { required: true }), f('expired_at')], 'list', [
|
||||||
{ name: '启用合同', resource: '/gasorder_contract/:identity/activate', fields: reason, visibleFor: { field: 'contract_status', values: [10] } },
|
{ name: '启用合同', resource: '/gasorder_contract/:identity/activate', fields: reason, visibleFor: { field: 'contract_status', values: [10] } },
|
||||||
{ name: '续签合同', resource: '/gasorder_contract/:identity/renew', fields: [f('effective_at', { required: true }), f('expired_at'), ...reason], visibleFor: { field: 'contract_status', values: [11, 12, 13] } },
|
{ name: '续签合同', resource: '/gasorder_contract/:identity/renew', fields: [f('effective_at', { required: true }), f('expired_at'), ...reason], visibleFor: { field: 'contract_status', values: [11, 12, 13] } },
|
||||||
{ name: '终止合同', resource: '/gasorder_contract/:identity/terminate', danger: true, fields: reason, visibleFor: { field: 'contract_status', values: [11] } },
|
{ name: '终止合同', resource: '/gasorder_contract/:identity/terminate', danger: true, fields: reason, visibleFor: { field: 'contract_status', values: [11] } },
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
<template #cell="{ record }">
|
<template #cell="{ record }">
|
||||||
<RelationNameText v-if="field.listRelationNameOnly && identityFieldValue(field, record)" :name="relationListName(field, record)" :identity="identityFieldValue(field, record)" :identity-label="field.label" />
|
<RelationNameText v-if="field.listRelationNameOnly && identityFieldValue(field, record)" :name="relationListName(field, record)" :identity="identityFieldValue(field, record)" :identity-label="field.label" />
|
||||||
<IdentityText v-else-if="field.type === 'identity' && identityFieldValue(field, record)" :value="identityFieldValue(field, record)" />
|
<IdentityText v-else-if="field.type === 'identity' && identityFieldValue(field, record)" :value="identityFieldValue(field, record)" />
|
||||||
|
<IdentityText v-else-if="field.listCopyable && record[field.key]" :value="String(record[field.key])" />
|
||||||
<template v-else>{{ displayFieldValue(field, record) }}</template>
|
<template v-else>{{ displayFieldValue(field, record) }}</template>
|
||||||
</template>
|
</template>
|
||||||
</a-table-column>
|
</a-table-column>
|
||||||
@@ -189,6 +190,7 @@
|
|||||||
<a-descriptions :column="1" bordered>
|
<a-descriptions :column="1" bordered>
|
||||||
<a-descriptions-item v-for="[key, value] in detailEntries" :key="key" :label="fieldLabel(key)">
|
<a-descriptions-item v-for="[key, value] in detailEntries" :key="key" :label="fieldLabel(key)">
|
||||||
<pre v-if="typeof value === 'object'" class="json-value">{{ formatValue(value) }}</pre>
|
<pre v-if="typeof value === 'object'" class="json-value">{{ formatValue(value) }}</pre>
|
||||||
|
<RelationNameText v-else-if="relationDetailField(key) && value" :name="relationListName(relationDetailField(key)!, detail)" :identity="String(value)" :identity-label="relationDetailField(key)!.label" />
|
||||||
<template v-else>{{ displayValue(key, value) }}</template>
|
<template v-else>{{ displayValue(key, value) }}</template>
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
</a-descriptions>
|
</a-descriptions>
|
||||||
@@ -1052,6 +1054,11 @@ function displayValue(key: string, value: unknown) {
|
|||||||
return String(value);
|
return String(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// relationDetailField 将详情中的关联标识映射回资源字段,以复用业务名称展示和标识复制。
|
||||||
|
function relationDetailField(key: string) {
|
||||||
|
return props.definition.fields.find((field) => field.key === key && field.relation);
|
||||||
|
}
|
||||||
|
|
||||||
/** 将各管理端稳定角色编码转换为中文名称,未知编码保留审计线索。 */
|
/** 将各管理端稳定角色编码转换为中文名称,未知编码保留审计线索。 */
|
||||||
function accountRoleLabel(resource: string | undefined, value: unknown) {
|
function accountRoleLabel(resource: string | undefined, value: unknown) {
|
||||||
const code = String(value ?? '');
|
const code = String(value ?? '');
|
||||||
|
|||||||
@@ -160,8 +160,8 @@ const resourcesSource = await readFile(
|
|||||||
);
|
);
|
||||||
assert.equal(
|
assert.equal(
|
||||||
(resourcesSource.match(/relationLinkage:/g) ?? []).length,
|
(resourcesSource.match(/relationLinkage:/g) ?? []).length,
|
||||||
2,
|
3,
|
||||||
'联动配置必须显式启用于工作人员和用户服务关系的配送点字段',
|
'联动配置必须显式启用于工作人员、用户服务关系和配送合同的配送点字段',
|
||||||
);
|
);
|
||||||
assert.match(resourcesSource, /filterKey: 'gas_basic_identities'/);
|
assert.match(resourcesSource, /filterKey: 'gas_basic_identities'/);
|
||||||
assert.match(resourcesSource, /organizationScoped: true/);
|
assert.match(resourcesSource, /organizationScoped: true/);
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ export type ResourceField = {
|
|||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
showIdentityCopy?: boolean;
|
showIdentityCopy?: boolean;
|
||||||
readonlyRelationText?: boolean;
|
readonlyRelationText?: boolean;
|
||||||
|
/** 列表中以可悬浮、可复制的紧凑文本展示普通字段。 */
|
||||||
|
listCopyable?: boolean;
|
||||||
options?: Array<{ label: string; value: string | number }>;
|
options?: Array<{ label: string; value: string | number }>;
|
||||||
defaultValue?: string | number | boolean;
|
defaultValue?: string | number | boolean;
|
||||||
readonlyOnCreate?: boolean;
|
readonlyOnCreate?: boolean;
|
||||||
@@ -429,7 +431,28 @@ export const resources: ResourceUiDefinition[] = [
|
|||||||
define('product_repair', '智能气阀检修记录', 'editable', [relation('product_info_identity', '/product_info', true), f('repair_no', { required: true }), f('repair_type', { required: true }), f('started_at', { required: true }), f('completed_at'), f('result', { type: 'select', options: resourceSearchEnumOptions('product_repair', 'result') }), f('target_product_status', { type: 'select', options: [{ label: '在库', value: 28 }, { label: '运输中', value: 29 }, { label: '使用中', value: 30 }, { label: '报废', value: 27 }] }), f('content'), f('operator'), f('remark')]),
|
define('product_repair', '智能气阀检修记录', 'editable', [relation('product_info_identity', '/product_info', true), f('repair_no', { required: true }), f('repair_type', { required: true }), f('started_at', { required: true }), f('completed_at'), f('result', { type: 'select', options: resourceSearchEnumOptions('product_repair', 'result') }), f('target_product_status', { type: 'select', options: [{ label: '在库', value: 28 }, { label: '运输中', value: 29 }, { label: '使用中', value: 30 }, { label: '报废', value: 27 }] }), f('content'), f('operator'), f('remark')]),
|
||||||
define('product_owner', '智能气阀归属记录', 'readonly', []),
|
define('product_owner', '智能气阀归属记录', 'readonly', []),
|
||||||
|
|
||||||
define('gasorder_contract', '配送合同', 'managed', [f('contract_no', { required: true }), relation('user_account_identity', '/user_account', true), relation('gas_basic_identity', '/gas_basic', true), relation('delivery_basic_identity', '/delivery_basic'), f('title', { required: true }), f('terms'), f('file_uri'), f('default_delivery_fee'), f('signed_at', { required: true }), f('effective_at', { required: true }), f('expired_at')], 'list', [
|
define('gasorder_contract', '配送合同', 'managed', [
|
||||||
|
f('contract_no', { required: true, listCopyable: true }),
|
||||||
|
relation('user_account_identity', '/user_account', true, {
|
||||||
|
label: '用户账户', listLabel: '用户账户', listRelationNameOnly: true,
|
||||||
|
displayRelationLabel: true, showIdentityCopy: true, readonlyRelationText: true,
|
||||||
|
}),
|
||||||
|
relation('gas_basic_identity', '/gas_basic', true, {
|
||||||
|
label: '所属气站', listLabel: '所属气站', listRelationNameOnly: true,
|
||||||
|
displayRelationLabel: true, showIdentityCopy: true, readonlyRelationText: true,
|
||||||
|
}),
|
||||||
|
relation('delivery_basic_identity', '/delivery_basic', false, {
|
||||||
|
label: '所属配送点', listLabel: '所属配送点', listRelationNameOnly: true,
|
||||||
|
displayRelationLabel: true, emptyText: '暂未指定', placeholder: '请选择默认配送点,可留空',
|
||||||
|
showIdentityCopy: true,
|
||||||
|
relationLinkage: {
|
||||||
|
parentKey: 'gas_basic_identity', optionParentKey: 'gas_basic_identity',
|
||||||
|
filterKey: 'gas_basic_identities', backfillParent: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
f('title', { required: true }), f('terms'), f('file_uri'), f('default_delivery_fee'),
|
||||||
|
f('signed_at', { required: true }), f('effective_at', { required: true }), f('expired_at'),
|
||||||
|
], 'list', [
|
||||||
{ name: '启用合同', resource: '/gasorder_contract/:identity/activate', fields: reason, visibleFor: { field: 'contract_status', values: [10] } },
|
{ name: '启用合同', resource: '/gasorder_contract/:identity/activate', fields: reason, visibleFor: { field: 'contract_status', values: [10] } },
|
||||||
{ name: '续签合同', resource: '/gasorder_contract/:identity/renew', fields: [f('effective_at', { required: true }), f('expired_at'), ...reason], visibleFor: { field: 'contract_status', values: [11, 12] } },
|
{ name: '续签合同', resource: '/gasorder_contract/:identity/renew', fields: [f('effective_at', { required: true }), f('expired_at'), ...reason], visibleFor: { field: 'contract_status', values: [11, 12] } },
|
||||||
{ name: '终止合同', resource: '/gasorder_contract/:identity/terminate', danger: true, fields: reason, visibleFor: { field: 'contract_status', values: [11] } },
|
{ name: '终止合同', resource: '/gasorder_contract/:identity/terminate', danger: true, fields: reason, visibleFor: { field: 'contract_status', values: [11] } },
|
||||||
|
|||||||
@@ -66,6 +66,10 @@
|
|||||||
v-else-if="field.type === 'identity' && !field.displayRelationLabel && identityFieldValue(field, record)"
|
v-else-if="field.type === 'identity' && !field.displayRelationLabel && identityFieldValue(field, record)"
|
||||||
:value="identityFieldValue(field, record)"
|
:value="identityFieldValue(field, record)"
|
||||||
/>
|
/>
|
||||||
|
<IdentityText
|
||||||
|
v-else-if="field.listCopyable && record[field.key]"
|
||||||
|
:value="String(record[field.key])"
|
||||||
|
/>
|
||||||
<template v-else>{{ displayListField(field, record) }}</template>
|
<template v-else>{{ displayListField(field, record) }}</template>
|
||||||
</template>
|
</template>
|
||||||
</a-table-column>
|
</a-table-column>
|
||||||
|
|||||||
Reference in New Issue
Block a user