update bill query and pay
This commit is contained in:
parent
081e96243d
commit
aabbd75a2f
@ -18,6 +18,7 @@
|
||||
"@emotion/react": "^11.11.4",
|
||||
"@emotion/styled": "^11.11.5",
|
||||
"@mui/system": "^5.15.15",
|
||||
"@sentry/react": "^8.7.0",
|
||||
"ahooks": "^3.7.11",
|
||||
"axios": "^1.7.2",
|
||||
"clsx": "^2.1.1",
|
||||
|
@ -196,7 +196,7 @@ export const BillList: React.FC<BillListProps> = (props) => {
|
||||
formatPageText: (params) => (
|
||||
<div className="bill-list-pagination">
|
||||
{props.tableFooter}
|
||||
<span>显示第 {params?.currentStart} 条 - 第 {params?.currentEnd} 条,共 {params?.total} 条</span>
|
||||
{props.source?.pagination.recordTotal && <span>{t('page.record-show',params)}</span>}
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
|
@ -4,6 +4,7 @@ import {Card} from "@/components/card";
|
||||
import {useTranslation} from "react-i18next";
|
||||
import {BillQueryParams} from "@/service/api/bill.ts";
|
||||
import dayjs from "dayjs";
|
||||
import useAuth from "@/hooks/useAuth.ts";
|
||||
|
||||
type SearchFormProps = {
|
||||
onSearch?: (params: BillQueryParams) => void;
|
||||
@ -15,14 +16,19 @@ type SearchFormProps = {
|
||||
type SearchFormFields = {
|
||||
dateRange?: Date[];
|
||||
student_number?: string;
|
||||
application_number?: string;
|
||||
bill_number?: string;
|
||||
pay_method?: string;
|
||||
payment_channel?: string;
|
||||
bill_status?: string;
|
||||
apply_status?: string;
|
||||
}
|
||||
const SearchForm: React.FC<SearchFormProps> = (props) => {
|
||||
const {user} = useAuth();
|
||||
const formSubmit = (value: SearchFormFields) => {
|
||||
const params: BillQueryParams = {}
|
||||
const params: BillQueryParams = {
|
||||
department: user?.department == 'RO' ? 'RO' : 'FO',
|
||||
}
|
||||
|
||||
if (value.dateRange && value.dateRange.length == 2) {
|
||||
params.start_date = dayjs(value.dateRange[0]).format('YYYY-MM-DD');
|
||||
params.end_date = dayjs(value.dateRange[1]).format('YYYY-MM-DD');
|
||||
@ -30,6 +36,9 @@ const SearchForm: React.FC<SearchFormProps> = (props) => {
|
||||
if (value.student_number) {
|
||||
params.student_number = value.student_number;
|
||||
}
|
||||
if (value.application_number) {
|
||||
params.application_number = value.application_number;
|
||||
}
|
||||
// 对账状态
|
||||
if (value.apply_status) {
|
||||
params.apply_status = value.apply_status;
|
||||
@ -39,8 +48,8 @@ const SearchForm: React.FC<SearchFormProps> = (props) => {
|
||||
params.status = value.bill_status;
|
||||
}
|
||||
// 支付方式
|
||||
if (value.pay_method) {
|
||||
params.payment_method = value.pay_method;
|
||||
if (value.payment_channel) {
|
||||
params.payment_channel = value.payment_channel;
|
||||
}
|
||||
props.onSearch?.(params);
|
||||
}
|
||||
@ -48,7 +57,7 @@ const SearchForm: React.FC<SearchFormProps> = (props) => {
|
||||
// 根据语言变化更新订单状态options
|
||||
const billStatusOptions = useMemo(() => {
|
||||
return [
|
||||
{value: `PENDING`, label: t('bill.pay_status_pending')},
|
||||
{value: `PENDING`, label: t('bill.pay_status_pending')},
|
||||
{value: 'PAID', label: t('bill.pay_status_paid')},
|
||||
{value: 'CANCELLED', label: t('bill.pay_status_canceled')}
|
||||
]
|
||||
@ -75,28 +84,28 @@ const SearchForm: React.FC<SearchFormProps> = (props) => {
|
||||
placeholder={t('base.please_enter')}/>
|
||||
</Col>
|
||||
<Col span={4}>
|
||||
<Form.Input field='bill_number' label={t('base.bill_number')} trigger='blur'
|
||||
<Form.Input field='application_number' label={t('base.bill_number')} trigger='blur'
|
||||
placeholder={t('base.please_enter')}/>
|
||||
</Col>
|
||||
<Col span={4}>
|
||||
<Form.Select showClear field="pay_method" label={t('bill.title_pay_method')}
|
||||
<Form.Select showClear field="payment_channel" label={t('bill.title_pay_method')}
|
||||
placeholder={t('base.please_select')} style={{width: '100%'}}>
|
||||
<Form.Select.Option value="ASIAPAY">AsiaPay</Form.Select.Option>
|
||||
<Form.Select.Option value="FLYWIRE">FlyWire</Form.Select.Option>
|
||||
<Form.Select.Option value="ASIAPAY">ASIAPAY</Form.Select.Option>
|
||||
<Form.Select.Option value="FLYWIRE">FLYWIRE</Form.Select.Option>
|
||||
<Form.Select.Option value="PPS">PPS</Form.Select.Option>
|
||||
</Form.Select>
|
||||
</Col>
|
||||
<Col span={4}>
|
||||
<Form.Select showClear field="bill_status" label={t('bill.pay_status')}
|
||||
placeholder={t('base.please_select')} style={{width: '100%'}}>
|
||||
{billStatusOptions.map((item,index) => (
|
||||
{billStatusOptions.map((item, index) => (
|
||||
<Form.Select.Option key={index} value={item.value}>{item.label}</Form.Select.Option>))}
|
||||
</Form.Select>
|
||||
</Col>
|
||||
{props.showApply && <Col span={4}>
|
||||
<Form.Select showClear field="apply_status" label={t('bill.title_reconciliation_status')}
|
||||
placeholder={t('base.please_select')} style={{width: '100%'}}>
|
||||
{applyStatusOptions.map((item,index) => (
|
||||
{applyStatusOptions.map((item, index) => (
|
||||
<Form.Select.Option key={index} value={item.value}>{item.label}</Form.Select.Option>))}
|
||||
</Form.Select>
|
||||
</Col>}
|
||||
|
@ -51,7 +51,11 @@ export const AuthProvider = ({children}: { children: React.ReactNode }) => {
|
||||
payload: {
|
||||
isInitialized: true,
|
||||
isLoggedIn: !!user,
|
||||
user
|
||||
user:{
|
||||
...user,
|
||||
// TODO 等待接口返回
|
||||
department:'root'
|
||||
}
|
||||
}
|
||||
})
|
||||
}).finally(() => {
|
||||
@ -73,7 +77,11 @@ export const AuthProvider = ({children}: { children: React.ReactNode }) => {
|
||||
action: 'login',
|
||||
payload: {
|
||||
isLoggedIn: true,
|
||||
user
|
||||
user:{
|
||||
...user,
|
||||
// TODO 等待接口返回
|
||||
department:'root'
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -98,6 +106,7 @@ export const AuthProvider = ({children}: { children: React.ReactNode }) => {
|
||||
id: 1,
|
||||
token: 'test-123123',
|
||||
email: 'test@qq.com',
|
||||
department: 'root',
|
||||
exp: 1,
|
||||
iat: 1,
|
||||
iss: "Hong Kong Chu Hai College",
|
||||
|
@ -78,6 +78,9 @@
|
||||
"student_number_required": "required student number",
|
||||
"success": "Create bill success"
|
||||
},
|
||||
"page": {
|
||||
"record-show": "Showing {{currentStart}} - {{currentEnd}} of {{total}}"
|
||||
},
|
||||
"pay": {
|
||||
"amount": "Amount",
|
||||
"bill_error": "Bills to be paid do not exist or are overdue",
|
||||
|
@ -78,6 +78,9 @@
|
||||
"student_number_required": "请填写学号",
|
||||
"success": "创建订单成功"
|
||||
},
|
||||
"page": {
|
||||
"record-show": "显示第 {{currentStart}} 条 - 第 {{currentEnd}} 条,共 {{total}} 条"
|
||||
},
|
||||
"pay": {
|
||||
"amount": "应付金额",
|
||||
"bill_error": "待支付账单不存在或已过期",
|
||||
|
@ -78,6 +78,9 @@
|
||||
"student_number_required": "請填入學號",
|
||||
"success": "創建訂單成功"
|
||||
},
|
||||
"page": {
|
||||
"record-show": "顯示第 {{currentStart}} 條 - 第 {{currentEnd}} 條,共 {{total}} 條"
|
||||
},
|
||||
"pay": {
|
||||
"amount": "應付金額",
|
||||
"bill_error": "待支付帳單不存在或已過期",
|
||||
|
13
src/main.tsx
13
src/main.tsx
@ -1,9 +1,22 @@
|
||||
// import React from "react";
|
||||
import ReactDOM from 'react-dom/client'
|
||||
import * as Sentry from '@sentry/react';
|
||||
|
||||
import App from './App.tsx'
|
||||
import '@/assets/index.less'
|
||||
|
||||
Sentry.init({
|
||||
dsn: "https://571faf95edca40ac981a573eff1b17fe@logs.1688cd.cn/1",
|
||||
//dsn: "https://5224dbb04d4a6a521edeb67552310836@o4505757500309504.ingest.us.sentry.io/4507373697564672",
|
||||
integrations: [
|
||||
Sentry.browserTracingIntegration(),
|
||||
Sentry.replayIntegration(),
|
||||
],
|
||||
tracesSampleRate: 1.0,
|
||||
tracePropagationTargets: ["localhost", ], // /^https:\/\/yourserver\.io\/api/,
|
||||
replaysSessionSampleRate: 0.1,
|
||||
replaysOnErrorSampleRate: 1.0,
|
||||
});
|
||||
ReactDOM.createRoot(document.getElementById('root')!).render(
|
||||
<App/>,
|
||||
// <React.StrictMode></React.StrictMode>,
|
||||
|
@ -27,9 +27,9 @@ const SubmitContainer = styled.div({
|
||||
margin: '70px auto 20px'
|
||||
})
|
||||
|
||||
const LoginURL = getAppUrl() + '/login?action=auth'
|
||||
const AuthLogin = () => {
|
||||
const {login, mockLogin} = useAuth();
|
||||
const LoginURL = getAppUrl() + '/login/auth'
|
||||
const AuthLogin = ({type}:{type?:'auth'|'login'}) => {
|
||||
const {login, mockLogin,user} = useAuth();
|
||||
const navigate = useNavigate();
|
||||
const [state, setState] = useSetState({
|
||||
showLogin: false,
|
||||
@ -40,11 +40,19 @@ const AuthLogin = () => {
|
||||
const {appName} = useConfig()
|
||||
const [query] = useSearchParams()
|
||||
|
||||
useEffect(()=>{
|
||||
if(user){
|
||||
navigate('/dashboard')
|
||||
}
|
||||
},[user]);
|
||||
|
||||
useEffect(() => {
|
||||
const code = query.get('code'),
|
||||
state = query.get('state');
|
||||
|
||||
if (query.get('action') == 'auth' && state && code) {
|
||||
if(user){
|
||||
return;
|
||||
}
|
||||
if (type == 'auth' && state && code) {
|
||||
setState({loading: true})
|
||||
// 授权回调
|
||||
login(code, state).then(() => {
|
||||
|
@ -2,13 +2,13 @@ import {BillList} from "@/components/bill/list.tsx";
|
||||
import {Button, Modal, Notification, Popconfirm, Space} from "@douyinfe/semi-ui";
|
||||
import {useState} from "react";
|
||||
import {useRequest} from "ahooks";
|
||||
import {useTranslation} from "react-i18next";
|
||||
|
||||
import SearchForm from "@/components/bill/search-form.tsx";
|
||||
import BillDetail from "@/components/bill/detail.tsx";
|
||||
import {billList, BillQueryParams, cancelBill} from "@/service/api/bill.ts";
|
||||
import {BillStatus} from "@/service/types.ts";
|
||||
import {useDownloadReceiptPDF} from "@/service/generate-pdf.ts";
|
||||
import {useTranslation} from "react-i18next";
|
||||
|
||||
const BillQuery = () => {
|
||||
const [showBill, setShowBill] = useState<BillModel>()
|
||||
@ -51,8 +51,11 @@ const BillQuery = () => {
|
||||
<BillList
|
||||
type={'query'} loading={loading}
|
||||
operationRender={operation} source={data}
|
||||
onPageChange={function (): void {
|
||||
throw new Error("Function not implemented.");
|
||||
onPageChange={(page_number) =>{
|
||||
setBillQueryParams({
|
||||
...queryParams,
|
||||
page_number
|
||||
})
|
||||
}}
|
||||
/>
|
||||
<Modal
|
||||
|
@ -46,13 +46,13 @@ const BillReconciliation = () => {
|
||||
)} loading={loading} onSearch={setBillQueryParams}/>
|
||||
<BillList
|
||||
source={data} type={'reconciliation'}
|
||||
operationRender={queryParams.apply_status == 'confirmed' ? undefined : operation}
|
||||
onRowSelection={queryParams.apply_status == 'confirmed' ? undefined : (keys: (number|string)[]) => {
|
||||
operationRender={queryParams.apply_status == 'CHECKED' ? undefined : operation}
|
||||
onRowSelection={queryParams.apply_status == 'CHECKED' ? undefined : (keys: (number|string)[]) => {
|
||||
setSelectedKeys(keys);
|
||||
}}
|
||||
loading={loading}
|
||||
onPageChange={(page_number) => setBillQueryParams({page_number})}
|
||||
tableFooter={queryParams.apply_status != 'confirmed' && selectKeys?.length > 0 && (
|
||||
tableFooter={queryParams.apply_status != 'CHECKED' && selectKeys?.length > 0 && (
|
||||
<Popconfirm
|
||||
title={'Notice'}
|
||||
content={`${t('bill.cancel_confirm_bills')}?`}
|
||||
|
@ -28,12 +28,12 @@ export const StartAsiaPay: React.FC<{ bill: BillModel }> = ({bill}) => {
|
||||
<input type="hidden" name="merchantId" value={state.pay?.merchantId || ''}/>
|
||||
{/*state.pay?.payment_amount || */}
|
||||
<input type="hidden" name="amount" value={'0.01'}/>
|
||||
<input type="hidden" name="orderRef" value={`hkchc-pay-${bill.id}-${Date.now().toString(16)}`}/>
|
||||
<input type="hidden" name="orderRef" value={state.pay?.merchant_ref}/>
|
||||
<input type="hidden" name="currCode" value={state.pay?.currCode || ''}/>
|
||||
<input type="hidden" name="mpsMode" value={state.pay?.mpsMode || ''}/>
|
||||
<input type="hidden" name="successUrl" value={`${appUrl}/pay/success?from=asia_pay&bill=${bill.id}`}/>
|
||||
<input type="hidden" name="failUrl" value={`${appUrl}/pay/fail?from=asia_pay&bill=${bill.id}`}/>
|
||||
<input type="hidden" name="cancelUrl" value={`${appUrl}/pay/cancel?from=asia_pay&bill=${bill.id}`}/>
|
||||
<input type="hidden" name="successUrl" value={`${appUrl}/pay/success?from=ASIAPAY&bill=${bill.id}`}/>
|
||||
<input type="hidden" name="failUrl" value={`${appUrl}/pay/fail?from=ASIAPAY&bill=${bill.id}`}/>
|
||||
<input type="hidden" name="cancelUrl" value={`${appUrl}/pay/cancel?from=ASIAPAY&bill=${bill.id}`}/>
|
||||
<input type="hidden" name="payType" value={state.pay?.payType || ''}/>
|
||||
<input type="hidden" name="lang" value={lang || ''}/>
|
||||
<input type="hidden" name="payMethod" value={state.pay?.payMethod || ''}/>
|
||||
|
@ -13,11 +13,7 @@ import {updateBillPaymentSuccess} from "@/service/api/bill.ts";
|
||||
|
||||
type PayResult = 'fail' | 'success' | 'cancel' | 'error' | string;
|
||||
|
||||
function updateBillSuccess(billId: number, type: string, ref: string) {
|
||||
updateBillPaymentSuccess(billId, ref, type).then(res => {
|
||||
console.log(res)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
const PayIndex = () => {
|
||||
const {t} = useTranslation()
|
||||
@ -31,6 +27,13 @@ const PayIndex = () => {
|
||||
}>({});
|
||||
const param = useParams<{ result: PayResult }>();
|
||||
const [search] = useSearchParams(); // 参数有: from: asia_spay || flywire
|
||||
const updateBillSuccess = (billId: number, type: string, ref: string) =>{
|
||||
updateBillPaymentSuccess(billId, ref, type).then(bill => {
|
||||
setState({bill})
|
||||
}).finally(()=>{
|
||||
setState({result:'fail'})
|
||||
})
|
||||
}
|
||||
useEffect(() => {
|
||||
const result = param.result,
|
||||
from = search.get('from'),
|
||||
@ -44,7 +47,7 @@ const PayIndex = () => {
|
||||
return;
|
||||
}
|
||||
if (result == 'success') {
|
||||
updateBillSuccess(Number(bill), from, (from == 'asia_pay' ? search.get('Ref')! : search.get('callback_id')!));
|
||||
updateBillSuccess(Number(bill), from , (from == 'asia_pay' ? search.get('Ref')! : search.get('callback_id')!));
|
||||
}
|
||||
}
|
||||
setState({result, status})
|
||||
|
@ -34,7 +34,11 @@ const routes: RouteObject[] = [
|
||||
},
|
||||
{
|
||||
path: 'login',
|
||||
element: <AuthLogin/>
|
||||
element: <AuthLogin type={'login'}/>
|
||||
},
|
||||
{
|
||||
path: 'login/auth',
|
||||
element: <AuthLogin type={'auth'}/>
|
||||
},
|
||||
{
|
||||
path: 'pay',
|
||||
|
@ -8,7 +8,7 @@ import AppLogo from "@/assets/AppLogo.tsx";
|
||||
import useAuth from "@/hooks/useAuth.ts";
|
||||
import {I18nSwitcher} from "@/i18n";
|
||||
import {AllDashboardMenu, DashboardNavigation} from "@/routes/layout/dashboard-navigation.tsx";
|
||||
import {IconExit} from "@douyinfe/semi-icons";
|
||||
import {IconExit, IconUser} from "@douyinfe/semi-icons";
|
||||
import styled from "@emotion/styled";
|
||||
import useConfig from "@/hooks/useConfig.ts";
|
||||
|
||||
@ -36,12 +36,12 @@ export const HeaderUserAvatar = () => {
|
||||
<>
|
||||
<HeaderUserProfile>
|
||||
<Space>
|
||||
<Avatar color="orange" size="small">{user?.username.substring(0, 3)}</Avatar>
|
||||
<Avatar color="orange" size="small"><IconUser /></Avatar>
|
||||
<div>
|
||||
<Typography.Title heading={6}>{user?.username}</Typography.Title>
|
||||
<Typography.Text
|
||||
type="quaternary"
|
||||
size={'small'}>{user?.iss?.toUpperCase()}</Typography.Text>
|
||||
size={'small'}>Department:{user?.department?.toUpperCase()}</Typography.Text>
|
||||
</div>
|
||||
</Space>
|
||||
</HeaderUserProfile>
|
||||
@ -53,7 +53,7 @@ export const HeaderUserAvatar = () => {
|
||||
}
|
||||
>
|
||||
|
||||
<Avatar color="orange" size="small">{user?.username.substring(0, 3)}</Avatar>
|
||||
<Avatar color="orange" size="small"><IconUser /></Avatar>
|
||||
</Dropdown>)
|
||||
}
|
||||
export const CommonHeader: React.FC<CommonHeaderProps> = ({children, title, rightExtra}) => {
|
||||
|
@ -33,7 +33,7 @@ export function DashboardNavigation() {
|
||||
if (!user) return [];
|
||||
|
||||
return AllDashboardMenu.filter(it => {
|
||||
return !it.role || it.role.includes(user.iss)
|
||||
return !it.role || it.role.includes(user.department)
|
||||
});
|
||||
}, [user])
|
||||
return (<div className={'dashboard-menu-container'}>
|
||||
|
@ -3,6 +3,7 @@ import {get, post, put} from "@/service/request.ts";
|
||||
export type BillQueryResult = {
|
||||
result: BillModel[];
|
||||
total_count: number;
|
||||
query_total_count: number;
|
||||
query_total_amount: number;
|
||||
}
|
||||
export type BillQueryParams = Partial<BillQueryParam>;
|
||||
@ -13,7 +14,7 @@ function formatBillQueryResult(params: BillQueryParams, result: BillQueryResult)
|
||||
const formatData: RecordList<BillModel> = {
|
||||
list: result.result,
|
||||
pagination: {
|
||||
total: result.total_count,
|
||||
total: result.query_total_count,
|
||||
pageSize: params.page_size || DEFAULT_PAGE_SIZE,
|
||||
current: params.page_number || 1,
|
||||
recordTotal: Number(result.query_total_amount || 0)
|
||||
@ -50,6 +51,6 @@ export function confirmBills(bill_ids: number[]) {
|
||||
return post(`/bills/apply`, {bill_ids})
|
||||
}
|
||||
|
||||
export function updateBillPaymentSuccess(billId: number, merchant_ref: string,payment_channel:string) {
|
||||
return post(`/bills/${billId}/finish`, {merchant_ref,payment_channel})
|
||||
export function updateBillPaymentSuccess(bill_id: number, merchant_ref: string,payment_channel:string) {
|
||||
return post<BillModel>(`/bills/finish`, {merchant_ref,payment_channel,bill_id})
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {get} from "@/service/request.ts";
|
||||
import {get,post} from "@/service/request.ts";
|
||||
|
||||
export function getUserInfo() {
|
||||
return get<UserProfile>('/userinfo')
|
||||
@ -10,5 +10,5 @@ export function getUserInfo() {
|
||||
* @param state
|
||||
*/
|
||||
export function auth(code:string,state:string){
|
||||
return get<UserProfile>('/auth', {code, state})
|
||||
return post<UserProfile>('/auth', {code, state})
|
||||
}
|
@ -35,7 +35,7 @@ export function GeneratePdf(bill: BillModel) {
|
||||
title: 'Programme:',
|
||||
content: bill.programme_english_name
|
||||
}, 56)
|
||||
drawItem(doc, {title: 'Mode of Study:', content: 'FULL-TIME'}, 70)
|
||||
drawItem(doc, {title: 'Mode of Study:', content: bill.attendance_mode}, 70)
|
||||
// draw table
|
||||
autoTable(doc, {
|
||||
startY: 80,
|
||||
@ -69,7 +69,7 @@ export function GeneratePdf(bill: BillModel) {
|
||||
colSpan: 4,
|
||||
content: 'TOTAL:',
|
||||
styles: {valign: 'middle', halign: 'right'},
|
||||
}, `${bill.payment_amount}`],
|
||||
}, `${bill.amount}`],
|
||||
],
|
||||
})
|
||||
// draw foot
|
||||
|
@ -17,7 +17,7 @@ const Axios = axios.create({
|
||||
Axios.interceptors.request.use(config => {
|
||||
const token = getAuthToken();
|
||||
if (token) {
|
||||
config.headers['Authorization'] = `Bearer ${token}`;
|
||||
config.headers['Token'] = `${token}`;
|
||||
}
|
||||
if (config.data && config.data instanceof FormData) {
|
||||
config.headers['Content-Type'] = 'multipart/form-data';
|
||||
|
3
src/types/auth.d.ts
vendored
3
src/types/auth.d.ts
vendored
@ -2,12 +2,13 @@ declare type UserProfile = {
|
||||
id: string | number;
|
||||
token: string;
|
||||
email: string;
|
||||
username: string;
|
||||
department: string;
|
||||
exp: number;
|
||||
iat: number;
|
||||
iss: string;
|
||||
nbf: number;
|
||||
type: string;
|
||||
username: string;
|
||||
}
|
||||
|
||||
declare interface AuthProps {
|
||||
|
7
src/types/bill.d.ts
vendored
7
src/types/bill.d.ts
vendored
@ -22,9 +22,11 @@ declare type BillQueryParam = {
|
||||
status:string;
|
||||
apply_status:string;
|
||||
student_number:string;
|
||||
payment_method:string;
|
||||
application_number:string;
|
||||
payment_channel:string;
|
||||
start_date:string;
|
||||
end_date:string;
|
||||
department:string;
|
||||
}
|
||||
/**
|
||||
* 账单模型
|
||||
@ -40,6 +42,7 @@ declare type BillModel = {
|
||||
student_english_name: string;
|
||||
programme_chinese_name: string;
|
||||
programme_english_name: string;
|
||||
attendance_mode: string;
|
||||
department_chinese_name: string;
|
||||
department_english_name: string;
|
||||
intake_year: string;
|
||||
@ -70,7 +73,7 @@ declare type AsiaPayModel = {
|
||||
amount: string;
|
||||
payment_amount: string;
|
||||
service_charge: string;
|
||||
orderRef: string;
|
||||
merchant_ref: string;
|
||||
currCode: number;
|
||||
mpsMode: string;
|
||||
payType: string;
|
||||
|
@ -14,7 +14,7 @@ export default defineConfig(({mode}) => {
|
||||
API_PREFIX: process.env.APP_API_PREFIX || '/api',
|
||||
FIY_WIRE_GATEWAY: process.env.FIY_WIRE_GATEWAY || 'https://gateway.flywire.com/v1/transfers',
|
||||
SSO_AUTH_URL: process.env.SSO_AUTH_URL || 'https://portal.chuhai.edu.hk',
|
||||
SSO_AUTH_CLIENT_KEY: process.env.AUTH_CLIENT_KEY || '',
|
||||
SSO_AUTH_CLIENT_KEY: process.env.AUTH_CLIENT_KEY || 'test_client_id',
|
||||
AUTH_TOKEN_KEY: process.env.AUTH_TOKEN_KEY || 'payment-auth-token',
|
||||
}),
|
||||
AppMode: JSON.stringify(mode)
|
||||
@ -28,7 +28,7 @@ export default defineConfig(({mode}) => {
|
||||
port:10086,
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://43.136.175.109:50000',
|
||||
target: 'http://43.136.175.109:50000', //
|
||||
changeOrigin: true,
|
||||
//rewrite: (path) => path.replace(/^\/api/, '')
|
||||
}
|
||||
|
84
yarn.lock
84
yarn.lock
@ -788,6 +788,88 @@
|
||||
resolved "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.17.2.tgz#5a2d08b81e8064b34242d5cc9973ef8dd1e60503"
|
||||
integrity sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==
|
||||
|
||||
"@sentry-internal/browser-utils@8.7.0":
|
||||
version "8.7.0"
|
||||
resolved "https://registry.npmmirror.com/@sentry-internal/browser-utils/-/browser-utils-8.7.0.tgz#8a75560c80c50e023db58faf055dacde670e9d78"
|
||||
integrity sha512-RFBK1sYBwV5qGMEwWF0rjOTqQpp4/SvE+qHkOJNRUTVYmfjM+Y9lcxwn4B6lu3aboxePpBw/i1PlP6XwX4UnGA==
|
||||
dependencies:
|
||||
"@sentry/core" "8.7.0"
|
||||
"@sentry/types" "8.7.0"
|
||||
"@sentry/utils" "8.7.0"
|
||||
|
||||
"@sentry-internal/feedback@8.7.0":
|
||||
version "8.7.0"
|
||||
resolved "https://registry.npmmirror.com/@sentry-internal/feedback/-/feedback-8.7.0.tgz#fa632c70de93b9c6626951f62c732984242097d8"
|
||||
integrity sha512-qcGtWCtRB4eP7NVQoxW936oPkU4qu9otMLYELPGmOJPnuAG0lujlJXW7BucaM7ADyJgJTE75hG849bHecfnbmQ==
|
||||
dependencies:
|
||||
"@sentry/core" "8.7.0"
|
||||
"@sentry/types" "8.7.0"
|
||||
"@sentry/utils" "8.7.0"
|
||||
|
||||
"@sentry-internal/replay-canvas@8.7.0":
|
||||
version "8.7.0"
|
||||
resolved "https://registry.npmmirror.com/@sentry-internal/replay-canvas/-/replay-canvas-8.7.0.tgz#78316619cc57b8d81cacabacdf0f5167eb805ef9"
|
||||
integrity sha512-FOnvBPbq6MJVHPduc0hcsdE3PeeovQ2z5WJnZDGhvp/Obehxqe+XgX7K/595vRIknv4EokRn/3Kw0mFwG8E+ZQ==
|
||||
dependencies:
|
||||
"@sentry-internal/replay" "8.7.0"
|
||||
"@sentry/core" "8.7.0"
|
||||
"@sentry/types" "8.7.0"
|
||||
"@sentry/utils" "8.7.0"
|
||||
|
||||
"@sentry-internal/replay@8.7.0":
|
||||
version "8.7.0"
|
||||
resolved "https://registry.npmmirror.com/@sentry-internal/replay/-/replay-8.7.0.tgz#2898303529bb2273129e2e86c861d03f69e95622"
|
||||
integrity sha512-bQzOkWplaWTe3u+aDBhxWY3Qy0aT7ss2A3VR8iC6N8ZIEP9PxqyJwTNoouhinfgmlnCguI7RDOO4f3r3e2M80Q==
|
||||
dependencies:
|
||||
"@sentry-internal/browser-utils" "8.7.0"
|
||||
"@sentry/core" "8.7.0"
|
||||
"@sentry/types" "8.7.0"
|
||||
"@sentry/utils" "8.7.0"
|
||||
|
||||
"@sentry/browser@8.7.0":
|
||||
version "8.7.0"
|
||||
resolved "https://registry.npmmirror.com/@sentry/browser/-/browser-8.7.0.tgz#78844ca196315327979ef7cfbad71788e95c9888"
|
||||
integrity sha512-4EEp+PlcktsMN0p+MdCPl/lghTkq7eOtZjQG9NGhWzfyWrJ3tuL1nsDr2SSivJ1V277F01KtKYo6BFwP2NtBZA==
|
||||
dependencies:
|
||||
"@sentry-internal/browser-utils" "8.7.0"
|
||||
"@sentry-internal/feedback" "8.7.0"
|
||||
"@sentry-internal/replay" "8.7.0"
|
||||
"@sentry-internal/replay-canvas" "8.7.0"
|
||||
"@sentry/core" "8.7.0"
|
||||
"@sentry/types" "8.7.0"
|
||||
"@sentry/utils" "8.7.0"
|
||||
|
||||
"@sentry/core@8.7.0":
|
||||
version "8.7.0"
|
||||
resolved "https://registry.npmmirror.com/@sentry/core/-/core-8.7.0.tgz#c98bc47020cd48d899806baaebc7a4b6fe10b9ab"
|
||||
integrity sha512-Sq/46B+5nWmgnCD6dEMZ6HTkKbV/KAdgaSvT8oXDb9OWoPy1jJ/gbLrhLs62KbjuDQk4/vWnOgHiKQbcslSzMw==
|
||||
dependencies:
|
||||
"@sentry/types" "8.7.0"
|
||||
"@sentry/utils" "8.7.0"
|
||||
|
||||
"@sentry/react@^8.7.0":
|
||||
version "8.7.0"
|
||||
resolved "https://registry.npmmirror.com/@sentry/react/-/react-8.7.0.tgz#fc3f4303abb2ccd1e23f75f9f5bb6e648e095fa0"
|
||||
integrity sha512-JFo8QW8JB4eaFC8RdkOBO96JvlGgstywmyMZ39qWfFbD735vGl8PnOa0AnrC/5Auc86dZ98/I4OEPboqUE9q1w==
|
||||
dependencies:
|
||||
"@sentry/browser" "8.7.0"
|
||||
"@sentry/core" "8.7.0"
|
||||
"@sentry/types" "8.7.0"
|
||||
"@sentry/utils" "8.7.0"
|
||||
hoist-non-react-statics "^3.3.2"
|
||||
|
||||
"@sentry/types@8.7.0":
|
||||
version "8.7.0"
|
||||
resolved "https://registry.npmmirror.com/@sentry/types/-/types-8.7.0.tgz#92731af32318d6abb8759216cf6c3c5035894e6e"
|
||||
integrity sha512-11KLOKumP6akugVGLvSoEig+JlP0ZEzW3nN9P+ppgdIx9HAxMIh6UvumbieG4/DWjAh2kh6NPNfUw3gk2Gfq1A==
|
||||
|
||||
"@sentry/utils@8.7.0":
|
||||
version "8.7.0"
|
||||
resolved "https://registry.npmmirror.com/@sentry/utils/-/utils-8.7.0.tgz#26893acc5bca9bfd4998d2eafe724491e3ca78a2"
|
||||
integrity sha512-aWmcbSoOmrbzll/FkNQFJcCtLAuJLvTYbRKiCSkV3FScA7UaA742HkTZAPFiioALFIESWk/fcGZqtN0s4I281Q==
|
||||
dependencies:
|
||||
"@sentry/types" "8.7.0"
|
||||
|
||||
"@types/babel__core@^7.20.5":
|
||||
version "7.20.5"
|
||||
resolved "https://registry.npmmirror.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017"
|
||||
@ -1763,7 +1845,7 @@ hasown@^2.0.0:
|
||||
dependencies:
|
||||
function-bind "^1.1.2"
|
||||
|
||||
hoist-non-react-statics@^3.3.1:
|
||||
hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2:
|
||||
version "3.3.2"
|
||||
resolved "https://registry.npmmirror.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
|
||||
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
|
||||
|
Loading…
x
Reference in New Issue
Block a user