// 【重要】必须使用 const Component 作为组件变量名 // 加氢站管理 - 站点信息(列表 + KPI 分类 + 独立新建页 / 编辑查看抽屉) var H2_REGION_CASCADER_OPTIONS = [ { value: '浙江省', label: '浙江省', children: [{ value: '嘉兴市', label: '嘉兴市' }, { value: '杭州市', label: '杭州市' }, { value: '宁波市', label: '宁波市' }] }, { value: '上海市', label: '上海市', children: [{ value: '上海市', label: '上海市' }] }, { value: '江苏省', label: '江苏省', children: [{ value: '南京市', label: '南京市' }, { value: '苏州市', label: '苏州市' }] }, { value: '广东省', label: '广东省', children: [{ value: '广州市', label: '广州市' }, { value: '深圳市', label: '深圳市' }] } ]; var H2_STATION_KPI_CARDS = [ { key: 'all', type: 'total', title: '全部加氢站', desc: '纳入台账管理的全部站点' }, { key: 'high', type: 'normal', title: '高频加氢站点', desc: '加氢次数 ≥ 3 次的站点' }, { key: 'low', type: 'warning', title: '低频加氢站点', desc: '加氢次数 1~2 次的站点' }, { key: 'none', type: 'unuploaded', title: '无加氢站点', desc: '暂无加氢记录的站点' } ]; var H2_SIGNED_FILTER_CARDS = [ { key: 'yes', type: 'normal', title: '已签约站点', desc: '已签约的加氢站点,点击快捷筛选' }, { key: 'no', type: 'unuploaded', title: '未签约站点', desc: '尚未签约的加氢站点,点击快捷筛选' } ]; var H2_BUSINESS_STATUS_OPTIONS = [ { value: '营业中', label: '营业中' }, { value: '暂停营业', label: '暂停营业' }, { value: '停止营业', label: '停止营业' } ]; var H2_PAGE_STYLE = [ '.h2-station-page { padding: 24px 24px 80px; height: 100vh; display: flex; flex-direction: column; background: linear-gradient(165deg, #f1f5f9 0%, #f8fafc 50%, #f1f5f9 100%); overflow: hidden; box-sizing: border-box; }', '.h2-station-page .lc-filter-card.ant-card { border-radius: 16px !important; border: 1px solid #e2e8f0 !important; box-shadow: 0 4px 20px -4px rgba(15, 23, 42, 0.03) !important; margin-bottom: 16px; }', '.h2-station-page .lc-filter-card > .ant-card-head { border-bottom: 1px solid #f1f5f9 !important; min-height: auto; padding: 12px 20px !important; }', '.h2-station-page .lc-filter-card > .ant-card-head .ant-card-head-title { font-size: 15px !important; font-weight: 700 !important; color: #0f172a !important; padding: 0 !important; }', '.h2-station-page .lc-filter-card > .ant-card-body { padding: 16px 20px 20px !important; }', '.h2-station-page .lc-filter-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px 24px; }', '@media (max-width: 1100px) { .h2-station-page .lc-filter-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }', '@media (max-width: 720px) { .h2-station-page .lc-filter-grid { grid-template-columns: 1fr; } }', '.h2-station-page .lc-filter-field { display: flex; align-items: center; gap: 12px; min-width: 0; }', '.h2-station-page .lc-filter-field-label { flex: 0 0 100px; text-align: right; font-size: 13px; font-weight: 500; color: #475569; line-height: 1.4; white-space: nowrap; }', '.h2-station-page .lc-filter-field-control { flex: 1; min-width: 0; }', '.h2-station-page .lc-filter-field-control .ant-input, .h2-station-page .lc-filter-field-control .ant-select { width: 100%; }', '.h2-station-page .lc-filter-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px; padding-top: 16px; border-top: 1px solid #f1f5f9; }', '.h2-station-page .lc-alert-stats-row { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 12px; margin-bottom: 16px; }', '@media (max-width: 1400px) { .h2-station-page .lc-alert-stats-row { grid-template-columns: repeat(3, minmax(0, 1fr)); } }', '@media (max-width: 900px) { .h2-station-page .lc-alert-stats-row { grid-template-columns: repeat(2, minmax(0, 1fr)); } }', '@media (max-width: 640px) { .h2-station-page .lc-alert-stats-row { grid-template-columns: 1fr; } }', '.h2-station-page .lc-alert-card { display: flex; align-items: flex-start; gap: 12px; padding: 14px 30px 14px 16px; border-radius: 12px; border: 1px solid #e2e8f0; background: #fff; position: relative; overflow: hidden; min-width: 0; min-height: 44px; }', '.h2-station-page .lc-alert-card-main { flex: 1; min-width: 0; }', '.h2-station-page .lc-alert-card-icon { flex-shrink: 0; width: 40px; height: 40px; border-radius: 10px; display: flex; align-items: center; justify-content: center; }', '.h2-station-page .lc-alert-card-val { font-size: 26px; font-weight: 800; line-height: 1.1; color: #0f172a; font-variant-numeric: tabular-nums; }', '.h2-station-page .lc-alert-card-title { font-size: 13px; font-weight: 600; color: #334155; margin-top: 2px; }', '.h2-station-page .lc-alert-card-tip-anchor { position: absolute; top: 8px; right: 8px; z-index: 2; line-height: 0; }', '.h2-station-page .lc-alert-card-tip { width: 18px; height: 18px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; color: #94a3b8; background: rgba(255,255,255,0.92); border: 1px solid #e2e8f0; cursor: help; line-height: 0; }', '.h2-station-page .lc-alert-card-tip:hover { color: #64748b; border-color: #cbd5e1; background: #fff; }', '.h2-station-page .lc-alert-card--total { background: linear-gradient(135deg, #f8fafc 0%, #fff 100%); }', '.h2-station-page .lc-alert-card--total .lc-alert-card-icon { background: #e2e8f0; color: #475569; }', '.h2-station-page .lc-alert-card--normal { background: linear-gradient(135deg, #ecfdf5 0%, #fff 55%); border-color: #bbf7d0; }', '.h2-station-page .lc-alert-card--normal .lc-alert-card-icon { background: #d1fae5; color: #059669; }', '.h2-station-page .lc-alert-card--normal .lc-alert-card-val { color: #047857; }', '.h2-station-page .lc-alert-card--warning { background: linear-gradient(135deg, #fff7ed 0%, #fff 55%); border-color: #fed7aa; }', '.h2-station-page .lc-alert-card--warning .lc-alert-card-icon { background: #ffedd5; color: #ea580c; }', '.h2-station-page .lc-alert-card--warning .lc-alert-card-val { color: #c2410c; }', '.h2-station-page .lc-alert-card--unuploaded { background: linear-gradient(135deg, #f8fafc 0%, #fff 55%); }', '.h2-station-page .lc-alert-card--unuploaded .lc-alert-card-icon { background: #f1f5f9; color: #64748b; }', '.h2-station-page .lc-alert-card--unuploaded .lc-alert-card-val { color: #64748b; }', '.h2-station-page .lc-alert-card-clickable { cursor: pointer; transition: box-shadow 0.2s ease, border-color 0.2s ease, transform 0.2s ease; }', '.h2-station-page .lc-alert-card-clickable:hover { box-shadow: 0 4px 14px rgba(15, 23, 42, 0.08); }', '.h2-station-page .lc-alert-card-clickable:focus-visible { outline: 2px solid #10b981; outline-offset: 2px; }', '.h2-station-page .lc-alert-card-active { box-shadow: 0 0 0 2px rgba(16, 185, 129, 0.25) !important; border-color: #10b981 !important; }', '.h2-station-page .lc-table-section { margin-bottom: 0; flex: 1; display: flex; flex-direction: column; min-height: 0; }', '.h2-station-page .lc-table-toolbar { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 10px 16px; margin-bottom: 8px; min-height: 32px; }', '.h2-station-page .lc-table-legend-outer { display: flex; align-items: center; flex-wrap: wrap; gap: 12px; padding: 6px 4px; font-size: 12px; color: #64748b; }', '.h2-station-page .lc-table-legend-label { font-weight: 600; color: #64748b; }', '.h2-station-page .lc-table-legend-item { display: inline-flex; align-items: center; gap: 6px; }', '.h2-station-page .lc-table-legend-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }', '.h2-station-page .lc-table-toolbar-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-left: auto; }', '.h2-station-page .lc-table-card { background: #fff; border-radius: 16px; border: 1px solid #e2e8f0; box-shadow: 0 4px 20px -4px rgba(15, 23, 42, 0.03); overflow: hidden; flex: 1; overflow-y: auto; display: flex; flex-direction: column; }', '.h2-station-page .lc-list-table .ant-table-wrapper, .h2-station-page .lc-list-table .ant-table { width: 100% !important; }', '.h2-station-page .lc-table-card .ant-table-thead > tr > th { background: #f8fafc !important; color: #475569 !important; font-weight: 700 !important; font-size: 13px !important; border-bottom: 1px solid #e2e8f0 !important; padding: 12px 16px !important; }', '.h2-station-page .lc-table-card .ant-table-tbody > tr.ant-table-measure-row, .h2-station-page .lc-table-card .ant-table-tbody > tr.ant-table-measure-row > td { height: 0 !important; max-height: 0 !important; padding: 0 !important; margin: 0 !important; border: none !important; line-height: 0 !important; font-size: 0 !important; overflow: hidden !important; visibility: hidden !important; }', '.h2-station-page .lc-table-card .ant-table-tbody > tr:not(.ant-table-measure-row) > td { padding: 12px 16px !important; font-size: 13px; }', '.h2-station-page .lc-table-card .ant-table-tbody > tr:not(.ant-table-measure-row):hover > td { background: #f8fafc !important; }', '.h2-station-page .lc-table-card .ant-pagination { margin: 0 !important; padding: 12px 16px !important; border-top: 1px solid #f1f5f9; }', '.h2-station-page .lc-action-btn { font-weight: 600 !important; color: #10b981 !important; padding: 0 !important; min-height: 44px; }', '.h2-station-page .lc-action-btn-danger { color: #ef4444 !important; }', '.h2-station-page .h2-action-more-btn { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: 8px; color: #64748b; cursor: pointer; transition: background 0.15s ease, color 0.15s ease; }', '.h2-station-page .h2-action-more-btn:hover { background: #f1f5f9; color: #334155; }', '.h2-station-page .h2-action-more-btn:focus-visible { outline: 2px solid #10b981; outline-offset: 2px; }', '.h2-station-page .h2-row-actions { display: inline-flex; align-items: center; gap: 4px; }', '.h2-station-page .lc-station-name { font-weight: 700; color: #0f172a; font-size: 13px; }', '.h2-station-page .lc-station-name-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; min-width: 0; }', '.h2-station-page .lc-station-name-row .lc-station-name { min-width: 0; }', '.h2-station-page .lc-station-signed-tag { margin: 0 !important; border-radius: 6px !important; font-weight: 600 !important; flex-shrink: 0; line-height: 20px !important; }', '.h2-station-page .lc-refuel-kg-row { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex-wrap: wrap; min-width: 0; }', '.h2-station-page .lc-refuel-freq-tag { margin: 0 !important; border-radius: 6px !important; font-weight: 600 !important; flex-shrink: 0; line-height: 20px !important; }', '.h2-station-page .lc-station-region { color: #64748b; font-size: 12px; margin-bottom: 2px; }', '.h2-station-page .lc-station-contact-name { font-weight: 600; color: #0f172a; font-size: 13px; line-height: 1.35; }', '.h2-station-page .lc-station-contact-phone { color: #64748b; font-size: 12px; margin-top: 2px; line-height: 1.35; font-variant-numeric: tabular-nums; }', '.h2-station-page .h2-drawer-section-title { font-size: 14px; font-weight: 700; color: #0f172a; margin: 4px 0 12px; display: flex; align-items: center; gap: 8px; }', '.h2-station-page .h2-drawer-section-title::before { content: ""; width: 3px; height: 14px; border-radius: 2px; background: linear-gradient(180deg, #10b981, #34d399); flex-shrink: 0; }', '.h2-station-page .h2-region-address { display: flex; flex-direction: column; gap: 12px; width: 100%; }', '.h2-station-page .h2-region-address .ant-select, .h2-station-page .h2-region-address .ant-input { width: 100%; }', '.h2-station-page .h2-region-address--inline { flex-direction: row; align-items: center; gap: 8px; }', '.h2-station-page .h2-region-address--inline .h2-region-address-cascader { flex: 0 0 38%; max-width: 220px; min-width: 140px; }', '.h2-station-page .h2-region-address--inline .h2-region-address-detail { flex: 1; min-width: 0; }', '.h2-station-page .h2-create-radio-group { display: flex; flex-wrap: wrap; align-items: center; gap: 16px; min-height: 32px; }', '.h2-station-page .h2-create-radio-group .ant-radio-wrapper { margin-inline-end: 0; font-size: 14px; color: #1d2129; }', '.h2-station-page .h2-contract-dates { display: flex; align-items: center; gap: 8px; width: 100%; flex-wrap: wrap; }', '.h2-station-page .h2-contract-dates-sep { color: #94a3b8; font-size: 13px; flex-shrink: 0; }', '.h2-station-page .h2-contract-upload { display: flex; flex-direction: column; gap: 10px; width: 100%; }', '.h2-station-page .h2-contract-upload-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }', '.h2-station-page .h2-contract-file-list { display: flex; flex-direction: column; gap: 6px; }', '.h2-station-page .h2-contract-file-item { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 6px 10px; border-radius: 6px; background: #f8fafc; border: 1px solid #e2e8f0; font-size: 13px; }', '.h2-station-page .h2-contract-file-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #334155; }', '.h2-station-page .h2-contract-file-btns { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }', '.h2-station-page--create .h2-create-form .h2-create-upload-btn.ant-upload-wrapper { width: auto; }', '.h2-station-page--create .h2-create-form .h2-region-address { gap: 12px; margin-top: 0; }', '.h2-station-page .h2-business-hours { display: flex; flex-direction: column; gap: 12px; width: 100%; }', '.h2-station-page .h2-business-hours-range { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; width: 100%; }', '.h2-station-page .h2-business-hours-range-item { display: flex; flex-direction: column; gap: 6px; min-width: 0; }', '.h2-station-page .h2-business-hours-range-label { font-size: 12px; color: #64748b; line-height: 1.2; }', '.h2-station-page--create .h2-create-form .h2-business-hours .ant-picker { width: 100% !important; height: 32px !important; border-radius: 2px !important; border: 1px solid #e5e6eb !important; background: #fff !important; }', '.h2-station-page--create .h2-create-form .h2-business-hours .ant-picker .ant-picker-input > input { font-size: 14px !important; color: #1d2129 !important; }', '.h2-station-page--create .h2-create-form .h2-business-hours .ant-picker:not(.ant-picker-disabled):hover { border-color: #c9cdd4 !important; background: #fff !important; }', '.h2-station-page--create .h2-create-form .h2-business-hours .ant-picker-focused { border-color: #10b981 !important; box-shadow: 0 0 0 2px rgba(16, 185, 129, 0.2) !important; background: #fff !important; }', '.h2-station-page--create .h2-create-form .h2-business-hours--col4 { gap: 8px; max-width: 100%; }', '.h2-station-page--create .h2-create-form .h2-business-hours--col4 .ant-select { width: 100% !important; max-width: 100%; }', '.h2-station-page--create .h2-create-form .h2-business-hours--col4 .h2-business-hours-range { grid-template-columns: 1fr; gap: 8px; }', '.h2-station-page--create .h2-create-form .ant-col-6 .ant-form-item-control-input { max-width: 100%; }', '.h2-station-page .h2-prd-modal .ant-modal-body { max-height: 70vh; overflow: auto; }', '.h2-station-page .h2-prd-content { padding: 8px 0; white-space: pre-wrap; font-size: 13px; line-height: 1.65; color: #475569; }', '.h2-station-page .h2-import-template-bar { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 14px 16px; margin-bottom: 14px; border-radius: 12px; background: linear-gradient(135deg, #ecfdf5 0%, #f8fafc 100%); border: 1px solid #bbf7d0; }', '.h2-station-page .h2-import-template-bar-text { font-size: 13px; color: #475569; line-height: 1.55; flex: 1; min-width: 0; }', '.h2-station-page .h2-import-preview { margin-top: 14px; padding: 12px 14px; border-radius: 10px; background: #f8fafc; border: 1px solid #e2e8f0; font-size: 13px; color: #334155; }', '.h2-station-page .h2-import-error-list { margin: 8px 0 0; padding-left: 18px; max-height: 120px; overflow: auto; font-size: 12px; color: #b91c1c; }', '.h2-station-page .h2-status-log-section { margin-top: 20px; padding-top: 16px; border-top: 1px solid #f1f5f9; }', '.h2-station-page .h2-status-log-title { font-size: 14px; font-weight: 700; color: #0f172a; margin-bottom: 10px; }', '.h2-station-page .h2-status-log-table .ant-table-thead > tr > th { background: #f8fafc !important; font-size: 12px !important; padding: 8px 12px !important; }', '.h2-station-page .h2-status-log-table .ant-table-tbody > tr > td { font-size: 12px !important; padding: 8px 12px !important; }', '.h2-station-page .h2-refuel-drill-link { border: none; background: none; padding: 0; font-weight: 700; color: #059669; cursor: pointer; font-variant-numeric: tabular-nums; font-size: 13px; }', '.h2-station-page .h2-refuel-drill-link:hover { color: #047857; text-decoration: underline; }', '.h2-station-page .h2-refuel-drill-link:focus-visible { outline: 2px solid #10b981; outline-offset: 2px; border-radius: 4px; }', '.h2-station-page .h2-ledger-totals-bar { display: flex; align-items: stretch; gap: 0; margin-bottom: 12px; border: 1px solid #bae6fd; border-radius: 10px; overflow: hidden; background: #f8fafc; box-shadow: 0 1px 0 rgba(15, 23, 42, 0.04); }', '.h2-station-page .h2-ledger-totals-bar__title { display: flex; align-items: center; justify-content: center; min-width: 72px; padding: 10px 14px; font-size: 14px; font-weight: 700; color: #0f172a; background: #e8f4fc; border-right: 1px solid #bae6fd; flex-shrink: 0; }', '.h2-station-page .h2-ledger-totals-bar__items { display: flex; flex: 1; flex-wrap: wrap; }', '.h2-station-page .h2-ledger-totals-bar__item { flex: 1; min-width: 140px; padding: 8px 20px; border-right: 1px solid #e2e8f0; display: flex; flex-direction: column; justify-content: center; gap: 4px; }', '.h2-station-page .h2-ledger-totals-bar__item:last-child { border-right: none; }', '.h2-station-page .h2-ledger-totals-bar__label { font-size: 12px; color: rgba(15, 23, 42, 0.55); font-weight: 500; line-height: 1.2; }', '.h2-station-page .h2-ledger-totals-bar__value { font-size: 16px; font-weight: 700; color: #0f172a; font-variant-numeric: tabular-nums; line-height: 1.3; }', '.h2-station-page .h2-refuel-record-table .ant-table-thead > tr > th { background: #f8fafc !important; font-size: 12px !important; padding: 8px 12px !important; }', '.h2-station-page .h2-refuel-record-table .ant-table-tbody > tr > td { font-size: 12px !important; padding: 8px 12px !important; }', '.h2-station-page .h2-prepaid-balance-cell { display: flex; align-items: center; justify-content: flex-end; gap: 6px; flex-wrap: nowrap; box-sizing: border-box; }', '.h2-station-page .h2-prepaid-balance-cell .h2-prepaid-balance-amount { flex: 0 0 auto; white-space: nowrap; border: none; background: none; padding: 0; font: inherit; font-weight: 700; cursor: pointer; text-decoration: underline; text-underline-offset: 2px; font-variant-numeric: tabular-nums; }', '.h2-station-page .h2-prepaid-balance-cell .h2-prepaid-balance-amount:focus-visible { outline: 2px solid #10b981; outline-offset: 2px; border-radius: 4px; }', '.h2-station-page .h2-prepaid-balance-cell .lc-station-signed-tag { flex-shrink: 0; }', '.h2-station-page .lc-table-card .ant-table-tbody > tr:not(.ant-table-measure-row) > td.h2-cell-prepaid-balance { overflow: visible !important; }', '.h2-station-page .h2-balance-record-table .ant-table-thead > tr > th { background: #f8fafc !important; font-size: 12px !important; padding: 8px 12px !important; }', '.h2-station-page .h2-balance-record-table .ant-table-tbody > tr > td { font-size: 12px !important; padding: 8px 12px !important; }', '.h2-station-page.h2-station-page--create { padding: 0 0 96px; height: auto; min-height: 100dvh; overflow: auto; }', '.h2-station-page--create .h2-create-shell { width: 100%; max-width: none; margin: 0; padding: 16px 20px 0; box-sizing: border-box; }', '.h2-station-page--create .h2-create-topbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 16px; padding: 12px 16px; background: #fff; border-radius: 4px; border: 1px solid #e2e8f0; }', '.h2-station-page--create .h2-create-back-btn { display: inline-flex !important; align-items: center; gap: 6px; height: 32px; padding: 0 12px !important; border-radius: 4px !important; font-weight: 500; color: #475569 !important; border: 1px solid #e2e8f0 !important; background: #fff !important; }', '.h2-station-page--create .h2-create-back-btn:hover { color: #059669 !important; border-color: #10b981 !important; background: #f0fdf4 !important; }', '.h2-station-page--create .h2-create-back-btn:focus-visible { outline: 2px solid #10b981; outline-offset: 2px; }', '.h2-station-page--create .h2-create-topbar-actions { display: flex; align-items: center; gap: 10px; }', '.h2-station-page .h2-create-card.ant-card { border-radius: 16px !important; border: 1px solid #e2e8f0 !important; box-shadow: 0 4px 20px -4px rgba(15, 23, 42, 0.05) !important; margin-bottom: 16px; transition: box-shadow 0.2s ease, border-color 0.2s ease; }', '.h2-station-page .h2-create-card:hover { box-shadow: 0 8px 28px -6px rgba(15, 23, 42, 0.08) !important; }', '.h2-station-page .h2-create-card > .ant-card-head { border-bottom: 1px solid #f1f5f9 !important; min-height: auto; padding: 16px 22px !important; background: linear-gradient(180deg, #fafbfc 0%, #fff 100%); }', '.h2-station-page .h2-create-card > .ant-card-head .ant-card-head-title { font-size: 15px !important; font-weight: 700 !important; color: #0f172a !important; padding: 0 !important; }', '.h2-station-page .h2-create-card > .ant-card-body { padding: 8px 22px 20px !important; }', '.h2-station-page .h2-card-title-bar { display: inline-flex; align-items: center; gap: 10px; }', '.h2-station-page .h2-card-title-bar::before { content: ""; width: 3px; height: 16px; border-radius: 2px; background: linear-gradient(180deg, #10b981, #34d399); flex-shrink: 0; }', '.h2-station-page .h2-card-title-icon { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: 10px; background: #ecfdf5; color: #059669; flex-shrink: 0; }', '.h2-station-page .h2-form-section { margin-bottom: 4px; }', '.h2-station-page .h2-form-section + .h2-form-section { margin-top: 8px; padding-top: 8px; border-top: 1px solid #f1f5f9; }', '.h2-station-page--create .h2-create-form .ant-row { width: 100%; }', '.h2-station-page--create .h2-create-form .ant-col-6 { min-width: 0; }', '.h2-station-page--create .h2-create-form .ant-form-item { margin-bottom: 24px; }', '.h2-station-page--create .h2-create-form .ant-form-item-label { padding: 0 0 8px; }', '.h2-station-page--create .h2-create-form .ant-form-item-label > label { font-size: 14px; font-weight: 400; color: #1d2129; height: auto; }', '.h2-station-page--create .h2-create-form .ant-form-item-label > label::after { display: none !important; }', '.h2-station-page--create .h2-create-input.ant-input:not(.ant-input-disabled):not(:disabled), .h2-station-page--create .h2-create-form .ant-select:not(.ant-select-disabled) .ant-select-selector, .h2-station-page--create .h2-create-form .ant-cascader:not(.ant-select-disabled) .ant-select-selector { height: 32px !important; min-height: 32px !important; border-radius: 2px !important; font-size: 14px !important; border: 1px solid #e5e6eb !important; background: #fff !important; color: #1d2129 !important; }', '.h2-station-page--create .h2-create-form .ant-input { padding: 4px 12px !important; }', '.h2-station-page--create .h2-create-form .ant-input-textarea:not(.ant-input-disabled):not(:disabled) { height: auto !important; min-height: auto !important; border-radius: 2px !important; background: #fff !important; color: #1d2129 !important; border: 1px solid #e5e6eb !important; }', '.h2-station-page--create .h2-create-form .ant-input:not(:disabled):not(.ant-input-disabled):hover, .h2-station-page--create .h2-create-form .ant-select:not(.ant-select-disabled):hover .ant-select-selector, .h2-station-page--create .h2-create-form .ant-cascader:not(.ant-select-disabled):hover .ant-select-selector { background: #fff !important; border-color: #c9cdd4 !important; }', '.h2-station-page--create .h2-create-form .ant-input:focus, .h2-station-page--create .h2-create-form .ant-input-focused, .h2-station-page--create .h2-create-form .ant-select-focused .ant-select-selector, .h2-station-page--create .h2-create-form .ant-cascader-focused .ant-select-selector { background: #fff !important; border-color: #10b981 !important; box-shadow: 0 0 0 2px rgba(16, 185, 129, 0.2) !important; }', '.h2-station-page--create .h2-create-form .ant-input-disabled, .h2-station-page--create .h2-create-form .ant-input:disabled, .h2-station-page--create .h2-create-form .ant-select-disabled .ant-select-selector, .h2-station-page--create .h2-create-form .ant-cascader.ant-select-disabled .ant-select-selector { background: #f2f3f5 !important; color: rgba(0, 0, 0, 0.25) !important; cursor: not-allowed !important; }', '.h2-station-page--create .h2-create-form .ant-select-selection-item { line-height: 30px !important; }', '.h2-station-page--create .h2-signed-toggle { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 12px; padding: 14px 16px; border-radius: 12px; background: #f8fafc; border: 1px solid #e2e8f0; margin-bottom: 4px; }', '.h2-station-page--create .h2-signed-toggle-label { font-size: 13px; font-weight: 600; color: #334155; }', '.h2-station-page--create .h2-signed-panel { display: grid; grid-template-rows: 0fr; opacity: 0; transition: grid-template-rows 0.28s ease-out, opacity 0.22s ease-out; }', '.h2-station-page--create .h2-signed-panel--open { grid-template-rows: 1fr; opacity: 1; }', '.h2-station-page--create .h2-signed-panel-inner { overflow: hidden; min-height: 0; }', '.h2-station-page--create .h2-signed-panel-content { padding-top: 12px; }', '.h2-station-page--create .h2-create-upload.ant-upload-wrapper .ant-upload-drag { border-radius: 12px !important; border: 1px dashed #cbd5e1 !important; background: #fafbfc !important; padding: 16px 12px !important; transition: border-color 0.2s ease, background 0.2s ease; }', '.h2-station-page--create .h2-create-upload.ant-upload-wrapper .ant-upload-drag:hover { border-color: #10b981 !important; background: #f0fdf4 !important; }', '.h2-station-page--create .h2-create-upload-hint { font-size: 12px; color: #64748b; margin-top: 4px; }', '.h2-station-page .h2-supplier-mode-bar { margin-bottom: 0; }', '.h2-station-page .h2-supplier-mode-card { position: relative; display: flex; align-items: flex-start; gap: 12px; width: 100%; padding: 14px 16px; min-height: 72px; border-radius: 12px; border: 2px solid #e2e8f0; background: #fff; cursor: pointer; text-align: left; transition: border-color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease, transform 0.15s ease; }', '.h2-station-page .h2-supplier-mode-card:hover { border-color: #86efac; background: #fafffe; }', '.h2-station-page .h2-supplier-mode-card:active { transform: scale(0.99); }', '.h2-station-page .h2-supplier-mode-card:focus-visible { outline: 2px solid #10b981; outline-offset: 2px; }', '.h2-station-page .h2-supplier-mode-card--active { border-color: #10b981; background: linear-gradient(135deg, #ecfdf5 0%, #fff 70%); box-shadow: 0 4px 16px -4px rgba(16, 185, 129, 0.25); }', '.h2-station-page .h2-supplier-mode-card-icon { flex-shrink: 0; width: 40px; height: 40px; border-radius: 10px; display: flex; align-items: center; justify-content: center; background: #f1f5f9; color: #64748b; transition: background 0.2s ease, color 0.2s ease; }', '.h2-station-page .h2-supplier-mode-card--active .h2-supplier-mode-card-icon { background: #d1fae5; color: #047857; }', '.h2-station-page .h2-supplier-mode-card-title { font-size: 14px; font-weight: 700; color: #0f172a; line-height: 1.3; }', '.h2-station-page .h2-supplier-mode-card-desc { font-size: 12px; color: #64748b; margin-top: 4px; line-height: 1.45; }', '.h2-station-page .h2-supplier-mode-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 10px 14px; margin-bottom: 16px; padding: 10px 14px; border-radius: 10px; background: #f8fafc; border: 1px solid #e2e8f0; }', '.h2-station-page .h2-supplier-type-tag { margin: 0 !important; border-radius: 6px !important; font-weight: 600 !important; }', '.h2-station-page .h2-supplier-link-select { margin-bottom: 16px; padding: 14px 16px; border-radius: 12px; background: linear-gradient(135deg, #eff6ff 0%, #f8fafc 100%); border: 1px solid #bfdbfe; }', '.h2-station-page .h2-create-footer { position: fixed; bottom: 0; left: 0; right: 0; z-index: 100; background: rgba(255, 255, 255, 0.92); backdrop-filter: blur(10px); border-top: 1px solid #e2e8f0; box-shadow: 0 -8px 24px rgba(15, 23, 42, 0.06); }', '.h2-station-page .h2-create-footer-inner { width: 100%; max-width: none; margin: 0; padding: 14px 24px; display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; box-sizing: border-box; }', '.h2-station-page .h2-create-footer-hint { font-size: 13px; color: #64748b; display: flex; align-items: center; gap: 10px; min-width: 0; }', '.h2-station-page .h2-create-footer-progress { flex: 1; min-width: 120px; max-width: 200px; }', '.h2-station-page .h2-create-footer-progress .ant-progress-text { font-size: 12px !important; font-weight: 700; color: #059669 !important; }', '.h2-station-page .h2-create-footer-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-left: auto; }', '.h2-station-page .h2-create-footer-actions .ant-btn { min-height: 44px; padding: 0 20px; border-radius: 10px; font-weight: 600; }', '.h2-station-page .h2-create-footer-actions .ant-btn-primary { min-width: 120px; box-shadow: 0 4px 14px -2px rgba(16, 185, 129, 0.45); }', '.h2-station-page .h2-create-footer-actions .ant-btn-primary:not(:disabled):hover { box-shadow: 0 6px 18px -2px rgba(16, 185, 129, 0.5); transform: translateY(-1px); }', '.h2-station-page .h2-field-readonly .ant-input, .h2-station-page .h2-field-readonly .ant-select-selector, .h2-station-page .h2-field-readonly .ant-input-textarea { background: #f1f5f9 !important; color: #64748b !important; cursor: default !important; border-style: dashed !important; }', '@media (prefers-reduced-motion: no-preference) { .h2-station-page--create .h2-create-card { animation: h2CreateCardIn 0.35s ease-out backwards; } .h2-station-page--create .h2-create-card:nth-of-type(2) { animation-delay: 0.08s; } }', '@keyframes h2CreateCardIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }', '@media (prefers-reduced-motion: reduce) { .h2-station-page--create .h2-create-card { animation: none; } .h2-station-page--create .h2-signed-panel { transition: none; } }' ].join('\n'); var H2_CURRENT_OPERATOR = '系统管理员'; function h2OperateTimestamp() { return new Date().toISOString().slice(0, 16).replace('T', ' '); } function h2CreateBusinessStatusLog(beforeStatus, afterStatus, operator) { return { id: 'bsl-' + Date.now() + '-' + Math.floor(Math.random() * 1000), operateTime: h2OperateTimestamp(), operator: operator || H2_CURRENT_OPERATOR, beforeStatus: beforeStatus || '—', afterStatus: afterStatus || '—' }; } var H2_IMPORT_TEMPLATE_HEADERS = [ '加氢站名称', '省', '市', '详细地址', '是否签约', '签约开始时间', '签约结束时间', '营业状态', '营业时间', '联系人', '联系电话' ]; var H2_IMPORT_TEMPLATE_SAMPLE = [ ['苏州新区加氢站(导入示例)', '江苏省', '苏州市', '工业园区星湖街100号', '是', '2025-01-01', '2027-12-31', '营业中', '08:00-20:00', '周八', '13900001111'] ]; var H2_IMPORT_HEADER_MAP = { '加氢站名称': 'name', '站点名称': 'name', '名称': 'name', '省': 'province', '省份': 'province', '市': 'city', '城市': 'city', '详细地址': 'detail', '地址详情': 'detail', '是否签约': 'isSigned', '签约状态': 'isSigned', '签约开始时间': 'contractStart', '签约开始': 'contractStart', '签约结束时间': 'contractEnd', '签约结束': 'contractEnd', '营业状态': 'businessStatus', '营业时间': 'businessHours', '联系人': 'contact', '联系电话': 'phone', '电话': 'phone' }; function h2CsvEscape(v) { var s = String(v == null ? '' : v); if (/[",\n\r]/.test(s)) return '"' + s.replace(/"/g, '""') + '"'; return s; } function h2DownloadCsv(filename, headers, rows) { var lines = [headers.map(h2CsvEscape).join(',')].concat( (rows || []).map(function (r) { return r.map(h2CsvEscape).join(','); }) ); var blob = new Blob(['\uFEFF' + lines.join('\n')], { type: 'text/csv;charset=utf-8;' }); var a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = filename; a.click(); URL.revokeObjectURL(a.href); } function h2ParseCsvLine(line) { var out = []; var cur = ''; var inQuote = false; var i; for (i = 0; i < line.length; i++) { var ch = line.charAt(i); if (inQuote) { if (ch === '"') { if (line.charAt(i + 1) === '"') { cur += '"'; i++; } else inQuote = false; } else cur += ch; } else if (ch === '"') inQuote = true; else if (ch === ',') { out.push(cur.trim()); cur = ''; } else cur += ch; } out.push(cur.trim()); return out; } function h2ParseSignedLabel(val) { var s = String(val || '').trim(); if (!s) return false; var lower = s.toLowerCase(); if (s === '是' || s === '已签约' || lower === 'yes' || lower === 'y' || lower === 'true' || lower === '1') return true; if (s === '否' || s === '未签约' || lower === 'no' || lower === 'n' || lower === 'false' || lower === '0') return false; return false; } function h2NormalizeBusinessStatus(val) { var s = String(val || '').trim(); var i; for (i = 0; i < H2_BUSINESS_STATUS_OPTIONS.length; i++) { if (H2_BUSINESS_STATUS_OPTIONS[i].value === s) return s; } if (s.indexOf('暂停') >= 0) return '暂停营业'; if (s.indexOf('停止') >= 0 || s.indexOf('停业') >= 0) return '停止营业'; if (s.indexOf('营业') >= 0) return '营业中'; return ''; } function h2ParseImportCsv(text) { var raw = String(text || '').replace(/^\uFEFF/, ''); var lines = raw.split(/\r?\n/).filter(function (ln) { return ln.trim().length > 0; }); if (lines.length < 2) return { rows: [], headerError: '文件至少需要表头行与一行数据' }; var headers = h2ParseCsvLine(lines[0]).map(function (h) { return String(h || '').trim().replace(/^\uFEFF/, ''); }); var fieldIdx = {}; var hi; for (hi = 0; hi < headers.length; hi++) { var key = H2_IMPORT_HEADER_MAP[headers[hi]]; if (key && fieldIdx[key] == null) fieldIdx[key] = hi; } if (fieldIdx.name == null) return { rows: [], headerError: '缺少必填列「加氢站名称」' }; var rows = []; var li; for (li = 1; li < lines.length; li++) { var cells = h2ParseCsvLine(lines[li]); if (!cells.some(function (c) { return String(c || '').trim(); })) continue; var get = function (field) { var idx = fieldIdx[field]; return idx == null || idx < 0 ? '' : String(cells[idx] == null ? '' : cells[idx]).trim(); }; rows.push({ lineNo: li + 1, name: get('name'), province: get('province'), city: get('city'), detail: get('detail'), isSigned: h2ParseSignedLabel(get('isSigned')), contractStart: get('contractStart'), contractEnd: get('contractEnd'), businessStatus: h2NormalizeBusinessStatus(get('businessStatus')), businessHours: get('businessHours'), contact: get('contact'), phone: get('phone') }); } return { rows: rows, headerError: null }; } function h2ValidateImportRow(row, existingNames) { var errors = []; if (!(row.name || '').trim()) errors.push('加氢站名称不能为空'); else if (existingNames[(row.name || '').trim()]) errors.push('站点名称「' + row.name + '」已存在'); if (!(row.province || '').trim()) errors.push('省不能为空'); if (!(row.city || '').trim()) errors.push('市不能为空'); if (!(row.detail || '').trim()) errors.push('详细地址不能为空'); if (!(row.contact || '').trim()) errors.push('联系人不能为空'); if (!(row.phone || '').trim()) errors.push('联系电话不能为空'); if (!(row.businessStatus || '').trim()) errors.push('营业状态无效,请填写:营业中 / 暂停营业 / 停止营业'); if (row.isSigned) { if (!row.contractStart) errors.push('已签约站点需填写签约开始时间'); if (!row.contractEnd) errors.push('已签约站点需填写签约结束时间'); } return errors; } function h2ImportRowToRecord(row, id) { var region = [row.province, row.city]; var form = { name: row.name, address: { region: region, detail: row.detail }, isSigned: row.isSigned, contractStart: row.isSigned ? (row.contractStart || '') : '', contractEnd: row.isSigned ? (row.contractEnd || '') : '', contractFiles: [], businessStatus: row.businessStatus || '营业中', businessHours: row.businessHours || '', contact: row.contact, phone: row.phone }; var record = h2FormToRecord(form, id); record.businessStatusLogs = []; return record; } function h2SvgIcon(paths, size) { var s = size || 18; return React.createElement('svg', { width: s, height: s, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: 2, strokeLinecap: 'round', strokeLinejoin: 'round', 'aria-hidden': true }, paths.map(function (p, i) { if (p.tag === 'circle') return React.createElement('circle', { key: i, cx: p.cx, cy: p.cy, r: p.r }); if (p.tag === 'line') return React.createElement('line', { key: i, x1: p.x1, y1: p.y1, x2: p.x2, y2: p.y2 }); if (p.tag === 'rect') return React.createElement('rect', { key: i, x: p.x, y: p.y, width: p.width, height: p.height, rx: p.rx }); return React.createElement('path', { key: i, d: p.d }); })); } var H2_ICONS = { station: h2SvgIcon([{ d: 'M3 21h18M5 21V7l8-4v18M19 21V11l-6-4' }]), high: h2SvgIcon([{ d: 'M13 2L3 14h9l-1 8 10-12h-9l1-8z' }], 16), low: h2SvgIcon([{ d: 'M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z' }], 16), none: h2SvgIcon([{ d: 'M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z' }, { tag: 'line', x1: 12, y1: 9, x2: 12, y2: 13 }, { tag: 'line', x1: 12, y1: 17, x2: 12.01, y2: 17 }], 16), doc: h2SvgIcon([{ d: 'M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z' }, { d: 'M14 2v6h6' }, { tag: 'line', x1: 16, y1: 13, x2: 8, y2: 13 }, { tag: 'line', x1: 16, y1: 17, x2: 8, y2: 17 }], 14), upload: h2SvgIcon([{ d: 'M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4' }, { d: 'M17 8l-5-5-5 5' }, { tag: 'line', x1: 12, y1: 3, x2: 12, y2: 15 }], 14), empty: h2SvgIcon([{ tag: 'circle', cx: 12, cy: 12, r: 10 }, { tag: 'line', x1: 8, y1: 12, x2: 16, y2: 12 }], 40), back: h2SvgIcon([{ tag: 'line', x1: 19, y1: 12, x2: 5, y2: 12 }, { d: 'M12 19l-7-7 7-7' }], 16), mapPin: h2SvgIcon([{ tag: 'path', d: 'M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z' }, { tag: 'circle', cx: 12, cy: 10, r: 3 }], 16), user: h2SvgIcon([{ tag: 'path', d: 'M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2' }, { tag: 'circle', cx: 12, cy: 7, r: 4 }], 16), building: h2SvgIcon([{ d: 'M3 21h18M5 21V7l8-4v18M19 21V11l-6-4' }], 18), truck: h2SvgIcon([{ d: 'M1 3h15v13H1zM16 8h4l3 3v5h-7V8z' }, { tag: 'circle', cx: 5.5, cy: 18.5, r: 2.5 }, { tag: 'circle', cx: 18.5, cy: 18.5, r: 2.5 }], 16), link: h2SvgIcon([{ tag: 'path', d: 'M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71' }, { tag: 'path', d: 'M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71' }], 16), plus: h2SvgIcon([{ tag: 'line', x1: 12, y1: 5, x2: 12, y2: 19 }, { tag: 'line', x1: 5, y1: 12, x2: 19, y2: 12 }], 16), file: h2SvgIcon([{ d: 'M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z' }, { d: 'M14 2v6h6' }], 16) }; function h2MoreIcon() { return React.createElement('svg', { viewBox: '0 0 16 16', width: 16, height: 16, fill: 'currentColor', 'aria-hidden': true }, React.createElement('circle', { cx: 8, cy: 3, r: 1.5 }), React.createElement('circle', { cx: 8, cy: 8, r: 1.5 }), React.createElement('circle', { cx: 8, cy: 13, r: 1.5 }) ); } function h2DeriveFrequencyByRefuelCount(refuelCount) { var n = typeof refuelCount === 'number' ? refuelCount : parseInt(refuelCount, 10); if (!n || n <= 0) return 'none'; if (n >= 3) return 'high'; return 'low'; } function h2FormatRegion(region) { if (!region || !region.length) return '—'; return region.join('-'); } function h2MatchRegionFilter(recordRegion, filterRegion) { if (!filterRegion || !filterRegion.length) return true; var rr = recordRegion || []; if (filterRegion[0] && rr[0] !== filterRegion[0]) return false; if (filterRegion[1] && rr[1] !== filterRegion[1]) return false; return true; } function h2EmptyListFilters() { return { name: '', signed: undefined, region: undefined, businessStatus: undefined }; } /** 距签约结束日天数:正=剩余,负=已过期 */ function h2DaysUntilContractEnd(dateStr) { if (!dateStr) return null; var parts = String(dateStr).trim().split('-'); if (parts.length < 3) return null; var y = parseInt(parts[0], 10); var m = parseInt(parts[1], 10) - 1; var d = parseInt(parts[2], 10); if (isNaN(y) || isNaN(m) || isNaN(d)) return null; var end = new Date(y, m, d, 23, 59, 59, 999); var today = new Date(); today.setHours(0, 0, 0, 0); return Math.ceil((end.getTime() - today.getTime()) / (1000 * 60 * 60 * 24)); } function h2RenderContractRemainTag(contractEnd) { var days = h2DaysUntilContractEnd(contractEnd); if (days == null) return null; var Tag = window.antd && window.antd.Tag; if (!Tag) return null; var tagProps = { style: { marginTop: 4, borderRadius: 6, fontWeight: 600, fontSize: 11 } }; if (days < 0) { return React.createElement(Tag, Object.assign({}, tagProps, { color: 'error', 'aria-label': '已过期 ' + Math.abs(days) + ' 天' }), '已过期 ' + Math.abs(days) + ' 天'); } if (days <= 30) { return React.createElement(Tag, Object.assign({}, tagProps, { color: 'warning', 'aria-label': '剩余 ' + days + ' 天' }), '剩余 ' + days + ' 天'); } return React.createElement(Tag, Object.assign({}, tagProps, { color: 'success', 'aria-label': '剩余 ' + days + ' 天' }), '剩余 ' + days + ' 天'); } function h2BuildFullAddress(region, detail) { var base = h2FormatRegion(region); if (!detail) return base === '—' ? '' : base; return base === '—' ? detail : base + detail; } function h2EmptyAddressValue() { return { region: [], detail: '' }; } function h2KpiIcon(key) { if (key === 'high') return H2_ICONS.high; if (key === 'low') return H2_ICONS.low; if (key === 'none') return H2_ICONS.none; return H2_ICONS.station; } function h2SignedFilterIcon(key) { if (key === 'yes') { return h2SvgIcon([{ d: 'M22 11.08V12a10 10 0 1 1-5.93-9.14' }, { d: 'M22 4 12 14.01l-3-3' }], 16); } return h2SvgIcon([{ tag: 'circle', cx: 12, cy: 12, r: 10 }, { tag: 'line', x1: 15, y1: 9, x2: 9, y2: 15 }, { tag: 'line', x1: 9, y1: 9, x2: 15, y2: 15 }], 16); } /** 地址组件:省/市级联 + 详细地址(无子标题,挂在「地址」表单项下) */ function RegionAddressInput(props) { var antd = window.antd; var Cascader = antd.Cascader; var Input = antd.Input; var value = props.value || h2EmptyAddressValue(); var onChange = props.onChange; var disabled = props.disabled; var inputClassName = props.inputClassName || ''; var layout = props.layout || 'stack'; var detailPlaceholder = props.detailPlaceholder || '请输入街道、门牌号等详细地址'; var regionPlaceholder = props.regionPlaceholder || '请选择省 / 市'; var fieldStyle = props.fieldStyle || { width: '100%', borderRadius: 8 }; var rootCls = 'h2-region-address' + (layout === 'inline' ? ' h2-region-address--inline' : ''); return React.createElement('div', { className: rootCls }, React.createElement(Cascader, { className: inputClassName + (layout === 'inline' ? ' h2-region-address-cascader' : ''), options: H2_REGION_CASCADER_OPTIONS, value: value.region && value.region.length ? value.region : undefined, onChange: function (v) { onChange && onChange({ region: v || [], detail: value.detail || '' }); }, placeholder: regionPlaceholder, style: layout === 'inline' ? { width: '100%', borderRadius: fieldStyle.borderRadius || 8 } : fieldStyle, disabled: disabled, allowClear: !disabled }), React.createElement(Input, { className: inputClassName + (layout === 'inline' ? ' h2-region-address-detail' : ''), value: value.detail || '', onChange: function (e) { onChange && onChange({ region: value.region || [], detail: e.target.value }); }, placeholder: detailPlaceholder, disabled: disabled, maxLength: 200, style: layout === 'inline' ? { width: '100%', borderRadius: fieldStyle.borderRadius || 8 } : fieldStyle }) ); } /** 供应商通讯地址:省/市 + 详细地址(横向嵌入) */ function SupplierCityAddressInput(props) { var antd = window.antd; var Cascader = antd.Cascader; var Input = antd.Input; var city = props.city; var address = props.address || ''; var onChange = props.onChange; var disabled = props.disabled; var inputClassName = props.inputClassName || ''; var onCityChange = props.onCityChange; return React.createElement('div', { className: 'h2-region-address h2-region-address--inline' }, React.createElement(Cascader, { className: inputClassName + ' h2-region-address-cascader', options: H2_REGION_CASCADER_OPTIONS, value: city && city.length ? city : undefined, onChange: onCityChange, placeholder: '请选择省 / 市', style: { width: '100%' }, disabled: disabled, allowClear: !disabled }), React.createElement(Input, { className: inputClassName + ' h2-region-address-detail', value: address, disabled: disabled, placeholder: '请输入详细地址', maxLength: 200, style: { width: '100%' }, onChange: function (e) { onChange && onChange(e.target.value); } }) ); } function h2GetUploadFileUrl(file) { if (!file) return ''; if (file.url) return file.url; if (file.thumbUrl) return file.thumbUrl; if (file.originFileObj && typeof URL !== 'undefined' && URL.createObjectURL) { try { return URL.createObjectURL(file.originFileObj); } catch (e) { return ''; } } return ''; } function h2DownloadUploadFile(file) { var url = h2GetUploadFileUrl(file); if (!url) return; var a = document.createElement('a'); a.href = url; a.download = file.name || '附件'; a.target = '_blank'; document.body.appendChild(a); a.click(); document.body.removeChild(a); } /** 合同附件:按钮上传 + 预览/下载 */ function ContractFilesUpload(props) { var antd = window.antd; var Upload = antd.Upload; var Button = antd.Button; var fileList = props.fileList || []; var disabled = props.disabled; return React.createElement('div', { className: 'h2-contract-upload' }, React.createElement('div', { className: 'h2-contract-upload-actions' }, React.createElement(Upload, { className: 'h2-create-upload-btn', multiple: true, disabled: disabled, fileList: fileList, beforeUpload: function () { return false; }, onChange: props.onChange, showUploadList: false }, React.createElement(Button, { type: 'default', icon: H2_ICONS.upload, disabled: disabled }, '上传附件') ), React.createElement('span', { style: { fontSize: 12, color: '#94a3b8' } }, '支持 PDF、图片,可多选,非必填') ), fileList.length ? React.createElement('div', { className: 'h2-contract-file-list' }, fileList.map(function (file) { return React.createElement('div', { key: file.uid, className: 'h2-contract-file-item' }, React.createElement('span', { className: 'h2-contract-file-name', title: file.name }, file.name || '未命名附件'), React.createElement('div', { className: 'h2-contract-file-btns' }, React.createElement(Button, { type: 'link', size: 'small', disabled: disabled, onClick: function () { var url = h2GetUploadFileUrl(file); if (url) window.open(url, '_blank'); } }, '预览'), React.createElement(Button, { type: 'link', size: 'small', disabled: disabled, onClick: function () { h2DownloadUploadFile(file); } }, '下载') ) ); }) ) : null ); } function h2StationContactPhone(station) { return (station.mobilePhone || '').trim() || (station.landlinePhone || '').trim(); } function h2ApplyStationContactPhone(station, text) { var v = String(text || '').trim(); if (/^1\d{10}$/.test(v.replace(/\s/g, ''))) { return Object.assign({}, station, { mobilePhone: v.replace(/\s/g, ''), landlinePhone: '' }); } return Object.assign({}, station, { mobilePhone: '', landlinePhone: v }); } var H2_BUSINESS_HOURS_MODE_OPTIONS = [ { label: '全天营业', value: 'allDay' }, { label: '非全天营业', value: 'custom' } ]; function h2IsAllDayBusinessHours(str) { var s = String(str || '').trim(); if (!s || s === '—') return false; if (s === '全天营业' || s === '24小时' || s === '24 小时') return true; return /^00:00\s*[-–]\s*24:00$/.test(s); } function h2ParseBusinessHours(str) { var s = String(str || '').trim(); if (!s || s === '—') { return { mode: 'allDay', start: '08:00', end: '22:00' }; } if (h2IsAllDayBusinessHours(s)) { return { mode: 'allDay', start: '08:00', end: '22:00' }; } var parts = s.split('-'); if (parts.length >= 2) { return { mode: 'custom', start: (parts[0] || '').trim(), end: (parts.slice(1).join('-') || '').trim() }; } return { mode: 'custom', start: '', end: '' }; } function h2FormatBusinessHours(val) { if (!val || val.mode === 'allDay') return '00:00-24:00'; var start = (val.start || '').trim(); var end = (val.end || '').trim(); if (!start || !end) return ''; return start + '-' + end; } function h2DisplayBusinessHours(str) { var s = String(str || '').trim(); if (!s || s === '—') return '—'; if (h2IsAllDayBusinessHours(s) || s === '全天营业') return '全天营业'; var parsed = h2ParseBusinessHours(s); if (parsed.mode === 'custom' && parsed.start && parsed.end) return parsed.start + '-' + parsed.end; return s; } function h2NormalizeTimeText(text) { var s = String(text || '').trim(); if (!s) return ''; var m = /^(\d{1,2}):(\d{2})$/.exec(s); if (!m) return s; var h = parseInt(m[1], 10); var min = parseInt(m[2], 10); if (isNaN(h) || isNaN(min) || h < 0 || h > 23 || min < 0 || min > 59) return s; return (h < 10 ? '0' : '') + h + ':' + (min < 10 ? '0' : '') + min; } function h2TimeTextToDayjs(text) { var dayjs = window.dayjs; if (!dayjs) return null; var norm = h2NormalizeTimeText(text); if (!norm) return null; var parts = norm.split(':'); return dayjs().hour(parseInt(parts[0], 10)).minute(parseInt(parts[1], 10)).second(0).millisecond(0); } function h2DayjsToTimeText(d) { var dayjs = window.dayjs; if (!d || !dayjs) return ''; return dayjs(d).format('HH:mm'); } /** 营业时间:全天 / 非全天 + 起止时间(时:分,可输入) */ function BusinessHoursInput(props) { var antd = window.antd; var Select = antd.Select; var TimePicker = antd.TimePicker; var Input = antd.Input; var parsed = h2ParseBusinessHours(props.value); var onChange = props.onChange; var disabled = props.disabled; var inputClassName = props.inputClassName || ''; var fieldStyle = props.fieldStyle || { width: '100%' }; var layout = props.layout || 'full'; var dayjs = window.dayjs; var rootClass = 'h2-business-hours' + (layout === 'col4' ? ' h2-business-hours--col4' : ''); var emit = function (next) { onChange && onChange(h2FormatBusinessHours(next)); }; var renderTimeField = function (label, timeKey, placeholder) { var timeVal = parsed[timeKey] || ''; var onTimeChange = function (nextText) { var patch = { mode: 'custom', start: parsed.start || '', end: parsed.end || '' }; patch[timeKey] = h2NormalizeTimeText(nextText); emit(patch); }; return React.createElement('div', { className: 'h2-business-hours-range-item', key: timeKey }, React.createElement('span', { className: 'h2-business-hours-range-label' }, label), dayjs ? React.createElement(TimePicker, { className: inputClassName, format: 'HH:mm', minuteStep: 1, hourStep: 1, showNow: false, allowClear: !disabled, inputReadOnly: false, disabled: disabled, style: fieldStyle, placeholder: placeholder, value: h2TimeTextToDayjs(timeVal), onChange: function (d) { onTimeChange(d ? h2DayjsToTimeText(d) : ''); } }) : React.createElement(Input, { className: inputClassName, disabled: disabled, style: fieldStyle, placeholder: placeholder || 'HH:mm', value: timeVal, maxLength: 5, onChange: function (e) { onTimeChange(e.target.value); }, onBlur: function (e) { onTimeChange(e.target.value); } }) ); }; return React.createElement('div', { className: rootClass }, React.createElement(Select, { className: inputClassName, value: parsed.mode, options: H2_BUSINESS_HOURS_MODE_OPTIONS, style: fieldStyle, disabled: disabled, placeholder: '请选择营业时间', onChange: function (mode) { if (mode === 'allDay') emit({ mode: 'allDay', start: parsed.start, end: parsed.end }); else emit({ mode: 'custom', start: parsed.start || '08:00', end: parsed.end || '22:00' }); }, dropdownStyle: { borderRadius: 8 } }), parsed.mode === 'custom' ? React.createElement('div', { className: 'h2-business-hours-range' }, renderTimeField('开始时间', 'start', '请选择开始时间'), renderTimeField('结束时间', 'end', '请选择结束时间') ) : null ); } function h2CreateEmptyForm() { return { name: '', address: h2EmptyAddressValue(), isSigned: true, contractStart: '', contractEnd: '', contractFiles: [], businessStatus: '营业中', businessHours: '', contact: '', phone: '' }; } function h2RecordToForm(record) { if (!record) return h2CreateEmptyForm(); return { name: record.name || '', address: { region: (record.region || []).slice(), detail: record.addressDetail || '' }, isSigned: record.isSigned !== false, contractStart: record.contractStart || '', contractEnd: record.contractEnd || '', contractFiles: (record.contractFiles || []).map(function (f, i) { return Object.assign({}, f, { uid: f.uid || ('f-' + i), status: 'done' }); }), businessStatus: record.businessStatus || '营业中', businessHours: record.businessHours || '', contact: record.contact || '', phone: record.phone || '' }; } function h2FormToRecord(form, id) { var files = (form.contractFiles || []).map(function (f) { return { uid: f.uid, name: f.name || '合同附件.pdf', url: f.url || '' }; }); return { id: id, name: (form.name || '').trim(), region: form.address.region || [], addressDetail: (form.address.detail || '').trim(), fullAddress: h2BuildFullAddress(form.address.region, form.address.detail), isSigned: !!form.isSigned, contractStart: form.contractStart || '', contractEnd: form.contractEnd || '', contractFiles: files, businessStatus: form.businessStatus || '营业中', businessHours: (form.businessHours || '').trim(), contact: (form.contact || '').trim(), phone: (form.phone || '').trim(), updateTime: new Date().toISOString().slice(0, 16).replace('T', ' ') }; } var H2_MOCK_STATIONS = [ { id: 1, name: '嘉兴加氢站(一期)', region: ['浙江省', '嘉兴市'], addressDetail: '南湖区科技大道88号', fullAddress: '浙江省-嘉兴市南湖区科技大道88号', isSigned: true, contractStart: '2024-01-01', contractEnd: '2026-12-31', contractFiles: [{ uid: 'c1', name: '嘉兴加氢站签约合同.pdf' }], businessStatus: '营业中', businessHours: '08:00-22:00', costUnitPrice: 42.5, customerUnitPrice: 45, prepaidBalance: 85620.0, contact: '张三', phone: '13800138001', businessStatusLogs: [], updateTime: '2026-05-20 14:30' }, { id: 2, name: '杭州临平加氢站', region: ['浙江省', '杭州市'], addressDetail: '临平区东湖街道能源路16号', fullAddress: '浙江省-杭州市临平区东湖街道能源路16号', isSigned: true, contractStart: '2025-03-01', contractEnd: '2027-02-28', contractFiles: [{ uid: 'c2', name: '临平加氢站合作协议.pdf' }, { uid: 'c3', name: '临平加氢站补充协议.pdf' }], businessStatus: '营业中', businessHours: '00:00-24:00', prepaidBalance: 125000.5, contact: '李四', phone: '13900139002', updateTime: '2026-06-01 09:15' }, { id: 3, name: '上海宝山加氢站', region: ['上海市', '上海市'], addressDetail: '宝山区富联路128号', fullAddress: '上海市-上海市宝山区富联路128号', isSigned: true, contractStart: '2023-06-01', contractEnd: '2025-05-31', contractFiles: [{ uid: 'c4', name: '宝山加氢站合同(即将到期).pdf' }], businessStatus: '暂停营业', businessHours: '09:00-18:00', prepaidBalance: -3250.0, businessStatusLogs: [ { id: 'bsl-3-2', operateTime: '2026-04-01 10:00', operator: '王五', beforeStatus: '营业中', afterStatus: '暂停营业' }, { id: 'bsl-3-1', operateTime: '2026-03-15 09:30', operator: '系统管理员', beforeStatus: '暂停营业', afterStatus: '营业中' } ], contact: '王五', phone: '13700137003', updateTime: '2026-04-12 16:40' }, { id: 4, name: '平湖合作停车场(待建加氢)', region: ['浙江省', '嘉兴市'], addressDetail: '平湖市乍嘉公路与平善大道交叉口', fullAddress: '浙江省-嘉兴市平湖市乍嘉公路与平善大道交叉口', isSigned: false, contractStart: '', contractEnd: '', contractFiles: [], businessStatus: '停止营业', businessHours: '—', prepaidBalance: 0, contact: '赵六', phone: '13600136004', updateTime: '2026-03-08 11:20' }, { id: 5, name: '苏州工业园区备用站', region: ['江苏省', '苏州市'], addressDetail: '工业园区星湖街328号', fullAddress: '江苏省-苏州市工业园区星湖街328号', isSigned: false, contractStart: '', contractEnd: '', contractFiles: [], businessStatus: '停止营业', businessHours: '10:00-17:00', prepaidBalance: 15800.0, contact: '钱七', phone: '13500135005', updateTime: '2026-02-18 08:50' } ]; /** 站点加氢记录 Mock(字段对齐车辆氢费明细) */ var H2_MOCK_REFUEL_RECORDS = [ { id: 'rf-1', stationName: '嘉兴加氢站(一期)', hydrogenTime: '2026-05-28 10:21:08', plateNo: '浙A12345F', customerName: '嘉兴市鑫峤供应链科技有限公司', hydrogenKg: 12.5, costUnitPrice: 42.5, costAmount: 531.25, customerUnitPrice: 45, customerAmount: 562.5 }, { id: 'rf-2', stationName: '嘉兴加氢站(一期)', hydrogenTime: '2026-05-26 14:08:33', plateNo: '浙A67890F', customerName: '浙江绿运物流有限公司', hydrogenKg: 10.0, costUnitPrice: 42.5, costAmount: 425.0, customerUnitPrice: 45, customerAmount: 450.0 }, { id: 'rf-3', stationName: '嘉兴加氢站(一期)', hydrogenTime: '2026-05-22 09:15:00', plateNo: '浙A88888F', customerName: '嘉兴市鑫峤供应链科技有限公司', hydrogenKg: 18.3, costUnitPrice: 42.5, costAmount: 777.75, customerUnitPrice: 45, customerAmount: 823.5 }, { id: 'rf-4', stationName: '嘉兴加氢站(一期)', hydrogenTime: '2026-05-18 16:42:11', plateNo: '浙A03561F', customerName: '嘉兴港务氢能运输队', hydrogenKg: 15.6, costUnitPrice: 42.5, costAmount: 663.0, customerUnitPrice: 45, customerAmount: 702.0 }, { id: 'rf-5', stationName: '杭州临平加氢站', hydrogenTime: '2026-05-30 09:30:22', plateNo: '浙B23456F', customerName: '杭州临平城配中心', hydrogenKg: 15.3, costUnitPrice: 43.0, costAmount: 657.9, customerUnitPrice: 46, customerAmount: 703.8 }, { id: 'rf-6', stationName: '杭州临平加氢站', hydrogenTime: '2026-05-27 18:10:05', plateNo: '浙B99999F', customerName: '浙江氢运科技', hydrogenKg: 18.2, costUnitPrice: 43.0, costAmount: 782.6, customerUnitPrice: 46, customerAmount: 837.2 }, { id: 'rf-7', stationName: '杭州临平加氢站', hydrogenTime: '2026-05-24 11:05:40', plateNo: '浙B58888F', customerName: '杭州临平城配中心', hydrogenKg: 11.8, costUnitPrice: 43.0, costAmount: 507.4, customerUnitPrice: 46, customerAmount: 542.8 }, { id: 'rf-8', stationName: '上海宝山加氢站', hydrogenTime: '2026-04-20 16:45:18', plateNo: '沪A88888F', customerName: '上海羚牛氢运', hydrogenKg: 8.0, costUnitPrice: 44.0, costAmount: 352.0, customerUnitPrice: 47, customerAmount: 376.0 }, { id: 'rf-9', stationName: '上海宝山加氢站', hydrogenTime: '2026-04-08 09:12:55', plateNo: '沪BDB9161F', customerName: '宝山园区试运车队', hydrogenKg: 9.5, costUnitPrice: 44.0, costAmount: 418.0, customerUnitPrice: 47, customerAmount: 446.5 }, { id: 'rf-10', stationName: '苏州工业园区备用站', hydrogenTime: '2026-03-15 10:00:00', plateNo: '苏E33333F', customerName: '苏州试运客户', hydrogenKg: 6.2, costUnitPrice: 41.0, costAmount: 254.2, customerUnitPrice: 44, customerAmount: 272.8 } ]; function h2FormatKgNum(v) { var n = typeof v === 'number' ? v : parseFloat(v); return isNaN(n) ? '0.00' : n.toFixed(2); } function h2FormatYuanNum(v) { var n = typeof v === 'number' ? v : parseFloat(v); return isNaN(n) ? '0.00' : n.toFixed(2); } function h2NumOrZero(v) { var n = typeof v === 'number' ? v : parseFloat(v); return isNaN(n) ? 0 : n; } function h2FormatLedgerMoney(v) { if (v === null || v === undefined || v === '' || Number(v) === 0) return '—'; return h2FormatYuanNum(v); } /** 原型:加氢站预付余额变更明细(联调后对接加氢站打款/余额流水接口) */ function h2BuildMockPrepaidBalanceRows(record) { var seed = 0; var code = String(record && record.id != null ? record.id : ''); var nameKey = String((record && record.name) || ''); var i; for (i = 0; i < code.length; i++) seed += code.charCodeAt(i); for (i = 0; i < nameKey.length; i++) seed += nameKey.charCodeAt(i); var stationName = (record && record.name) || '—'; var finalBalance = h2NumOrZero(record && record.prepaidBalance); var lineCount = Math.max(5, 6 + (seed % 5)); var rows = []; var openingBalance = Math.round((finalBalance + 38000 + seed * 620) * 100) / 100; if (openingBalance < 0) openingBalance = Math.abs(openingBalance) + 50000; rows.push({ key: code + '-bal-0', stationName: stationName, incomeAmount: openingBalance, expenseAmount: null, balance: openingBalance, orderNo: 'QC' + code + '260101' }); var balance = openingBalance; for (i = 1; i < lineCount - 1; i++) { var isIncome = (seed + i) % 3 === 0; var incomeAmount = null; var expenseAmount = null; if (isIncome) { incomeAmount = Math.round((6000 + (seed + i) * 380) * 100) / 100; balance = Math.round((balance + incomeAmount) * 100) / 100; } else { expenseAmount = Math.round((2800 + (seed + i) * 210) * 100) / 100; balance = Math.round((balance - expenseAmount) * 100) / 100; } rows.push({ key: code + '-bal-' + i, stationName: stationName, incomeAmount: incomeAmount, expenseAmount: expenseAmount, balance: balance, orderNo: (isIncome ? 'DK' : 'JQ') + code + String(200 + i).padStart(5, '0') }); } var diff = Math.round((finalBalance - balance) * 100) / 100; if (Math.abs(diff) < 0.01) { rows.push({ key: code + '-bal-last', stationName: stationName, incomeAmount: null, expenseAmount: null, balance: finalBalance, orderNo: 'BZ' + code + String(900).padStart(5, '0') }); } else if (diff > 0) { rows.push({ key: code + '-bal-last', stationName: stationName, incomeAmount: diff, expenseAmount: null, balance: finalBalance, orderNo: 'DK' + code + String(999).padStart(5, '0') }); } else { rows.push({ key: code + '-bal-last', stationName: stationName, incomeAmount: null, expenseAmount: Math.round(Math.abs(diff) * 100) / 100, balance: finalBalance, orderNo: 'JQ' + code + String(999).padStart(5, '0') }); } return rows; } function h2GetRefuelRecordsByStation(stationName) { var name = String(stationName || '').trim(); return H2_MOCK_REFUEL_RECORDS.filter(function (r) { return r.stationName === name; }).slice().sort(function (a, b) { return String(b.hydrogenTime || '').localeCompare(String(a.hydrogenTime || '')); }); } function h2CalcRefuelStats(stationName) { var records = h2GetRefuelRecordsByStation(stationName); var totalKg = 0; var i; for (i = 0; i < records.length; i++) totalKg += records[i].hydrogenKg || 0; return { count: records.length, totalKg: totalKg }; } var H2_MOCK_EXISTING_SUPPLIERS = [ { id: 'sup-h2-1', name: '嘉兴氢能供应有限公司', type: '加氢站', city: ['浙江省', '嘉兴市'], address: '南湖区科技大道66号', region: '华东', dept: '能源部', manager: '张经理', remark: '嘉兴区域主力加氢站运营商', contactName: '李供', contactMobile: '13800138088', contactTitle: '站长', taxId: '91330400MA2ABCDEF1', invoiceAddress: '浙江省嘉兴市南湖区科技大道66号', invoicePhone: '0573-88886666', bankName: '中国工商银行嘉兴南湖支行', bankAccount: '6222021203001234567', mailingAddress: '浙江省嘉兴市南湖区科技大道66号', businessAddress: '浙江省嘉兴市南湖区科技大道66号', businessLicenseFiles: [{ uid: 'bl-1', name: '营业执照_嘉兴氢能.pdf', status: 'done' }], fillingLicenseFiles: [{ uid: 'fl-1', name: '充装许可证_嘉兴氢能.pdf', status: 'done' }] }, { id: 'sup-h2-2', name: '上海羚牛氢能科技', type: '加氢站', city: ['上海市', '上海市'], address: '宝山区富联路200号', region: '华东', dept: '能源部', manager: '王专员', remark: '', contactName: '陈氢', contactMobile: '13900139001', contactTitle: '运营主管', taxId: '91310100MA1XYZ7890', invoiceAddress: '上海市宝山区富联路200号', invoicePhone: '021-66886688', bankName: '招商银行上海宝山支行', bankAccount: '6214830210123456789', mailingAddress: '上海市宝山区富联路200号', businessAddress: '上海市宝山区富联路200号', businessLicenseFiles: [{ uid: 'bl-2', name: '营业执照_羚牛氢能.pdf', status: 'done' }], fillingLicenseFiles: [{ uid: 'fl-2', name: '充装许可证_羚牛氢能.pdf', status: 'done' }] }, { id: 'sup-h2-3', name: '苏州工业园区氢源科技', type: '加氢站', city: ['江苏省', '苏州市'], address: '工业园区星湖街328号', region: '华东', dept: '华东大区', manager: '赵经理', remark: '备用站点供应商', contactName: '钱七', contactMobile: '13500135005', contactTitle: '联系人', taxId: '91320500MA2SUPPLIER', invoiceAddress: '江苏省苏州市工业园区星湖街328号', invoicePhone: '0512-66668888', bankName: '中国银行苏州工业园区支行', bankAccount: '6216600100009876543', mailingAddress: '江苏省苏州市工业园区星湖街328号', businessAddress: '江苏省苏州市工业园区星湖街328号', businessLicenseFiles: [], fillingLicenseFiles: [] }, { id: 'sup-other-1', name: '杭州绿能备件有限公司', type: '备件供应商', city: ['浙江省', '杭州市'], address: '余杭区文一西路998号', region: '华东', dept: '采购部', manager: '孙采购', remark: '', contactName: '周备件', contactMobile: '13600136001', contactTitle: '销售', taxId: '91330100MA3OTHER01', invoiceAddress: '浙江省杭州市余杭区文一西路998号', invoicePhone: '0571-88880001', bankName: '中国建设银行杭州余杭支行', bankAccount: '6227000012345678901', mailingAddress: '浙江省杭州市余杭区文一西路998号', businessAddress: '浙江省杭州市余杭区文一西路998号', businessLicenseFiles: [], fillingLicenseFiles: [] } ]; function h2CreateEmptyStationForm() { return { name: '', address: h2EmptyAddressValue(), isSigned: true, contractStart: '', contractEnd: '', contractFiles: [], businessStatus: '营业中', businessHours: '00:00-24:00', contact: '', mobilePhone: '', landlinePhone: '', costUnitPrice: '', customerUnitPrice: '', prepaidBalance: 0 }; } function h2CreateEmptySupplierForm() { return { name: '', city: undefined, address: '', region: '', dept: '', manager: '', remark: '', contactName: '', contactMobile: '', contactTitle: '', taxId: '', invoiceAddress: '', invoicePhone: '', bankName: '', bankAccount: '', mailingAddress: '', businessAddress: '', businessLicenseFiles: [], fillingLicenseFiles: [] }; } function h2GetRegionByProvince(province) { var a = String(province || '').trim(); if (!a) return ''; if (a === '北京市' || a === '天津市' || a === '河北省' || a === '山西省' || a === '内蒙古') return '华北'; if (a === '上海市' || a === '江苏省' || a === '浙江省' || a === '安徽省' || a === '福建省' || a === '江西省' || a === '山东省') return '华东'; if (a === '广东省' || a === '广西省' || a === '海南省') return '华南'; if (a === '河南省' || a === '湖北省' || a === '湖南省') return '华中'; if (a === '辽宁省' || a === '吉林省' || a === '黑龙江省') return '东北'; if (a === '四川省' || a === '云南省' || a === '贵州省' || a === '重庆市') return '西南'; if (a === '陕西省' || a === '甘肃省' || a === '青海省' || a === '宁夏' || a === '新疆') return '西北'; return ''; } function h2SupplierToForm(s) { if (!s) return h2CreateEmptySupplierForm(); return { name: s.name || '', city: s.city ? s.city.slice() : undefined, address: s.address || '', region: s.region || '', dept: s.dept || '', manager: s.manager || '', remark: s.remark || '', contactName: s.contactName || '', contactMobile: s.contactMobile || '', contactTitle: s.contactTitle || '', taxId: s.taxId || '', invoiceAddress: s.invoiceAddress || '', invoicePhone: s.invoicePhone || '', bankName: s.bankName || '', bankAccount: s.bankAccount || '', mailingAddress: s.mailingAddress || '', businessAddress: s.businessAddress || s.mailingAddress || '', businessLicenseFiles: (s.businessLicenseFiles || []).map(function (f, i) { return Object.assign({}, f, { uid: f.uid || ('bl-' + i), status: 'done' }); }), fillingLicenseFiles: (s.fillingLicenseFiles || []).map(function (f, i) { return Object.assign({}, f, { uid: f.uid || ('fl-' + i), status: 'done' }); }) }; } function getH2StationRequirementDoc() { return [ '加氢站管理 - 站点信息', '', '一、页面定位', ' 管理全部加氢站点基础信息,支持 KPI 分类筛选、条件检索、新建、编辑、查看与删除。', '', '二、站点分类 KPI', ' · 全部加氢站:展示全部记录', ' · 高频 / 低频 / 无加氢站点:按加氢次数自动划分(≥3 高频,1~2 低频,0 无加氢)', '', '三、列表字段', ' 加氢站名称(含签约标签)、地址、签约起止时间、营业状态、营业时间、加氢次数、加氢量(含高频/低频标签)、预付余额、联系方式、操作', ' · 加氢次数/加氢量可点击,弹窗展示该站点加氢记录(对齐车辆氢费明细字段)', ' · 预付余额:可点击查看余额变更明细;负值红色展示(已欠费);更多菜单支持生成对账单', '', '四、表单字段', ' · 新建:同页内嵌视图,含加氢站基本信息、供应商相关信息两张卡片;供应商类型固定「加氢站」', ' · 编辑/查看:抽屉;基本信息含名称、地址、营业时间、签约信息、联系方式;营业状态仅在列表「更多-营业状态」维护', '', '五、交互', ' · 筛选:加氢站名称、是否签约、地区(省-市)、营业状态', ' · KPI 统计:全部加氢站右侧为已签约/未签约站点快捷筛选,其后为高频/低频/无加氢分类', ' · 未签约时签约时间与附件可选填;已签约建议填写完整', ' · 查看模式只读;编辑/新建可保存', ' · 列表支持分页,默认每页 10 条,可切换 5/10/20/50;筛选或 KPI 切换后回到第 1 页', ' · 操作列:查看 + 更多(编辑、删除、营业状态、价格配置、生成对账单)', ' · 营业状态弹窗:修改营业状态/时间,并展示状态变更记录(操作时间、操作人、修改前/后状态)', '', '六、批量导入', ' · 下载 CSV 模板,填写后上传;支持 .csv(推荐)、.xlsx、.xls', ' · 模板字段:加氢站名称、省、市、详细地址、是否签约、签约起止时间、营业状态、营业时间、联系人、联系电话', ' · 站点名称不可与现有台账重复;解析后确认导入' ].join('\n'); } var H2_PRIMARY_BTN_STYLE = { borderRadius: 8, fontWeight: 600, background: 'linear-gradient(135deg, #10b981 0%, #059669 100%)', border: 'none' }; var H2_REQ_BTN_STYLE = { borderRadius: 8, border: '1px solid #cbd5e1', fontWeight: 600, display: 'inline-flex', alignItems: 'center', boxShadow: '0 1px 2px rgba(0,0,0,0.05)', color: '#475569' }; function h2CreateFormDirty(station, supplier, supplierMode, linkedSupplierId) { if ((station.name || '').trim()) return true; if ((station.contact || '').trim()) return true; if ((station.mobilePhone || '').trim() || (station.landlinePhone || '').trim()) return true; if (station.address && ((station.address.region && station.address.region.length) || (station.address.detail || '').trim())) return true; if ((supplier.name || '').trim()) return true; if (supplierMode === 'link' && linkedSupplierId) return true; if ((supplier.businessLicenseFiles || []).length || (supplier.fillingLicenseFiles || []).length) return true; if ((station.contractFiles || []).length) return true; return false; } function h2CreateFormProgress(station, supplier, supplierMode, linkedSupplierId) { var checks = [ !!(station.name || '').trim(), station.address && station.address.region && station.address.region.length >= 2 && !!(station.address.detail || '').trim(), !!(station.contact || '').trim(), !!((station.mobilePhone || '').trim() || (station.landlinePhone || '').trim()), supplierMode === 'link' ? !!linkedSupplierId : !!(supplier.name || '').trim(), supplierMode === 'new' ? (supplier.businessLicenseFiles || []).length > 0 && (supplier.fillingLicenseFiles || []).length > 0 : !!linkedSupplierId ]; var done = checks.filter(Boolean).length; return Math.round((done / checks.length) * 100); } function h2BuildStationCreateView(ctx) { var antd = window.antd; var Card = antd.Card; var Button = antd.Button; var Input = antd.Input; var Select = antd.Select; var Radio = antd.Radio; var DatePicker = antd.DatePicker; var Upload = antd.Upload; var Form = antd.Form; var Progress = antd.Progress; var Row = antd.Row; var Col = antd.Col; var dayjs = window.dayjs; var inputCls = 'h2-create-input'; var progressPct = h2CreateFormProgress(ctx.station, ctx.supplier, ctx.supplierMode, ctx.linkedSupplierId); var H2_COL_4 = 6; var H2_COL_HALF = 12; var H2_COL_FULL = 24; var formItem = function (label, required, node, extra) { return React.createElement(Form.Item, { label: required ? React.createElement('span', null, React.createElement('span', { style: { color: '#ef4444', marginRight: 4 } }, '*'), label) : label, extra: extra }, node); }; var formRow = function () { return React.createElement.apply(null, [Row, { gutter: 24 }].concat(Array.prototype.slice.call(arguments))); }; var col4 = function (node) { return React.createElement(Col, { span: H2_COL_4 }, node); }; var col12 = function (node) { return React.createElement(Col, { span: H2_COL_HALF }, node); }; var colFull = function (node) { return React.createElement(Col, { span: H2_COL_FULL }, node); }; var cardTitle = function (text, icon) { return React.createElement('span', { className: 'h2-card-title-bar' }, icon ? React.createElement('span', { className: 'h2-card-title-icon', 'aria-hidden': true }, icon) : null, text ); }; var uploadDragger = function (fileList, onChange, btnText, hint, disabled) { return React.createElement(Upload.Dragger, { className: 'h2-create-upload', multiple: true, disabled: disabled, fileList: fileList, beforeUpload: function () { return false; }, onChange: onChange, showUploadList: true }, React.createElement('p', { className: 'ant-upload-drag-icon', style: { marginBottom: 8 } }, H2_ICONS.upload), React.createElement('p', { style: { margin: 0, fontWeight: 600, color: '#334155' } }, btnText), React.createElement('p', { className: 'h2-create-upload-hint' }, hint) ); }; var supplierOptions = H2_MOCK_EXISTING_SUPPLIERS.map(function (s) { return { value: s.id, label: s.name + (s.type ? '(' + s.type + ')' : '') + (s.city && s.city.length ? ' · ' + s.city.join('-') : '') }; }); var contractDateRangeValue = null; if (dayjs && ctx.station.contractStart && ctx.station.contractEnd) { var ds = dayjs(ctx.station.contractStart); var de = dayjs(ctx.station.contractEnd); if (ds.isValid() && de.isValid()) contractDateRangeValue = [ds, de]; } var renderContractDates = function () { if (dayjs && DatePicker && DatePicker.RangePicker) { return React.createElement(DatePicker.RangePicker, { className: inputCls, style: { width: '100%' }, format: 'YYYY-MM-DD', placeholder: ['开始日期', '结束日期'], value: contractDateRangeValue, onChange: function (dates) { if (!dates || dates.length < 2) { ctx.updateStation({ contractStart: '', contractEnd: '' }); return; } ctx.updateStation({ contractStart: dayjs(dates[0]).format('YYYY-MM-DD'), contractEnd: dayjs(dates[1]).format('YYYY-MM-DD') }); } }); } return React.createElement('div', { className: 'h2-contract-dates' }, React.createElement(Input, { className: inputCls, type: 'date', value: ctx.station.contractStart || '', style: { flex: 1, minWidth: 0 }, onChange: function (e) { ctx.updateStation({ contractStart: e.target.value }); } }), React.createElement('span', { className: 'h2-contract-dates-sep' }, '至'), React.createElement(Input, { className: inputCls, type: 'date', value: ctx.station.contractEnd || '', style: { flex: 1, minWidth: 0 }, onChange: function (e) { ctx.updateStation({ contractEnd: e.target.value }); } }) ); }; return React.createElement(React.Fragment, null, React.createElement('div', { className: 'h2-create-shell' }, React.createElement('div', { className: 'h2-create-topbar' }, React.createElement(Button, { className: 'h2-create-back-btn', type: 'default', icon: H2_ICONS.back, onClick: ctx.onCancel, disabled: ctx.submitting }, '返回'), React.createElement('div', { className: 'h2-create-topbar-actions' }, React.createElement(Button, { type: 'default', icon: ctx.reqIcon, style: ctx.reqBtnStyle, onClick: ctx.onOpenRequirement, 'aria-label': '查看需求说明' }, '需求说明') ) ), React.createElement(Form, { layout: 'vertical', requiredMark: false, className: 'h2-create-form' }, React.createElement(Card, { className: 'h2-create-card', id: 'h2-create-station-card', title: cardTitle('加氢站基本信息', H2_ICONS.building), bordered: false }, formRow( col4(formItem('加氢站名称', true, React.createElement(Input, { className: inputCls, value: ctx.station.name, placeholder: '请输入加氢站名称', maxLength: 80, onChange: function (e) { ctx.updateStation({ name: e.target.value }); }, onBlur: ctx.syncSupplierFromStation }))), col4(formItem('是否签约站点', false, React.createElement(Radio.Group, { className: 'h2-create-radio-group', value: ctx.station.isSigned ? 'signed' : 'unsigned', onChange: function (e) { var signed = e.target.value === 'signed'; ctx.updateStation({ isSigned: signed, contractStart: signed ? ctx.station.contractStart : '', contractEnd: signed ? ctx.station.contractEnd : '' }); } }, React.createElement(Radio, { value: 'signed' }, '签约'), React.createElement(Radio, { value: 'unsigned' }, '非签约') ))), ctx.station.isSigned ? col12(formItem('签约时间', true, renderContractDates())) : null ), formRow( col12(formItem('地址', true, React.createElement(RegionAddressInput, { value: ctx.station.address, layout: 'inline', inputClassName: inputCls, regionPlaceholder: '省 / 市', detailPlaceholder: '请输入详细地址', onChange: function (v) { ctx.updateStation({ address: v }); } }))), col12(formItem('合同附件', false, React.createElement(ContractFilesUpload, { fileList: ctx.station.contractFiles, onChange: function (info) { ctx.updateStation({ contractFiles: info.fileList }); } }))) ), formRow( col4(formItem('联系人', true, React.createElement(Input, { className: inputCls, value: ctx.station.contact, placeholder: '请输入联系人', onChange: function (e) { ctx.updateStation({ contact: e.target.value }); }, onBlur: ctx.syncSupplierFromStation }))), col4(formItem('联系电话', true, React.createElement(Input, { className: inputCls, value: h2StationContactPhone(ctx.station), placeholder: '手机号或固定电话', type: 'tel', autoComplete: 'tel', onChange: function (e) { ctx.updateStation(h2ApplyStationContactPhone(ctx.station, e.target.value)); }, onBlur: ctx.syncSupplierFromStation }))) ) ), React.createElement(Card, { className: 'h2-create-card', id: 'h2-create-supplier-card', title: cardTitle('供应商相关信息', H2_ICONS.truck), bordered: false }, formRow( col12(formItem('关联方式', true, React.createElement(Radio.Group, { className: 'h2-create-radio-group', value: ctx.supplierMode, onChange: function (e) { ctx.handleSupplierModeChange({ target: { value: e.target.value } }); } }, React.createElement(Radio, { value: 'link' }, '关联已有供应商'), React.createElement(Radio, { value: 'new' }, '新增供应商') ))), ctx.supplierMode === 'link' ? col12(formItem('供应商', true, React.createElement(Select, { className: inputCls, showSearch: true, placeholder: '请搜索并选择供应商', value: ctx.linkedSupplierId, options: supplierOptions, optionFilterProp: 'label', style: { width: '100%' }, onChange: ctx.handleLinkSupplierChange, dropdownStyle: { borderRadius: 8 } }))) : null ), ctx.supplierMode === 'new' ? React.createElement(React.Fragment, null, formRow( col4(formItem('供应商名称', true, React.createElement(Input, { className: inputCls, value: ctx.supplier.name, placeholder: '请输入供应商名称', onChange: function (e) { ctx.updateSupplier({ name: e.target.value }); } }))), col12(formItem('通讯地址', false, React.createElement(SupplierCityAddressInput, { city: ctx.supplier.city, address: ctx.supplier.address, inputClassName: inputCls, onCityChange: ctx.handleSupplierCityChange, onChange: function (v) { ctx.updateSupplier({ address: v }); } }))), col4(formItem('区域', false, React.createElement(Input, { className: inputCls, value: ctx.supplier.region, disabled: true, placeholder: '根据省市自动关联' }))) ), formRow( col4(formItem('纳税人识别号', false, React.createElement(Input, { className: inputCls, value: ctx.supplier.taxId, placeholder: '请输入纳税人识别号', onChange: function (e) { ctx.updateSupplier({ taxId: e.target.value }); } }))), col4(formItem('注册地址', false, React.createElement(Input, { className: inputCls, value: ctx.supplier.invoiceAddress, placeholder: '请输入注册地址', onChange: function (e) { ctx.updateSupplier({ invoiceAddress: e.target.value }); } }))), col4(formItem('注册电话', false, React.createElement(Input, { className: inputCls, value: ctx.supplier.invoicePhone, placeholder: '手机号或固定电话', type: 'tel', onChange: function (e) { ctx.updateSupplier({ invoicePhone: e.target.value }); } }))) ), formRow( col4(formItem('开户行', false, React.createElement(Input, { className: inputCls, value: ctx.supplier.bankName, placeholder: '请输入开户行', onChange: function (e) { ctx.updateSupplier({ bankName: e.target.value }); } }))), col4(formItem('银行账号', false, React.createElement(Input, { className: inputCls, value: ctx.supplier.bankAccount, placeholder: '请输入银行账号', onChange: function (e) { ctx.updateSupplier({ bankAccount: e.target.value }); } }))), col4(formItem('营业地址', false, React.createElement(Input, { className: inputCls, value: ctx.supplier.businessAddress, placeholder: '请输入营业地址', onChange: function (e) { ctx.updateSupplier({ businessAddress: e.target.value }); } }))) ), formRow( col4(formItem('营业执照', true, uploadDragger( ctx.supplier.businessLicenseFiles, function (info) { ctx.updateSupplier({ businessLicenseFiles: info.fileList }); }, '点击或拖拽上传', '支持 PDF、图片', false ))), col4(formItem('充装许可证', true, uploadDragger( ctx.supplier.fillingLicenseFiles, function (info) { ctx.updateSupplier({ fillingLicenseFiles: info.fileList }); }, '点击或拖拽上传', '支持 PDF、图片', false ))) ) ) : null ) ) ), React.createElement('footer', { className: 'h2-create-footer' }, React.createElement('div', { className: 'h2-create-footer-inner' }, React.createElement('div', { className: 'h2-create-footer-hint' }, React.createElement(Progress, { className: 'h2-create-footer-progress', type: 'line', percent: progressPct, strokeColor: { from: '#34d399', to: '#059669' }, trailColor: '#e2e8f0', size: 'small', 'aria-label': '表单完成度 ' + progressPct + '%' }), React.createElement('span', null, progressPct >= 100 ? '必填项已就绪,可提交' : '请完善必填项后提交(' + progressPct + '%)') ), React.createElement('div', { className: 'h2-create-footer-actions' }, React.createElement(Button, { onClick: ctx.onCancel, disabled: ctx.submitting, 'aria-label': '取消并返回列表' }, '取消'), React.createElement(Button, { onClick: ctx.onReset, disabled: ctx.submitting, 'aria-label': '重置表单' }, '重置'), React.createElement(Button, { type: 'primary', onClick: ctx.onSubmit, loading: ctx.submitting, style: H2_PRIMARY_BTN_STYLE, 'aria-label': '提交新建加氢站点' }, '提交创建') ) ) ) ); } const Component = function () { var useState = React.useState; var useMemo = React.useMemo; var useCallback = React.useCallback; var antd = window.antd; var Breadcrumb = antd.Breadcrumb; var Card = antd.Card; var Table = antd.Table; var Button = antd.Button; var Select = antd.Select; var Input = antd.Input; var Space = antd.Space; var Modal = antd.Modal; var Drawer = antd.Drawer; var Form = antd.Form; var Switch = antd.Switch; var Upload = antd.Upload; var Tag = antd.Tag; var Tooltip = antd.Tooltip; var Divider = antd.Divider; var Alert = antd.Alert; var Dropdown = antd.Dropdown; var Cascader = antd.Cascader; var Radio = antd.Radio; var message = antd.message; var listState = useState(H2_MOCK_STATIONS.slice()); var listData = listState[0]; var setListData = listState[1]; var categoryTabState = useState('all'); var categoryTab = categoryTabState[0]; var setCategoryTab = categoryTabState[1]; var listFiltersState = useState(h2EmptyListFilters()); var listFilters = listFiltersState[0]; var setListFilters = listFiltersState[1]; var appliedFiltersState = useState(h2EmptyListFilters()); var appliedFilters = appliedFiltersState[0]; var setAppliedFilters = appliedFiltersState[1]; var drawerState = useState({ open: false, mode: 'create', record: null }); var drawer = drawerState[0]; var setDrawer = drawerState[1]; var formState = useState(h2CreateEmptyForm()); var form = formState[0]; var setForm = formState[1]; var deleteModalState = useState({ open: false, record: null }); var deleteModal = deleteModalState[0]; var setDeleteModal = deleteModalState[1]; var requirementModalState = useState(false); var requirementModalOpen = requirementModalState[0]; var setRequirementModalOpen = requirementModalState[1]; var importModalState = useState(false); var importModalOpen = importModalState[0]; var setImportModalOpen = importModalState[1]; var importFileListState = useState([]); var importFileList = importFileListState[0]; var setImportFileList = importFileListState[1]; var importPreviewState = useState(null); var importPreview = importPreviewState[0]; var setImportPreview = importPreviewState[1]; var pageState = useState(1); var page = pageState[0]; var setPage = pageState[1]; var pageSizeState = useState(10); var pageSize = pageSizeState[0]; var setPageSize = pageSizeState[1]; var businessModalState = useState({ open: false, record: null, businessStatus: '营业中', businessHours: '', originBusinessStatus: '营业中', statusLogs: [] }); var businessModal = businessModalState[0]; var setBusinessModal = businessModalState[1]; var priceModalState = useState({ open: false, record: null, costUnitPrice: '', customerUnitPrice: '' }); var priceModal = priceModalState[0]; var setPriceModal = priceModalState[1]; var refuelModalState = useState({ open: false, station: null, records: [] }); var refuelModal = refuelModalState[0]; var setRefuelModal = refuelModalState[1]; var statementModalState = useState({ open: false, record: null, period: '2026-05' }); var statementModal = statementModalState[0]; var setStatementModal = statementModalState[1]; var prepaidBalanceDrillState = useState({ open: false, stationName: '', endingBalance: 0, rows: [] }); var prepaidBalanceDrill = prepaidBalanceDrillState[0]; var setPrepaidBalanceDrill = prepaidBalanceDrillState[1]; var subViewState = useState('list'); var subView = subViewState[0]; var setSubView = subViewState[1]; var createStationState = useState(h2CreateEmptyStationForm()); var createStation = createStationState[0]; var setCreateStation = createStationState[1]; var createSupplierModeState = useState('new'); var createSupplierMode = createSupplierModeState[0]; var setCreateSupplierMode = createSupplierModeState[1]; var createLinkedSupplierIdState = useState(undefined); var createLinkedSupplierId = createLinkedSupplierIdState[0]; var setCreateLinkedSupplierId = createLinkedSupplierIdState[1]; var createSupplierState = useState(h2CreateEmptySupplierForm()); var createSupplier = createSupplierState[0]; var setCreateSupplier = createSupplierState[1]; var createSubmittingState = useState(false); var createSubmitting = createSubmittingState[0]; var setCreateSubmitting = createSubmittingState[1]; var createSupplierReadonly = createSupplierMode === 'link' && !!createLinkedSupplierId; var readOnly = drawer.mode === 'view'; var existingNameMap = useMemo(function () { var map = {}; listData.forEach(function (r) { if (r.name) map[String(r.name).trim()] = true; }); return map; }, [listData]); var categoryCounts = useMemo(function () { var counts = { all: listData.length, high: 0, low: 0, none: 0 }; listData.forEach(function (r) { var stats = h2CalcRefuelStats(r.name); var k = h2DeriveFrequencyByRefuelCount(stats.count); if (counts[k] != null) counts[k] += 1; }); return counts; }, [listData]); var signedStats = useMemo(function () { var signed = 0; listData.forEach(function (r) { if (r.isSigned) signed += 1; }); return { signed: signed, unsigned: listData.length - signed }; }, [listData]); var filteredList = useMemo(function () { var list = listData.slice(); if (categoryTab !== 'all') { list = list.filter(function (r) { var stats = h2CalcRefuelStats(r.name); return h2DeriveFrequencyByRefuelCount(stats.count) === categoryTab; }); } var kw = (appliedFilters.name || '').trim().toLowerCase(); if (kw) list = list.filter(function (r) { return (r.name || '').toLowerCase().indexOf(kw) !== -1; }); if (appliedFilters.signed === 'yes') list = list.filter(function (r) { return r.isSigned; }); if (appliedFilters.signed === 'no') list = list.filter(function (r) { return !r.isSigned; }); if (appliedFilters.region && appliedFilters.region.length) { list = list.filter(function (r) { return h2MatchRegionFilter(r.region, appliedFilters.region); }); } if (appliedFilters.businessStatus) { list = list.filter(function (r) { return r.businessStatus === appliedFilters.businessStatus; }); } return list.map(function (r) { var stats = h2CalcRefuelStats(r.name); return Object.assign({}, r, { refuelCount: stats.count, refuelTotalKg: stats.totalKg, refuelFreqKey: h2DeriveFrequencyByRefuelCount(stats.count) }); }); }, [listData, categoryTab, appliedFilters]); var totalCount = filteredList.length; var displayList = useMemo(function () { var start = (page - 1) * pageSize; return filteredList.slice(start, start + pageSize); }, [filteredList, page, pageSize]); var tablePagination = useMemo(function () { return { current: page, pageSize: pageSize, total: totalCount, showSizeChanger: true, pageSizeOptions: ['5', '10', '20', '50'], showTotal: function (t) { return '共 ' + t + ' 条'; }, onChange: function (p, size) { setPage(p); if (size && size !== pageSize) setPageSize(size); } }; }, [page, pageSize, totalCount]); var handleKpiCardClick = useCallback(function (key) { setCategoryTab(key); setPage(1); }, []); var handleSignedFilterCardClick = useCallback(function (key) { var nextSigned = appliedFilters.signed === key ? undefined : key; setListFilters(function (p) { return Object.assign({}, p, { signed: nextSigned }); }); setAppliedFilters(function (p) { return Object.assign({}, p, { signed: nextSigned }); }); setPage(1); }, [appliedFilters.signed]); var handleListFilterQuery = useCallback(function () { setAppliedFilters({ name: listFilters.name, signed: listFilters.signed, region: listFilters.region, businessStatus: listFilters.businessStatus }); setPage(1); }, [listFilters]); var handleListFilterReset = useCallback(function () { var empty = h2EmptyListFilters(); setListFilters(empty); setAppliedFilters(empty); setPage(1); }, []); var renderFilterField = useCallback(function (label, control) { return React.createElement('div', { className: 'lc-filter-field' }, React.createElement('span', { className: 'lc-filter-field-label' }, label), React.createElement('div', { className: 'lc-filter-field-control' }, control) ); }, []); var renderAlertStatCard = useCallback(function (card, options) { var active = options.active; var count = options.count; var onClick = options.onClick; var icon = options.icon; return React.createElement('div', { key: card.key, role: 'button', tabIndex: 0, className: 'lc-alert-card lc-alert-card--' + card.type + ' lc-alert-card-clickable' + (active ? ' lc-alert-card-active' : ''), onClick: onClick, onKeyDown: function (e) { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onClick(); } }, 'aria-pressed': active, 'aria-label': card.title + ',共 ' + count + ' 个' }, React.createElement('div', { className: 'lc-alert-card-tip-anchor' }, React.createElement(Tooltip, { title: card.desc, placement: 'topRight', overlayStyle: { maxWidth: 320 } }, React.createElement('span', { className: 'lc-alert-card-tip', role: 'img', 'aria-label': card.title + '说明', onClick: function (e) { e.stopPropagation(); }, onMouseDown: function (e) { e.stopPropagation(); } }, h2SvgIcon([{ tag: 'circle', cx: 12, cy: 12, r: 10 }, { tag: 'line', x1: 12, y1: 16, x2: 12, y2: 12 }, { tag: 'line', x1: 12, y1: 8, x2: 12.01, y2: 8 }], 12) ) ) ), React.createElement('div', { className: 'lc-alert-card-icon' }, icon), React.createElement('div', { className: 'lc-alert-card-main' }, React.createElement('div', { className: 'lc-alert-card-val' }, count), React.createElement('div', { className: 'lc-alert-card-title' }, card.title) ) ); }, []); var resetCreateForm = useCallback(function () { setCreateStation(h2CreateEmptyStationForm()); setCreateSupplierMode('new'); setCreateLinkedSupplierId(undefined); setCreateSupplier(h2CreateEmptySupplierForm()); }, []); var openCreate = useCallback(function () { resetCreateForm(); setSubView('create'); }, [resetCreateForm]); var handleCreatePageBack = useCallback(function () { setCreateSubmitting(false); setSubView('list'); }, []); var handleCreateCancel = useCallback(function () { if (createSubmitting) return; if (h2CreateFormDirty(createStation, createSupplier, createSupplierMode, createLinkedSupplierId)) { Modal.confirm({ title: '放弃未保存的更改?', content: '当前填写内容尚未提交,返回列表后将丢失。', okText: '放弃并返回', cancelText: '继续填写', okButtonProps: { danger: true }, centered: true, onOk: handleCreatePageBack }); return; } handleCreatePageBack(); }, [createSubmitting, createStation, createSupplier, createSupplierMode, createLinkedSupplierId, handleCreatePageBack]); var updateCreateStation = useCallback(function (patch) { setCreateStation(function (prev) { return Object.assign({}, prev, patch); }); }, []); var updateCreateSupplier = useCallback(function (patch) { setCreateSupplier(function (prev) { return Object.assign({}, prev, patch); }); }, []); var handleCreateSupplierModeChange = useCallback(function (e) { setCreateSupplierMode(e.target.value); setCreateLinkedSupplierId(undefined); setCreateSupplier(h2CreateEmptySupplierForm()); }, []); var handleCreateLinkSupplierChange = useCallback(function (id) { setCreateLinkedSupplierId(id); var found = H2_MOCK_EXISTING_SUPPLIERS.filter(function (s) { return s.id === id; })[0]; setCreateSupplier(h2SupplierToForm(found)); }, []); var handleCreateSupplierCityChange = useCallback(function (v) { updateCreateSupplier({ city: v, region: v && v[0] ? h2GetRegionByProvince(v[0]) : '' }); }, [updateCreateSupplier]); var syncCreateSupplierFromStation = useCallback(function () { if (createSupplierMode !== 'new') return; setCreateSupplier(function (supplier) { var patch = {}; if (createStation.name && !supplier.name) patch.name = createStation.name; if (createStation.address && createStation.address.region && createStation.address.region.length >= 2) { patch.city = createStation.address.region.slice(); patch.region = h2GetRegionByProvince(createStation.address.region[0]); } if (createStation.address && createStation.address.detail && !supplier.address) patch.address = createStation.address.detail; if (createStation.contact && !supplier.contactName) patch.contactName = createStation.contact; if (createStation.mobilePhone && !supplier.contactMobile) patch.contactMobile = createStation.mobilePhone; return Object.keys(patch).length ? Object.assign({}, supplier, patch) : supplier; }); }, [createSupplierMode, createStation]); var validateCreateForm = useCallback(function () { if (!(createStation.name || '').trim()) { message.warning('请填写加氢站名称'); return false; } if (!createStation.address.region || createStation.address.region.length < 2) { message.warning('请选择加氢站地址的省 / 市'); return false; } if (!(createStation.address.detail || '').trim()) { message.warning('请填写加氢站详细地址'); return false; } if (!(createStation.contact || '').trim()) { message.warning('请填写联系人'); return false; } if (!h2StationContactPhone(createStation)) { message.warning('请填写联系电话'); return false; } if (createStation.isSigned) { if (!createStation.contractStart || !createStation.contractEnd) { message.warning('签约站点请填写签约开始与结束时间'); return false; } } var hoursParsed = h2ParseBusinessHours(createStation.businessHours); if (hoursParsed.mode === 'custom') { if (!(hoursParsed.start || '').trim() || !(hoursParsed.end || '').trim()) { message.warning('非全天营业请选择开始与结束时间'); return false; } if (!/^(\d{1,2}):(\d{2})$/.test(h2NormalizeTimeText(hoursParsed.start)) || !/^(\d{1,2}):(\d{2})$/.test(h2NormalizeTimeText(hoursParsed.end))) { message.warning('营业时间格式须为 HH:mm'); return false; } } if (createSupplierMode === 'link' && !createLinkedSupplierId) { message.warning('请选择要关联的已有供应商'); return false; } if (createSupplierMode === 'new') { if (!(createSupplier.name || '').trim()) { message.warning('请填写供应商名称'); return false; } if (!createSupplier.businessLicenseFiles || !createSupplier.businessLicenseFiles.length) { message.warning('请上传营业执照'); return false; } if (!createSupplier.fillingLicenseFiles || !createSupplier.fillingLicenseFiles.length) { message.warning('请上传充装许可证'); return false; } } return true; }, [createStation, createSupplierMode, createLinkedSupplierId, createSupplier]); var handleCreatePageSubmit = useCallback(function (payload) { var station = payload && payload.station; if (!station) return; var nextId = listData.reduce(function (m, r) { return Math.max(m, r.id || 0); }, 0) + 1; var created = Object.assign({}, station, { id: nextId }); setListData(function (prev) { return [created].concat(prev); }); setPage(1); setSubView('list'); var supplierHint = payload.supplierMode === 'link' ? '已关联已有供应商' : '已同步创建加氢站类型供应商'; message.success('站点已创建;' + supplierHint + '(原型)'); }, [listData]); var handleCreateSubmit = useCallback(function () { if (createSubmitting) return; if (!validateCreateForm()) return; setCreateSubmitting(true); syncCreateSupplierFromStation(); var now = h2OperateTimestamp(); var phoneDisplay = createStation.mobilePhone || createStation.landlinePhone || ''; if (createStation.mobilePhone && createStation.landlinePhone) phoneDisplay = createStation.mobilePhone; var stationRecord = { name: (createStation.name || '').trim(), region: createStation.address.region || [], addressDetail: (createStation.address.detail || '').trim(), fullAddress: h2BuildFullAddress(createStation.address.region, createStation.address.detail), isSigned: !!createStation.isSigned, contractStart: createStation.isSigned ? createStation.contractStart : '', contractEnd: createStation.isSigned ? createStation.contractEnd : '', contractFiles: (createStation.contractFiles || []).map(function (f) { return { uid: f.uid, name: f.name || '合同附件.pdf', url: f.url || '' }; }), businessStatus: createStation.businessStatus || '营业中', businessHours: (createStation.businessHours || '').trim(), contact: (createStation.contact || '').trim(), phone: phoneDisplay, mobilePhone: (createStation.mobilePhone || '').trim(), landlinePhone: (createStation.landlinePhone || '').trim(), costUnitPrice: createStation.costUnitPrice ? parseFloat(createStation.costUnitPrice) : undefined, customerUnitPrice: createStation.customerUnitPrice ? parseFloat(createStation.customerUnitPrice) : undefined, prepaidBalance: 0, businessStatusLogs: [], updateTime: now, supplierMode: createSupplierMode, linkedSupplierId: createSupplierMode === 'link' ? createLinkedSupplierId : undefined, supplier: Object.assign({ type: '加氢站' }, createSupplier) }; window.setTimeout(function () { handleCreatePageSubmit({ station: stationRecord, supplier: createSupplier, supplierMode: createSupplierMode }); setCreateSubmitting(false); }, 380); }, [createSubmitting, validateCreateForm, syncCreateSupplierFromStation, createStation, createSupplier, createSupplierMode, createLinkedSupplierId, handleCreatePageSubmit]); var handleCreateReset = useCallback(function () { resetCreateForm(); message.info('表单已重置'); }, [resetCreateForm]); var openRefuelModal = useCallback(function (record) { setRefuelModal({ open: true, station: record, records: h2GetRefuelRecordsByStation(record.name) }); }, []); var closeRefuelModal = useCallback(function () { setRefuelModal({ open: false, station: null, records: [] }); }, []); var openPrepaidBalanceDrill = useCallback(function (record) { setPrepaidBalanceDrill({ open: true, stationName: record.name || '', endingBalance: h2NumOrZero(record.prepaidBalance), rows: h2BuildMockPrepaidBalanceRows(record) }); }, []); var closePrepaidBalanceDrill = useCallback(function () { setPrepaidBalanceDrill({ open: false, stationName: '', endingBalance: 0, rows: [] }); }, []); var openStatementModal = useCallback(function (record) { setStatementModal({ open: true, record: record, period: '2026-05' }); }, []); var closeStatementModal = useCallback(function () { setStatementModal({ open: false, record: null, period: '2026-05' }); }, []); var handleGenerateStatement = useCallback(function () { if (!statementModal.record) return; if (!statementModal.period) { message.warning('请选择对账周期'); return; } var periodLabel = statementModal.period.replace('-', '年') + '月'; message.success('已生成「' + statementModal.record.name + '」' + periodLabel + '氢费对账单(原型)'); closeStatementModal(); }, [statementModal, closeStatementModal]); var openEdit = useCallback(function (record) { setForm(h2RecordToForm(record)); setDrawer({ open: true, mode: 'edit', record: record }); }, []); var openView = useCallback(function (record) { setForm(h2RecordToForm(record)); setDrawer({ open: true, mode: 'view', record: record }); }, []); var openBusinessSetting = useCallback(function (record) { setBusinessModal({ open: true, record: record, businessStatus: record.businessStatus || '营业中', businessHours: record.businessHours === '—' ? '' : (record.businessHours || ''), originBusinessStatus: record.businessStatus || '营业中', statusLogs: (record.businessStatusLogs || []).slice() }); }, []); var closeBusinessModal = useCallback(function () { setBusinessModal({ open: false, record: null, businessStatus: '营业中', businessHours: '', originBusinessStatus: '营业中', statusLogs: [] }); }, []); var handleSaveBusinessSetting = useCallback(function () { if (!businessModal.record) return; var nextStatus = businessModal.businessStatus || '营业中'; var statusChanged = nextStatus !== businessModal.originBusinessStatus; var newLog = statusChanged ? h2CreateBusinessStatusLog(businessModal.originBusinessStatus, nextStatus, H2_CURRENT_OPERATOR) : null; setListData(function (prev) { return prev.map(function (r) { if (r.id !== businessModal.record.id) return r; var logs = (r.businessStatusLogs || []).slice(); if (newLog) logs.unshift(newLog); return Object.assign({}, r, { businessStatus: nextStatus, businessHours: (businessModal.businessHours || '').trim() || '—', businessStatusLogs: logs, updateTime: h2OperateTimestamp() }); }); }); message.success(statusChanged ? '营业状态已更新(原型)' : '营业时间已保存(原型)'); closeBusinessModal(); }, [businessModal, closeBusinessModal]); var openPriceConfig = useCallback(function (record) { setPriceModal({ open: true, record: record, costUnitPrice: record.costUnitPrice != null ? String(record.costUnitPrice) : '', customerUnitPrice: record.customerUnitPrice != null ? String(record.customerUnitPrice) : '' }); }, []); var closePriceModal = useCallback(function () { setPriceModal({ open: false, record: null, costUnitPrice: '', customerUnitPrice: '' }); }, []); var handleSavePriceConfig = useCallback(function () { if (!priceModal.record) return; var cost = parseFloat(priceModal.costUnitPrice); var customer = parseFloat(priceModal.customerUnitPrice); if (priceModal.costUnitPrice !== '' && isNaN(cost)) { message.warning('请输入有效的成本单价'); return; } if (priceModal.customerUnitPrice !== '' && isNaN(customer)) { message.warning('请输入有效的对客单价'); return; } setListData(function (prev) { return prev.map(function (r) { if (r.id !== priceModal.record.id) return r; return Object.assign({}, r, { costUnitPrice: priceModal.costUnitPrice === '' ? null : cost, customerUnitPrice: priceModal.customerUnitPrice === '' ? null : customer, updateTime: new Date().toISOString().slice(0, 16).replace('T', ' ') }); }); }); message.success('价格配置已保存(原型)'); closePriceModal(); }, [priceModal, closePriceModal]); var getRowMoreMenuItems = useCallback(function (record) { return [ { key: 'edit', label: '编辑', onClick: function () { openEdit(record); } }, { key: 'business', label: '营业状态', onClick: function () { openBusinessSetting(record); } }, { key: 'price', label: '价格配置', onClick: function () { openPriceConfig(record); } }, { key: 'statement', label: '生成对账单', onClick: function () { openStatementModal(record); } }, { type: 'divider' }, { key: 'delete', label: '删除', danger: true, onClick: function () { setDeleteModal({ open: true, record: record }); } } ]; }, [openEdit, openBusinessSetting, openPriceConfig, openStatementModal]); var closeDrawer = useCallback(function () { setDrawer({ open: false, mode: 'create', record: null }); }, []); var validateForm = useCallback(function () { if (!(form.name || '').trim()) { message.warning('请填写加氢站名称'); return false; } if (!form.address.region || form.address.region.length < 2) { message.warning('请选择省 / 市'); return false; } if (!(form.address.detail || '').trim()) { message.warning('请填写详细地址'); return false; } if (!(form.contact || '').trim()) { message.warning('请填写联系人'); return false; } if (!(form.phone || '').trim()) { message.warning('请填写联系电话'); return false; } if (form.isSigned) { if (!form.contractStart || !form.contractEnd) { message.warning('已签约站点请填写签约开始与结束时间'); return false; } } return true; }, [form]); var handleSave = useCallback(function () { if (!validateForm()) return; if (!drawer.record) return; var updated = h2FormToRecord(form, drawer.record.id); updated.businessStatus = drawer.record.businessStatus || '营业中'; updated.costUnitPrice = drawer.record.costUnitPrice; updated.customerUnitPrice = drawer.record.customerUnitPrice; updated.businessStatusLogs = drawer.record.businessStatusLogs || []; updated.prepaidBalance = drawer.record.prepaidBalance; updated.mobilePhone = drawer.record.mobilePhone; updated.landlinePhone = drawer.record.landlinePhone; updated.supplier = drawer.record.supplier; updated.linkedSupplierId = drawer.record.linkedSupplierId; setListData(function (prev) { return prev.map(function (r) { return r.id === updated.id ? updated : r; }); }); message.success('站点已保存(原型)'); closeDrawer(); }, [validateForm, drawer, form, closeDrawer]); var closeImportModal = useCallback(function () { setImportModalOpen(false); setImportFileList([]); setImportPreview(null); }, []); var downloadImportTemplate = useCallback(function () { h2DownloadCsv('加氢站点批量导入模板.csv', H2_IMPORT_TEMPLATE_HEADERS, H2_IMPORT_TEMPLATE_SAMPLE); message.success('已下载导入模板'); }, []); var parseImportFile = useCallback(function (file) { if (!file) return; var name = String(file.name || '').toLowerCase(); if (name.endsWith('.xls') || name.endsWith('.xlsx')) { message.warning('原型环境请使用 CSV 模板导入;联调后将支持 Excel 直接上传'); setImportFileList([file]); setImportPreview(null); return; } if (!name.endsWith('.csv')) { message.error('仅支持 .csv、.xls、.xlsx 格式'); return; } setImportFileList([file]); var reader = new FileReader(); reader.onload = function (ev) { var text = (ev && ev.target && ev.target.result) || ''; var parsed = h2ParseImportCsv(text); if (parsed.headerError) { message.error(parsed.headerError); setImportPreview(null); return; } if (!parsed.rows.length) { message.warning('未解析到有效数据,请检查文件内容'); setImportPreview(null); return; } var nameMap = Object.assign({}, existingNameMap); var valid = []; var errors = []; var ri; for (ri = 0; ri < parsed.rows.length; ri++) { var row = parsed.rows[ri]; var rowErrors = h2ValidateImportRow(row, nameMap); if (rowErrors.length) { errors.push({ lineNo: row.lineNo, name: row.name || '—', reasons: rowErrors }); } else { valid.push(row); if (row.name) nameMap[String(row.name).trim()] = true; } } setImportPreview({ valid: valid, errors: errors, fileName: file.name }); }; reader.onerror = function () { message.error('文件读取失败'); }; reader.readAsText(file, 'UTF-8'); }, [existingNameMap]); var handleConfirmImport = useCallback(function () { if (!importPreview || !importPreview.valid.length) { message.warning('没有可导入的有效数据'); return; } setListData(function (prev) { var maxId = prev.reduce(function (m, r) { return Math.max(m, r.id || 0); }, 0); var imported = importPreview.valid.map(function (row, idx) { return h2ImportRowToRecord(row, maxId + idx + 1); }); return imported.concat(prev); }); var errN = (importPreview.errors || []).length; if (errN) { message.success('成功导入 ' + importPreview.valid.length + ' 条,' + errN + ' 条校验失败已跳过'); } else { message.success('成功导入 ' + importPreview.valid.length + ' 条站点'); } setPage(1); closeImportModal(); }, [importPreview, closeImportModal]); React.useEffect(function () { var maxPage = Math.max(1, Math.ceil(totalCount / pageSize) || 1); if (page > maxPage) setPage(maxPage); }, [totalCount, pageSize, page]); var renderRefuelFreqShortTag = function (freqKey) { if (freqKey === 'high') { return React.createElement(Tag, { color: 'success', className: 'lc-refuel-freq-tag' }, '高频'); } if (freqKey === 'low') { return React.createElement(Tag, { color: 'warning', className: 'lc-refuel-freq-tag' }, '低频'); } return null; }; var renderBusinessStatusTag = function (v) { if (v === '营业中') return React.createElement(Tag, { color: 'success', style: { borderRadius: 6, fontWeight: 600 } }, v); if (v === '暂停营业') return React.createElement(Tag, { color: 'warning', style: { borderRadius: 6, fontWeight: 600 } }, v); if (v === '停止营业') return React.createElement(Tag, { color: 'error', style: { borderRadius: 6, fontWeight: 600 } }, v); return React.createElement(Tag, { style: { borderRadius: 6, fontWeight: 600, color: '#64748b', background: '#f1f5f9', border: '1px solid #e2e8f0' } }, v || '—'); }; var renderBusinessStatusText = function (v, tone) { var color = v === '营业中' ? '#059669' : v === '暂停营业' ? '#ea580c' : v === '停止营业' ? '#dc2626' : '#64748b'; if (tone === 'muted') color = '#94a3b8'; return React.createElement('span', { style: { fontWeight: 600, color: color } }, v || '—'); }; var renderRefuelDrillLink = function (text, record, ariaLabel) { return React.createElement('button', { type: 'button', className: 'h2-refuel-drill-link', onClick: function (e) { e.stopPropagation(); openRefuelModal(record); }, 'aria-label': ariaLabel }, text); }; var renderPrepaidBalance = useCallback(function (v, record) { if (v == null || v === '') return React.createElement('span', { style: { color: '#94a3b8' } }, '—'); var n = typeof v === 'number' ? v : parseFloat(v); if (isNaN(n)) return '—'; if (!record) { var plainColor = n < 0 ? '#dc2626' : '#0f172a'; return React.createElement('span', { style: { fontWeight: 700, color: plainColor, fontVariantNumeric: 'tabular-nums' }, title: n < 0 ? '预付余额不足,已欠费' : undefined }, h2FormatYuanNum(n)); } var isArrears = n < 0; var amountStyle = isArrears ? { color: '#dc2626', fontVariantNumeric: 'tabular-nums' } : { color: '#059669', fontVariantNumeric: 'tabular-nums' }; return React.createElement('div', { className: 'h2-prepaid-balance-cell' }, isArrears ? React.createElement(Tag, { color: 'error', className: 'lc-station-signed-tag' }, '已欠费') : null, React.createElement('button', { type: 'button', className: 'h2-prepaid-balance-amount', style: amountStyle, title: '点击查看余额变更明细', 'aria-label': '查看「' + (record.name || '') + '」余额变更明细', onClick: function (e) { e.stopPropagation(); openPrepaidBalanceDrill(record); } }, h2FormatYuanNum(n)) ); }, [openPrepaidBalanceDrill]); var prepaidBalanceDrillColumns = [ { title: '加氢站名称', dataIndex: 'stationName', key: 'stationName', width: 220, ellipsis: true }, { title: '收入金额(元)', dataIndex: 'incomeAmount', key: 'incomeAmount', width: 120, align: 'right', render: function (v) { return h2FormatLedgerMoney(v); } }, { title: '支出金额(元)', dataIndex: 'expenseAmount', key: 'expenseAmount', width: 120, align: 'right', render: function (v) { return h2FormatLedgerMoney(v); } }, { title: '余额(元)', dataIndex: 'balance', key: 'balance', width: 120, align: 'right', render: function (v) { var bn = h2NumOrZero(v); var style = bn < 0 ? { color: '#dc2626', fontWeight: 600, fontVariantNumeric: 'tabular-nums' } : { fontVariantNumeric: 'tabular-nums' }; return React.createElement('span', { style: style }, h2FormatYuanNum(v)); } }, { title: '订单编号', dataIndex: 'orderNo', key: 'orderNo', width: 168, align: 'center', render: function (v) { return React.createElement('span', { style: { fontFamily: 'monospace', fontSize: 12 } }, v || '—'); } } ]; var prepaidBalanceDrillSummary = useMemo(function () { if (!prepaidBalanceDrill.rows || !prepaidBalanceDrill.rows.length) { return { incomeTotal: 0, expenseTotal: 0, endingBalance: 0 }; } var last = prepaidBalanceDrill.rows[prepaidBalanceDrill.rows.length - 1]; return prepaidBalanceDrill.rows.reduce(function (acc, r) { acc.incomeTotal += h2NumOrZero(r.incomeAmount); acc.expenseTotal += h2NumOrZero(r.expenseAmount); return acc; }, { incomeTotal: 0, expenseTotal: 0, endingBalance: h2NumOrZero(last.balance) }); }, [prepaidBalanceDrill.rows]); var renderPrepaidBalanceDrillSummary = useCallback(function () { return React.createElement(Table.Summary, null, React.createElement(Table.Summary.Row, null, React.createElement(Table.Summary.Cell, { index: 0, align: 'center' }, '合计'), React.createElement(Table.Summary.Cell, { index: 1, align: 'right' }, h2FormatYuanNum(prepaidBalanceDrillSummary.incomeTotal)), React.createElement(Table.Summary.Cell, { index: 2, align: 'right' }, h2FormatYuanNum(prepaidBalanceDrillSummary.expenseTotal)), React.createElement(Table.Summary.Cell, { index: 3, align: 'right' }, h2FormatYuanNum(prepaidBalanceDrillSummary.endingBalance)), React.createElement(Table.Summary.Cell, { index: 4 }) ) ); }, [prepaidBalanceDrillSummary]); var refuelRecordColumns = [ { title: '序号', key: 'seq', width: 52, align: 'center', render: function (_, __, index) { return index + 1; } }, { title: '加氢时间', dataIndex: 'hydrogenTime', key: 'hydrogenTime', width: 168 }, { title: '车牌号', dataIndex: 'plateNo', key: 'plateNo', width: 110 }, { title: '客户名称', dataIndex: 'customerName', key: 'customerName', width: 180, ellipsis: true }, { title: '加氢量(kg)', dataIndex: 'hydrogenKg', key: 'hydrogenKg', width: 100, align: 'right', render: function (v) { return h2FormatKgNum(v); } }, { title: '成本单价', dataIndex: 'costUnitPrice', key: 'costUnitPrice', width: 92, align: 'right', render: function (v) { return h2FormatYuanNum(v); } }, { title: '成本总价', dataIndex: 'costAmount', key: 'costAmount', width: 92, align: 'right', render: function (v) { return h2FormatYuanNum(v); } }, { title: '加氢单价', dataIndex: 'customerUnitPrice', key: 'customerUnitPrice', width: 92, align: 'right', render: function (v) { return h2FormatYuanNum(v); } }, { title: '加氢总价', dataIndex: 'customerAmount', key: 'customerAmount', width: 92, align: 'right', render: function (v) { return h2FormatYuanNum(v); } } ]; var refuelModalSummary = useMemo(function () { var records = refuelModal.records || []; var totalKg = 0; var totalCost = 0; var totalCustomer = 0; var i; for (i = 0; i < records.length; i++) { totalKg += records[i].hydrogenKg || 0; totalCost += records[i].costAmount || 0; totalCustomer += records[i].customerAmount || 0; } return { count: records.length, totalKg: totalKg, totalCost: totalCost, totalCustomer: totalCustomer }; }, [refuelModal.records]); var renderRefuelTotalsBar = useCallback(function (summary) { var items = [ { key: 'count', label: '加氢次数(次)', value: String(summary.count || 0) }, { key: 'hydrogenKg', label: '加氢量(kg)', value: h2FormatKgNum(summary.totalKg) }, { key: 'costTotal', label: '成本总价(元)', value: h2FormatYuanNum(summary.totalCost) }, { key: 'customerAmount', label: '加氢总价(元)', value: h2FormatYuanNum(summary.totalCustomer) } ]; return React.createElement('div', { className: 'h2-ledger-totals-bar' }, React.createElement('div', { className: 'h2-ledger-totals-bar__title' }, '合计'), React.createElement('div', { className: 'h2-ledger-totals-bar__items' }, items.map(function (item) { return React.createElement('div', { key: item.key, className: 'h2-ledger-totals-bar__item' }, React.createElement('div', { className: 'h2-ledger-totals-bar__label' }, item.label), React.createElement('div', { className: 'h2-ledger-totals-bar__value' }, item.value) ); }) ) ); }, []); var businessStatusLogColumns = [ { title: '操作时间', dataIndex: 'operateTime', key: 'operateTime', width: 150 }, { title: '操作人', dataIndex: 'operator', key: 'operator', width: 100, ellipsis: true }, { title: '修改前状态', dataIndex: 'beforeStatus', key: 'beforeStatus', width: 110, render: function (v) { return renderBusinessStatusText(v, 'muted'); } }, { title: '修改后状态', dataIndex: 'afterStatus', key: 'afterStatus', width: 110, render: function (v) { return renderBusinessStatusText(v); } } ]; var columns = [ { title: '加氢站名称', dataIndex: 'name', key: 'name', width: 248, fixed: 'left', render: function (v, r) { return React.createElement('div', { className: 'lc-station-name-row' }, React.createElement('div', { className: 'lc-station-name' }, v || '—'), React.createElement(Tag, { color: r.isSigned ? 'success' : 'default', className: 'lc-station-signed-tag', style: r.isSigned ? undefined : { color: '#64748b', background: '#f1f5f9', border: '1px solid #e2e8f0' } }, r.isSigned ? '已签约' : '未签约') ); } }, { title: '地址', key: 'address', width: 280, ellipsis: true, render: function (_, r) { return React.createElement('div', null, React.createElement('div', { className: 'lc-station-region' }, h2FormatRegion(r.region)), React.createElement('div', { style: { color: '#334155' } }, r.addressDetail || '—') ); } }, { title: '签约时间', key: 'contractRange', width: 220, render: function (_, r) { if (!r.isSigned) return React.createElement('span', { style: { color: '#94a3b8' } }, '—'); return React.createElement('div', null, React.createElement('div', { style: { fontSize: 12, fontWeight: 600, color: '#334155' } }, (r.contractStart || '—') + ' 至 ' + (r.contractEnd || '—') ), r.contractEnd ? h2RenderContractRemainTag(r.contractEnd) : null ); } }, { title: '营业状态', dataIndex: 'businessStatus', key: 'businessStatus', width: 110, render: renderBusinessStatusTag }, { title: '营业时间', dataIndex: 'businessHours', key: 'businessHours', width: 140, render: function (v) { return h2DisplayBusinessHours(v); } }, { title: '加氢次数', dataIndex: 'refuelCount', key: 'refuelCount', width: 96, align: 'right', render: function (v, record) { return renderRefuelDrillLink(String(v || 0), record, '查看加氢记录,共 ' + (v || 0) + ' 次'); } }, { title: '加氢量(kg)', dataIndex: 'refuelTotalKg', key: 'refuelTotalKg', width: 148, align: 'right', render: function (v, record) { return React.createElement('div', { className: 'lc-refuel-kg-row' }, renderRefuelFreqShortTag(record.refuelFreqKey), renderRefuelDrillLink(h2FormatKgNum(v), record, '查看加氢记录,合计 ' + h2FormatKgNum(v) + ' kg') ); } }, { title: '预付余额(元)', dataIndex: 'prepaidBalance', key: 'prepaidBalance', width: 188, align: 'right', className: 'h2-col-prepaid-balance', onCell: function () { return { className: 'h2-cell-prepaid-balance' }; }, render: function (v, record) { return renderPrepaidBalance(v, record); } }, { title: '联系方式', key: 'contactInfo', width: 120, render: function (_, r) { var mobile = r.mobilePhone || r.phone || ''; var landline = r.landlinePhone || ''; return React.createElement('div', null, React.createElement('div', { className: 'lc-station-contact-name' }, r.contact || '—'), mobile ? React.createElement('div', { className: 'lc-station-contact-phone' }, mobile) : null, landline ? React.createElement('div', { className: 'lc-station-contact-phone' }, landline) : null, !mobile && !landline ? React.createElement('div', { className: 'lc-station-contact-phone' }, '—') : null ); } }, { title: '操作', key: 'action', width: 108, fixed: 'right', render: function (_, record) { return React.createElement('div', { className: 'h2-row-actions' }, React.createElement(Button, { type: 'link', size: 'small', className: 'lc-action-btn', onClick: function () { openView(record); } }, '查看'), React.createElement(Dropdown, { trigger: ['click'], placement: 'bottomRight', menu: { items: getRowMoreMenuItems(record) } }, React.createElement(Tooltip, { title: '更多' }, React.createElement('span', { className: 'h2-action-more-btn', role: 'button', tabIndex: 0, 'aria-label': '更多操作', onClick: function (e) { e.stopPropagation(); } }, h2MoreIcon()) ) ) ); } } ]; var formItem = function (label, required, node, extra) { return React.createElement(Form.Item, { label: required ? React.createElement('span', null, React.createElement('span', { style: { color: '#ef4444', marginRight: 4 } }, '*'), label) : label, extra: extra, style: { marginBottom: 16 } }, node); }; var drawerSection = function (title, children) { return React.createElement('div', { style: { marginBottom: 8 } }, React.createElement('div', { className: 'h2-drawer-section-title' }, title), children ); }; var drawerTitle = drawer.mode === 'edit' ? '编辑加氢站点' : '查看加氢站点'; var createViewNode = subView === 'create' ? h2BuildStationCreateView({ station: createStation, supplier: createSupplier, supplierMode: createSupplierMode, linkedSupplierId: createLinkedSupplierId, supplierReadonly: createSupplierReadonly, updateStation: updateCreateStation, updateSupplier: updateCreateSupplier, syncSupplierFromStation: syncCreateSupplierFromStation, handleSupplierModeChange: handleCreateSupplierModeChange, handleLinkSupplierChange: handleCreateLinkSupplierChange, handleSupplierCityChange: handleCreateSupplierCityChange, onCancel: handleCreateCancel, onReset: handleCreateReset, onSubmit: handleCreateSubmit, submitting: createSubmitting, onOpenRequirement: function () { setRequirementModalOpen(true); }, reqIcon: H2_ICONS.doc, reqBtnStyle: H2_REQ_BTN_STYLE }) : null; var emptyNode = React.createElement('div', { style: { padding: '40px 0', textAlign: 'center' } }, H2_ICONS.empty, React.createElement('div', { style: { color: '#94a3b8', marginTop: 12 } }, '暂无符合检索条件的站点') ); return React.createElement('div', { className: 'h2-station-page lc-edit-page' + (subView === 'create' ? ' h2-station-page--create' : '') }, React.createElement('style', null, H2_PAGE_STYLE), createViewNode, subView === 'list' ? React.createElement('div', { style: { display: 'flex', flexDirection: 'column', height: '100%', overflow: 'hidden' } }, React.createElement('div', { style: { marginBottom: 16, display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: 12 } }, React.createElement(Breadcrumb, { items: [{ title: '加氢站管理' }, { title: '站点信息' }] }), React.createElement(Button, { type: 'default', icon: H2_ICONS.doc, style: H2_REQ_BTN_STYLE, onClick: function () { setRequirementModalOpen(true); }, 'aria-label': '查看需求说明' }, '查看需求说明') ), React.createElement(Card, { className: 'lc-filter-card', title: '筛选条件', bordered: false }, React.createElement('div', { className: 'lc-filter-grid' }, renderFilterField('加氢站名称', React.createElement(Input, { placeholder: '请输入加氢站名称', value: listFilters.name, onChange: function (e) { setListFilters(function (p) { return Object.assign({}, p, { name: e.target.value }); }); }, onPressEnter: handleListFilterQuery, allowClear: true, style: { borderRadius: 8 } })), renderFilterField('是否签约', React.createElement(Select, { placeholder: '全部', allowClear: true, value: listFilters.signed, onChange: function (v) { setListFilters(function (p) { return Object.assign({}, p, { signed: v }); }); }, options: [{ value: 'yes', label: '已签约' }, { value: 'no', label: '未签约' }], style: { width: '100%' }, dropdownStyle: { borderRadius: 8 } })), renderFilterField('地区(省-市)', React.createElement(Cascader, { options: H2_REGION_CASCADER_OPTIONS, value: listFilters.region && listFilters.region.length ? listFilters.region : undefined, onChange: function (v) { setListFilters(function (p) { return Object.assign({}, p, { region: v || undefined }); }); }, placeholder: '请选择省 / 市', allowClear: true, style: { width: '100%', borderRadius: 8 }, changeOnSelect: true })), renderFilterField('营业状态', React.createElement(Select, { placeholder: '全部', allowClear: true, value: listFilters.businessStatus, onChange: function (v) { setListFilters(function (p) { return Object.assign({}, p, { businessStatus: v }); }); }, options: H2_BUSINESS_STATUS_OPTIONS, style: { width: '100%' }, dropdownStyle: { borderRadius: 8 } })) ), React.createElement('div', { className: 'lc-filter-actions' }, React.createElement(Button, { onClick: handleListFilterReset, style: { borderRadius: 8 } }, '重置'), React.createElement(Button, { type: 'primary', onClick: handleListFilterQuery, style: H2_PRIMARY_BTN_STYLE }, '查询') ) ), React.createElement('div', { className: 'lc-alert-stats-row' }, renderAlertStatCard(H2_STATION_KPI_CARDS[0], { active: categoryTab === 'all', count: categoryCounts.all || 0, onClick: function () { handleKpiCardClick('all'); }, icon: h2KpiIcon('all') }), H2_SIGNED_FILTER_CARDS.map(function (card) { return renderAlertStatCard(card, { active: appliedFilters.signed === card.key, count: card.key === 'yes' ? signedStats.signed : signedStats.unsigned, onClick: function () { handleSignedFilterCardClick(card.key); }, icon: h2SignedFilterIcon(card.key) }); }), H2_STATION_KPI_CARDS.slice(1).map(function (card) { return renderAlertStatCard(card, { active: categoryTab === card.key, count: categoryCounts[card.key] || 0, onClick: function () { handleKpiCardClick(card.key); }, icon: h2KpiIcon(card.key) }); }) ), React.createElement('div', { className: 'lc-table-section' }, React.createElement('div', { className: 'lc-table-toolbar' }, React.createElement('div', { className: 'lc-table-toolbar-actions' }, React.createElement(Button, { type: 'default', icon: H2_ICONS.upload, style: { borderRadius: 8, fontWeight: 600, borderColor: '#10b981', color: '#059669' }, onClick: function () { setImportModalOpen(true); }, 'aria-label': '批量导入加氢站点' }, '批量导入'), React.createElement(Button, { type: 'primary', style: H2_PRIMARY_BTN_STYLE, onClick: openCreate, 'aria-label': '新建加氢站点' }, '新建站点') ) ), React.createElement('div', { className: 'lc-table-card' }, React.createElement(Table, { className: 'lc-list-table', rowKey: 'id', columns: columns, dataSource: displayList, pagination: tablePagination, size: 'middle', scroll: { x: 1570 }, locale: { emptyText: emptyNode } }) ) ) ) : null, React.createElement(Drawer, { title: drawerTitle, width: 580, open: drawer.open, onClose: closeDrawer, destroyOnClose: true, styles: { body: { paddingTop: 8 } }, footer: readOnly ? React.createElement(Button, { onClick: closeDrawer, style: { borderRadius: 8 } }, '关闭') : React.createElement(Space, null, React.createElement(Button, { onClick: closeDrawer, style: { borderRadius: 8 } }, '取消'), React.createElement(Button, { type: 'primary', onClick: handleSave, style: H2_PRIMARY_BTN_STYLE }, '保存') ) }, React.createElement(Form, { layout: 'vertical', requiredMark: false }, drawerSection('基本信息', React.createElement(React.Fragment, null, formItem('加氢站名称', true, React.createElement(Input, { value: form.name, disabled: readOnly, placeholder: '请输入加氢站名称', maxLength: 80, style: { borderRadius: 8 }, onChange: function (e) { setForm(function (f) { return Object.assign({}, f, { name: e.target.value }); }); } })), formItem('地址', true, React.createElement(RegionAddressInput, { value: form.address, disabled: readOnly, onChange: function (v) { setForm(function (f) { return Object.assign({}, f, { address: v }); }); } })), formItem('营业时间', false, React.createElement(BusinessHoursInput, { value: form.businessHours, disabled: readOnly, fieldStyle: { width: '100%', borderRadius: 8 }, onChange: function (v) { setForm(function (f) { return Object.assign({}, f, { businessHours: v }); }); } })) ) ), React.createElement(Divider, { style: { margin: '8px 0 20px' } }), drawerSection('签约信息', React.createElement(React.Fragment, null, formItem('是否签约', false, React.createElement(Switch, { checked: form.isSigned, disabled: readOnly, checkedChildren: '已签约', unCheckedChildren: '未签约', onChange: function (v) { setForm(function (f) { return Object.assign({}, f, { isSigned: v }); }); } })), formItem('签约开始时间', form.isSigned, React.createElement(Input, { type: 'date', style: { width: '100%', borderRadius: 8 }, disabled: readOnly || !form.isSigned, value: form.contractStart || '', onChange: function (e) { setForm(function (f) { return Object.assign({}, f, { contractStart: e.target.value }); }); } })), formItem('签约结束时间', form.isSigned, React.createElement(Input, { type: 'date', style: { width: '100%', borderRadius: 8 }, disabled: readOnly || !form.isSigned, value: form.contractEnd || '', onChange: function (e) { setForm(function (f) { return Object.assign({}, f, { contractEnd: e.target.value }); }); } })) ) ), React.createElement(Divider, { style: { margin: '8px 0 20px' } }), drawerSection('联系信息', React.createElement(React.Fragment, null, formItem('联系人', true, React.createElement(Input, { value: form.contact, disabled: readOnly, placeholder: '请输入联系人', style: { borderRadius: 8 }, onChange: function (e) { setForm(function (f) { return Object.assign({}, f, { contact: e.target.value }); }); } })), formItem('联系电话', true, React.createElement(Input, { value: form.phone, disabled: readOnly, placeholder: '请输入联系电话', style: { borderRadius: 8 }, onChange: function (e) { setForm(function (f) { return Object.assign({}, f, { phone: e.target.value }); }); } })) ) ) ) ), React.createElement(Modal, { title: '确认删除', open: deleteModal.open, centered: true, onCancel: function () { setDeleteModal({ open: false, record: null }); }, onOk: function () { if (deleteModal.record) { setListData(function (prev) { return prev.filter(function (r) { return r.id !== deleteModal.record.id; }); }); message.success('已删除'); } setDeleteModal({ open: false, record: null }); }, okButtonProps: { danger: true }, okText: '删除', cancelText: '取消' }, '确定删除站点「' + ((deleteModal.record && deleteModal.record.name) || '') + '」吗?此操作不可撤销。'), React.createElement(Modal, { className: 'h2-prd-modal', title: React.createElement('span', { style: { fontWeight: 700 } }, '需求说明 · 站点信息'), open: requirementModalOpen, onCancel: function () { setRequirementModalOpen(false); }, width: 640, centered: true, footer: React.createElement(Button, { onClick: function () { setRequirementModalOpen(false); }, style: { borderRadius: 8 } }, '关闭') }, React.createElement('div', { className: 'h2-prd-content' }, getH2StationRequirementDoc())), React.createElement(Modal, { title: '批量导入加氢站点', open: importModalOpen, onCancel: closeImportModal, width: 560, centered: true, destroyOnClose: true, okText: '确认导入', cancelText: '取消', okButtonProps: { disabled: !importPreview || !importPreview.valid.length, style: H2_PRIMARY_BTN_STYLE }, onOk: handleConfirmImport }, React.createElement('div', { className: 'h2-import-template-bar' }, React.createElement('div', { className: 'h2-import-template-bar-text' }, React.createElement('div', { style: { fontWeight: 700, marginBottom: 4, color: '#0f172a' } }, '第一步:下载 CSV 导入模板'), '模板含加氢站名称、省、市、详细地址、是否签约、签约起止时间、营业状态、营业时间、联系人、联系电话;与新建表单字段一致。' ), React.createElement(Button, { type: 'primary', ghost: true, style: { borderColor: '#10b981', color: '#059669', fontWeight: 600, flexShrink: 0, borderRadius: 8 }, onClick: downloadImportTemplate }, '下载模板') ), React.createElement(Alert, { type: 'info', showIcon: true, style: { marginBottom: 14, borderRadius: 10 }, message: '第二步:填写模板后上传文件', description: '支持 .csv(推荐)、.xlsx、.xls;原型阶段 Excel 请另存为 CSV UTF-8 后上传。上传后系统将校验并预览可导入条数。' }), React.createElement(Upload.Dragger, { accept: '.csv,.xlsx,.xls', multiple: false, maxCount: 1, fileList: importFileList, beforeUpload: function (file) { parseImportFile(file); return false; }, onRemove: function () { setImportFileList([]); setImportPreview(null); return true; } }, React.createElement('p', { style: { margin: '8px 0 4px', fontWeight: 600, color: '#334155' } }, '点击或拖拽文件到此处上传'), React.createElement('p', { style: { margin: 0, fontSize: 12, color: '#94a3b8' } }, '单次上传一个文件') ), importPreview ? React.createElement('div', { className: 'h2-import-preview' }, React.createElement('div', { style: { fontWeight: 700, marginBottom: 6 } }, '解析结果 · ' + (importPreview.fileName || '')), React.createElement('div', null, React.createElement('span', { style: { color: '#059669', fontWeight: 600 } }, '可导入 ' + importPreview.valid.length + ' 条'), importPreview.errors.length ? React.createElement('span', { style: { marginLeft: 12, color: '#dc2626', fontWeight: 600 } }, '失败 ' + importPreview.errors.length + ' 条') : null ), importPreview.errors.length ? React.createElement('ul', { className: 'h2-import-error-list' }, importPreview.errors.slice(0, 8).map(function (err, ei) { return React.createElement('li', { key: ei }, '第 ' + err.lineNo + ' 行「' + err.name + '」:' + err.reasons.join(';') ); }).concat( importPreview.errors.length > 8 ? [React.createElement('li', { key: 'more' }, '… 另有 ' + (importPreview.errors.length - 8) + ' 条错误未展示')] : [] ) ) : null ) : null ), React.createElement(Modal, { title: '营业状态', open: businessModal.open, onCancel: closeBusinessModal, onOk: handleSaveBusinessSetting, okText: '保存', cancelText: '取消', centered: true, width: 680, destroyOnClose: true, okButtonProps: { style: H2_PRIMARY_BTN_STYLE } }, React.createElement('div', { style: { marginBottom: 12, fontSize: 13, color: '#64748b' } }, '站点:', React.createElement('strong', { style: { color: '#0f172a' } }, (businessModal.record && businessModal.record.name) || '—') ), formItem('营业状态', true, React.createElement(Select, { style: { width: '100%' }, value: businessModal.businessStatus, options: H2_BUSINESS_STATUS_OPTIONS, onChange: function (v) { setBusinessModal(function (m) { return Object.assign({}, m, { businessStatus: v }); }); }, dropdownStyle: { borderRadius: 8 } })), formItem('营业时间', false, React.createElement(BusinessHoursInput, { value: businessModal.businessHours, fieldStyle: { width: '100%', borderRadius: 8 }, onChange: function (v) { setBusinessModal(function (m) { return Object.assign({}, m, { businessHours: v }); }); } }), '暂停或停止营业时可将类型改为非全天并清空时间'), React.createElement('div', { className: 'h2-status-log-section' }, React.createElement('div', { className: 'h2-status-log-title' }, '营业状态变更记录'), React.createElement(Table, { className: 'h2-status-log-table', size: 'small', rowKey: 'id', columns: businessStatusLogColumns, dataSource: businessModal.statusLogs || [], pagination: (businessModal.statusLogs || []).length > 5 ? { pageSize: 5, size: 'small' } : false, locale: { emptyText: '暂无状态变更记录' }, scroll: { x: 520 } }) ) ), React.createElement(Modal, { title: '加氢记录' + (refuelModal.station && refuelModal.station.name ? ' · ' + refuelModal.station.name : ''), open: refuelModal.open, onCancel: closeRefuelModal, footer: React.createElement(Button, { onClick: closeRefuelModal, style: { borderRadius: 8 } }, '关闭'), width: 960, centered: true, destroyOnClose: true, styles: { body: { maxHeight: '72vh', overflow: 'auto', paddingTop: 8 } } }, renderRefuelTotalsBar(refuelModalSummary), React.createElement(Table, { className: 'h2-refuel-record-table', size: 'small', bordered: true, rowKey: 'id', columns: refuelRecordColumns, dataSource: refuelModal.records || [], pagination: (refuelModal.records || []).length > 8 ? { pageSize: 8, showSizeChanger: false, size: 'small' } : false, locale: { emptyText: '暂无加氢记录' }, scroll: { x: 'max-content', y: 360 } }) ), React.createElement(Modal, { title: '余额变更明细' + (prepaidBalanceDrill.stationName ? ' · ' + prepaidBalanceDrill.stationName : ''), open: prepaidBalanceDrill.open, onCancel: closePrepaidBalanceDrill, footer: React.createElement(Button, { onClick: closePrepaidBalanceDrill, style: { borderRadius: 8 } }, '关闭'), width: 880, centered: true, destroyOnClose: true, styles: { body: { maxHeight: '72vh', overflow: 'auto', paddingTop: 8 } } }, React.createElement(Table, { className: 'h2-balance-record-table', size: 'small', bordered: true, rowKey: 'key', columns: prepaidBalanceDrillColumns, dataSource: prepaidBalanceDrill.rows || [], pagination: (prepaidBalanceDrill.rows || []).length > 10 ? { pageSize: 10, showSizeChanger: false, size: 'small' } : false, summary: renderPrepaidBalanceDrillSummary, locale: { emptyText: '暂无余额变更记录' }, scroll: { x: 'max-content' } }) ), React.createElement(Modal, { title: '生成对账单', open: statementModal.open, onCancel: closeStatementModal, onOk: handleGenerateStatement, okText: '生成对账单', cancelText: '取消', centered: true, width: 520, destroyOnClose: true, okButtonProps: { style: H2_PRIMARY_BTN_STYLE } }, React.createElement('div', { style: { marginBottom: 12, fontSize: 13, color: '#64748b' } }, '站点:', React.createElement('strong', { style: { color: '#0f172a' } }, (statementModal.record && statementModal.record.name) || '—') ), React.createElement(Alert, { type: 'info', showIcon: true, style: { marginBottom: 14, borderRadius: 10 }, message: '按周期汇总站点加氢明细,生成氢费对账单(对站)', description: '对账单将汇总该周期内加氢量、成本总价等,提交后可进入审批流程(原型演示)。' }), formItem('对账周期', true, React.createElement(Input, { type: 'month', style: { width: '100%', borderRadius: 8 }, value: statementModal.period || '', onChange: function (e) { setStatementModal(function (m) { return Object.assign({}, m, { period: e.target.value }); }); } })), statementModal.record ? React.createElement('div', { style: { fontSize: 12, color: '#64748b', lineHeight: 1.6 } }, '当前预付余额:', renderPrepaidBalance(statementModal.record.prepaidBalance), ';本站点累计加氢 ', React.createElement('strong', { style: { color: '#0f172a' } }, String(statementModal.record.refuelCount != null ? statementModal.record.refuelCount : h2CalcRefuelStats(statementModal.record.name).count)), ' 次' ) : null ), React.createElement(Modal, { title: '价格配置', open: priceModal.open, onCancel: closePriceModal, onOk: handleSavePriceConfig, okText: '保存', cancelText: '取消', centered: true, width: 480, destroyOnClose: true, okButtonProps: { style: H2_PRIMARY_BTN_STYLE } }, React.createElement('div', { style: { marginBottom: 12, fontSize: 13, color: '#64748b' } }, '站点:', React.createElement('strong', { style: { color: '#0f172a' } }, (priceModal.record && priceModal.record.name) || '—') ), formItem('成本单价(元/kg)', false, React.createElement(Input, { value: priceModal.costUnitPrice, placeholder: '请输入成本单价', style: { borderRadius: 8 }, onChange: function (e) { setPriceModal(function (m) { return Object.assign({}, m, { costUnitPrice: e.target.value }); }); } })), formItem('对客单价(元/kg)', false, React.createElement(Input, { value: priceModal.customerUnitPrice, placeholder: '请输入对客单价', style: { borderRadius: 8 }, onChange: function (e) { setPriceModal(function (m) { return Object.assign({}, m, { customerUnitPrice: e.target.value }); }); } }), '用于加氢订单结算参考,联调后对接价格体系') ) ); }; if (typeof window !== 'undefined') window.Component = Component;