diff --git a/backend/app/api/pl/vehicle_recharge.py b/backend/app/api/pl/vehicle_recharge.py index 82cb7d5e6..9c2d962b4 100644 --- a/backend/app/api/pl/vehicle_recharge.py +++ b/backend/app/api/pl/vehicle_recharge.py @@ -36,7 +36,7 @@ from app.services import pl_vehicle_recharge_summary_service as summary_svc apply_router = APIRouter(prefix="/vehicle-recharge-apply", tags=["运输计划-ETC油卡申请"]) record_router = APIRouter(prefix="/vehicle-recharge-record", tags=["运输计划-ETC油卡发放"]) -RECHARGE_TYPE_LABELS = {"etc": "ETC", "fuel": "油卡", "shanxia": "山峡"} +RECHARGE_TYPE_LABELS = {"etc": "ETC", "fuel": "油卡", "shanxia": "山峡", "bailian": "百链"} RECHARGE_APPLY_STATUS_LABELS = { "draft": "草稿", "pending": "待发放", diff --git a/backend/app/models/pl_models.py b/backend/app/models/pl_models.py index a5531f2ed..6f05ca0e8 100644 --- a/backend/app/models/pl_models.py +++ b/backend/app/models/pl_models.py @@ -1352,7 +1352,7 @@ class PlVehicleRechargeApply(Base): id = Column(String(64), primary_key=True, comment="主键ID") apply_no = Column(String(32), nullable=False, unique=True, comment="申请单号") license_plate = Column(String(20), nullable=False, comment="车牌号") - recharge_type = Column(String(20), nullable=False, comment="充值类型 etc/fuel/shanxia") + recharge_type = Column(String(20), nullable=False, comment="充值类型 etc/fuel/shanxia/bailian") apply_date = Column(Date, nullable=False, comment="申请日期") odometer_km = Column(DECIMAL(10, 1), nullable=True, comment="期初公里数") attachment_urls = Column(String(2000), nullable=True, comment="附件URL") diff --git a/backend/app/schemas/pl/vehicle_recharge.py b/backend/app/schemas/pl/vehicle_recharge.py index 1cfc2c795..c96f2d400 100644 --- a/backend/app/schemas/pl/vehicle_recharge.py +++ b/backend/app/schemas/pl/vehicle_recharge.py @@ -5,7 +5,7 @@ from typing import List, Optional from pydantic import BaseModel, Field, field_validator -RECHARGE_TYPES = {"etc", "fuel", "shanxia"} +RECHARGE_TYPES = {"etc", "fuel", "shanxia", "bailian"} APPLY_STATUSES = {"draft", "in_approval", "rejected", "disbursed", "cancelled"} NODE_ACTION_TYPES = {"approve", "disburse"} APPROVAL_STATUSES = {"approved", "rejected", "disbursed"} @@ -26,7 +26,7 @@ class VehicleRechargeApplyCreate(BaseModel): @classmethod def validate_recharge_type(cls, v: str) -> str: if v not in RECHARGE_TYPES: - raise ValueError("充值类型须为 ETC、油卡或山峡") + raise ValueError("充值类型须为 ETC、油卡、山峡或百链") return v @field_validator("odometer_km") @@ -181,7 +181,7 @@ class VehicleRechargeRecordCreate(BaseModel): @classmethod def validate_recharge_type(cls, v: str) -> str: if v not in RECHARGE_TYPES: - raise ValueError("充值类型须为 ETC、油卡或山峡") + raise ValueError("充值类型须为 ETC、油卡、山峡或百链") return v @field_validator("amount") diff --git a/backend/app/services/pl_vehicle_recharge_service.py b/backend/app/services/pl_vehicle_recharge_service.py index 2510fdecc..bca94e4c6 100644 --- a/backend/app/services/pl_vehicle_recharge_service.py +++ b/backend/app/services/pl_vehicle_recharge_service.py @@ -41,6 +41,7 @@ from app.services.pl_vehicle_mine_vehicles import ( _EDITABLE_STATUSES = frozenset({"draft", "rejected"}) _BIZ_TYPE_VEHICLE_RECHARGE = "vehicle_recharge" +_APPLY_NO_PREFIX = {"etc": "ETC", "fuel": "YK", "shanxia": "SX", "bailian": "BL"} def _generate_seq_no( @@ -57,12 +58,15 @@ def _generate_seq_no( return f"{prefix}{seq:0{seq_width}d}" -def generate_apply_no(db: Session) -> str: +def generate_apply_no(db: Session, recharge_type: str) -> str: + prefix = _APPLY_NO_PREFIX.get(recharge_type) + if not prefix: + raise ValueError(f"未知充值类型: {recharge_type}") return _generate_seq_no( db, PlVehicleRechargeApply, "apply_no", - f"ETC{date.today():%Y%m%d}", + f"{prefix}{date.today():%Y%m%d}", seq_width=2, ) @@ -647,7 +651,7 @@ def create_apply( now = datetime.now() row = PlVehicleRechargeApply( id=generate_uuid(), - apply_no=generate_apply_no(db), + apply_no=generate_apply_no(db, payload.recharge_type), license_plate=license_plate, recharge_type=payload.recharge_type, apply_date=payload.apply_date, diff --git a/backend/tests/test_pl_vehicle_recharge_workflow.py b/backend/tests/test_pl_vehicle_recharge_workflow.py index ad3788c70..54879fee7 100644 --- a/backend/tests/test_pl_vehicle_recharge_workflow.py +++ b/backend/tests/test_pl_vehicle_recharge_workflow.py @@ -110,7 +110,45 @@ def _patch_scope(monkeypatch, *modules) -> None: ) -@pytest.mark.parametrize("recharge_type", ["etc", "fuel", "shanxia"]) +@pytest.mark.parametrize( + "recharge_type,prefix", + [("etc", "ETC"), ("fuel", "YK"), ("shanxia", "SX"), ("bailian", "BL")], +) +def test_apply_no_prefix_follows_recharge_type(recharge_type, prefix): + from app.services.pl_vehicle_recharge_service import generate_apply_no + + db = _make_session() + day = date.today().strftime("%Y%m%d") + assert generate_apply_no(db, recharge_type) == f"{prefix}{day}01" + + +def test_apply_no_sequences_are_independent_per_type(): + from app.services.pl_vehicle_recharge_service import generate_apply_no + + db = _make_session() + day = date.today().strftime("%Y%m%d") + db.add( + PlVehicleRechargeApply( + id="apply-etc-1", + apply_no=f"ETC{day}01", + license_plate="鄂A00001", + recharge_type="etc", + apply_date=date.today(), + applicant_id="u-applicant", + status="draft", + tenant_no="t1", + create_dept_id="d1", + ) + ) + db.commit() + + assert generate_apply_no(db, "etc") == f"ETC{day}02" + assert generate_apply_no(db, "fuel") == f"YK{day}01" + assert generate_apply_no(db, "shanxia") == f"SX{day}01" + assert generate_apply_no(db, "bailian") == f"BL{day}01" + + +@pytest.mark.parametrize("recharge_type", ["etc", "fuel", "shanxia", "bailian"]) def test_submit_sets_in_approval_and_first_node(monkeypatch, recharge_type): from app.services import pl_vehicle_recharge_service as svc from app.schemas.pl.vehicle_recharge import VehicleRechargeApplyCreate @@ -136,6 +174,8 @@ def test_submit_sets_in_approval_and_first_node(monkeypatch, recharge_type): ), ) assert created.recharge_type == recharge_type + prefix = {"etc": "ETC", "fuel": "YK", "shanxia": "SX", "bailian": "BL"}[recharge_type] + assert created.apply_no.startswith(f"{prefix}{date.today():%Y%m%d}") assert created.status == "draft" assert created.approval_round == 0 @@ -280,7 +320,7 @@ def test_reject_sets_rejected_and_appends_history(monkeypatch): assert result.approvals[-1].approval_status == "rejected" -@pytest.mark.parametrize("recharge_type", ["etc", "fuel", "shanxia"]) +@pytest.mark.parametrize("recharge_type", ["etc", "fuel", "shanxia", "bailian"]) def test_disburse_writes_record_and_disbursed(monkeypatch, recharge_type): from app.services import pl_vehicle_recharge_approval_service as approval_svc from app.services import pl_vehicle_recharge_service as svc diff --git a/backend/tests/test_vehicle_recharge_types.py b/backend/tests/test_vehicle_recharge_types.py index 3436007e6..b14eb246f 100644 --- a/backend/tests/test_vehicle_recharge_types.py +++ b/backend/tests/test_vehicle_recharge_types.py @@ -14,11 +14,11 @@ from app.schemas.pl.vehicle_recharge import ( def test_recharge_types_include_all_supported_types(): - assert RECHARGE_TYPES == {"etc", "fuel", "shanxia"} + assert RECHARGE_TYPES == {"etc", "fuel", "shanxia", "bailian"} @pytest.mark.parametrize("schema", [VehicleRechargeApplyCreate, VehicleRechargeApplyUpdate]) -@pytest.mark.parametrize("recharge_type", ["etc", "fuel", "shanxia"]) +@pytest.mark.parametrize("recharge_type", ["etc", "fuel", "shanxia", "bailian"]) def test_apply_accepts_supported_types(schema, recharge_type): obj = schema.model_validate({ "licensePlate": "鄂A12345", @@ -50,7 +50,7 @@ def test_recharge_rejects_unknown_type(schema): @pytest.mark.parametrize("schema", [VehicleRechargeRecordCreate, VehicleRechargeRecordUpdate]) -@pytest.mark.parametrize("recharge_type", ["etc", "fuel", "shanxia"]) +@pytest.mark.parametrize("recharge_type", ["etc", "fuel", "shanxia", "bailian"]) def test_record_accepts_supported_types(schema, recharge_type): obj = schema.model_validate({ "rechargeDate": "2026-10-25", @@ -62,7 +62,7 @@ def test_record_accepts_supported_types(schema, recharge_type): @pytest.mark.parametrize("recharge_type,label", [ - ("etc", "ETC"), ("fuel", "油卡"), ("shanxia", "山峡"), + ("etc", "ETC"), ("fuel", "油卡"), ("shanxia", "山峡"), ("bailian", "百链"), ]) def test_export_recharge_type_labels(recharge_type, label): from app.api.pl.vehicle_recharge import RECHARGE_TYPE_LABELS diff --git a/docs/sql/migrations/2026-11-07-pl-vehicle-recharge-apply-no-prefix.sql b/docs/sql/migrations/2026-11-07-pl-vehicle-recharge-apply-no-prefix.sql new file mode 100644 index 000000000..8cf002716 --- /dev/null +++ b/docs/sql/migrations/2026-11-07-pl-vehicle-recharge-apply-no-prefix.sql @@ -0,0 +1,14 @@ +-- ETC/油卡充值申请单号按充值类型校正前缀。 +-- etc 保持 ETC;fuel 开头的 ETC 改为 YK;shanxia 开头的 ETC 改为 SX。 +-- 只替换前三个字符,日期和两位序号不变。已是目标前缀的记录不改。 +-- 含软删除行,避免唯一索引下恢复后仍显示旧前缀。可重复执行。 + +UPDATE `pl_vehicle_recharge_apply` +SET `apply_no` = CONCAT('YK', SUBSTRING(`apply_no`, 4)) +WHERE `recharge_type` = 'fuel' + AND `apply_no` LIKE 'ETC%'; + +UPDATE `pl_vehicle_recharge_apply` +SET `apply_no` = CONCAT('SX', SUBSTRING(`apply_no`, 4)) +WHERE `recharge_type` = 'shanxia' + AND `apply_no` LIKE 'ETC%'; diff --git a/docs/sql/migrations/2026-11-07-pl-vehicle-recharge-bailian.sql b/docs/sql/migrations/2026-11-07-pl-vehicle-recharge-bailian.sql new file mode 100644 index 000000000..ec4f1c2ac --- /dev/null +++ b/docs/sql/migrations/2026-11-07-pl-vehicle-recharge-bailian.sql @@ -0,0 +1,25 @@ +-- 充值类型新增「百链」;现有 recharge_type VARCHAR(20) 可直接存储 bailian。 +-- 按已有充值类型字典的租户补充选项,可重复执行,不修改历史充值记录。 +SET NAMES utf8mb4; + +UPDATE `sys_dict_data` AS d +INNER JOIN `sys_dict_type` AS t + ON t.`tenant_no` = d.`tenant_no` AND t.`dict_type` = d.`dict_type` +SET d.`dict_label` = '百链', d.`tag_type` = 'info', + d.`del_flag` = 0, d.`update_by` = 'system', d.`update_time` = NOW() +WHERE t.`dict_type` = 'pl_recharge_type' AND t.`del_flag` = 0 + AND d.`dict_value` = 'bailian'; + +INSERT INTO `sys_dict_data` + (`id`, `dict_label`, `dict_value`, `tag_type`, `dict_type`, `tenant_no`, + `order_num`, `remark`, `create_by`, `create_dept_id`, `create_time`, + `update_by`, `update_time`, `del_flag`) +SELECT UUID(), '百链', 'bailian', 'info', 'pl_recharge_type', t.`tenant_no`, + 4, NULL, 'system', '', NOW(), 'system', NOW(), 0 +FROM (SELECT DISTINCT `tenant_no` FROM `sys_dict_type` + WHERE `dict_type` = 'pl_recharge_type' AND `del_flag` = 0) AS t +WHERE NOT EXISTS ( + SELECT 1 FROM `sys_dict_data` AS d + WHERE d.`tenant_no` = t.`tenant_no` + AND d.`dict_type` = 'pl_recharge_type' AND d.`dict_value` = 'bailian' +); diff --git a/miniprogram/pages/pl/vehicle-recharge-apply/form.vue b/miniprogram/pages/pl/vehicle-recharge-apply/form.vue index fe1233523..963e38a72 100644 --- a/miniprogram/pages/pl/vehicle-recharge-apply/form.vue +++ b/miniprogram/pages/pl/vehicle-recharge-apply/form.vue @@ -296,7 +296,8 @@ const MAX_ATTACHMENTS = 5 const typeOptions = [ { label: 'ETC', value: 'etc' }, { label: '油卡', value: 'fuel' }, - { label: '山峡', value: 'shanxia' } + { label: '山峡', value: 'shanxia' }, + { label: '百链', value: 'bailian' } ] const editId = ref('') diff --git a/miniprogram/pages/pl/vehicle-recharge-apply/list.vue b/miniprogram/pages/pl/vehicle-recharge-apply/list.vue index 470d70400..f3b56dab4 100644 --- a/miniprogram/pages/pl/vehicle-recharge-apply/list.vue +++ b/miniprogram/pages/pl/vehicle-recharge-apply/list.vue @@ -171,6 +171,7 @@ function typeLabel(v) { if (v === 'etc') return 'ETC' if (v === 'fuel') return '油卡' if (v === 'shanxia') return '山峡' + if (v === 'bailian') return '百链' return v || '—' } diff --git a/miniprogram/utils/plVehicleRechargeCopy.js b/miniprogram/utils/plVehicleRechargeCopy.js index 5e65a6569..5c072bb3a 100644 --- a/miniprogram/utils/plVehicleRechargeCopy.js +++ b/miniprogram/utils/plVehicleRechargeCopy.js @@ -7,7 +7,8 @@ import { countPlAttachmentUrls } from '@/utils/plFuelRegisterCopy' const TYPE_LABELS = { etc: 'ETC', fuel: '油卡', - shanxia: '山峡' + shanxia: '山峡', + bailian: '百链' } export function getPlRechargeTypeLabel(type) { diff --git a/web-admin/scripts/pl-child-identity.test.ts b/web-admin/scripts/pl-child-identity.test.ts index 36dd7ba2c..0562aa5c7 100644 --- a/web-admin/scripts/pl-child-identity.test.ts +++ b/web-admin/scripts/pl-child-identity.test.ts @@ -6,7 +6,9 @@ import { buildStopProductPayload, syncDeliveriesProductsFromLoad, createEmptyDeliveryForm, - mergePlanProductsFromLoadMirror + mergePlanProductsFromLoadMirror, + mapLoadProductsToPlanFormRows, + shouldRetainPlanProductsWhileLoadEmpty } from '../src/utils/pl-plan-stop-form' const product = { @@ -35,6 +37,34 @@ test('refreshing delivery products retains that delivery identity', () => { assert.equal(result.deliveries[0].products[0].id, 'delivery-product') }) +test('clearing load products keeps the plan product until the same product is selected again', () => { + const previous = [ + { + id: 'pp', + productId: 'sku', + packageSpec: '槽罐车', + quantity: 33, + deliveryMethod: '一票制送到', + productName: '32%液碱' + } + ] + assert.equal(shouldRetainPlanProductsWhileLoadEmpty([], previous), true) + assert.equal(shouldRetainPlanProductsWhileLoadEmpty([], []), false) + const reselected = mapLoadProductsToPlanFormRows([ + { + productId: 'sku', + productName: '32%液碱', + packageSpec: '槽罐车', + planQty: 33, + deliveryMethod: '自提' + } + ]) + const merged = mergePlanProductsFromLoadMirror(reselected, previous) + assert.equal(merged[0].id, 'pp') + assert.equal(merged[0].deliveryMethod, '自提') + assert.equal(merged.length, 1) +}) + test('desktop mirror consumes previous product identities once for repeated SKUs', () => { const before = [ { ...product, id: 'first', quantity: 1 }, diff --git a/web-admin/src/api/pl/index.ts b/web-admin/src/api/pl/index.ts index 91af3f4cd..dc5180ed7 100644 --- a/web-admin/src/api/pl/index.ts +++ b/web-admin/src/api/pl/index.ts @@ -1798,7 +1798,7 @@ export interface VehicleRechargeApply { applyNo: string licensePlate: string boundFuelCardNo?: string | null - rechargeType: 'etc' | 'fuel' | 'shanxia' + rechargeType: 'etc' | 'fuel' | 'shanxia' | 'bailian' applyDate: string odometerKm?: number | null attachmentUrls?: string @@ -1830,14 +1830,14 @@ export interface VehicleRechargeApplyOption { id: string applyNo: string licensePlate: string - rechargeType: 'etc' | 'fuel' | 'shanxia' + rechargeType: 'etc' | 'fuel' | 'shanxia' | 'bailian' } export interface VehicleRechargeRecord { id: string rechargeOrderNo: string rechargeDate: string - rechargeType: 'etc' | 'fuel' | 'shanxia' + rechargeType: 'etc' | 'fuel' | 'shanxia' | 'bailian' cardNo?: string gasStation?: string amount: number @@ -1864,7 +1864,7 @@ export interface VehicleRechargeDisburseBoardItem { applyNo: string licensePlate: string boundFuelCardNo?: string | null - rechargeType: 'etc' | 'fuel' | 'shanxia' + rechargeType: 'etc' | 'fuel' | 'shanxia' | 'bailian' applyDate: string odometerKm?: number | null applicantName?: string diff --git a/web-admin/src/components/business/pl-plan-form-dialog/index.vue b/web-admin/src/components/business/pl-plan-form-dialog/index.vue index 2e6be810a..79cbc0ca2 100644 --- a/web-admin/src/components/business/pl-plan-form-dialog/index.vue +++ b/web-admin/src/components/business/pl-plan-form-dialog/index.vue @@ -712,6 +712,7 @@ enrichStopProductsDisplayFromPlan, mapLoadProductsToPlanFormRows, mergePlanProductsFromLoadMirror, + shouldRetainPlanProductsWhileLoadEmpty, resolveStopDibangDefaults, sumStopProductsPlanQty, type PlanDeliveryForm, @@ -1460,6 +1461,7 @@ /** 装货产品变更后:仅镜像计划层产品(不再同步到送货段) */ function syncFromLoadProducts() { if (suppressStopProductSync.value || detailLoading.value) return + if (shouldRetainPlanProductsWhileLoadEmpty(loadForm.value.products || [], formData.products)) return mirrorPlanProductsFromLoad() } diff --git a/web-admin/src/utils/pl-display.ts b/web-admin/src/utils/pl-display.ts index 371ee14cc..a78e45ac1 100644 --- a/web-admin/src/utils/pl-display.ts +++ b/web-admin/src/utils/pl-display.ts @@ -551,7 +551,7 @@ export function parsePlFeedbackImages(raw?: string | string[] | null): string[] } export function getPlRechargeTypeLabel(type: string) { - const labels: Record = { etc: 'ETC', fuel: '油卡', shanxia: '山峡' } + const labels: Record = { etc: 'ETC', fuel: '油卡', shanxia: '山峡', bailian: '百链' } return labels[type] || type } diff --git a/web-admin/src/utils/pl-plan-stop-form.ts b/web-admin/src/utils/pl-plan-stop-form.ts index e58c10b54..7913ea4e0 100644 --- a/web-admin/src/utils/pl-plan-stop-form.ts +++ b/web-admin/src/utils/pl-plan-stop-form.ts @@ -768,6 +768,17 @@ export function mapLoadProductsToPlanFormRows( })) } +/** + * 更换装货客户会先清空装货产品。这段空窗不要抹掉已有计划产品, + * 重新选回同一产品和包装时才能继承原 id。正式保存仍按当前装货产品镜像。 + */ +export function shouldRetainPlanProductsWhileLoadEmpty( + loadProducts: Array, + previous: Array +): boolean { + return loadProducts.length === 0 && previous.length > 0 +} + /** 合并装货映射行与既有计划产品元数据(危化证、税额等) */ export function mergePlanProductsFromLoadMirror( fromLoad: PlanFormProductRow[], diff --git a/web-admin/src/views/m/pl/plan-cert/ArchiveTab.vue b/web-admin/src/views/m/pl/plan-cert/ArchiveTab.vue index 3d40368d3..fd73f68cb 100644 --- a/web-admin/src/views/m/pl/plan-cert/ArchiveTab.vue +++ b/web-admin/src/views/m/pl/plan-cert/ArchiveTab.vue @@ -14,30 +14,49 @@
{{ row.certNo }}
-
{{ row.certType === 'transport' ? '运输证' : '购买证' }}
+
{{ + row.certType === 'transport' ? '运输证' : '购买证' + }}
- {{ statusLabel(row.status) }} + {{ + statusLabel(row.status) + }}
-
-
销售单位{{ salePartyName(row) || '—' }}
-
购买单位{{ buyPartyName(row) || '—' }}
-
有效次数{{ row.validUseText || '—' }}
+
+
销售单位{{ salePartyName(row) || '—' }}
+
购买单位{{ buyPartyName(row) || '—' }}
+
有效次数{{ row.validUseText || '—' }}
是否预警 - {{ warningText(row) }} + {{ + warningText(row) + }} —
-
品名{{ row.productNameOnCert || '—' }}
+
品名{{ row.productNameOnCert || '—' }}
数量{{ qty(row.totalQty) }} {{ unit(row.quantityUnit) }}
可用余额{{ qty(row.availableQty) }} {{ unit(row.quantityUnit) }}
+
上传时间{{ uploadTime(row.createTime) }}
- + - +
- +
@@ -82,6 +105,7 @@ import { quotaCertApi, type CertType, type QuotaCert } from '@/api/pl/quota-cert' import ArchiveForm from './archive-form.vue' import CertConfirmSheet from './CertConfirmSheet.vue' + import { formatDateTime } from '@/utils/format' import { formatCertQty } from '@/views/pl/quota-cert/model' import { buyPartyName, expiryWarning, salePartyName } from '@/views/pl/quota-cert/cert-list-face' import { useDictStore } from '@/store/modules/dict' @@ -115,7 +139,9 @@ return !props.expiringSoon || Boolean(expiryWarning(row.validTo)) }) ) - const expiringCount = computed(() => rows.value.filter((row) => expiryWarning(row.validTo)).length) + const expiringCount = computed( + () => rows.value.filter((row) => expiryWarning(row.validTo)).length + ) watch(expiringCount, (count) => emit('expiring-count', count), { immediate: true }) let epoch = 0 @@ -134,6 +160,9 @@ function qty(value: unknown) { return formatCertQty(value) } + function uploadTime(value?: string | null) { + return formatDateTime(value) || '—' + } function unit(value?: string | null) { const label = getProductUnitLabel(useDictStore().getLabel, value) return !label || label === '—' ? '' : label diff --git a/web-admin/src/views/pl/quota-cert/index.vue b/web-admin/src/views/pl/quota-cert/index.vue index d7cf66f01..a18465f37 100644 --- a/web-admin/src/views/pl/quota-cert/index.vue +++ b/web-admin/src/views/pl/quota-cert/index.vue @@ -9,8 +9,12 @@ v-model="keyword" placeholder="编号" @search="search" - @clear="search" />共 {{ filteredRows.length }} 张新增证件

已有车号不能删除,只能追加。保存后证件仍可安排运输。 @@ -397,49 +409,51 @@ type="danger" title="移除引用" aria-label="移除引用" - :disabled="saving || form.referencesEditable === false || referenceRowLocked(row)" + :disabled=" + saving || form.referencesEditable === false || referenceRowLocked(row) + " @click="removeReference(index)" >

- - - + + + + + + - - - - - - - - - - + + + + + +
@@ -595,18 +609,11 @@ import QuotaHistoryDialog from './QuotaHistoryDialog.vue' const historyDialog = ref>() - import { - Check, - Close, - Connection, - Delete, - Document, - Edit, - Plus - } from '@element-plus/icons-vue' + import { Check, Close, Connection, Delete, Document, Edit, Plus } from '@element-plus/icons-vue' import { useUserStore } from '@/store/modules/user' import { useDictStore } from '@/store/modules/dict' import { getProductUnitLabel } from '@/utils/crm-product-display' + import { formatDateTime } from '@/utils/format' import { randomOperationId } from '@/utils/random-id' import { fetchGetMenuCodes } from '@/api/auth' import { @@ -1131,9 +1138,7 @@ return row?.certType === 'transport' || row?.certType === 'purchase' ? row.certType : kind.value } function plateList(value: unknown) { - return Array.isArray(value) - ? value.map((item) => String(item).trim()).filter(Boolean) - : [] + return Array.isArray(value) ? value.map((item) => String(item).trim()).filter(Boolean) : [] } function plateLocked(plate: string) { return lockedPlates.value.includes(plate) @@ -1529,7 +1534,9 @@ form.value.contractBindings = next } function referenceRowLocked(row: { id?: string; purchaseCertId?: string | null }) { - return form.value.referencesEditable === false && !!row.id && linkedRefIds.value.includes(row.id) + return ( + form.value.referencesEditable === false && !!row.id && linkedRefIds.value.includes(row.id) + ) } function onPurchaseArchiveChange() { edited.add('purchaseRefs') @@ -1678,10 +1685,17 @@ enumOptions: Object.entries(statusLabels).map(([value, label]) => ({ value, label })) }, ...qtyColumns.map((c) => ({ prop: c.key, label: c.label, type: 'number' as const })), - { prop: 'validTo', label: '有效期限止', type: 'datetime' } + { prop: 'validTo', label: '有效期限止', type: 'datetime' }, + { + prop: 'createTime', + label: '上传时间', + type: 'datetime' as const, + getValue: (row: { createTime?: string | null }) => + String(row.createTime || '').replace('T', ' ') + } ] const { visibleColumns, checkAll, isIndeterminate, resetToDefault } = usePersistedListColumns( - 'pl-quota-cert-columns-v3', + 'pl-quota-cert-columns-v4', listColumnDefs ) const visibleDefs = computed(() => @@ -1704,7 +1718,9 @@ () => columnRows.value.filter((row) => expiryWarning(row.validTo)).length ) const filteredRows = computed(() => - expiringSoon.value ? columnRows.value.filter((row) => expiryWarning(row.validTo)) : columnRows.value + expiringSoon.value + ? columnRows.value.filter((row) => expiryWarning(row.validTo)) + : columnRows.value ) const pageRows = computed(() => filteredRows.value.slice((page.value - 1) * 20, page.value * 20)) function search() { diff --git a/web-admin/src/views/pl/vehicle-recharge-apply/columnFilterDefs.ts b/web-admin/src/views/pl/vehicle-recharge-apply/columnFilterDefs.ts index 66425ab73..cc66cd742 100644 --- a/web-admin/src/views/pl/vehicle-recharge-apply/columnFilterDefs.ts +++ b/web-admin/src/views/pl/vehicle-recharge-apply/columnFilterDefs.ts @@ -3,7 +3,8 @@ import type { ColumnFilterDef } from '@/composables/useClientColumnFilters' const RECHARGE_TYPE_OPTIONS = [ { value: 'etc', label: 'ETC' }, { value: 'fuel', label: '油卡' }, - { value: 'shanxia', label: '山峡' } + { value: 'shanxia', label: '山峡' }, + { value: 'bailian', label: '百链' } ] const RECHARGE_STATUS_OPTIONS = [ diff --git a/web-admin/src/views/pl/vehicle-recharge-apply/index.vue b/web-admin/src/views/pl/vehicle-recharge-apply/index.vue index ebaae7901..7788b9843 100644 --- a/web-admin/src/views/pl/vehicle-recharge-apply/index.vue +++ b/web-admin/src/views/pl/vehicle-recharge-apply/index.vue @@ -372,6 +372,7 @@ + @@ -767,7 +768,7 @@ const formData = reactive({ applyNo: '', applicantId: '', licensePlate: '', - rechargeType: 'etc' as 'etc' | 'fuel' | 'shanxia', + rechargeType: 'etc' as 'etc' | 'fuel' | 'shanxia' | 'bailian', applyDate: '', odometerKm: null as number | null, attachmentUrls: '', diff --git a/web-admin/src/views/pl/vehicle-recharge-record/index.vue b/web-admin/src/views/pl/vehicle-recharge-record/index.vue index 0874460b0..9ef155fac 100644 --- a/web-admin/src/views/pl/vehicle-recharge-record/index.vue +++ b/web-admin/src/views/pl/vehicle-recharge-record/index.vue @@ -463,6 +463,7 @@ + @@ -779,7 +780,7 @@ const formData = reactive({ rechargeOrderNo: '', applyId: '', licensePlate: '', - rechargeType: 'etc' as 'etc' | 'fuel' | 'shanxia', + rechargeType: 'etc' as 'etc' | 'fuel' | 'shanxia' | 'bailian', rechargeDate: '', cardNo: '', gasStation: '',