feat: add customer field to Bug model with configurable mapping

- Bug model: added optional 'customer' property
- FieldMappings: added 'customerField' (default: 客户名称)
- BugMapper: reads customer value from configured column
- BugRow: displays customer in blue when present
- Settings: Customer field text field in Field Mappings section

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
tigerenwork 2026-06-29 20:50:46 +08:00
parent 7590389a04
commit 0ce557ac8e
5 changed files with 9 additions and 0 deletions

View File

@ -16,6 +16,7 @@ struct AppConfig: Codable, Equatable {
var statusField: String = "Status" var statusField: String = "Status"
var assigneeField: String = "Assignee" var assigneeField: String = "Assignee"
var reporterField: String = "Reporter" var reporterField: String = "Reporter"
var customerField: String = "客户名称"
var createdAtField: String = "Created At" var createdAtField: String = "Created At"
var updatedAtField: String = "Updated At" var updatedAtField: String = "Updated At"

View File

@ -7,6 +7,7 @@ struct Bug: Identifiable, Equatable, Hashable {
let status: BugStatus let status: BugStatus
let assignee: String let assignee: String
let reporter: String? let reporter: String?
let customer: String?
let createdAt: Date let createdAt: Date
let updatedAt: Date let updatedAt: Date
let feishuURL: URL let feishuURL: URL

View File

@ -120,6 +120,7 @@ enum BugMapper {
status: mapStatus(stringValue(in: fields, key: mappings.statusField), mappings: mappings), status: mapStatus(stringValue(in: fields, key: mappings.statusField), mappings: mappings),
assignee: userName(in: fields, key: mappings.assigneeField) ?? "Unknown", assignee: userName(in: fields, key: mappings.assigneeField) ?? "Unknown",
reporter: userName(in: fields, key: mappings.reporterField), reporter: userName(in: fields, key: mappings.reporterField),
customer: stringValue(in: fields, key: mappings.customerField),
createdAt: FeishuDateParser.parse(rawValue(in: fields, key: mappings.createdAtField)) ?? .distantPast, createdAt: FeishuDateParser.parse(rawValue(in: fields, key: mappings.createdAtField)) ?? .distantPast,
updatedAt: FeishuDateParser.parse(rawValue(in: fields, key: mappings.updatedAtField)) ?? .distantPast, updatedAt: FeishuDateParser.parse(rawValue(in: fields, key: mappings.updatedAtField)) ?? .distantPast,
feishuURL: FeishuURLBuilder.recordURL( feishuURL: FeishuURLBuilder.recordURL(

View File

@ -29,6 +29,11 @@ struct BugRow: View {
.font(.caption2) .font(.caption2)
.foregroundStyle(.secondary) .foregroundStyle(.secondary)
} }
if let customer = bug.customer {
Text(customer)
.font(.caption2)
.foregroundStyle(.blue.opacity(0.8))
}
} }
} }

View File

@ -73,6 +73,7 @@ struct SettingsView: View {
TextField("Status field", text: $config.fieldMappings.statusField) TextField("Status field", text: $config.fieldMappings.statusField)
TextField("Assignee field", text: $config.fieldMappings.assigneeField) TextField("Assignee field", text: $config.fieldMappings.assigneeField)
TextField("Reporter field", text: $config.fieldMappings.reporterField) TextField("Reporter field", text: $config.fieldMappings.reporterField)
TextField("Customer field", text: $config.fieldMappings.customerField)
TextField("Created At field", text: $config.fieldMappings.createdAtField) TextField("Created At field", text: $config.fieldMappings.createdAtField)
TextField("Updated At field", text: $config.fieldMappings.updatedAtField) TextField("Updated At field", text: $config.fieldMappings.updatedAtField)
} }