fix: add amount UI to contract lines and reason code to SN activation

This commit is contained in:
2026-05-25 14:45:54 +08:00
parent 13c42d2c87
commit 1726f486fa
5 changed files with 60 additions and 3 deletions
@@ -243,6 +243,9 @@ public class LicenseSnService {
} }
String oldJson = toJson(Map.of("status", from.name())); String oldJson = toJson(Map.of("status", from.name()));
row.setStatus(to.name()); row.setStatus(to.name());
if (to == LicenseSnStatus.ACTIVATED && request.getReasonCode() != null) {
row.setActivationRemark(request.getReasonCode());
}
row.setUpdatedAt(OffsetDateTime.now(ZoneOffset.UTC)); row.setUpdatedAt(OffsetDateTime.now(ZoneOffset.UTC));
licenseSnMapper.updateById(row); licenseSnMapper.updateById(row);
auditService.record( auditService.record(
@@ -7,6 +7,8 @@ public class LicenseSnStatusPatchRequest {
@NotBlank @NotBlank
private String status; private String status;
private String reasonCode;
public String getStatus() { public String getStatus() {
return status; return status;
} }
@@ -14,4 +16,12 @@ public class LicenseSnStatusPatchRequest {
public void setStatus(String status) { public void setStatus(String status) {
this.status = status; this.status = status;
} }
public String getReasonCode() {
return reasonCode;
}
public void setReasonCode(String reasonCode) {
this.reasonCode = reasonCode;
}
} }
@@ -31,6 +31,9 @@
</template> </template>
<template v-else>{{ contract.remarks ?? "" }}</template> <template v-else>{{ contract.remarks ?? "" }}</template>
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="签订日期">{{ contract.signingDate || '—' }}</el-descriptions-item>
<el-descriptions-item label="生效日期">{{ contract.effectiveDate || '—' }}</el-descriptions-item>
<el-descriptions-item label="终止日期" :span="2">{{ contract.endDate || '—' }}</el-descriptions-item>
</el-descriptions> </el-descriptions>
<div v-if="transitionButtons.length" class="transition-bar"> <div v-if="transitionButtons.length" class="transition-bar">
@@ -54,6 +57,7 @@
<el-table-column prop="itemName" label="标的/行项" min-width="200" show-overflow-tooltip /> <el-table-column prop="itemName" label="标的/行项" min-width="200" show-overflow-tooltip />
<el-table-column prop="quantity" label="数量" width="100" /> <el-table-column prop="quantity" label="数量" width="100" />
<el-table-column prop="unit" label="单位" width="90" show-overflow-tooltip /> <el-table-column prop="unit" label="单位" width="90" show-overflow-tooltip />
<el-table-column prop="amount" label="金额" width="120" />
<el-table-column v-if="isDraft" label="操作" width="140" fixed="right"> <el-table-column v-if="isDraft" label="操作" width="140" fixed="right">
<template #default="{ row }"> <template #default="{ row }">
<el-button type="primary" link @click="openLineDialog(row)">编辑</el-button> <el-button type="primary" link @click="openLineDialog(row)">编辑</el-button>
@@ -106,6 +110,9 @@
<el-form-item label="单位"> <el-form-item label="单位">
<el-input v-model="lineForm.unit" maxlength="32" placeholder="选填" /> <el-input v-model="lineForm.unit" maxlength="32" placeholder="选填" />
</el-form-item> </el-form-item>
<el-form-item label="金额">
<el-input-number v-model="lineForm.amount" :min="0" :precision="2" controls-position="right" style="width: 100%" placeholder="选填" />
</el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
<el-button @click="lineDialogVisible = false">取消</el-button> <el-button @click="lineDialogVisible = false">取消</el-button>
@@ -166,6 +173,7 @@ const lineForm = reactive({
itemName: "", itemName: "",
quantity: 1, quantity: 1,
unit: "", unit: "",
amount: undefined,
}); });
const lineRules = { const lineRules = {
itemName: [{ required: true, message: "请输入行项名称", trigger: "blur" }], itemName: [{ required: true, message: "请输入行项名称", trigger: "blur" }],
@@ -400,11 +408,13 @@ function openLineDialog(row) {
lineForm.itemName = row.itemName ?? ""; lineForm.itemName = row.itemName ?? "";
lineForm.quantity = Number(row.quantity ?? 1); lineForm.quantity = Number(row.quantity ?? 1);
lineForm.unit = row.unit ?? ""; lineForm.unit = row.unit ?? "";
lineForm.amount = row.amount ?? undefined;
} else { } else {
lineEditingId.value = null; lineEditingId.value = null;
lineForm.itemName = ""; lineForm.itemName = "";
lineForm.quantity = 1; lineForm.quantity = 1;
lineForm.unit = ""; lineForm.unit = "";
lineForm.amount = undefined;
} }
lineDialogVisible.value = true; lineDialogVisible.value = true;
} }
@@ -414,6 +424,7 @@ function resetLineForm() {
lineForm.itemName = ""; lineForm.itemName = "";
lineForm.quantity = 1; lineForm.quantity = 1;
lineForm.unit = ""; lineForm.unit = "";
lineForm.amount = undefined;
lineFormRef.value?.resetFields?.(); lineFormRef.value?.resetFields?.();
} }
@@ -431,6 +442,7 @@ async function submitLine() {
itemName: lineForm.itemName.trim(), itemName: lineForm.itemName.trim(),
quantity: lineForm.quantity, quantity: lineForm.quantity,
unit: lineForm.unit?.trim() || undefined, unit: lineForm.unit?.trim() || undefined,
amount: lineForm.amount ?? undefined,
}; };
lineSaving.value = true; lineSaving.value = true;
try { try {
@@ -60,6 +60,15 @@
<el-form-item label="备注"> <el-form-item label="备注">
<el-input v-model="header.remarks" type="textarea" :rows="3" maxlength="4000" show-word-limit placeholder="选填" /> <el-input v-model="header.remarks" type="textarea" :rows="3" maxlength="4000" show-word-limit placeholder="选填" />
</el-form-item> </el-form-item>
<el-form-item label="签订日期">
<el-date-picker v-model="header.signingDate" type="date" value-format="YYYY-MM-DD" placeholder="选填" style="width:100%" />
</el-form-item>
<el-form-item label="生效日期">
<el-date-picker v-model="header.effectiveDate" type="date" value-format="YYYY-MM-DD" placeholder="选填" style="width:100%" />
</el-form-item>
<el-form-item label="终止日期">
<el-date-picker v-model="header.endDate" type="date" value-format="YYYY-MM-DD" placeholder="选填" style="width:100%" />
</el-form-item>
</el-form> </el-form>
</div> </div>
@@ -83,6 +92,11 @@
<el-input v-model="row.unit" maxlength="32" placeholder="选填" /> <el-input v-model="row.unit" maxlength="32" placeholder="选填" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="金额" width="140">
<template #default="{ row }">
<el-input-number v-model="row.amount" :min="0" :precision="2" controls-position="right" style="width: 100%" placeholder="选填" />
</template>
</el-table-column>
<el-table-column label="操作" width="90" fixed="right"> <el-table-column label="操作" width="90" fixed="right">
<template #default="{ $index }"> <template #default="{ $index }">
<el-button type="danger" link :disabled="lines.length <= 1" @click="removeLine($index)">删除</el-button> <el-button type="danger" link :disabled="lines.length <= 1" @click="removeLine($index)">删除</el-button>
@@ -125,13 +139,16 @@ const headerFormRef = ref(null);
const header = reactive({ const header = reactive({
title: "", title: "",
remarks: "", remarks: "",
signingDate: null,
effectiveDate: null,
endDate: null,
}); });
const headerRules = { const headerRules = {
title: [{ required: true, message: "请输入合同标题或编号", trigger: "blur" }], title: [{ required: true, message: "请输入合同标题或编号", trigger: "blur" }],
}; };
const lines = ref([{ itemName: "", quantity: 1, unit: "" }]); const lines = ref([{ itemName: "", quantity: 1, unit: "", amount: undefined }]);
const projectOptionsFiltered = computed(() => { const projectOptionsFiltered = computed(() => {
const cid = customerId.value; const cid = customerId.value;
@@ -186,7 +203,7 @@ async function loadAllProjects() {
} }
function addLineRow() { function addLineRow() {
lines.value.push({ itemName: "", quantity: 1, unit: "" }); lines.value.push({ itemName: "", quantity: 1, unit: "", amount: undefined });
} }
function removeLine(index) { function removeLine(index) {
@@ -233,6 +250,9 @@ async function submit() {
projectId: projectId.value, projectId: projectId.value,
title: header.title.trim(), title: header.title.trim(),
remarks: header.remarks?.trim() || undefined, remarks: header.remarks?.trim() || undefined,
signingDate: header.signingDate || undefined,
effectiveDate: header.effectiveDate || undefined,
endDate: header.endDate || undefined,
}); });
const id = data?.id; const id = data?.id;
if (id == null) { if (id == null) {
@@ -245,6 +265,7 @@ async function submit() {
itemName: r.itemName.trim(), itemName: r.itemName.trim(),
quantity: r.quantity, quantity: r.quantity,
unit: r.unit?.trim() || undefined, unit: r.unit?.trim() || undefined,
amount: r.amount ?? undefined,
}); });
} }
ElMessage.success("已创建草稿"); ElMessage.success("已创建草稿");
@@ -58,6 +58,15 @@
:value="opt.value" :value="opt.value"
/> />
</el-select> </el-select>
<el-form-item label="原因码">
<el-select v-model="reasonCode" placeholder="选填" style="width:220px">
<el-option label="成功激活" value="ACTIVATION_SUCCESS" />
<el-option label="激活失败-网络" value="ACTIVATION_FAILED_NETWORK" />
<el-option label="激活失败-密钥无效" value="ACTIVATION_FAILED_KEY" />
<el-option label="手工变更" value="MANUAL_CHANGE" />
<el-option label="到期失效" value="EXPIRED" />
</el-select>
</el-form-item>
<el-button type="primary" :loading="patchingStatus" :disabled="!statusPick" @click="applyStatus">更新状态</el-button> <el-button type="primary" :loading="patchingStatus" :disabled="!statusPick" @click="applyStatus">更新状态</el-button>
</div> </div>
</template> </template>
@@ -92,6 +101,7 @@ const bindForm = reactive({
}); });
const statusPick = ref(""); const statusPick = ref("");
const reasonCode = ref("");
const statusOptions = [ const statusOptions = [
{ value: "REGISTERED", label: "已登记 (REGISTERED)" }, { value: "REGISTERED", label: "已登记 (REGISTERED)" },
@@ -214,9 +224,10 @@ async function applyStatus() {
if (id == null || !st) return; if (id == null || !st) return;
patchingStatus.value = true; patchingStatus.value = true;
try { try {
await patchLicenseSnStatus(id, { status: st }); await patchLicenseSnStatus(id, { status: st, reasonCode: reasonCode.value || undefined });
ElMessage.success("状态已更新"); ElMessage.success("状态已更新");
statusPick.value = ""; statusPick.value = "";
reasonCode.value = "";
await loadSn(); await loadSn();
} catch (e) { } catch (e) {
ElMessage.error(apiErrorMessage(e, "状态更新失败")); ElMessage.error(apiErrorMessage(e, "状态更新失败"));