починил поле с форматированным текстом

This commit is contained in:
Андрей Дувакин 2025-06-01 17:16:00 +05:00
parent 1dbd83af2e
commit 6add3821c7
9 changed files with 603 additions and 584 deletions

View File

@ -65,7 +65,7 @@ async def create_appointment(
user=Depends(get_current_user), user=Depends(get_current_user),
): ):
appointment_service = AppointmentsService(db) appointment_service = AppointmentsService(db)
return await appointment_service.create_appointment(appointment) return await appointment_service.create_appointment(appointment, user.id)
@router.put( @router.put(

View File

@ -15,7 +15,7 @@ class AppointmentEntity(BaseModel):
appointment_datetime: datetime.datetime appointment_datetime: datetime.datetime
patient_id: int patient_id: int
doctor_id: int doctor_id: Optional[int] = None
type_id: int type_id: int
patient: Optional[PatientEntity] = None patient: Optional[PatientEntity] = None

View File

@ -62,7 +62,7 @@ class AppointmentsService:
for appointment in appointments for appointment in appointments
] ]
async def create_appointment(self, appointment: AppointmentEntity) -> Optional[AppointmentEntity]: async def create_appointment(self, appointment: AppointmentEntity, doctor_id: int) -> Optional[AppointmentEntity]:
patient = await self.patients_repository.get_by_id(appointment.patient_id) patient = await self.patients_repository.get_by_id(appointment.patient_id)
if not patient: if not patient:
@ -71,7 +71,7 @@ class AppointmentsService:
detail='The patient with this ID was not found', detail='The patient with this ID was not found',
) )
doctor = await self.users_repository.get_by_id(appointment.doctor_id) doctor = await self.users_repository.get_by_id(doctor_id)
if not doctor: if not doctor:
raise HTTPException( raise HTTPException(
@ -79,6 +79,8 @@ class AppointmentsService:
detail='The doctor/user with this ID was not found', detail='The doctor/user with this ID was not found',
) )
appointment.doctor_id = doctor_id
appointment_type = await self.appointment_types_repository.get_by_id(appointment.type_id) appointment_type = await self.appointment_types_repository.get_by_id(appointment.type_id)
if not appointment_type: if not appointment_type:

1120
web-app/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -19,10 +19,10 @@
"antd-mask-input": "^2.0.7", "antd-mask-input": "^2.0.7",
"axios": "^1.7.9", "axios": "^1.7.9",
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"jodit-react": "^5.2.19",
"prop-types": "^15.8.1", "prop-types": "^15.8.1",
"react": "^18.3.1", "react": "^18.3.1",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
"react-quill": "^2.0.0",
"react-redux": "^9.2.0", "react-redux": "^9.2.0",
"react-router-dom": "^7.1.1", "react-router-dom": "^7.1.1",
"validator": "^13.12.0" "validator": "^13.12.0"

View File

@ -1,9 +1,2 @@
import {StrictMode} from 'react' import {ComponentPreviews, useInitial} from "../dev/index.js";
import {createRoot} from 'react-dom/client' import {DevSupport} from "@react-buddy/ide-toolbox";
import App from './App.jsx'
createRoot(document.getElementById('root')).render(
<StrictMode>
<App/>
</StrictMode>
)

View File

@ -1,5 +1,5 @@
import ReactQuill from 'react-quill'; import JoditEditor from 'jodit-react';
import 'react-quill/dist/quill.snow.css'; import {useRef} from 'react';
import dayjs from "dayjs"; import dayjs from "dayjs";
import { import {
Button, Button,
@ -31,6 +31,9 @@ const AppointmentFormModal = ({onCancel}) => {
appointmentFormModalData.patients, appointmentFormModalData.patients,
); );
const editor = useRef(null);
const patientsItems = appointmentFormModalUI.filteredPatients.map((patient) => ({ const patientsItems = appointmentFormModalUI.filteredPatients.map((patient) => ({
key: patient.id, key: patient.id,
label: `${patient.last_name} ${patient.first_name} (${appointmentFormModalUI.getDateString(patient.birthday)})`, label: `${patient.last_name} ${patient.first_name} (${appointmentFormModalUI.getDateString(patient.birthday)})`,
@ -119,7 +122,8 @@ const AppointmentFormModal = ({onCancel}) => {
label="Время приема" label="Время приема"
rules={[{required: true, message: 'Выберите время'}]} rules={[{required: true, message: 'Выберите время'}]}
> >
<DatePicker maxDate={dayjs(new Date()).add(1, 'day')} defaultValue={dayjs(new Date())} showTime format="DD.MM.YYYY HH:mm" style={{width: '100%'}}/> <DatePicker maxDate={dayjs(new Date()).add(1, 'day')} showTime format="DD.MM.YYYY HH:mm"
style={{width: '100%'}}/>
</Form.Item> </Form.Item>
<Form.Item <Form.Item
name="days_until_the_next_appointment" name="days_until_the_next_appointment"
@ -132,8 +136,17 @@ const AppointmentFormModal = ({onCancel}) => {
name="results" name="results"
label="Результаты приема" label="Результаты приема"
> >
<ReactQuill theme="snow" style={{height: 150, marginBottom: 40}}/> <JoditEditor
ref={editor}
value={appointmentFormModalUI.results}
config={{
readonly: false,
height: 150,
}}
onBlur={appointmentFormModalUI.handleResultsChange}
/>
</Form.Item> </Form.Item>
</Form> </Form>
); );
}, [ }, [

View File

@ -19,6 +19,7 @@ const useAppointmentFormModalUI = (onCancel, createAppointment, updateAppointmen
const [appointmentDate, setAppointmentDate] = useState(dayjs(new Date())); const [appointmentDate, setAppointmentDate] = useState(dayjs(new Date()));
const [searchPatientString, setSearchPatientString] = useState(""); const [searchPatientString, setSearchPatientString] = useState("");
const [formValues, setFormValues] = useState({}); const [formValues, setFormValues] = useState({});
const [results, setResults] = useState('');
const {data: appointments = []} = useGetAppointmentsQuery(undefined, { const {data: appointments = []} = useGetAppointmentsQuery(undefined, {
pollingInterval: 20000, pollingInterval: 20000,
@ -54,20 +55,28 @@ const useAppointmentFormModalUI = (onCancel, createAppointment, updateAppointmen
if (selectedAppointment) { if (selectedAppointment) {
const patient = appointments.find(p => p.id === selectedAppointment.patient_id); const patient = appointments.find(p => p.id === selectedAppointment.patient_id);
setSelectedPatient(patient); setSelectedPatient(patient);
setCurrentStep(1); // При редактировании начинаем со второго шага setCurrentStep(1);
form.setFieldsValue({ form.setFieldsValue({
patient_id: selectedAppointment.patient_id, patient_id: selectedAppointment.patient_id,
type_id: selectedAppointment.type_id, type_id: selectedAppointment.type_id,
appointment_datetime: selectedAppointment.appointment_datetime appointment_datetime: selectedAppointment.appointment_datetime
? dayjs(selectedAppointment.appointment_datetime) ? dayjs(selectedAppointment.appointment_datetime)
: null, : dayjs(new Date()),
days_until_the_next_appointment: selectedAppointment.days_until_the_next_appointment, days_until_the_next_appointment: selectedAppointment.days_until_the_next_appointment,
results: selectedAppointment.results, results: selectedAppointment.results,
}); });
} else {
form.setFieldsValue({
appointment_datetime: dayjs(new Date()),
})
} }
} }
}, [modalVisible, selectedAppointment, form, appointments]); }, [modalVisible, selectedAppointment, form, appointments]);
const handleResultsChange = (newContent) => {
setResults(newContent);
};
const handleSetSearchPatientString = (e) => { const handleSetSearchPatientString = (e) => {
setSearchPatientString(e.target.value); setSearchPatientString(e.target.value);
}; };
@ -105,7 +114,7 @@ const useAppointmentFormModalUI = (onCancel, createAppointment, updateAppointmen
const values = await form.validateFields(); const values = await form.validateFields();
setFormValues(values); setFormValues(values);
setCurrentStep(2); setCurrentStep(2);
} catch (error) { } catch (_) {
notification.error({ notification.error({
message: 'Ошибка валидации', message: 'Ошибка валидации',
description: 'Пожалуйста, заполните все обязательные поля.', description: 'Пожалуйста, заполните все обязательные поля.',
@ -147,7 +156,7 @@ const useAppointmentFormModalUI = (onCancel, createAppointment, updateAppointmen
type_id: values.type_id, type_id: values.type_id,
appointment_datetime: appointmentTime.format("YYYY-MM-DD HH:mm:ss"), appointment_datetime: appointmentTime.format("YYYY-MM-DD HH:mm:ss"),
days_until_the_next_appointment: values.days_until_the_next_appointment, days_until_the_next_appointment: values.days_until_the_next_appointment,
results: values.results, results: results,
}; };
if (selectedAppointment) { if (selectedAppointment) {
@ -201,6 +210,8 @@ const useAppointmentFormModalUI = (onCancel, createAppointment, updateAppointmen
currentStep, currentStep,
searchPatientString, searchPatientString,
appointmentDate, appointmentDate,
results,
setResults,
handleSetSearchPatientString, handleSetSearchPatientString,
filteredPatients, filteredPatients,
handleOk, handleOk,
@ -211,6 +222,7 @@ const useAppointmentFormModalUI = (onCancel, createAppointment, updateAppointmen
handleClickNextButton, handleClickNextButton,
handleClickBackButton, handleClickBackButton,
handleSetAppointmentDate, handleSetAppointmentDate,
handleResultsChange,
modalWidth, modalWidth,
disableBackButton, disableBackButton,
disableNextButton, disableNextButton,

View File

@ -7,4 +7,7 @@ export default defineConfig({
outDir: '../dist', outDir: '../dist',
}, },
publicDir: 'public', publicDir: 'public',
optimizeDeps: {
include: ['jodit-react']
}
}) })