Преглед на файлове

add payment limited setting and checking

master
Alex Cheung преди 1 година
родител
ревизия
0b69d1f912
променени са 10 файла, в които са добавени 212 реда и са изтрити 70 реда
  1. +148
    -52
      src/pages/Payment/MultiPaymentWindow.js
  2. +43
    -10
      src/pages/Payment/index.js
  3. +1
    -1
      src/pages/PublicNotice/Details_Public/index.js
  4. +2
    -2
      src/pages/PublicNotice/ListPanel/index.js
  5. +1
    -1
      src/pages/authentication/ForgotPassword/AuthCallback/ResetPasswordSuccess.js
  6. +1
    -1
      src/pages/authentication/auth-forms/AuthLoginCustom.js
  7. +4
    -1
      src/translations/en.json
  8. +4
    -1
      src/translations/zh-CN.json
  9. +3
    -0
      src/translations/zh-HK.json
  10. +5
    -1
      src/utils/ApiPathConst.js

+ 148
- 52
src/pages/Payment/MultiPaymentWindow.js Целия файл

@@ -40,6 +40,8 @@ const MultiPaymentWindow = (props) => {
const [loadtTransactionData, setLoadtTransactionData] = useState({});
const [loadAvailableMethodData, setLoadAvailableMethodData] = useState([]);
const [paymentMethod, setPaymentMethod] = useState("");
const [isLimit, setIsLimit] = useState(false);
const [isPPSLimit, setIsPPSLimit] = useState(false);
const [transactionData, setTransactionData] = useState({});
const [availableMethodData, setAvailableMethodData] = useState([]);
const [fpsClass, setFpsClass] = useState("");
@@ -49,7 +51,7 @@ const MultiPaymentWindow = (props) => {
const [unionPayClass, setUnionPayClass] = useState("");
const [pPSClass, setPPSlass] = useState("");
const [filteredPaymentMethod, setFilteredPaymentMethod] = useState([]);
// const [onReady, setOnReady] = useState(false);
const [onReady, setOnReady] = useState(false);

useEffect(() => {
// console.log(props.transactionData)
@@ -83,50 +85,123 @@ const MultiPaymentWindow = (props) => {
}
}, [loadAvailableMethodData]);

// useEffect(() => {
// if(availableMethodData.length > 0 && Object.keys(transactionData).length > 0){
// setOnReady(true)
// }
// }, [availableMethodData]);
useEffect(() => {
if(filteredPaymentMethod!= undefined && filteredPaymentMethod.length>0){
setOnReady(true)
} else if(filteredPaymentMethod!= undefined && Object.keys(filteredPaymentMethod).length > 0){
setOnReady(true)
}

}, [filteredPaymentMethod]);

useEffect(() => {
// console.log(paymentMethod)
// const subtype = (paymentMethod === "Visa" || paymentMethod === "MasterCard" || paymentMethod === "JCB" || paymentMethod === "UnionPay") ? "CreditCard" : paymentMethod;
// const filteredPaymentMethod = availableMethodData.filter(obj => obj.subtype === subtype);
const filteredPaymentMethod = availableMethodData.filter(obj => {
if (obj.supportedcard && obj.supportedcard.includes(paymentMethod)) {
return obj.subtype === "CreditCard";
const availableMethod = availableMethodData;

if(props.availableMethods.length > 0){
const filteringPaymentMethod = availableMethod.filter(obj => {
if (obj.supportedcard && obj.supportedcard.includes(paymentMethod)) {
return obj.subtype === "CreditCard";
}
return obj.subtype === paymentMethod;
});

if (isLimit && filteringPaymentMethod!= undefined && filteringPaymentMethod.length>0){
if (paymentMethod == "FPS" || paymentMethod == "PPS"){
filteringPaymentMethod[0].pointstonote = paymentMethod + intl.formatMessage({id: 'paymentLimitPrice1'})
setFilteredPaymentMethod(filteringPaymentMethod[0]);
} else if (isLimit) {
filteringPaymentMethod[0].pointstonote = paymentMethod + intl.formatMessage({id: 'paymentLimitPrice2'})
setFilteredPaymentMethod(filteringPaymentMethod[0]);
}
}
if (!isLimit && filteringPaymentMethod!= undefined && filteringPaymentMethod.length>0){
setFilteredPaymentMethod(filteringPaymentMethod);
}
if(isPPSLimit && filteringPaymentMethod!= undefined && filteringPaymentMethod.length>0 && paymentMethod =="PPS"){
filteringPaymentMethod[0].pointstonote = paymentMethod + intl.formatMessage({id: 'paymentLimitPPS'})
setFilteredPaymentMethod(filteringPaymentMethod[0]);
}
return obj.subtype === paymentMethod;
});
// console.log(filteredPaymentMethod)
setFilteredPaymentMethod(filteredPaymentMethod);
setFpsClass(paymentMethod == "FPS" || paymentMethod == "" ? "" : "grayscale")
setVisaClass(paymentMethod == "Visa" || paymentMethod == "" ? "" : "grayscale")
setMastercardClass(paymentMethod == "MasterCard" || paymentMethod == "" ? "" : "grayscale")
setJCBClass(paymentMethod == "JCB" || paymentMethod == "" ? "" : "grayscale")
setUnionPayClass(paymentMethod == "UnionPay" || paymentMethod == "" ? "" : "grayscale")
setPPSlass(paymentMethod == "PPS" || paymentMethod == "" ? "" : "grayscale")

setFpsClass(paymentMethod == "FPS" || paymentMethod == "" ? "" : "grayscale")
setVisaClass(paymentMethod == "Visa" || paymentMethod == "" ? "" : "grayscale")
setMastercardClass(paymentMethod == "MasterCard" || paymentMethod == "" ? "" : "grayscale")
setJCBClass(paymentMethod == "JCB" || paymentMethod == "" ? "" : "grayscale")
setUnionPayClass(paymentMethod == "UnionPay" || paymentMethod == "" ? "" : "grayscale")
setPPSlass(paymentMethod == "PPS" || paymentMethod == "" ? "" : "grayscale")
// getMethodImgClass(paymentMethod)
}, [paymentMethod]);
}

}, [paymentMethod]);
const selectedPaymentMethodHandle = (method) => () =>{
console.log(getBowserType())
if (getBowserType() === "PC_Browser"){
setPaymentMethod(method)
props.setSelectedPaymentMethod(method);
}
if (getBowserType() !== "PC_Browser" && method !== "PPS"){
setPaymentMethod(method)
props.setSelectedPaymentMethod(method);
if (method != paymentMethod){
resetForm()
let totalAmount = props.totalAmount;
// totalAmount = 99999999.99
// totalAmount = 0.01
const paymentLimitList = props.paymentLimit
let limitRecordList;
switch (method) {
case "Visa":
case "JCB":
case "MasterCard":
limitRecordList = paymentLimitList.creditCardLimitRecord;
break;
case "FPS":
limitRecordList = paymentLimitList.fpsLimitRecord;
break;
case "PPS":
limitRecordList = paymentLimitList.ppsbLimitRecord;
break;
case "UnionPay":
limitRecordList = paymentLimitList.unionPlayLimitRecord;
break;
default:
break;
}
if (totalAmount >= limitRecordList.minLimit && totalAmount <= limitRecordList.maxLimit) {
setIsLimit(false)
} else {
setIsLimit(true)
}
if (getBowserType() === "PC_Browser"){
setPaymentMethod(method)
props.setSelectedPaymentMethod(method);
setIsPPSLimit(false)
} else if (getBowserType() !== "PC_Browser" && method !== "PPS"){
setPaymentMethod(method)
props.setSelectedPaymentMethod(method);
} else {
setPaymentMethod(method)
setIsPPSLimit(true)
}

}

};

const confirmPaymentHandle = () => () =>{
props.setConfirmPayment(true);
};

const closeHandle = () => () =>{
resetForm()
props.setOpen(false)
};

const resetForm = () =>{
setOnReady(false)
setPaymentMethod("")
setFilteredPaymentMethod([])
setIsLimit(false)
setIsPPSLimit(false)
};


useEffect(() => {
if(props.selectedPaymentMethod === ""){
setPaymentMethod("")
@@ -147,6 +222,7 @@ const MultiPaymentWindow = (props) => {
onClose={() => props.setOpen(false)}
fullWidth={true}
maxWidth={'xl'}
fullScreen={props.isFullScreen}
>
<DialogTitle >
<Grid container>
@@ -186,6 +262,7 @@ const MultiPaymentWindow = (props) => {
<FormattedMessage id="selectPaymentMethod"/>:
</Typography>
</Grid>
<Grid item sx={{display: { sm: 'block', md: 'none' }}}></Grid>
<Grid item>
<Button variant="contained" color="white" onClick={selectedPaymentMethodHandle("FPS")} disabled={props.fpsStatus.active === "N"}>
<img className={fpsClass} src={FpsIcon} width="80" height="80" alt="FPS"></img>
@@ -255,25 +332,44 @@ const MultiPaymentWindow = (props) => {
</Typography>
</Grid>
</Grid>
{paymentMethod !=""?
filteredPaymentMethod.map((availableMethod) => {
return (
<Grid container key={availableMethod.subtype} className={"css-1tx0bae"} sx={{ mt: 1, p:2 }}>
{availableMethod.pointstonote.map((pointstonote) => {
return (
<Grid container key={pointstonote.order} sx={{ p:0.5 }} direction="row" justifyContent="flex-start" alignItems="center">
<Grid item>
<Typography sx={{fontSize: "16px", color: "#000000", textAlign: "left" }}>
{pointstonote.content}
</Typography>
</Grid>
</Grid>
);
})}
{paymentMethod === "" ?
paymentMethod !="" && !onReady ? <LoadingComponent/> : null
:
!isLimit?
!onReady? <LoadingComponent/> :
!isLimit?
filteredPaymentMethod.map((availableMethod) => {
return (
<Grid container key={availableMethod.subtype} className={"css-1tx0bae"} sx={{ mt: 1, p:2 }}>
{
availableMethod.pointstonote.map((pointstonote) => {
return (
<Grid container key={pointstonote.order} sx={{ p:0.5 }} direction="row" justifyContent="flex-start" alignItems="center">
<Grid item>
<Typography sx={{fontSize: "16px", color: "#000000", textAlign: "left" }}>
{pointstonote.content}
</Typography>
</Grid>
</Grid>
);
})
}
</Grid>
);
})
: null
:
!onReady? <LoadingComponent/> :
<Grid container className={"css-1tx0bae"} sx={{ mt: 1, p:2 }}>
<Grid container sx={{ p:0.5 }} direction="row" justifyContent="flex-start" alignItems="center">
<Grid item>
<Typography color="error" sx={{fontSize: "16px", textAlign: "left" }}>
{filteredPaymentMethod.pointstonote}
</Typography>
</Grid>
</Grid>
</Grid>
);
})
: null}
}
</Grid>
</center>
</Grid>
@@ -285,12 +381,12 @@ const MultiPaymentWindow = (props) => {
</FormikProvider>
<Stack direction="row" justifyContent="space-around">
<DialogActions>
<Button variant="contained" onClick={() => props.setOpen(false)} autoFocus >
<Button variant="contained" onClick={closeHandle()} autoFocus >
<FormattedMessage id="cancel"/>
</Button>
</DialogActions>
<DialogActions>
<Button variant="contained" color="success" onClick={confirmPaymentHandle()} disabled={paymentMethod === ""}>
<Button variant="contained" color="success" onClick={confirmPaymentHandle()} disabled={paymentMethod === "" || isLimit || isPPSLimit}>
<FormattedMessage id="confirm"/>
</Button>
</DialogActions>


+ 43
- 10
src/pages/Payment/index.js Целия файл

@@ -7,9 +7,9 @@ const DataGrid = Loadable(React.lazy(() => import('./Details_Public/DataGrid')))
// const FPS = Loadable(React.lazy(() => import('./FPS')));
import { useEffect, useState } from "react";
import { useNavigate, useLocation } from "react-router-dom";
import { paymentPath } from "auth/utils";
// import * as FormatUtils from "utils/FormatUtils";
// const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent')));
import {getBowserType} from "auth/utils";

import {
Button,
@@ -25,7 +25,7 @@ import {ThemeProvider} from "@emotion/react";
import {PNSPS_BUTTON_THEME} from "../../themes/buttonConst";
import {
FormattedMessage,
// useIntl
useIntl
} from "react-intl";
const BackgroundHead = {
backgroundImage: `url(${titleBackgroundImg})`,
@@ -38,12 +38,10 @@ const BackgroundHead = {
}

const Index = () => {
// const getAvailablePaymentUrl = "/api/payment/availability";
const getTransactionIdUrl = "/api/payment/transaction";
const navigate = useNavigate()
const location = useLocation();
// const intl = useIntl();
// const { locale } = intl;
const intl = useIntl();
const { locale } = intl;

// const local = {en:"en-us", zh:"zh-hk", cn:"zh-cn"};
// const preferpaymentmethods = ['visa', 'mastercard', 'pps', 'creditcard', 'fps'];
@@ -54,6 +52,7 @@ const Index = () => {
//statusWindow
const [open, setOpen] = useState(false);
const [availableMethods, setAvailableMethods] = useState([]);
const [paymentLimit, setPaymentLimit] = useState([]);
const [transactionData, setTransactionData] = useState({});
const [fpsStatus, setFPSStatus] = useState({});
const [creditCardStatus, setCreditCardStatus] = useState({});
@@ -65,6 +64,7 @@ const Index = () => {

const [itemList, setItemList] = useState([]);
const [onReady, setOnReady] = useState(false);
const [isFullScreen, setIsFullScreen] = useState(false);

const [expiryDateErrText, setExpiryDateErrText] = React.useState("");
const [expiryDateErr, setExpiryDateErr] = React.useState(false);
@@ -75,6 +75,11 @@ const Index = () => {
localStorage.removeItem("webtoken");
localStorage.removeItem("transactionid");
localStorage.removeItem("paymentId");
if (getBowserType() === "PC_Browser"){
setIsFullScreen(false)
} else {
setIsFullScreen(true)
}
}, []);

useEffect(() => {
@@ -155,7 +160,7 @@ const Index = () => {

const getAvailablePayment = () =>{
// HttpUtils.post({
// url: paymentPath + getAvailablePaymentUrl,
// url: UrlUtils.PAYMENT_AVAILABLE_PAYMENT,
// params: {
// "locale": locale === 'en' ?local.en:locale === 'zh-HK' ?local.zh:local.cn,
// "amount": totalAmount,
@@ -174,6 +179,19 @@ const Index = () => {
// }
// });
HttpUtils.get({
url: UrlUtils.PAYMENT_LIMIT_SETTING_LIST,
params: {},
onSuccess: (responseData) => {
// console.log(responseData)
setPaymentLimit(responseData)

},
onError: () =>{
setOnReady(true)
}
});

const responseData = {
"availablepaymentmethods": [
{
@@ -308,7 +326,19 @@ const Index = () => {
if (availableMethods.length > 0) {
availableMethods.forEach((method) => {
if (method.subtype === "FPS") {
setFPSStatus(method)
if (totalAmount<1){
// method["minLimit"] = true
setFPSStatus(method)
}
else if (totalAmount>9999999.99){
// method["maxLimit"] = true
setFPSStatus(method)
} else {
// method["minLimit"] = true
// method["maxLimit"] = true
// console.log(method)
setFPSStatus(method)
}
} else if (method.subtype === "CreditCard") {
method.supportedcard.forEach((supportedcard) => {
if (supportedcard === "JCB" || supportedcard === "MasterCard" || supportedcard === "Visa") {
@@ -329,7 +359,7 @@ const Index = () => {

const getTransactionId = () => {
HttpUtils.get({
url: paymentPath + getTransactionIdUrl,
url: UrlUtils.PAYMENT_TRANSACTION_ID,
onSuccess: (responseData) => {
// const transactionData = responseData;
setTransactionData(responseData)
@@ -411,7 +441,7 @@ const Index = () => {
</Grid>
</Grid>
<Grid item xs={12} md={12} width="100%">
<Stack direction="row" justifyContent="flex-end" alignItems="flex-start" spacing={2} mr={12} >
<Stack direction="row" justifyContent="flex-end" alignItems="flex-start" spacing={2} mr={{xs:2,md:12}} >
<ThemeProvider theme={PNSPS_BUTTON_THEME}>
<Button
component="span"
@@ -466,6 +496,7 @@ const Index = () => {
<MultiPaymentWindow open={open}
setOpen={setOpen}
availableMethods={availableMethods}
paymentLimit={paymentLimit}
transactionData={transactionData}
totalAmount={totalAmount}
fpsStatus={fpsStatus}
@@ -477,6 +508,8 @@ const Index = () => {
setConfirmPayment={setConfirmPayment}
getMethodImgClass = {getMethodImgClass}
onReady = {onReady}
locale = {locale}
isFullScreen={isFullScreen}
/>
</Grid >
);


+ 1
- 1
src/pages/PublicNotice/Details_Public/index.js Целия файл

@@ -183,7 +183,7 @@ const DashboardDefault = () => {
/>
</Box>
</Grid>
<Grid item width="75%">
<Grid item width={{md:"75%"}}>
<Box xs={12} mt={3} sx={{ border: '0px groove grey', borderRadius: '10px', ..._sx, mb:2 }}>
<TabTableDetail
proofList={proofList}


+ 2
- 2
src/pages/PublicNotice/ListPanel/index.js Целия файл

@@ -133,7 +133,7 @@ const PublicNotice = () => {

{
JSON.parse(localStorage.getItem('userData')).creditor ? (
<Grid item xs={12} sm={12} md={12} lg={12} sx={{ height:'100%', maxWidth: '100%',width: "-webkit-fill-available", backgroundColor: "#fff", mt: 3, mr: 3, ml: 3, mb: 3, ..._sx }}>
<Grid item xs={12} sm={12} md={12} lg={12} sx={{ height:'100%', maxWidth: '100%',width: "-webkit-fill-available", backgroundColor: "#fff", mt: 3, mr:{xs:1,md:3}, ml:{xs:1,md:3}, mb: 3, ..._sx }}>
<TabContext value={selectedTab}>
<Box sx={{ borderBottom: 1, borderColor: 'divider', overflowX: 'auto', overflowY:'auto' }}>
<TabList onChange={handleChange} aria-label="lab API tabs example" sx={{ display: 'flex', flexDirection: 'row' }}>
@@ -170,7 +170,7 @@ const PublicNotice = () => {
</TabContext>
</Grid>
) : (
<Grid item xs={12} sx={{ minHeight: '80vh',height:"100%", maxHeight:'300vh', maxWidth: '95%', width: "-webkit-fill-available", backgroundColor: "#fff", mt: 3, mr: 3, ml: 3, mb: 3, ..._sx }}>
<Grid item xs={12} sx={{ minHeight: '80vh',height:"100%", maxHeight:'300vh', maxWidth: '95%', width: "-webkit-fill-available", backgroundColor: "#fff", mt: 3, mr:{xs:1,md:3}, ml:{xs:1,md:3}, mb: 3, ..._sx }}>
<TabContext value={selectedTab}>
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
<TabList onChange={handleChange} aria-label="lab API tabs example">


+ 1
- 1
src/pages/authentication/ForgotPassword/AuthCallback/ResetPasswordSuccess.js Целия файл

@@ -93,7 +93,7 @@ const ResetPasswordSuccess = () => {
</Stack>
</div>
</Grid>
<Grid item xs={12} md={12} width={{ sx:"90%", sm:"90%",md: "60%", xs: "90%" }}>
<Grid item xs={12} md={12} width={{ xs:"90%", sm:"90%",md: "60%", lg: "90%", xl: "90%" }}>
<MainCard
sx={{
maxWidth: { xs: 400, sm:730, md:800, lg: 1000 },


+ 1
- 1
src/pages/authentication/auth-forms/AuthLoginCustom.js Целия файл

@@ -339,7 +339,7 @@ const AuthLoginCustom = () => {
</AnimateButton>
</Grid>
<Grid item xs={12}>
<Stack direction="row" justifyContent="flex-start" alignItems="center" spacing={2}>
<Stack direction="row" justifyContent="flex-start" alignItems="center" spacing={1}>
<Link component={RouterLink} to="/forgot/password" color="primary" sx={{textDecoration:"none"}}>
<Typography align="center" variant="h7">
<FormattedMessage id="forgotUserPassword"/>?


+ 4
- 1
src/translations/en.json Целия файл

@@ -297,7 +297,10 @@
"transactionRefNo": "Transaction Reference Number",
"selectedPaymentMethod": "Selected payment method",
"paymentMethodNotAvailable":"The payment function is currently not available",

"paymentLimitPrice1":" is only applicable when minimum amount is 1.00 and maximum amount is 9,999,999.99",
"paymentLimitPrice2":" is only applicable when minimum amount is 0.10 and maximum amount is 9,999,999.99",
"paymentLimitPPS":" is not available via mobile device browsers, please access the service via desktop computers.",
"publicNoticeDetailTitle": "Public Notice Application Information",
"applyPerson": "Applicant",
"applyStatus": "Application Status",


+ 4
- 1
src/translations/zh-CN.json Целия файл

@@ -293,7 +293,10 @@
"transactionRefNo": "交易參考編號",
"selectedPaymentMethod": "已選擇付款方法",
"paymentMethodNotAvailable":"付款功能現在不可用",

"paymentLimitPrice1":"只适用于最小金额为 1.00 及最高金额为 9,999,999.99",
"paymentLimitPrice2":"只适用于最小金额为 0.10 及最高金额为 9,999,999.99",
"paymentLimitPPS":"付款不适用于流动装置的浏览器,请使用桌面电脑。",
"publicNoticeDetailTitle": "公共启事申请资料",
"applyPerson": "申请人",
"applyStatus": "申请状态",


+ 3
- 0
src/translations/zh-HK.json Целия файл

@@ -298,6 +298,9 @@
"transactionRefNo": "交易參考編號",
"selectedPaymentMethod": "已選擇付款方法",
"paymentMethodNotAvailable":"付款功能現在不可用",
"paymentLimitPrice1":"只適用於最小金額為 1.00 及最高金額為 9,999,999.99",
"paymentLimitPrice2":"只適用於最小金額為 0.10 及最高金額為 9,999,999.99",
"paymentLimitPPS":"付款不適用於流動裝置的瀏覽器,請使用桌面電腦。",

"publicNoticeDetailTitle": "公共啟事申請資料",
"applyPerson": "申請人",


+ 5
- 1
src/utils/ApiPathConst.js Целия файл

@@ -1,4 +1,4 @@
import {apiPath} from "../auth/utils";
import {apiPath, paymentPath} from "../auth/utils";

// GET request
export const REFRESH_TOKEN = "/refresh-token"
@@ -123,6 +123,10 @@ export const PAYMENT_LIST = apiPath+'/payment/list';//GET
export const PAYMENT_LOAD = apiPath+'/payment/load';//GET
export const PAYMENT_APP_LIST = apiPath+'/payment/applist';//POST

export const PAYMENT_LIMIT_SETTING_LIST = apiPath+'/settings/payment';//GET
export const PAYMENT_AVAILABLE_PAYMENT = paymentPath+'/api/payment/availability';//POST
export const PAYMENT_TRANSACTION_ID = paymentPath+'/api/payment/transaction';//GET

export const DEMAND_NOTE_PREVIEW = apiPath+'/demandNote/preview';//GET
export const DEMAND_NOTE_CREATE = apiPath+'/demandNote/create';//POST
export const DEMAND_NOTE_LIST = apiPath+'/demandNote/list';//GET


Зареждане…
Отказ
Запис