You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

380 lines
13 KiB

2 months ago
4 months ago
5 months ago
4 months ago
4 months ago
4 months ago
4 months ago
2 months ago
2 months ago
2 months ago
2 months ago
4 months ago
4 months ago
2 months ago
4 months ago
4 months ago
2 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
2 months ago
4 months ago
2 months ago
4 months ago
2 months ago
4 months ago
4 months ago
4 months ago
4 months ago
5 months ago
4 months ago
4 months ago
4 months ago
  1. import {Mask, NavBar, Picker, SpinLoading, Toast} from 'antd-mobile';
  2. import { useNavigate } from 'react-router';
  3. import icon_arr_r from '../assets/icon_arr_s_r.svg';
  4. import {ChangeEvent, useCallback, useEffect, useState} from 'react';
  5. import { useAppDispatch, useAppSelector } from '../utils/hooks';
  6. import { DATA_SOURCE, LINE_CLASSIFY, UNIT_TYPES, XB_CODES } from '../utils/constant';
  7. import { ExtraDesc, MeasurementDTO } from '../services/apiTypes';
  8. import Bridge from '../utils/bridge';
  9. import { resetState } from '../store/features/measureSlice';
  10. import { selectOrgTextArr } from '../store';
  11. export default function MeasureSave() {
  12. const navigate = useNavigate();
  13. const dispatch = useAppDispatch();
  14. const back = () => navigate(-1);
  15. const contextState = useAppSelector((state) => state.context);
  16. const baseState = useAppSelector((state) => state.baseData);
  17. const measureState = useAppSelector((state) => state.measure);
  18. const orgTextArr = useAppSelector(selectOrgTextArr);
  19. const loadData = useCallback(() => {
  20. Bridge.getRecordList({ pageNum: 1, size: 1 }).then((res) => {
  21. if (res.success && res.data.list.length) {
  22. const data = res.data.list[0]?.records?.[0]
  23. console.log(data)
  24. setName(data?.name)
  25. setBatch(data?.batch)
  26. setMile(data?.mileage?.split('+')?.[0])
  27. setMeter(data?.mileage?.split('+')?.[1])
  28. setLineClassCode([data?.lineClassify])
  29. setDataSourceCode([data?.dataSource])
  30. setDirectionCode([data?.xbCode])
  31. setUnitType([data?.unitType])
  32. setTurnoutNum(Number(data?.turnoutNum || 1))
  33. setSleeperNum(Number(data?.sleeperNum || 1))
  34. setStationCode([data?.stationCode])
  35. document.getElementById('name-id')?.focus()
  36. }
  37. });
  38. }, []);
  39. useEffect(() => {
  40. loadData();
  41. }, [loadData]);
  42. const [name, setName] = useState('');
  43. const [batch, setBatch] = useState('');
  44. const [mile, setMile] = useState('10');
  45. const [meter, setMeter] = useState('10');
  46. const [turnoutNum, setTurnoutNum] = useState(1);
  47. const [sleeperNum, setSleeperNum] = useState(1);
  48. const [railPickerVisible, setRailPickerVisible] = useState(false);
  49. const [dataSourcePickerVisible, setDataSourcePickerVisible] = useState(false);
  50. const [lineClassPickerVisible, setLineClassPickerVisible] = useState(false);
  51. const [unitTypePickerVisible, setUnitTypePickerVisible] = useState(false);
  52. const [stationPickerVisible, setStationPickerVisible] = useState(false);
  53. const [directionCode, setDirectionCode] = useState<string[]>([XB_CODES[0].value]);
  54. const [dataSourceCode, setDataSourceCode] = useState<string[]>([DATA_SOURCE[0].value]);
  55. const [lineClassCode, setLineClassCode] = useState<string[]>([LINE_CLASSIFY[0].value]);
  56. const [stationCode, setStationCode] = useState<string[]>(
  57. contextState.stationList.length > 0 ? [contextState.stationList[0].value] : []
  58. );
  59. const [unitType, setUnitType] = useState<string[]>([UNIT_TYPES[0].value]);
  60. const onInputChange = (evt: ChangeEvent<HTMLInputElement>) => {
  61. if (evt.target.name === 'name') {
  62. if (evt.target.value.length <= 50) {
  63. setName(evt.target.value);
  64. }else {
  65. Toast.show('名称长度不能超过50个字符');
  66. }
  67. } else if (evt.target.name === 'batch') {
  68. if (evt.target.value.length <= 10) {
  69. setBatch(evt.target.value);
  70. }
  71. else {
  72. Toast.show('批次长度不能超过10个字符');
  73. }
  74. } else if (evt.target.name === 'mile') {
  75. const val = evt.target.value.replace(/^0+/, '')
  76. if (/^\d*$/.test(val)) {
  77. setMile(val || '');
  78. }
  79. } else if (evt.target.name === 'meter') {
  80. const val = evt.target.value.replace(/^0+/, '')
  81. if (/^\d*$/.test(val)) {
  82. setMeter(val || '');
  83. }
  84. } else if (evt.target.name === 'turnoutNum') {
  85. if (/^\d*$/.test(evt.target.value)) {
  86. setTurnoutNum(+evt.target.value);
  87. }
  88. } else if (evt.target.name === 'sleeperNum') {
  89. if (/^\d*$/.test(evt.target.value)) {
  90. setSleeperNum(+evt.target.value);
  91. }
  92. }
  93. };
  94. const [measureData, setMeasureData] = useState(measureState.measureData)
  95. useEffect(()=>{
  96. setMeasureData(measureState.measureData)
  97. },[measureState.measureData])
  98. const [loading, setLoading] = useState(false);
  99. const onSaveBtnClick = () => {
  100. if (!name) {
  101. return Toast.show('请输入测量名称');
  102. }
  103. if (!batch) {
  104. return Toast.show('请输入批次号');
  105. }
  106. setLoading(true)
  107. const railType = baseState.railTypes.find((r) => r.id === contextState.currRailTypeId);
  108. const [tlj, gwd, xm] = orgTextArr;
  109. const desc: ExtraDesc = {
  110. railSize: railType!.name,
  111. tljCode: tlj,
  112. gwdCode: gwd,
  113. xmCode: xm,
  114. xbCode: XB_CODES.find((x) => x.value === directionCode[0])!.label,
  115. stationCode:
  116. stationCode.length > 0
  117. ? contextState.stationList.find((s) => s.value === stationCode[0])!.label
  118. : '',
  119. lineClassify: LINE_CLASSIFY.find((l) => l.value === lineClassCode[0])!.label,
  120. dataSource: DATA_SOURCE.find((d) => d.value === dataSourceCode[0])!.label,
  121. unitType: UNIT_TYPES.find((u) => u.value === unitType[0])!.label,
  122. mile: +mile,
  123. meter: +meter,
  124. };
  125. const dto: MeasurementDTO = {
  126. operator: 'klj_test',
  127. dataType: 'MINIPROF',
  128. name,
  129. batch,
  130. railSize: railType!.code,
  131. tljCode: contextState.currOrgCode,
  132. gwdCode: contextState.currGWDCode,
  133. xmCode: contextState.currXMCode,
  134. xbCode: directionCode[0],
  135. stationCode: stationCode.length > 0 ? stationCode[0] : '',
  136. lineClassify: lineClassCode[0],
  137. dataSource: dataSourceCode[0],
  138. turnoutNum: turnoutNum?.toFixed(),
  139. sleeperNum: sleeperNum?.toFixed(),
  140. unitType: unitType[0],
  141. mileage: `${mile}+${meter.padStart(3, '0')}`,
  142. radius: '',
  143. extraDesc: JSON.stringify(desc),
  144. alignPoints:[]
  145. };
  146. if(measureData && measureData.length){
  147. dto.alignPoints = measureData
  148. }
  149. Bridge.saveMeasure(dto).then((res) => {
  150. if (res.success) {
  151. Toast.show('保存成功');
  152. setTimeout(() => {
  153. navigate('/home/measure');
  154. dispatch(resetState());
  155. }, 300);
  156. } else {
  157. Toast.show(res.message);
  158. }
  159. }).catch(e=>{
  160. Toast.show({
  161. content: '操作失败',
  162. });
  163. }).finally(() => {
  164. setLoading(false)
  165. });
  166. };
  167. return (
  168. <>
  169. <div>
  170. {loading && (
  171. <Mask opacity='thick' className="h-[100vh] flex justify-center items-center">
  172. <div style={{ margin: '45%', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center' }}>
  173. <SpinLoading color="#5c92b4" />
  174. <span className="whitespace-nowrap mt-5 text-[#5c92b4]" style={{fontSize: '16px'}}>...</span>
  175. </div>
  176. </Mask>
  177. )}
  178. <NavBar className="bg-white" onBack={back}>
  179. </NavBar>
  180. <div className="main-page-content overflow-x-hidden overflow-y-auto">
  181. <div className="bg-white px-5 text-sm text-text mt-2">
  182. <div className="h-12 flex items-center border-b border-[#eee]">
  183. <span></span>
  184. <input
  185. id='name-id'
  186. type="text"
  187. name="name"
  188. value={name}
  189. placeholder="请填写测量名称"
  190. className="border-0 outline-none self-stretch text-right flex-1 ml-4"
  191. onChange={onInputChange}
  192. />
  193. </div>
  194. <div className="h-12 flex items-center border-b border-[#eee]">
  195. <span></span>
  196. <input
  197. type="text"
  198. name="batch"
  199. value={batch}
  200. placeholder="请填写批次"
  201. className="border-0 outline-none self-stretch text-right flex-1 ml-4"
  202. onChange={onInputChange}
  203. />
  204. </div>
  205. <div
  206. className="h-12 flex items-center border-b border-[#eee]"
  207. onClick={() => setDataSourcePickerVisible(true)}
  208. >
  209. <span></span>
  210. <span className="ml-auto mr-4">
  211. {DATA_SOURCE.find((r) => r.value === dataSourceCode[0])?.label || ''}
  212. </span>
  213. <img src={icon_arr_r} alt="arr" />
  214. </div>
  215. {dataSourceCode[0] === 'DCDC' ? (
  216. <>
  217. <div className="h-12 flex items-center border-b border-[#eee]">
  218. <span></span>
  219. <input
  220. type="number"
  221. name="turnoutNum"
  222. value={turnoutNum}
  223. className="border-0 outline-none self-stretch text-right flex-1 ml-4"
  224. onChange={onInputChange}
  225. />
  226. </div>
  227. <div className="h-12 flex items-center border-b border-[#eee]">
  228. <span></span>
  229. <input
  230. type="number"
  231. name="sleeperNum"
  232. value={sleeperNum}
  233. className="border-0 outline-none self-stretch text-right flex-1 ml-4"
  234. onChange={onInputChange}
  235. />
  236. </div>
  237. <div
  238. className="h-12 flex items-center border-b border-[#eee]"
  239. onClick={() => {
  240. if (contextState.stationList.length > 0) {
  241. setStationPickerVisible(true);
  242. }
  243. }}
  244. >
  245. <span></span>
  246. <span className="ml-auto mr-4">
  247. {contextState.stationList.find((r) => r.value === stationCode[0])?.label || ''}
  248. </span>
  249. <img src={icon_arr_r} alt="arr" />
  250. </div>
  251. </>
  252. ) : (
  253. <div className="h-12 flex items-center border-b border-[#eee]">
  254. <span></span>
  255. <input
  256. type="number"
  257. name="mile"
  258. value={mile}
  259. className="w-14 h-8 mx-1 border border-[#eee] rounded outline-none text-center ml-auto"
  260. onChange={onInputChange}
  261. />
  262. <span>+</span>
  263. <input
  264. type="number"
  265. name="meter"
  266. value={meter}
  267. className="w-14 h-8 mx-1 border border-[#eee] rounded outline-none text-center"
  268. onChange={onInputChange}
  269. />
  270. <span></span>
  271. </div>
  272. )}
  273. <div
  274. className="h-12 flex items-center border-b border-[#eee]"
  275. onClick={() => setLineClassPickerVisible(true)}
  276. >
  277. <span>线</span>
  278. <span className="ml-auto mr-4">
  279. {LINE_CLASSIFY.find((r) => r.value === lineClassCode[0])?.label || ''}
  280. </span>
  281. <img src={icon_arr_r} alt="arr" />
  282. </div>
  283. <div
  284. className="h-12 flex items-center border-b border-[#eee]"
  285. onClick={() => setRailPickerVisible(true)}
  286. >
  287. <span></span>
  288. <span className="ml-auto mr-4">
  289. {XB_CODES.find((r) => r.value === directionCode[0])?.label || ''}
  290. </span>
  291. <img src={icon_arr_r} alt="arr" />
  292. </div>
  293. <div className="h-12 flex items-center " onClick={() => setUnitTypePickerVisible(true)}>
  294. <span></span>
  295. <span className="ml-auto mr-4">
  296. {UNIT_TYPES.find((r) => r.value === unitType[0])?.label || ''}
  297. </span>
  298. <img src={icon_arr_r} alt="arr" />
  299. </div>
  300. </div>
  301. <div
  302. className="btn-contained rounded-md h-12 mx-9 my-8 text-base font-medium"
  303. onClick={onSaveBtnClick}
  304. >
  305. </div>
  306. </div>
  307. </div>
  308. <Picker
  309. columns={[XB_CODES]}
  310. visible={railPickerVisible}
  311. onClose={() => {
  312. setRailPickerVisible(false);
  313. }}
  314. value={directionCode}
  315. onConfirm={(v) => {
  316. setDirectionCode(v as string[]);
  317. }}
  318. />
  319. <Picker
  320. columns={[DATA_SOURCE]}
  321. visible={dataSourcePickerVisible}
  322. onClose={() => {
  323. setDataSourcePickerVisible(false);
  324. }}
  325. value={dataSourceCode}
  326. onConfirm={(v) => {
  327. setDataSourceCode(v as string[]);
  328. }}
  329. />
  330. <Picker
  331. columns={[LINE_CLASSIFY]}
  332. visible={lineClassPickerVisible}
  333. onClose={() => {
  334. setLineClassPickerVisible(false);
  335. }}
  336. value={dataSourceCode}
  337. onConfirm={(v) => {
  338. setLineClassCode(v as string[]);
  339. }}
  340. />
  341. <Picker
  342. columns={[UNIT_TYPES]}
  343. visible={unitTypePickerVisible}
  344. onClose={() => {
  345. setUnitTypePickerVisible(false);
  346. }}
  347. value={unitType}
  348. onConfirm={(v) => {
  349. setUnitType(v as string[]);
  350. }}
  351. />
  352. <Picker
  353. columns={[contextState.stationList]}
  354. visible={stationPickerVisible}
  355. onClose={() => {
  356. setStationPickerVisible(false);
  357. }}
  358. value={stationCode}
  359. onConfirm={(v) => {
  360. setStationCode(v as string[]);
  361. }}
  362. />
  363. </>
  364. );
  365. }