import 'package:flutter/material.dart'; import 'theme.dart'; /// 后端枚举 / 码 → 中文。对齐 web `labels.ts` + 投标状态。 const zhMap = { 'TECH_INITIAL': '技术初审', 'FETCH': '取标', 'TECH_FINAL': '技术终审', 'DRAFTING': '制标', 'REVIEW1': '商务一审', 'REVIEW2': '商务二审', 'PRINT': '印封', 'LIST': '投标执行', 'PENDING': '待审批', 'WON': '中标', 'LOST': '未中标', 'FAILED': '流标废标', 'TERMINATED': '已终止', 'DRAFT': '草稿', 'APPROVED': '已通过', 'REJECTED': '已驳回', 'CANCELLED': '已取消', 'ACTIVE': '启用', 'DISABLED': '停用', 'OPEN': '进行中', 'OFFSET': '已冲账', 'DONE': '已完成', 'RETURNED': '已交回', 'PAID': '已付', 'UNPAID': '待付', 'TO_ISSUE': '待开', 'ISSUED': '已开', 'RECEIVED': '已回', 'OVERDUE': '逾期', 'INTERNAL_ACCEPTED': '内部已验收', 'ACCEPTED': '已验收', 'ALL': '全部', 'DEPT': '本部门', 'SELF': '本人', 'BID': '投标', 'PROJECT': '正式项目', 'ADMIN': '行政', 'MARKETING': '营销', 'LABOR': '人工', 'TRAVEL': '差旅', 'PURCHASE': '采购', 'TENDER': '招标', 'PERFORMANCE': '履约保证金', 'WARRANTY': '项目质保金', 'EXPENSE': '报销', 'BOND': '保证金打出', 'LOAN': '借款', 'OFFICE': '办公申请', 'SEAL': '用章', 'HR': '人事', 'LEAVE': '请假', 'OVERTIME': '加班', 'TRIP': '出差', 'OUT': '外出', 'RESIGN': '离职', 'PROMOTE': '晋升', 'INTERN': '实习', 'PROBATION': '试用', 'REGULAR': '正式', 'LEFT': '离职', 'SINGLE': '单休', 'DOUBLE': '双休', 'MALE': '男', 'FEMALE': '女', 'HIGH_SCHOOL': '高中及以下', 'COLLEGE': '专科', 'BACHELOR': '本科', 'MASTER': '硕士', 'DOCTOR': '博士', 'HIRE': '入职', 'REGULARIZE': '转正', 'TRANSFER': '调岗', 'CREATE': '发起', 'SUBMIT': '提交', 'APPROVE': '同意', 'REJECT': '驳回', 'DRAFTER': '制标人', 'FETCHER': '取标人', 'COORDINATOR': '特殊协调人', 'BIDDER': '投标人', 'SPECIAL': '特殊筛选', 'FLOW': '普通筛选', 'BID_TECH_INITIAL': '技术初审', 'BID_TECH_FINAL': '技术终审', 'BID_FETCH': '取标', 'BID_ASSIGN_FETCH': '派取标人', 'BID_ASSIGN_DRAFT': '派制标人', 'BID_FINAL_PASSED': '终审通过通知', 'BID_DRAFT_DONE': '制标完成通知', 'BID_TERMINATED': '投标终止通知', 'BID_DRAFT': '制标', 'BID_REVIEW1': '商务一审', 'BID_REVIEW2': '商务二审', 'BID_PRINT': '印封', 'BID_COMPLETE': '补全投标', 'BID_EXECUTION': '投标执行', 'BID_ASSIGN_FETCHER': '派取标人', 'UPDATE_COMPETITOR_WIN': '登记对方中标信息', 'UPDATE_LEGAL_ENTITY': '修改参与主体', 'CONFIRMED': '已确认', 'INTERNAL': '内部验收', 'CUSTOMER': '客户验收', 'CONTRACT_APPROVAL': '合同审批', 'CONTRACT_DRAFT': '完善合同草稿', 'EXPENSE_APPROVAL': '报销确认', 'LOAN_APPROVAL': '借款确认', 'LOAN_OFFSET': '借款冲账', 'PROJECT_TIMESHEET': '工时填报', 'PROJECT_ACCEPT': '项目验收', 'SEAL_APPROVAL': '用章审批', 'SEAL_RETURN': '印章归还', 'CREDENTIAL_RETURN': '证照归还', 'BID_OPEN': '开标反馈', 'WORK_ASSIGN': '工作安排', 'OFFICE_APPLY': '办公申请', 'HR_LEAVE': '人事申请', 'SEAL_REQUEST': '用章申请', 'WORK_REPORT': '工作汇报', 'NOTICE': '通知公告', 'ASSET_BUY': '资产购置', 'ASSET_USE': '资产领用', 'VEHICLE': '用车', 'DIGITAL': '数字资产', 'FIXED': '固定资产', 'IN_USE': '占用中', 'IN_STOCK': '在库', 'OUT_STOCK': '已出库', 'TAKEN_OUT': '外带', 'LENT': '外借', 'BORROWED': '已外借', 'IDLE': '闲置', 'SCRAPPED': '已报废', 'AVAILABLE': '可用', 'MAINTAIN': '维修中', 'OCCUPIED': '占用中', 'PENDING_IN': '待入库', 'ID_CARD': '身份证', 'PASSPORT': '护照', 'OTHER_ID': '其他证件', 'GENERAL': '通用', 'TODO': '待办', 'TASK': '任务截止', 'BORROW': '证照归还', 'LOGIN': '登录', 'LOGIN_FAIL': '登录失败', 'APPROVAL': '审批', 'FORBIDDEN': '越权', 'ACL': '权限', 'SENT': '已提交', 'UPDATE': '修改', 'DELETE': '删除', 'OK': '成功', 'FAIL': '失败', 'BUSINESS': '商务', 'TECH': '技术', 'FINANCE': '财务', 'PUBLISHED': '已发布', 'ANNOUNCE': '公告', 'POLICY': '制度', 'direct': '单聊', 'group': '群聊', 'admin': '管理员', 'owner': '负责人', 'hr': '人事', 'finance': '财务', 'finance_manager': '财务经理', 'cashier': '出纳', 'seal': '用章管理员', 'asset': '资产管理员', 'project_manager': '项目经理', 'tech_director': '技术总监', 'marketing': '营销', 'bidder': '投标', 'staff': '员工', 'user': '用户', 'true': '是', 'false': '否', 'INQUIRY': '询价', 'OPEN_TENDER': '公开招标', 'INVITE': '邀请招标', 'COMPETITIVE': '竞争性谈判', 'SINGLE_SOURCE': '单一来源', }; /// 详情页字段名。没有映射的 camelCase 一律不展示,避免露出英文列名。 const fieldZh = { 'title': '标题', 'name': '名称', 'purpose': '事由', 'reason': '事由', 'remark': '备注', 'status': '状态', 'kind': '类型', 'source': '来源', 'sourceType': '筛选类型', 'bizType': '业务', 'amount': '金额', 'days': '天数', 'claimNo': '报销单号', 'loanNo': '借款单号', 'bidNo': '招标编号', 'externalNo': '招标编号', 'contractNo': '合同号', 'projectNo': '项目编号', 'projectType': '项目类型', 'sealType': '印章类型', 'destination': '目的地', 'assetKind': '资产类型', 'createdAt': '创建时间', 'updatedAt': '更新时间', 'dueAt': '截止', 'startAt': '开始', 'endAt': '结束', 'decidedAt': '审批时间', 'comment': '意见', 'createdBy': '发起人', 'bidCase': '关联投标', 'legalEntity': '参与主体', 'qualificationNeed': '所需资质', 'tenderMethod': '招标方式', 'applyStartAt': '申领开始', 'applyEndAt': '申领截止', 'applyMethod': '申领方式', 'openAt': '开标时间', 'openMethod': '开标方式', 'openPlace': '开标地点', 'bondMethod': '保证金', 'bondStatus': '保证金状态', 'bondType': '保证金类型', 'delivererName': '递交人', 'contactName': '联系人', 'contactPhone': '联系电话', 'nasPath': '标书路径', 'summary': '摘要', 'resultNote': '结果说明', 'printCost': '印封费用', 'printNote': '印封备注', 'projectNature': '项目性质', 'securityLevel': '密级', 'priceCap': '限价', 'quoteAmount': '报价', 'needSurvey': '需要踏勘', 'fetchedAt': '取标时间', 'printedAt': '印封时间', 'openedResultAt': '开标反馈时间', 'actionLogs': '操作记录', 'projects': '关联项目', 'files': '附件', 'reviewers': '审批人', 'assignees': '经办人', 'versions': '标书版本', 'displayName': '姓名', 'departmentName': '部门', 'department': '部门', 'mobile': '手机', 'email': '邮箱', 'party': '客商', 'applicant': '申请人', 'assignee': '经办人', 'keeper': '保管人', 'holder': '占用人', 'spec': '规格', 'unit': '单位', 'qty': '数量', 'quantity': '数量', 'location': '位置', 'address': '地址', 'code': '编号', 'no': '编号', 'type': '类型', 'category': '分类', 'level': '级别', 'priority': '优先级', 'progress': '进度', 'budget': '预算', 'cost': '成本', 'owner': '负责人', 'manager': '负责人', 'description': '说明', 'content': '内容', 'body': '正文', 'note': '备注', 'result': '结果', 'outcome': '结果', 'method': '方式', 'channel': '渠道', 'scope': '范围', 'role': '角色', 'roles': '角色', 'employmentStatus': '用工状态', 'gender': '性别', 'idNo': '证件号', 'idType': '证件类型', 'idNumber': '证件号码', 'idCard': '身份证号', 'jobTitle': '岗位', 'hireDate': '入职日期', 'hiredAt': '入职日期', 'birthday': '出生日期', 'birthDate': '出生日期', 'education': '学历', 'school': '毕业院校', 'major': '专业', 'emergencyContact': '紧急联系人', 'emergencyPhone': '紧急电话', 'bankName': '开户行', 'bankAccount': '银行账号', 'workCity': '工作城市', 'officeLocation': '办公地点', 'employeeNo': '工号', 'staffNo': '工号', 'jobNo': '工号', 'realName': '姓名', 'username': '账号', 'phone': '手机', 'wechat': '微信', 'nation': '民族', 'nativePlace': '籍贯', 'maritalStatus': '婚姻状况', 'addressHome': '家庭住址', 'entryDate': '入职日期', 'regularDate': '转正日期', 'leaveDate': '离职日期', 'contractEnd': '合同到期', 'keeperName': '保管人', 'holderName': '占用人', 'legalEntityName': '参与主体', 'winnerName': '中标单位', 'winnerAmount': '中标金额', }; String zh(dynamic v) { if (v == null) return '—'; if (v is bool) return v ? '是' : '否'; final s = '$v'.trim(); if (s.isEmpty) return '—'; return zhMap[s] ?? s; } /// 字段名转中文。仍是英文驼峰的返回空串,调用方应跳过。 String fieldLabel(String k) { final key = k.contains('.') ? k.split('.').last : k; if (fieldZh.containsKey(k)) return fieldZh[k]!; if (fieldZh.containsKey(key)) return fieldZh[key]!; if (zhMap.containsKey(key)) return zhMap[key]!; if (RegExp(r'[\u4e00-\u9fff]').hasMatch(key)) return key; return ''; } Color statusColor(dynamic v) { switch ('$v') { case 'APPROVED': case 'DONE': case 'OFFSET': case 'RETURNED': case 'PAID': case 'WON': case 'ACCEPTED': case 'ISSUED': case 'RECEIVED': return kWeGreen; case 'PENDING': case 'OPEN': case 'DRAFT': case 'FETCH': case 'DRAFTING': case 'TECH_INITIAL': case 'TECH_FINAL': case 'REVIEW1': case 'REVIEW2': case 'PRINT': case 'LIST': return const Color(0xFFFA9D3B); case 'REJECTED': case 'CANCELLED': case 'OVERDUE': case 'TERMINATED': case 'FAILED': case 'LOST': return kDanger; default: return kMute; } } class StatusDot extends StatelessWidget { const StatusDot(this.code, {super.key}); final dynamic code; @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), decoration: BoxDecoration( color: statusColor(code).withValues(alpha: 0.12), borderRadius: BorderRadius.circular(4), ), child: Text(zh(code), style: TextStyle(fontSize: 11, color: statusColor(code), fontWeight: FontWeight.w600)), ); } }