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.

381 lines
14 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
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
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 {clearData, 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. dispatch(clearData());
  156. }, 300);
  157. } else {
  158. Toast.show(res.message);
  159. }
  160. }).catch(e=>{
  161. Toast.show({
  162. content: '操作失败',
  163. });
  164. }).finally(() => {
  165. setLoading(false)
  166. });
  167. };
  168. return (
  169. <>
  170. <div>
  171. {loading && (
  172. <Mask opacity='thick' className="h-[100vh] flex justify-center items-center">
  173. <div style={{ margin: '45%', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center' }}>
  174. <SpinLoading color="#5c92b4" />
  175. <span className="whitespace-nowrap mt-5 text-[#5c92b4]" style={{fontSize: '16px'}}>...</span>
  176. </div>
  177. </Mask>
  178. )}
  179. <NavBar className="bg-white" onBack={back}>
  180. </NavBar>
  181. <div className="main-page-content overflow-x-hidden overflow-y-auto">
  182. <div className="bg-white px-5 text-sm text-text mt-2">
  183. <div className="h-12 flex items-center border-b border-[#eee]">
  184. <span></span>
  185. <input
  186. id='name-id'
  187. type="text"
  188. name="name"
  189. value={name}
  190. placeholder="请填写测量名称"
  191. className="border-0 outline-none self-stretch text-right flex-1 ml-4"
  192. onChange={onInputChange}
  193. />
  194. </div>
  195. <div className="h-12 flex items-center border-b border-[#eee]">
  196. <span></span>
  197. <input
  198. type="text"
  199. name="batch"
  200. value={batch}
  201. placeholder="请填写批次"
  202. className="border-0 outline-none self-stretch text-right flex-1 ml-4"
  203. onChange={onInputChange}
  204. />
  205. </div>
  206. <div
  207. className="h-12 flex items-center border-b border-[#eee]"
  208. onClick={() => setDataSourcePickerVisible(true)}
  209. >
  210. <span></span>
  211. <span className="ml-auto mr-4">
  212. {DATA_SOURCE.find((r) => r.value === dataSourceCode[0])?.label || ''}
  213. </span>
  214. <img src={icon_arr_r} alt="arr" />
  215. </div>
  216. {dataSourceCode[0] === 'DCDC' ? (
  217. <>
  218. <div className="h-12 flex items-center border-b border-[#eee]">
  219. <span></span>
  220. <input
  221. type="number"
  222. name="turnoutNum"
  223. value={turnoutNum}
  224. className="border-0 outline-none self-stretch text-right flex-1 ml-4"
  225. onChange={onInputChange}
  226. />
  227. </div>
  228. <div className="h-12 flex items-center border-b border-[#eee]">
  229. <span></span>
  230. <input
  231. type="number"
  232. name="sleeperNum"
  233. value={sleeperNum}
  234. className="border-0 outline-none self-stretch text-right flex-1 ml-4"
  235. onChange={onInputChange}
  236. />
  237. </div>
  238. <div
  239. className="h-12 flex items-center border-b border-[#eee]"
  240. onClick={() => {
  241. if (contextState.stationList.length > 0) {
  242. setStationPickerVisible(true);
  243. }
  244. }}
  245. >
  246. <span></span>
  247. <span className="ml-auto mr-4">
  248. {contextState.stationList.find((r) => r.value === stationCode[0])?.label || ''}
  249. </span>
  250. <img src={icon_arr_r} alt="arr" />
  251. </div>
  252. </>
  253. ) : (
  254. <div className="h-12 flex items-center border-b border-[#eee]">
  255. <span></span>
  256. <input
  257. type="number"
  258. name="mile"
  259. value={mile}
  260. className="w-14 h-8 mx-1 border border-[#eee] rounded outline-none text-center ml-auto"
  261. onChange={onInputChange}
  262. />
  263. <span>+</span>
  264. <input
  265. type="number"
  266. name="meter"
  267. value={meter}
  268. className="w-14 h-8 mx-1 border border-[#eee] rounded outline-none text-center"
  269. onChange={onInputChange}
  270. />
  271. <span></span>
  272. </div>
  273. )}
  274. <div
  275. className="h-12 flex items-center border-b border-[#eee]"
  276. onClick={() => setLineClassPickerVisible(true)}
  277. >
  278. <span>线</span>
  279. <span className="ml-auto mr-4">
  280. {LINE_CLASSIFY.find((r) => r.value === lineClassCode[0])?.label || ''}
  281. </span>
  282. <img src={icon_arr_r} alt="arr" />
  283. </div>
  284. <div
  285. className="h-12 flex items-center border-b border-[#eee]"
  286. onClick={() => setRailPickerVisible(true)}
  287. >
  288. <span></span>
  289. <span className="ml-auto mr-4">
  290. {XB_CODES.find((r) => r.value === directionCode[0])?.label || ''}
  291. </span>
  292. <img src={icon_arr_r} alt="arr" />
  293. </div>
  294. <div className="h-12 flex items-center " onClick={() => setUnitTypePickerVisible(true)}>
  295. <span></span>
  296. <span className="ml-auto mr-4">
  297. {UNIT_TYPES.find((r) => r.value === unitType[0])?.label || ''}
  298. </span>
  299. <img src={icon_arr_r} alt="arr" />
  300. </div>
  301. </div>
  302. <div
  303. className="btn-contained rounded-md h-12 mx-9 my-8 text-base font-medium"
  304. onClick={onSaveBtnClick}
  305. >
  306. </div>
  307. </div>
  308. </div>
  309. <Picker
  310. columns={[XB_CODES]}
  311. visible={railPickerVisible}
  312. onClose={() => {
  313. setRailPickerVisible(false);
  314. }}
  315. value={directionCode}
  316. onConfirm={(v) => {
  317. setDirectionCode(v as string[]);
  318. }}
  319. />
  320. <Picker
  321. columns={[DATA_SOURCE]}
  322. visible={dataSourcePickerVisible}
  323. onClose={() => {
  324. setDataSourcePickerVisible(false);
  325. }}
  326. value={dataSourceCode}
  327. onConfirm={(v) => {
  328. setDataSourceCode(v as string[]);
  329. }}
  330. />
  331. <Picker
  332. columns={[LINE_CLASSIFY]}
  333. visible={lineClassPickerVisible}
  334. onClose={() => {
  335. setLineClassPickerVisible(false);
  336. }}
  337. value={dataSourceCode}
  338. onConfirm={(v) => {
  339. setLineClassCode(v as string[]);
  340. }}
  341. />
  342. <Picker
  343. columns={[UNIT_TYPES]}
  344. visible={unitTypePickerVisible}
  345. onClose={() => {
  346. setUnitTypePickerVisible(false);
  347. }}
  348. value={unitType}
  349. onConfirm={(v) => {
  350. setUnitType(v as string[]);
  351. }}
  352. />
  353. <Picker
  354. columns={[contextState.stationList]}
  355. visible={stationPickerVisible}
  356. onClose={() => {
  357. setStationPickerVisible(false);
  358. }}
  359. value={stationCode}
  360. onConfirm={(v) => {
  361. setStationCode(v as string[]);
  362. }}
  363. />
  364. </>
  365. );
  366. }