feat(i18n): migrate billing, triage, pharmacy pages to vue-i18n (206+120+60 keys)

This commit is contained in:
2026-06-24 22:04:53 +08:00
parent d0f2e21af5
commit 1a0e6aabb4
21 changed files with 2047 additions and 735 deletions

View File

@@ -686,5 +686,416 @@
"hospitalizationError": "An error occurred during hospitalization, please try again later!", "hospitalizationError": "An error occurred during hospitalization, please try again later!",
"infectiousReportSaved": "Infectious disease report saved successfully", "infectiousReportSaved": "Infectious disease report saved successfully",
"defaultDepartment": "Cardiology" "defaultDepartment": "Cardiology"
},
"triage": {
"title": "Smart Triage Queue Management",
"exit": "Exit",
"backendConfig": "Backend Config",
"candidatePoolTitle": "① Smart Candidate Pool (Checked-in, Not Queued)",
"seqNo": "No.",
"patient": "Patient",
"age": "Age",
"ticketType": "Ticket Type",
"room": "Room",
"doctor": "Doctor",
"matchedRule": "Matched Rule",
"addToQueue": "Add to Queue >>",
"addAllToQueue": "Add All to Queue",
"queueTitle": "② Smart Queue (All Depts)",
"selectDate": "Select Date",
"query": "Query",
"today": "Today",
"queueOrder": "Queue #",
"waiting": "Waiting",
"status": "Status",
"removeFromQueue": "<< Remove from Queue",
"roomFilterTitle": "③ Room Quick Filter",
"all": "All",
"showOnlyWaiting": "Show Waiting Only",
"showAllStatus": "Show All Status",
"callPanelTitle": "④ Call Control Panel",
"currentCall": "Current Call",
"selectCall": "Select Call",
"nextPatient": "Next Patient",
"skip": "Skip",
"complete": "Complete",
"requeue": "Requeue",
"ledLabel": "⑤ LED",
"pleaseGoTo": "please go to",
"voiceLabel": "Voice",
"voiceCallText": "Number {number}, {name}, please go to {room} ({type})",
"ruleConfigTitle": "Smart Triage Rule Engine Config - Cardiology",
"addRule": "Add Rule",
"saveAll": "Save All",
"testRule": "Test Rule",
"rule": "Rule",
"ruleName": "Rule Name",
"placeholderRuleName": "Enter rule name",
"department": "Department",
"cardiology": "Cardiology",
"ruleDesc": "Rule Description",
"placeholderRuleDesc": "Enter rule description",
"priority": "Priority",
"weekDayActive": "Effective Days",
"conditionExpr": "Condition Expression(JSON)",
"quickGenerator": "Quick Generator",
"syntaxCheck": "Syntax Check",
"ageCondition": "Age Condition",
"clear": "Clear",
"ticketTypeLabel": "Ticket Type",
"placeholderSelectTicketType": "Select ticket type",
"expert": "Expert",
"normal": "Normal",
"specialNeeds": "Special",
"emergency": "Emergency",
"placeholderSelectDept": "Select department",
"cardiacSurgery": "Cardiac Surgery",
"neurology": "Neurology",
"placeholderDoctor": "Enter doctor name (fuzzy match)",
"customCondition": "Custom Condition",
"placeholderFieldName": "Field name (e.g. gender)",
"placeholderFieldValue": "Field value (e.g. Male)",
"previewJson": "Preview JSON",
"apply": "Apply",
"weekMon": "Mon",
"weekTue": "Tue",
"weekWed": "Wed",
"weekThu": "Thu",
"weekFri": "Fri",
"weekSat": "Sat",
"weekSun": "Sun",
"statusWaiting": "Waiting",
"statusCalling": "Calling",
"statusInConsultation": "In Consultation",
"statusCompleted": "Completed",
"statusSkipped": "Skipped",
"statusRefunded": "Refunded",
"statusFollowUp": "Follow-up",
"newRule": "New Rule",
"msgDataLoaded": "Data loaded from outpatient registration",
"msgSelectPatientToAdd": "Please select patients to add to queue first",
"msgAddedToQueue": "Successfully added {count} patient(s) to queue (saved)",
"msgAlreadyInQueue": "Selected patients already in queue, removed from candidate pool",
"msgAddFailed": "Failed to add to queue, please retry",
"msgAddFailedUnsaved": "Failed to add to queue (unsaved)",
"msgNoCandidates": "No patients in candidate pool",
"msgAllAlreadyInQueue": "All candidate patients already in queue, removed from pool",
"msgAddAllFailed": "Failed to add all, please retry",
"msgAddAllFailedUnsaved": "Failed to add all (unsaved)",
"msgRefreshed": "Refreshed (queue restored from database)",
"msgSelectQueryDate": "Please select a query date",
"msgLoadedHistory": "Loaded queue data for {date}",
"msgSwitchedToToday": "Switched to today's queue",
"msgExitNotImpl": "Exit feature not yet implemented",
"msgSelectPatientInQueue": "Please select a patient from the right queue first",
"msgMissingIdSelectCall": "Queue item missing ID, cannot save. Please refresh the page",
"msgAlreadyCalling": "This patient is already in \"Calling\" status",
"msgCanOnlyCallWaiting": "Can only call \"Waiting\" patients, current status: \"{status}\"",
"msgSelectCalledWithCount": "Select-call saved, {count} patient(s) currently calling",
"msgSelectCalledSingle": "Select-call saved",
"msgSelectCallFailed": "Select-call failed (unsaved)",
"msgNextCalled": "Next patient called (saved)",
"msgNoWaitingPatient": "No \"Waiting\" patients in current scope",
"msgSkipped": "Skipped (saved)",
"msgNoCallingPatient": "No \"Calling\" patients",
"msgCompleted": "Completed (saved)",
"msgRequeued": "Requeued (saved)",
"msgNoWaitingPatientRequeue": "No waiting patients",
"msgFillRuleNameAndPriority": "Please fill in rule name and priority",
"msgSelectWeekDays": "Please select effective days",
"msgJsonSyntaxError": "Condition expression JSON syntax error",
"msgRuleSaved": "Current rule saved",
"msgAllRulesSaved": "All rules saved (frontend simulation)",
"msgSyntaxCheckPassed": "Syntax check passed",
"msgAtLeastOneCondition": "Please set at least one condition",
"msgConditionApplied": "Condition expression generated and applied",
"msgTestRulePlaceholder": "Test rule feature pending backend integration",
"msgSelectPatientToRemove": "Please select a patient to remove from queue first",
"msgMissingIdRemove": "Queue item missing ID, cannot save delete. Please refresh",
"msgRemovedFromQueue": "{name} removed from queue, patient reappeared in candidate pool (saved)",
"msgRemoveFailed": "Failed to remove from queue (unsaved)",
"msgMissingIdSort": "Queue item missing ID, cannot save sort. Please refresh",
"msgOrderAdjusted": "Queue order adjusted (saved)",
"msgOrderAdjustFailed": "Queue order adjustment failed (unsaved)"
},
"pharmacy": {
"patientInfo": "Patient Info",
"placeholderNameOrId": "Enter name/ID number",
"dispenseStatus": "Dispense Status",
"placeholderSelectDispenseStatus": "Select dispense status",
"visitDate": "Visit Date",
"startDate": "Start Date",
"endDate": "End Date",
"name": "Name",
"gender": "Gender",
"age": "Age",
"phone": "Phone",
"visitDateCol": "Visit Date",
"preparer": "Preparer",
"placeholderPreparer": "Preparer",
"drugCategory": "Drug Category",
"placeholderDrugCategory": "Drug Category",
"westernChinese": "Western/Chinese Patent",
"chinese": "Chinese Herbal",
"project": "Project",
"placeholderProject": "Project",
"all": "All",
"drug": "Drug",
"consumable": "Consumable",
"batchDispense": "Batch Dispense",
"scan": "Scan",
"prescriptionPrint": "Print Prescription",
"totalAmount": "Total Amount",
"prescriptionNo": "Prescription No.",
"diagnosis": "Diagnosis",
"prescriptionType": "Prescription Type",
"itemName": "Item Name",
"merchandiseName": "Merchandise Name",
"dispenseQty": "Dispense Qty",
"lotNumber": "Lot Number",
"dispenseStatusCol": "Dispense Status",
"days": "Days",
"spec": "Spec",
"traceNo": "Trace No.",
"placeholderTraceNo": "Enter trace number",
"amount": "Amount",
"dispensePharmacy": "Dispense Pharmacy",
"manufacturer": "Manufacturer",
"orderingDoctor": "Ordering Doctor",
"frequency": "Frequency",
"usage": "Usage",
"operation": "Action",
"dispense": "Dispense",
"void": "Void",
"selectVoidReason": "Select Void Reason",
"placeholderSelectVoidReason": "Select void reason",
"confirm": "OK",
"cancel": "Cancel",
"printWarningNoTable": "Table not initialized, please refresh and retry",
"printWarningNoSelect": "No items selected for printing, print failed",
"printWarningNoData": "Failed to get print data, please retry later",
"printFailed": "Prescription print failed",
"msgDispenseSuccess": "Dispensed successfully",
"msgDispenseFailed": "Dispense failed",
"msgNoMatchTraceNo": "No trace number matched in inventory, please scan individually in the dispense list",
"msgOperationFailed": "Operation failed",
"msgInsufficientStock": "Insufficient stock for this lot",
"msgQtyExceedsTotal": "Dispense quantity cannot exceed total quantity",
"msgQtyBelowTotal": "Dispense quantity cannot be less than total quantity",
"msgSelectDispenseItem": "No items selected for dispensing, please reselect",
"msgSelectVoidReason": "Please select a void reason",
"msgNoDataSelected": "No data selected",
"voiding": "Voiding...",
"yuan": "yuan",
"remaining": "remaining",
"expDate": "exp"
},
"billing": {
"patientList": "Patient List",
"searchPlaceholder": "Enter patient name/medical record no.",
"searchPlaceholderName": "Enter patient name",
"chargeStatus": "Charge Status",
"startTime": "Start Time",
"endTime": "End Time",
"search": "Search",
"medicalRecordNo": "Medical Record No.",
"name": "Name",
"basicInfo": "Basic Info",
"gender": "Gender",
"age": "Age",
"department": "Department",
"visitTime": "Visit Time",
"chargeItems": "Charge Items",
"confirmCharge": "Confirm Charge",
"electronicCertificate": "E-Certificate",
"idCard": "ID Card",
"medicalInsuranceCard": "Insurance Card",
"insuranceToSelf": "Insurance to Self-Pay",
"selfToInsurance": "Self-Pay to Insurance",
"studentInsuranceToSelf": "Student Insurance to Self-Pay",
"studentSelfToInsurance": "Student Self-Pay to Insurance",
"totalAmount": "Total Amount",
"docNo": "Doc No.",
"itemName": "Charge Item",
"quantity": "Qty",
"medicalType": "Medical Type",
"insuranceCode": "Insurance Code",
"feeNature": "Fee Nature",
"amount": "Amount",
"cashier": "Cashier",
"operation": "Action",
"print": "Print",
"yuan": "yuan",
"chargeDate": "Charge Date",
"receivableAmount": "Receivable",
"refundAmount": "Refundable",
"discountAmount": "Discount",
"payMethod": "Payment Method",
"selectPayMethod": "Select Payment",
"payAmount": "Pay Amount",
"refundMethod": "Refund Method",
"selectRefundMethod": "Select Refund",
"refundAmountLabel": "Refund Amount",
"addPayMethod": "Add Payment Method",
"addRefundMethod": "Add Refund Method",
"amountSatisfied": "Amount satisfied, cannot add more",
"refundAmountSatisfied": "Amount satisfied, cannot add more",
"discount": "Discount",
"wechatPay": "Scan to Pay",
"viewResult": "View Result",
"payType": "Payment Type",
"actualTotal": "Actual Total",
"refundTotal": "Refund Total",
"changeAmount": "Change",
"confirm": "Confirm",
"cancel": "Cancel",
"selectChargeItem": "Please select a charge item",
"preSettleFail": "Pre-settlement failed",
"enterCorrectAmount": "Please enter correct amount",
"chargeFail": "Charge failed",
"chargeFailRetry": "Charge failed, please retry",
"printFail": "Print failed",
"opSuccess": "Operation successful",
"outpatientChargeDetail": "Outpatient Charge Detail",
"outpatientChargeReceipt": "Outpatient Charge Receipt",
"refundReason": "Refund Reason",
"enterReason": "Enter reason",
"enterReasonPlaceholder": "Enter reason",
"refundConfirm": "Confirm Refund",
"refundDate": "Refund Date",
"refundDocNo": "Payment Doc No.",
"itemDocNo": "Item Doc No.",
"itemNameCol": "Item Name",
"chargeStatusCol": "Charge Status",
"paymentTotal": "Payment Total",
"refundItem": "Refund",
"encounterNo": "Encounter No.",
"refundDocs": "Refund Documents",
"enterCorrectRefundAmount": "Please enter correct amount",
"invoiceNo": "Invoice No.",
"invoiceStatus": "Invoice Status",
"issued": "Issued",
"notIssued": "Not Issued",
"settleTime": "Settlement Time",
"startDate": "Start Date",
"endDate": "End Date",
"query": "Query",
"reset": "Reset",
"total": "Total",
"success": "Success",
"batchIssue": "Batch Issue",
"payStatus": "Pay Status",
"feeType": "Fee Type",
"insuranceSettleId": "Insurance Settle ID",
"chargeSerialNo": "Charge Serial No.",
"settleAmount": "Settle Amount",
"payAmountCol": "Pay Amount",
"settleTimeCol": "Settle Time",
"payResult": "Pay Result",
"printCount": "Print Count",
"chargeDetail": "Charge Detail",
"issueInvoice": "Issue E-Invoice",
"writeoffInvoice": "Writeoff Invoice",
"viewInvoice": "View Invoice",
"payDetail": "Payment Type",
"change": "Change",
"payment": "Payment",
"writeoffReason": "Writeoff Reason",
"writeoffSuccess": "Writeoff successful",
"patientBasicInfo": "Patient Basic Info",
"surgeryNo": "Surgery No.",
"surgeryName": "Surgery Name",
"cardRenewal": "Card Renewal",
"patientQuery": "Patient Query(Q)",
"confirmBtn": "Confirm (O)",
"closeBtn": "Close (C)",
"patientNameLabel": "Patient Name:",
"idCardLabel": "ID Card No.:",
"phoneLabel": "Phone No.:",
"outpatientNo": "Outpatient No.",
"newOutpatientNo": "New Outpatient No.:",
"enterNewOutpatientNo": "Enter new outpatient no.",
"patientArchiveQuery": "Patient Archive Query",
"confirmSelect": "Confirm(Q)",
"closeSelect": "Close(C)",
"birthDate": "Birth Date",
"seqNo": "No.",
"patientName": "Patient Name",
"searchPlaceholderPatient": "Enter patient name",
"payBusNo": "Payment No.",
"txnAmount": "Amount(Yuan)",
"txnType": "Transaction Type",
"payTypeCol": "Pay Method",
"txnTime": "Transaction Time",
"origTxnType": "Original Type",
"thirdPartyDiscount": "3rd Party Discount",
"errorMsg": "Error Message",
"queryResult": "Query Result",
"queryResultMsg": "Result Description",
"payResultQuery": "Pay Result Query",
"nextDayRefund": "Next-Day Refund",
"refundResultQuery": "Refund Result Query",
"registerChargeRecord": "Schedule",
"schedule": "Schedule",
"detail": "Detail",
"normal": "Normal",
"disabled": "Disabled",
"nameCol": "Name",
"dateCol": "Date",
"statusCol": "Status",
"wechat": "WeChat",
"alipay": "Alipay",
"unionpay": "UnionPay",
"cash": "Cash",
"discountLabel": "Discount",
"selfPay": "Self-Pay",
"enterCashAmount": "Enter cash amount",
"payMethodPlaceholder": " payment QR code",
"reading": "Reading...",
"patientCardRenewalSuccess": "Card Renewal Success",
"patientRenewalSuccessMsg": "Patient card renewal completed successfully!",
"pleaseEnterQuery": "Please enter at least one query condition",
"autoSelectUnique": "Auto-selected the only patient",
"noPatientFound": "No patient found",
"queryFail": "Query failed",
"queryFailRetry": "Query failed, please retry later",
"selectPatient": "Please select a patient",
"selectPatientWarning": "Patient selected, please click confirm",
"patientRenewalSuccess": "Card renewal successful!",
"patientRenewalFail": "Card renewal failed",
"patientRenewalFailCardExists": "Card renewal failed, card number already exists",
"closeConfirm": "Are you sure to close this page?",
"cancelClose": "Close cancelled",
"newCardNoCannotSame": "New card number cannot be the same as the original",
"pleaseQueryPatient": "Please query patient info first",
"registerChargeRecordTitle": "Registration Charge Records",
"reprintRegistration": "Reprint Registration",
"reprintTitle": "Registration Slip Reprint",
"reprintSubtitle": "Reprinting will invalidate the original slip and generate a new one",
"doctorName": "Doctor Name",
"serialNo": "Serial No.",
"totalLabel": "Total",
"medicalRecordFee": "Medical Record Fee",
"printTime": "Print Time",
"visitTimeLabel": "Appointment/Registration Time",
"enterCardNoSearch": "Enter card number to search",
"regRecordSelect": "Registration Record Selection",
"enterCardNo": "Please enter card number",
"noRegRecord": "No registration records found, please check the card number",
"queryFailMsg": "Query failed: {msg}",
"queryError": "Query error: {error}",
"reprintSuccess": "Reprint successful",
"reprintFail": "Reprint failed",
"reprintFailMsg": "Reprint failed: {error}",
"selectRegRecordFirst": "Please search and select a registration record first",
"printSuccess": "Print successful",
"printFailMsg": "Print failed: {error}",
"selectRegRecord": "Please select a registration record",
"getRegIdFail": "Failed to get registration record ID, please retry",
"processFail": "Processing failed: {error}",
"statusReserved": "Reserved",
"statusCompleted": "Completed",
"statusCancelled": "Cancelled",
"statusInProgress": "In Progress"
} }
} }

View File

@@ -686,5 +686,416 @@
"hospitalizationError": "Đã xảy ra lỗi trong quá trình nhập viện, vui lòng thử lại sau!", "hospitalizationError": "Đã xảy ra lỗi trong quá trình nhập viện, vui lòng thử lại sau!",
"infectiousReportSaved": "Lưu thẻ báo cáo bệnh truyền nhiễm thành công", "infectiousReportSaved": "Lưu thẻ báo cáo bệnh truyền nhiễm thành công",
"defaultDepartment": "Khoa Tim Mạch" "defaultDepartment": "Khoa Tim Mạch"
},
"triage": {
"title": "Quản Lý Hàng Chờ Phân Loại Thông Minh",
"exit": "Thoát",
"backendConfig": "Cấu Hình Backend",
"candidatePoolTitle": "① Hồ Ứng Viên Thông Minh (Đã Check-in, Chưa Vào Hàng Chờ)",
"seqNo": "STT",
"patient": "Bệnh Nhân",
"age": "Tuổi",
"ticketType": "Loại Vé",
"room": "Phòng",
"doctor": "Bác Sĩ",
"matchedRule": "Quy Tắc Khớp",
"addToQueue": "Thêm Vào Hàng Chờ >>",
"addAllToQueue": "Thêm Tất Cả Vào Hàng Chờ",
"queueTitle": "② Hàng Chờ Thông Minh (Tất Cả Khoa)",
"selectDate": "Chọn Ngày",
"query": "Tìm Kiếm",
"today": "Hôm Nay",
"queueOrder": "STT Chờ",
"waiting": "Đang Chờ",
"status": "Trạng Thái",
"removeFromQueue": "<< Rời Khỏi Hàng Chờ",
"roomFilterTitle": "③ Lọc Nhanh Theo Phòng",
"all": "Tất Cả",
"showOnlyWaiting": "Chỉ Hiện Đang Chờ",
"showAllStatus": "Hiện Tất Cả Trạng Thái",
"callPanelTitle": "④ Bảng Điều Khiển Gọi Số",
"currentCall": "Đang Gọi",
"selectCall": "Gọi Chọn",
"nextPatient": "Bệnh Nhân Tiếp",
"skip": "Bỏ Qua",
"complete": "Hoàn Thành",
"requeue": "Xếp Lại",
"ledLabel": "⑤ LED",
"pleaseGoTo": "vui lòng đến",
"voiceLabel": "Giọng Nói",
"voiceCallText": "Số {number}, {name}, vui lòng đến {room} ({type})",
"ruleConfigTitle": "Cấu Hình Động Cơ Quy Tắc Phân Loại - Tim Mạch",
"addRule": "Thêm Quy Tắc",
"saveAll": "Lưu Tất Cả",
"testRule": "Thử Nghiệm Quy Tắc",
"rule": "Quy Tắc",
"ruleName": "Tên Quy Tắc",
"placeholderRuleName": "Nhập tên quy tắc",
"department": "Khoa",
"cardiology": "Tim Mạch",
"ruleDesc": "Mô Tả Quy Tắc",
"placeholderRuleDesc": "Nhập mô tả quy tắc",
"priority": "Ưu Tiên",
"weekDayActive": "Ngày Hiệu Lực",
"conditionExpr": "Biểu Thức Điều Kiện(JSON)",
"quickGenerator": "Tạo Nhanh",
"syntaxCheck": "Kiểm Tra Cú Pháp",
"ageCondition": "Điều Kiện Tuổi",
"clear": "Xóa",
"ticketTypeLabel": "Loại Vé",
"placeholderSelectTicketType": "Chọn loại vé",
"expert": "Chuyên Gia",
"normal": "Bình Thường",
"specialNeeds": "Đặc Biệt",
"emergency": "Cấp Cứu",
"placeholderSelectDept": "Chọn khoa",
"cardiacSurgery": "Phẫu Thuật Tim",
"neurology": "Thần Kinh",
"placeholderDoctor": "Nhập tên bác sĩ (tìm mờ)",
"customCondition": "Điều Kiện Tùy Chỉnh",
"placeholderFieldName": "Tên trường (vd: gender)",
"placeholderFieldValue": "Giá trị (vd: Nam)",
"previewJson": "Xem Trước JSON",
"apply": "Áp Dụng",
"weekMon": "T2",
"weekTue": "T3",
"weekWed": "T4",
"weekThu": "T5",
"weekFri": "T6",
"weekSat": "T7",
"weekSun": "CN",
"statusWaiting": "Đang Chờ",
"statusCalling": "Đang Gọi",
"statusInConsultation": "Đang Khám",
"statusCompleted": "Hoàn Thành",
"statusSkipped": "Bỏ Qua",
"statusRefunded": "Đã Hoàn Phí",
"statusFollowUp": "Tái Khám",
"newRule": "Quy Tắc Mới",
"msgDataLoaded": "Đã tải dữ liệu từ đăng ký khám bệnh",
"msgSelectPatientToAdd": "Vui lòng chọn bệnh nhân để thêm vào hàng chờ",
"msgAddedToQueue": "Đã thêm {count} bệnh nhân vào hàng chờ (đã lưu)",
"msgAlreadyInQueue": "Bệnh nhân đã có trong hàng chờ, đã xóa khỏi hồ ứng viên",
"msgAddFailed": "Thêm vào hàng chờ thất bại, vui lòng thử lại",
"msgAddFailedUnsaved": "Thêm vào hàng chờ thất bại (chưa lưu)",
"msgNoCandidates": "Không có bệnh nhân trong hồ ứng viên",
"msgAllAlreadyInQueue": "Tất cả bệnh nhân đã có trong hàng chờ",
"msgAddAllFailed": "Thêm tất cả thất bại, vui lòng thử lại",
"msgAddAllFailedUnsaved": "Thêm tất cả thất bại (chưa lưu)",
"msgRefreshed": "Đã làm mới (hàng chờ đã khôi phục từ CSDL)",
"msgSelectQueryDate": "Vui lòng chọn ngày truy vấn",
"msgLoadedHistory": "Đã tải dữ liệu hàng chờ ngày {date}",
"msgSwitchedToToday": "Đã chuyển sang hàng chờ hôm nay",
"msgExitNotImpl": "Chức năng thoát chưa được triển khai",
"msgSelectPatientInQueue": "Vui lòng chọn bệnh nhân từ hàng chờ bên phải",
"msgMissingIdSelectCall": "Mục hàng chờ thiếu ID, không thể lưu. Vui lòng tải lại trang",
"msgAlreadyCalling": "Bệnh nhân này đang ở trạng thái \"Đang Gọi\"",
"msgCanOnlyCallWaiting": "Chỉ có thể gọi bệnh nhân \"Đang Chờ\", trạng thái hiện tại: \"{status}\"",
"msgSelectCalledWithCount": "Đã gọi chọn (đã lưu), hiện có {count} bệnh nhân đang được gọi",
"msgSelectCalledSingle": "Đã gọi chọn (đã lưu)",
"msgSelectCallFailed": "Gọi chọn thất bại (chưa lưu)",
"msgNextCalled": "Đã gọi bệnh nhân tiếp theo (đã lưu)",
"msgNoWaitingPatient": "Không có bệnh nhân \"Đang Chờ\" trong phạm vi",
"msgSkipped": "Đã bỏ qua (đã lưu)",
"msgNoCallingPatient": "Không có bệnh nhân \"Đang Gọi\"",
"msgCompleted": "Đã hoàn thành (đã lưu)",
"msgRequeued": "Đã xếp lại (đã lưu)",
"msgNoWaitingPatientRequeue": "Không có bệnh nhân đang chờ",
"msgFillRuleNameAndPriority": "Vui lòng điền tên quy tắc và mức ưu tiên",
"msgSelectWeekDays": "Vui lòng chọn ngày hiệu lực",
"msgJsonSyntaxError": "Lỗi cú pháp JSON biểu thức điều kiện",
"msgRuleSaved": "Đã lưu quy tắc hiện tại",
"msgAllRulesSaved": "Đã lưu tất cả quy tắc (mô phỏng frontend)",
"msgSyntaxCheckPassed": "Kiểm tra cú pháp thành công",
"msgAtLeastOneCondition": "Vui lòng đặt ít nhất một điều kiện",
"msgConditionApplied": "Biểu thức điều kiện đã được tạo và áp dụng",
"msgTestRulePlaceholder": "Chức năng thử nghiệm quy tắc đang chờ tích hợp backend",
"msgSelectPatientToRemove": "Vui lòng chọn bệnh nhân để rời khỏi hàng chờ",
"msgMissingIdRemove": "Mục hàng chờ thiếu ID, không thể xóa. Vui lòng tải lại",
"msgRemovedFromQueue": "Đã xóa {name} khỏi hàng chờ, bệnh nhân đã xuất hiện lại trong hồ (đã lưu)",
"msgRemoveFailed": "Rời khỏi hàng chờ thất bại (chưa lưu)",
"msgMissingIdSort": "Mục hàng chờ thiếu ID, không thể lưu sắp xếp. Vui lòng tải lại",
"msgOrderAdjusted": "Đã điều chỉnh thứ tự hàng chờ (đã lưu)",
"msgOrderAdjustFailed": "Điều chỉnh thứ tự thất bại (chưa lưu)"
},
"pharmacy": {
"patientInfo": "Thông Tin Bệnh Nhân",
"placeholderNameOrId": "Nhập tên/số giấy tờ",
"dispenseStatus": "Trạng Thái Phát Thuốc",
"placeholderSelectDispenseStatus": "Chọn trạng thái phát thuốc",
"visitDate": "Ngày Khám",
"startDate": "Ngày Bắt Đầu",
"endDate": "Ngày Kết Thúc",
"name": "Họ Tên",
"gender": "Giới Tính",
"age": "Tuổi",
"phone": "Điện Thoại",
"visitDateCol": "Ngày Khám",
"preparer": "Dược Sĩ Pha Chế",
"placeholderPreparer": "Dược Sĩ Pha Chế",
"drugCategory": "Phân Loại Thuốc",
"placeholderDrugCategory": "Phân Loại Thuốc",
"westernChinese": "Tây Y/Thuốc Hoàn",
"chinese": "Thuốc Nam",
"project": "Dự Án",
"placeholderProject": "Dự Án",
"all": "Tất Cả",
"drug": "Thuốc",
"consumable": "Vật Tư",
"batchDispense": "Phát Hàng Loạt",
"scan": "Quét Mã",
"prescriptionPrint": "In Đơn Thuốc",
"totalAmount": "Tổng Tiền",
"prescriptionNo": "Số Đơn",
"diagnosis": "Chẩn Đoán",
"prescriptionType": "Loại Đơn",
"itemName": "Tên Mục",
"merchandiseName": "Tên Hàng Hóa",
"dispenseQty": "SL Phát",
"lotNumber": "Số Lô",
"dispenseStatusCol": "Trạng Thái",
"days": "Số Ngày",
"spec": "Quy Cách",
"traceNo": "Mã Truy Xuất",
"placeholderTraceNo": "Nhập mã truy xuất",
"amount": "Thành Tiền",
"dispensePharmacy": "Nhà Thuốc",
"manufacturer": "Nhà Sản Xuất",
"orderingDoctor": "Bác Sĩ Kê Đơn",
"frequency": "Tần Suất",
"usage": "Cách Dùng",
"operation": "Thao Tác",
"dispense": "Phát",
"void": "Hủy",
"selectVoidReason": "Chọn Lý Do Hủy",
"placeholderSelectVoidReason": "Chọn lý do hủy",
"confirm": "Xác Nhận",
"cancel": "Hủy Bỏ",
"printWarningNoTable": "Bảng chưa sẵn sàng, vui lòng tải lại",
"printWarningNoSelect": "Chưa chọn mục để in, in thất bại",
"printWarningNoData": "Lấy dữ liệu in thất bại, vui lòng thử lại",
"printFailed": "In đơn thuốc thất bại",
"msgDispenseSuccess": "Phát thuốc thành công",
"msgDispenseFailed": "Phát thuốc thất bại",
"msgNoMatchTraceNo": "Không khớp mã truy xuất trong kho, vui lòng quét riêng trong danh sách",
"msgOperationFailed": "Thao tác thất bại",
"msgInsufficientStock": "Tồn kho lô này không đủ",
"msgQtyExceedsTotal": "Số lượng phát không được vượt quá tổng",
"msgQtyBelowTotal": "Số lượng phát không được nhỏ hơn tổng",
"msgSelectDispenseItem": "Chưa chọn mục để phát, vui lòng chọn lại",
"msgSelectVoidReason": "Vui lòng chọn lý do hủy",
"msgNoDataSelected": "Chưa chọn dữ liệu",
"voiding": "Đang hủy...",
"yuan": "đ",
"remaining": "còn lại",
"expDate": "HSD"
},
"billing": {
"patientList": "Danh sách bệnh nhân",
"searchPlaceholder": "Nhập tên/số bệnh án",
"searchPlaceholderName": "Nhập tên bệnh nhân",
"chargeStatus": "Trạng thái thu phí",
"startTime": "Thời gian bắt đầu",
"endTime": "Thời gian kết thúc",
"search": "Tìm kiếm",
"medicalRecordNo": "Số bệnh án",
"name": "Họ tên",
"basicInfo": "Thông tin cơ bản",
"gender": "Giới tính",
"age": "Tuổi",
"department": "Khoa",
"visitTime": "Thời gian khám",
"chargeItems": "Dịch vụ thu phí",
"confirmCharge": "Xác nhận thu phí",
"electronicCertificate": "Chứng từ điện tử",
"idCard": "CCCD",
"medicalInsuranceCard": "Thẻ BHYT",
"insuranceToSelf": "BHYT sang tự trả",
"selfToInsurance": "Tự trả sang BHYT",
"studentInsuranceToSelf": "BHYT sinh viên sang tự trả",
"studentSelfToInsurance": "Tự trả sang BHYT sinh viên",
"totalAmount": "Tổng cộng",
"docNo": "Số chứng từ",
"itemName": "Dịch vụ",
"quantity": "Số lượng",
"medicalType": "Loại y tế",
"insuranceCode": "Mã BHYT",
"feeNature": "Tính chất phí",
"amount": "Số tiền",
"cashier": "Thu ngân",
"operation": "Thao tác",
"print": "In",
"yuan": "đ",
"chargeDate": "Ngày thu phí",
"receivableAmount": "Số tiền phải thu",
"refundAmount": "Số tiền hoàn",
"discountAmount": "Giảm giá",
"payMethod": "Phương thức thanh toán",
"selectPayMethod": "Chọn phương thức",
"payAmount": "Số tiền thanh toán",
"refundMethod": "Phương thức hoàn tiền",
"selectRefundMethod": "Chọn phương thức",
"refundAmountLabel": "Số tiền hoàn",
"addPayMethod": "Thêm phương thức",
"addRefundMethod": "Thêm phương thức",
"amountSatisfied": "Đã đủ số tiền, không thể thêm",
"refundAmountSatisfied": "Đã đủ số tiền, không thể thêm",
"discount": "Giảm giá",
"wechatPay": "Quét mã thanh toán",
"viewResult": "Xem kết quả",
"payType": "Loại thanh toán",
"actualTotal": "Tổng thực thu",
"refundTotal": "Tổng hoàn lại",
"changeAmount": "Tiền thừa",
"confirm": "Xác nhận",
"cancel": "Hủy",
"selectChargeItem": "Vui lòng chọn dịch vụ",
"preSettleFail": "Tính trước thất bại",
"enterCorrectAmount": "Vui lòng nhập đúng số tiền",
"chargeFail": "Thu phí thất bại",
"chargeFailRetry": "Thu phí thất bại, vui lòng thử lại",
"printFail": "In thất bại",
"opSuccess": "Thao tác thành công",
"outpatientChargeDetail": "Chi tiết thu phí ngoại trú",
"outpatientChargeReceipt": "Biên lai thu phí ngoại trú",
"refundReason": "Lý do hoàn tiền",
"enterReason": "Nhập lý do",
"enterReasonPlaceholder": "Nhập lý do",
"refundConfirm": "Xác nhận hoàn tiền",
"refundDate": "Ngày hoàn tiền",
"refundDocNo": "Số CT thanh toán",
"itemDocNo": "Số CT dịch vụ",
"itemNameCol": "Tên dịch vụ",
"chargeStatusCol": "Trạng thái thu phí",
"paymentTotal": "Tổng thanh toán",
"refundItem": "Hoàn tiền",
"encounterNo": "Số khám",
"refundDocs": "Chứng từ hoàn",
"enterCorrectRefundAmount": "Vui lòng nhập đúng số tiền",
"invoiceNo": "Số hóa đơn",
"invoiceStatus": "Trạng thái hóa đơn",
"issued": "Đã phát hành",
"notIssued": "Chưa phát hành",
"settleTime": "Thời gian thanh toán",
"startDate": "Ngày bắt đầu",
"endDate": "Ngày kết thúc",
"query": "Tìm kiếm",
"reset": "Đặt lại",
"total": "Tổng",
"success": "Thành công",
"batchIssue": "Phát hành hàng loạt",
"payStatus": "Trạng thái TT",
"feeType": "Loại phí",
"insuranceSettleId": "Mã QT BHYT",
"chargeSerialNo": "Số serial thu phí",
"settleAmount": "Số tiền thanh toán",
"payAmountCol": "Số tiền TT",
"settleTimeCol": "Thời gian TT",
"payResult": "Kết quả TT",
"printCount": "Số lần in",
"chargeDetail": "Chi tiết thu phí",
"issueInvoice": "Phát hành HĐ điện tử",
"writeoffInvoice": "Hủy hóa đơn",
"viewInvoice": "Xem hóa đơn",
"payDetail": "Loại thanh toán",
"change": "Tiền thừa",
"payment": "Thanh toán",
"writeoffReason": "Lý do hủy",
"writeoffSuccess": "Hủy thành công",
"patientBasicInfo": "Thông tin BN cơ bản",
"surgeryNo": "Số phẫu thuật",
"surgeryName": "Tên phẫu thuật",
"cardRenewal": "Đổi thẻ",
"patientQuery": "Tìm BN (Q)",
"confirmBtn": "Xác nhận (O)",
"closeBtn": "Đóng (C)",
"patientNameLabel": "Tên BN:",
"idCardLabel": "Số CCCD:",
"phoneLabel": "Số ĐT:",
"outpatientNo": "Số ngoại trú",
"newOutpatientNo": "Số ngoại trú mới:",
"enterNewOutpatientNo": "Nhập số ngoại trú mới",
"patientArchiveQuery": "Tìm kiếm hồ sơ BN",
"confirmSelect": "Xác nhận(Q)",
"closeSelect": "Đóng(C)",
"birthDate": "Ngày sinh",
"seqNo": "STT",
"patientName": "Tên bệnh nhân",
"searchPlaceholderPatient": "Nhập tên bệnh nhân",
"payBusNo": "Số thanh toán",
"txnAmount": "Số tiền(đ)",
"txnType": "Loại giao dịch",
"payTypeCol": "Phương thức TT",
"txnTime": "Thời gian GD",
"origTxnType": "Loại GD gốc",
"thirdPartyDiscount": "KM bên thứ 3",
"errorMsg": "Thông báo lỗi",
"queryResult": "KQ tìm kiếm",
"queryResultMsg": "Mô tả KQ",
"payResultQuery": "Truy vấn KQ TT",
"nextDayRefund": "Hoàn ngày sau",
"refundResultQuery": "Truy vấn KQ hoàn",
"registerChargeRecord": "Lịch trực",
"schedule": "Lịch trực",
"detail": "Chi tiết",
"normal": "Bình thường",
"disabled": "Tắt",
"nameCol": "Tên",
"dateCol": "Ngày",
"statusCol": "Trạng thái",
"wechat": "WeChat",
"alipay": "Alipay",
"unionpay": "UnionPay",
"cash": "Tiền mặt",
"discountLabel": "Giảm giá",
"selfPay": "Tự trả",
"enterCashAmount": "Nhập số tiền mặt",
"payMethodPlaceholder": " mã QR thanh toán",
"reading": "Đang đọc...",
"patientCardRenewalSuccess": "Đổi thẻ thành công",
"patientRenewalSuccessMsg": "Đổi thẻ bệnh nhân thành công!",
"pleaseEnterQuery": "Vui lòng nhập ít nhất một điều kiện",
"autoSelectUnique": "Đã tự động chọn BN duy nhất",
"noPatientFound": "Không tìm thấy bệnh nhân",
"queryFail": "Tìm kiếm thất bại",
"queryFailRetry": "Tìm kiếm thất bại, vui lòng thử lại",
"selectPatient": "Vui lòng chọn bệnh nhân",
"selectPatientWarning": "Đã chọn BN, vui lòng nhấn xác nhận",
"patientRenewalSuccess": "Đổi thẻ thành công!",
"patientRenewalFail": "Đổi thẻ thất bại",
"patientRenewalFailCardExists": "Đổi thẻ thất bại, số thẻ đã tồn tại",
"closeConfirm": "Bạn có chắc muốn đóng trang này?",
"cancelClose": "Đã hủy thao tác đóng",
"newCardNoCannotSame": "Số thẻ mới không được trùng số cũ",
"pleaseQueryPatient": "Vui lòng tìm thông tin BN trước",
"registerChargeRecordTitle": "Lịch sử thu phí đăng ký",
"reprintRegistration": "In lại phiếu đăng ký",
"reprintTitle": "In lại phiếu đăng ký khám",
"reprintSubtitle": "In lại sẽ hủy phiếu cũ và tạo phiếu mới",
"doctorName": "Tên bác sĩ",
"serialNo": "Số serial",
"totalLabel": "Tổng cộng",
"medicalRecordFee": "Phí bệnh án",
"printTime": "Thời gian in",
"visitTimeLabel": "Thời gian hẹn/đăng ký",
"enterCardNoSearch": "Nhập số thẻ để tìm kiếm",
"regRecordSelect": "Chọn bản ghi đăng ký",
"enterCardNo": "Vui lòng nhập số thẻ",
"noRegRecord": "Không tìm thấy bản ghi đăng ký, vui lòng kiểm tra số thẻ",
"queryFailMsg": "Tìm kiếm thất bại: {msg}",
"queryError": "Lỗi tìm kiếm: {error}",
"reprintSuccess": "In lại thành công",
"reprintFail": "In lại thất bại",
"reprintFailMsg": "In lại thất bại: {error}",
"selectRegRecordFirst": "Vui lòng tìm và chọn bản ghi đăng ký trước",
"printSuccess": "In thành công",
"printFailMsg": "In thất bại: {error}",
"selectRegRecord": "Vui lòng chọn một bản ghi đăng ký",
"getRegIdFail": "Lấy ID bản ghi thất bại, vui lòng thử lại",
"processFail": "Xử lý thất bại: {error}",
"statusReserved": "Đã đặt",
"statusCompleted": "Hoàn thành",
"statusCancelled": "Đã hủy",
"statusInProgress": "Đang xử lý"
} }
} }

View File

@@ -685,5 +685,416 @@
"hospitalizationError": "办理住院过程中发生错误,请稍后重试!", "hospitalizationError": "办理住院过程中发生错误,请稍后重试!",
"infectiousReportSaved": "传染病报告卡保存成功", "infectiousReportSaved": "传染病报告卡保存成功",
"defaultDepartment": "心内科" "defaultDepartment": "心内科"
},
"triage": {
"title": "智能分诊排队管理",
"exit": "退出",
"backendConfig": "后台配置",
"candidatePoolTitle": "① 智能候选池 (已签到未入队)",
"seqNo": "序号",
"patient": "患者",
"age": "年龄",
"ticketType": "号别",
"room": "诊室",
"doctor": "医生",
"matchedRule": "命中规则",
"addToQueue": "加入队列 >>",
"addAllToQueue": "一键加入队列",
"queueTitle": "② 智能队列 (全科)",
"selectDate": "选择日期",
"query": "查询",
"today": "今天",
"queueOrder": "队序",
"waiting": "等待",
"status": "状态",
"removeFromQueue": "<< 移出队列",
"roomFilterTitle": "③ 诊室快速过滤栏",
"all": "全部",
"showOnlyWaiting": "只显示等待",
"showAllStatus": "显示全部状态",
"callPanelTitle": "④ 叫号控制板",
"currentCall": "当前呼叫",
"selectCall": "选呼",
"nextPatient": "下一患者",
"skip": "跳过",
"complete": "完成",
"requeue": "过号重排",
"ledLabel": "⑤ LED",
"pleaseGoTo": "请到",
"voiceLabel": "语音",
"voiceCallText": "请{number}号{name}到{room}({type})",
"ruleConfigTitle": "智能分诊规则引擎配置 - 心内科",
"addRule": "新增规则",
"saveAll": "保存全部",
"testRule": "测试规则",
"rule": "规则",
"ruleName": "规则名称",
"placeholderRuleName": "请输入规则名称",
"department": "科室",
"cardiology": "心内科",
"ruleDesc": "规则描述",
"placeholderRuleDesc": "请输入规则描述",
"priority": "优先级",
"weekDayActive": "周几生效",
"conditionExpr": "条件表达式(JSON)",
"quickGenerator": "快速生成器",
"syntaxCheck": "语法检查",
"ageCondition": "年龄条件",
"clear": "清除",
"ticketTypeLabel": "号别/类型",
"placeholderSelectTicketType": "请选择号别",
"expert": "专家",
"normal": "普通",
"specialNeeds": "特需",
"emergency": "急诊",
"placeholderSelectDept": "请选择科室",
"cardiacSurgery": "心外科",
"neurology": "神经内科",
"placeholderDoctor": "请输入医生姓名(支持模糊匹配)",
"customCondition": "自定义条件",
"placeholderFieldName": "字段名gender",
"placeholderFieldValue": "字段值(如:男)",
"previewJson": "预览JSON",
"apply": "应用",
"weekMon": "一",
"weekTue": "二",
"weekWed": "三",
"weekThu": "四",
"weekFri": "五",
"weekSat": "六",
"weekSun": "日",
"statusWaiting": "等待",
"statusCalling": "叫号中",
"statusInConsultation": "就诊中",
"statusCompleted": "已完成",
"statusSkipped": "跳过",
"statusRefunded": "已退费",
"statusFollowUp": "已随访",
"newRule": "新规则",
"msgDataLoaded": "已从门诊挂号接口加载数据",
"msgSelectPatientToAdd": "请先选择要加入队列的患者",
"msgAddedToQueue": "成功将 {count} 位患者加入队列(已保存)",
"msgAlreadyInQueue": "所选患者已在队列中,已从候选池移除",
"msgAddFailed": "加入队列失败,请重试",
"msgAddFailedUnsaved": "加入队列失败(未保存)",
"msgNoCandidates": "候选池中没有患者",
"msgAllAlreadyInQueue": "所有候选池患者已在队列中,已从候选池移除",
"msgAddAllFailed": "一键加入失败,请重试",
"msgAddAllFailedUnsaved": "一键加入失败(未保存)",
"msgRefreshed": "已刷新(已从数据库恢复队列)",
"msgSelectQueryDate": "请选择查询日期",
"msgLoadedHistory": "已加载 {date} 的队列数据",
"msgSwitchedToToday": "已切换到今天队列",
"msgExitNotImpl": "退出功能待实现",
"msgSelectPatientInQueue": "请先在右侧队列中选择一个患者",
"msgMissingIdSelectCall": "该队列项缺少ID无法保存选呼请先刷新页面",
"msgAlreadyCalling": "该患者已经是\"叫号中\"状态",
"msgCanOnlyCallWaiting": "只能选呼\"等待\"状态的患者,当前患者状态为:\"{status}\"",
"msgSelectCalledWithCount": "已选呼(已保存),当前共有 {count} 位患者处于\"叫号中\"状态",
"msgSelectCalledSingle": "已选呼(已保存)",
"msgSelectCallFailed": "选呼失败(未保存)",
"msgNextCalled": "已呼叫下一位(已保存)",
"msgNoWaitingPatient": "当前范围内没有\"等待\"的患者",
"msgSkipped": "已跳过(已保存)",
"msgNoCallingPatient": "当前没有\"叫号中\"的患者",
"msgCompleted": "已完成(已保存)",
"msgRequeued": "已过号重排(已保存)",
"msgNoWaitingPatientRequeue": "当前没有等待中的患者",
"msgFillRuleNameAndPriority": "请填写规则名称和优先级",
"msgSelectWeekDays": "请选择生效周几",
"msgJsonSyntaxError": "条件表达式 JSON 语法错误",
"msgRuleSaved": "当前规则已保存",
"msgAllRulesSaved": "全部规则已保存(前端模拟)",
"msgSyntaxCheckPassed": "语法检查通过",
"msgAtLeastOneCondition": "请至少设置一个条件",
"msgConditionApplied": "条件表达式已生成并应用",
"msgTestRulePlaceholder": "测试规则功能待接入后端,当前为占位",
"msgSelectPatientToRemove": "请先选择要移出队列的患者",
"msgMissingIdRemove": "该队列项缺少ID无法保存删除请先刷新页面",
"msgRemovedFromQueue": "已将 {name} 移出队列,患者已重新出现在候选池中(已保存)",
"msgRemoveFailed": "移出队列失败(未保存)",
"msgMissingIdSort": "该队列项缺少ID无法保存排序请先刷新页面",
"msgOrderAdjusted": "队列顺序已调整(已保存)",
"msgOrderAdjustFailed": "队列顺序调整失败(未保存)"
},
"pharmacy": {
"patientInfo": "患者信息",
"placeholderNameOrId": "请输入姓名/证件号",
"dispenseStatus": "发药状态",
"placeholderSelectDispenseStatus": "请选择发药状态",
"visitDate": "就诊日期",
"startDate": "开始日期",
"endDate": "结束日期",
"name": "姓名",
"gender": "性别",
"age": "年龄",
"phone": "电话",
"visitDateCol": "就诊日期",
"preparer": "调配药师",
"placeholderPreparer": "调配药师",
"drugCategory": "药品分类",
"placeholderDrugCategory": "药品分类",
"westernChinese": "西药中成药",
"chinese": "中药",
"project": "项目",
"placeholderProject": "项目",
"all": "全部",
"drug": "药品",
"consumable": "耗材",
"batchDispense": "批量发药",
"scan": "扫码",
"prescriptionPrint": "处方打印",
"totalAmount": "总金额",
"prescriptionNo": "处方号",
"diagnosis": "诊断",
"prescriptionType": "处方类型",
"itemName": "项目名称",
"merchandiseName": "商品名称",
"dispenseQty": "发药数量",
"lotNumber": "批次号",
"dispenseStatusCol": "发药状态",
"days": "天数",
"spec": "规格",
"traceNo": "追溯码",
"placeholderTraceNo": "请输入追溯码",
"amount": "金额",
"dispensePharmacy": "发药药房",
"manufacturer": "生产厂家",
"orderingDoctor": "开单医生",
"frequency": "频次",
"usage": "用法",
"operation": "操作",
"dispense": "发药",
"void": "作废",
"selectVoidReason": "选择作废原因",
"placeholderSelectVoidReason": "请选择作废原因",
"confirm": "确定",
"cancel": "取消",
"printWarningNoTable": "表格组件未初始化,请刷新页面重试",
"printWarningNoSelect": "未选择要打印的项目,请重新选择,打印失败",
"printWarningNoData": "获取打印数据失败,请稍后重试",
"printFailed": "处方打印失败",
"msgDispenseSuccess": "发药成功",
"msgDispenseFailed": "发药失败",
"msgNoMatchTraceNo": "未在库存中匹配到追溯码,请在发药列表中单独扫描",
"msgOperationFailed": "操作失败",
"msgInsufficientStock": "当前批次库存不足",
"msgQtyExceedsTotal": "发药数量不能大于总数量",
"msgQtyBelowTotal": "发药数量不能小于总数量",
"msgSelectDispenseItem": "未选择要发药的项目,请重新选择,发药失败",
"msgSelectVoidReason": "请选择作废原因",
"msgNoDataSelected": "未选择数据",
"voiding": "作废中...",
"yuan": "元",
"remaining": "剩余",
"expDate": "有效期至"
},
"billing": {
"patientList": "患者列表",
"searchPlaceholder": "请输入患者名/病历号",
"searchPlaceholderName": "请输入患者名",
"chargeStatus": "收费状态",
"startTime": "开始时间",
"endTime": "结束时间",
"search": "搜索",
"medicalRecordNo": "病历号",
"name": "姓名",
"basicInfo": "基本信息",
"gender": "性别",
"age": "年龄",
"department": "科室",
"visitTime": "就诊时间",
"chargeItems": "收费项目",
"confirmCharge": "确认收费",
"electronicCertificate": "电子凭证",
"idCard": "身份证",
"medicalInsuranceCard": "医保卡",
"insuranceToSelf": "医保转自费",
"selfToInsurance": "自费转医保",
"studentInsuranceToSelf": "学生医保转学生自费",
"studentSelfToInsurance": "学生自费转学生医保",
"totalAmount": "合计金额",
"docNo": "单据号",
"itemName": "收费项目",
"quantity": "数量",
"medicalType": "医疗类型",
"insuranceCode": "医保编码",
"feeNature": "费用性质",
"amount": "金额",
"cashier": "收款人",
"operation": "操作",
"print": "打印",
"yuan": "元",
"chargeDate": "收费日期",
"receivableAmount": "应收金额",
"refundAmount": "应退金额",
"discountAmount": "折扣金额",
"payMethod": "支付方式",
"selectPayMethod": "选择支付方式",
"payAmount": "支付金额",
"refundMethod": "退费方式",
"selectRefundMethod": "选择退费方式",
"refundAmountLabel": "退费金额",
"addPayMethod": "添加支付方式",
"addRefundMethod": "添加退费方式",
"amountSatisfied": "金额已满足应收,不可继续添加",
"refundAmountSatisfied": "金额已满足应退,不可继续添加",
"discount": "折扣",
"wechatPay": "扫码支付",
"viewResult": "查看结果",
"payType": "支付类型",
"actualTotal": "实收合计",
"refundTotal": "实退合计",
"changeAmount": "应找零",
"confirm": "确 定",
"cancel": "取 消",
"selectChargeItem": "请选择一条收费项目",
"preSettleFail": "预结算失败",
"enterCorrectAmount": "请输入正确的结算金额",
"chargeFail": "收费失败",
"chargeFailRetry": "收费失败,请重试",
"printFail": "打印失败",
"opSuccess": "操作成功",
"outpatientChargeDetail": "门诊收费明细",
"outpatientChargeReceipt": "门诊收费结算单",
"refundReason": "退费原因",
"enterReason": "请输入原因",
"enterReasonPlaceholder": "请输入原因",
"refundConfirm": "确认退费",
"refundDate": "退费日期",
"refundDocNo": "支付单据号",
"itemDocNo": "项目单据号",
"itemNameCol": "项目名称",
"chargeStatusCol": "收费状态",
"paymentTotal": "付款总额",
"refundItem": "退费",
"encounterNo": "就诊号",
"refundDocs": "退费单据",
"enterCorrectRefundAmount": "请输入正确的金额",
"invoiceNo": "发票号",
"invoiceStatus": "发票状态",
"issued": "已开具",
"notIssued": "未开具",
"settleTime": "结算时间",
"startDate": "开始日期",
"endDate": "结束日期",
"query": "查询",
"reset": "重置",
"total": "总数",
"success": "成功",
"batchIssue": "批量开具",
"payStatus": "支付状态",
"feeType": "费用类型",
"insuranceSettleId": "医保结算Id",
"chargeSerialNo": "收费流水号",
"settleAmount": "结算金额",
"payAmountCol": "支付金额",
"settleTimeCol": "结算时间",
"payResult": "支付结果",
"printCount": "打印次数",
"chargeDetail": "收费详情",
"issueInvoice": "开具电子发票",
"writeoffInvoice": "冲销发票",
"viewInvoice": "调阅发票",
"payDetail": "支付类型",
"change": "找零",
"payment": "交款",
"writeoffReason": "冲销原因",
"writeoffSuccess": "红冲成功",
"patientBasicInfo": "患者基本信息",
"surgeryNo": "手术单号",
"surgeryName": "手术名称",
"cardRenewal": "换卡处理",
"patientQuery": "病人查询(Q)",
"confirmBtn": "确定 (O)",
"closeBtn": "关闭 (C)",
"patientNameLabel": "病人姓名:",
"idCardLabel": "身份证号码:",
"phoneLabel": "手机号码:",
"outpatientNo": "门诊号码",
"newOutpatientNo": "新门诊号码:",
"enterNewOutpatientNo": "请输入新门诊号码",
"patientArchiveQuery": "病人档案查询",
"confirmSelect": "确认(Q)",
"closeSelect": "关闭(C)",
"birthDate": "出生年月",
"seqNo": "序号",
"patientName": "患者姓名",
"searchPlaceholderPatient": "请输入患者姓名",
"payBusNo": "支付单号",
"txnAmount": "交易金额(元)",
"txnType": "交易类型",
"payTypeCol": "支付方式",
"txnTime": "交易时间",
"origTxnType": "原交易类型",
"thirdPartyDiscount": "第三方优惠说明",
"errorMsg": "错误信息",
"queryResult": "查询结果",
"queryResultMsg": "查询结果说明",
"payResultQuery": "支付结果查询",
"nextDayRefund": "隔天退费",
"refundResultQuery": "退费结果查询",
"registerChargeRecord": "排班管理",
"schedule": "排班管理",
"detail": "详情",
"normal": "正常",
"disabled": "停用",
"nameCol": "名称",
"dateCol": "日期",
"statusCol": "状态",
"wechat": "微信",
"alipay": "支付宝",
"unionpay": "银联",
"cash": "现金",
"discountLabel": "优惠",
"selfPay": "自费",
"enterCashAmount": "请输入现金金额",
"payMethodPlaceholder": "支付二维码",
"reading": "正在读取...",
"patientCardRenewalSuccess": "换卡成功",
"patientRenewalSuccessMsg": "患者换卡操作已成功完成!",
"pleaseEnterQuery": "请至少输入一个查询条件",
"autoSelectUnique": "已自动选中唯一患者",
"noPatientFound": "未查询到患者信息",
"queryFail": "查询失败",
"queryFailRetry": "查询失败,请稍后重试",
"selectPatient": "请选择患者",
"selectPatientWarning": "已选择患者,请点击确定",
"patientRenewalSuccess": "换卡成功!",
"patientRenewalFail": "换卡失败",
"patientRenewalFailCardExists": "换卡失败,卡号已存在",
"closeConfirm": "确定要关闭此页面吗?",
"cancelClose": "已取消关闭操作",
"newCardNoCannotSame": "新门诊号码不能与原号码相同",
"pleaseQueryPatient": "请先查询患者信息",
"registerChargeRecordTitle": "挂号收费记录",
"reprintRegistration": "补打挂号单",
"reprintTitle": "挂号单重打",
"reprintSubtitle": "补打挂号单将作废原有的挂号单据并生成新的挂号单据",
"doctorName": "医生姓名",
"serialNo": "流水号",
"totalLabel": "合计",
"medicalRecordFee": "病历费",
"printTime": "打印时间",
"visitTimeLabel": "预约/挂号时间",
"enterCardNoSearch": "请输入就诊卡号检索条",
"regRecordSelect": "挂号记录选择",
"enterCardNo": "请输入就诊卡号",
"noRegRecord": "未查询到相关挂号记录,请检查就诊卡号是否正确",
"queryFailMsg": "查询失败: {msg}",
"queryError": "查询出错: {error}",
"reprintSuccess": "补打挂号成功",
"reprintFail": "补打挂号失败",
"reprintFailMsg": "补打挂号失败: {error}",
"selectRegRecordFirst": "请先搜索并选择挂号记录",
"printSuccess": "打印成功",
"printFailMsg": "打印失败: {error}",
"selectRegRecord": "请选择一条挂号记录",
"getRegIdFail": "获取挂号记录ID失败请重试",
"processFail": "处理失败: {error}",
"statusReserved": "已预约",
"statusCompleted": "已完成",
"statusCancelled": "已取消",
"statusInProgress": "进行中"
} }
} }

View File

@@ -1,4 +1,4 @@
<template> <template>
<div class="app-continer"> <div class="app-continer">
<div style="margin: 15px 0; padding: 0 20px"> <div style="margin: 15px 0; padding: 0 20px">
<el-form <el-form
@@ -8,38 +8,38 @@
label-width="90px" label-width="90px"
> >
<el-form-item <el-form-item
label="患者姓名:" :label="$t('billing.patientName') + ''"
prop="searchKey" prop="searchKey"
> >
<el-input <el-input
v-model="queryParams.searchKey" v-model="queryParams.searchKey"
placeholder="患者姓名" :placeholder="$t('billing.searchPlaceholderPatient')"
clearable clearable
style="width: 240px" style="width: 240px"
@keyup.enter="getClinicRecord" @keyup.enter="getClinicRecord"
/> />
</el-form-item> </el-form-item>
<el-form-item <el-form-item
label="发票号:" :label="$t('billing.invoiceNo') + ''"
prop="invoiceNo" prop="invoiceNo"
label-width="120px" label-width="120px"
> >
<el-input <el-input
v-model="queryParams.invoiceNo" v-model="queryParams.invoiceNo"
placeholder="发票号" :placeholder="$t('billing.invoiceNo')"
clearable clearable
style="width: 240px" style="width: 240px"
@keyup.enter="getClinicRecord" @keyup.enter="getClinicRecord"
/> />
</el-form-item> </el-form-item>
<el-form-item <el-form-item
label="发票状态:" :label="$t('billing.invoiceStatus') + ''"
prop="invoiceStatus" prop="invoiceStatus"
> >
<el-select <el-select
v-model="queryParams.invoiceStatus" v-model="queryParams.invoiceStatus"
select select
placeholder="发票状态" :placeholder="$t('billing.invoiceStatus')"
clearable clearable
style="width: 240px" style="width: 240px"
@keyup.enter="getClinicRecord" @keyup.enter="getClinicRecord"
@@ -53,14 +53,14 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item <el-form-item
label="结算时间:" :label="$t('billing.settleTime') + ''"
prop="activeFlag" prop="activeFlag"
> >
<el-date-picker <el-date-picker
v-model="occurrenceTime" v-model="occurrenceTime"
type="daterange" type="daterange"
start-placeholder="开始日期" :start-placeholder="$t('billing.startDate')"
end-placeholder="结束日期" :end-placeholder="$t('billing.endDate')"
style="width: 300px; margin-bottom: 10px; margin-left: 20px" style="width: 300px; margin-bottom: 10px; margin-left: 20px"
value-format="YYYY-MM-DD" value-format="YYYY-MM-DD"
:clearable="false" :clearable="false"
@@ -73,21 +73,21 @@
plain plain
@click="getClinicRecord" @click="getClinicRecord"
> >
查询 {{ $t('billing.query') }}
</el-button> </el-button>
<el-button <el-button
type="warning" type="warning"
plain plain
@click="handleReset" @click="handleReset"
> >
重置 {{ $t('billing.reset') }}
</el-button> </el-button>
</div> </div>
</el-form> </el-form>
</div> </div>
<div style="float: right; margin: 0 20px 10px 0"> <div style="float: right; margin: 0 20px 10px 0">
<span style="margin-right: 20px"> <span style="margin-right: 20px">
{{ '总数:' + count + '/' + '成功' + successCount }} {{ $t('billing.total') + '' + count + '/' + $t('billing.success') + '' + successCount }}
</span> </span>
<el-button <el-button
type="primary" type="primary"
@@ -95,7 +95,7 @@
plain plain
@click="handleBatchProcess" @click="handleBatchProcess"
> >
批量开具 {{ $t('billing.batchIssue') }}
</el-button> </el-button>
</div> </div>
<vxe-table <vxe-table
@@ -104,44 +104,44 @@
> >
<!-- <vxe-column title="计算类型" align="center" field="statusEnum_enumText" /> --> <!-- <vxe-column title="计算类型" align="center" field="statusEnum_enumText" /> -->
<vxe-column <vxe-column
title="患者姓名" :title="$t('billing.patientName')"
align="center" align="center"
field="patientName" field="patientName"
show-overflow="title" show-overflow="title"
/> />
<vxe-column <vxe-column
title="支付状态" :title="$t('billing.payStatus')"
align="center" align="center"
field="statusEnum_dictText" field="statusEnum_dictText"
show-overflow="title" show-overflow="title"
/> />
<vxe-column <vxe-column
title="费用类型" :title="$t('billing.feeType')"
align="center" align="center"
field="paymentEnum_dictText" field="paymentEnum_dictText"
show-overflow="title" show-overflow="title"
/> />
<vxe-column <vxe-column
title="医保结算Id" :title="$t('billing.insuranceSettleId')"
align="center" align="center"
field="ybSettleIds" field="ybSettleIds"
show-overflow="title" show-overflow="title"
/> />
<vxe-column <vxe-column
title="收费流水号" :title="$t('billing.chargeSerialNo')"
align="center" align="center"
field="paymentNo" field="paymentNo"
width="280" width="280"
show-overflow="title" show-overflow="title"
/> />
<vxe-column <vxe-column
title="发票号" :title="$t('billing.invoiceNo')"
align="center" align="center"
field="invoiceNo" field="invoiceNo"
show-overflow="title" show-overflow="title"
/> />
<vxe-column <vxe-column
title="结算金额" :title="$t('billing.settleAmount')"
align="right" align="right"
field="tenderedAmount" field="tenderedAmount"
header-align="center" header-align="center"
@@ -149,11 +149,11 @@
show-overflow="title" show-overflow="title"
> >
<template #default="scope"> <template #default="scope">
<span>{{ scope.row.tenderedAmount + ' ' }}</span> <span>{{ scope.row.tenderedAmount + ' ' + $t('billing.yuan') }}</span>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column <vxe-column
title="支付金额" :title="$t('billing.payAmountCol')"
align="right" align="right"
field="displayAmount" field="displayAmount"
header-align="center" header-align="center"
@@ -161,12 +161,12 @@
show-overflow="title" show-overflow="title"
> >
<template #default="scope"> <template #default="scope">
<span>{{ scope.row.displayAmount + ' ' }}</span> <span>{{ scope.row.displayAmount + ' ' + $t('billing.yuan') }}</span>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column <vxe-column
key="billDate" key="billDate"
title="结算时间" :title="$t('billing.settleTimeCol')"
align="center" align="center"
field="billDate" field="billDate"
@@ -177,26 +177,26 @@
</template> </template>
</vxe-column> </vxe-column>
<vxe-column <vxe-column
title="收款人" :title="$t('billing.cashier')"
align="center" align="center"
field="entererName" field="entererName"
show-overflow="title" show-overflow="title"
/> />
<!-- <vxe-column title="医生" align="center" field="paymentEnum_enumText" /> --> <!-- <vxe-column title="医生" align="center" field="paymentEnum_enumText" /> -->
<vxe-column <vxe-column
title="支付结果" :title="$t('billing.payResult')"
align="center" align="center"
field="outcomeEnum_dictText" field="outcomeEnum_dictText"
show-overflow="title" show-overflow="title"
/> />
<vxe-column <vxe-column
title="打印次数" :title="$t('billing.printCount')"
align="center" align="center"
field="printCount" field="printCount"
show-overflow="title" show-overflow="title"
/> />
<vxe-column <vxe-column
title="操作" :title="$t('billing.operation')"
align="center" align="center"
field="paymentEnum_enumText" field="paymentEnum_enumText"
width="340" width="340"
@@ -209,7 +209,7 @@
link link
@click="handleOpen(scope.row,4)" @click="handleOpen(scope.row,4)"
> >
收费详情 {{ $t('billing.chargeDetail') }}
</el-button> </el-button>
<el-button <el-button
type="primary" type="primary"
@@ -217,7 +217,7 @@
:disabled="scope.row.invoiceNo || scope.row.statusEnum == 3" :disabled="scope.row.invoiceNo || scope.row.statusEnum == 3"
@click="handleOpen(scope.row,1)" @click="handleOpen(scope.row,1)"
> >
开具电子发票 {{ $t('billing.issueInvoice') }}
</el-button> </el-button>
<el-button <el-button
:disabled="!scope.row.relationId" :disabled="!scope.row.relationId"
@@ -225,7 +225,7 @@
link link
@click="handleOpenReasonDialog(scope.row)" @click="handleOpenReasonDialog(scope.row)"
> >
冲销发票 {{ $t('billing.writeoffInvoice') }}
</el-button> </el-button>
<el-button <el-button
type="primary" type="primary"
@@ -233,7 +233,7 @@
:disabled="!scope.row.invoiceNo" :disabled="!scope.row.invoiceNo"
@click="handleOpen(scope.row,3)" @click="handleOpen(scope.row,3)"
> >
调阅发票 {{ $t('billing.viewInvoice') }}
</el-button> </el-button>
</template> </template>
</vxe-column> </vxe-column>
@@ -247,7 +247,7 @@
/> />
<el-dialog <el-dialog
v-model="paymentDetailShow" v-model="paymentDetailShow"
title="收费详情" :title="$t('billing.chargeDetail')"
width="1000" width="1000"
teleported teleported
style="height:90vh" style="height:90vh"
@@ -258,25 +258,25 @@
style="height: 80vh" style="height: 80vh"
> >
<vxe-column <vxe-column
title="支付类型" :title="$t('billing.payType')"
align="center" align="center"
field="payEnum_dictText" field="payEnum_dictText"
show-overflow="title" show-overflow="title"
/> />
<vxe-column <vxe-column
title="金额" :title="$t('billing.amount')"
align="center" align="center"
field="amount" field="amount"
show-overflow="title" show-overflow="title"
/> />
<vxe-column <vxe-column
title="找零" :title="$t('billing.change')"
align="center" align="center"
field="returnAmount" field="returnAmount"
show-overflow="title" show-overflow="title"
/> />
<vxe-column <vxe-column
title="交款" :title="$t('billing.payment')"
align="center" align="center"
field="chargeAmount" field="chargeAmount"
show-overflow="title" show-overflow="title"
@@ -285,17 +285,17 @@
</el-dialog> </el-dialog>
<el-dialog <el-dialog
v-model="reasonDialogVisible" v-model="reasonDialogVisible"
title="请输入原因" :title="$t('billing.enterReason')"
width="30%" width="30%"
> >
<el-form <el-form
:model="reasonForm" :model="reasonForm"
label-width="80px" label-width="80px"
> >
<el-form-item label="冲销原因"> <el-form-item :label="$t('billing.writeoffReason')">
<el-input <el-input
v-model="reasonForm.reason" v-model="reasonForm.reason"
placeholder="请输入原因" :placeholder="$t('billing.enterReasonPlaceholder')"
type="textarea" type="textarea"
:rows="3" :rows="3"
/> />
@@ -303,11 +303,11 @@
</el-form> </el-form>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="reasonDialogVisible = false"> </el-button> <el-button @click="reasonDialogVisible = false">{{ $t('billing.cancel') }}</el-button>
<el-button <el-button
type="primary" type="primary"
@click="submitReason" @click="submitReason"
> </el-button> >{{ $t('billing.confirm') }}</el-button>
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
@@ -315,6 +315,8 @@
</template> </template>
<script setup name="ClinicRecord"> <script setup name="ClinicRecord">
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
import {getList, invoiceOpen, invoiceReissue, invoiceWriteoff, paymentDetail} from './components/api.js'; import {getList, invoiceOpen, invoiceReissue, invoiceWriteoff, paymentDetail} from './components/api.js';
import {formatDate} from '@/utils/index'; import {formatDate} from '@/utils/index';
@@ -330,9 +332,9 @@ const queryParams = ref({
invoiceStatus:1, invoiceStatus:1,
kinsEnum: 1 kinsEnum: 1
}); });
const invoiceStatusList = ref([ const invoiceStatusList = computed(() => [
{ value: 1, label: '已开具' }, { value: 1, label: t('billing.issued') },
{ value: 0, label: '未开具' }, { value: 0, label: t('billing.notIssued') },
]); ]);
const paymentDetailShow = ref(false) const paymentDetailShow = ref(false)
const clinicRecord = ref([]); const clinicRecord = ref([]);
@@ -372,7 +374,7 @@ function handleOpenReasonDialog(row) {
// 提交原因 // 提交原因
function submitReason() { function submitReason() {
if (!reasonForm.value.reason.trim()) { if (!reasonForm.value.reason.trim()) {
proxy.$message.warning('请输入原因'); proxy.$message.warning(t('billing.enterReason'));
return; return;
} }
@@ -381,7 +383,7 @@ function submitReason() {
if(res.data.includes(" 电子票据红冲失败")){ if(res.data.includes(" 电子票据红冲失败")){
proxy.$message.error(res.data); proxy.$message.error(res.data);
}else{ }else{
proxy.$message.success('红冲成功'); proxy.$message.success(t('billing.writeoffSuccess'));
// 关闭弹窗 // 关闭弹窗
reasonDialogVisible.value = false; reasonDialogVisible.value = false;

View File

@@ -1,7 +1,7 @@
<template> <template>
<el-dialog <el-dialog
v-model="props.open" v-model="props.open"
title="确认收费" :title="$t('billing.confirmCharge')"
width="700px" width="700px"
teleported teleported
destroy-on-close destroy-on-close
@@ -13,33 +13,33 @@
size="large" size="large"
style="display: block; margin-bottom: 15px" style="display: block; margin-bottom: 15px"
> >
收费日期{{ currentDate }} {{ $t('billing.chargeDate') }}{{ currentDate }}
</el-text> </el-text>
<el-text size="large"> <el-text size="large">
费用性质{{ '自费' }} {{ $t('billing.feeNature') }}{{ $t('billing.selfPay') }}
</el-text> </el-text>
<div class="amount-row"> <div class="amount-row">
<el-text size="large"> <el-text size="large">
应收金额 {{ $t('billing.receivableAmount') }}
</el-text> </el-text>
<el-text <el-text
size="large" size="large"
type="primary" type="primary"
class="amount" class="amount"
> >
{{ props.totalAmount.toFixed(2) + ' ' }} {{ props.totalAmount.toFixed(2) + ' ' + $t('billing.yuan') }}
</el-text> </el-text>
</div> </div>
<div class="amount-row"> <div class="amount-row">
<el-text size="large"> <el-text size="large">
折扣金额 {{ $t('billing.discountAmount') }}
</el-text> </el-text>
<el-text <el-text
size="large" size="large"
type="warning" type="warning"
class="amount" class="amount"
> >
{{ discountAmount.toFixed(2) + ' ' }} {{ discountAmount.toFixed(2) + ' ' + $t('billing.yuan') }}
</el-text> </el-text>
</div> </div>
@@ -53,7 +53,7 @@
v-show="item.payEnum != 220500" v-show="item.payEnum != 220500"
class="payment-item" class="payment-item"
> >
<span>支付方式</span> <span>{{ $t('billing.payMethod') }}</span>
<img <img
v-if="item.payEnum == 220100 || item.payEnum == 220200" v-if="item.payEnum == 220100 || item.payEnum == 220200"
:src="imgs[item.payEnum == 220100 ? 0 : 1]" :src="imgs[item.payEnum == 220100 ? 0 : 1]"
@@ -61,7 +61,7 @@
> >
<el-select <el-select
v-model="item.payEnum" v-model="item.payEnum"
placeholder="选择支付方式" :placeholder="$t('billing.selectPayMethod')"
style="width: 160px" style="width: 160px"
@change="(value) => clearAmount(index, value)" @change="(value) => clearAmount(index, value)"
> >
@@ -73,7 +73,7 @@
:disabled="isMethodDisabled(payEnum)" :disabled="isMethodDisabled(payEnum)"
/> />
</el-select> </el-select>
<span>支付金额</span> <span>{{ $t('billing.payAmount') }}</span>
<div class="suffix-wrapper"> <div class="suffix-wrapper">
<el-input-number <el-input-number
v-model="item.amount" v-model="item.amount"
@@ -81,11 +81,11 @@
:min="0" :min="0"
:max="getMax(index)" :max="getMax(index)"
:controls="false" :controls="false"
placeholder="金额" :placeholder="$t('billing.amount')"
class="amount-input" class="amount-input"
@change="handleAmountChange" @change="handleAmountChange"
/> />
<span class="suffix-text"></span> <span class="suffix-text">{{ $t('billing.yuan') }}</span>
</div> </div>
<el-button <el-button
v-if="index > 0" v-if="index > 0"
@@ -103,21 +103,21 @@
:disabled="formData.selfPay.length >= 4 || remainingAmount <= 0" :disabled="formData.selfPay.length >= 4 || remainingAmount <= 0"
@click="addPayment" @click="addPayment"
> >
添加支付方式 {{ $t('billing.addPayMethod') }}
</el-button> </el-button>
<el-text <el-text
v-if="remainingAmount <= 0" v-if="remainingAmount <= 0"
type="danger" type="danger"
class="tip" class="tip"
> >
金额已满足应收不可继续添加 {{ $t('billing.amountSatisfied') }}
</el-text> </el-text>
</div> </div>
<div <div
v-if="userStore.hospitalName == '同一医院'" v-if="userStore.hospitalName == '同一医院'"
style="margin-top: 10px" style="margin-top: 10px"
> >
<span>折扣</span> <span>{{ $t('billing.discount') }}</span>
<el-radio-group <el-radio-group
v-model="discountRadio" v-model="discountRadio"
@change="handleDiscountChange" @change="handleDiscountChange"
@@ -132,7 +132,7 @@
</div> </div>
</div> </div>
<div class="payment-item"> <div class="payment-item">
<span>{{ payTypeText }}支付</span> <span>{{ payTypeTextDisplay }}{{ $t('billing.payMethod') }}</span>
<el-input <el-input
ref="txtCodeRef" ref="txtCodeRef"
v-model="txtCode" v-model="txtCode"
@@ -144,14 +144,14 @@
type="primary" type="primary"
@click="handleWxPay()" @click="handleWxPay()"
> >
扫码支付 {{ $t('billing.wechatPay') }}
</el-button> </el-button>
<el-button <el-button
link link
type="primary" type="primary"
@click="getWxPayResult()" @click="getWxPayResult()"
> >
查看结果 {{ $t('billing.viewResult') }}
</el-button> </el-button>
</div> </div>
<div> <div>
@@ -162,18 +162,18 @@
> >
<vxe-column <vxe-column
field="payEnumText" field="payEnumText"
title="支付类型" :title="$t('billing.payType')"
align="center" align="center"
/> />
<vxe-column <vxe-column
field="amount" field="amount"
title="金额" :title="$t('billing.amount')"
header-align="center" header-align="center"
align="right" align="right"
width="200" width="200"
> >
<template #default="scope"> <template #default="scope">
{{ scope.row.amount ? scope.row.amount + ' ' : '-' }} {{ scope.row.amount ? scope.row.amount + ' ' + $t('billing.yuan') : '-' }}
</template> </template>
</vxe-column> </vxe-column>
</vxe-table> </vxe-table>
@@ -183,18 +183,18 @@
<el-space :size="30"> <el-space :size="30">
<div class="summary-item"> <div class="summary-item">
<el-text type="info"> <el-text type="info">
实收合计 {{ $t('billing.actualTotal') }}
</el-text> </el-text>
<el-text type="success"> <el-text type="success">
{{ displayAmount + ' ' }} {{ displayAmount + ' ' + $t('billing.yuan') }}
</el-text> </el-text>
</div> </div>
<div class="summary-item"> <div class="summary-item">
<el-text type="info"> <el-text type="info">
应找零 {{ $t('billing.changeAmount') }}
</el-text> </el-text>
<el-text type="warning"> <el-text type="warning">
{{ returnedAmount + ' ' }} {{ returnedAmount + ' ' + $t('billing.yuan') }}
</el-text> </el-text>
</div> </div>
</el-space> </el-space>
@@ -207,14 +207,14 @@
:disabled="dialogLoading" :disabled="dialogLoading"
@click="throttledGetList" @click="throttledGetList"
> >
{{ $t('billing.confirm') }}
</el-button> </el-button>
<!-- <el-button type="primary" @click="print()" :disabled="dialogLoading"> </el-button> --> <!-- <el-button type="primary" @click="print()" :disabled="dialogLoading"> </el-button> -->
<el-button <el-button
:disabled="dialogLoading" :disabled="dialogLoading"
@click="close" @click="close"
> >
{{ $t('billing.cancel') }}
</el-button> </el-button>
</div> </div>
</template> </template>
@@ -232,6 +232,9 @@ import templateJson from './template.json';
import printUtils, {PRINT_TEMPLATE} from '@/utils/printUtils'; import printUtils, {PRINT_TEMPLATE} from '@/utils/printUtils';
import image1 from '../../../../assets/images/weixinzhifu.png'; import image1 from '../../../../assets/images/weixinzhifu.png';
import image2 from '../../../../assets/images/zhifubaozhifu.png'; import image2 from '../../../../assets/images/zhifubaozhifu.png';
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
const imgs = ref([image1, image2]); const imgs = ref([image1, image2]);
const props = defineProps({ const props = defineProps({
@@ -617,7 +620,7 @@ async function printReceipt(param) {
personType: param.contractName, personType: param.contractName,
fixmedinsName: (param.fixmedinsName || '') + '门诊收费明细', fixmedinsName: (param.fixmedinsName || '') + t('billing.outpatientChargeDetail'),
//电子收据二维码 //电子收据二维码
pictureUrl: param.pictureUrl || 'https://chinaebill.com/img/xiaochengxu.png', pictureUrl: param.pictureUrl || 'https://chinaebill.com/img/xiaochengxu.png',
@@ -666,7 +669,7 @@ async function printReceipt(param) {
console.error('[ERROR] 错误详情:', error.message); console.error('[ERROR] 错误详情:', error.message);
console.error('[ERROR] 错误堆栈:', error.stack); console.error('[ERROR] 错误堆栈:', error.stack);
console.log('========== 打印收费小票 - 异常结束 =========='); console.log('========== 打印收费小票 - 异常结束 ==========');
proxy.$modal.msgError('打印失败: ' + error.message); proxy.$modal.msgError(t('billing.printFail') + ': ' + error.message);
} }
} }
const throttledGetList = debounce(submit, 300); const throttledGetList = debounce(submit, 300);
@@ -709,7 +712,7 @@ async function submit() {
}, 0) }, 0)
.toFixed(2); .toFixed(2);
if (parseFloat(amount) < parseFloat(formData.totalAmount.toFixed(2))) { if (parseFloat(amount) < parseFloat(formData.totalAmount.toFixed(2))) {
proxy.$modal.msgError('请输入正确的结算金额'); proxy.$modal.msgError(t('billing.enterCorrectAmount'));
return; return;
} }
dialogLoading.value = true; dialogLoading.value = true;
@@ -743,12 +746,12 @@ async function submit() {
}); });
} }
} else { } else {
proxy.$modal.msgError(res.msg || '收费失败'); proxy.$modal.msgError(res.msg || t('billing.chargeFail'));
} }
}) })
.catch((error) => { .catch((error) => {
console.error('收费失败:', error); console.error('收费失败:', error);
proxy.$modal.msgError(error.message || '收费失败,请重试'); proxy.$modal.msgError(error.message || t('billing.chargeFailRetry'));
}) })
.finally(() => { .finally(() => {
dialogLoading.value = false; dialogLoading.value = false;
@@ -775,9 +778,9 @@ async function print() {
encounterBusNo: props.patientInfo.encounterBusNo, // 病例号 encounterBusNo: props.patientInfo.encounterBusNo, // 病例号
currentDate: currentDate.value, // 收费日期 currentDate: currentDate.value, // 收费日期
chargedItems: props.chargedItems, // 收费项目 chargedItems: props.chargedItems, // 收费项目
totalAmount: props.totalAmount.toFixed(2) + ' ', // 应收金额 totalAmount: props.totalAmount.toFixed(2) + ' ' + t('billing.yuan'), // 应收金额
displayAmount: displayAmount.value + ' ', // 实收金额 displayAmount: displayAmount.value + ' ' + t('billing.yuan'), // 实收金额
returnedAmount: returnedAmount.value + ' ', // 应找零 returnedAmount: returnedAmount.value + ' ' + t('billing.yuan'), // 应找零
}, },
], ],
}; };
@@ -790,19 +793,19 @@ async function print() {
const printerList = hiprintTemplate.getPrinterList(); const printerList = hiprintTemplate.getPrinterList();
console.log(hiprintTemplate, '打印机列表'); console.log(hiprintTemplate, '打印机列表');
hiprintTemplate.print2(result.data[0], { hiprintTemplate.print2(result.data[0], {
title: '门诊收费结算单', title: t('billing.outpatientChargeReceipt'),
}); });
} }
const currentDate = ref(new Date().toLocaleString()); const currentDate = ref(new Date().toLocaleString());
const selfPayMethods = [ const selfPayMethods = computed(() => [
{ label: '现金', value: 220400, isWebPay: false }, { label: t('billing.cash'), labelKey: 'billing.cash', value: 220400, isWebPay: false },
{ label: '微信', value: 220100, isWebPay: true }, { label: t('billing.wechat'), labelKey: 'billing.wechat', value: 220100, isWebPay: true },
{ label: '支付宝', value: 220200, isWebPay: true }, { label: t('billing.alipay'), labelKey: 'billing.alipay', value: 220200, isWebPay: true },
{ label: '银联', value: 220300, isWebPay: true }, { label: t('billing.unionpay'), labelKey: 'billing.unionpay', value: 220300, isWebPay: true },
{ label: '优惠', value: 220500, isWebPay: false }, { label: t('billing.discountLabel'), labelKey: 'billing.discountLabel', value: 220500, isWebPay: false },
]; ]);
// 计算剩余可输入金额 // 计算剩余可输入金额
const remainingAmount = computed(() => { const remainingAmount = computed(() => {
@@ -843,7 +846,7 @@ const isMethodDisabled = (option) => {
} }
// 若已经选择了任一线上支付方式,则其他线上方式不可再选,仅允许现金等线下方式 // 若已经选择了任一线上支付方式,则其他线上方式不可再选,仅允许现金等线下方式
const hasSelectedWebPay = selectedEnums.some((val) => { const hasSelectedWebPay = selectedEnums.some((val) => {
const found = selfPayMethods.find((m) => m.value === val); const found = selfPayMethods.value.find((m) => m.value === val);
return found ? found.isWebPay === true : false; return found ? found.isWebPay === true : false;
}); });
if (hasSelectedWebPay && option.isWebPay) { if (hasSelectedWebPay && option.isWebPay) {
@@ -870,17 +873,18 @@ const removePayment = (index) => {
formData.selfPay.splice(index, 1); formData.selfPay.splice(index, 1);
}; };
const payTypeText = ref('微信'); const payTypeText = ref('billing.wechat');
const payTypeTextDisplay = computed(() => t(payTypeText.value));
const payTypePlaceholder = computed(() => { const payTypePlaceholder = computed(() => {
if (payTypeText.value === '现金') { if (payTypeText.value === 'billing.cash') {
return '请输入现金金额'; return t('billing.enterCashAmount');
} }
return payTypeText.value + '支付二维码'; return t(payTypeText.value) + t('billing.payMethodPlaceholder');
}); });
const clearAmount = (index, value) => { const clearAmount = (index, value) => {
const selectedOption = selfPayMethods.find((item) => item.value === value); const selectedOption = selfPayMethods.value.find((item) => item.value === value);
if (selectedOption) { if (selectedOption) {
payTypeText.value = selectedOption.label; payTypeText.value = selectedOption.labelKey;
} }
}; };

View File

@@ -7,12 +7,12 @@
> >
<el-card style="width: 30%"> <el-card style="width: 30%">
<template #header> <template #header>
<span style="vertical-align: middle">患者列表</span> <span style="vertical-align: middle">{{ $t('billing.patientList') }}</span>
</template> </template>
<div style="width: 100%"> <div style="width: 100%">
<el-input <el-input
v-model="queryParams.searchKey" v-model="queryParams.searchKey"
placeholder="请输入患者名/病历号" :placeholder="$t('billing.searchPlaceholder')"
clearable clearable
style="width: 48%; margin-bottom: 10px; margin-right: 10px" style="width: 48%; margin-bottom: 10px; margin-right: 10px"
@keyup.enter="getPatientList" @keyup.enter="getPatientList"
@@ -27,7 +27,7 @@
<el-select <el-select
v-model="queryParams.statusEnum" v-model="queryParams.statusEnum"
style="width: 48%; margin-bottom: 10px; margin-right: 10px" style="width: 48%; margin-bottom: 10px; margin-right: 10px"
placeholder="收费状态" :placeholder="$t('billing.chargeStatus')"
@change="getPatientList" @change="getPatientList"
> >
<el-option <el-option
@@ -42,8 +42,8 @@
v-model="receptionTime" v-model="receptionTime"
type="daterange" type="daterange"
range-separator="~" range-separator="~"
start-placeholder="开始时间" :start-placeholder="$t('billing.startTime')"
end-placeholder="结束时间" :end-placeholder="$t('billing.endTime')"
placement="bottom" placement="bottom"
value-format="YYYY-MM-DD" value-format="YYYY-MM-DD"
style="width: 84%; margin-bottom: 10px; margin-right: 10px" style="width: 84%; margin-bottom: 10px; margin-right: 10px"
@@ -54,7 +54,7 @@
style="margin-bottom: 10px" style="margin-bottom: 10px"
@click="getPatientList" @click="getPatientList"
> >
搜索 {{ $t('billing.search') }}
</el-button> </el-button>
</div> </div>
<vxe-table <vxe-table
@@ -65,12 +65,12 @@
@cell-click="clickRow" @cell-click="clickRow"
> >
<vxe-column <vxe-column
title="病历号" :title="$t('billing.medicalRecordNo')"
align="center" align="center"
field="encounterBusNo" field="encounterBusNo"
/> />
<vxe-column <vxe-column
title="姓名" :title="$t('billing.name')"
align="center" align="center"
field="patientName" field="patientName"
/> />
@@ -80,7 +80,7 @@
</template> </template>
</vxe-column> --> </vxe-column> -->
<vxe-column <vxe-column
title="收费状态" :title="$t('billing.chargeStatus')"
align="center" align="center"
field="statusEnum_enumText" field="statusEnum_enumText"
/> />
@@ -90,22 +90,22 @@
<div style="width: 69%"> <div style="width: 69%">
<el-card style="margin-bottom: 20px"> <el-card style="margin-bottom: 20px">
<template #header> <template #header>
<span style="vertical-align: middle">基本信息</span> <span style="vertical-align: middle">{{ $t('billing.basicInfo') }}</span>
</template> </template>
<el-descriptions :column="5"> <el-descriptions :column="5">
<el-descriptions-item label="姓名:"> <el-descriptions-item :label="$t('billing.name') + ':'">
{{ patientInfo.patientName }} {{ patientInfo.patientName }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="性别:"> <el-descriptions-item :label="$t('billing.gender') + ':'">
{{ patientInfo.genderEnum_enumText }} {{ patientInfo.genderEnum_enumText }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="年龄:"> <el-descriptions-item :label="$t('billing.age') + ':'">
{{ patientInfo.age }} {{ patientInfo.age }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="科室:"> <el-descriptions-item :label="$t('billing.department') + ':'">
{{ patientInfo.organizationName }} {{ patientInfo.organizationName }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="就诊时间:"> <el-descriptions-item :label="$t('billing.visitTime') + ':'">
{{ formatDateStr(patientInfo.receptionTime, 'YYYY-MM-DD HH:mm:ss') }} {{ formatDateStr(patientInfo.receptionTime, 'YYYY-MM-DD HH:mm:ss') }}
</el-descriptions-item> </el-descriptions-item>
<!-- <el-descriptions-item label="身份证号:">{{ patientInfo.idCard }}</el-descriptions-item> --> <!-- <el-descriptions-item label="身份证号:">{{ patientInfo.idCard }}</el-descriptions-item> -->
@@ -115,7 +115,7 @@
</el-card> </el-card>
<el-card style="min-width: 1100px"> <el-card style="min-width: 1100px">
<template #header> <template #header>
<span style="vertical-align: middle">收费项目</span> <span style="vertical-align: middle">{{ $t('billing.chargeItems') }}</span>
</template> </template>
<div style="margin-bottom: 10px"> <div style="margin-bottom: 10px">
<el-button <el-button
@@ -123,7 +123,7 @@
:disabled="buttonDisabled" :disabled="buttonDisabled"
@click="confirmCharge()" @click="confirmCharge()"
> >
确认收费 {{ $t('billing.confirmCharge') }}
</el-button> </el-button>
<el-button <el-button
type="primary" type="primary"
@@ -131,7 +131,7 @@
style="width: 65px" style="width: 65px"
@click="handleReadCard('01')" @click="handleReadCard('01')"
> >
电子凭证 {{ $t('billing.electronicCertificate') }}
</el-button> </el-button>
<el-button <el-button
type="primary" type="primary"
@@ -140,7 +140,7 @@
:disabled="true" :disabled="true"
@click="handleReadCard('02')" @click="handleReadCard('02')"
> >
身份证 {{ $t('billing.idCard') }}
</el-button> </el-button>
<el-button <el-button
type="primary" type="primary"
@@ -148,7 +148,7 @@
style="width: 65px" style="width: 65px"
@click="handleReadCard('03')" @click="handleReadCard('03')"
> >
医保卡 {{ $t('billing.medicalInsuranceCard') }}
</el-button> </el-button>
<el-button <el-button
type="primary" type="primary"
@@ -156,7 +156,7 @@
:disabled="buttonDisabled" :disabled="buttonDisabled"
@click="payToSelt()" @click="payToSelt()"
> >
医保转自费 {{ $t('billing.insuranceToSelf') }}
</el-button> </el-button>
<el-button <el-button
type="primary" type="primary"
@@ -164,7 +164,7 @@
:disabled="buttonDisabled" :disabled="buttonDisabled"
@click="patToMedicalInsurance()" @click="patToMedicalInsurance()"
> >
自费转医保 {{ $t('billing.selfToInsurance') }}
</el-button> </el-button>
<el-button <el-button
type="primary" type="primary"
@@ -172,7 +172,7 @@
:disabled="buttonDisabled" :disabled="buttonDisabled"
@click="studentPayTosStudentSelf()" @click="studentPayTosStudentSelf()"
> >
学生医保转学生自费 {{ $t('billing.studentInsuranceToSelf') }}
</el-button> </el-button>
<el-button <el-button
type="primary" type="primary"
@@ -180,11 +180,11 @@
:disabled="buttonDisabled" :disabled="buttonDisabled"
@click="studentSelfToStudentPay()" @click="studentSelfToStudentPay()"
> >
学生自费转学生医保 {{ $t('billing.studentSelfToInsurance') }}
</el-button> </el-button>
</div> </div>
<div style="text-align: right; padding-right: 20px; margin-bottom: 10px;"> <div style="text-align: right; padding-right: 20px; margin-bottom: 10px;">
<span style="font-weight: bold; font-size: 14px;">合计金额{{ totalAmounts ? totalAmounts.toFixed(2) : 0 }}</span> <span style="font-weight: bold; font-size: 14px;">{{ $t('billing.totalAmount') }}{{ totalAmounts ? totalAmounts.toFixed(2) : 0 }}{{ $t('billing.yuan') }}</span>
</div> </div>
<vxe-table <vxe-table
ref="chargeListRef" ref="chargeListRef"
@@ -201,40 +201,40 @@
width="55" width="55"
/> />
<vxe-column <vxe-column
title="单据号" :title="$t('billing.docNo')"
align="center" align="center"
field="busNo" field="busNo"
width="180" width="180"
/> />
<vxe-column <vxe-column
title="收费项目" :title="$t('billing.chargeItems')"
align="center" align="center"
field="itemName" field="itemName"
width="200" width="200"
/> />
<vxe-column <vxe-column
title="数量" :title="$t('billing.quantity')"
align="center" align="center"
field="quantityValue" field="quantityValue"
width="80" width="80"
/> />
<vxe-column <vxe-column
title="医疗类型" :title="$t('billing.medicalType')"
align="center" align="center"
field="medTypeCode_dictText" field="medTypeCode_dictText"
/> />
<vxe-column <vxe-column
title="医保编码" :title="$t('billing.insuranceCode')"
align="center" align="center"
field="ybNo" field="ybNo"
/> />
<vxe-column <vxe-column
title="费用性质" :title="$t('billing.feeNature')"
align="center" align="center"
field="contractName" field="contractName"
/> />
<vxe-column <vxe-column
title="收费状态" :title="$t('billing.chargeStatus')"
align="center" align="center"
field="statusEnum_enumText" field="statusEnum_enumText"
width="150" width="150"
@@ -270,22 +270,22 @@
</template> </template>
</vxe-column> </vxe-column>
<vxe-column <vxe-column
title="金额" :title="$t('billing.amount')"
align="right" align="right"
field="totalPrice" field="totalPrice"
header-align="center" header-align="center"
> >
<template #default="scope"> <template #default="scope">
{{ scope.row.totalPrice.toFixed(2) + ' 元' || '0.00' + ' 元' }} {{ scope.row.totalPrice.toFixed(2) + ' ' + $t('billing.yuan') || '0.00' + ' ' + $t('billing.yuan') }}
</template> </template>
</vxe-column> </vxe-column>
<vxe-column <vxe-column
title="收款人" :title="$t('billing.cashier')"
align="center" align="center"
field="entererId_dictText" field="entererId_dictText"
/> />
<vxe-column <vxe-column
title="操作" :title="$t('billing.operation')"
align="center" align="center"
fixed="right" fixed="right"
header-align="center" header-align="center"
@@ -298,7 +298,7 @@
type="primary" type="primary"
@click="printCharge(scope.row)" @click="printCharge(scope.row)"
> >
打印 {{ $t('billing.print') }}
</el-button> </el-button>
</template> </template>
</vxe-column> </vxe-column>
@@ -344,7 +344,9 @@ import ChargeDialog from './components/chargeDialog.vue';
import {formatDateStr} from '@/utils'; import {formatDateStr} from '@/utils';
import useUserStore from '@/store/modules/user'; import useUserStore from '@/store/modules/user';
import Decimal from 'decimal.js'; import Decimal from 'decimal.js';
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const userStore = useUserStore(); const userStore = useUserStore();
const { medfee_paymtd_code } = proxy.useDict('medfee_paymtd_code'); const { medfee_paymtd_code } = proxy.useDict('medfee_paymtd_code');
@@ -368,7 +370,13 @@ const openDialog = ref(false);
const totalAmount = ref(0); const totalAmount = ref(0);
const chargeListRef = ref(); const chargeListRef = ref();
const details = ref({}); const details = ref({});
const chargeStatusOptions = ref([]); const chargeStatusOptionsRaw = ref([]);
const chargeStatusOptions = computed(() => {
return (chargeStatusOptionsRaw.value || []).map(item => ({
value: item.value,
label: item.label ? t('billing.' + item.label, item.label) : item.label,
}));
});
const receptionTime = ref([ const receptionTime = ref([
formatDateStr(new Date(), 'YYYY-MM-DD'), formatDateStr(new Date(), 'YYYY-MM-DD'),
formatDateStr(new Date(), 'YYYY-MM-DD'), formatDateStr(new Date(), 'YYYY-MM-DD'),
@@ -435,7 +443,7 @@ function getPatientList() {
function initOption() { function initOption() {
init().then((res) => { init().then((res) => {
chargeStatusOptions.value = res.data.chargeItemStatusOptions; chargeStatusOptionsRaw.value = res.data.chargeItemStatusOptions;
}); });
} }
@@ -487,7 +495,7 @@ const consumablesIdList = ref([]);
function confirmCharge() { function confirmCharge() {
let selectRows = chargeListRef.value.getSelectionRows(); let selectRows = chargeListRef.value.getSelectionRows();
if (selectRows.length == 0) { if (selectRows.length == 0) {
proxy.$modal.msgWarning('请选择一条收费项目'); proxy.$modal.msgWarning(t('billing.selectChargeItem'));
return; return;
} }
chargeItemIdList.value = selectRows.map((item) => { chargeItemIdList.value = selectRows.map((item) => {
@@ -523,7 +531,7 @@ function confirmCharge() {
}) || []; }) || [];
openDialog.value = true; openDialog.value = true;
} else { } else {
proxy.$modal.msgError(res?.msg || '预结算失败'); proxy.$modal.msgError(res?.msg || t('billing.preSettleFail'));
} }
}); });
// console.log(patientInfo) // console.log(patientInfo)
@@ -566,7 +574,7 @@ async function handleReadCard(value) {
}) })
.then((res) => { .then((res) => {
readCardLoading.value = true; readCardLoading.value = true;
loadingText.value = '正在读取...'; loadingText.value = t('billing.reading');
jsonResult = res.data; jsonResult = res.data;
}) })
.catch(() => { .catch(() => {
@@ -578,24 +586,24 @@ async function handleReadCard(value) {
cardInfo = JSON.parse(JSON.stringify(jsonResult)); cardInfo = JSON.parse(JSON.stringify(jsonResult));
let message = JSON.parse(cardInfo.data); let message = JSON.parse(cardInfo.data);
userMessage = { userMessage = {
certType: '02', // 证件类型 certType: '02',
certNo: message.data.idNo, // 身份证号 certNo: message.data.idNo,
psnCertType: '02', // 居民身份证 psnCertType: '02',
}; };
userCardInfo = { userCardInfo = {
certType: '01', // 证件类型 certType: '01',
certNo: message.data.idNo, // 身份证号 certNo: message.data.idNo,
psnCertType: '01', // 居民身份证 psnCertType: '01',
busiCardInfo: message.data.ecToken, // 令牌 busiCardInfo: message.data.ecToken,
}; };
BusiCardInfo.value = message.data.ecToken; BusiCardInfo.value = message.data.ecToken;
console.log(BusiCardInfo.value); console.log(BusiCardInfo.value);
break; break;
case '02': case '02':
break; break;
case '03': // 社保卡 case '03':
readCardLoading.value = true; readCardLoading.value = true;
loadingText.value = '正在读取...'; loadingText.value = t('billing.reading');
await invokeYbPlugin5001( await invokeYbPlugin5001(
JSON.stringify({ JSON.stringify({
FunctionId: 1, FunctionId: 1,
@@ -651,7 +659,7 @@ async function handleReadCard(value) {
if (userMessage.certNo) { if (userMessage.certNo) {
let selectRows = chargeListRef.value.getSelectionRows(); let selectRows = chargeListRef.value.getSelectionRows();
if (selectRows.length == 0) { if (selectRows.length == 0) {
proxy.$modal.msgWarning('请选择一条收费项目'); proxy.$modal.msgWarning(t('billing.selectChargeItem'));
return; return;
} }
chargeItemIdList.value = selectRows.map((item) => { chargeItemIdList.value = selectRows.map((item) => {
@@ -687,7 +695,7 @@ async function handleReadCard(value) {
}); });
openDialog.value = true; openDialog.value = true;
} else { } else {
proxy.$modal.msgError(res?.msg || '预结算失败'); proxy.$modal.msgError(res?.msg || t('billing.preSettleFail'));
} }
}); });
} }
@@ -704,7 +712,7 @@ async function handleReadCard(value) {
function payToSelt() { function payToSelt() {
changeToSelfPay(encounterId.value).then((res) => { changeToSelfPay(encounterId.value).then((res) => {
if (res.code == 200) { if (res.code == 200) {
proxy.$modal.msgSuccess('操作成功'); proxy.$modal.msgSuccess(t('billing.opSuccess'));
} }
}); });
} }
@@ -715,7 +723,7 @@ function payToSelt() {
function patToMedicalInsurance() { function patToMedicalInsurance() {
changeToMedicalInsurance(encounterId.value).then((res) => { changeToMedicalInsurance(encounterId.value).then((res) => {
if (res.code == 200) { if (res.code == 200) {
proxy.$modal.msgSuccess('操作成功'); proxy.$modal.msgSuccess(t('billing.opSuccess'));
} }
}); });
} }
@@ -726,7 +734,7 @@ function patToMedicalInsurance() {
function studentPayTosStudentSelf() { function studentPayTosStudentSelf() {
changeStudentPayTosStudentSelf(encounterId.value).then((res) => { changeStudentPayTosStudentSelf(encounterId.value).then((res) => {
if (res.code == 200) { if (res.code == 200) {
proxy.$modal.msgSuccess('操作成功'); proxy.$modal.msgSuccess(t('billing.opSuccess'));
} }
}); });
} }
@@ -737,7 +745,7 @@ function studentPayTosStudentSelf() {
function studentSelfToStudentPay() { function studentSelfToStudentPay() {
changeStudentSelfToStudentPay(encounterId.value).then((res) => { changeStudentSelfToStudentPay(encounterId.value).then((res) => {
if (res.code == 200) { if (res.code == 200) {
proxy.$modal.msgSuccess('操作成功'); proxy.$modal.msgSuccess(t('billing.opSuccess'));
} }
}); });
} }

View File

@@ -1,7 +1,7 @@
<template> <template>
<el-dialog <el-dialog
v-model="props.open" v-model="props.open"
title="确认退费" :title="$t('billing.refundConfirm')"
width="700px" width="700px"
teleported teleported
destroy-on-close destroy-on-close
@@ -12,21 +12,21 @@
size="large" size="large"
style="display: block; margin-bottom: 15px" style="display: block; margin-bottom: 15px"
> >
退费日期{{ currentDate }} {{ $t('billing.refundDate') + '' }}{{ currentDate }}
</el-text> </el-text>
<el-text size="large"> <el-text size="large">
费用性质{{ getFeeTypeText }} {{ $t('billing.feeNature') + '' }}{{ getFeeTypeText }}
</el-text> </el-text>
<div class="amount-row"> <div class="amount-row">
<el-text size="large"> <el-text size="large">
应退金额 {{ $t('billing.refundAmount') + '' }}
</el-text> </el-text>
<el-text <el-text
size="large" size="large"
type="primary" type="primary"
class="amount" class="amount"
> >
{{ props.totalAmount.toFixed(2) + ' ' }} {{ props.totalAmount.toFixed(2) + ' ' + $t('billing.yuan') }}
</el-text> </el-text>
</div> </div>
@@ -37,10 +37,10 @@
:key="index" :key="index"
class="payment-item" class="payment-item"
> >
<span>退费方式</span> <span>{{ $t('billing.refundMethod') + '' }}</span>
<el-select <el-select
v-model="item.payEnum" v-model="item.payEnum"
placeholder="选择退费方式" :placeholder="$t('billing.selectRefundMethod')"
style="width: 160px" style="width: 160px"
@change="clearAmount(index)" @change="clearAmount(index)"
> >
@@ -52,7 +52,7 @@
:disabled="isMethodDisabled(payEnum.value)" :disabled="isMethodDisabled(payEnum.value)"
/> />
</el-select> </el-select>
<span>退费金额</span> <span>{{ $t('billing.refundAmountLabel') + '' }}</span>
<div class="suffix-wrapper"> <div class="suffix-wrapper">
<el-input-number <el-input-number
v-model="item.amount" v-model="item.amount"
@@ -64,7 +64,7 @@
class="amount-input" class="amount-input"
@change="handleAmountChange" @change="handleAmountChange"
/> />
<span class="suffix-text"></span> <span class="suffix-text">{{ $t('billing.yuan') }}</span>
</div> </div>
<el-button <el-button
v-if="index > 0" v-if="index > 0"
@@ -78,12 +78,12 @@
class="payment-container" class="payment-container"
style="position: relative" style="position: relative"
> >
<span style="position: absolute; top: 5px">退费原因</span> <span style="position: absolute; top: 5px">{{ $t('billing.refundReason') + '' }}</span>
<el-input <el-input
v-model="reason" v-model="reason"
type="textarea" type="textarea"
:rows="2" :rows="2"
placeholder="退费原因" :placeholder="$t('billing.refundReason')"
class="reason-textarea" class="reason-textarea"
@change="handleAmountChange" @change="handleAmountChange"
/> />
@@ -95,14 +95,14 @@
:disabled="formData.selfPay.length >= 4 || remainingAmount <= 0" :disabled="formData.selfPay.length >= 4 || remainingAmount <= 0"
@click="addPayment" @click="addPayment"
> >
添加退费方式 {{ $t('billing.addRefundMethod') }}
</el-button> </el-button>
<el-text <el-text
v-if="remainingAmount <= 0" v-if="remainingAmount <= 0"
type="danger" type="danger"
class="tip" class="tip"
> >
金额已满足应退不可继续添加 {{ $t('billing.refundAmountSatisfied') }}
</el-text> </el-text>
</div> </div>
</div> </div>
@@ -114,18 +114,18 @@
> >
<vxe-column <vxe-column
field="payEnum_dictText" field="payEnum_dictText"
title="支付类型" :title="$t('billing.payType')"
align="center" align="center"
/> />
<vxe-column <vxe-column
field="amount" field="amount"
title="金额" :title="$t('billing.amount')"
header-align="center" header-align="center"
align="right" align="right"
width="200" width="200"
> >
<template #default="scope"> <template #default="scope">
{{ scope.row.amount ? scope.row.amount + ' ' : '-' }} {{ scope.row.amount ? scope.row.amount + ' ' + $t('billing.yuan') : '-' }}
</template> </template>
</vxe-column> </vxe-column>
</vxe-table> </vxe-table>
@@ -135,10 +135,10 @@
<el-space :size="30"> <el-space :size="30">
<div class="summary-item"> <div class="summary-item">
<el-text type="info"> <el-text type="info">
实退合计 {{ $t('billing.refundTotal') + '' }}
</el-text> </el-text>
<el-text type="success"> <el-text type="success">
{{ displayAmount + ' ' }} {{ displayAmount + ' ' + $t('billing.yuan') }}
</el-text> </el-text>
</div> </div>
<!-- <div class="summary-item"> <!-- <div class="summary-item">
@@ -154,10 +154,10 @@
type="primary" type="primary"
@click="submit" @click="submit"
> >
{{ $t('billing.confirm') }}
</el-button> </el-button>
<el-button @click="close"> <el-button @click="close">
{{ $t('billing.cancel') }}
</el-button> </el-button>
</div> </div>
</template> </template>
@@ -167,6 +167,8 @@
<script setup> <script setup>
import {getReturnMedicineList, refund, renturnDispenseMedical} from './api'; import {getReturnMedicineList, refund, renturnDispenseMedical} from './api';
import {computed, getCurrentInstance, reactive, ref, watch} from 'vue'; import {computed, getCurrentInstance, reactive, ref, watch} from 'vue';
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
import {Delete} from '@element-plus/icons-vue'; import {Delete} from '@element-plus/icons-vue';
import useUserStore from '@/store/modules/user'; import useUserStore from '@/store/modules/user';
@@ -247,7 +249,7 @@ function submit() {
); );
//比较时,将金额都转换为两位小数的字符串再转换为浮点数,避免浮点数精度问题 //比较时,将金额都转换为两位小数的字符串再转换为浮点数,避免浮点数精度问题
if (parseFloat(displayAmount.value) < parseFloat(formData.totalAmount.toFixed(2))) { if (parseFloat(displayAmount.value) < parseFloat(formData.totalAmount.toFixed(2))) {
proxy.$modal.msgError('请输入正确的金额'); proxy.$modal.msgError(t('billing.enterCorrectRefundAmount'));
return; return;
} }
if (userStore.fixmedinsCode == '1123123') { if (userStore.fixmedinsCode == '1123123') {
@@ -313,12 +315,12 @@ function submit() {
const currentDate = ref(new Date().toLocaleString()); const currentDate = ref(new Date().toLocaleString());
const selfPayMethods = [ const selfPayMethods = computed(() => [
{ label: '现金', value: 220400 }, { label: t('billing.cash'), value: 220400 },
{ label: '微信', value: 220100 }, { label: t('billing.wechat'), value: 220100 },
{ label: '支付宝', value: 220200 }, { label: t('billing.alipay'), value: 220200 },
{ label: '银联', value: 220300 }, { label: t('billing.unionpay'), value: 220300 },
]; ]);
// 计算剩余可输入金额 // 计算剩余可输入金额
const remainingAmount = computed(() => { const remainingAmount = computed(() => {
@@ -384,18 +386,18 @@ function close() {
// 获取费用性质文本 // 获取费用性质文本
const getFeeTypeText = computed(() => { const getFeeTypeText = computed(() => {
if (!props.medfee_paymtd_code || !Array.isArray(props.medfee_paymtd_code)) { if (!props.medfee_paymtd_code || !Array.isArray(props.medfee_paymtd_code)) {
return '自费'; return t('billing.selfPay');
} }
// 如果有feeType根据feeType查找对应的文本 // 如果有feeType根据feeType查找对应的文本
if (props.feeType) { if (props.feeType) {
const dict = props.medfee_paymtd_code.find(item => item.value === props.feeType); const dict = props.medfee_paymtd_code.find(item => item.value === props.feeType);
return dict ? dict.label : '自费'; return dict ? dict.label : t('billing.selfPay');
} }
// 如果只有一个选项,直接返回第一个选项的文本 // 如果只有一个选项,直接返回第一个选项的文本
if (props.medfee_paymtd_code.length === 1) { if (props.medfee_paymtd_code.length === 1) {
return props.medfee_paymtd_code[0].label || '自费'; return props.medfee_paymtd_code[0].label || t('billing.selfPay');
} }
return '自费'; return t('billing.selfPay');
}); });
</script> </script>

View File

@@ -1,16 +1,16 @@
<template> <template>
<div <div
style="display: flex; justify-content: space-between" style="display: flex; justify-content: space-between"
class="app-container" class="app-container"
> >
<el-card style="width: 30%"> <el-card style="width: 30%">
<template #header> <template #header>
<span style="vertical-align: middle">患者列表</span> <span style="vertical-align: middle">{{ $t('billing.patientList') }}</span>
</template> </template>
<div style="width: 100%"> <div style="width: 100%">
<el-input <el-input
v-model="queryParams.patientName" v-model="queryParams.patientName"
placeholder="请输入患者名" :placeholder="$t('billing.searchPlaceholderName')"
clearable clearable
style="width: 49%; margin-bottom: 10px; margin-right: 10px" style="width: 49%; margin-bottom: 10px; margin-right: 10px"
@keyup.enter="getPatientList" @keyup.enter="getPatientList"
@@ -25,7 +25,7 @@
<el-select <el-select
v-model="queryParams.statusEnum" v-model="queryParams.statusEnum"
style="width: 49%; margin-bottom: 10px" style="width: 49%; margin-bottom: 10px"
placeholder="收费状态" :placeholder="$t('billing.chargeStatus')"
@change="getPatientList" @change="getPatientList"
> >
<el-option <el-option
@@ -39,8 +39,8 @@
v-model="maxBillDate" v-model="maxBillDate"
type="daterange" type="daterange"
range-separator="~" range-separator="~"
start-placeholder="开始时间" :start-placeholder="$t('billing.startTime')"
end-placeholder="结束时间" :end-placeholder="$t('billing.endTime')"
placement="bottom" placement="bottom"
:clearable="false" :clearable="false"
value-format="YYYY-MM-DD" value-format="YYYY-MM-DD"
@@ -51,7 +51,7 @@
style="margin-bottom: 10px" style="margin-bottom: 10px"
@click="getPatientList" @click="getPatientList"
> >
搜索 {{ $t('billing.search') }}
</el-button> </el-button>
<vxe-table <vxe-table
ref="patientListRef" ref="patientListRef"
@@ -62,12 +62,12 @@
@cell-click="clickRow" @cell-click="clickRow"
> >
<vxe-column <vxe-column
title="病历号" :title="$t('billing.medicalRecordNo')"
align="center" align="center"
field="encounterBusNo" field="encounterBusNo"
/> />
<vxe-column <vxe-column
title="姓名" :title="$t('billing.name')"
align="center" align="center"
field="patientName" field="patientName"
/> />
@@ -77,7 +77,7 @@
</template> </template>
</vxe-column> --> </vxe-column> -->
<vxe-column <vxe-column
title="收费状态" :title="$t('billing.chargeStatus')"
align="center" align="center"
field="statusEnum_enumText" field="statusEnum_enumText"
/> />
@@ -87,19 +87,19 @@
<div style="width: 69%"> <div style="width: 69%">
<el-card style="margin-bottom: 20px; height: 15%"> <el-card style="margin-bottom: 20px; height: 15%">
<template #header> <template #header>
<span style="vertical-align: middle">基本信息</span> <span style="vertical-align: middle">{{ $t('billing.basicInfo') }}</span>
</template> </template>
<el-descriptions :column="4"> <el-descriptions :column="4">
<el-descriptions-item label="就诊号:"> <el-descriptions-item :label="$t('billing.encounterNo') + ':'">
{{ patientInfo.encounterId }} {{ patientInfo.encounterId }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="姓名:"> <el-descriptions-item :label="$t('billing.name') + ':'">
{{ patientInfo.patientName }} {{ patientInfo.patientName }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="性别:"> <el-descriptions-item :label="$t('billing.gender') + ':'">
{{ patientInfo.genderEnum_enumText }} {{ patientInfo.genderEnum_enumText }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="年龄:"> <el-descriptions-item :label="$t('billing.age') + ':'">
{{ patientInfo.age }} {{ patientInfo.age }}
</el-descriptions-item> </el-descriptions-item>
<!-- <el-descriptions-item label="合同类型:"> <!-- <el-descriptions-item label="合同类型:">
@@ -129,7 +129,7 @@
</el-card> </el-card>
<el-card style="height: 83%"> <el-card style="height: 83%">
<template #header> <template #header>
<span style="vertical-align: middle">退费单据</span> <span style="vertical-align: middle">{{ $t('billing.refundDocs') }}</span>
</template> </template>
<!-- <el-button type="primary" @click="handleRefund()" :disabled="buttonDisabled"> <!-- <el-button type="primary" @click="handleRefund()" :disabled="buttonDisabled">
确认退费 确认退费
@@ -146,7 +146,7 @@
> >
<!-- <vxe-column type="checkbox" :selectable="checkSelectable" width="55" /> --> <!-- <vxe-column type="checkbox" :selectable="checkSelectable" width="55" /> -->
<vxe-column <vxe-column
title="操作" :title="$t('billing.operation')"
align="center" align="center"
> >
<template #default="scope"> <template #default="scope">
@@ -155,34 +155,34 @@
type="primary" type="primary"
@click="handleRefund(scope.row)" @click="handleRefund(scope.row)"
> >
退费 {{ $t('billing.refundItem') }}
</el-button> </el-button>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column <vxe-column
field="paymentId" field="paymentId"
title="支付单据号" :title="$t('billing.refundDocNo')"
align="center" align="center"
/> />
<vxe-column <vxe-column
title="项目单据号" :title="$t('billing.itemDocNo')"
align="center" align="center"
field="busNo" field="busNo"
width="150" width="150"
/> />
<vxe-column <vxe-column
title="项目名称" :title="$t('billing.itemNameCol')"
align="center" align="center"
field="itemName" field="itemName"
/> />
<vxe-column <vxe-column
title="收费状态" :title="$t('billing.chargeStatusCol')"
align="center" align="center"
field="chargeStatus_enumText" field="chargeStatus_enumText"
width="100" width="100"
/> />
<vxe-column <vxe-column
title="数量" :title="$t('billing.quantity')"
align="center" align="center"
width="100" width="100"
> >
@@ -191,19 +191,19 @@
</template> </template>
</vxe-column> </vxe-column>
<vxe-column <vxe-column
title="付款总额" :title="$t('billing.paymentTotal')"
align="right" align="right"
field="totalPrice" field="totalPrice"
header-align="center" header-align="center"
width="100" width="100"
> >
<template #default="scope"> <template #default="scope">
{{ scope.row.totalPrice.toFixed(2) + ' ' }} {{ scope.row.totalPrice.toFixed(2) + ' ' + $t('billing.yuan') }}
</template> </template>
</vxe-column> </vxe-column>
<!-- <vxe-column title="处方号" align="center" field="prescriptionNo" /> --> <!-- <vxe-column title="处方号" align="center" field="prescriptionNo" /> -->
<vxe-column <vxe-column
title="收款人" :title="$t('billing.cashier')"
align="center" align="center"
field="entererName" field="entererName"
width="120" width="120"
@@ -226,6 +226,8 @@
</template> </template>
<script setup name="ClinicCharge"> <script setup name="ClinicCharge">
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
import {getChargeItemIds, getList, getRefundList, getReturnDetail, init, validReturnDrug,} from './components/api'; import {getChargeItemIds, getList, getRefundList, getReturnDetail, init, validReturnDrug,} from './components/api';
import {formatDateStr} from '@/utils/index'; import {formatDateStr} from '@/utils/index';
import RefundDialog from './components/refundDialog.vue'; import RefundDialog from './components/refundDialog.vue';
@@ -389,7 +391,7 @@ function handleRefund(row) {
function handleClose(value) { function handleClose(value) {
openDialog.value = false; openDialog.value = false;
if (value == 'success') { if (value == 'success') {
proxy.$modal.msgSuccess('操作成功'); proxy.$modal.msgSuccess(t('billing.opSuccess'));
clickRow(patientInfo.value); clickRow(patientInfo.value);
} }
} }

View File

@@ -1,7 +1,7 @@
<template> <template>
<el-dialog <el-dialog
v-model="props.open" v-model="props.open"
title="确认收费" :title="$t('billing.confirmCharge')"
width="700px" width="700px"
teleported teleported
destroy-on-close destroy-on-close
@@ -12,21 +12,21 @@
size="large" size="large"
style="display: block; margin-bottom: 15px" style="display: block; margin-bottom: 15px"
> >
收费日期{{ currentDate }} {{ $t('billing.chargeDate') }}{{ currentDate }}
</el-text> </el-text>
<el-text size="large"> <el-text size="large">
费用性质{{ getFeeTypeText }} {{ $t('billing.feeNature') }}{{ getFeeTypeText }}
</el-text> </el-text>
<div class="amount-row"> <div class="amount-row">
<el-text size="large"> <el-text size="large">
应收金额 {{ $t('billing.receivableAmount') }}
</el-text> </el-text>
<el-text <el-text
size="large" size="large"
type="primary" type="primary"
class="amount" class="amount"
> >
{{ props.totalAmount.toFixed(2) + ' ' }} {{ props.totalAmount.toFixed(2) + ' ' + $t('billing.yuan') }}
</el-text> </el-text>
</div> </div>
@@ -37,10 +37,10 @@
:key="index" :key="index"
class="payment-item" class="payment-item"
> >
<span>支付方式</span> <span>{{ $t('billing.payMethod') }}</span>
<el-select <el-select
v-model="item.payEnum" v-model="item.payEnum"
placeholder="选择支付方式" :placeholder="$t('billing.selectPayMethod')"
style="width: 160px" style="width: 160px"
@change="clearAmount(index)" @change="clearAmount(index)"
> >
@@ -52,7 +52,7 @@
:disabled="isMethodDisabled(payEnum)" :disabled="isMethodDisabled(payEnum)"
/> />
</el-select> </el-select>
<span>支付金额</span> <span>{{ $t('billing.payAmount') }}</span>
<div class="suffix-wrapper"> <div class="suffix-wrapper">
<el-input-number <el-input-number
v-model="item.amount" v-model="item.amount"
@@ -60,11 +60,11 @@
:min="0" :min="0"
:max="getMax(index)" :max="getMax(index)"
:controls="false" :controls="false"
placeholder="金额" :placeholder="$t('billing.amount')"
class="amount-input" class="amount-input"
@change="handleAmountChange" @change="handleAmountChange"
/> />
<span class="suffix-text"></span> <span class="suffix-text">{{ $t('billing.yuan') }}</span>
</div> </div>
<el-button <el-button
v-if="index > 0" v-if="index > 0"
@@ -81,19 +81,19 @@
:disabled="formData.selfPay.length >= 4 || remainingAmount <= 0" :disabled="formData.selfPay.length >= 4 || remainingAmount <= 0"
@click="addPayment" @click="addPayment"
> >
添加支付方式 {{ $t('billing.addPayMethod') }}
</el-button> </el-button>
<el-text <el-text
v-if="remainingAmount <= 0" v-if="remainingAmount <= 0"
type="danger" type="danger"
class="tip" class="tip"
> >
金额已满足应收不可继续添加 {{ $t('billing.amountSatisfied') }}
</el-text> </el-text>
</div> </div>
</div> </div>
<div class="payment-item"> <div class="payment-item">
<span>{{ payTypeText }}支付</span> <span>{{ payTypeText + $t('billing.payMethod') }}</span>
<el-input <el-input
ref="txtCodeRef" ref="txtCodeRef"
v-model="txtCode" v-model="txtCode"
@@ -105,14 +105,14 @@
type="primary" type="primary"
@click="handleWxPay()" @click="handleWxPay()"
> >
扫码支付 {{ $t('billing.wechatPay') }}
</el-button> </el-button>
<el-button <el-button
link link
type="primary" type="primary"
@click="getWxPayResult()" @click="getWxPayResult()"
> >
查看结果 {{ $t('billing.viewResult') }}
</el-button> </el-button>
</div> </div>
<!-- 金额汇总 --> <!-- 金额汇总 -->
@@ -120,18 +120,18 @@
<el-space :size="30"> <el-space :size="30">
<div class="summary-item"> <div class="summary-item">
<el-text type="info"> <el-text type="info">
实收合计 {{ $t('billing.actualTotal') }}
</el-text> </el-text>
<el-text type="success"> <el-text type="success">
{{ displayAmount + ' ' }} {{ displayAmount + ' ' + $t('billing.yuan') }}
</el-text> </el-text>
</div> </div>
<div class="summary-item"> <div class="summary-item">
<el-text type="info"> <el-text type="info">
应找零 {{ $t('billing.changeAmount') }}
</el-text> </el-text>
<el-text type="warning"> <el-text type="warning">
{{ returnedAmount + ' ' }} {{ returnedAmount + ' ' + $t('billing.yuan') }}
</el-text> </el-text>
</div> </div>
</el-space> </el-space>
@@ -144,13 +144,13 @@
:disabled="dialogLoading" :disabled="dialogLoading"
@click="throttledGetList" @click="throttledGetList"
> >
{{ $t('billing.confirm') }}
</el-button> </el-button>
<el-button <el-button
:disabled="dialogLoading" :disabled="dialogLoading"
@click="close" @click="close"
> >
{{ $t('billing.cancel') }}
</el-button> </el-button>
</div> </div>
</template> </template>
@@ -162,8 +162,11 @@ import {savePayment, wxPay, WxPayResult} from './outpatientregistration';
import {computed, getCurrentInstance, nextTick, reactive, ref, watch} from 'vue'; import {computed, getCurrentInstance, nextTick, reactive, ref, watch} from 'vue';
import {Delete} from '@element-plus/icons-vue'; import {Delete} from '@element-plus/icons-vue';
import {debounce} from 'lodash-es'; import {debounce} from 'lodash-es';
import {useI18n} from 'vue-i18n';
import printUtils, {PRINT_TEMPLATE, printRegistrationReceipt} from '@/utils/printUtils'; import printUtils, {PRINT_TEMPLATE, printRegistrationReceipt} from '@/utils/printUtils';
const { t } = useI18n();
// 获取费用性质文本 // 获取费用性质文本
const getFeeTypeText = computed(() => { const getFeeTypeText = computed(() => {
if (!props.medfee_paymtd_code || !Array.isArray(props.medfee_paymtd_code)) { if (!props.medfee_paymtd_code || !Array.isArray(props.medfee_paymtd_code)) {
@@ -282,7 +285,7 @@ async function printReceipt(param) {
console.log('打印成功'); console.log('打印成功');
} catch (error) { } catch (error) {
console.error('打印失败:', error); console.error('打印失败:', error);
proxy.$modal.msgError('打印失败:' + error.message); proxy.$modal.msgError(t('billing.printFail') + ': ' + error.message);
} }
} }
function handleWxPay() { function handleWxPay() {
@@ -322,7 +325,7 @@ function getWxPayResult() {
function submit() { function submit() {
if (parseFloat(displayAmount.value) < formData.totalAmount) { if (parseFloat(displayAmount.value) < formData.totalAmount) {
proxy.$modal.msgError('请输入正确的结算金额'); proxy.$modal.msgError(t('billing.enterCorrectAmount'));
return; return;
} }
dialogLoading.value = true; dialogLoading.value = true;
@@ -352,12 +355,12 @@ function submit() {
const currentDate = ref(new Date().toLocaleString()); const currentDate = ref(new Date().toLocaleString());
const selfPayMethods = [ const selfPayMethods = computed(() => [
{ label: '现金', value: 220400, isWebPay: false }, { label: t('billing.cash'), value: 220400, isWebPay: false },
{ label: '微信', value: 220100, isWebPay: true }, { label: t('billing.wechat'), value: 220100, isWebPay: true },
{ label: '支付宝', value: 220200, isWebPay: true }, { label: t('billing.alipay'), value: 220200, isWebPay: true },
{ label: '银联', value: 220300, isWebPay: true }, { label: t('billing.unionpay'), value: 220300, isWebPay: true },
]; ]);
// 计算剩余可输入金额 // 计算剩余可输入金额
const remainingAmount = computed(() => { const remainingAmount = computed(() => {
@@ -389,7 +392,7 @@ const isMethodDisabled = (option) => {
} }
// 若已经选择了任一线上支付方式,则其他线上方式不可再选,仅允许现金等线下方式 // 若已经选择了任一线上支付方式,则其他线上方式不可再选,仅允许现金等线下方式
const hasSelectedWebPay = selectedEnums.some((val) => { const hasSelectedWebPay = selectedEnums.some((val) => {
const found = selfPayMethods.find((m) => m.value === val); const found = selfPayMethods.value.find((m) => m.value === val);
return found ? found.isWebPay === true : false; return found ? found.isWebPay === true : false;
}); });
if (hasSelectedWebPay && option.isWebPay) { if (hasSelectedWebPay && option.isWebPay) {
@@ -414,16 +417,16 @@ const addPayment = () => {
const removePayment = (index) => { const removePayment = (index) => {
formData.selfPay.splice(index, 1); formData.selfPay.splice(index, 1);
}; };
const payTypeText = ref('微信'); const payTypeText = ref(t('billing.wechat'));
const payTypePlaceholder = computed(() => { const payTypePlaceholder = computed(() => {
if (payTypeText.value === '现金') { if (payTypeText.value === t('billing.cash')) {
return '请输入现金金额'; return '请输入现金金额';
} }
return payTypeText.value + '支付二维码'; return payTypeText.value + '支付二维码';
}); });
const clearAmount = (index) => { const clearAmount = (index) => {
// formData.selfPay[index].amount = 0; // formData.selfPay[index].amount = 0;
const selectedOption = selfPayMethods.find( const selectedOption = selfPayMethods.value.find(
(item) => item.value === formData.selfPay[index].payEnum (item) => item.value === formData.selfPay[index].payEnum
); );
if (selectedOption) { if (selectedOption) {

View File

@@ -1,4 +1,4 @@
<template> <template>
<!-- <div class="app-container"> --> <!-- <div class="app-container"> -->
<el-dialog <el-dialog
v-model="visible" v-model="visible"
@@ -19,28 +19,28 @@
/> />
<vxe-column <vxe-column
key="name" key="name"
title="患者姓名" :title="$t('billing.patientName')"
align="center" align="center"
field="name" field="name"
show-overflow="title" show-overflow="title"
/> />
<vxe-column <vxe-column
key="genderEnum_enumText" key="genderEnum_enumText"
title="性别" :title="$t('billing.gender')"
align="center" align="center"
field="genderEnum_enumText" field="genderEnum_enumText"
show-overflow="title" show-overflow="title"
/> />
<vxe-column <vxe-column
key="idCard" key="idCard"
title="身份证号" :title="$t('registration.idCardNo')"
align="center" align="center"
field="idCard" field="idCard"
show-overflow="title" show-overflow="title"
/> />
<vxe-column <vxe-column
key="phone" key="phone"
title="电话" :title="$t('registration.phone')"
align="center" align="center"
field="phone" field="phone"
show-overflow="title" show-overflow="title"
@@ -48,7 +48,7 @@
/> />
<vxe-column <vxe-column
key="birthDate" key="birthDate"
title="生日" :title="$t('billing.birthDate')"
align="center" align="center"
field="birthDate" field="birthDate"
show-overflow="title" show-overflow="title"
@@ -56,12 +56,12 @@
/> />
<vxe-column <vxe-column
key="age" key="age"
title="年龄" :title="$t('billing.age')"
align="center" align="center"
show-overflow="title" show-overflow="title"
> >
<template #default="scope"> <template #default="scope">
{{ scope.row.age ? `${scope.row.age}` : '-' }} {{ scope.row.age ? `${scope.row.age}` : '-' }}
</template> </template>
</vxe-column> </vxe-column>
</vxe-table> </vxe-table>
@@ -78,10 +78,10 @@
type="primary" type="primary"
@click="submitForm" @click="submitForm"
> >
{{ $t('billing.confirm') }}
</el-button> </el-button>
<el-button @click="cancel"> <el-button @click="cancel">
{{ $t('billing.cancel') }}
</el-button> </el-button>
</div> </div>
</template> </template>
@@ -91,7 +91,9 @@
<script setup name="PatientInfoDialog"> <script setup name="PatientInfoDialog">
import {getOutpatientRegistrationList,} from "./outpatientregistration"; import {getOutpatientRegistrationList,} from "./outpatientregistration";
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
@@ -100,7 +102,7 @@ const selectedData = ref([]); // 存储选择的行数据
const single = ref(true); const single = ref(true);
const multiple = ref(true); const multiple = ref(true);
const total = ref(0); const total = ref(0);
const title = ref("病人信息"); const title = ref(t('billing.patientArchiveQuery'));
const visible = ref(false); const visible = ref(false);
const emits = defineEmits(['submit']); // 声明自定义事件 const emits = defineEmits(['submit']); // 声明自定义事件
@@ -170,7 +172,7 @@ function cancel() {
/** 提交按钮 */ /** 提交按钮 */
function submitForm() { function submitForm() {
if (selectedData.value.length > 1) { if (selectedData.value.length > 1) {
proxy.$modal.msgSuccess("只能选中一条数据操作!"); proxy.$modal.msgSuccess(t('billing.opSuccess'));
} else if (selectedData.value.length === 1) { } else if (selectedData.value.length === 1) {
console.log(selectedData.value[0], "selectedData.value"); console.log(selectedData.value[0], "selectedData.value");
const data = selectedData.value[0]; const data = selectedData.value[0];

View File

@@ -8,37 +8,37 @@
@cell-click="clickRow" @cell-click="clickRow"
> >
<vxe-column <vxe-column
title="姓名" :title="$t('billing.name')"
align="center" align="center"
field="name" field="name"
:min-width="80" :min-width="80"
/> />
<vxe-column <vxe-column
title="就诊卡号" :title="$t('registration.cardNo')"
align="center" align="center"
field="identifierNo" field="identifierNo"
:min-width="140" :min-width="140"
/> />
<vxe-column <vxe-column
title="性别" :title="$t('billing.gender')"
align="center" align="center"
field="genderEnum_enumText" field="genderEnum_enumText"
:min-width="60" :min-width="60"
/> />
<vxe-column <vxe-column
title="证件号" :title="$t('registration.idCardNo')"
align="center" align="center"
field="idCard" field="idCard"
:min-width="180" :min-width="180"
/> />
<vxe-column <vxe-column
title="联系电话" :title="$t('registration.phone')"
align="center" align="center"
field="phone" field="phone"
:min-width="130" :min-width="130"
/> />
<vxe-column <vxe-column
title="年龄" :title="$t('billing.age')"
align="center" align="center"
:min-width="60" :min-width="60"
> >
@@ -52,6 +52,9 @@
<script setup> <script setup>
import {getOutpatientRegistrationList} from "./outpatientregistration"; import {getOutpatientRegistrationList} from "./outpatientregistration";
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
const props = defineProps({ const props = defineProps({
searchkey: { searchkey: {

View File

@@ -1,7 +1,7 @@
<template> <template>
<el-dialog <el-dialog
v-model="props.open" v-model="props.open"
:title="eventType == '1' ? '确认退费' : '挂号详情'" :title="eventType == '1' ? $t('billing.refundConfirm') : $t('registration.detail')"
width="700px" width="700px"
teleported teleported
destroy-on-close destroy-on-close
@@ -12,21 +12,21 @@
size="large" size="large"
style="display: block; margin-bottom: 15px" style="display: block; margin-bottom: 15px"
> >
退费日期{{ currentDate }} {{ $t('billing.refundDate') + '' }}{{ currentDate }}
</el-text> </el-text>
<el-text size="large"> <el-text size="large">
费用性质{{ props.category || '自费' }} {{ $t('billing.feeNature') + '' }}{{ props.category || $t('billing.selfPay') }}
</el-text> </el-text>
<div class="amount-row"> <div class="amount-row">
<el-text size="large"> <el-text size="large">
应退金额 {{ $t('billing.refundAmount') + '' }}
</el-text> </el-text>
<el-text <el-text
size="large" size="large"
type="primary" type="primary"
class="amount" class="amount"
> >
{{ (calculatedTotalAmount || 0) + ' ' }} {{ (calculatedTotalAmount || 0) + ' ' + $t('billing.yuan') }}
</el-text> </el-text>
</div> </div>
<div <div
@@ -34,14 +34,14 @@
class="amount-row" class="amount-row"
> >
<el-text size="large"> <el-text size="large">
退费金额 {{ $t('billing.refundAmountLabel') + '' }}
</el-text> </el-text>
<el-text <el-text
size="large" size="large"
type="primary" type="primary"
class="amount" class="amount"
> >
{{ (calculatedReturnAmount || 0) + ' ' }} {{ (calculatedReturnAmount || 0) + ' ' + $t('billing.yuan') }}
</el-text> </el-text>
</div> </div>
@@ -52,13 +52,13 @@
:key="index" :key="index"
class="payment-item" class="payment-item"
> >
<span>退费方式</span> <span>{{ $t('billing.refundMethod') + '' }}</span>
<el-input <el-input
:value="getPayMethodLabel(item.payEnum)" :value="getPayMethodLabel(item.payEnum)"
readonly readonly
style="width: 160px" style="width: 160px"
/> />
<span>退费金额</span> <span>{{ $t('billing.refundAmountLabel') + '' }}</span>
<div class="suffix-wrapper"> <div class="suffix-wrapper">
<el-input-number <el-input-number
:model-value="(Number(item.amount) || 0) - (Number(item.returnAmount) || 0)" :model-value="(Number(item.amount) || 0) - (Number(item.returnAmount) || 0)"
@@ -67,19 +67,19 @@
disabled disabled
class="amount-input" class="amount-input"
/> />
<span class="suffix-text"></span> <span class="suffix-text">{{ $t('billing.yuan') }}</span>
</div> </div>
</div> </div>
<div <div
class="payment-container" class="payment-container"
style="position: relative" style="position: relative"
> >
<span style="position: absolute; top: 5px">退费原因</span> <span style="position: absolute; top: 5px">{{ $t('billing.refundReason') + '' }}</span>
<el-input <el-input
v-model="reason" v-model="reason"
type="textarea" type="textarea"
:rows="2" :rows="2"
placeholder="退费原因" :placeholder="$t('billing.refundReason')"
class="reason-textarea" class="reason-textarea"
:disabled="eventType == '1' ? false : true" :disabled="eventType == '1' ? false : true"
/> />
@@ -99,11 +99,11 @@
<el-space :size="30"> <el-space :size="30">
<div class="summary-item"> <div class="summary-item">
<el-text type="info"> <el-text type="info">
实退合计 {{ $t('billing.refundTotal') + '' }}
</el-text> </el-text>
<el-text type="success"> <el-text type="success">
{{ {{
displayAmount > 0 ? displayAmount + ' ' : props.totalAmount + ' ' displayAmount > 0 ? displayAmount + ' ' + $t('billing.yuan') : props.totalAmount + ' ' + $t('billing.yuan')
}} }}
</el-text> </el-text>
</div> </div>
@@ -128,12 +128,12 @@
> >
<vxe-column <vxe-column
field="payEnum_dictText" field="payEnum_dictText"
title="支付方式" :title="$t('billing.payMethod')"
min-width="200" min-width="200"
/> />
<vxe-column <vxe-column
field="amount" field="amount"
title="金额" :title="$t('billing.amount')"
width="120" width="120"
align="right" align="right"
> >
@@ -143,7 +143,7 @@
</vxe-column> </vxe-column>
<vxe-column <vxe-column
field="returnAmount" field="returnAmount"
title="退费金额" :title="$t('billing.refundAmountLabel')"
width="120" width="120"
align="right" align="right"
> >
@@ -153,7 +153,7 @@
</vxe-column> </vxe-column>
<vxe-column <vxe-column
field="chargeAmount" field="chargeAmount"
title="收费金额" :title="$t('billing.amount')"
min-width="120" min-width="120"
align="right" align="right"
> >
@@ -171,10 +171,10 @@
type="primary" type="primary"
@click="submit" @click="submit"
> >
{{ $t('billing.confirm') }}
</el-button> </el-button>
<el-button @click="close"> <el-button @click="close">
{{ $t('billing.cancel') }}
</el-button> </el-button>
</div> </div>
</template> </template>
@@ -184,7 +184,9 @@
<script setup> <script setup>
import {cancelRegister, preCancelReg} from './outpatientregistration'; import {cancelRegister, preCancelReg} from './outpatientregistration';
import {computed, getCurrentInstance, reactive, ref, watch} from 'vue'; import {computed, getCurrentInstance, reactive, ref, watch} from 'vue';
import { useI18n } from 'vue-i18n';
import useUserStore from '@/store/modules/user.js' import useUserStore from '@/store/modules/user.js'
const { t } = useI18n();
//获取当前登陆用户的信息 //获取当前登陆用户的信息
const userStore = useUserStore(); const userStore = useUserStore();
@@ -198,10 +200,10 @@ const getFeeTypeText = computed(() => {
// 如果没有传递名称,则根据费用性质代码查找 // 如果没有传递名称,则根据费用性质代码查找
if (props.feeType && props.medfee_paymtd_code && Array.isArray(props.medfee_paymtd_code)) { if (props.feeType && props.medfee_paymtd_code && Array.isArray(props.medfee_paymtd_code)) {
const dictItem = props.medfee_paymtd_code.find(item => item.value === props.feeType); const dictItem = props.medfee_paymtd_code.find(item => item.value === props.feeType);
return dictItem ? dictItem.label : '自费'; return dictItem ? dictItem.label : t('billing.selfPay');
} }
return '自费'; // 默认值 return t('billing.selfPay'); // 默认值
}); });
const props = defineProps({ const props = defineProps({
@@ -336,12 +338,12 @@ function submit() {
const currentDate = ref(new Date().toLocaleString()); const currentDate = ref(new Date().toLocaleString());
const selfPayMethods = [ const selfPayMethods = computed(() => [
{ label: '现金', value: 220400 }, { label: t('billing.cash'), value: 220400 },
{ label: '微信', value: 220100 }, { label: t('billing.wechat'), value: 220100 },
{ label: '支付宝', value: 220200 }, { label: t('billing.alipay'), value: 220200 },
{ label: '银联', value: 220300 }, { label: t('billing.unionpay'), value: 220300 },
]; ]);
const getMax = (index) => { const getMax = (index) => {
const otherSum = formData.selfPay.reduce( const otherSum = formData.selfPay.reduce(
@@ -443,13 +445,13 @@ const refundMethodsFromApi = computed(() => {
// 根据 payEnum 获取支付方式标签 // 根据 payEnum 获取支付方式标签
const getPayMethodLabel = (payEnum) => { const getPayMethodLabel = (payEnum) => {
const method = selfPayMethods.find((m) => m.value === payEnum); const method = selfPayMethods.value.find((m) => m.value === payEnum);
if (method) { if (method) {
return method.label; return method.label;
} }
// 如果找不到,尝试从接口返回的 dictText 中获取 // 如果找不到,尝试从接口返回的 dictText 中获取
const apiItem = preCancelData.value?.find((item) => item.payEnum === payEnum); const apiItem = preCancelData.value?.find((item) => item.payEnum === payEnum);
return apiItem?.payEnum_dictText || `支付方式${payEnum}`; return apiItem?.payEnum_dictText || t('billing.payMethod') + payEnum;
}; };
// 计算所有退费方式的总和 // 计算所有退费方式的总和

View File

@@ -1,7 +1,7 @@
<template> <template>
<el-dialog <el-dialog
v-model="dialogVisible" v-model="dialogVisible"
title="补打挂号单凭证" :title="$t('billing.reprintRegistration')"
width="900px" width="900px"
teleported teleported
destroy-on-close destroy-on-close
@@ -14,10 +14,10 @@
<!-- 标题区域 --> <!-- 标题区域 -->
<div style="text-align: center; margin-bottom: 20px;"> <div style="text-align: center; margin-bottom: 20px;">
<h2 style="color: #ff0000; font-size: 24px; font-weight: bold; margin: 0 0 10px 0;"> <h2 style="color: #ff0000; font-size: 24px; font-weight: bold; margin: 0 0 10px 0;">
挂号单重打 {{ $t('billing.reprintTitle') }}
</h2> </h2>
<p style="color: #ff0000; font-size: 14px; margin: 0;"> <p style="color: #ff0000; font-size: 14px; margin: 0;">
补打挂号单将作废原有的挂号单据并生成新的挂号单据 {{ $t('billing.reprintSubtitle') }}
</p> </p>
</div> </div>
@@ -32,52 +32,52 @@
<!-- 左列 --> <!-- 左列 -->
<el-col :span="12"> <el-col :span="12">
<el-form-item <el-form-item
label="病人姓名:" :label="$t('billing.patientName') + ''"
prop="name" prop="name"
> >
<el-input <el-input
v-model="form.name" v-model="form.name"
placeholder="病人姓名" :placeholder="$t('billing.patientName')"
:disabled="true" :disabled="true"
/> />
</el-form-item> </el-form-item>
<el-form-item <el-form-item
label="医生姓名:" :label="$t('billing.doctorName') + ''"
prop="practitionerName" prop="practitionerName"
> >
<el-input <el-input
v-model="form.practitionerName" v-model="form.practitionerName"
placeholder="医生姓名" :placeholder="$t('billing.doctorName')"
:disabled="true" :disabled="true"
/> />
</el-form-item> </el-form-item>
<el-form-item <el-form-item
label="诊疗费:" :label="$t('registration.consultationFeeLabel')"
prop="activityPrice" prop="activityPrice"
> >
<el-input <el-input
v-model="form.activityPrice" v-model="form.activityPrice"
placeholder="诊疗费" :placeholder="$t('registration.consultationFee')"
:disabled="true" :disabled="true"
/> />
</el-form-item> </el-form-item>
<el-form-item <el-form-item
label="流水号:" :label="$t('billing.serialNo') + ''"
prop="serialNo" prop="serialNo"
> >
<el-input <el-input
v-model="form.serialNo" v-model="form.serialNo"
placeholder="流水号" :placeholder="$t('billing.serialNo')"
:disabled="true" :disabled="true"
/> />
</el-form-item> </el-form-item>
<el-form-item <el-form-item
label="合计:" :label="$t('billing.totalLabel') + ''"
prop="totalPrice" prop="totalPrice"
> >
<el-input <el-input
v-model="form.totalPrice" v-model="form.totalPrice"
placeholder="合计" :placeholder="$t('billing.totalLabel')"
:disabled="true" :disabled="true"
/> />
</el-form-item> </el-form-item>
@@ -86,42 +86,42 @@
<!-- 右列 --> <!-- 右列 -->
<el-col :span="12"> <el-col :span="12">
<el-form-item <el-form-item
label="挂号科室:" :label="$t('registration.registrationDepartmentLabel')"
prop="organizationName" prop="organizationName"
> >
<el-input <el-input
v-model="form.organizationName" v-model="form.organizationName"
placeholder="挂号科室" :placeholder="$t('registration.registrationDepartment')"
:disabled="true" :disabled="true"
/> />
</el-form-item> </el-form-item>
<el-form-item <el-form-item
label="挂号费:" :label="$t('registration.registrationFeeLabel')"
prop="price" prop="price"
> >
<el-input <el-input
v-model="form.price" v-model="form.price"
placeholder="挂号费" :placeholder="$t('registration.registrationFee')"
:disabled="true" :disabled="true"
/> />
</el-form-item> </el-form-item>
<el-form-item <el-form-item
label="病历费:" :label="$t('billing.medicalRecordFee') + ''"
prop="medicalRecordFee" prop="medicalRecordFee"
> >
<el-input <el-input
v-model="form.medicalRecordFee" v-model="form.medicalRecordFee"
placeholder="病历费" :placeholder="$t('billing.medicalRecordFee')"
:disabled="true" :disabled="true"
/> />
</el-form-item> </el-form-item>
<el-form-item <el-form-item
label="打印时间:" :label="$t('billing.printTime') + ''"
prop="printTime" prop="printTime"
> >
<el-input <el-input
v-model="form.printTime" v-model="form.printTime"
placeholder="打印时间" :placeholder="$t('billing.printTime')"
:disabled="true" :disabled="true"
/> />
</el-form-item> </el-form-item>
@@ -132,12 +132,12 @@
<el-row> <el-row>
<el-col :span="24"> <el-col :span="24">
<el-form-item <el-form-item
label="预约/挂号时间:" :label="$t('billing.visitTimeLabel') + ''"
prop="visitTime" prop="visitTime"
> >
<el-input <el-input
v-model="form.visitTime" v-model="form.visitTime"
placeholder="预约/挂号时间" :placeholder="$t('billing.visitTimeLabel')"
:disabled="true" :disabled="true"
/> />
</el-form-item> </el-form-item>
@@ -152,12 +152,12 @@
style="margin: 0;" style="margin: 0;"
> >
<el-form-item <el-form-item
label="就诊卡号:" :label="$t('registration.cardNoLabel')"
style="margin-bottom: 0;" style="margin-bottom: 0;"
> >
<el-input <el-input
v-model="searchForm.cardNo" v-model="searchForm.cardNo"
placeholder="请输入就诊卡号检索条" :placeholder="$t('billing.enterCardNoSearch')"
style="width: 300px; margin-right: 10px;" style="width: 300px; margin-right: 10px;"
clearable clearable
@keyup.enter="handleSearch" @keyup.enter="handleSearch"
@@ -167,10 +167,10 @@
:loading="loading" :loading="loading"
@click="handleSearch" @click="handleSearch"
> >
确认(O) {{ $t('billing.confirmSelect') }}
</el-button> </el-button>
<el-button @click="handleCancel"> <el-button @click="handleCancel">
取消(C) {{ $t('billing.cancel') }}
</el-button> </el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
@@ -180,7 +180,7 @@
<!-- 挂号记录选择对话框 --> <!-- 挂号记录选择对话框 -->
<el-dialog <el-dialog
v-model="selectDialogVisible" v-model="selectDialogVisible"
title="挂号记录选择" :title="$t('billing.regRecordSelect')"
width="800px" width="800px"
teleported teleported
:close-on-click-modal="false" :close-on-click-modal="false"
@@ -193,13 +193,13 @@
@current-change="handleRecordSelect" @current-change="handleRecordSelect"
> >
<vxe-column <vxe-column
title="序号" :title="$t('billing.seqNo')"
type="seq" type="seq"
width="60" width="60"
align="center" align="center"
/> />
<vxe-column <vxe-column
title="挂号时间" :title="$t('registration.registrationTime')"
field="registerTime" field="registerTime"
width="180" width="180"
align="center" align="center"
@@ -209,7 +209,7 @@
</template> </template>
</vxe-column> </vxe-column>
<vxe-column <vxe-column
title="挂号科室" :title="$t('registration.registrationDepartment')"
field="organizationName" field="organizationName"
align="center" align="center"
> >
@@ -218,7 +218,7 @@
</template> </template>
</vxe-column> </vxe-column>
<vxe-column <vxe-column
title="医生姓名" :title="$t('billing.doctorName')"
field="practitionerName" field="practitionerName"
align="center" align="center"
> >
@@ -227,7 +227,7 @@
</template> </template>
</vxe-column> </vxe-column>
<vxe-column <vxe-column
title="流水号" :title="$t('billing.serialNo')"
field="encounterNo" field="encounterNo"
align="center" align="center"
> >
@@ -239,14 +239,14 @@
<template #footer> <template #footer>
<div class="dialog-footer"> <div class="dialog-footer">
<el-button @click="selectDialogVisible = false"> <el-button @click="selectDialogVisible = false">
取消 (C) {{ $t('billing.cancel') }}
</el-button> </el-button>
<el-button <el-button
type="primary" type="primary"
:disabled="!selectedRecord" :disabled="!selectedRecord"
@click="handleConfirmSelect" @click="handleConfirmSelect"
> >
确认 (O) {{ $t('billing.confirmSelect') }}
</el-button> </el-button>
</div> </div>
</template> </template>
@@ -255,7 +255,8 @@
</template> </template>
<script setup> <script setup>
import {getCurrentInstance, reactive, ref, watch, nextTick, onMounted} from 'vue'; import {getCurrentInstance, reactive, ref, watch, nextTick, onMounted, computed} from 'vue';
import { useI18n } from 'vue-i18n';
import {getOutpatientRegistrationCurrent, reprintRegistration} from './outpatientregistration'; import {getOutpatientRegistrationCurrent, reprintRegistration} from './outpatientregistration';
import {parseTime} from '@/utils/his'; import {parseTime} from '@/utils/his';
import {formatDateStr} from '@/utils/index'; import {formatDateStr} from '@/utils/index';
@@ -264,6 +265,7 @@ import outpatientRegistrationTemplate from '@/components/Print/OutpatientRegistr
import useUserStore from '@/store/modules/user'; import useUserStore from '@/store/modules/user';
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const { t } = useI18n();
const userStore = useUserStore(); const userStore = useUserStore();
const props = defineProps({ const props = defineProps({
@@ -306,12 +308,12 @@ const form = reactive({
encounterId: '', encounterId: '',
}); });
const rules = { const rules = computed(() => ({
cardNo: [{ required: true, message: '就诊卡号不能为空', trigger: 'blur' }], cardNo: [{ required: true, message: t('billing.enterCardNo'), trigger: 'blur' }],
name: [{ required: true, message: '姓名不能为空', trigger: 'blur' }], name: [{ required: true, message: t('billing.name'), trigger: 'blur' }],
organizationName: [{ required: true, message: '就诊科室不能为空', trigger: 'blur' }], organizationName: [{ required: true, message: t('registration.visitDepartment'), trigger: 'blur' }],
practitionerName: [{ required: true, message: '医生不能为空', trigger: 'blur' }], practitionerName: [{ required: true, message: t('billing.doctorName'), trigger: 'blur' }],
}; }));
// 监听open属性变化 // 监听open属性变化
watch( watch(
@@ -337,7 +339,7 @@ watch(dialogVisible, (newVal) => {
// 搜索挂号记录并确认补打 // 搜索挂号记录并确认补打
async function handleSearch() { async function handleSearch() {
if (!searchForm.cardNo) { if (!searchForm.cardNo) {
proxy.$modal.msgWarning('请输入就诊卡号'); proxy.$modal.msgWarning(t('billing.enterCardNo'));
return; return;
} }
@@ -386,18 +388,18 @@ async function handleSearch() {
loading.value = false; loading.value = false;
} }
} else { } else {
proxy.$modal.msgWarning('未查询到相关挂号记录,请检查就诊卡号是否正确'); proxy.$modal.msgWarning(t('billing.noRegRecord'));
resetForm(); resetForm();
loading.value = false; loading.value = false;
} }
} else { } else {
proxy.$modal.msgWarning('查询失败: ' + (response.msg || '接口返回异常')); proxy.$modal.msgWarning(t('billing.queryFailMsg', { msg: response.msg || t('billing.queryFail') }));
resetForm(); resetForm();
loading.value = false; loading.value = false;
} }
} catch (error) { } catch (error) {
console.error('查询挂号记录异常:', error); console.error('查询挂号记录异常:', error);
proxy.$modal.msgError('查询出错: ' + (error.message || '网络异常')); proxy.$modal.msgError(t('billing.queryError', { error: error.message || t('billing.queryFail') }));
resetForm(); resetForm();
loading.value = false; loading.value = false;
} }
@@ -499,14 +501,14 @@ function fillForm(row) {
// 根据 statusEnum 判断状态 // 根据 statusEnum 判断状态
// 状态枚举可能需要根据实际情况调整 // 状态枚举可能需要根据实际情况调整
const statusMap = { const statusMap = {
1: '已预约', 1: t('billing.statusReserved'),
2: '已完成', 2: t('billing.statusCompleted'),
3: '已取消', 3: t('billing.statusCancelled'),
4: '进行中' 4: t('billing.statusInProgress')
}; };
form.statusText = statusMap[row.statusEnum] || '已预约'; form.statusText = statusMap[row.statusEnum] || t('billing.statusReserved');
} else { } else {
form.statusText = '已预约'; form.statusText = t('billing.statusReserved');
} }
// 打印时间(当前时间) // 打印时间(当前时间)
@@ -549,7 +551,7 @@ function calculateSerialNo(row) {
// 提交补打挂号 // 提交补打挂号
async function handleSubmit() { async function handleSubmit() {
if (!form.encounterId) { if (!form.encounterId) {
proxy.$modal.msgWarning('请先搜索并选择挂号记录'); proxy.$modal.msgWarning(t('billing.selectRegRecordFirst'));
loading.value = false; loading.value = false;
return; return;
} }
@@ -585,14 +587,14 @@ async function handleSubmit() {
const res = await reprintRegistration(submitData); const res = await reprintRegistration(submitData);
if (res.code === 200) { if (res.code === 200) {
proxy.$modal.msgSuccess('补打挂号成功'); proxy.$modal.msgSuccess(t('billing.reprintSuccess'));
// 不关闭补打对话框,直接显示打印预览 // 不关闭补打对话框,直接显示打印预览
// 这样可以确保 form 数据不会丢失 // 这样可以确保 form 数据不会丢失
loading.value = false; loading.value = false;
showPrintPreview(); showPrintPreview();
} else { } else {
proxy.$modal.msgError(res.msg || '补打挂号失败'); proxy.$modal.msgError(res.msg || t('billing.reprintFail'));
loading.value = false; loading.value = false;
} }
} catch (error) { } catch (error) {

View File

@@ -1,8 +1,8 @@
<template> <template>
<div class="card-renewal-container"> <div class="card-renewal-container">
<!-- 标题栏 --> <!-- 标题栏 -->
<div class="title-bar"> <div class="title-bar">
<h2>换卡处理</h2> <h2>{{ $t('billing.cardRenewal') }}</h2>
</div> </div>
<!-- 按钮栏 - 修改为水平排放 --> <!-- 按钮栏 - 修改为水平排放 -->
@@ -15,7 +15,7 @@
style="min-width: 140px;" style="min-width: 140px;"
@click="handlePatientSearch" @click="handlePatientSearch"
> >
病人查询(Q) {{ $t('billing.patientQuery') }}
</el-button> </el-button>
<el-button <el-button
@@ -26,7 +26,7 @@
style="min-width: 140px;" style="min-width: 140px;"
@click="handleConfirm" @click="handleConfirm"
> >
确定 (O) {{ $t('billing.confirmBtn') }}
</el-button> </el-button>
<el-button <el-button
@@ -36,7 +36,7 @@
style="min-width: 140px;" style="min-width: 140px;"
@click="handleClose" @click="handleClose"
> >
关闭 (C) {{ $t('billing.closeBtn') }}
</el-button> </el-button>
</div> </div>
@@ -45,10 +45,10 @@
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="8"> <el-col :span="8">
<div class="input-item"> <div class="input-item">
<label>病人姓名:</label> <label>{{ $t('billing.patientNameLabel') }}</label>
<el-input <el-input
v-model="searchForm.patientName" v-model="searchForm.patientName"
placeholder="请输入" :placeholder="$t('common.pleaseEnter')"
clearable clearable
@keyup.enter="handlePatientSearch" @keyup.enter="handlePatientSearch"
/> />
@@ -56,10 +56,10 @@
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<div class="input-item"> <div class="input-item">
<label>身份证号码:</label> <label>{{ $t('billing.idCardLabel') }}</label>
<el-input <el-input
v-model="searchForm.idCard" v-model="searchForm.idCard"
placeholder="请输入" :placeholder="$t('common.pleaseEnter')"
clearable clearable
@keyup.enter="handlePatientSearch" @keyup.enter="handlePatientSearch"
/> />
@@ -67,10 +67,10 @@
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<div class="input-item"> <div class="input-item">
<label>手机号码:</label> <label>{{ $t('billing.phoneLabel') }}</label>
<el-input <el-input
v-model="searchForm.phoneNumber" v-model="searchForm.phoneNumber"
placeholder="请输入" :placeholder="$t('common.pleaseEnter')"
clearable clearable
@keyup.enter="handlePatientSearch" @keyup.enter="handlePatientSearch"
/> />
@@ -84,7 +84,7 @@
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="8"> <el-col :span="8">
<div class="info-item"> <div class="info-item">
<label>门诊号码</label> <label>{{ $t('billing.outpatientNo') }}</label>
<div class="info-value"> <div class="info-value">
{{ patientInfo?.outpatientNo || '' }} {{ patientInfo?.outpatientNo || '' }}
</div> </div>
@@ -92,7 +92,7 @@
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<div class="info-item"> <div class="info-item">
<label>病人姓名</label> <label>{{ $t('billing.name') }}</label>
<div class="info-value"> <div class="info-value">
{{ patientInfo?.patientName || '' }} {{ patientInfo?.patientName || '' }}
</div> </div>
@@ -100,7 +100,7 @@
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<div class="info-item"> <div class="info-item">
<label>身份证号码</label> <label>{{ $t('billing.idCardLabel').replace(':', '') }}</label>
<div class="info-value"> <div class="info-value">
{{ patientInfo?.idCard || '' }} {{ patientInfo?.idCard || '' }}
</div> </div>
@@ -114,7 +114,7 @@
> >
<el-col :span="8"> <el-col :span="8">
<div class="info-item"> <div class="info-item">
<label>手机号码</label> <label>{{ $t('billing.phoneLabel').replace(':', '') }}</label>
<div class="info-value"> <div class="info-value">
{{ patientInfo?.phoneNumber || '' }} {{ patientInfo?.phoneNumber || '' }}
</div> </div>
@@ -122,7 +122,7 @@
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<div class="info-item"> <div class="info-item">
<label>性别</label> <label>{{ $t('billing.gender') }}</label>
<div class="info-value"> <div class="info-value">
{{ patientInfo?.gender || '' }} {{ patientInfo?.gender || '' }}
</div> </div>
@@ -130,7 +130,7 @@
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<div class="info-item"> <div class="info-item">
<label>年龄</label> <label>{{ $t('billing.age') }}</label>
<div class="info-value"> <div class="info-value">
{{ patientInfo?.age || '' }} {{ patientInfo?.age || '' }}
</div> </div>
@@ -142,10 +142,10 @@
<!-- 新门诊号码输入 --> <!-- 新门诊号码输入 -->
<div class="new-number-section"> <div class="new-number-section">
<div class="input-item"> <div class="input-item">
<label>新门诊号码:</label> <label>{{ $t('billing.newOutpatientNo') }}</label>
<el-input <el-input
v-model="renewalForm.newOutpatientNo" v-model="renewalForm.newOutpatientNo"
placeholder="请输入新门诊号码" :placeholder="$t('billing.enterNewOutpatientNo')"
style="width: 250px;" style="width: 250px;"
@keyup.enter="handleConfirm" @keyup.enter="handleConfirm"
/> />
@@ -168,7 +168,7 @@
<!-- 标题行 --> <!-- 标题行 -->
<div style="display: flex; justify-content: flex-start; align-items: center; padding: 10px 20px;"> <div style="display: flex; justify-content: flex-start; align-items: center; padding: 10px 20px;">
<h3 style="margin: 0; font-size: 16px; font-weight: 500; color: #303133;"> <h3 style="margin: 0; font-size: 16px; font-weight: 500; color: #303133;">
病人档案查询 {{ $t('billing.patientArchiveQuery') }}
</h3> </h3>
</div> </div>
<!-- 按钮行 --> <!-- 按钮行 -->
@@ -178,13 +178,13 @@
style="background-color: #3B82F6; border-color: #3B82F6; padding: 8px 16px; font-size: 14px;" style="background-color: #3B82F6; border-color: #3B82F6; padding: 8px 16px; font-size: 14px;"
@click="confirmSelectPatient" @click="confirmSelectPatient"
> >
确认(Q) {{ $t('billing.confirmSelect') }}
</el-button> </el-button>
<el-button <el-button
style="background-color: #EF4444; border-color: #EF4444; color: white; padding: 8px 16px; font-size: 14px;" style="background-color: #EF4444; border-color: #EF4444; color: white; padding: 8px 16px; font-size: 14px;"
@click="showPatientList = false; selectedPatient = null" @click="showPatientList = false; selectedPatient = null"
> >
关闭(C) {{ $t('billing.closeSelect') }}
</el-button> </el-button>
</div> </div>
</div> </div>
@@ -199,12 +199,12 @@
@cell-click="selectPatient" @cell-click="selectPatient"
> >
<vxe-column <vxe-column
title="序号" :title="$t('billing.seqNo')"
width="60" width="60"
type="seq" type="seq"
/> />
<vxe-column <vxe-column
title="病人姓名" :title="$t('billing.name')"
width="120" width="120"
> >
<template #default="scope"> <template #default="scope">
@@ -212,7 +212,7 @@
</template> </template>
</vxe-column> </vxe-column>
<vxe-column <vxe-column
title="门诊号码" :title="$t('billing.outpatientNo')"
width="120" width="120"
> >
<template #default="scope"> <template #default="scope">
@@ -220,7 +220,7 @@
</template> </template>
</vxe-column> </vxe-column>
<vxe-column <vxe-column
title="身份证号码" :title="$t('billing.idCardLabel').replace(':', '')"
width="200" width="200"
> >
<template #default="scope"> <template #default="scope">
@@ -228,7 +228,7 @@
</template> </template>
</vxe-column> </vxe-column>
<vxe-column <vxe-column
title="手机号码" :title="$t('billing.phoneLabel').replace(':', '')"
width="120" width="120"
> >
<template #default="scope"> <template #default="scope">
@@ -236,7 +236,7 @@
</template> </template>
</vxe-column> </vxe-column>
<vxe-column <vxe-column
title="性别" :title="$t('billing.gender')"
width="80" width="80"
> >
<template #default="scope"> <template #default="scope">
@@ -244,7 +244,7 @@
</template> </template>
</vxe-column> </vxe-column>
<vxe-column <vxe-column
title="年龄" :title="$t('billing.age')"
width="80" width="80"
> >
<template #default="scope"> <template #default="scope">
@@ -252,7 +252,7 @@
</template> </template>
</vxe-column> </vxe-column>
<vxe-column <vxe-column
title="出生年月" :title="$t('billing.birthDate')"
width="120" width="120"
> >
<template #default="scope"> <template #default="scope">
@@ -283,7 +283,7 @@
<!-- 换卡成功提示 --> <!-- 换卡成功提示 -->
<el-dialog <el-dialog
v-model="renewalSuccessVisible" v-model="renewalSuccessVisible"
title="换卡成功" :title="$t('billing.patientCardRenewalSuccess')"
width="400px" width="400px"
:close-on-click-modal="false" :close-on-click-modal="false"
> >
@@ -292,15 +292,15 @@
</div> </div>
<p style="margin-top: 15px; font-size: 16px;"> <p style="margin-top: 15px; font-size: 16px;">
患者换卡操作已成功完成! {{ $t('billing.patientRenewalSuccessMsg') }}
</p> </p>
<p style="margin-top: 10px;"> <p style="margin-top: 10px;">
新门诊号码:{{ renewalForm.newOutpatientNo }} {{ $t('billing.newOutpatientNo') }} {{ renewalForm.newOutpatientNo }}
</p> </p>
</div> </div>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="renewalSuccessVisible = false; resetForm">确定</el-button> <el-button @click="renewalSuccessVisible = false; resetForm">{{ $t('billing.confirm') }}</el-button>
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
@@ -311,8 +311,10 @@
import {getCurrentInstance, onMounted, onUnmounted, reactive, ref} from 'vue' import {getCurrentInstance, onMounted, onUnmounted, reactive, ref} from 'vue'
import {ElMessage, ElMessageBox} from 'element-plus' import {ElMessage, ElMessageBox} from 'element-plus'
import {useRouter} from 'vue-router' import {useRouter} from 'vue-router'
import {useI18n} from 'vue-i18n'
import {doCardRenewal, getPatientList} from './components/api.js'; import {doCardRenewal, getPatientList} from './components/api.js';
const { t } = useI18n()
// 获取路由实例 // 获取路由实例
const router = useRouter(); const router = useRouter();
// 获取当前组件实例以访问全局属性 // 获取当前组件实例以访问全局属性
@@ -371,7 +373,7 @@ const handleCurrentChange = (newPage) => {
const handlePatientSearch = async () => { const handlePatientSearch = async () => {
// 检查是否至少填写了一个查询条件 // 检查是否至少填写了一个查询条件
if (!searchForm.patientName && !searchForm.idCard && !searchForm.phoneNumber) { if (!searchForm.patientName && !searchForm.idCard && !searchForm.phoneNumber) {
ElMessage.warning('请至少输入一个查询条件') ElMessage.warning(t('billing.pleaseEnterQuery'))
return return
} }
@@ -407,7 +409,7 @@ const handleCurrentChange = (newPage) => {
// 设置为选中状态并自动确认,将患者信息展示到页面 // 设置为选中状态并自动确认,将患者信息展示到页面
selectedPatient.value = patient selectedPatient.value = patient
confirmSelectPatient() // 自动调用确认选择方法,将患者信息展示到页面 confirmSelectPatient() // 自动调用确认选择方法,将患者信息展示到页面
ElMessage.success('已自动选中唯一患者') ElMessage.success(t('billing.autoSelectUnique'))
} else { } else {
// 如果有多条记录或不是第一页,显示患者列表供选择 // 如果有多条记录或不是第一页,显示患者列表供选择
// 确保每条患者记录都包含patientId字段优先使用id字段 // 确保每条患者记录都包含patientId字段优先使用id字段
@@ -420,10 +422,10 @@ const handleCurrentChange = (newPage) => {
} else { } else {
// 无数据时重置总条数 // 无数据时重置总条数
total.value = 0 total.value = 0
ElMessage.warning('未查询到患者信息') ElMessage.warning(t('billing.noPatientFound'))
} }
} else { } else {
ElMessage.error('查询失败' + (response?.msg || '未知错误')) ElMessage.error(t('billing.queryFail') + '' + (response?.msg || '未知错误'))
} }
} catch (error) { } catch (error) {
@@ -440,17 +442,17 @@ const handleCurrentChange = (newPage) => {
// 确定换卡 // 确定换卡
const handleConfirm = async () => { const handleConfirm = async () => {
if (!patientInfo.value) { if (!patientInfo.value) {
ElMessage.warning('请先查询患者信息') ElMessage.warning(t('billing.pleaseQueryPatient'))
return return
} }
if (!renewalForm.newOutpatientNo) { if (!renewalForm.newOutpatientNo) {
ElMessage.warning('请输入新门诊号码') ElMessage.warning(t('billing.enterNewOutpatientNo'))
return return
} }
if (renewalForm.newOutpatientNo === patientInfo.value.outpatientNo) { if (renewalForm.newOutpatientNo === patientInfo.value.outpatientNo) {
ElMessage.warning('新门诊号码不能与原号码相同') ElMessage.warning(t('billing.newCardNoCannotSame'))
return return
} }
@@ -474,13 +476,13 @@ const handleConfirm = async () => {
if (patientInfo.value) { if (patientInfo.value) {
patientInfo.value.outpatientNo = renewalForm.newOutpatientNo patientInfo.value.outpatientNo = renewalForm.newOutpatientNo
} }
ElMessage.success('换卡成功!') ElMessage.success(t('billing.patientRenewalSuccess'))
} else { } else {
ElMessage.error('换卡失败' + (res?.msg || '未知错误')) ElMessage.error(t('billing.patientRenewalFail') + '' + (res?.msg || '未知错误'))
} }
} catch (error) { } catch (error) {
ElMessage.error('换卡失败,卡号已存在') ElMessage.error(t('billing.patientRenewalFailCardExists'))
// 可以在这里添加错误监控或日志记录 // 可以在这里添加错误监控或日志记录
} finally { } finally {
loading.value = false loading.value = false
@@ -490,7 +492,7 @@ const handleConfirm = async () => {
// 关闭窗口,同时关闭标签页并返回上一级页面 // 关闭窗口,同时关闭标签页并返回上一级页面
const handleClose = () => { const handleClose = () => {
// 显示确认对话框 // 显示确认对话框
ElMessageBox.confirm('确定要关闭此页面吗?', '提示', { ElMessageBox.confirm(t('billing.closeConfirm'), t('common.tip'), {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
@@ -505,7 +507,7 @@ const handleClose = () => {
}).catch(() => { }).catch(() => {
// 用户取消操作,不执行任何操作 // 用户取消操作,不执行任何操作
// 可以选择显示一个提示消息 // 可以选择显示一个提示消息
ElMessage.info('已取消关闭操作') ElMessage.info(t('billing.cancelClose'))
}) })
} }
@@ -564,13 +566,13 @@ onUnmounted(() => {
// 选择患者(仅设置选中状态) // 选择患者(仅设置选中状态)
const selectPatient = (row) => { const selectPatient = (row) => {
selectedPatient.value = row selectedPatient.value = row
ElMessage.warning('已选择患者,请点击确定') ElMessage.warning(t('billing.selectPatientWarning'))
} }
// 确认选择患者 // 确认选择患者
const confirmSelectPatient = () => { const confirmSelectPatient = () => {
if (!selectedPatient.value) { if (!selectedPatient.value) {
ElMessage.warning('请先选择患者') ElMessage.warning(t('billing.selectPatient'))
return return
} }
@@ -591,7 +593,7 @@ const confirmSelectPatient = () => {
} }
showPatientList.value = false showPatientList.value = false
ElMessage.success('已选择患者:' + (row.patientName || row.name)) ElMessage.success(t('billing.opSuccess'))
// 重置选中状态 // 重置选中状态
selectedPatient.value = null selectedPatient.value = null
} }

View File

@@ -1,8 +1,8 @@
<template> <template>
<div class="patient-search-container"> <div class="patient-search-container">
<!-- 标题栏 --> <!-- 标题栏 -->
<div class="title-bar"> <div class="title-bar">
<h2>病人档案查询</h2> <h2>{{ $t('billing.patientArchiveQuery') }}</h2>
<div class="button-bar"> <div class="button-bar">
<el-button <el-button
type="primary" type="primary"
@@ -11,7 +11,7 @@
icon="el-icon-check" icon="el-icon-check"
@click="handleQuery" @click="handleQuery"
> >
确认(Q) {{ $t('billing.confirmSelect') }}
</el-button> </el-button>
<el-button <el-button
type="danger" type="danger"
@@ -19,7 +19,7 @@
icon="el-icon-close" icon="el-icon-close"
@click="handleClose" @click="handleClose"
> >
关闭(C) {{ $t('billing.closeSelect') }}
</el-button> </el-button>
</div> </div>
</div> </div>
@@ -29,10 +29,10 @@
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="8"> <el-col :span="8">
<div class="form-item"> <div class="form-item">
<label>病人姓名:</label> <label>{{ $t('billing.patientNameLabel') }}</label>
<el-input <el-input
v-model="searchForm.patientName" v-model="searchForm.patientName"
placeholder="请输入病人姓名" :placeholder="$t('billing.searchPlaceholderName')"
clearable clearable
@keyup.enter="handleQuery" @keyup.enter="handleQuery"
/> />
@@ -40,10 +40,10 @@
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<div class="form-item"> <div class="form-item">
<label>身份证号码:</label> <label>{{ $t('billing.idCardLabel') }}</label>
<el-input <el-input
v-model="searchForm.idCard" v-model="searchForm.idCard"
placeholder="请输入身份证号码" :placeholder="$t('billing.idCard')"
clearable clearable
@keyup.enter="handleQuery" @keyup.enter="handleQuery"
/> />
@@ -51,10 +51,10 @@
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<div class="form-item"> <div class="form-item">
<label>手机号码:</label> <label>{{ $t('billing.phoneLabel') }}</label>
<el-input <el-input
v-model="searchForm.phoneNumber" v-model="searchForm.phoneNumber"
placeholder="请输入手机号码" :placeholder="$t('billing.phoneLabel').replace(':', '')"
clearable clearable
@keyup.enter="handleQuery" @keyup.enter="handleQuery"
/> />
@@ -74,13 +74,13 @@
@cell-click="handleRowClick" @cell-click="handleRowClick"
> >
<vxe-column <vxe-column
title="序号" :title="$t('billing.seqNo')"
type="seq" type="seq"
width="80" width="80"
align="center" align="center"
/> />
<vxe-column <vxe-column
title="病人姓名" :title="$t('billing.name')"
width="120" width="120"
align="center" align="center"
> >
@@ -89,7 +89,7 @@
</template> </template>
</vxe-column> </vxe-column>
<vxe-column <vxe-column
title="门诊号码" :title="$t('billing.outpatientNo')"
width="150" width="150"
align="center" align="center"
> >
@@ -98,7 +98,7 @@
</template> </template>
</vxe-column> </vxe-column>
<vxe-column <vxe-column
title="身份证号码" :title="$t('billing.idCardLabel').replace(':', '')"
width="200" width="200"
align="center" align="center"
> >
@@ -107,7 +107,7 @@
</template> </template>
</vxe-column> </vxe-column>
<vxe-column <vxe-column
title="手机号码" :title="$t('billing.phoneLabel').replace(':', '')"
width="120" width="120"
align="center" align="center"
> >
@@ -116,7 +116,7 @@
</template> </template>
</vxe-column> </vxe-column>
<vxe-column <vxe-column
title="性别" :title="$t('billing.gender')"
width="80" width="80"
align="center" align="center"
> >
@@ -125,7 +125,7 @@
</template> </template>
</vxe-column> </vxe-column>
<vxe-column <vxe-column
title="年龄" :title="$t('billing.age')"
width="80" width="80"
align="center" align="center"
> >
@@ -134,7 +134,7 @@
</template> </template>
</vxe-column> </vxe-column>
<vxe-column <vxe-column
title="出生年月" :title="$t('billing.birthDate')"
width="120" width="120"
align="center" align="center"
> >
@@ -150,8 +150,11 @@
<script setup> <script setup>
import {computed, onMounted, onUnmounted, reactive, ref, watch} from 'vue' import {computed, onMounted, onUnmounted, reactive, ref, watch} from 'vue'
import {ElMessage} from 'element-plus' import {ElMessage} from 'element-plus'
import {useI18n} from 'vue-i18n'
import {getOutpatientRegistrationList} from '../outpatientregistration/components/outpatientregistration' import {getOutpatientRegistrationList} from '../outpatientregistration/components/outpatientregistration'
const { t } = useI18n()
// 搜索表单 // 搜索表单
const searchForm = reactive({ const searchForm = reactive({
patientName: '', patientName: '',
@@ -197,7 +200,7 @@ watch(searchKey, (newValue) => {
// 处理行点击 // 处理行点击
const handleRowClick = (row) => { const handleRowClick = (row) => {
selectedPatient.value = row selectedPatient.value = row
ElMessage.success(`已选择患者:${row.patientName}`) ElMessage.success(t('billing.opSuccess'))
} }
// 查询患者信息和确认选择 // 查询患者信息和确认选择
@@ -206,13 +209,13 @@ const handleQuery = async () => {
if (selectedPatient.value) { if (selectedPatient.value) {
// 发射选择患者事件 // 发射选择患者事件
emit('selectPatient', selectedPatient.value) emit('selectPatient', selectedPatient.value)
ElMessage.success(`已确认选择患者:${selectedPatient.value.patientName}`) ElMessage.success(t('billing.opSuccess'))
return return
} }
// 检查是否至少填写了一个查询条件 // 检查是否至少填写了一个查询条件
if (!searchKey.value) { if (!searchKey.value) {
ElMessage.warning('请至少输入一个查询条件') ElMessage.warning(t('billing.pleaseEnterQuery'))
return return
} }
@@ -235,14 +238,14 @@ const handleQuery = async () => {
})) }))
if (patientList.value.length === 0) { if (patientList.value.length === 0) {
ElMessage.warning('未找到符合条件的患者信息') ElMessage.warning(t('billing.noPatientFound'))
} }
} else { } else {
ElMessage.error('查询失败') ElMessage.error(t('billing.queryFail'))
patientList.value = [] patientList.value = []
} }
} catch (error) { } catch (error) {
ElMessage.error('查询失败,请稍后重试') ElMessage.error(t('billing.queryFailRetry'))
console.error('查询失败:', error) console.error('查询失败:', error)
patientList.value = [] patientList.value = []
} finally { } finally {

View File

@@ -2,16 +2,16 @@
<div class="app-container"> <div class="app-container">
<el-card shadow="never"> <el-card shadow="never">
<template #header> <template #header>
<span class="card-title">挂号收费记录</span> <span class="card-title">{{ $t('billing.registerChargeRecordTitle') }}</span>
</template> </template>
<el-form <el-form
:inline="true" :inline="true"
:model="queryParams" :model="queryParams"
> >
<el-form-item label="搜索"> <el-form-item :label="$t('billing.search')">
<el-input <el-input
v-model="queryParams.searchKey" v-model="queryParams.searchKey"
placeholder="搜索" :placeholder="$t('billing.search')"
clearable clearable
@keyup.enter="handleQuery" @keyup.enter="handleQuery"
/> />
@@ -22,7 +22,7 @@
icon="Search" icon="Search"
@click="handleQuery" @click="handleQuery"
> >
搜索 {{ $t('billing.search') }}
</el-button> </el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
@@ -33,29 +33,29 @@
> >
<vxe-column <vxe-column
type="seq" type="seq"
title="序号" :title="$t('billing.seqNo')"
width="60" width="60"
/> />
<vxe-column <vxe-column
field="name" field="name"
title="名称" :title="$t('billing.nameCol')"
/> />
<vxe-column <vxe-column
field="date" field="date"
title="日期" :title="$t('billing.dateCol')"
/> />
<vxe-column <vxe-column
field="status" field="status"
title="状态" :title="$t('billing.statusCol')"
> >
<template #default="{ row }"> <template #default="{ row }">
<el-tag :type="row.status === '0' ? 'success' : 'info'"> <el-tag :type="row.status === '0' ? 'success' : 'info'">
{{ row.status === '0' ? '正常' : '停用' }} {{ row.status === '0' ? $t('billing.normal') : $t('billing.disabled') }}
</el-tag> </el-tag>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column <vxe-column
title="操作" :title="$t('billing.operation')"
width="120" width="120"
> >
<template #default="{ row }"> <template #default="{ row }">
@@ -64,7 +64,7 @@
link link
@click="handleDetail(row)" @click="handleDetail(row)"
> >
详情 {{ $t('billing.detail') }}
</el-button> </el-button>
</template> </template>
</vxe-column> </vxe-column>
@@ -75,10 +75,13 @@
<script setup> <script setup>
import { ref, onMounted } from 'vue' import { ref, onMounted } from 'vue'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const queryParams = ref({ searchKey: '', pageNum: 1, pageSize: 10 }) const queryParams = ref({ searchKey: '', pageNum: 1, pageSize: 10 })
const tableData = ref([]) const tableData = ref([])
const handleQuery = async () => { tableData.value = [] } const handleQuery = async () => { tableData.value = [] }
const handleDetail = (row) => { ElMessage.info('详情') } const handleDetail = (row) => { ElMessage.info(t('billing.detail')) }
onMounted(() => handleQuery()) onMounted(() => handleQuery())
</script> </script>
<style scoped>.card-title { font-weight: bold; font-size: 16px; }</style> <style scoped>.card-title { font-weight: bold; font-size: 16px; }</style>

View File

@@ -2,16 +2,16 @@
<div class="app-container"> <div class="app-container">
<el-card shadow="never"> <el-card shadow="never">
<template #header> <template #header>
<span class="card-title">排班管理</span> <span class="card-title">{{ $t('billing.schedule') }}</span>
</template> </template>
<el-form <el-form
:inline="true" :inline="true"
:model="queryParams" :model="queryParams"
> >
<el-form-item label="搜索"> <el-form-item :label="$t('billing.search')">
<el-input <el-input
v-model="queryParams.searchKey" v-model="queryParams.searchKey"
placeholder="搜索" :placeholder="$t('billing.search')"
clearable clearable
@keyup.enter="handleQuery" @keyup.enter="handleQuery"
/> />
@@ -22,7 +22,7 @@
icon="Search" icon="Search"
@click="handleQuery" @click="handleQuery"
> >
搜索 {{ $t('billing.search') }}
</el-button> </el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
@@ -33,29 +33,29 @@
> >
<vxe-column <vxe-column
type="seq" type="seq"
title="序号" :title="$t('billing.seqNo')"
width="60" width="60"
/> />
<vxe-column <vxe-column
field="name" field="name"
title="名称" :title="$t('billing.nameCol')"
/> />
<vxe-column <vxe-column
field="date" field="date"
title="日期" :title="$t('billing.dateCol')"
/> />
<vxe-column <vxe-column
field="status" field="status"
title="状态" :title="$t('billing.statusCol')"
> >
<template #default="{ row }"> <template #default="{ row }">
<el-tag :type="row.status === '0' ? 'success' : 'info'"> <el-tag :type="row.status === '0' ? 'success' : 'info'">
{{ row.status === '0' ? '正常' : '停用' }} {{ row.status === '0' ? $t('billing.normal') : $t('billing.disabled') }}
</el-tag> </el-tag>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column <vxe-column
title="操作" :title="$t('billing.operation')"
width="120" width="120"
> >
<template #default="{ row }"> <template #default="{ row }">
@@ -64,7 +64,7 @@
link link
@click="handleDetail(row)" @click="handleDetail(row)"
> >
详情 {{ $t('billing.detail') }}
</el-button> </el-button>
</template> </template>
</vxe-column> </vxe-column>
@@ -75,10 +75,13 @@
<script setup> <script setup>
import { ref, onMounted } from 'vue' import { ref, onMounted } from 'vue'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const queryParams = ref({ searchKey: '', pageNum: 1, pageSize: 10 }) const queryParams = ref({ searchKey: '', pageNum: 1, pageSize: 10 })
const tableData = ref([]) const tableData = ref([])
const handleQuery = async () => { tableData.value = [] } const handleQuery = async () => { tableData.value = [] }
const handleDetail = (row) => { ElMessage.info('详情') } const handleDetail = (row) => { ElMessage.info(t('billing.detail')) }
onMounted(() => handleQuery()) onMounted(() => handleQuery())
</script> </script>
<style scoped>.card-title { font-weight: bold; font-size: 16px; }</style> <style scoped>.card-title { font-weight: bold; font-size: 16px; }</style>

View File

@@ -8,34 +8,34 @@
<!-- 左侧患者基本信息区 --> <!-- 左侧患者基本信息区 -->
<el-card style="width: 30%"> <el-card style="width: 30%">
<template #header> <template #header>
<span style="vertical-align: middle">患者基本信息</span> <span style="vertical-align: middle">{{ $t('billing.patientBasicInfo') }}</span>
</template> </template>
<el-descriptions <el-descriptions
:column="1" :column="1"
border border
> >
<el-descriptions-item label="病历号"> <el-descriptions-item :label="$t('billing.medicalRecordNo')">
{{ patientInfo.encounterBusNo }} {{ patientInfo.encounterBusNo }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="姓名"> <el-descriptions-item :label="$t('billing.name')">
{{ patientInfo.patientName }} {{ patientInfo.patientName }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="性别"> <el-descriptions-item :label="$t('billing.gender')">
{{ patientInfo.genderEnum_enumText }} {{ patientInfo.genderEnum_enumText }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="年龄"> <el-descriptions-item :label="$t('billing.age')">
{{ patientInfo.age }} {{ patientInfo.age }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="科室"> <el-descriptions-item :label="$t('billing.department')">
{{ patientInfo.organizationName }} {{ patientInfo.organizationName }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="就诊时间"> <el-descriptions-item :label="$t('billing.visitTime')">
{{ formatDateStr(patientInfo.receptionTime, 'YYYY-MM-DD HH:mm:ss') }} {{ formatDateStr(patientInfo.receptionTime, 'YYYY-MM-DD HH:mm:ss') }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="手术单号"> <el-descriptions-item :label="$t('billing.surgeryNo')">
{{ surgeryInfo.surgeryNo }} {{ surgeryInfo.surgeryNo }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="手术名称"> <el-descriptions-item :label="$t('billing.surgeryName')">
{{ surgeryInfo.surgeryName }} {{ surgeryInfo.surgeryName }}
</el-descriptions-item> </el-descriptions-item>
</el-descriptions> </el-descriptions>
@@ -45,7 +45,7 @@
<div style="width: 69%"> <div style="width: 69%">
<el-card style="min-width: 1100px"> <el-card style="min-width: 1100px">
<template #header> <template #header>
<span style="vertical-align: middle">收费项目</span> <span style="vertical-align: middle">{{ $t('billing.chargeItems') }}</span>
</template> </template>
<div style="margin-bottom: 10px"> <div style="margin-bottom: 10px">
<el-button <el-button
@@ -53,7 +53,7 @@
:disabled="buttonDisabled" :disabled="buttonDisabled"
@click="confirmCharge()" @click="confirmCharge()"
> >
确认收费 {{ $t('billing.confirmCharge') }}
</el-button> </el-button>
<el-button <el-button
type="primary" type="primary"
@@ -61,7 +61,7 @@
style="width: 65px" style="width: 65px"
@click="handleReadCard('01')" @click="handleReadCard('01')"
> >
电子凭证 {{ $t('billing.electronicCertificate') }}
</el-button> </el-button>
<el-button <el-button
type="primary" type="primary"
@@ -69,10 +69,10 @@
style="width: 65px" style="width: 65px"
@click="handleReadCard('03')" @click="handleReadCard('03')"
> >
医保卡 {{ $t('billing.medicalInsuranceCard') }}
</el-button> </el-button>
<span style="float: right"> <span style="float: right">
合计金额{{ totalAmounts ? totalAmounts.toFixed(2) : 0 }} {{ $t('billing.totalAmount') }}{{ totalAmounts ? totalAmounts.toFixed(2) : 0 }}{{ $t('billing.yuan') }}
</span> </span>
</div> </div>
<vxe-table <vxe-table
@@ -91,40 +91,40 @@
width="55" width="55"
/> />
<vxe-column <vxe-column
title="单据号" :title="$t('billing.docNo')"
align="center" align="center"
field="busNo" field="busNo"
width="180" width="180"
/> />
<vxe-column <vxe-column
title="收费项目" :title="$t('billing.chargeItems')"
align="center" align="center"
field="itemName" field="itemName"
width="200" width="200"
/> />
<vxe-column <vxe-column
title="数量" :title="$t('billing.quantity')"
align="center" align="center"
field="quantityValue" field="quantityValue"
width="80" width="80"
/> />
<vxe-column <vxe-column
title="医疗类型" :title="$t('billing.medicalType')"
align="center" align="center"
field="medTypeCode_dictText" field="medTypeCode_dictText"
/> />
<vxe-column <vxe-column
title="医保编码" :title="$t('billing.insuranceCode')"
align="center" align="center"
field="ybNo" field="ybNo"
/> />
<vxe-column <vxe-column
title="费用性质" :title="$t('billing.feeNature')"
align="center" align="center"
field="contractName" field="contractName"
/> />
<vxe-column <vxe-column
title="收费状态" :title="$t('billing.chargeStatus')"
align="center" align="center"
field="statusEnum_enumText" field="statusEnum_enumText"
width="150" width="150"
@@ -160,22 +160,22 @@
</template> </template>
</vxe-column> </vxe-column>
<vxe-column <vxe-column
title="金额" :title="$t('billing.amount')"
align="right" align="right"
field="totalPrice" field="totalPrice"
header-align="center" header-align="center"
> >
<template #default="scope"> <template #default="scope">
{{ scope.row.totalPrice.toFixed(2) + ' 元' || '0.00' + ' 元' }} {{ scope.row.totalPrice.toFixed(2) + ' ' + $t('billing.yuan') || '0.00' + ' ' + $t('billing.yuan') }}
</template> </template>
</vxe-column> </vxe-column>
<vxe-column <vxe-column
title="收款人" :title="$t('billing.cashier')"
align="center" align="center"
field="entererId_dictText" field="entererId_dictText"
/> />
<vxe-column <vxe-column
title="操作" :title="$t('billing.operation')"
align="center" align="center"
fixed="right" fixed="right"
header-align="center" header-align="center"
@@ -188,7 +188,7 @@
type="primary" type="primary"
@click="printCharge(scope.row)" @click="printCharge(scope.row)"
> >
打印 {{ $t('billing.print') }}
</el-button> </el-button>
</template> </template>
</vxe-column> </vxe-column>
@@ -219,11 +219,14 @@
</template> </template>
<script setup name="SurgeryCharge"> <script setup name="SurgeryCharge">
import { useI18n } from 'vue-i18n';
import { import {
getChargeList, getChargeList,
precharge, precharge,
getChargeInfo, getChargeInfo,
} from '../cliniccharge/components/api'; } from '../cliniccharge/components/api';
const { t } = useI18n();
import {invokeYbPlugin5000, invokeYbPlugin5001} from '@/api/public'; import {invokeYbPlugin5000, invokeYbPlugin5001} from '@/api/public';
import ChargeDialog from '../cliniccharge/components/chargeDialog.vue'; import ChargeDialog from '../cliniccharge/components/chargeDialog.vue';
import {formatDateStr} from '@/utils'; import {formatDateStr} from '@/utils';
@@ -363,7 +366,7 @@ function handleClose(value, msg) {
function confirmCharge() { function confirmCharge() {
let selectRows = chargeListRef.value.getSelectionRows(); let selectRows = chargeListRef.value.getSelectionRows();
if (selectRows.length == 0) { if (selectRows.length == 0) {
proxy.$modal.msgWarning('请选择一条收费项目'); proxy.$modal.msgWarning(t('billing.selectChargeItem'));
return; return;
} }
chargeItemIdList.value = selectRows.map((item) => { chargeItemIdList.value = selectRows.map((item) => {
@@ -395,7 +398,7 @@ function confirmCharge() {
}) || []; }) || [];
openDialog.value = true; openDialog.value = true;
} else { } else {
proxy.$modal.msgError(res?.msg || '预结算失败'); proxy.$modal.msgError(res?.msg || t('billing.preSettleFail'));
} }
}); });
} }
@@ -420,7 +423,7 @@ async function handleReadCard(value) {
}) })
.then((res) => { .then((res) => {
readCardLoading.value = true; readCardLoading.value = true;
loadingText.value = '正在读取...'; loadingText.value = t('billing.reading');
jsonResult = res.data; jsonResult = res.data;
}) })
.catch(() => { .catch(() => {
@@ -445,7 +448,7 @@ async function handleReadCard(value) {
break; break;
case '03': // 医保卡 case '03': // 医保卡
readCardLoading.value = true; readCardLoading.value = true;
loadingText.value = '正在读取...'; loadingText.value = t('billing.reading');
await invokeYbPlugin5001( await invokeYbPlugin5001(
JSON.stringify({ JSON.stringify({
FunctionId: 1, FunctionId: 1,
@@ -479,7 +482,7 @@ async function handleReadCard(value) {
if (userMessage.certNo) { if (userMessage.certNo) {
let selectRows = chargeListRef.value.getSelectionRows(); let selectRows = chargeListRef.value.getSelectionRows();
if (selectRows.length == 0) { if (selectRows.length == 0) {
proxy.$modal.msgWarning('请选择一条收费项目'); proxy.$modal.msgWarning(t('billing.selectChargeItem'));
return; return;
} }
chargeItemIdList.value = selectRows.map((item) => { chargeItemIdList.value = selectRows.map((item) => {
@@ -514,7 +517,7 @@ async function handleReadCard(value) {
}); });
openDialog.value = true; openDialog.value = true;
} else { } else {
proxy.$modal.msgError(res?.msg || '预结算失败'); proxy.$modal.msgError(res?.msg || t('billing.preSettleFail'));
} }
}); });
} }

View File

@@ -1,4 +1,4 @@
<template> <template>
<div class="app-continer"> <div class="app-continer">
<el-form <el-form
ref="queryRef" ref="queryRef"
@@ -6,12 +6,12 @@
:inline="true" :inline="true"
> >
<el-form-item <el-form-item
label="患者姓名" :label="$t('billing.patientName')"
prop="patientName" prop="patientName"
> >
<el-input <el-input
v-model="queryParams.searchKey" v-model="queryParams.searchKey"
placeholder="请输入患者姓名" :placeholder="$t('billing.searchPlaceholderPatient')"
/> />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
@@ -20,13 +20,13 @@
icon="Search" icon="Search"
@click="handleQuery" @click="handleQuery"
> >
搜索 {{ $t('billing.search') }}
</el-button> </el-button>
<el-button <el-button
icon="Refresh" icon="Refresh"
@click="resetQuery" @click="resetQuery"
> >
重置 {{ $t('billing.reset') }}
</el-button> </el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
@@ -38,19 +38,19 @@
border border
> >
<vxe-column <vxe-column
title="患者姓名" :title="$t('billing.patientName')"
align="center" align="center"
field="patientName" field="patientName"
show-overflow="title" show-overflow="title"
/> />
<vxe-column <vxe-column
title="支付单号" :title="$t('billing.payBusNo')"
align="center" align="center"
field="paymentBusNo" field="paymentBusNo"
show-overflow="title" show-overflow="title"
/> />
<vxe-column <vxe-column
title="交易金额(元)" :title="$t('billing.txnAmount')"
align="right" align="right"
field="txnAmt" field="txnAmt"
header-align="center" header-align="center"
@@ -58,19 +58,19 @@
show-overflow="title" show-overflow="title"
/> />
<vxe-column <vxe-column
title="交易类型" :title="$t('billing.txnType')"
align="center" align="center"
field="tranType" field="tranType"
show-overflow="title" show-overflow="title"
/> />
<vxe-column <vxe-column
title="支付方式" :title="$t('billing.payTypeCol')"
align="center" align="center"
field="payType" field="payType"
show-overflow="title" show-overflow="title"
/> />
<vxe-column <vxe-column
title="交易时间" :title="$t('billing.txnTime')"
align="center" align="center"
field="txnTime" field="txnTime"
show-overflow="title" show-overflow="title"
@@ -80,43 +80,43 @@
</template> </template>
</vxe-column> </vxe-column>
<vxe-column <vxe-column
title="原交易类型" :title="$t('billing.origTxnType')"
align="center" align="center"
field="orgTranType" field="orgTranType"
show-overflow="title" show-overflow="title"
/> />
<vxe-column <vxe-column
title="原交易类型" :title="$t('billing.origTxnType')"
align="center" align="center"
field="orgTranType" field="orgTranType"
show-overflow="title" show-overflow="title"
/> />
<vxe-column <vxe-column
title="第三方优惠说明" :title="$t('billing.thirdPartyDiscount')"
align="center" align="center"
field="otherMsg" field="otherMsg"
show-overflow="title" show-overflow="title"
/> />
<vxe-column <vxe-column
title="错误信息" :title="$t('billing.errorMsg')"
align="center" align="center"
field="errMsg" field="errMsg"
show-overflow="title" show-overflow="title"
/> />
<vxe-column <vxe-column
title="查询结果" :title="$t('billing.queryResult')"
align="center" align="center"
field="queryResult" field="queryResult"
show-overflow="title" show-overflow="title"
/> />
<vxe-column <vxe-column
title="查询结果说明" :title="$t('billing.queryResultMsg')"
align="center" align="center"
field="queryResultMsg" field="queryResultMsg"
show-overflow="title" show-overflow="title"
/> />
<vxe-column <vxe-column
title="操作" :title="$t('billing.operation')"
align="center" align="center"
field="paymentEnum_enumText" field="paymentEnum_enumText"
width="340" width="340"
@@ -128,7 +128,7 @@
:disabled="!scope.row.paymentId" :disabled="!scope.row.paymentId"
@click="getPayInfo(scope.row.paymentId)" @click="getPayInfo(scope.row.paymentId)"
> >
支付结果查询 {{ $t('billing.payResultQuery') }}
</el-button> </el-button>
<el-button <el-button
type="warning" type="warning"
@@ -136,7 +136,7 @@
:disabled="!scope.row.paymentId" :disabled="!scope.row.paymentId"
@click="returnFee(scope.row.paymentId)" @click="returnFee(scope.row.paymentId)"
> >
退费 {{ $t('billing.refundItem') }}
</el-button> </el-button>
<el-button <el-button
type="danger" type="danger"
@@ -145,14 +145,14 @@
:disabled="!scope.row.paymentId" :disabled="!scope.row.paymentId"
@click="returnFeeNext(scope.row.paymentId)" @click="returnFeeNext(scope.row.paymentId)"
> >
隔天退费 {{ $t('billing.nextDayRefund') }}
</el-button> </el-button>
<el-button <el-button
type="success" type="success"
link link
@click="returnFeeResultQuery(scope.row.id)" @click="returnFeeResultQuery(scope.row.id)"
> >
退费结果查询 {{ $t('billing.refundResultQuery') }}
</el-button> </el-button>
</template> </template>
</vxe-column> </vxe-column>
@@ -169,8 +169,11 @@
<script setup name="ClinicRecord"> <script setup name="ClinicRecord">
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
import { useI18n } from 'vue-i18n';
import {getList, getPayinfo, returnfee, returnFeednext, returnResult} from './components/api.js'; import {getList, getPayinfo, returnfee, returnFeednext, returnResult} from './components/api.js';
const { t } = useI18n();
const total = ref(0); const total = ref(0);
const queryParams = ref({ const queryParams = ref({
pageNo: 1, pageNo: 1,
@@ -182,19 +185,19 @@ const loading = ref(false);
const getPayInfo = (paymentId) => { const getPayInfo = (paymentId) => {
console console
getPayinfo({ paymentId }).then((res) => { getPayinfo({ paymentId }).then((res) => {
proxy.$message.success('支付结果查询成功'); proxy.$message.success(t('billing.opSuccess'));
console.log(res); console.log(res);
}); });
}; };
const returnFee = (paymentId) => { const returnFee = (paymentId) => {
returnfee({ paymentId }).then((res) => { returnfee({ paymentId }).then((res) => {
proxy.$message.success('退费成功'); proxy.$message.success(t('billing.opSuccess'));
console.log(res); console.log(res);
}); });
}; };
const returnFeeNext = (paymentId) => { const returnFeeNext = (paymentId) => {
returnFeednext({ paymentId }).then((res) => { returnFeednext({ paymentId }).then((res) => {
proxy.$message.success('隔天退费成功'); proxy.$message.success(t('billing.opSuccess'));
console.log(res); console.log(res);
}); });
}; };

View File

@@ -10,25 +10,25 @@
label-position="right" label-position="right"
> >
<el-form-item <el-form-item
label="患者信息" :label="$t('pharmacy.patientInfo')"
prop="searchKey" prop="searchKey"
> >
<el-input <el-input
v-model="queryParams.searchKey" v-model="queryParams.searchKey"
placeholder="请输入姓名/证件号" :placeholder="$t('pharmacy.placeholderNameOrId')"
clearable clearable
style="width: 160px" style="width: 160px"
@keyup.enter="handleQuery" @keyup.enter="handleQuery"
/> />
</el-form-item> </el-form-item>
<el-form-item <el-form-item
label="发药状态" :label="$t('pharmacy.dispenseStatus')"
prop="departmentId" prop="departmentId"
style="margin-left: 10px" style="margin-left: 10px"
> >
<el-select <el-select
v-model="queryParams.statusEnum" v-model="queryParams.statusEnum"
placeholder="请选择发药状态" :placeholder="$t('pharmacy.placeholderSelectDispenseStatus')"
clearable clearable
style="width: 160px" style="width: 160px"
@change="handleQuery" @change="handleQuery"
@@ -41,12 +41,12 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="就诊日期"> <el-form-item :label="$t('pharmacy.visitDate')">
<el-date-picker <el-date-picker
v-model="dateRange" v-model="dateRange"
type="daterange" type="daterange"
start-placeholder="开始日期" :start-placeholder="$t('pharmacy.startDate')"
end-placeholder="结束日期" :end-placeholder="$t('pharmacy.endDate')"
style="width: 250px" style="width: 250px"
value-format="YYYY-MM-DD" value-format="YYYY-MM-DD"
@change="handleQuery" @change="handleQuery"
@@ -73,10 +73,10 @@
type="primary" type="primary"
@click="handleQuery" @click="handleQuery"
> >
搜索 {{ $t('common.search') }}
</el-button> </el-button>
<el-button @click="resetQuery"> <el-button @click="resetQuery">
重置 {{ $t('common.reset') }}
</el-button> </el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
@@ -91,31 +91,31 @@
> >
<vxe-column <vxe-column
field="patientName" field="patientName"
title="姓名" :title="$t('pharmacy.name')"
width="130" width="130"
align="center" align="center"
/> />
<vxe-column <vxe-column
field="genderEnum_enumText" field="genderEnum_enumText"
title="性别" :title="$t('pharmacy.gender')"
width="80" width="80"
align="center" align="center"
/> />
<vxe-column <vxe-column
field="age" field="age"
title="年龄" :title="$t('pharmacy.age')"
width="80" width="80"
align="center" align="center"
/> />
<vxe-column <vxe-column
field="phone" field="phone"
title="电话" :title="$t('pharmacy.phone')"
width="80" width="80"
align="center" align="center"
/> />
<vxe-column <vxe-column
field="receptionTime" field="receptionTime"
title="就诊日期" :title="$t('pharmacy.visitDateCol')"
align="center" align="center"
> >
<template #default="scope"> <template #default="scope">
@@ -182,11 +182,11 @@
<span <span
style="color: #606266; font-size: 14px; font-weight: 700; margin-right: 15px" style="color: #606266; font-size: 14px; font-weight: 700; margin-right: 15px"
> >
调配药师 {{ $t('pharmacy.preparer') }}
</span> </span>
<el-select <el-select
v-model="preparerDoctor" v-model="preparerDoctor"
placeholder="调配药师" :placeholder="$t('pharmacy.placeholderPreparer')"
style="width: 160px" style="width: 160px"
> >
<el-option <el-option
@@ -199,11 +199,11 @@
<span <span
style="color: #606266; font-size: 14px; font-weight: 700; margin-right: 15px" style="color: #606266; font-size: 14px; font-weight: 700; margin-right: 15px"
> >
药品分类 {{ $t('pharmacy.drugCategory') }}
</span> </span>
<el-select <el-select
v-model="tcmFlag" v-model="tcmFlag"
placeholder="药品分类" :placeholder="$t('pharmacy.placeholderDrugCategory')"
style="width: 160px" style="width: 160px"
@change=" @change="
() => { () => {
@@ -223,11 +223,11 @@
<span <span
style="color: #606266; font-size: 14px; font-weight: 700; margin-right: 15px" style="color: #606266; font-size: 14px; font-weight: 700; margin-right: 15px"
> >
项目 {{ $t('pharmacy.project') }}
</span> </span>
<el-select <el-select
v-model="projectTypeCode" v-model="projectTypeCode"
placeholder="项目" :placeholder="$t('pharmacy.placeholderProject')"
style="width: 160px" style="width: 160px"
:clearable="false" :clearable="false"
@change=" @change="
@@ -240,15 +240,15 @@
" "
> >
<el-option <el-option
label="全部" :label="$t('pharmacy.all')"
value="1" value="1"
/> />
<el-option <el-option
label="药品" :label="$t('pharmacy.drug')"
value="2" value="2"
/> />
<el-option <el-option
label="耗材" :label="$t('pharmacy.consumable')"
value="3" value="3"
/> />
</el-select> </el-select>
@@ -258,24 +258,24 @@
style="margin-left: 30px" style="margin-left: 30px"
@click="handleBatch()" @click="handleBatch()"
> >
批量发药 {{ $t('pharmacy.batchDispense') }}
</el-button> </el-button>
<el-button <el-button
type="primary" type="primary"
style="margin-left: 30px" style="margin-left: 30px"
@click="handleScan()" @click="handleScan()"
> >
扫码 {{ $t('pharmacy.scan') }}
</el-button> </el-button>
<el-button <el-button
type="primary" type="primary"
style="margin-left: 30px" style="margin-left: 30px"
@click="printPrescription()" @click="printPrescription()"
> >
处方打印 {{ $t('pharmacy.prescriptionPrint') }}
</el-button> </el-button>
<div style="position: absolute; top: 30px; right: 25px"> <div style="position: absolute; top: 30px; right: 25px">
总金额{{ medicineTotalPrice ? medicineTotalPrice.toFixed(2) : "0.00" }} {{ $t('pharmacy.totalAmount') }}{{ medicineTotalPrice ? medicineTotalPrice.toFixed(2) : "0.00" }}{{ $t('pharmacy.yuan') }}
</div> </div>
</div> </div>
<vxe-table <vxe-table
@@ -297,37 +297,37 @@
/> />
<vxe-column <vxe-column
field="prescriptionNo" field="prescriptionNo"
title="处方号" :title="$t('pharmacy.prescriptionNo')"
width="120" width="120"
align="center" align="center"
/> />
<vxe-column <vxe-column
field="conditionName" field="conditionName"
title="诊断" :title="$t('pharmacy.diagnosis')"
width="120" width="120"
align="center" align="center"
/> />
<vxe-column <vxe-column
field="dispenseEnum_enumText" field="dispenseEnum_enumText"
title="处方类型" :title="$t('pharmacy.prescriptionType')"
width="120" width="120"
align="center" align="center"
/> />
<vxe-column <vxe-column
field="itemName" field="itemName"
title="项目名称" :title="$t('pharmacy.itemName')"
width="160" width="160"
align="center" align="center"
/> />
<vxe-column <vxe-column
field="merchandiseName" field="merchandiseName"
title="商品名称" :title="$t('pharmacy.merchandiseName')"
width="160" width="160"
align="center" align="center"
/> />
<vxe-column <vxe-column
field="quantity" field="quantity"
title="发药数量" :title="$t('pharmacy.dispenseQty')"
width="130" width="130"
align="center" align="center"
> >
@@ -367,7 +367,7 @@
</vxe-column> </vxe-column>
<vxe-column <vxe-column
field="lotNumber" field="lotNumber"
title="批次号" :title="$t('pharmacy.lotNumber')"
width="160" width="160"
align="center" align="center"
> >
@@ -405,7 +405,7 @@
</vxe-column> </vxe-column>
<vxe-column <vxe-column
field="statusEnum_enumText" field="statusEnum_enumText"
title="发药状态" :title="$t('pharmacy.dispenseStatusCol')"
width="100" width="100"
align="center" align="center"
> >
@@ -417,7 +417,7 @@
</vxe-column> </vxe-column>
<vxe-column <vxe-column
field="dispensePerDuration" field="dispensePerDuration"
title="天数" :title="$t('pharmacy.days')"
width="80" width="80"
align="center" align="center"
/> />
@@ -425,7 +425,7 @@
<!-- <vxe-column field="quantity" title="发药数量" width="100" align="center" /> --> <!-- <vxe-column field="quantity" title="发药数量" width="100" align="center" /> -->
<vxe-column <vxe-column
field="totalVolume" field="totalVolume"
title="规格" :title="$t('pharmacy.spec')"
width="100" width="100"
align="center" align="center"
/> />
@@ -444,7 +444,7 @@
<vxe-column <vxe-column
v-if="tcmFlag == '0'" v-if="tcmFlag == '0'"
field="traceNo" field="traceNo"
title="追溯码" :title="$t('pharmacy.traceNo')"
width="180" width="180"
align="center" align="center"
> >
@@ -457,7 +457,7 @@
<el-input <el-input
:ref="'traceNoRef' + scope.rowIndex" :ref="'traceNoRef' + scope.rowIndex"
v-model="scope.row.traceNo" v-model="scope.row.traceNo"
placeholder="请输入追溯码" :placeholder="$t('pharmacy.placeholderTraceNo')"
@input="handleTraceNoInput(scope.row, scope.rowIndex)" @input="handleTraceNoInput(scope.row, scope.rowIndex)"
/> />
</el-tooltip> </el-tooltip>
@@ -465,7 +465,7 @@
</vxe-column> </vxe-column>
<vxe-column <vxe-column
field="totalPrice" field="totalPrice"
title="金额" :title="$t('pharmacy.amount')"
width="100" width="100"
:formatter="formatPrice" :formatter="formatPrice"
align="right" align="right"
@@ -473,37 +473,37 @@
/> />
<vxe-column <vxe-column
field="locationName" field="locationName"
title="发药药房" :title="$t('pharmacy.dispensePharmacy')"
width="90" width="90"
align="center" align="center"
/> />
<vxe-column <vxe-column
field="manufacturerText" field="manufacturerText"
title="生产厂家" :title="$t('pharmacy.manufacturer')"
width="200" width="200"
align="center" align="center"
/> />
<vxe-column <vxe-column
field="doctorName" field="doctorName"
title="开单医生" :title="$t('pharmacy.orderingDoctor')"
width="100" width="100"
align="center" align="center"
/> />
<!-- <vxe-column field="dose" title="剂量" width="100" align="center" /> --> <!-- <vxe-column field="dose" title="剂量" width="100" align="center" /> -->
<vxe-column <vxe-column
field="rateCode" field="rateCode"
title="频次" :title="$t('pharmacy.frequency')"
width="100" width="100"
align="center" align="center"
/> />
<vxe-column <vxe-column
field="methodCode_dictText" field="methodCode_dictText"
title="用法" :title="$t('pharmacy.usage')"
width="100" width="100"
align="center" align="center"
/> />
<vxe-column <vxe-column
title="操作" :title="$t('pharmacy.operation')"
align="center" align="center"
width="160" width="160"
fixed="right" fixed="right"
@@ -517,7 +517,7 @@
icon="SuccessFilled" icon="SuccessFilled"
@click="handleBatch(scope.row)" @click="handleBatch(scope.row)"
> >
发药 {{ $t('pharmacy.dispense') }}
</el-button> </el-button>
<el-button <el-button
link link
@@ -526,7 +526,7 @@
icon="CircleClose" icon="CircleClose"
@click="backMedicine(scope.row)" @click="backMedicine(scope.row)"
> >
作废 {{ $t('pharmacy.void') }}
</el-button> </el-button>
</template> </template>
</vxe-column> </vxe-column>
@@ -552,13 +552,13 @@
</div> </div>
<el-dialog <el-dialog
v-model="showDialog" v-model="showDialog"
title="选择作废原因" :title="$t('pharmacy.selectVoidReason')"
width="30%" width="30%"
> >
<!-- 下拉选择框 --> <!-- 下拉选择框 -->
<el-select <el-select
v-model="notPerformedReasonEnum" v-model="notPerformedReasonEnum"
placeholder="请选择作废原因" :placeholder="$t('pharmacy.placeholderSelectVoidReason')"
> >
<el-option <el-option
v-for="item in backReason" v-for="item in backReason"
@@ -574,8 +574,8 @@
<el-button <el-button
type="primary" type="primary"
@click="handleConfirm" @click="handleConfirm"
> </el-button> >{{ $t('pharmacy.confirm') }}</el-button>
<el-button @click="handleCancel"> </el-button> <el-button @click="handleCancel">{{ $t('pharmacy.cancel') }}</el-button>
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
@@ -589,7 +589,8 @@
</template> </template>
<script setup name="westernmedicine"> <script setup name="westernmedicine">
import {onMounted, ref} from 'vue'; import {onMounted, ref, computed} from 'vue';
import {useI18n} from 'vue-i18n';
import {ElMessage} from 'element-plus'; import {ElMessage} from 'element-plus';
import { import {
deviceDispense, deviceDispense,
@@ -616,6 +617,7 @@ import useUserStore from '@/store/modules/user';
const userStore = useUserStore(); const userStore = useUserStore();
const { t } = useI18n();
const {proxy} = getCurrentInstance(); const {proxy} = getCurrentInstance();
const showSearch = ref(true); const showSearch = ref(true);
const total = ref(0); const total = ref(0);
@@ -655,13 +657,13 @@ const ypName = ref('');
const medicineTotalPrice = ref(0); const medicineTotalPrice = ref(0);
const projectTypeCode = ref("2"); const projectTypeCode = ref("2");
const selectedRow = ref(null); const selectedRow = ref(null);
const medCategoryCode = ref([ const medCategoryCode = computed(() => [
{ {
label: "西药中成药", label: t('pharmacy.westernChinese'),
value: "0", value: "0",
}, },
{ {
label: "中药", label: t('pharmacy.chinese'),
value: "1", value: "1",
}, },
]); ]);
@@ -697,7 +699,7 @@ function submit(value) {
itemTraceNo(list).then((res) => { itemTraceNo(list).then((res) => {
if (res.code === 200) { if (res.code === 200) {
if (!res.data) { if (!res.data) {
proxy.$modal.msgWarning("未在库存中匹配到追溯码,请在发药列表中单独扫描"); proxy.$modal.msgWarning(t('pharmacy.msgNoMatchTraceNo'));
openTraceNoDialog.value = false; openTraceNoDialog.value = false;
proxy.$refs["traceNoRef0"].focus(); proxy.$refs["traceNoRef0"].focus();
return; return;
@@ -707,7 +709,7 @@ function submit(value) {
res.data[item.medicineId] && res.data[item.medicineId] &&
res.data[item.medicineId].split(",") > item.quantity res.data[item.medicineId].split(",") > item.quantity
) { ) {
proxy.$modal.msgWarning("操作失败"); proxy.$modal.msgWarning(t('pharmacy.msgOperationFailed'));
return; return;
} }
medicineInfoList.value[index].traceNo = res.data[item.medicineId]; medicineInfoList.value[index].traceNo = res.data[item.medicineId];
@@ -760,13 +762,13 @@ function getList() {
async function printPrescription() { async function printPrescription() {
// 空值检查 - 防止 tableRef 为空时报错 // 空值检查 - 防止 tableRef 为空时报错
if (!tableRef.value) { if (!tableRef.value) {
proxy.$modal.msgWarning("表格组件未初始化,请刷新页面重试"); proxy.$modal.msgWarning(t('pharmacy.printWarningNoTable'));
return; return;
} }
const selectedRows = tableRef.value.getSelectionRows(); const selectedRows = tableRef.value.getSelectionRows();
if (!selectedRows || selectedRows.length === 0) { if (!selectedRows || selectedRows.length === 0) {
proxy.$modal.msgWarning("未选择要打印的项目,请重新选择,打印失败"); proxy.$modal.msgWarning(t('pharmacy.printWarningNoSelect'));
return; return;
} }
@@ -777,7 +779,7 @@ async function printPrescription() {
const res = await advicePrint({requestIds: requestIds, isPrescription: "1"}); const res = await advicePrint({requestIds: requestIds, isPrescription: "1"});
if (!res || !res.data || !res.data.adviceItemList) { if (!res || !res.data || !res.data.adviceItemList) {
proxy.$modal.msgWarning("获取打印数据失败,请稍后重试"); proxy.$modal.msgWarning(t('pharmacy.printWarningNoData'));
return; return;
} }
@@ -883,7 +885,7 @@ async function printPrescription() {
}); });
} catch (error) { } catch (error) {
console.error('处方打印失败:', error); console.error('处方打印失败:', error);
proxy.$modal.msgError('处方打印失败: ' + (error.message || '未知错误')); proxy.$modal.msgError(t('pharmacy.printFailed') + ': ' + (error.message || t('common.error')));
} }
} }
@@ -918,14 +920,14 @@ function formatLotNumberLabel(row, item) {
if (row.unitCode == item.maxUnitCode) { if (row.unitCode == item.maxUnitCode) {
return ( return (
item.inventoryLotNumber + item.inventoryLotNumber +
' 剩余' + ' ' + t('pharmacy.remaining') + '' +
formatInventory( formatInventory(
item.inventoryQuantity, item.inventoryQuantity,
item.partPercent, item.partPercent,
item.maxUnitCode_dictText, item.maxUnitCode_dictText,
item.inventoryUnitCode_dictText item.inventoryUnitCode_dictText
) + ) +
' 有效期至' + ' ' + t('pharmacy.expDate') + '' +
proxy.formatDateStr(item.expirationDate, 'YYYY-MM-DD') proxy.formatDateStr(item.expirationDate, 'YYYY-MM-DD')
); );
} else { } else {
@@ -935,7 +937,7 @@ function formatLotNumberLabel(row, item) {
item.inventoryQuantity + item.inventoryQuantity +
' ' + ' ' +
item.inventoryUnitCode_dictText + item.inventoryUnitCode_dictText +
' 有效期至' + ' ' + t('pharmacy.expDate') + '' +
proxy.formatDateStr(item.expirationDate, 'YYYY-MM-DD') proxy.formatDateStr(item.expirationDate, 'YYYY-MM-DD')
); );
} }
@@ -1052,9 +1054,9 @@ function handleCellDbClick(row, column, cellValue, event) {
function formatPrice(row, column, cellValue) { function formatPrice(row, column, cellValue) {
if (cellValue === null || cellValue === undefined) { if (cellValue === null || cellValue === undefined) {
return "0.00 "; // 如果值为空返回0.00 return "0.00 " + t('pharmacy.yuan');
} }
return cellValue.toFixed(2) + " "; // 保留两位小数 return cellValue.toFixed(2) + " " + t('pharmacy.yuan');
} }
function tagType(statusEnum) { function tagType(statusEnum) {
@@ -1130,7 +1132,7 @@ function getMedicineList(encounterId) {
loading.value = false; loading.value = false;
}) })
.catch((error) => { .catch((error) => {
proxy.$modal.msgError('获取数据失败'); proxy.$modal.msgError(t('pharmacy.msgDispenseFailed'));
}); });
} else if (projectTypeCode.value == 2) { } else if (projectTypeCode.value == 2) {
// 只调用listWesternmedicine接口 // 只调用listWesternmedicine接口
@@ -1228,7 +1230,7 @@ function submitMedicine(saveList) {
promises.push( promises.push(
deviceDispense(deviceList).then((res) => { deviceDispense(deviceList).then((res) => {
if (res.code != 200) { if (res.code != 200) {
throw new Error("耗材发药失败"); throw new Error(t('pharmacy.msgDispenseFailed'));
} }
return res; return res;
}) })
@@ -1247,7 +1249,7 @@ function submitMedicine(saveList) {
promises.push( promises.push(
prepareMedicion(preparationList).then((res) => { prepareMedicion(preparationList).then((res) => {
if (res.code != 200) { if (res.code != 200) {
throw new Error('药品发药失败'); throw new Error(t('pharmacy.msgDispenseFailed'));
} }
return res; return res;
}) })
@@ -1257,7 +1259,7 @@ function submitMedicine(saveList) {
promises.push( promises.push(
updateMedicion(preparedList).then((res) => { updateMedicion(preparedList).then((res) => {
if (res.code != 200) { if (res.code != 200) {
throw new Error("药品发药失败"); throw new Error(t('pharmacy.msgDispenseFailed'));
} }
return res; return res;
}) })
@@ -1273,12 +1275,12 @@ function submitMedicine(saveList) {
} }
}) })
.then((response) => { .then((response) => {
proxy.$modal.msgSuccess("发药成功"); proxy.$modal.msgSuccess(t('pharmacy.msgDispenseSuccess'));
// 重新获取数据 // 重新获取数据
getMedicineList(currentRow.value.encounterId); getMedicineList(currentRow.value.encounterId);
}) })
.catch((error) => { .catch((error) => {
proxy.$modal.msgError('发药失败: ' + error.message); proxy.$modal.msgError(t('pharmacy.msgDispenseFailed') + ': ' + error.message);
}); });
} else if (projectTypeCode.value == 2) { } else if (projectTypeCode.value == 2) {
let preparationList = saveList.filter((item) => { let preparationList = saveList.filter((item) => {
@@ -1296,7 +1298,7 @@ function submitMedicine(saveList) {
prepareMedicion(preparationList).then((res) => { prepareMedicion(preparationList).then((res) => {
if (res.code == 200) { if (res.code == 200) {
updateMedicion(preparationList).then((response) => { updateMedicion(preparationList).then((response) => {
proxy.$modal.msgSuccess('发药成功'); proxy.$modal.msgSuccess(t('pharmacy.msgDispenseSuccess'));
getMedicineList(currentRow.value.encounterId); getMedicineList(currentRow.value.encounterId);
}); });
} }
@@ -1320,7 +1322,7 @@ function validInventory(row, item) {
quantity = quantity * item.partPercent; quantity = quantity * item.partPercent;
} }
if (quantity > item.inventoryQuantity) { if (quantity > item.inventoryQuantity) {
proxy.$modal.msgError('当前批次库存不足'); proxy.$modal.msgError(t('pharmacy.msgInsufficientStock'));
return; return;
} }
} }
@@ -1336,10 +1338,10 @@ function handleQuantity(row) {
}); });
if (totalQuantity > row.requestQuantity) { if (totalQuantity > row.requestQuantity) {
couldSave.value = false; couldSave.value = false;
proxy.$modal.msgError('发药数量不能大于总数量'); proxy.$modal.msgError(t('pharmacy.msgQtyExceedsTotal'));
} else if (totalQuantity < row.requestQuantity) { } else if (totalQuantity < row.requestQuantity) {
couldSave.value = false; couldSave.value = false;
proxy.$modal.msgError('发药数量不能小于总数量'); proxy.$modal.msgError(t('pharmacy.msgQtyBelowTotal'));
} else { } else {
couldSave.value = true; couldSave.value = true;
} }
@@ -1428,7 +1430,7 @@ function handleBatch(row) {
}; };
}); });
} else { } else {
proxy.$modal.msgWarning('未选择要发药的项目,请重新选择,发药失败'); proxy.$modal.msgWarning(t('pharmacy.msgSelectDispenseItem'));
return; return;
} }
} }
@@ -1456,7 +1458,7 @@ async function handleConfirm() {
return; return;
} }
const loading = ElLoading.service({text: "作废中..."}); const loading = ElLoading.service({text: t('pharmacy.voiding')});
try { try {
const params = buildParams(); const params = buildParams();
@@ -1472,10 +1474,10 @@ async function handleConfirm() {
// 分离验证逻辑 // 分离验证逻辑
function validate() { function validate() {
if (!notPerformedReasonEnum.value) { if (!notPerformedReasonEnum.value) {
return {success: false, message: "请选择作废原因"}; return {success: false, message: t('pharmacy.msgSelectVoidReason')};
} }
if (!selectedRow.value) { if (!selectedRow.value) {
return {success: false, message: "未选择数据"}; return {success: false, message: t('pharmacy.msgNoDataSelected')};
} }
return {success: true}; return {success: true};
} }

View File

@@ -1,9 +1,9 @@
<template> <template>
<div class="smart-triage-queue"> <div class="smart-triage-queue">
<!-- 顶部标题栏 --> <!-- 顶部标题栏 -->
<div class="header-section"> <div class="header-section">
<div class="header-left"> <div class="header-left">
<span class="title">智能分诊排队管理 - {{ currentDeptName }}</span> <span class="title">{{ $t('triage.title') }} - {{ currentDeptName }}</span>
</div> </div>
<div class="header-right"> <div class="header-right">
<el-button <el-button
@@ -11,13 +11,13 @@
@click="handleRefresh" @click="handleRefresh"
> >
<el-icon><Refresh /></el-icon> <el-icon><Refresh /></el-icon>
刷新 {{ $t('common.refresh') }}
</el-button> </el-button>
<el-button @click="handleExit"> <el-button @click="handleExit">
退出 {{ $t('triage.exit') }}
</el-button> </el-button>
<el-button @click="handleConfig"> <el-button @click="handleConfig">
后台配置 {{ $t('triage.backendConfig') }}
</el-button> </el-button>
</div> </div>
</div> </div>
@@ -27,7 +27,7 @@
<!-- 左侧智能候选池 --> <!-- 左侧智能候选池 -->
<div class="left-panel"> <div class="left-panel">
<div class="panel-header"> <div class="panel-header">
<span class="panel-title"> 智能候选池 (已签到未入队)</span> <span class="panel-title"> {{ $t('triage.candidatePoolTitle') }}</span>
</div> </div>
<div class="table-container"> <div class="table-container">
<vxe-table <vxe-table
@@ -45,43 +45,43 @@
/> />
<vxe-column <vxe-column
field="sequenceNo" field="sequenceNo"
title="序号" :title="$t('triage.seqNo')"
width="80" width="80"
align="center" align="center"
/> />
<vxe-column <vxe-column
field="patientName" field="patientName"
title="患者" :title="$t('triage.patient')"
width="100" width="100"
align="center" align="center"
/> />
<vxe-column <vxe-column
field="age" field="age"
title="年龄" :title="$t('triage.age')"
width="80" width="80"
align="center" align="center"
/> />
<vxe-column <vxe-column
field="appointmentType" field="appointmentType"
title="号别" :title="$t('triage.ticketType')"
width="100" width="100"
align="center" align="center"
/> />
<vxe-column <vxe-column
field="room" field="room"
title="诊室" :title="$t('triage.room')"
width="120" width="120"
align="center" align="center"
/> />
<vxe-column <vxe-column
field="doctor" field="doctor"
title="医生" :title="$t('triage.doctor')"
width="120" width="120"
align="center" align="center"
/> />
<vxe-column <vxe-column
field="matchingRule" field="matchingRule"
title="命中规则" :title="$t('triage.matchedRule')"
min-width="150" min-width="150"
align="center" align="center"
/> />
@@ -93,14 +93,14 @@
:disabled="selectedCandidates.length === 0 || isQueryingHistory" :disabled="selectedCandidates.length === 0 || isQueryingHistory"
@click="handleAddToQueue" @click="handleAddToQueue"
> >
加入队列 >> {{ $t('triage.addToQueue') }}
</el-button> </el-button>
<el-button <el-button
type="primary" type="primary"
:disabled="filteredCandidatePoolList.length === 0 || isQueryingHistory" :disabled="filteredCandidatePoolList.length === 0 || isQueryingHistory"
@click="handleAddAllToQueue" @click="handleAddAllToQueue"
> >
一键加入队列 {{ $t('triage.addAllToQueue') }}
</el-button> </el-button>
</div> </div>
</div> </div>
@@ -108,12 +108,12 @@
<!-- 右侧智能队列 --> <!-- 右侧智能队列 -->
<div class="right-panel"> <div class="right-panel">
<div class="panel-header"> <div class="panel-header">
<span class="panel-title"> 智能队列 (全科)</span> <span class="panel-title"> {{ $t('triage.queueTitle') }}</span>
<div class="history-query"> <div class="history-query">
<el-date-picker <el-date-picker
v-model="queryDate" v-model="queryDate"
type="date" type="date"
placeholder="选择日期" :placeholder="$t('triage.selectDate')"
format="YYYY-MM-DD" format="YYYY-MM-DD"
value-format="YYYY-MM-DD" value-format="YYYY-MM-DD"
size="small" size="small"
@@ -124,19 +124,19 @@
size="small" size="small"
@click="handleHistoryQuery" @click="handleHistoryQuery"
> >
查询 {{ $t('triage.query') }}
</el-button> </el-button>
<el-button <el-button
size="small" size="small"
@click="handleTodayQuery" @click="handleTodayQuery"
> >
今天 {{ $t('triage.today') }}
</el-button> </el-button>
</div> </div>
</div> </div>
<div class="table-container"> <div class="table-container">
<vxe-table <vxe-table
:data="filteredQueueList" :data="translatedQueueList"
stripe stripe
border border
height="100%" height="100%"
@@ -146,49 +146,49 @@
> >
<vxe-column <vxe-column
field="queueOrder" field="queueOrder"
title="队序" :title="$t('triage.queueOrder')"
width="80" width="80"
align="center" align="center"
/> />
<vxe-column <vxe-column
field="patientName" field="patientName"
title="患者" :title="$t('triage.patient')"
width="100" width="100"
align="center" align="center"
/> />
<vxe-column <vxe-column
field="appointmentType" field="appointmentType"
title="号别" :title="$t('triage.ticketType')"
width="100" width="100"
align="center" align="center"
/> />
<vxe-column <vxe-column
field="room" field="room"
title="诊室" :title="$t('triage.room')"
width="120" width="120"
align="center" align="center"
/> />
<vxe-column <vxe-column
field="doctor" field="doctor"
title="医生" :title="$t('triage.doctor')"
width="120" width="120"
align="center" align="center"
/> />
<vxe-column <vxe-column
field="waitingTime" field="waitingTime"
title="等待" :title="$t('triage.waiting')"
width="100" width="100"
align="center" align="center"
/> />
<vxe-column <vxe-column
field="status" field="status"
title="状态" :title="$t('triage.status')"
width="100" width="100"
align="center" align="center"
> >
<template #default="scope"> <template #default="scope">
<el-tag :type="getStatusTagType(scope.row.status)"> <el-tag :type="getStatusTagType(scope.row.status)">
{{ scope.row.status }} {{ scope.row.displayStatus }}
</el-tag> </el-tag>
</template> </template>
</vxe-column> </vxe-column>
@@ -202,7 +202,7 @@
size="small" size="small"
@click="handleRemoveFromQueue" @click="handleRemoveFromQueue"
> >
&lt;&lt; 移出队列 &lt;&lt; {{ $t('triage.removeFromQueue') }}
</el-button> </el-button>
<el-button <el-button
type="info" type="info"
@@ -231,7 +231,7 @@
<div class="filter-section"> <div class="filter-section">
<div class="filter-left"> <div class="filter-left">
<div class="filter-label"> <div class="filter-label">
诊室快速过滤栏 {{ $t('triage.roomFilterTitle') }}
</div> </div>
<div class="filter-button-wrapper"> <div class="filter-button-wrapper">
<el-button <el-button
@@ -239,7 +239,7 @@
size="small" size="small"
@click="selectedRoom = 'all'" @click="selectedRoom = 'all'"
> >
全部 {{ $t('triage.all') }}
</el-button> </el-button>
<el-button <el-button
v-for="room in uniqueRooms" v-for="room in uniqueRooms"
@@ -258,14 +258,14 @@
size="small" size="small"
@click="showOnlyWaiting = true" @click="showOnlyWaiting = true"
> >
只显示等待 {{ $t('triage.showOnlyWaiting') }}
</el-button> </el-button>
<el-button <el-button
:type="!showOnlyWaiting ? 'primary' : ''" :type="!showOnlyWaiting ? 'primary' : ''"
size="small" size="small"
@click="showOnlyWaiting = false" @click="showOnlyWaiting = false"
> >
显示全部状态 {{ $t('triage.showAllStatus') }}
</el-button> </el-button>
</div> </div>
</div> </div>
@@ -273,11 +273,11 @@
<!-- 叫号控制板 --> <!-- 叫号控制板 -->
<div class="call-control-section"> <div class="call-control-section">
<div class="call-control-label"> <div class="call-control-label">
叫号控制板 {{ $t('triage.callPanelTitle') }}
</div> </div>
<div class="call-control-content"> <div class="call-control-content">
<div class="current-call-display"> <div class="current-call-display">
当前呼叫: {{ currentCall.number }} {{ currentCall.name }} 诊室: {{ currentCall.room }} {{ $t('triage.currentCall') }}: {{ currentCall.number }} {{ currentCall.name }} {{ $t('triage.room') }}: {{ currentCall.room }}
</div> </div>
<div class="control-buttons"> <div class="control-buttons">
<el-button <el-button
@@ -285,35 +285,35 @@
:disabled="isQueryingHistory" :disabled="isQueryingHistory"
@click="handleSelectCall" @click="handleSelectCall"
> >
选呼 {{ $t('triage.selectCall') }}
</el-button> </el-button>
<el-button <el-button
type="success" type="success"
:disabled="isQueryingHistory" :disabled="isQueryingHistory"
@click="handleNextPatient" @click="handleNextPatient"
> >
下一患者 {{ $t('triage.nextPatient') }}
</el-button> </el-button>
<el-button <el-button
type="warning" type="warning"
:disabled="isQueryingHistory" :disabled="isQueryingHistory"
@click="handleSkip" @click="handleSkip"
> >
跳过 {{ $t('triage.skip') }}
</el-button> </el-button>
<el-button <el-button
type="primary" type="primary"
:disabled="isQueryingHistory" :disabled="isQueryingHistory"
@click="handleComplete" @click="handleComplete"
> >
完成 {{ $t('triage.complete') }}
</el-button> </el-button>
<el-button <el-button
type="info" type="info"
:disabled="isQueryingHistory" :disabled="isQueryingHistory"
@click="handleRequeue" @click="handleRequeue"
> >
过号重排 {{ $t('triage.requeue') }}
</el-button> </el-button>
</div> </div>
</div> </div>
@@ -322,17 +322,17 @@
<!-- LED显示 --> <!-- LED显示 -->
<div class="led-section"> <div class="led-section">
<div class="led-label"> <div class="led-label">
LED: {{ $t('triage.ledLabel') }}:
</div> </div>
<div class="led-display"> <div class="led-display">
[{{ currentCall.number }}]{{ currentCall.name }}请到{{ currentCall.room }}({{ callType }}) [{{ currentCall.number }}]{{ currentCall.name }}{{ $t('triage.pleaseGoTo') }}{{ currentCall.room }}({{ callTypeDisplay }})
</div> </div>
</div> </div>
<!-- 语音提示 --> <!-- 语音提示 -->
<div class="voice-section"> <div class="voice-section">
<span class="voice-label">语音:</span> <span class="voice-label">{{ $t('triage.voiceLabel') }}:</span>
<span class="voice-text">{{ currentCall.number }}{{ currentCall.name }}{{ currentCall.room }}({{ callType }})</span> <span class="voice-text">{{ $t('triage.voiceCallText', { number: currentCall.number, name: currentCall.name, room: currentCall.room, type: callTypeDisplay }) }}</span>
</div> </div>
</div> </div>
@@ -345,23 +345,23 @@
<template #header> <template #header>
<div class="config-dialog-header"> <div class="config-dialog-header">
<div class="config-dialog-title"> <div class="config-dialog-title">
智能分诊规则引擎配置 - 心内科 {{ $t('triage.ruleConfigTitle') }}
</div> </div>
<div class="config-topbar-actions"> <div class="config-topbar-actions">
<el-button <el-button
type="primary" type="primary"
@click="handleAddRule" @click="handleAddRule"
> >
新增规则 {{ $t('triage.addRule') }}
</el-button> </el-button>
<el-button <el-button
type="primary" type="primary"
@click="handleSaveAllRules" @click="handleSaveAllRules"
> >
保存全部 {{ $t('triage.saveAll') }}
</el-button> </el-button>
<el-button @click="handleTestRule"> <el-button @click="handleTestRule">
测试规则 {{ $t('triage.testRule') }}
</el-button> </el-button>
</div> </div>
</div> </div>
@@ -378,7 +378,7 @@
@click="handleSelectRule(idx)" @click="handleSelectRule(idx)"
> >
<div class="rule-title"> <div class="rule-title">
规则{{ idx + 1 }} {{ $t('triage.rule') }}{{ idx + 1 }}
</div> </div>
<div class="rule-sub"> <div class="rule-sub">
prio={{ item.priority }} prio={{ item.priority }}
@@ -391,13 +391,13 @@
size="small" size="small"
@click.stop="handleSelectRule(idx)" @click.stop="handleSelectRule(idx)"
> >
编辑 {{ $t('common.edit') }}
</el-button> </el-button>
<el-button <el-button
size="small" size="small"
@click.stop="handleDeleteRule(idx)" @click.stop="handleDeleteRule(idx)"
> >
删除 {{ $t('common.delete') }}
</el-button> </el-button>
<el-button <el-button
size="small" size="small"
@@ -424,43 +424,43 @@
class="config-form" class="config-form"
> >
<el-form-item <el-form-item
label="规则名称:" :label="$t('triage.ruleName') + ':'"
required required
> >
<el-input <el-input
v-model="ruleForm.name" v-model="ruleForm.name"
placeholder="请输入规则名称" :placeholder="$t('triage.placeholderRuleName')"
/> />
</el-form-item> </el-form-item>
<el-form-item label="科室:"> <el-form-item :label="$t('triage.department') + ':'">
<el-select <el-select
v-model="ruleForm.dept" v-model="ruleForm.dept"
class="config-fullwidth" class="config-fullwidth"
disabled disabled
> >
<el-option <el-option
label="心内科" :label="$t('triage.cardiology')"
value="心内科" value="心内科"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="规则描述:"> <el-form-item :label="$t('triage.ruleDesc') + ':'">
<el-input <el-input
v-model="ruleForm.desc" v-model="ruleForm.desc"
placeholder="请输入规则描述" :placeholder="$t('triage.placeholderRuleDesc')"
/> />
</el-form-item> </el-form-item>
<el-form-item <el-form-item
label="优先级:" :label="$t('triage.priority') + ':'"
required required
> >
<el-input v-model="ruleForm.priority" /> <el-input v-model="ruleForm.priority" />
</el-form-item> </el-form-item>
<el-form-item label="周几生效:"> <el-form-item :label="$t('triage.weekDayActive') + ':'">
<el-checkbox-group v-model="ruleForm.weeks"> <el-checkbox-group v-model="ruleForm.weeks">
<el-checkbox <el-checkbox
v-for="w in weekOptions" v-for="w in weekOptions"
@@ -472,7 +472,7 @@
</el-checkbox-group> </el-checkbox-group>
</el-form-item> </el-form-item>
<el-form-item label="条件表达式(JSON):"> <el-form-item :label="$t('triage.conditionExpr') + ':'">
<el-input <el-input
v-model="ruleForm.expr" v-model="ruleForm.expr"
type="textarea" type="textarea"
@@ -483,10 +483,10 @@
<div class="config-inline-actions"> <div class="config-inline-actions">
<el-button @click="handleQuickGenerate"> <el-button @click="handleQuickGenerate">
快速生成器 {{ $t('triage.quickGenerator') }}
</el-button> </el-button>
<el-button @click="handleValidateRule"> <el-button @click="handleValidateRule">
语法检查 {{ $t('triage.syntaxCheck') }}
</el-button> </el-button>
</div> </div>
</el-form> </el-form>
@@ -499,10 +499,10 @@
type="primary" type="primary"
@click="handleSaveCurrentRule" @click="handleSaveCurrentRule"
> >
保存 {{ $t('common.save') }}
</el-button> </el-button>
<el-button @click="configDialogVisible = false"> <el-button @click="configDialogVisible = false">
取消 {{ $t('common.cancel') }}
</el-button> </el-button>
</div> </div>
</template> </template>
@@ -511,7 +511,7 @@
<!-- 快速生成器对话框 --> <!-- 快速生成器对话框 -->
<el-dialog <el-dialog
v-model="quickGeneratorDialogVisible" v-model="quickGeneratorDialogVisible"
title="快速生成器" :title="$t('triage.quickGenerator')"
width="600px" width="600px"
:close-on-click-modal="false" :close-on-click-modal="false"
> >
@@ -519,7 +519,7 @@
:model="quickGeneratorForm" :model="quickGeneratorForm"
label-width="120px" label-width="120px"
> >
<el-form-item label="年龄条件:"> <el-form-item :label="$t('triage.ageCondition') + ':'">
<div style="display: flex; align-items: center; gap: 10px;"> <div style="display: flex; align-items: center; gap: 10px;">
<el-select <el-select
v-model="quickGeneratorForm.ageOperator" v-model="quickGeneratorForm.ageOperator"
@@ -551,94 +551,94 @@
:min="0" :min="0"
:max="150" :max="150"
:precision="0" :precision="0"
placeholder="年龄" :placeholder="$t('triage.age')"
style="width: 150px;" style="width: 150px;"
/> />
<el-button <el-button
type="link" type="link"
@click="quickGeneratorForm.ageOperator = null; quickGeneratorForm.ageValue = null" @click="quickGeneratorForm.ageOperator = null; quickGeneratorForm.ageValue = null"
> >
清除 {{ $t('triage.clear') }}
</el-button> </el-button>
</div> </div>
</el-form-item> </el-form-item>
<el-form-item label="号别/类型:"> <el-form-item :label="$t('triage.ticketTypeLabel') + ':'">
<el-select <el-select
v-model="quickGeneratorForm.regType" v-model="quickGeneratorForm.regType"
placeholder="请选择号别" :placeholder="$t('triage.placeholderSelectTicketType')"
clearable clearable
style="width: 100%" style="width: 100%"
> >
<el-option <el-option
label="专家" :label="$t('triage.expert')"
value="专家" value="专家"
/> />
<el-option <el-option
label="普通" :label="$t('triage.normal')"
value="普通" value="普通"
/> />
<el-option <el-option
label="特需" :label="$t('triage.specialNeeds')"
value="特需" value="特需"
/> />
<el-option <el-option
label="急诊" :label="$t('triage.emergency')"
value="急诊" value="急诊"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="科室:"> <el-form-item :label="$t('triage.department') + ':'">
<el-select <el-select
v-model="quickGeneratorForm.dept" v-model="quickGeneratorForm.dept"
placeholder="请选择科室" :placeholder="$t('triage.placeholderSelectDept')"
clearable clearable
style="width: 100%" style="width: 100%"
> >
<el-option <el-option
label="心内科" :label="$t('triage.cardiology')"
value="心内科" value="心内科"
/> />
<el-option <el-option
label="心外科" :label="$t('triage.cardiacSurgery')"
value="心外科" value="心外科"
/> />
<el-option <el-option
label="神经内科" :label="$t('triage.neurology')"
value="神经内科" value="神经内科"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="医生:"> <el-form-item :label="$t('triage.doctor') + ':'">
<el-input <el-input
v-model="quickGeneratorForm.doctor" v-model="quickGeneratorForm.doctor"
placeholder="请输入医生姓名(支持模糊匹配)" :placeholder="$t('triage.placeholderDoctor')"
clearable clearable
/> />
</el-form-item> </el-form-item>
<el-form-item label="自定义条件:"> <el-form-item :label="$t('triage.customCondition') + ':'">
<el-input <el-input
v-model="quickGeneratorForm.customKey" v-model="quickGeneratorForm.customKey"
placeholder="字段名gender" :placeholder="$t('triage.placeholderFieldName')"
style="width: 150px; margin-right: 10px;" style="width: 150px; margin-right: 10px;"
/> />
<el-input <el-input
v-model="quickGeneratorForm.customValue" v-model="quickGeneratorForm.customValue"
placeholder="字段值(如:男)" :placeholder="$t('triage.placeholderFieldValue')"
style="width: 200px;" style="width: 200px;"
/> />
<el-button <el-button
type="link" type="link"
@click="quickGeneratorForm.customKey = ''; quickGeneratorForm.customValue = ''" @click="quickGeneratorForm.customKey = ''; quickGeneratorForm.customValue = ''"
> >
清除 {{ $t('triage.clear') }}
</el-button> </el-button>
</el-form-item> </el-form-item>
<el-form-item label="预览JSON:"> <el-form-item :label="$t('triage.previewJson') + ':'">
<el-input <el-input
:value="previewJson" :value="previewJson"
type="textarea" type="textarea"
@@ -652,13 +652,13 @@
<template #footer> <template #footer>
<div style="text-align: right;"> <div style="text-align: right;">
<el-button @click="quickGeneratorDialogVisible = false"> <el-button @click="quickGeneratorDialogVisible = false">
取消 {{ $t('common.cancel') }}
</el-button> </el-button>
<el-button <el-button
type="primary" type="primary"
@click="handleApplyQuickGenerate" @click="handleApplyQuickGenerate"
> >
应用 {{ $t('triage.apply') }}
</el-button> </el-button>
</div> </div>
</template> </template>
@@ -668,8 +668,10 @@
<script setup> <script setup>
import { ref, reactive, computed, onMounted, onUnmounted } from 'vue' import { ref, reactive, computed, onMounted, onUnmounted } from 'vue'
import { useI18n } from 'vue-i18n'
import useUserStore from '@/store/modules/user' import useUserStore from '@/store/modules/user'
const { t } = useI18n()
const userStore = useUserStore() const userStore = useUserStore()
import { Refresh } from '@element-plus/icons-vue' import { Refresh } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
@@ -772,19 +774,47 @@ const quickGeneratorForm = reactive({
customKey: '', // 自定义字段名 customKey: '', // 自定义字段名
customValue: '' // 自定义字段值 customValue: '' // 自定义字段值
}) })
const weekOptions = [ const weekOptions = computed(() => [
{ label: '一', value: '1' }, { label: t('triage.weekMon'), value: '1' },
{ label: '二', value: '2' }, { label: t('triage.weekTue'), value: '2' },
{ label: '三', value: '3' }, { label: t('triage.weekWed'), value: '3' },
{ label: '四', value: '4' }, { label: t('triage.weekThu'), value: '4' },
{ label: '五', value: '5' }, { label: t('triage.weekFri'), value: '5' },
{ label: '六', value: '6' }, { label: t('triage.weekSat'), value: '6' },
{ label: '日', value: '0' } { label: t('triage.weekSun'), value: '0' }
] ])
// 叫号类型 // 叫号类型
const callType = ref('选呼') const callType = ref('选呼')
const callTypeDisplay = computed(() => {
const map = {
'选呼': t('triage.selectCall'),
'下一患者': t('triage.nextPatient'),
'跳过': t('triage.skip'),
'完成': t('triage.complete'),
'过号重排': t('triage.requeue'),
'刷新': t('common.refresh')
}
return map[callType.value] || callType.value
})
const translatedQueueList = computed(() => {
const statusMap = {
'等待': t('triage.statusWaiting'),
'叫号中': t('triage.statusCalling'),
'就诊中': t('triage.statusInConsultation'),
'已完成': t('triage.statusCompleted'),
'跳过': t('triage.statusSkipped'),
'已退费': t('triage.statusRefunded'),
'已随访': t('triage.statusFollowUp')
}
return filteredQueueList.value.map(item => ({
...item,
displayStatus: statusMap[item.status] || item.status
}))
})
const syncCurrentCallFromQueue = () => { const syncCurrentCallFromQueue = () => {
const calling = originalQueueList.value.find((i) => i.status === '叫号中') const calling = originalQueueList.value.find((i) => i.status === '叫号中')
if (!calling) { if (!calling) {
@@ -1059,7 +1089,7 @@ const loadDataFromApi = async () => {
// 同步当前呼叫(队列从 DB 加载后已同步;这里再兜底一次) // 同步当前呼叫(队列从 DB 加载后已同步;这里再兜底一次)
syncCurrentCallFromQueue() syncCurrentCallFromQueue()
console.log('【心内科】数据加载完成:候选池', originalCandidatePoolList.value.length, '条,队列', originalQueueList.value.length, '条') console.log('【心内科】数据加载完成:候选池', originalCandidatePoolList.value.length, '条,队列', originalQueueList.value.length, '条')
ElMessage.success(`${currentDeptName.value}】已从门诊挂号接口加载数据`) ElMessage.success(t('triage.msgDataLoaded'))
} catch (e) { } catch (e) {
console.error('【心内科】loadDataFromApi 执行异常:', e) console.error('【心内科】loadDataFromApi 执行异常:', e)
originalCandidatePoolList.value = [] originalCandidatePoolList.value = []
@@ -1147,7 +1177,7 @@ const handleCandidateSelectionChange = ({ records }) => {
// 加入队列(选中的候选池患者)——落库 // 加入队列(选中的候选池患者)——落库
const handleAddToQueue = async () => { const handleAddToQueue = async () => {
if (selectedCandidates.value.length === 0) { if (selectedCandidates.value.length === 0) {
ElMessage.warning('请先选择要加入队列的患者') ElMessage.warning(t('triage.msgSelectPatientToAdd'))
return return
} }
@@ -1236,11 +1266,11 @@ const handleAddToQueue = async () => {
console.log('【心内科】handleAddToQueue 完成:候选池从', beforeCount, '条减少到', afterCount, '条,成功加入', added, '位') console.log('【心内科】handleAddToQueue 完成:候选池从', beforeCount, '条减少到', afterCount, '条,成功加入', added, '位')
if (added > 0) { if (added > 0) {
ElMessage.success(`成功将 ${added} 位患者加入队列(已保存)`) ElMessage.success(t('triage.msgAddedToQueue', { count: added }))
} else if (addedEncounterIds.size > 0) { } else if (addedEncounterIds.size > 0) {
ElMessage.warning('所选患者已在队列中,已从候选池移除') ElMessage.warning(t('triage.msgAlreadyInQueue'))
} else { } else {
ElMessage.warning('加入队列失败,请重试') ElMessage.warning(t('triage.msgAddFailed'))
} }
} catch (e) { } catch (e) {
console.error('【心内科】handleAddToQueue 异常:', e) console.error('【心内科】handleAddToQueue 异常:', e)
@@ -1258,14 +1288,14 @@ const handleAddToQueue = async () => {
totalSignedIn.value = originalCandidatePoolList.value.length totalSignedIn.value = originalCandidatePoolList.value.length
selectedCandidates.value = [] selectedCandidates.value = []
} }
ElMessage.error('加入队列失败(未保存)') ElMessage.error(t('triage.msgAddFailedUnsaved'))
} }
} }
// 一键加入队列(所有候选池患者)——落库 // 一键加入队列(所有候选池患者)——落库
const handleAddAllToQueue = async () => { const handleAddAllToQueue = async () => {
if (filteredCandidatePoolList.value.length === 0) { if (filteredCandidatePoolList.value.length === 0) {
ElMessage.warning('候选池中没有患者') ElMessage.warning(t('triage.msgNoCandidates'))
return return
} }
@@ -1354,11 +1384,11 @@ const handleAddAllToQueue = async () => {
console.log('【心内科】handleAddAllToQueue 完成:候选池从', beforeCount, '条减少到', afterCount, '条,成功加入', added, '位') console.log('【心内科】handleAddAllToQueue 完成:候选池从', beforeCount, '条减少到', afterCount, '条,成功加入', added, '位')
if (added > 0) { if (added > 0) {
ElMessage.success(`成功将 ${added} 位患者加入队列(已保存)`) ElMessage.success(t('triage.msgAddedToQueue', { count: added }))
} else if (addedEncounterIds.size > 0) { } else if (addedEncounterIds.size > 0) {
ElMessage.warning('所有候选池患者已在队列中,已从候选池移除') ElMessage.warning(t('triage.msgAllAlreadyInQueue'))
} else { } else {
ElMessage.warning('一键加入失败,请重试') ElMessage.warning(t('triage.msgAddAllFailed'))
} }
} catch (e) { } catch (e) {
console.error('【心内科】handleAddAllToQueue 异常:', e) console.error('【心内科】handleAddAllToQueue 异常:', e)
@@ -1376,21 +1406,21 @@ const handleAddAllToQueue = async () => {
totalSignedIn.value = originalCandidatePoolList.value.length totalSignedIn.value = originalCandidatePoolList.value.length
selectedCandidates.value = [] selectedCandidates.value = []
} }
ElMessage.error('一键加入失败(未保存)') ElMessage.error(t('triage.msgAddAllFailedUnsaved'))
} }
} }
// 移出队列——落库 // 移出队列——落库
const handleRemoveFromQueue = async () => { const handleRemoveFromQueue = async () => {
if (!selectedQueueRow.value) { if (!selectedQueueRow.value) {
ElMessage.warning('请先选择要移出队列的患者') ElMessage.warning(t('triage.msgSelectPatientToRemove'))
return return
} }
try { try {
const row = selectedQueueRow.value const row = selectedQueueRow.value
if (!row.id) { if (!row.id) {
ElMessage.warning('该队列项缺少ID无法保存删除请先刷新页面') ElMessage.warning(t('triage.msgMissingIdRemove'))
return return
} }
@@ -1404,10 +1434,10 @@ const handleRemoveFromQueue = async () => {
await loadDataFromApi() await loadDataFromApi()
console.log('【心内科】移出队列完成,患者应已重新出现在候选池中') console.log('【心内科】移出队列完成,患者应已重新出现在候选池中')
ElMessage.success(`已将 ${patientName} 移出队列,患者已重新出现在候选池中(已保存)`) ElMessage.success(t('triage.msgRemovedFromQueue', { name: patientName }))
} catch (e) { } catch (e) {
console.error('【心内科】handleRemoveFromQueue 异常:', e) console.error('【心内科】handleRemoveFromQueue 异常:', e)
ElMessage.error('移出队列失败(未保存)') ElMessage.error(t('triage.msgRemoveFailed'))
} }
} }
@@ -1433,16 +1463,16 @@ const canMoveDown = computed(() => {
const handleMoveUp = async () => { const handleMoveUp = async () => {
if (!selectedQueueRow.value || !canMoveUp.value) return if (!selectedQueueRow.value || !canMoveUp.value) return
if (!selectedQueueRow.value.id) { if (!selectedQueueRow.value.id) {
ElMessage.warning('该队列项缺少ID无法保存排序请先刷新页面') ElMessage.warning(t('triage.msgMissingIdSort'))
return return
} }
try { try {
await adjustQueueOrder({ id: selectedQueueRow.value.id, direction: 'up' }) await adjustQueueOrder({ id: selectedQueueRow.value.id, direction: 'up' })
await loadDataFromApi() await loadDataFromApi()
ElMessage.success('队列顺序已调整(已保存)') ElMessage.success(t('triage.msgOrderAdjusted'))
} catch (e) { } catch (e) {
console.error('【心内科】handleMoveUp 异常:', e) console.error('【心内科】handleMoveUp 异常:', e)
ElMessage.error('队列顺序调整失败(未保存)') ElMessage.error(t('triage.msgOrderAdjustFailed'))
} }
} }
@@ -1450,16 +1480,16 @@ const handleMoveUp = async () => {
const handleMoveDown = async () => { const handleMoveDown = async () => {
if (!selectedQueueRow.value || !canMoveDown.value) return if (!selectedQueueRow.value || !canMoveDown.value) return
if (!selectedQueueRow.value.id) { if (!selectedQueueRow.value.id) {
ElMessage.warning('该队列项缺少ID无法保存排序请先刷新页面') ElMessage.warning(t('triage.msgMissingIdSort'))
return return
} }
try { try {
await adjustQueueOrder({ id: selectedQueueRow.value.id, direction: 'down' }) await adjustQueueOrder({ id: selectedQueueRow.value.id, direction: 'down' })
await loadDataFromApi() await loadDataFromApi()
ElMessage.success('队列顺序已调整(已保存)') ElMessage.success(t('triage.msgOrderAdjusted'))
} catch (e) { } catch (e) {
console.error('【心内科】handleMoveDown 异常:', e) console.error('【心内科】handleMoveDown 异常:', e)
ElMessage.error('队列顺序调整失败(未保存)') ElMessage.error(t('triage.msgOrderAdjustFailed'))
} }
} }
@@ -1533,19 +1563,19 @@ const handleRefresh = async () => {
stopWaitingTimer() stopWaitingTimer()
startWaitingTimer() startWaitingTimer()
ElMessage.success('已刷新(已从数据库恢复队列)') ElMessage.success(t('triage.msgRefreshed'))
} }
// 历史队列查询 // 历史队列查询
const handleHistoryQuery = async () => { const handleHistoryQuery = async () => {
if (!queryDate.value) { if (!queryDate.value) {
ElMessage.warning('请选择查询日期') ElMessage.warning(t('triage.msgSelectQueryDate'))
return return
} }
console.log('【心内科】历史队列查询:', queryDate.value) console.log('【心内科】历史队列查询:', queryDate.value)
await loadQueueFromDb(queryDate.value) await loadQueueFromDb(queryDate.value)
if (isQueryingHistory.value) { if (isQueryingHistory.value) {
ElMessage.success(`已加载 ${queryDate.value} 的队列数据`) ElMessage.success(t('triage.msgLoadedHistory', { date: queryDate.value }))
} }
} }
@@ -1553,12 +1583,12 @@ const handleHistoryQuery = async () => {
const handleTodayQuery = async () => { const handleTodayQuery = async () => {
queryDate.value = getTodayStr() queryDate.value = getTodayStr()
await loadQueueFromDb(getTodayStr()) await loadQueueFromDb(getTodayStr())
ElMessage.success('已切换到今天队列') ElMessage.success(t('triage.msgSwitchedToToday'))
} }
// 退出 // 退出
const handleExit = () => { const handleExit = () => {
ElMessage.info('退出功能待实现') ElMessage.info(t('triage.msgExitNotImpl'))
// TODO: 实现退出逻辑 // TODO: 实现退出逻辑
} }
@@ -1585,24 +1615,24 @@ const handleConfig = () => {
// 选呼——落库 // 选呼——落库
const handleSelectCall = async () => { const handleSelectCall = async () => {
if (!selectedQueueRow.value) { if (!selectedQueueRow.value) {
ElMessage.warning('请先在右侧队列中选择一个患者') ElMessage.warning(t('triage.msgSelectPatientInQueue'))
return return
} }
try { try {
callType.value = '选呼' callType.value = '选呼'
if (!selectedQueueRow.value.id) { if (!selectedQueueRow.value.id) {
ElMessage.warning('该队列项缺少ID无法保存选呼请先刷新页面') ElMessage.warning(t('triage.msgMissingIdSelectCall'))
return return
} }
// 检查患者状态,只有"等待"状态才能选呼 // 检查患者状态,只有"等待"状态才能选呼
if (selectedQueueRow.value.status !== '等待') { if (selectedQueueRow.value.status !== '等待') {
if (selectedQueueRow.value.status === '叫号中') { if (selectedQueueRow.value.status === '叫号中') {
ElMessage.info('该患者已经是"叫号中"状态') ElMessage.info(t('triage.msgAlreadyCalling'))
return return
} else { } else {
ElMessage.warning('只能选呼"等待"状态的患者,当前患者状态为:"' + selectedQueueRow.value.status + '"') ElMessage.warning(t('triage.msgCanOnlyCallWaiting', { status: selectedQueueRow.value.status }))
return return
} }
} }
@@ -1620,13 +1650,13 @@ const handleSelectCall = async () => {
// 统计当前"叫号中"的患者数量 // 统计当前"叫号中"的患者数量
const callingCount = originalQueueList.value.filter(i => i.status === '叫号中').length const callingCount = originalQueueList.value.filter(i => i.status === '叫号中').length
if (callingCount > 1) { if (callingCount > 1) {
ElMessage.success(`已选呼(已保存),当前共有 ${callingCount} 位患者处于"叫号中"状态`) ElMessage.success(t('triage.msgSelectCalledWithCount', { count: callingCount }))
} else { } else {
ElMessage.success('已选呼(已保存)') ElMessage.success(t('triage.msgSelectCalledSingle'))
} }
} catch (e) { } catch (e) {
console.error('【心内科】handleSelectCall 异常:', e) console.error('【心内科】handleSelectCall 异常:', e)
ElMessage.error('选呼失败(未保存)') ElMessage.error(t('triage.msgSelectCallFailed'))
} }
} }
@@ -1655,11 +1685,11 @@ const handleNextPatient = async () => {
await nextPatient(reqData) await nextPatient(reqData)
selectedQueueRow.value = null selectedQueueRow.value = null
await loadDataFromApi() await loadDataFromApi()
ElMessage.success('已呼叫下一位(已保存)') ElMessage.success(t('triage.msgNextCalled'))
} catch (e) { } catch (e) {
console.error('【心内科】handleNextPatient 异常:', e) console.error('【心内科】handleNextPatient 异常:', e)
// 从错误对象中提取错误消息 // 从错误对象中提取错误消息
const errorMsg = e?.message || e?.response?.data?.msg || '当前范围内没有"等待"的患者' const errorMsg = e?.message || e?.response?.data?.msg || t('triage.msgNoWaitingPatient')
ElMessage.warning(errorMsg) ElMessage.warning(errorMsg)
} }
} }
@@ -1685,11 +1715,11 @@ const handleSkip = async () => {
await skipPatient(reqData) await skipPatient(reqData)
selectedQueueRow.value = null selectedQueueRow.value = null
await loadDataFromApi() await loadDataFromApi()
ElMessage.success('已跳过(已保存)') ElMessage.success(t('triage.msgSkipped'))
} catch (e) { } catch (e) {
console.error('【心内科】handleSkip 异常:', e) console.error('【心内科】handleSkip 异常:', e)
// 从错误对象中提取错误消息 // 从错误对象中提取错误消息
const errorMsg = e?.message || e?.response?.data?.msg || '当前没有"叫号中"的患者' const errorMsg = e?.message || e?.response?.data?.msg || t('triage.msgNoCallingPatient')
ElMessage.warning(errorMsg) ElMessage.warning(errorMsg)
} }
} }
@@ -1715,11 +1745,11 @@ const handleComplete = async () => {
await completeCall(reqData) await completeCall(reqData)
selectedQueueRow.value = null selectedQueueRow.value = null
await loadDataFromApi() await loadDataFromApi()
ElMessage.success('已完成(已保存)') ElMessage.success(t('triage.msgCompleted'))
} catch (e) { } catch (e) {
console.error('【心内科】handleComplete 异常:', e) console.error('【心内科】handleComplete 异常:', e)
// 从错误对象中提取错误消息 // 从错误对象中提取错误消息
const errorMsg = e?.message || e?.response?.data?.msg || '当前没有"叫号中"的患者' const errorMsg = e?.message || e?.response?.data?.msg || t('triage.msgNoCallingPatient')
ElMessage.warning(errorMsg) ElMessage.warning(errorMsg)
} }
} }
@@ -1746,13 +1776,13 @@ const handleRequeue = async () => {
// 如果执行到这里,说明操作成功 // 如果执行到这里,说明操作成功
selectedQueueRow.value = null selectedQueueRow.value = null
await loadDataFromApi() await loadDataFromApi()
ElMessage.success('已过号重排(已保存)') ElMessage.success(t('triage.msgRequeued'))
} catch (e) { } catch (e) {
console.error('【心内科】handleRequeue 异常:', e) console.error('【心内科】handleRequeue 异常:', e)
// 从错误对象中提取错误消息 // 从错误对象中提取错误消息
// 注意:当后端返回 R.fail() 时code=500响应拦截器会 Promise.reject(new Error(msg)) // 注意:当后端返回 R.fail() 时code=500响应拦截器会 Promise.reject(new Error(msg))
// 所以错误消息在 e.message 中 // 所以错误消息在 e.message 中
const errorMsg = e?.message || e?.response?.data?.msg || '当前没有等待中的患者' const errorMsg = e?.message || e?.response?.data?.msg || t('triage.msgNoWaitingPatientRequeue')
ElMessage.warning(errorMsg) ElMessage.warning(errorMsg)
// 失败时不要刷新数据,避免显示错误的状态 // 失败时不要刷新数据,避免显示错误的状态
// await loadDataFromApi() // 注释掉,避免刷新数据 // await loadDataFromApi() // 注释掉,避免刷新数据
@@ -1768,11 +1798,11 @@ const handleSelectRule = (index) => {
// 后台配置:保存当前规则到列表 // 后台配置:保存当前规则到列表
const persistRuleForm = () => { const persistRuleForm = () => {
if (!ruleForm.name || !ruleForm.priority) { if (!ruleForm.name || !ruleForm.priority) {
ElMessage.warning('请填写规则名称和优先级') ElMessage.warning(t('triage.msgFillRuleNameAndPriority'))
return false return false
} }
if (!Array.isArray(ruleForm.weeks) || ruleForm.weeks.length === 0) { if (!Array.isArray(ruleForm.weeks) || ruleForm.weeks.length === 0) {
ElMessage.warning('请选择生效周几') ElMessage.warning(t('triage.msgSelectWeekDays'))
return false return false
} }
const parsed = tryParseExpr(ruleForm.expr) const parsed = tryParseExpr(ruleForm.expr)
@@ -1802,7 +1832,7 @@ const tryParseExpr = (expr) => {
JSON.parse(expr || '{}') JSON.parse(expr || '{}')
return true return true
} catch (e) { } catch (e) {
ElMessage.error('条件表达式 JSON 语法错误') ElMessage.error(t('triage.msgJsonSyntaxError'))
return null return null
} }
} }
@@ -1812,7 +1842,7 @@ const handleAddRule = () => {
const ok = persistRuleForm() const ok = persistRuleForm()
if (!ok) return if (!ok) return
const newRule = { const newRule = {
name: '新规则', name: t('triage.newRule'),
dept: '心内科', dept: '心内科',
desc: '', desc: '',
priority: rules.value.length * 10 + 10, priority: rules.value.length * 10 + 10,
@@ -1862,7 +1892,7 @@ const handleRuleMoveDown = (index) => {
const handleSaveCurrentRule = () => { const handleSaveCurrentRule = () => {
const ok = persistRuleForm() const ok = persistRuleForm()
if (ok) { if (ok) {
ElMessage.success('当前规则已保存') ElMessage.success(t('triage.msgRuleSaved'))
} }
} }
@@ -1871,14 +1901,14 @@ const handleSaveAllRules = () => {
const ok = persistRuleForm() const ok = persistRuleForm()
if (!ok) return if (!ok) return
// TODO: 调用后端保存接口 // TODO: 调用后端保存接口
ElMessage.success('全部规则已保存(前端模拟)') ElMessage.success(t('triage.msgAllRulesSaved'))
} }
// 后台配置:语法检查 // 后台配置:语法检查
const handleValidateRule = () => { const handleValidateRule = () => {
const ok = tryParseExpr(ruleForm.expr) const ok = tryParseExpr(ruleForm.expr)
if (ok) { if (ok) {
ElMessage.success('语法检查通过') ElMessage.success(t('triage.msgSyntaxCheckPassed'))
} }
} }
@@ -1978,7 +2008,7 @@ const handleApplyQuickGenerate = () => {
// 检查是否至少有一个条件 // 检查是否至少有一个条件
if (Object.keys(conditions).length === 0) { if (Object.keys(conditions).length === 0) {
ElMessage.warning('请至少设置一个条件') ElMessage.warning(t('triage.msgAtLeastOneCondition'))
return return
} }
@@ -1988,14 +2018,14 @@ const handleApplyQuickGenerate = () => {
// 关闭对话框 // 关闭对话框
quickGeneratorDialogVisible.value = false quickGeneratorDialogVisible.value = false
ElMessage.success('条件表达式已生成并应用') ElMessage.success(t('triage.msgConditionApplied'))
} }
// 后台配置:测试规则(占位) // 后台配置:测试规则(占位)
const handleTestRule = () => { const handleTestRule = () => {
const ok = tryParseExpr(ruleForm.expr) const ok = tryParseExpr(ruleForm.expr)
if (!ok) return if (!ok) return
ElMessage.info('测试规则功能待接入后端,当前为占位') ElMessage.info(t('triage.msgTestRulePlaceholder'))
} }
// 组件挂载 // 组件挂载