Replace phone last-4 verification with customer signature

Customer now signs on the confirm page instead of inputting the last
4 digits of their phone. Signature is stored as a base64 PNG dataURL
on the work order and shown back to the customer plus archived for
admin review. Reject still bypasses signature but now requires a
reason.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Frudrax Cheng
2026-05-26 18:02:04 +08:00
parent 128bb7cda6
commit 6a48b0624f
4 changed files with 146 additions and 20 deletions
+6 -2
View File
@@ -255,6 +255,7 @@ type AftersalesOrder struct {
ScannedAt *time.Time `json:"scannedAt"`
ConfirmedAt *time.Time `json:"confirmedAt"`
RejectCount int `gorm:"default:0" json:"rejectCount"`
Signature string `gorm:"type:text" json:"signature,omitempty"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
@@ -293,10 +294,12 @@ type SubmitForConfirmationDTO struct {
}
// CustomerConfirmDTO 客户确认请求
// Signature 为客户在网页上手写签名的 base64 PNG dataURL,仅 authorize 时必填
// RejectReason 为客户拒绝的原因,仅 reject 时必填
type CustomerConfirmDTO struct {
PhoneLast4 string `json:"phoneLast4" validate:"required,len=4,numeric"`
Action string `json:"action" validate:"required,oneof=authorize reject"`
RejectReason string `json:"rejectReason,omitempty"`
Signature string `json:"signature,omitempty" validate:"required_if=Action authorize"`
RejectReason string `json:"rejectReason,omitempty" validate:"required_if=Action reject"`
}
// ReassignAftersalesDTO 重新分配技术员请求
@@ -318,4 +321,5 @@ type AftersalesPublicView struct {
TechnicianName string `json:"technicianName"`
CreatedAt time.Time `json:"createdAt"`
ConfirmedAt *time.Time `json:"confirmedAt"`
Signature string `json:"signature,omitempty"`
}