@@ -8,13 +8,14 @@ import { | |||
export function FiDataGrid({ rows, columns, sx, autoHeight, | |||
hideFooterSelectedRowCount, rowModesModel, editMode, | |||
pageSizeOptions, | |||
pageSizeOptions, filterItems, | |||
...props }) { | |||
const [_rows, set_rows] = React.useState([]); | |||
const [_columns, set_columns] = React.useState([]); | |||
const [_rowModesModel, set_rowModesModel] = React.useState({}); | |||
const [_editMode, set_editMode] = React.useState("row"); | |||
const [_pageSizeOptions, set_pageSizeOptions] = React.useState([10, 25, 50]); | |||
const [_filterItems, set_filterItems] = React.useState([]); | |||
const [_autoHeight, set_autoHeight] = React.useState(true); | |||
const [myHideFooterSelectedRowCount, setMyHideFooterSelectedRowCount] = React.useState(true); | |||
@@ -110,7 +111,12 @@ export function FiDataGrid({ rows, columns, sx, autoHeight, | |||
} | |||
}, [editMode]); | |||
React.useEffect(() => { | |||
if(filterItems){ | |||
set_filterItems(filterItems); | |||
} | |||
}, [filterItems]); | |||
return ( | |||
<DataGrid | |||
{...props} | |||
@@ -121,6 +127,7 @@ export function FiDataGrid({ rows, columns, sx, autoHeight, | |||
editMode={_editMode} | |||
autoHeight={_autoHeight} | |||
hideFooterSelectedRowCount={myHideFooterSelectedRowCount} | |||
filterModel={{items:_filterItems}} | |||
sx={_sx} | |||
/> | |||
); | |||
@@ -32,7 +32,6 @@ export default function SearchPublicNoticeTable({ recordList }) { | |||
flex: 1, | |||
renderCell: (params) => { | |||
let appNo = params.row.appNo; | |||
console.log(params) | |||
return <div style={{ margin: 4 }}>{appNo}<br/>{isORGLoggedIn()?<>{params.row.careOf}<br /></>:null}{params.row.remarks}</div> | |||
}, | |||
}, | |||
@@ -62,11 +62,12 @@ const Index = () => { | |||
React.useEffect(() => { | |||
// console.log (location.state) | |||
if(Object.keys(location.state).length > 0){ | |||
console.log (location.state) | |||
// console.log (location.state) | |||
setLocationData(location.state) | |||
if (/Android|webOS|iPhone|iPad|iPod|Opera Mini/i.test(navigator.userAgent)) { | |||
console.log('Mobile web browser'); | |||
setBrowserType(mobileBrowser) | |||
// setFpsqrcodeurl(openPASGUrl) | |||
} else { | |||
console.log('Desktop web browser'); | |||
setBrowserType(desktopBrowser) | |||
@@ -159,7 +160,7 @@ const Index = () => { | |||
// const parsedUrl = new URL(responseData.fpsqrcodeurl); | |||
// const fpsqrcodeurl = parsedUrl.pathname; | |||
const openPASGUrl = pasgPath + '?pay_req_obj=' + encodeURIComponent(responseData.fpsqrcodeurl) + '&callback=' | |||
+ encodeURIComponent("https://"+window.location.hostname+ '/paymentPage/fps/ackpage'); | |||
+ encodeURIComponent("https://"+window.location.hostname+ '/paymentPage/fps/fpscallback?TRANSACTION_ID='+paymentData.transactionid+"&WEB_TOKEN="+paymentData.webtoken+"&PAYMENT_ID="+localStorage.getItem("paymentId")); | |||
setFpsqrcodeurl(openPASGUrl) | |||
} | |||
}); | |||
@@ -57,7 +57,7 @@ const Index = () => { | |||
// const pasgPath = 'https://fps.payapps.hkicl.com.hk'; //PRD | |||
//timer | |||
const openPASGUrl = pasgPath + '?pay_req_obj=' + encodeURIComponent("http://127.0.0.1:8080/api/payment/wallet/fps/enquiryfpspayload/vm.JKDDlTOavR3ASviSwUnS1Lw4-") + '&callback=' | |||
+ encodeURIComponent("https://"+window.location.hostname+ '/paymentPage/fps/ackpage'); | |||
+ encodeURIComponent("https://"+window.location.hostname+ '/paymentPage/fps/fpscallback?TRANSACTION_ID='+transactionid+"&WEB_TOKEN="+webtoken); | |||
const currentTimer = React.useRef(); | |||
const [time, setTime] = React.useState(0); | |||
@@ -1,16 +1,280 @@ | |||
// material-ui | |||
import { | |||
Grid, | |||
Typography, | |||
Stack, | |||
Box | |||
// Button, | |||
// FormLabel, | |||
} from '@mui/material'; | |||
import * as React from "react"; | |||
import {useEffect} from "react"; | |||
import * as HttpUtils from "utils/HttpUtils"; | |||
import * as UrlUtils from "utils/ApiPathConst"; | |||
// import { useNavigate } from "react-router-dom"; | |||
// import FpsIcon from "assets/images/icons/fps.svg"; | |||
// import { useLocation } from 'react-router-dom'; | |||
import {paymentPath} from "auth/utils"; | |||
// import {poll} from "utils/Utils"; | |||
import * as DateUtils from "utils/DateUtils" | |||
import Loadable from 'components/Loadable'; | |||
const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | |||
const PaymentDetails = Loadable(React.lazy(() => import('../Details_Public/PaymentDetails'))); | |||
const DataGrid = Loadable(React.lazy(() => import('../Details_Public/DataGrid'))); | |||
import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' | |||
const BackgroundHead = { | |||
backgroundImage: `url(${titleBackgroundImg})`, | |||
width: '100%', | |||
height: '100%', | |||
backgroundSize: 'contain', | |||
backgroundRepeat: 'no-repeat', | |||
backgroundColor: '#0C489E', | |||
backgroundPosition: 'right' | |||
} | |||
// ==============================|| DASHBOARD - DEFAULT ||============================== // | |||
const Fpscallback = () => { | |||
// const navigate = useNavigate() | |||
// const location = useLocation(); | |||
// const [locationData, setLocationData] = React.useState({}); | |||
const [paymentData, setPaymentData] = React.useState({}); | |||
const [responeData, setResponeDataData] = React.useState({}); | |||
const [itemList, setItemList] = React.useState([]); | |||
const [transactionData, setTransactionData] = React.useState({}); | |||
// const [transactionDate, setTransactionDate] = React.useState(""); | |||
// const [transactionTime, setTransactionTime] = React.useState(""); | |||
const [onReady, setOnReady] = React.useState(false); | |||
const paymentStatusApi = "/api/payment/status/"; | |||
useEffect(() => { | |||
window.close(); | |||
React.useEffect(() => { | |||
loadForm(); | |||
}, []); | |||
React.useEffect(() => { | |||
console.log(responeData) | |||
if(Object.keys(responeData).length > 0){ | |||
setTransactionData(responeData) | |||
} | |||
}, [responeData]); | |||
React.useEffect(() => { | |||
// console.log(paymentData) | |||
console.log(transactionData) | |||
if(Object.keys(transactionData).length > 0 ){ | |||
setOnReady(true); | |||
} | |||
}, [transactionData]); | |||
const loadForm = () => { | |||
const params = new URLSearchParams(window.location.search); | |||
let transactionid = params.get("TRANSACTION_ID") | |||
let webtoken = params.get("WEB_TOKEN") | |||
let paymentId = params.get("PAYMENT_ID") | |||
console.log(transactionid) | |||
console.log(webtoken) | |||
console.log(paymentId) | |||
HttpUtils.post({ | |||
url: paymentPath+paymentStatusApi+transactionid, | |||
params:{ | |||
"apprefid": transactionid, | |||
"webtoken": webtoken, | |||
}, | |||
onSuccess: function(responseData){ | |||
setResponeDataData(responseData) | |||
if (responseData.paymentdetail?.result?.paymentstatuscode === "APPR") { | |||
localStorage.removeItem("webtoken"); | |||
localStorage.removeItem("transactionid"); | |||
} | |||
HttpUtils.post({ | |||
url: UrlUtils.PAYMENT_SAVE, | |||
params: { | |||
id: paymentId, | |||
transNo: responseData.transactionid, | |||
transDateTime: responseData.paymentdetail.time.replace("[UTC]", ""), | |||
egisRefNo: responseData.paymentdetail.paymentid, | |||
status: responseData.paymentdetail.result.paymentstatuscode, | |||
payload: responseData | |||
}, | |||
onSuccess: function (responseData2) { | |||
responseData2.data["transDateStr"] = DateUtils.dateFormat(responseData2.data.transDateTime, "DD/MM/YYYY"); | |||
responseData2.data["transTimeStr"] = DateUtils.dateFormat(responseData2.data.transDateTime, "HH:mm:ss"); | |||
setItemList(responseData2.paymentItemList) | |||
setPaymentData(responseData2.data); | |||
localStorage.removeItem("paymentId"); | |||
} | |||
}); | |||
} | |||
}); | |||
// setTransactionData( | |||
// { | |||
// "amount": 999.99, | |||
// "currencycode": "HKD", | |||
// "paymentdetail": { | |||
// "attemptno": 1, | |||
// "channel": "MobileWallet", | |||
// "paymentid": "C202310268000681", | |||
// "paymentmethod": "04", | |||
// "result": { | |||
// "canretry": "Y", | |||
// "description": "CANC - Cancelled by user or Payment Server.", | |||
// "paymentstatuscode": "CANC", | |||
// "rejectreasoncode": "Payment Cancelled. [PAY-E-9022]" | |||
// }, | |||
// "subtype": "FPS", | |||
// "time": "2023-10-26T09:02:17Z[UTC]" | |||
// }, | |||
// "transactionid": "20231026170103921" | |||
// } | |||
// ) | |||
} | |||
return ( | |||
<div></div> | |||
!onReady ? | |||
<LoadingComponent /> | |||
: | |||
transactionData.paymentdetail?.result?.paymentstatuscode === "APPR" ? | |||
( | |||
<Grid container sx={{ minHeight: '110vh', backgroundColor: '#fff' }} direction="column" justifyContent="flex-start" alignItems="center" > | |||
<Grid item xs={12} width="100%"> | |||
<div style={BackgroundHead} width="100%"> | |||
<Stack direction="row" height='70px'> | |||
<Typography ml={15} color='#FFF' variant="h4" sx={{ pt: 2 }}>公共啟事:付款成功</Typography> | |||
</Stack> | |||
</div> | |||
</Grid> | |||
{/*row 1*/} | |||
<Grid item xs={12} md={12} > | |||
<Grid container justifyContent="flex-start" alignItems="center" > | |||
<center> | |||
<Grid item xs={12} md={12} > | |||
<Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}> | |||
您的申請和付款已收到 | |||
</Typography> | |||
<Grid container> | |||
<Grid item xs={12} md={12} sx={{ textAlign: "center" }}> | |||
<Grid container justifyContent="center" spacing={2} sx={{ p: 2 }} alignitems="stretch" > | |||
<Grid item xs={12} md={5} sx={{ pt: 1, pb: 2 }} style={{ height: '100%' }}> | |||
<Box xs={12} md={12} sx={{ p: 4, border: '3px solid #eee', borderRadius: '10px' }} > | |||
<DataGrid | |||
recordList={itemList} | |||
/> | |||
</Box> | |||
</Grid> | |||
<Grid item xs={12} md={5} sx={{ pt: 2 }} style={{ height: '100%' }}> | |||
<Box xs={12} md={12} sx={{ p: 4, border: '3px solid #eee', borderRadius: '10px' }} > | |||
<PaymentDetails | |||
formData={paymentData} | |||
style={{ | |||
display: "flex", | |||
height: "100%", | |||
flex: 1 | |||
}} | |||
/> | |||
</Box> | |||
</Grid> | |||
</Grid> | |||
</Grid> | |||
</Grid> | |||
</Grid> | |||
</center> | |||
</Grid> | |||
</Grid> | |||
{/*row 2*/} | |||
</Grid > | |||
) : | |||
(transactionData.paymentdetail?.result?.paymentstatuscode === "CANC" ? | |||
<Grid container sx={{ minHeight: '110vh', backgroundColor: '#fff' }} direction="column" justifyContent="flex-start" alignItems="center" > | |||
<Grid item xs={12} width="100%"> | |||
<div style={BackgroundHead} width="100%"> | |||
<Stack direction="row" height='70px'> | |||
<Typography ml={15} color='#FFF' variant="h4" sx={{ pt: 2 }}>公共啟事:付款取消</Typography> | |||
</Stack> | |||
</div> | |||
</Grid> | |||
{/*row 1*/} | |||
<Grid item xs={12} md={12} > | |||
<Grid container justifyContent="flex-start" alignItems="center" > | |||
<center> | |||
<Grid item xs={12} md={8} > | |||
<Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}> | |||
付款取消訊息: | |||
<br /><br /> | |||
您的付款已被取消。我們收到了您的付款請求,但由於某些原因,付款無法完成。請注意以下事項: | |||
<br /><br /> | |||
如果您主動取消了支付,請確認並確保取消是您的意願。 | |||
<br /> | |||
如果付款被取消是由於系統問題或其他原因,請您嘗試以下解決方法: | |||
<br /><br /> | |||
檢查您的支付帳戶是否有任何異常或限制。 | |||
<br /> | |||
確保您的付款資訊準確無誤。 | |||
<br /> | |||
檢查您的網路連線是否正常。 | |||
<br /><br /> | |||
如果您需要進一步的協助或有任何疑問,請隨時與我們聯繫,我們將盡快解決您的付款問題。謝謝! | |||
</Typography> | |||
</Grid> | |||
</center> | |||
</Grid> | |||
</Grid> | |||
{/*row 2*/} | |||
</Grid > | |||
: | |||
<Grid container sx={{ minHeight: '110vh', backgroundColor: '#fff' }} direction="column" justifyContent="flex-start" alignItems="center" > | |||
<Grid item xs={12} width="100%"> | |||
<div style={BackgroundHead} width="100%"> | |||
<Stack direction="row" height='70px'> | |||
<Typography ml={15} color='#FFF' variant="h4" sx={{ pt: 2 }}>公共啟事:付款失敗</Typography> | |||
</Stack> | |||
</div> | |||
</Grid> | |||
{/*row 1*/} | |||
<Grid item xs={12} md={12} > | |||
<Grid container justifyContent="flex-start" alignItems="center" > | |||
<center> | |||
<Grid item xs={12} md={8} > | |||
<Typography variant="h5" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "left" }}> | |||
付款失敗訊息: | |||
<br /><br /> | |||
親愛的用戶,很遺憾地告訴您,您的付款操作未成功。我們在處理您的付款時遇到了問題。請您仔細檢查以下事項: | |||
<br /><br /> | |||
您的支付帳戶餘額是否足夠。 | |||
<br /> | |||
您提供的付款資訊是否準確無誤。 | |||
<br /> | |||
請檢查您的網路連線是否正常。 | |||
<br /><br /> | |||
如果您已確認以上問題無誤,但付款失敗,請您嘗試以下解決方法: | |||
<br /><br /> | |||
嘗試使用其他付款方式進行付款。 | |||
<br /> | |||
檢查您的支付帳戶是否有異常或限制。 | |||
<br /> | |||
聯絡我們的客服人員尋求協助。 | |||
<br /><br /> | |||
如果您需要進一步的協助或有任何疑問,請隨時與我們聯繫。非常抱歉給您帶來不便,我們將盡快解決您的付款問題。謝謝! | |||
</Typography> | |||
</Grid> | |||
</center> | |||
</Grid> | |||
</Grid> | |||
{/*row 2*/} | |||
</Grid > | |||
) | |||
); | |||
} | |||
}; | |||
export default Fpscallback; | |||
export default Fpscallback; |
@@ -332,6 +332,7 @@ const Index = () => { | |||
setPPSStatus(method) | |||
} | |||
}); | |||
setOnReady(true) | |||
} | |||
}, [availableMethods]); | |||
@@ -345,11 +346,11 @@ const Index = () => { | |||
}); | |||
} | |||
useEffect(() => { | |||
if (availableMethods.length > 0 && Object.keys(transactionData).length > 0) { | |||
setOnReady(true) | |||
} | |||
}, [transactionData, availableMethods]); | |||
// useEffect(() => { | |||
// if (availableMethods.length > 0 && Object.keys(transactionData).length > 0) { | |||
// setOnReady(true) | |||
// } | |||
// }, [transactionData, availableMethods]); | |||
const getAppList = () => { | |||
HttpUtils.post({ | |||
@@ -4,7 +4,10 @@ import { | |||
Stack, | |||
Typography, | |||
Button, | |||
Dialog, DialogTitle, DialogContent, DialogActions | |||
Autocomplete, | |||
TextField, | |||
Grid, | |||
Dialog, DialogTitle, DialogContent, DialogActions, | |||
} from '@mui/material'; | |||
import { FiDataGrid } from "components/FiDataGrid"; | |||
import * as DateUtils from "utils/DateUtils" | |||
@@ -17,12 +20,46 @@ import { | |||
// ==============================|| EVENT TABLE ||============================== // | |||
export default function SubmittedTab({ rows }) { | |||
const [rowList, setRowList] = React.useState([]); | |||
const [selectedRowItems, setSelectedRowItems] = React.useState([]); | |||
const [isPopUp, setIsPopUp] = React.useState(false); | |||
const [checkCareOf, setCheckCareOf] = React.useState(false); | |||
const [getCareOfList, setCareOfList] = React.useState([]); | |||
const [careOfComboList, setCareOfComboList] = React.useState([{}]); | |||
const [selectedCareOf, setSelectedCareOf] = React.useState(null); | |||
//const [amount, setAmount] = React.useState(0); | |||
const navigate = useNavigate() | |||
React.useEffect(() => { | |||
// const careOfList = rows.map(obj => obj.careOf); | |||
console.log(rows) | |||
// console.log(careOfList) | |||
setRowList(rows) | |||
const formattedData = rows.filter(obj => obj.careOf !== null).map((obj, index) => ({ | |||
key: index, | |||
id: obj.id, | |||
label: obj.careOf, | |||
})); | |||
console.log(formattedData) | |||
setCareOfList(formattedData) | |||
}, []); | |||
React.useEffect(() => { | |||
console.log(getCareOfList) | |||
setCareOfComboList(getCareOfList) | |||
}, [getCareOfList]); | |||
React.useEffect(() => { | |||
if(selectedCareOf != null){ | |||
const afteSelectedList = []; | |||
afteSelectedList.push(rows.find(obj => obj.id === selectedCareOf.id)); | |||
setRowList(afteSelectedList) | |||
}else{ | |||
setRowList(rows) | |||
} | |||
}, [selectedCareOf]); | |||
const handleDetailClick = (params) => () => { | |||
navigate('/publicNotice/' + params.id); | |||
}; | |||
@@ -148,13 +185,11 @@ export default function SubmittedTab({ rows }) { | |||
const datas = rows?.filter((row) => | |||
selectedRowItems.includes(row.id) | |||
); | |||
console.log(datas) | |||
// console.log(datas) | |||
for (var i = 0; i < datas?.length; i++) { | |||
totalAmount += datas[i].fee; | |||
appIdList.push(datas[i].id); | |||
} | |||
console.log(appIdList) | |||
console.log(totalAmount) | |||
const firstCareOf = datas[0].careOf; | |||
const areAllCareOfEqual = datas.every(obj => obj.careOf === firstCareOf); | |||
@@ -170,10 +205,30 @@ export default function SubmittedTab({ rows }) { | |||
return ( | |||
<> | |||
<div style={{ minHeight: 400, width: '100%', padding: 4 }}> | |||
{isORGLoggedIn()? | |||
<Grid container direction="row" justifyContent="flex-start" alignItems="center" > | |||
<Grid item xs={3} md={1}> | |||
<Typography variant="h5">Care Of:</Typography> | |||
</Grid> | |||
<Grid item xs={8} md={2}> | |||
<Autocomplete | |||
disablePortal | |||
id="careOfCombo" | |||
value={selectedCareOf === null ? null : selectedCareOf} | |||
options={careOfComboList} | |||
onChange={(event, newValue) => { | |||
// console.log(newValue) | |||
setSelectedCareOf(newValue); | |||
}} | |||
renderInput={(params) => <TextField {...params} />} | |||
/> | |||
</Grid> | |||
</Grid>:null | |||
} | |||
<FiDataGrid | |||
checkboxSelection | |||
disableRowSelectionOnClick | |||
rows={rows} | |||
rows={rowList} | |||
columns={columns} | |||
initialState={{ | |||
pagination: { | |||
@@ -21,6 +21,8 @@ const IAmSmart_RegistryCallback = Loadable(lazy(() => import('pages/iAmSmart/Reg | |||
const TestMailPage = Loadable(lazy(() => import('pages/pnspsNotifyTest'))); | |||
const VerifyPage = Loadable(lazy(() => import('pages/authentication/Verify'))); | |||
const Testfps = Loadable(lazy(() => import('pages/Payment/FPS/FPSTest'))); | |||
const Payment_FPS_CallBack = Loadable(lazy(() => import('pages/Payment/FPS/fpscallback'))); | |||
// ==============================|| AUTH ROUTING ||============================== // | |||
const LoginRoutes = { | |||
@@ -86,6 +88,10 @@ const LoginRoutes = { | |||
{ | |||
path: 'testfps', | |||
element: <Testfps/> | |||
}, | |||
{ | |||
path: 'testfpscallback', | |||
element: <Payment_FPS_CallBack/> | |||
} | |||
] | |||
}; | |||