您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 

332 行
15 KiB

  1. // material-ui
  2. import {
  3. Grid,
  4. Typography,
  5. Stack,
  6. Button,
  7. Dialog, DialogTitle, DialogContent, DialogActions
  8. } from '@mui/material';
  9. import * as UrlUtils from "utils/ApiPathConst";
  10. import * as React from "react";
  11. import * as HttpUtils from "utils/HttpUtils";
  12. import { useParams } from "react-router-dom";
  13. import { useNavigate } from "react-router-dom";
  14. import * as DateUtils from "utils/DateUtils"
  15. import * as FormatUtils from "utils/FormatUtils";
  16. import { checkPaymentSuspension } from "utils/Utils";
  17. import {
  18. checkIsOnlyOnlinePayment,
  19. } from "utils/Utils";
  20. import Loadable from 'components/Loadable';
  21. const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent')));
  22. import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png'
  23. const BackgroundHead = {
  24. backgroundImage: `url(${titleBackgroundImg})`,
  25. width: '100%',
  26. height: '100%',
  27. backgroundSize: 'contain',
  28. backgroundRepeat: 'no-repeat',
  29. backgroundColor: '#0C489E',
  30. backgroundPosition: 'right'
  31. }
  32. import {
  33. // useEffect,
  34. useState
  35. } from "react";
  36. import { PNSPS_BUTTON_THEME,
  37. // PNSPS_LONG_BUTTON_THEME
  38. } from "../../../themes/buttonConst";
  39. import { ThemeProvider } from "@emotion/react";
  40. import { FormattedMessage, useIntl } from "react-intl";
  41. // ==============================|| DASHBOARD - DEFAULT ||============================== //
  42. const Index = () => {
  43. const params = useParams();
  44. const navigate = useNavigate()
  45. const [fee, setFee] = useState(0);
  46. const [record, setRecord] = React.useState({});
  47. const [onReady, setOnReady] = React.useState(false);
  48. const [isPopUp, setIsPopUp] = useState(false);
  49. const [paymentHoldedErrText, setPaymentHoldedErrText] = React.useState("");
  50. const [paymentHoldedErr, setPaymentHoldedErr] = React.useState(false);
  51. const intl = useIntl();
  52. const { locale } = intl;
  53. React.useEffect(() => {
  54. loadForm();
  55. }, []);
  56. React.useEffect(() => {
  57. setOnReady(true);
  58. }, [record]);
  59. const isAfter = checkIsOnlyOnlinePayment();
  60. const loadForm = () => {
  61. if (params.id > 0) {
  62. HttpUtils.get({
  63. url: UrlUtils.GET_PROOF_PAY + "/" + params.id,
  64. onSuccess: (responseData) => {
  65. // if (!responseData.data?.id) {
  66. // navigate("/proof/search");
  67. // }
  68. setRecord(responseData.data);
  69. setFee(responseData.data.fee);
  70. },
  71. onError: () => {
  72. }
  73. });
  74. }
  75. }
  76. function doPayment() {
  77. setIsPopUp(false);
  78. let appIdList = [record?.appId]
  79. handlePaymentCheck(appIdList)
  80. }
  81. const handlePaymentCheck = (appIdList) => {
  82. HttpUtils.post({
  83. url: UrlUtils.PAYMENT_CHECK,
  84. params: {
  85. appIds: appIdList
  86. },
  87. onSuccess: (responseData) => {
  88. const latestData = {};
  89. responseData.forEach(item => {
  90. const { appId, timeDiff } = item;
  91. if (latestData[appId] === undefined || timeDiff < latestData[appId].timeDiff) {
  92. latestData[appId] = item;
  93. }
  94. });
  95. const latestDataObjects = Object.values(latestData);
  96. const filteredData = latestDataObjects.filter(item => item.timeDiff > 30 || item.status !== "APPR");
  97. const filteredAppIds = filteredData.map(item => item.appId);
  98. const appIdsNotInData = appIdList.filter(appId => !latestDataObjects.some(item => item.appId === appId));
  99. const combinedAppIdsArray = [...appIdsNotInData, ...filteredAppIds];
  100. const readyToPayment = appIdList.every(appId => combinedAppIdsArray.includes(appId));
  101. if (readyToPayment) {
  102. navigate('/paymentPage', { state: { amount: fee, appIdList: appIdList } });
  103. } else {
  104. const appIdsInData = appIdList.filter(appId => !combinedAppIdsArray.some(item => item === appId));
  105. const HoldingApplication = latestDataObjects.filter(item => appIdsInData.includes(item.appId));
  106. const resultString = HoldingApplication.map(item => item.appNo).join(' , ');
  107. setPaymentHoldedErrText(resultString);
  108. // setPaymentHoldedErrText(intl.formatMessage({ id: 'MSG.paymentHolded' }, { appNo: record.appNo }));
  109. setPaymentHoldedErr(true);
  110. }
  111. }
  112. });
  113. };
  114. return (
  115. !onReady ?
  116. <Grid container sx={{ minHeight: '87vh', mb: 3 }} direction="column" justifyContent="center" alignItems="center">
  117. <Grid item>
  118. <LoadingComponent />
  119. </Grid>
  120. </Grid>
  121. :
  122. (
  123. <Grid container sx={{ minHeight: '110vh', backgroundColor: '#fff' }} direction="column" justifyContent="flex-start" alignItems="center" >
  124. <Grid item xs={12} width="100%">
  125. <div style={BackgroundHead} width="100%" >
  126. <Stack direction="row" height='70px'>
  127. <Typography ml={15} color='#FFF' variant="h4" sx={{ display: { xs: 'none', sm: 'none', md: 'block' }, pt: 2 }}>
  128. <FormattedMessage id="proofRecord" />
  129. </Typography>
  130. </Stack>
  131. </div>
  132. </Grid>
  133. {/*row 1*/}
  134. <Grid item xs={12} md={12} >
  135. <Grid container justifyContent="flex-start" alignItems="center" >
  136. <center>
  137. <Grid item xs={12} md={8} >
  138. {isAfter ? (
  139. <Typography
  140. variant="h4"
  141. sx={{ textAlign: "left", ml: 8, mr: 4, mt: 4 }}
  142. >
  143. <FormattedMessage id="proofPaymentHeader_online2" />
  144. </Typography>
  145. ) : (
  146. <Typography
  147. variant="h4"
  148. sx={{
  149. textAlign: "left",
  150. ml: 4,
  151. mr: 4,
  152. mt: 4,
  153. borderBottom: "1px solid black"
  154. }}
  155. >
  156. <FormattedMessage id="proofPaymentHeader_online" />
  157. </Typography>
  158. )}
  159. <Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}>
  160. <div dangerouslySetInnerHTML={{
  161. __html: intl.formatMessage(
  162. {
  163. id: 'proofPaymentBody_online'
  164. },
  165. {
  166. appNo: record?.appNo,
  167. }
  168. )
  169. }} />
  170. <br />
  171. <div dangerouslySetInnerHTML={{
  172. __html: intl.formatMessage(
  173. {
  174. id: 'proofPaymentBody_online2'
  175. },
  176. {
  177. paymentDeadline: DateUtils.formatDateForLocale(record?.expiryDate, intl, locale),
  178. }
  179. )
  180. }} />
  181. <br />
  182. {checkPaymentSuspension()?
  183. <div>
  184. <Typography style={{ textAlign: "flex-start", color: "red" }}>
  185. <div dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: "suspensionMessageText" }) }} />
  186. </Typography>
  187. <br />
  188. </div>:null
  189. }
  190. </Typography>
  191. {!checkPaymentSuspension()?
  192. <Typography variant="h4" sx={{ ml: 8, textAlign: "left" }}>
  193. <ThemeProvider theme={PNSPS_BUTTON_THEME}>
  194. <Button
  195. component="span"
  196. variant="contained"
  197. // sx={{ ml: { sm: 4, md: 4, lg: 4 }, mr: 4, mt: { xs: 2, sm: 2 }, mb: { xs: 2, sm: 2 } }}
  198. sx={{mr: 4 }}
  199. onClick={() => { setIsPopUp(true) }}
  200. >
  201. <FormattedMessage id="payInstantly" />
  202. </Button>
  203. </ThemeProvider>
  204. <FormattedMessage id="or" />
  205. <ThemeProvider theme={PNSPS_BUTTON_THEME}>
  206. <Button
  207. component="span"
  208. variant="contained"
  209. sx={{ ml: { sm: 4, md: 4, lg: 4 }, mr: 4, mt: { xs: 2, sm: 2 }, mb: { xs: 2, sm: 2 } }}
  210. onClick={() => {
  211. navigate("/publicNotice");
  212. }}
  213. >
  214. <FormattedMessage id="payLater" />
  215. </Button>
  216. </ThemeProvider>
  217. </Typography>:null
  218. }
  219. <Typography variant="h4" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}>
  220. <div dangerouslySetInnerHTML={{
  221. __html: intl.formatMessage(
  222. {
  223. id: 'proofPaymentBody_online3'
  224. }
  225. )
  226. }} />
  227. <br />
  228. </Typography>
  229. </Grid>
  230. </center>
  231. </Grid>
  232. </Grid>
  233. <div>
  234. <Dialog
  235. open={isPopUp}
  236. onClose={() => setIsPopUp(false)}
  237. PaperProps={{
  238. sx: {
  239. minWidth: '40vw',
  240. maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '30vw' },
  241. maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '50vh' }
  242. }
  243. }}
  244. >
  245. <DialogTitle>
  246. <Typography variant="h3" >
  247. <FormattedMessage id="payConfirm" />
  248. </Typography>
  249. </DialogTitle>
  250. <DialogContent style={{ display: 'flex', }}>
  251. <Stack direction="column" justifyContent="space-between">
  252. <Typography variant="h4">
  253. <FormattedMessage id="totalAmount" /> ($): {FormatUtils.currencyFormat(fee)}
  254. </Typography>
  255. </Stack>
  256. </DialogContent>
  257. <DialogActions>
  258. <Button onClick={() => setIsPopUp(false)}>
  259. <Typography variant="h5">
  260. <FormattedMessage id="close" />
  261. </Typography></Button>
  262. <Button onClick={() => doPayment()}><Typography variant="h5">
  263. <FormattedMessage id="confirm" />
  264. </Typography></Button>
  265. </DialogActions>
  266. </Dialog>
  267. </div>
  268. {/*row 2*/}
  269. <div>
  270. <Dialog
  271. open={paymentHoldedErr}
  272. onClose={() => setPaymentHoldedErr(false)}
  273. PaperProps={{
  274. sx: {
  275. minWidth: '40vw',
  276. maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '70vw' },
  277. maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '60vh' }
  278. }
  279. }}
  280. >
  281. <DialogTitle></DialogTitle>
  282. <Typography variant="h4" style={{ paddingLeft: '24px' }}><FormattedMessage id="MSG.actionFail" /></Typography>
  283. <DialogContent style={{ display: 'flex', }}>
  284. <Stack direction="column" justifyContent="space-between">
  285. <div dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: 'MSG.paymentHolded' }, { appNo: paymentHoldedErrText }) }} />
  286. </Stack>
  287. </DialogContent>
  288. <DialogActions>
  289. <Button onClick={() => setPaymentHoldedErr(false)} aria-label={intl.formatMessage({ id: 'close' })}>
  290. <Typography variant="h5">
  291. <FormattedMessage id="close" />
  292. </Typography></Button>
  293. </DialogActions>
  294. </Dialog>
  295. </div>
  296. </Grid >
  297. )
  298. );
  299. };
  300. export default Index;