Compare commits
No commits in common. "main-new" and "main" have entirely different histories.
@ -32,13 +32,13 @@ WORKDIR /app
|
|||||||
ENV APP_API_URL localhost:50000
|
ENV APP_API_URL localhost:50000
|
||||||
|
|
||||||
# nginx配置文件
|
# nginx配置文件
|
||||||
#COPY nginx.conf /etc/nginx/conf.d/default.conf.template
|
COPY nginx.conf /etc/nginx/conf.d/default.conf.template
|
||||||
# 编译文件
|
# 编译文件
|
||||||
COPY --from=builder /app/dist ./
|
COPY --from=builder /app/dist ./
|
||||||
# RUN /bin/sh envsubst /etc/nginx/templates/*.template /etc/nginx/conf.d
|
# RUN /bin/sh envsubst /etc/nginx/templates/*.template /etc/nginx/conf.d
|
||||||
#WORKDIR /etc/nginx/conf.d/
|
WORKDIR /etc/nginx/conf.d/
|
||||||
#ENTRYPOINT sed -i "s~<!--app_url-->~<script>const APP_SITE_URL='${APP_SITE_URL}';</script>~" /app/index.html && envsubst '$APP_API_URL' < default.conf.template > default.conf && cat default.conf && nginx -g 'daemon off;'
|
ENTRYPOINT sed -i "s~<!--app_url-->~<script>const APP_SITE_URL='${APP_SITE_URL}';</script>~" /app/index.html && envsubst '$APP_API_URL' < default.conf.template > default.conf && cat default.conf && nginx -g 'daemon off;'
|
||||||
# 暴露80端口
|
# 暴露80端口
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
# 启动Nginx服务
|
# 启动Nginx服务
|
||||||
CMD ["nginx", "-g", "daemon off;"]
|
# CMD ["nginx", "-g", "daemon off;"]
|
@ -15,12 +15,13 @@ services:
|
|||||||
hkchc-payment-frontend-server:
|
hkchc-payment-frontend-server:
|
||||||
image: registry.hkchc.team/hkchc-payment-frontend:latest
|
image: registry.hkchc.team/hkchc-payment-frontend:latest
|
||||||
container_name: hkchc-payment-frontend
|
container_name: hkchc-payment-frontend
|
||||||
volumes:
|
environment:
|
||||||
- ./nginx.conf:/etc/nginx/conf.d/default.conf
|
APP_API_URL: "10.10.0.152:50000" # payment backend service
|
||||||
working_dir: /etc/nginx/conf.d/
|
working_dir: /etc/nginx/conf.d/
|
||||||
ports:
|
ports:
|
||||||
- "50001:80"
|
- "50001:80"
|
||||||
command: [
|
command: [
|
||||||
|
"sed -i \"s~<!--app_url-->~<script>const APP_SITE_URL='${APP_SITE_URL}';</script>~\" /app/index.html && envsubst '$APP_API_URL' < default.conf.template > default.conf && cat default.conf",
|
||||||
"nginx -g daemon off;"
|
"nginx -g daemon off;"
|
||||||
]
|
]
|
||||||
<<: *common
|
<<: *common
|
@ -1,12 +1,15 @@
|
|||||||
export const AppConfig: {
|
export const AppConfig: {
|
||||||
[key:string]: {
|
[key:string]: {
|
||||||
|
ldapApiUrl: string,
|
||||||
ldapApiKey: string
|
ldapApiKey: string
|
||||||
}
|
}
|
||||||
} = {
|
} = {
|
||||||
default:{
|
default:{
|
||||||
|
ldapApiUrl: 'https://test-api.hkchc.team',
|
||||||
ldapApiKey: 'MPCbsNa6l2RJ7D1Zo6D03qtVF1P93st3'
|
ldapApiKey: 'MPCbsNa6l2RJ7D1Zo6D03qtVF1P93st3'
|
||||||
},
|
},
|
||||||
production:{
|
production:{
|
||||||
ldapApiKey: 'NFIgLIzvmL0ENQeeIDJu5Z7MEp5TjhlE'
|
ldapApiUrl: 'https://test-api.hkchc.team',
|
||||||
|
ldapApiKey: 'MPCbsNa6l2RJ7D1Zo6D03qtVF1P93st3'
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,3 +1,7 @@
|
|||||||
|
upstream payment_backend {
|
||||||
|
server $APP_API_URL;
|
||||||
|
}
|
||||||
|
|
||||||
server {
|
server {
|
||||||
listen 80;
|
listen 80;
|
||||||
listen [::]:80;
|
listen [::]:80;
|
||||||
@ -22,7 +26,7 @@ server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
location ^~/api {
|
location ^~/api {
|
||||||
proxy_pass http://localhost:30000;
|
proxy_pass http://payment_backend;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
@ -45,6 +49,7 @@ server {
|
|||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_set_header REMOTE-HOST $remote_addr;
|
proxy_set_header REMOTE-HOST $remote_addr;
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection $connection_upgrade;
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
# proxy_hide_header Upgrade;
|
# proxy_hide_header Upgrade;
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import {Button, Checkbox, CheckboxGroup, Space, Table, Tag, Typography} from "@douyinfe/semi-ui";
|
import {Button, Checkbox, CheckboxGroup, Space, Table, Tag, Typography} from "@douyinfe/semi-ui";
|
||||||
import {ColumnProps} from "@douyinfe/semi-ui/lib/es/table";
|
import {ColumnProps} from "@douyinfe/semi-ui/lib/es/table";
|
||||||
import React, {ReactNode, useEffect, useMemo, useState} from "react";
|
import React, {ReactNode, useMemo, useState} from "react";
|
||||||
import {useTranslation} from "react-i18next";
|
import {useTranslation} from "react-i18next";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import {IconCheckCircleStroked, IconSetting, IconTickCircle} from "@douyinfe/semi-icons";
|
import {IconCheckCircleStroked, IconSetting, IconTickCircle} from "@douyinfe/semi-icons";
|
||||||
@ -20,7 +20,6 @@ type BillListProps = {
|
|||||||
rowSelectionDisabled?: (record: BillModel) => boolean;
|
rowSelectionDisabled?: (record: BillModel) => boolean;
|
||||||
source?: RecordList<BillModel>;
|
source?: RecordList<BillModel>;
|
||||||
onPageChange: (pageIndex: number) => void;
|
onPageChange: (pageIndex: number) => void;
|
||||||
onPageSizeChange: (pageSize:number) => void;
|
|
||||||
tableFooter?: React.ReactNode;
|
tableFooter?: React.ReactNode;
|
||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
beforeTotalAmount?: React.ReactNode;
|
beforeTotalAmount?: React.ReactNode;
|
||||||
@ -41,15 +40,13 @@ export const BillList: React.FC<BillListProps> = (props) => {
|
|||||||
const [currentTotalAmount, setCurrentTotalAmount] = useState(0)
|
const [currentTotalAmount, setCurrentTotalAmount] = useState(0)
|
||||||
const [state, setState] = useSetState<{
|
const [state, setState] = useSetState<{
|
||||||
showColumnsConfig?: boolean;
|
showColumnsConfig?: boolean;
|
||||||
showCols: string[];
|
showCols: string[]
|
||||||
selectedKeys: string[];
|
|
||||||
}>({
|
}>({
|
||||||
showCols: [
|
showCols: [
|
||||||
"id", "merchant_ref", "student_number", "application_number", 'confirm_status', "initiated_paid_at", "delivered_at",
|
"id", "merchant_ref", "student_number", "application_number", 'confirm_status', "initiated_paid_at", "delivered_at",
|
||||||
"paid_at", "student_english_name", "student_email", "programme_english_name","department_english_name",
|
"paid_at", "student_english_name", "student_email", "programme_english_name","department_english_name",
|
||||||
"intake_year", "detail", "detail_confirms", "amount", "pay_amount", "actual_payment_amount", "pay_method", "status", "apply_status"
|
"intake_year", "detail", "detail_confirms", "amount", "pay_amount", "actual_payment_amount", "pay_method", "status", "apply_status"
|
||||||
],
|
]
|
||||||
selectedKeys:[]
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const billStatusText = (billStatus: string) => {
|
const billStatusText = (billStatus: string) => {
|
||||||
@ -89,7 +86,7 @@ export const BillList: React.FC<BillListProps> = (props) => {
|
|||||||
title: 'Merchant Ref',
|
title: 'Merchant Ref',
|
||||||
dataIndex: 'merchant_ref',
|
dataIndex: 'merchant_ref',
|
||||||
width: 200,
|
width: 200,
|
||||||
render: (value: string) => (value || 'N/A')
|
// render: (_) => (<MoneyFormat money={_}/>),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('base.student_number'),
|
title: t('base.student_number'),
|
||||||
@ -146,7 +143,7 @@ export const BillList: React.FC<BillListProps> = (props) => {
|
|||||||
title: t('bill.title_student_name'),
|
title: t('bill.title_student_name'),
|
||||||
dataIndex: 'student_english_name',
|
dataIndex: 'student_english_name',
|
||||||
width: 180,
|
width: 180,
|
||||||
render: (_, record) => _?(<div>{record.student_english_name}<br/>{record.student_chinese_name}</div>):'N/A'
|
render: (_, record) => (<div>{record.student_english_name}<br/>{record.student_chinese_name}</div>)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Email',
|
title: 'Email',
|
||||||
@ -159,14 +156,14 @@ export const BillList: React.FC<BillListProps> = (props) => {
|
|||||||
title: t('bill.title_program_name'),
|
title: t('bill.title_program_name'),
|
||||||
dataIndex: 'programme_english_name',
|
dataIndex: 'programme_english_name',
|
||||||
width: 250,
|
width: 250,
|
||||||
render: (_, record) => _?(i18n.language == 'en-US' ? record.programme_english_name : record.programme_chinese_name):'N/A',
|
render: (_, record) => (i18n.language == 'en-US' ? record.programme_english_name : record.programme_chinese_name),
|
||||||
// dataIndex: i18n.language == 'en-US' ? 'programme_english_name' : 'programme_chinese_name',
|
// dataIndex: i18n.language == 'en-US' ? 'programme_english_name' : 'programme_chinese_name',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('bill.title_department'),
|
title: t('bill.title_department'),
|
||||||
width: 200,
|
width: 200,
|
||||||
dataIndex: 'department_english_name',
|
dataIndex: 'department_english_name',
|
||||||
render: (_, record) => _?(i18n.language == 'en-US' ? record.department_english_name : record.department_chinese_name):'N/A',
|
render: (_, record) => (i18n.language == 'en-US' ? record.department_english_name : record.department_chinese_name),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('bill.title_year'),
|
title: t('bill.title_year'),
|
||||||
@ -201,7 +198,7 @@ export const BillList: React.FC<BillListProps> = (props) => {
|
|||||||
dataIndex: 'detail_confirms',
|
dataIndex: 'detail_confirms',
|
||||||
ellipsis: {showTitle: true},
|
ellipsis: {showTitle: true},
|
||||||
width: 220,
|
width: 220,
|
||||||
render: (_, record) => record.detail_confirms?(<div style={{
|
render: (_, record) => (<div style={{
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
lineHeight: 1.2,
|
lineHeight: 1.2,
|
||||||
wordBreak: 'break-all',
|
wordBreak: 'break-all',
|
||||||
@ -210,7 +207,7 @@ export const BillList: React.FC<BillListProps> = (props) => {
|
|||||||
}}>
|
}}>
|
||||||
{record.detail_confirms?.map((it) => (
|
{record.detail_confirms?.map((it) => (
|
||||||
<div key={it.id}>{it.bill_type}: <MoneyFormat money={it.amount}/></div>))}
|
<div key={it.id}>{it.bill_type}: <MoneyFormat money={it.amount}/></div>))}
|
||||||
</div>):'N/A',
|
</div>),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('bill.title_amount'),
|
title: t('bill.title_amount'),
|
||||||
@ -304,11 +301,6 @@ export const BillList: React.FC<BillListProps> = (props) => {
|
|||||||
setCurrentTotalAmount(_total)
|
setCurrentTotalAmount(_total)
|
||||||
return originList;
|
return originList;
|
||||||
}, [props.source])
|
}, [props.source])
|
||||||
useEffect(()=>{
|
|
||||||
setState({
|
|
||||||
selectedKeys:[]
|
|
||||||
})
|
|
||||||
},[currentList])
|
|
||||||
|
|
||||||
return <Card
|
return <Card
|
||||||
title={<Space>
|
title={<Space>
|
||||||
@ -364,10 +356,7 @@ export const BillList: React.FC<BillListProps> = (props) => {
|
|||||||
currentPage: props.source?.pagination.current,
|
currentPage: props.source?.pagination.current,
|
||||||
pageSize: props.source?.pagination.pageSize,
|
pageSize: props.source?.pagination.pageSize,
|
||||||
total: props.source?.pagination.total,
|
total: props.source?.pagination.total,
|
||||||
pageSizeOpts:[10,20,50],
|
|
||||||
showSizeChanger:true,
|
|
||||||
onPageChange: props.onPageChange,
|
onPageChange: props.onPageChange,
|
||||||
onPageSizeChange: props.onPageSizeChange,
|
|
||||||
formatPageText: (params) => (
|
formatPageText: (params) => (
|
||||||
<div className="bill-list-pagination">
|
<div className="bill-list-pagination">
|
||||||
{props.tableFooter}
|
{props.tableFooter}
|
||||||
@ -379,9 +368,7 @@ export const BillList: React.FC<BillListProps> = (props) => {
|
|||||||
loading={props.loading}
|
loading={props.loading}
|
||||||
rowSelection={props.onRowSelection ? {
|
rowSelection={props.onRowSelection ? {
|
||||||
fixed: true,
|
fixed: true,
|
||||||
selectedRowKeys: state.selectedKeys,
|
|
||||||
onChange: (selectedRowKeys) => {
|
onChange: (selectedRowKeys) => {
|
||||||
setState({selectedKeys: selectedRowKeys as string[]})
|
|
||||||
selectedRowKeys && props.onRowSelection?.(selectedRowKeys)
|
selectedRowKeys && props.onRowSelection?.(selectedRowKeys)
|
||||||
},
|
},
|
||||||
getCheckboxProps: (record) => {
|
getCheckboxProps: (record) => {
|
||||||
|
@ -138,11 +138,11 @@ const SearchForm: React.FC<SearchFormProps> = (props) => {
|
|||||||
<Form.Select.Option value="student_number asc">{t('base.student_number')} {t('bill.sort_asc')}</Form.Select.Option>
|
<Form.Select.Option value="student_number asc">{t('base.student_number')} {t('bill.sort_asc')}</Form.Select.Option>
|
||||||
<Form.Select.Option value="application_number desc">{t('base.bill_number')} {t('bill.sort_desc')}</Form.Select.Option>
|
<Form.Select.Option value="application_number desc">{t('base.bill_number')} {t('bill.sort_desc')}</Form.Select.Option>
|
||||||
<Form.Select.Option value="application_number asc">{t('base.bill_number')} {t('bill.sort_asc')}</Form.Select.Option>
|
<Form.Select.Option value="application_number asc">{t('base.bill_number')} {t('bill.sort_asc')}</Form.Select.Option>
|
||||||
<Form.Select.Option value="initiated_paid_at desc">{t('bill.title_initiated_paid_at')} {t('bill.sort_desc')}</Form.Select.Option>
|
<Form.Select.Option value="paid_at desc">{t('bill.title_paid_at')} {t('bill.sort_desc')}</Form.Select.Option>
|
||||||
<Form.Select.Option value="initiated_paid_at asc">{t('bill.title_initiated_paid_at')} {t('bill.sort_asc')}</Form.Select.Option>
|
<Form.Select.Option value="paid_at asc">{t('bill.title_paid_at')} {t('bill.sort_asc')}</Form.Select.Option>
|
||||||
|
|
||||||
<Form.Select.Option value="delivered_at desc">{t('bill.title_delivered_at')} {t('bill.sort_desc')}</Form.Select.Option>
|
<Form.Select.Option value="create_at desc">{t('bill.title_create_at')} {t('bill.sort_desc')}</Form.Select.Option>
|
||||||
<Form.Select.Option value="delivered_at asc">{t('bill.title_delivered_at')} {t('bill.sort_asc')}</Form.Select.Option>
|
<Form.Select.Option value="create_at asc">{t('bill.title_create_at')} {t('bill.sort_asc')}</Form.Select.Option>
|
||||||
</Form.Select>
|
</Form.Select>
|
||||||
</Col>
|
</Col>
|
||||||
<Col xxl={4} xl={6} md={8}>
|
<Col xxl={4} xl={6} md={8}>
|
||||||
@ -153,16 +153,8 @@ const SearchForm: React.FC<SearchFormProps> = (props) => {
|
|||||||
<Form.Select.Option value="PPS">PPS</Form.Select.Option>
|
<Form.Select.Option value="PPS">PPS</Form.Select.Option>
|
||||||
</Form.Select>
|
</Form.Select>
|
||||||
</Col>
|
</Col>
|
||||||
<Col xxl={4} xl={6} md={8}>
|
|
||||||
<Form.Select showClear field="is_delivered" label={t('bill.delivered_status')}
|
|
||||||
placeholder={t('base.please_select')} style={{width: '100%'}}>
|
|
||||||
<Form.Select.Option value="false">{t('bill.delivered_status_no')}</Form.Select.Option>
|
|
||||||
<Form.Select.Option value="true">{t('bill.delivered_status_yes')}</Form.Select.Option>
|
|
||||||
</Form.Select>
|
|
||||||
</Col>
|
|
||||||
<Col xxl={4} xl={6} md={8}>
|
<Col xxl={4} xl={6} md={8}>
|
||||||
<Form.Select
|
<Form.Select
|
||||||
showClear
|
|
||||||
field="confirm_bill_type" style={{width: '100%'}}
|
field="confirm_bill_type" style={{width: '100%'}}
|
||||||
label={t('manual.bill_type')}
|
label={t('manual.bill_type')}
|
||||||
placeholder={t('manual.bill_type')}
|
placeholder={t('manual.bill_type')}
|
||||||
|
@ -61,6 +61,6 @@ const formatCurrency = (currency = 'HKD') => {
|
|||||||
const MoneyFormat: React.FC<MoneyFormatProps> = ({money, currency = 'HKD'}) => {
|
const MoneyFormat: React.FC<MoneyFormatProps> = ({money, currency = 'HKD'}) => {
|
||||||
// 将货币数字转换为千分位格式且带2位小数
|
// 将货币数字转换为千分位格式且带2位小数
|
||||||
return (money || money == 0 || money == '0') ?
|
return (money || money == 0 || money == '0') ?
|
||||||
<span className={'money-format'}>{formatCurrency(currency)} {formatMoneyNumber(money)}</span> : 'N/A';
|
<span className={'money-format'}>{formatCurrency(currency)} {formatMoneyNumber(money)}</span> : null;
|
||||||
}
|
}
|
||||||
export default MoneyFormat;
|
export default MoneyFormat;
|
@ -17,8 +17,6 @@ export function useBillTypes(){
|
|||||||
const types = ret.filter(it=>!it.description.toUpperCase().startsWith('ADJUSTMENT'))
|
const types = ret.filter(it=>!it.description.toUpperCase().startsWith('ADJUSTMENT'))
|
||||||
.map(it=>({value: it.type, label: it.description}))
|
.map(it=>({value: it.type, label: it.description}))
|
||||||
setBillTypes(types)
|
setBillTypes(types)
|
||||||
// 避免出现多次
|
|
||||||
BillTypesCache.length = 0;
|
|
||||||
BillTypesCache.push(...types)
|
BillTypesCache.push(...types)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -35,15 +35,11 @@
|
|||||||
"confirm_bill_type": "Confirm Bill",
|
"confirm_bill_type": "Confirm Bill",
|
||||||
"confirm_bill_type_batch": "Batch confirm Bill Type",
|
"confirm_bill_type_batch": "Batch confirm Bill Type",
|
||||||
"confirm_bill_warning_amount": "The bill amount and actual payment amount are inconsistent",
|
"confirm_bill_warning_amount": "The bill amount and actual payment amount are inconsistent",
|
||||||
"confirm_bill_warning_amount_id": "The bill id({{id}}) confirmed amount and actual payment amount are inconsistent",
|
|
||||||
"confirm_confirm_title": "Confirm check and sync the Bill?",
|
"confirm_confirm_title": "Confirm check and sync the Bill?",
|
||||||
"confirm_select_empty": "Require confirm bill data",
|
"confirm_select_empty": "Require confirm bill data",
|
||||||
"confirm_student_number": "Confirm Student Number",
|
"confirm_student_number": "Confirm Student Number",
|
||||||
"confirm_success": "Confirm success!",
|
"confirm_success": "Confirm success!",
|
||||||
"confirmed": "Confirmed",
|
"confirmed": "Confirmed",
|
||||||
"delivered_status": "Delivered Status",
|
|
||||||
"delivered_status_no": "Undivided",
|
|
||||||
"delivered_status_yes": "Delivered",
|
|
||||||
"download-qr-code": "Download QR Code",
|
"download-qr-code": "Download QR Code",
|
||||||
"download_receipt": "Download receipt",
|
"download_receipt": "Download receipt",
|
||||||
"export_excel": "Export Transaction Excel",
|
"export_excel": "Export Transaction Excel",
|
||||||
|
@ -35,15 +35,11 @@
|
|||||||
"confirm_bill_type": "确认账单",
|
"confirm_bill_type": "确认账单",
|
||||||
"confirm_bill_type_batch": "批量确认账单",
|
"confirm_bill_type_batch": "批量确认账单",
|
||||||
"confirm_bill_warning_amount": "账单金额和实付金额不一致",
|
"confirm_bill_warning_amount": "账单金额和实付金额不一致",
|
||||||
"confirm_bill_warning_amount_id": "账单ID({{id}})确认金额和实付金额不一致",
|
|
||||||
"confirm_confirm_title": "请确定对账并同步此账单?",
|
"confirm_confirm_title": "请确定对账并同步此账单?",
|
||||||
"confirm_select_empty": "对账账单为空",
|
"confirm_select_empty": "对账账单为空",
|
||||||
"confirm_student_number": "确认学号",
|
"confirm_student_number": "确认学号",
|
||||||
"confirm_success": "对账成功!",
|
"confirm_success": "对账成功!",
|
||||||
"confirmed": "已对账",
|
"confirmed": "已对账",
|
||||||
"delivered_status": "分账状态",
|
|
||||||
"delivered_status_no": "未分账",
|
|
||||||
"delivered_status_yes": "已分账",
|
|
||||||
"download-qr-code": "下载二维码",
|
"download-qr-code": "下载二维码",
|
||||||
"download_receipt": "下载收据",
|
"download_receipt": "下载收据",
|
||||||
"export_excel": "导出交易记录",
|
"export_excel": "导出交易记录",
|
||||||
|
@ -34,16 +34,12 @@
|
|||||||
"confirm_bill_number": "確認帳單編號",
|
"confirm_bill_number": "確認帳單編號",
|
||||||
"confirm_bill_type": "確認賬單",
|
"confirm_bill_type": "確認賬單",
|
||||||
"confirm_bill_type_batch": "批次確認帳單",
|
"confirm_bill_type_batch": "批次確認帳單",
|
||||||
"confirm_bill_warning_amount": "帳單金額和實付金額不一致",
|
"confirm_bill_warning_amount": "账单金额和实付金额不一致",
|
||||||
"confirm_bill_warning_amount_id": "帳單ID({{id}})確認金額和實付金額不一致",
|
|
||||||
"confirm_confirm_title": "請確定對帳并同步此帳單?",
|
"confirm_confirm_title": "請確定對帳并同步此帳單?",
|
||||||
"confirm_select_empty": "對帳帳單為空",
|
"confirm_select_empty": "對帳帳單為空",
|
||||||
"confirm_student_number": "確認學號",
|
"confirm_student_number": "確認學號",
|
||||||
"confirm_success": "對帳成功!",
|
"confirm_success": "對帳成功!",
|
||||||
"confirmed": "已對帳",
|
"confirmed": "已對帳",
|
||||||
"delivered_status": "分帳狀態",
|
|
||||||
"delivered_status_no": "未分帳",
|
|
||||||
"delivered_status_yes": "已分賬",
|
|
||||||
"download-qr-code": "下載二維碼",
|
"download-qr-code": "下載二維碼",
|
||||||
"download_receipt": "下載收據",
|
"download_receipt": "下載收據",
|
||||||
"export_excel": "導出交易记录",
|
"export_excel": "導出交易记录",
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import {Button, Select, Space, Divider, InputNumber, Modal} from "@douyinfe/semi-ui";
|
import {Button, Select, Space, Divider, InputNumber, Modal,} from "@douyinfe/semi-ui";
|
||||||
import React, {useEffect} from "react";
|
import React, {useEffect} from "react";
|
||||||
import {useSetState} from "ahooks";
|
import {useSetState} from "ahooks";
|
||||||
import MoneyFormat from "@/components/money-format.tsx";
|
import MoneyFormat from "@/components/money-format.tsx";
|
||||||
@ -103,7 +103,7 @@ export const BillTypeConfirmModal: React.FC<BillTypeConfirmProps> = (props) => {
|
|||||||
const onBillConfirm = () => {
|
const onBillConfirm = () => {
|
||||||
// 判断confirm的总金额是否和实付金额相等
|
// 判断confirm的总金额是否和实付金额相等
|
||||||
const total = state.detail_confirms.reduce((total, item) => {
|
const total = state.detail_confirms.reduce((total, item) => {
|
||||||
return total + Number(item.amount)
|
return total + item.amount
|
||||||
}, 0)
|
}, 0)
|
||||||
if(total != props.bill.actual_payment_amount){
|
if(total != props.bill.actual_payment_amount){
|
||||||
Modal.warning({
|
Modal.warning({
|
||||||
@ -121,11 +121,6 @@ export const BillTypeConfirmModal: React.FC<BillTypeConfirmProps> = (props) => {
|
|||||||
...state
|
...state
|
||||||
}]).then(() => {
|
}]).then(() => {
|
||||||
props.onClose?.(true)
|
props.onClose?.(true)
|
||||||
}).catch(e=>{
|
|
||||||
Modal.error({
|
|
||||||
title: 'Error',
|
|
||||||
content: `Confirmed Fail: ${e.message}`
|
|
||||||
})
|
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
setState({loading: false})
|
setState({loading: false})
|
||||||
})
|
})
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import {Button, Modal, Popconfirm} from "@douyinfe/semi-ui";
|
import {Button, Popconfirm} from "@douyinfe/semi-ui";
|
||||||
import {useTranslation} from "react-i18next";
|
import {useTranslation} from "react-i18next";
|
||||||
import {confirmBillType} from "@/service/api/bill.ts";
|
import {confirmBillType} from "@/service/api/bill.ts";
|
||||||
import {useSetState} from "ahooks";
|
import {useSetState} from "ahooks";
|
||||||
@ -21,24 +21,7 @@ export const BillTypeConfirmBatch: React.FC<BillTypeConfirmBatchProps> = (props)
|
|||||||
}
|
}
|
||||||
const confirmBillTypeBatch = () => {
|
const confirmBillTypeBatch = () => {
|
||||||
const bills: BillConfirmParams[] = [];
|
const bills: BillConfirmParams[] = [];
|
||||||
const arr = props.data?.list.filter(item => props.selectKeys.includes(item.id));
|
props.data?.list.filter(item => props.selectKeys.includes(item.id)).forEach(item => {
|
||||||
if(!arr) return;
|
|
||||||
for (let i = 0; i < arr.length; i++) {
|
|
||||||
const item = arr[i];
|
|
||||||
if(item.confirm_status != 'UNCONFIRMED'){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// 判断confirm的总金额是否和实付金额相等
|
|
||||||
const total = item.details.reduce((total, item) => {
|
|
||||||
return total + Number(item.amount)
|
|
||||||
}, 0)
|
|
||||||
if(total != item.actual_payment_amount){
|
|
||||||
Modal.warning({
|
|
||||||
title: 'Warning',
|
|
||||||
content: t('bill.confirm_bill_warning_amount_id',{id: item.id})
|
|
||||||
})
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bills.push({
|
bills.push({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
confirm_application_number: String(item.application_number),
|
confirm_application_number: String(item.application_number),
|
||||||
@ -51,7 +34,7 @@ export const BillTypeConfirmBatch: React.FC<BillTypeConfirmBatchProps> = (props)
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
})
|
||||||
if (bills.length == 0) return;
|
if (bills.length == 0) return;
|
||||||
confirm(bills)
|
confirm(bills)
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,6 @@ import {BillTypeConfirmModal} from "@/pages/bill/components/bill_type_confirm.ts
|
|||||||
import {saveAs} from "file-saver";
|
import {saveAs} from "file-saver";
|
||||||
// import {AddBillModal} from "@/pages/bill/components/add_bill_modal.tsx";
|
// import {AddBillModal} from "@/pages/bill/components/add_bill_modal.tsx";
|
||||||
import {BillTypeConfirmBatch} from "@/pages/bill/components/bill_type_confirm_batch.tsx";
|
import {BillTypeConfirmBatch} from "@/pages/bill/components/bill_type_confirm_batch.tsx";
|
||||||
import {AddBillModal} from "@/pages/bill/components/add_bill_modal.tsx";
|
|
||||||
|
|
||||||
|
|
||||||
const DownloadButton = ({bill, text}: { bill: BillModel; text: string }) => {
|
const DownloadButton = ({bill, text}: { bill: BillModel; text: string }) => {
|
||||||
@ -42,9 +41,6 @@ const BillQuery = () => {
|
|||||||
});
|
});
|
||||||
const {data, loading, refresh} = useRequest(() => billList(queryParams), {
|
const {data, loading, refresh} = useRequest(() => billList(queryParams), {
|
||||||
refreshDeps: [queryParams],
|
refreshDeps: [queryParams],
|
||||||
onSuccess:()=>{
|
|
||||||
document.documentElement.scrollTo({top:0});
|
|
||||||
},
|
|
||||||
onError: (e) => {
|
onError: (e) => {
|
||||||
Notification.error({title: 'Error', content: e.message})
|
Notification.error({title: 'Error', content: e.message})
|
||||||
}
|
}
|
||||||
@ -129,7 +125,7 @@ const BillQuery = () => {
|
|||||||
operationRender={operation} operationRenderWidth={180}
|
operationRender={operation} operationRenderWidth={180}
|
||||||
beforeTotalAmount={<Space>
|
beforeTotalAmount={<Space>
|
||||||
<BillTypeConfirmBatch data={data} selectKeys={selectKeys} onConfirm={refresh}/>
|
<BillTypeConfirmBatch data={data} selectKeys={selectKeys} onConfirm={refresh}/>
|
||||||
<AddBillModal onConfirm={refresh}/>
|
{/*<AddBillModal onConfirm={refresh}/>*/}
|
||||||
<ButtonGroup style={{marginRight: 20}} theme={'solid'}>
|
<ButtonGroup style={{marginRight: 20}} theme={'solid'}>
|
||||||
<Button onClick={onImportExcel}>{t('bill.import_excel')}</Button>
|
<Button onClick={onImportExcel}>{t('bill.import_excel')}</Button>
|
||||||
<Button loading={state.exporting} onClick={onExportExcel}>{t('bill.export_excel')}</Button>
|
<Button loading={state.exporting} onClick={onExportExcel}>{t('bill.export_excel')}</Button>
|
||||||
@ -144,12 +140,6 @@ const BillQuery = () => {
|
|||||||
page_number
|
page_number
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
onPageSizeChange={(page_size) => {
|
|
||||||
setBillQueryParams({
|
|
||||||
...queryParams,
|
|
||||||
page_size
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
<Modal
|
<Modal
|
||||||
title="Bill Detail"
|
title="Bill Detail"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import {Button, Space, TabPane, Tabs, Popconfirm, Toast, Modal} from "@douyinfe/semi-ui";
|
import {Button, Space, TabPane, Tabs, Notification, Popconfirm, Toast} from "@douyinfe/semi-ui";
|
||||||
import {useRequest, useSetState} from "ahooks";
|
import {useRequest, useSetState} from "ahooks";
|
||||||
import {useTranslation} from "react-i18next";
|
import {useTranslation} from "react-i18next";
|
||||||
import {useState} from "react";
|
import {useState} from "react";
|
||||||
@ -6,23 +6,22 @@ import {useState} from "react";
|
|||||||
import SearchForm from "@/components/bill/search-form.tsx";
|
import SearchForm from "@/components/bill/search-form.tsx";
|
||||||
import {BillList} from "@/components/bill/list.tsx";
|
import {BillList} from "@/components/bill/list.tsx";
|
||||||
import {billList, BillQueryParams, confirmBills} from "@/service/api/bill.ts";
|
import {billList, BillQueryParams, confirmBills} from "@/service/api/bill.ts";
|
||||||
|
import useAuth from "@/hooks/useAuth.ts";
|
||||||
import {BizError} from "@/service/types.ts";
|
import {BizError} from "@/service/types.ts";
|
||||||
|
|
||||||
const BillReconciliation = () => {
|
const BillReconciliation = () => {
|
||||||
const {t} = useTranslation()
|
const {t} = useTranslation()
|
||||||
|
const {user} = useAuth();
|
||||||
const [queryParams, setBillQueryParams] = useState<BillQueryParams>({
|
const [queryParams, setBillQueryParams] = useState<BillQueryParams>({
|
||||||
apply_status: 'UNCHECKED'
|
apply_status: 'UNCHECKED'
|
||||||
});
|
});
|
||||||
const {data, loading, refresh} = useRequest(() => billList({
|
const {data, loading, refresh} = useRequest(() => billList({
|
||||||
...queryParams,
|
...queryParams,
|
||||||
status: 'PAID',
|
status: 'PAID',
|
||||||
confirm_status: 'CONFIRMED'
|
confirm_status: 'CONFIRMED',
|
||||||
|
department: user?.department == 'RO' ? 'RO' : 'FO',
|
||||||
}), {
|
}), {
|
||||||
refreshDeps: [queryParams],
|
refreshDeps: [queryParams],
|
||||||
onSuccess: () => {
|
|
||||||
document.documentElement.scrollTo({top:0});
|
|
||||||
setState({checkingId: -1})
|
|
||||||
},
|
|
||||||
onError: (e: Error) => {
|
onError: (e: Error) => {
|
||||||
Toast.error({
|
Toast.error({
|
||||||
content: `${t('base.query_bill')}:${e.message}`,
|
content: `${t('base.query_bill')}:${e.message}`,
|
||||||
@ -37,31 +36,12 @@ const BillReconciliation = () => {
|
|||||||
})
|
})
|
||||||
const confirmBill = (records: number[]) => {
|
const confirmBill = (records: number[]) => {
|
||||||
if (records.length == 0) {
|
if (records.length == 0) {
|
||||||
Toast.error({content: t('bill.confirm_select_empty')})
|
Notification.error({title: 'Notice', content: t('bill.confirm_select_empty')})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const arr = data?.list.filter(item => records.includes(item.id));
|
setState({checkingId: records.length > 1 ? 0 : records[0]})
|
||||||
if (!arr) return;
|
|
||||||
for (let i = 0; i < arr.length; i++) {
|
|
||||||
const item = arr[i];
|
|
||||||
|
|
||||||
// 判断confirm的总金额是否和实付金额相等
|
|
||||||
const total = item.detail_confirms ? item.detail_confirms.reduce((total, item) => {
|
|
||||||
return total + Number(item.amount)
|
|
||||||
}, 0) : 0;
|
|
||||||
|
|
||||||
if (total != item.actual_payment_amount) {
|
|
||||||
Modal.warning({
|
|
||||||
title: 'Warning',
|
|
||||||
content: t('bill.confirm_bill_warning_amount_id', {id: item.id})
|
|
||||||
})
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setState({checkingId: records.length > 1 ? 0 : Number(records[0])})
|
|
||||||
confirmBills(records).then(() => {
|
confirmBills(records).then(() => {
|
||||||
Toast.success({content: t('bill.confirm_success')})
|
Notification.success({title: 'Notice', content: t('bill.confirm_success')})
|
||||||
refresh()
|
refresh()
|
||||||
}).catch((e: BizError) => {
|
}).catch((e: BizError) => {
|
||||||
Toast.error({
|
Toast.error({
|
||||||
@ -80,7 +60,6 @@ const BillReconciliation = () => {
|
|||||||
onConfirm={() => confirmBill([_record.id])}
|
onConfirm={() => confirmBill([_record.id])}
|
||||||
okText={t('base.confirm')}
|
okText={t('base.confirm')}
|
||||||
cancelText={t('base.cancel')}
|
cancelText={t('base.cancel')}
|
||||||
disabled={state.checkingId == _record.id}
|
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
loading={state.checkingId == _record.id} size={'small'} theme={'solid'}
|
loading={state.checkingId == _record.id} size={'small'} theme={'solid'}
|
||||||
@ -131,12 +110,6 @@ const BillReconciliation = () => {
|
|||||||
...queryParams,
|
...queryParams,
|
||||||
page_number
|
page_number
|
||||||
})}
|
})}
|
||||||
onPageSizeChange={(page_size) => {
|
|
||||||
setBillQueryParams({
|
|
||||||
...queryParams,
|
|
||||||
page_size
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>)
|
</div>)
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ export function confirmBillType(bills:BillConfirmParams[]) {
|
|||||||
return post<BillModel>(`/bills/confirm`, {bills})
|
return post<BillModel>(`/bills/confirm`, {bills})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function confirmBills(bill_ids: number[] | string[]) {
|
export function confirmBills(bill_ids: number[]) {
|
||||||
return post(`/bills/apply`, {bill_ids})
|
return post(`/bills/apply`, {bill_ids})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user