ExamSampleEditModal.tsx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. import ExamPlanController from "@/services/apis/ExamPlanController";
  2. import ExamSampleController from "@/services/apis/ExamSampleController";
  3. import { DrawerForm, ProFormCheckbox, ProFormDependency, ProFormDigit, ProFormItem, ProFormRadio, ProFormSelect, ProFormText, ProFormTextArea } from "@ant-design/pro-components";
  4. import { useRequest } from "ahooks";
  5. import { App, Space, Typography } from "antd";
  6. import { useState } from "react";
  7. /** 添加修改抽样方案 */
  8. const ExamSampleEditModal: React.FC<{
  9. /** 抽样方案 */
  10. data: Partial<API.ExamSampleOutput>;
  11. /** 保存成功回调 */
  12. onFinish: () => void;
  13. /** 关闭回调 */
  14. onClose: () => void;
  15. }> = ({ data, onFinish, onClose }) => {
  16. const [open, setOpen] = useState<boolean>(true);
  17. const handleClose = () => { setOpen(false); setTimeout(onClose, 300); };
  18. const { message } = App.useApp();
  19. const [isEnabledOnlyOneClassStudentMin, setIsEnabledOnlyOneClassStudentMin] = useState(data.config?.isEnabledOnlyOneClassStudentMin);
  20. const [isEnabledGradeNoSampleStudentMin, setIsEnabledGradeNoSampleStudentMin] = useState(data.config?.isEnabledGradeNoSampleStudentMin);
  21. const [isEnabledClassStudentMin, setIsEnabledClassStudentMin] = useState(data.config?.isEnabledClassStudentMin);
  22. const { data: refPlanList } = useRequest(async () => { return await ExamPlanController.getSampleRefPlanList({ id: data.examPlanId }) });
  23. const { config, ...restData } = data;
  24. return (
  25. <DrawerForm<API.ExamSampleOutput>
  26. title="监测抽样方案参数配置"
  27. width={800}
  28. open={open}
  29. drawerProps={{
  30. maskClosable: false,
  31. onClose: handleClose,
  32. }}
  33. initialValues={{
  34. config: {
  35. percent: 40,
  36. startPosition: 1,
  37. interval: 2,
  38. isRandomSampling: false,
  39. isExcludeSpecialStudent: true,
  40. specialStudentMustApproved: true,
  41. ...config,
  42. },
  43. ...restData
  44. }}
  45. onFinish={async (values) => {
  46. try {
  47. const { config, ...restValues } = values;
  48. let p: API.AddExamSampleInput = {
  49. ...restValues,
  50. examPlanId: data.examPlanId ?? 0,
  51. config: {
  52. ...data.config,
  53. ...config,
  54. },
  55. };
  56. if ((data.id ?? 0) > 0) {
  57. const up = { id: data.id ?? 0, ...p } as API.UpdateExamSampleInput;
  58. await ExamSampleController.update(up);
  59. }
  60. else {
  61. await ExamSampleController.add(p);
  62. }
  63. message.success('操作成功!');
  64. onFinish();
  65. handleClose();
  66. return true;
  67. } catch {
  68. message.error('操作失败!');
  69. return false;
  70. }
  71. }}
  72. >
  73. {(data.id ?? 0) > 0 &&
  74. <>
  75. <ProFormText
  76. label={<strong>方案全称</strong>}
  77. name="fullName"
  78. required
  79. rules={[{ required: true, message: '请输入方案全称' }]}
  80. />
  81. <ProFormText
  82. label={<strong>方案名称</strong>}
  83. name="name"
  84. required
  85. rules={[{ required: true, message: '请输入方案名称' }]}
  86. />
  87. <ProFormText
  88. label={<strong>方案简称</strong>}
  89. name="shortName"
  90. required
  91. rules={[{ required: true, message: '请输入方案简称' }]}
  92. />
  93. </>
  94. }
  95. <ProFormSelect
  96. label={<strong>抽样参照成绩所在监测计划</strong>}
  97. name="examScoreRefExamPlanId"
  98. rules={[{ required: true, message: '请选择' }]}
  99. fieldProps={{
  100. options: refPlanList?.map(t => ({ label: t.name, value: t.id })) ?? [],
  101. }}
  102. />
  103. <ProFormDigit
  104. label={<strong>抽样比例</strong>}
  105. name={['config', 'percent']}
  106. fieldProps={{ addonAfter: '%' }}
  107. rules={[{ required: true, message: '请输入抽样比例' }]}
  108. />
  109. <ProFormRadio.Group
  110. label={<strong>抽样方式</strong>}
  111. name={['config', 'isRandomSampling']}
  112. fieldProps={{
  113. options: [
  114. { label: '随机抽样', value: true },
  115. { label: <Typography.Text>等距抽样<Typography.Text type="secondary">(班级无成绩时将采用随机抽样)</Typography.Text></Typography.Text>, value: false }
  116. ],
  117. }}
  118. rules={[{ required: true, message: '请选择抽样方式' }]}
  119. />
  120. <ProFormItem label={<strong>位置间距</strong>} required>
  121. <Space size="large">
  122. <div>
  123. <label>开始抽样位置:</label>
  124. <ProFormDigit
  125. name={['config', 'startPosition']}
  126. noStyle
  127. width={96}
  128. fieldProps={{ min: 1, max: 50 }}
  129. // help={false}
  130. rules={[{ required: true, message: '请输入开始抽样位置' }]}
  131. />
  132. </div>
  133. <div>
  134. <label>抽样间距:</label>
  135. <ProFormDigit
  136. name={['config', 'interval']}
  137. noStyle
  138. width={96}
  139. fieldProps={{ min: 1, max: 50 }}
  140. // help={false}
  141. rules={[{ required: true, message: '请输入抽样间距' }]}
  142. />
  143. </div>
  144. </Space>
  145. </ProFormItem>
  146. <ProFormItem label={<strong>全抽配置</strong>} tooltip="以下全抽规则序号越小优先级越高">
  147. <Space direction="vertical">
  148. <div>
  149. <ProFormCheckbox
  150. name={['config', 'isEnabledOnlyOneClassStudentMin']}
  151. noStyle
  152. fieldProps={{
  153. onChange: (e) => setIsEnabledOnlyOneClassStudentMin(e.target.checked),
  154. }}
  155. >1. 年级仅有一个班,且该班学生人数小于等于</ProFormCheckbox>
  156. <Space>
  157. <ProFormDigit
  158. name={['config', 'onlyOneClassStudentMin']}
  159. noStyle
  160. width={96}
  161. fieldProps={{ min: 10, max: 100 }}
  162. disabled={!isEnabledOnlyOneClassStudentMin}
  163. help={false}
  164. rules={[{ required: isEnabledOnlyOneClassStudentMin }]}
  165. />
  166. <label>人,则该班学生全抽</label>
  167. </Space>
  168. </div>
  169. <div>
  170. <ProFormCheckbox
  171. name={['config', 'isEnabledGradeNoSampleStudentMin']}
  172. noStyle
  173. fieldProps={{
  174. onChange: (e) => setIsEnabledGradeNoSampleStudentMin(e.target.checked),
  175. }}
  176. >2. 年级多于一个班,且年级未抽样部分学生人数小于</ProFormCheckbox>
  177. <Space>
  178. <ProFormDigit
  179. name={['config', 'gradeNoSampleStudentMin']}
  180. noStyle
  181. width={96}
  182. fieldProps={{ min: 10, max: 100 }}
  183. disabled={!isEnabledGradeNoSampleStudentMin}
  184. help={false}
  185. rules={[{ required: isEnabledGradeNoSampleStudentMin }]}
  186. />
  187. <label>人,则该年级所有学生全抽</label>
  188. </Space>
  189. </div>
  190. <div>
  191. <ProFormCheckbox
  192. name={['config', 'isEnabledClassStudentMin']}
  193. noStyle
  194. fieldProps={{
  195. onChange: (e) => setIsEnabledClassStudentMin(e.target.checked),
  196. }}
  197. >3. 班级学生人数小于等于</ProFormCheckbox>
  198. <Space>
  199. <ProFormDigit
  200. name={['config', 'classStudentMin']}
  201. noStyle
  202. width={96}
  203. fieldProps={{ min: 10, max: 100 }}
  204. disabled={!isEnabledClassStudentMin}
  205. help={false}
  206. rules={[{ required: isEnabledClassStudentMin }]}
  207. />
  208. <label>人,则该班学生全抽</label>
  209. </Space>
  210. </div>
  211. </Space>
  212. </ProFormItem>
  213. <ProFormItem label={<strong>特殊学生</strong>}>
  214. <Space>
  215. <ProFormCheckbox name={['config', 'isExcludeSpecialStudent']} noStyle>
  216. 不参与抽样
  217. </ProFormCheckbox>
  218. <ProFormDependency name={[['config', 'isExcludeSpecialStudent'], ['config', 'specialStudentMustApproved']]}>
  219. {({ config }) => (
  220. <ProFormCheckbox
  221. name={['config', 'specialStudentMustApproved']}
  222. noStyle
  223. disabled={!config?.isExcludeSpecialStudent}
  224. >必须审核通过{config?.specialStudentMustApproved ? '(勾选仅审核已通过不参与抽样)' : '(未勾选待审核和审核已通过均不参与抽样)'}</ProFormCheckbox>
  225. )}
  226. </ProFormDependency>
  227. </Space>
  228. </ProFormItem>
  229. <ProFormItem label={<strong>排序设置</strong>}>
  230. <ProFormCheckbox name={['config', 'isGradeSeatNumberRandom']} noStyle>
  231. 监测顺序号在年级内随机打乱
  232. <Typography.Text type="secondary">(默认在班内按前期成绩排序)</Typography.Text>
  233. </ProFormCheckbox>
  234. </ProFormItem>
  235. <ProFormTextArea
  236. label={<strong>备注说明</strong>}
  237. name="remark"
  238. />
  239. </DrawerForm>
  240. );
  241. }
  242. export default ExamSampleEditModal;