develop #26
@ -17,8 +17,8 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
proxy: {
|
proxy: {
|
||||||
'/api/': {
|
'/api/': {
|
||||||
target: 'http://10.39.13.78:8002/',
|
// target: 'http://10.39.13.78:8002/',
|
||||||
// target: 'http://test-company.linyikj.com.cn/',
|
target: 'http://test-company.linyikj.com.cn/',
|
||||||
// target: 'https://company.linyikj.com.cn/',
|
// target: 'https://company.linyikj.com.cn/',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
pathRewrite: { '^': '' },
|
pathRewrite: { '^': '' },
|
||||||
|
|||||||
@ -1,9 +1,20 @@
|
|||||||
import { MyIcons, MyIconsType, PermissionsType, useMyState } from '@/common';
|
import { MyIcons, MyIconsType, PermissionsType, useMyState } from '@/common';
|
||||||
import AvatarProps from '@/common/components/layout/AvatarProps';
|
import AvatarProps from '@/common/components/layout/AvatarProps';
|
||||||
import { Apis } from '@/gen/Apis';
|
import { Apis } from '@/gen/Apis';
|
||||||
|
import { BellOutlined } from '@ant-design/icons';
|
||||||
import { Link, RuntimeConfig, history, useNavigate } from '@umijs/max';
|
import { Link, RuntimeConfig, history, useNavigate } from '@umijs/max';
|
||||||
import { AutoComplete, Input, Menu, MenuProps, Select, Space } from 'antd';
|
import {
|
||||||
import { useEffect, useState } from 'react';
|
AutoComplete,
|
||||||
|
Badge,
|
||||||
|
Button,
|
||||||
|
Input,
|
||||||
|
Menu,
|
||||||
|
MenuProps,
|
||||||
|
Select,
|
||||||
|
Space,
|
||||||
|
Tooltip,
|
||||||
|
} from 'antd';
|
||||||
|
import { useEffect, useRef, useState } from 'react';
|
||||||
import './allConfig.scss';
|
import './allConfig.scss';
|
||||||
// import Logo from './logo.png';
|
// import Logo from './logo.png';
|
||||||
interface LevelKeysProps {
|
interface LevelKeysProps {
|
||||||
@ -61,6 +72,41 @@ export const LayoutConfig: RuntimeConfig['layout'] = () => {
|
|||||||
const [getSelectProject, setSelectProject] = useState<LevelKeysProps[]>([]);
|
const [getSelectProject, setSelectProject] = useState<LevelKeysProps[]>([]);
|
||||||
const { snap } = useMyState();
|
const { snap } = useMyState();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const [pendingCount, setPendingCount] = useState<number>();
|
||||||
|
const intervalRef = useRef<NodeJS.Timeout | null>(null);
|
||||||
|
|
||||||
|
// 获取待审核数量
|
||||||
|
const fetchPendingCount = async () => {
|
||||||
|
try {
|
||||||
|
const res = await Apis.Approval.ApprovalInstances.PendingCount();
|
||||||
|
setPendingCount(res?.data?.count || '');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to fetch pending count:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 组件挂载和用户状态变化时获取数据
|
||||||
|
useEffect(() => {
|
||||||
|
if (!snap.session.user) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fetchPendingCount();
|
||||||
|
if (intervalRef.current !== null) {
|
||||||
|
clearInterval(intervalRef.current);
|
||||||
|
}
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
fetchPendingCount().catch((error) => {
|
||||||
|
console.error('Interval fetch failed:', error);
|
||||||
|
});
|
||||||
|
}, 3000000);
|
||||||
|
intervalRef.current = interval;
|
||||||
|
return () => {
|
||||||
|
if (intervalRef.current !== null) {
|
||||||
|
clearInterval(intervalRef.current);
|
||||||
|
intervalRef.current = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, [snap.session.user]);
|
||||||
const permissionsList = (snap.session.permissions || [])
|
const permissionsList = (snap.session.permissions || [])
|
||||||
.filter((p: any) => p.type !== 'Button' && p.path)
|
.filter((p: any) => p.type !== 'Button' && p.path)
|
||||||
.sort((a: any, b: any) => a._lft - b._lft)
|
.sort((a: any, b: any) => a._lft - b._lft)
|
||||||
@ -74,7 +120,7 @@ export const LayoutConfig: RuntimeConfig['layout'] = () => {
|
|||||||
const handleLoadProject = async () => {
|
const handleLoadProject = async () => {
|
||||||
let res = await Apis.Common.Auth.GetProjects();
|
let res = await Apis.Common.Auth.GetProjects();
|
||||||
setSelectProject(
|
setSelectProject(
|
||||||
res?.data?.map((item) => ({
|
res?.data?.map((item: any) => ({
|
||||||
value: item.id,
|
value: item.id,
|
||||||
label: item.name,
|
label: item.name,
|
||||||
})),
|
})),
|
||||||
@ -130,12 +176,6 @@ export const LayoutConfig: RuntimeConfig['layout'] = () => {
|
|||||||
<HeaderSearch permissionsList={permissionsList} />
|
<HeaderSearch permissionsList={permissionsList} />
|
||||||
</div>
|
</div>
|
||||||
<Space size={10}>
|
<Space size={10}>
|
||||||
{/* <Button
|
|
||||||
type="default"
|
|
||||||
shape="circle"
|
|
||||||
icon={<SettingOutlined />}
|
|
||||||
onClick={() => history.push('/system/sys_permissions')}
|
|
||||||
/> */}
|
|
||||||
<Select
|
<Select
|
||||||
onSearch={handleLoadProject}
|
onSearch={handleLoadProject}
|
||||||
options={getSelectProject}
|
options={getSelectProject}
|
||||||
@ -152,6 +192,16 @@ export const LayoutConfig: RuntimeConfig['layout'] = () => {
|
|||||||
}}
|
}}
|
||||||
placeholder="选择项目"
|
placeholder="选择项目"
|
||||||
/>
|
/>
|
||||||
|
<Tooltip title="待审核">
|
||||||
|
<Badge count={pendingCount} showZero>
|
||||||
|
<Button
|
||||||
|
type="default"
|
||||||
|
shape="circle"
|
||||||
|
icon={<BellOutlined />}
|
||||||
|
onClick={() => history.push('/approval/pending')}
|
||||||
|
/>
|
||||||
|
</Badge>
|
||||||
|
</Tooltip>
|
||||||
</Space>
|
</Space>
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
|
|||||||
146
src/gen/ApiTypes.d.ts
vendored
146
src/gen/ApiTypes.d.ts
vendored
@ -743,17 +743,19 @@ declare namespace ApiTypes {
|
|||||||
}
|
}
|
||||||
namespace AttendanceSchedules {
|
namespace AttendanceSchedules {
|
||||||
type List = {
|
type List = {
|
||||||
|
"organizations_id"?: number; // 组织机构ID
|
||||||
"company_employees_id"?: number; // 员工ID
|
"company_employees_id"?: number; // 员工ID
|
||||||
"asset_projects_id"?: number; // 项目ID
|
"asset_projects_id"?: number; // 项目ID
|
||||||
"schedule_date"?: Date; // 排班日期
|
"schedule_date"?: Date; // 排班日期
|
||||||
"status"?: string; // 状态,[enum:AttendanceSchedulesStatusEnum]
|
"status"?: string; // 状态,[enum:AttendanceSchedulesStatusEnum]
|
||||||
"project_name"?: string; // 项目名称
|
"project_name"?: string; // 项目名称
|
||||||
"employee_name"?: string; // -
|
"employee_name"?: string; // -
|
||||||
|
"schedule_dates"?: string[]; // -
|
||||||
};
|
};
|
||||||
type Store = {
|
type Store = {
|
||||||
"company_employees_id": number; // 员工ID
|
"company_employees_id": number; // 员工ID
|
||||||
"attendance_shifts_id": number; // 班次ID
|
"attendance_shifts_id": number; // 班次ID
|
||||||
"asset_projects_id": number; // 项目ID
|
"asset_projects_id"?: number; // 项目ID
|
||||||
"schedule_date": Date; // 排班日期
|
"schedule_date": Date; // 排班日期
|
||||||
"remark"?: string; // 备注
|
"remark"?: string; // 备注
|
||||||
};
|
};
|
||||||
@ -801,7 +803,7 @@ declare namespace ApiTypes {
|
|||||||
};
|
};
|
||||||
type Store = {
|
type Store = {
|
||||||
"name": string; // 班次名称
|
"name": string; // 班次名称
|
||||||
"asset_projects_id": number; // 关联项目IDs
|
"asset_projects_id"?: number; // 关联项目IDs
|
||||||
"allow_checkin_start": date_format:H:i:s; // 可打卡开始时间
|
"allow_checkin_start": date_format:H:i:s; // 可打卡开始时间
|
||||||
"allow_checkin_end": date_format:H:i:s; // 可打卡结束时间
|
"allow_checkin_end": date_format:H:i:s; // 可打卡结束时间
|
||||||
"is_enabled"?: boolean; // 状态
|
"is_enabled"?: boolean; // 状态
|
||||||
@ -894,6 +896,45 @@ declare namespace ApiTypes {
|
|||||||
"type"?: string; // 类型,[enum:BillPaymentsTypeEnum]
|
"type"?: string; // 类型,[enum:BillPaymentsTypeEnum]
|
||||||
"flow_type"?: string; // 收支类型,[enum:BillsFlowTypeEnum]
|
"flow_type"?: string; // 收支类型,[enum:BillsFlowTypeEnum]
|
||||||
"status"?: string; // 账单状态,[enum:BillsStatusEnum]
|
"status"?: string; // 账单状态,[enum:BillsStatusEnum]
|
||||||
|
"year"?: number; // 年
|
||||||
|
"month"?: number; // 月
|
||||||
|
};
|
||||||
|
type Store = {
|
||||||
|
"type": string; // 类型,[enum:BillPaymentsTypeEnum]
|
||||||
|
"flow_type": string; // 收支类型,[enum:BillsFlowTypeEnum]
|
||||||
|
"business_id"?: number; // 业务记录ID(根据type自动关联对应模型)
|
||||||
|
"amount": number; // 金额(元)
|
||||||
|
"payable_amount"?: number; // 应付金额(元),不传则等于amount
|
||||||
|
"phone"?: string; // 手机号
|
||||||
|
"year"?: number; // 年
|
||||||
|
"month"?: number; // 月
|
||||||
|
"company_receipt_accounts_id": number; // 公司收款账户id,[ref:company_receipt_accounts]
|
||||||
|
"payer"?: string; // 付款人
|
||||||
|
"payer_bank"?: string; // 付款银行
|
||||||
|
"payer_account"?: string; // 付款账号
|
||||||
|
"asset_projects_id"?: number; // 项目ID,[ref:asset_projects]
|
||||||
|
"asset_buildings_id"?: number; // 楼栋ID,[ref:asset_buildings]
|
||||||
|
"asset_units_id"?: number; // 单元ID,[ref:asset_units]
|
||||||
|
"asset_houses_id"?: number; // 房屋ID,[ref:asset_houses]
|
||||||
|
"remark"?: string; // 备注
|
||||||
|
};
|
||||||
|
type Update = {
|
||||||
|
"id": number; // 账单ID
|
||||||
|
"type"?: string; // 类型,[enum:BillPaymentsTypeEnum]
|
||||||
|
"flow_type"?: string; // 收支类型,[enum:BillsFlowTypeEnum]
|
||||||
|
"amount"?: number; // 金额(元)
|
||||||
|
"payable_amount"?: number; // 应付金额(元)
|
||||||
|
"phone"?: string; // 手机号
|
||||||
|
"year"?: number; // 年
|
||||||
|
"month"?: number; // 月
|
||||||
|
"company_receipt_accounts_id": number; // 公司收款账户id,[ref:company_receipt_accounts]
|
||||||
|
"payer"?: string; // 付款人
|
||||||
|
"payer_bank"?: string; // 付款银行
|
||||||
|
"payer_account"?: string; // 付款账号
|
||||||
|
"remark"?: string; // 备注
|
||||||
|
"approval_templates_id": number; // 审批模板id
|
||||||
|
"approval_remark"?: string; // 审批备注
|
||||||
|
"node_approvers"?: string[]; // 各节点审批人员列表
|
||||||
};
|
};
|
||||||
type Show = {
|
type Show = {
|
||||||
"id": number; // id
|
"id": number; // id
|
||||||
@ -907,6 +948,38 @@ declare namespace ApiTypes {
|
|||||||
type Delete = {
|
type Delete = {
|
||||||
"id": number; // id
|
"id": number; // id
|
||||||
};
|
};
|
||||||
|
type Export = {
|
||||||
|
"phone"?: string; // 模糊搜索:手机号
|
||||||
|
"type"?: string; // 类型,[enum:BillPaymentsTypeEnum]
|
||||||
|
"flow_type"?: string; // 收支类型,[enum:BillsFlowTypeEnum]
|
||||||
|
"status"?: string; // 账单状态,[enum:BillsStatusEnum]
|
||||||
|
"year"?: number; // 年
|
||||||
|
"month"?: number; // 月
|
||||||
|
"asset_projects_id"?: number; // 项目ID,[ref:asset_projects]
|
||||||
|
"current"?: number; // 页码(download_type=page时使用)
|
||||||
|
"download_type": string; // 下载类型:page 当前页(含查询条件),query 所有页(含查询条件),all所有记录
|
||||||
|
};
|
||||||
|
type OfflinePayment = {
|
||||||
|
"id": number; // 账单ID
|
||||||
|
"payment_method": string; // 支付方式,[enum:HouseOrdersPaymentMethodEnum]
|
||||||
|
"paid_time": Date; // 支付时间
|
||||||
|
"accept_account_name"?: string; // 收款账户名称
|
||||||
|
"accept_account_number"?: string; // 收款账号
|
||||||
|
"accept_serial_number"?: string; // 收款流水号
|
||||||
|
"pay_certificate"?: string[]; // 支付凭证(图片)
|
||||||
|
"remark"?: string; // 备注
|
||||||
|
};
|
||||||
|
type GetPayCode = {
|
||||||
|
"id": number; // 账单ID
|
||||||
|
};
|
||||||
|
type AlipayQrCode = {
|
||||||
|
"id": number; // 账单ID
|
||||||
|
};
|
||||||
|
type AuditPayment = {
|
||||||
|
"id": number; // 支付记录ID(bill_payments.id)
|
||||||
|
"status": string; // 审核状态,[enum:BillPaymentsStatusEnum]
|
||||||
|
"rejected_reason"?: string; // 驳回原因
|
||||||
|
};
|
||||||
}
|
}
|
||||||
namespace HouseBills {
|
namespace HouseBills {
|
||||||
type List = {
|
type List = {
|
||||||
@ -918,7 +991,10 @@ declare namespace ApiTypes {
|
|||||||
"year"?: number; // 账单年份
|
"year"?: number; // 账单年份
|
||||||
"month"?: number; // 账单月份
|
"month"?: number; // 账单月份
|
||||||
"type"?: string; // 账单类型,[enum:HouseBillsTypeEnum]
|
"type"?: string; // 账单类型,[enum:HouseBillsTypeEnum]
|
||||||
|
"types"?: string[]; // 账单类型,[enum:HouseBillsTypeEnum]
|
||||||
"has_refunding"?: boolean; // 是否有退款中:false-无,true-有
|
"has_refunding"?: boolean; // 是否有退款中:false-无,true-有
|
||||||
|
"car_port_name"?: string; // 模糊搜索:车位名称
|
||||||
|
"paid_time"?: string[]; // 支付时间范围
|
||||||
};
|
};
|
||||||
type SummaryBillList = {
|
type SummaryBillList = {
|
||||||
"project_name"?: string; // 模糊搜索:项目名称
|
"project_name"?: string; // 模糊搜索:项目名称
|
||||||
@ -986,6 +1062,9 @@ declare namespace ApiTypes {
|
|||||||
"year"?: number; // 账单年份
|
"year"?: number; // 账单年份
|
||||||
"month"?: number; // 账单月份
|
"month"?: number; // 账单月份
|
||||||
"type"?: string; // 账单类型,[enum:HouseBillsTypeEnum]
|
"type"?: string; // 账单类型,[enum:HouseBillsTypeEnum]
|
||||||
|
"types"?: string[]; // 账单类型(数组),[enum:HouseBillsTypeEnum]
|
||||||
|
"car_port_name"?: string; // 模糊搜索:车位名称
|
||||||
|
"paid_time"?: string[]; // 支付时间范围
|
||||||
"current"?: number; // 页码
|
"current"?: number; // 页码
|
||||||
"download_type": string; // 下载类型:page 当前页(含查询条件),query 所有页(含查询条件),all所有记录
|
"download_type": string; // 下载类型:page 当前页(含查询条件),query 所有页(含查询条件),all所有记录
|
||||||
};
|
};
|
||||||
@ -2773,6 +2852,69 @@ declare namespace ApiTypes {
|
|||||||
"id": number; // id
|
"id": number; // id
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
namespace HouseDoorCards {
|
||||||
|
type List = {
|
||||||
|
"card_number"?: string; // 模糊搜索:卡号
|
||||||
|
"is_enable"?: boolean; // 是否启用:0-否,1-是
|
||||||
|
"name"?: string; // 模糊搜索:客户姓名
|
||||||
|
"phone"?: string; // 模糊搜索:手机号码
|
||||||
|
"full_name"?: string; // 模糊搜索:房屋名称
|
||||||
|
};
|
||||||
|
type Store = {
|
||||||
|
"card_number": string; // 门禁卡编号
|
||||||
|
"name": string; // 客户姓名
|
||||||
|
"phone": string; // 手机号码
|
||||||
|
"process_date": Date; // 办理日期
|
||||||
|
"is_enable": boolean; // 是否启用:0-否,1-是
|
||||||
|
"labor_cost": number; // 人工成本费(元)
|
||||||
|
"asset_houses_id": number; // 房屋id,[ref:asset_houses]
|
||||||
|
};
|
||||||
|
type Update = {
|
||||||
|
"id": number; // id
|
||||||
|
"card_number": string; // 门禁卡编号
|
||||||
|
"name": string; // 客户姓名
|
||||||
|
"phone": string; // 手机号码
|
||||||
|
"process_date": Date; // 办理日期
|
||||||
|
"is_enable": number; // 是否启用:0-否,1-是
|
||||||
|
"labor_cost": number; // 人工成本费(元)
|
||||||
|
"asset_houses_id": number; // 房屋id,[ref:asset_houses]
|
||||||
|
};
|
||||||
|
type Show = {
|
||||||
|
"id": number; // id
|
||||||
|
};
|
||||||
|
type SoftDelete = {
|
||||||
|
"id": number; // id
|
||||||
|
};
|
||||||
|
type Restore = {
|
||||||
|
"id": number; // id
|
||||||
|
};
|
||||||
|
type Delete = {
|
||||||
|
"id": number; // id
|
||||||
|
};
|
||||||
|
type CreateBill = {
|
||||||
|
"id": number; // 门卡id
|
||||||
|
"amount": number; // 金额(元)
|
||||||
|
"payment_method": string; // 支付方式,[enum:HouseOrdersPaymentMethodEnum]
|
||||||
|
"company_receipt_accounts_id": number; // 收款账号id,[ref:company_receipt_accounts]
|
||||||
|
"accept_serial_number"?: string; // 收款流水号(线下支付必填)
|
||||||
|
"pay_certificate"?: string[]; // 支付凭证(线下支付必填)
|
||||||
|
"remark"?: string; // 备注
|
||||||
|
};
|
||||||
|
type GetBill = {
|
||||||
|
"id": number; // 门卡id
|
||||||
|
};
|
||||||
|
type OfflinePay = {
|
||||||
|
"bills_id": number; // 账单id
|
||||||
|
"amount": number; // 金额(元)
|
||||||
|
"payment_method": string; // 支付方式,[enum:HouseOrdersPaymentMethodEnum]
|
||||||
|
"paid_time": Date; // 支付时间
|
||||||
|
"accept_account_name"?: string; // 收款账号名称
|
||||||
|
"accept_account_number"?: string; // 收款账号
|
||||||
|
"accept_serial_number": string; // 收款流水号
|
||||||
|
"pay_certificate"?: string[]; // 支付凭证
|
||||||
|
"remark"?: string; // 备注
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
namespace HouseOrder {
|
namespace HouseOrder {
|
||||||
namespace HouseOrderPayments {
|
namespace HouseOrderPayments {
|
||||||
|
|||||||
3506
src/gen/Apis.ts
3506
src/gen/Apis.ts
File diff suppressed because it is too large
Load Diff
@ -71,6 +71,7 @@ export const ApprovalTemplatesTypeEnum= {
|
|||||||
'ContractPayment': {"text":"合同支付","color":"#00bcd4","value":"ContractPayment"},
|
'ContractPayment': {"text":"合同支付","color":"#00bcd4","value":"ContractPayment"},
|
||||||
'OtherContractSeal': {"text":"其它合同用印","color":"#795548","value":"OtherContractSeal"},
|
'OtherContractSeal': {"text":"其它合同用印","color":"#795548","value":"OtherContractSeal"},
|
||||||
'HouseBillUpdate': {"text":"物业账单修改","color":"#607d8b","value":"HouseBillUpdate"},
|
'HouseBillUpdate': {"text":"物业账单修改","color":"#607d8b","value":"HouseBillUpdate"},
|
||||||
|
'BillUpdate': {"text":"其他账单修改","color":"#795548","value":"BillUpdate"},
|
||||||
};
|
};
|
||||||
|
|
||||||
// 车位产权类型
|
// 车位产权类型
|
||||||
@ -327,13 +328,15 @@ export const BillsRefundStatusEnum= {
|
|||||||
export const BillsStatusEnum= {
|
export const BillsStatusEnum= {
|
||||||
'PendingPayment': {"text":"待支付","color":"#facc15","value":"PendingPayment"},
|
'PendingPayment': {"text":"待支付","color":"#facc15","value":"PendingPayment"},
|
||||||
'Paid': {"text":"已支付","color":"#10b981","value":"Paid"},
|
'Paid': {"text":"已支付","color":"#10b981","value":"Paid"},
|
||||||
|
'ToBeConfirmed': {"text":"待确认","color":"#f97316","value":"ToBeConfirmed"},
|
||||||
'Overdue': {"text":"已逾期","color":"#ef4444","value":"Overdue"},
|
'Overdue': {"text":"已逾期","color":"#ef4444","value":"Overdue"},
|
||||||
|
'UnderApproval': {"text":"审批中","color":"#8b5cf6","value":"UnderApproval"},
|
||||||
'Cancelled': {"text":"已取消","color":"#9ca3af","value":"Cancelled"},
|
'Cancelled': {"text":"已取消","color":"#9ca3af","value":"Cancelled"},
|
||||||
};
|
};
|
||||||
|
|
||||||
// 缓存类型
|
// 缓存类型
|
||||||
export const CacheTypeEnum= {
|
export const CacheTypeEnum= {
|
||||||
'MobilePhoneVerificationCode': {"text":"手机验证码","color":"#40ec73","value":"MobilePhoneVerificationCode"},
|
'MobilePhoneVerificationCode': {"text":"手机验证码","color":"#40a1af","value":"MobilePhoneVerificationCode"},
|
||||||
};
|
};
|
||||||
|
|
||||||
// CompaniesMerchantTypeEnum
|
// CompaniesMerchantTypeEnum
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { MyColumns, MyPageContainer, MyProTableProps } from '@/common';
|
import { MyColumns, MyPageContainer, MyProTableProps } from '@/common';
|
||||||
|
import { Selects } from '@/components/Select';
|
||||||
import { Apis } from '@/gen/Apis';
|
import { Apis } from '@/gen/Apis';
|
||||||
import {
|
import {
|
||||||
ApprovalInstancesStatusEnum,
|
ApprovalInstancesStatusEnum,
|
||||||
@ -6,13 +7,14 @@ import {
|
|||||||
} from '@/gen/Enums';
|
} from '@/gen/Enums';
|
||||||
import { ProTable } from '@ant-design/pro-components';
|
import { ProTable } from '@ant-design/pro-components';
|
||||||
import { Space } from 'antd';
|
import { Space } from 'antd';
|
||||||
import Show from './modals/Show';
|
import AuditShow from '../common_info/AuditShow';
|
||||||
export default function Index({ title = '抄送我的' }) {
|
|
||||||
|
export default function Index({ title = '审批列表' }) {
|
||||||
return (
|
return (
|
||||||
<MyPageContainer
|
<MyPageContainer
|
||||||
title={title}
|
title={title}
|
||||||
enableTabs={true}
|
enableTabs={true}
|
||||||
tabKey="my_apply_list"
|
tabKey="all_approval_instances"
|
||||||
tabLabel={title}
|
tabLabel={title}
|
||||||
>
|
>
|
||||||
<ProTable
|
<ProTable
|
||||||
@ -21,12 +23,28 @@ export default function Index({ title = '抄送我的' }) {
|
|||||||
MyProTableProps.request(
|
MyProTableProps.request(
|
||||||
params,
|
params,
|
||||||
sort,
|
sort,
|
||||||
Apis.Approval.ApprovalInstances.CcList,
|
Apis.Approval.ApprovalInstances.List,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
headerTitle={title}
|
headerTitle={title}
|
||||||
columns={[
|
columns={[
|
||||||
MyColumns.ID({ search: false }),
|
MyColumns.ID({ search: false }),
|
||||||
|
Selects?.AssetProjects({
|
||||||
|
title: '选择项目',
|
||||||
|
key: 'asset_projects_id',
|
||||||
|
hidden: true,
|
||||||
|
}),
|
||||||
|
MyColumns.EnumTag({
|
||||||
|
title: '状态',
|
||||||
|
dataIndex: 'status',
|
||||||
|
valueEnum: ApprovalInstancesStatusEnum,
|
||||||
|
}),
|
||||||
|
MyColumns.EnumTag({
|
||||||
|
dataIndex: 'type',
|
||||||
|
title: '类型',
|
||||||
|
valueEnum: ApprovalTemplatesTypeEnum,
|
||||||
|
search: false,
|
||||||
|
}),
|
||||||
{
|
{
|
||||||
title: '申请事项',
|
title: '申请事项',
|
||||||
dataIndex: 'title',
|
dataIndex: 'title',
|
||||||
@ -37,33 +55,29 @@ export default function Index({ title = '抄送我的' }) {
|
|||||||
dataIndex: ['asset_project', 'name'],
|
dataIndex: ['asset_project', 'name'],
|
||||||
search: false,
|
search: false,
|
||||||
},
|
},
|
||||||
MyColumns.EnumTag({
|
{
|
||||||
title: '状态',
|
title: '申请人',
|
||||||
dataIndex: 'status',
|
dataIndex: ['applicant', 'name'],
|
||||||
valueEnum: ApprovalInstancesStatusEnum,
|
|
||||||
}),
|
|
||||||
MyColumns.EnumTag({
|
|
||||||
dataIndex: 'type',
|
|
||||||
title: '业务类型',
|
|
||||||
valueEnum: ApprovalTemplatesTypeEnum,
|
|
||||||
search: false,
|
search: false,
|
||||||
}),
|
},
|
||||||
|
{
|
||||||
// {
|
title: '当前审批人',
|
||||||
// title: '项目ID',
|
dataIndex: ['approval_records', 'approver_name'],
|
||||||
// dataIndex: 'asset_projects_id',
|
search: false,
|
||||||
// hidden: true,
|
render: (_, item: any) =>
|
||||||
// },
|
`${item?.approval_records?.[0]?.company_employee?.name || ''}-${
|
||||||
// {
|
item?.approval_records?.[0]?.company_employee?.phone || ''
|
||||||
// title: '申请人',
|
}`,
|
||||||
// dataIndex: 'applicant_name',
|
},
|
||||||
// search: false,
|
{
|
||||||
// },
|
title: '申请人',
|
||||||
MyColumns.CreatedAt(),
|
dataIndex: 'applicant_name',
|
||||||
|
hidden: true,
|
||||||
|
},
|
||||||
MyColumns.Option({
|
MyColumns.Option({
|
||||||
render: (_, item: any, index, action) => (
|
render: (_, item: any, index, action) => (
|
||||||
<Space key={index}>
|
<Space key={index}>
|
||||||
<Show item={item} reload={action?.reload} title={title} />
|
<AuditShow item={item} reload={action?.reload} title={title} />
|
||||||
</Space>
|
</Space>
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
|
|||||||
@ -1,250 +0,0 @@
|
|||||||
import {
|
|
||||||
MyBetaModalFormProps,
|
|
||||||
MyButtons,
|
|
||||||
MyModalFormProps,
|
|
||||||
renderTextHelper,
|
|
||||||
} from '@/common';
|
|
||||||
|
|
||||||
import { Apis } from '@/gen/Apis';
|
|
||||||
import { RefundsTypeEnum } from '@/gen/Enums';
|
|
||||||
import BIllInfo from '@/pages/bills/house_bills/modals/BIllInfo';
|
|
||||||
import {
|
|
||||||
BetaSchemaForm,
|
|
||||||
ProCard,
|
|
||||||
ProDescriptions,
|
|
||||||
} from '@ant-design/pro-components';
|
|
||||||
import { useNavigate } from '@umijs/max';
|
|
||||||
import { Form, Space, Steps } from 'antd';
|
|
||||||
|
|
||||||
export default function Update(props: MyBetaModalFormProps) {
|
|
||||||
const [form] = Form.useForm();
|
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<BetaSchemaForm<ApiTypes.Archive.HouseRegisters.Update>
|
|
||||||
{...MyModalFormProps.props}
|
|
||||||
title={props.title}
|
|
||||||
trigger={<MyButtons.Default title="查看" type="primary" />}
|
|
||||||
wrapperCol={{ span: 24 }}
|
|
||||||
width="600px"
|
|
||||||
key={new Date().getTime()}
|
|
||||||
form={form}
|
|
||||||
onOpenChange={() => {
|
|
||||||
if (props?.item?.id) {
|
|
||||||
Apis.Approval.ApprovalInstances.Show({
|
|
||||||
id: props.item?.model_id,
|
|
||||||
}).then((res) => {
|
|
||||||
form.setFieldsValue({
|
|
||||||
info_display: res?.data,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
columns={[
|
|
||||||
{
|
|
||||||
// title: '登记信息',
|
|
||||||
dataIndex: 'info_display',
|
|
||||||
valueType: 'text',
|
|
||||||
renderFormItem: (_, config) => (
|
|
||||||
<Space direction="vertical" style={{ width: '100%' }}>
|
|
||||||
<div>
|
|
||||||
{/* 退款详情 */}
|
|
||||||
{config?.value?.type === 'Refund' && (
|
|
||||||
<ProCard size="small">
|
|
||||||
<ProDescriptions size="small" column={2}>
|
|
||||||
<ProDescriptions.Item label="申请事项" span={2}>
|
|
||||||
{config?.value?.title || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="账单类型">
|
|
||||||
<renderTextHelper.Tag
|
|
||||||
Enums={RefundsTypeEnum}
|
|
||||||
value={config?.value?.model?.type}
|
|
||||||
/>
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="退款金额">
|
|
||||||
<Space>
|
|
||||||
{config?.value?.model?.refund_amount || '-'}
|
|
||||||
元
|
|
||||||
<BIllInfo
|
|
||||||
item={{
|
|
||||||
id: config?.value?.model?.refundable_id,
|
|
||||||
type: 'link',
|
|
||||||
}}
|
|
||||||
title="查看账单"
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="付款信息" span={2}>
|
|
||||||
{config?.value?.model?.payer_name || '-'}|
|
|
||||||
{config?.value?.model?.payer_bank || '-'}|
|
|
||||||
{config?.value?.model?.payer_account || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="收款信息" span={2}>
|
|
||||||
{config?.value?.model?.payee_name || '-'}
|
|
||||||
{config?.value?.model?.payee_bank || '-'}
|
|
||||||
{config?.value?.model?.payee_account || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="申请人" span={2}>
|
|
||||||
{props?.item?.applicant?.name || '-'}:
|
|
||||||
{props?.item?.applicant?.phone || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="申请时间">
|
|
||||||
{props?.item?.created_at || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
</ProDescriptions>
|
|
||||||
</ProCard>
|
|
||||||
)}
|
|
||||||
{/* 合同详情 */}
|
|
||||||
{config?.value?.type === 'Contract' && (
|
|
||||||
<ProCard size="small">
|
|
||||||
<ProDescriptions size="small" column={2}>
|
|
||||||
<ProDescriptions.Item label="合同名称" span={2}>
|
|
||||||
{config?.value?.model?.name || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
|
|
||||||
<ProDescriptions.Item label="合同编号" span={2}>
|
|
||||||
<Space>
|
|
||||||
{config?.value?.model?.code || '-'}
|
|
||||||
<BIllInfo
|
|
||||||
item={{
|
|
||||||
id: config?.value?.model?.refundable_id,
|
|
||||||
type: 'Contract',
|
|
||||||
}}
|
|
||||||
title="查看合同"
|
|
||||||
/>
|
|
||||||
<MyButtons.View
|
|
||||||
title="查看"
|
|
||||||
key="configInfo"
|
|
||||||
onClick={() => {
|
|
||||||
navigate(
|
|
||||||
`/contract/contracts/show/${config?.value?.model?.id}`,
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
{/* <ProDescriptions.Item label="收支类型">
|
|
||||||
<renderTextHelper.Tag
|
|
||||||
Enums={ContractTemplatesIncomeExpenseTypeEnum}
|
|
||||||
value={config?.value?.model?.income_expense_type}
|
|
||||||
/>
|
|
||||||
</ProDescriptions.Item> */}
|
|
||||||
{/* <ProDescriptions.Item label="合同性质">
|
|
||||||
<renderTextHelper.Tag
|
|
||||||
Enums={ContractsContractNatureEnum}
|
|
||||||
value={config?.value?.model?.contract_nature}
|
|
||||||
/>
|
|
||||||
</ProDescriptions.Item> */}
|
|
||||||
<ProDescriptions.Item label="合同类型">
|
|
||||||
{config?.value?.model?.contract_type_name || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
{/* <ProDescriptions.Item label="结算模式">
|
|
||||||
<renderTextHelper.Tag
|
|
||||||
Enums={ContractsSettlementModeEnum}
|
|
||||||
value={config?.value?.model?.settlement_mode}
|
|
||||||
/>
|
|
||||||
</ProDescriptions.Item> */}
|
|
||||||
<ProDescriptions.Item label="合同金额">
|
|
||||||
{config?.value?.model?.total_amount || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="保证金金额">
|
|
||||||
{config?.value?.model?.deposit_amount || '无'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="签约主体">
|
|
||||||
{config?.value?.model?.sign_subject || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="签约部门">
|
|
||||||
{config?.value?.model?.sign_department || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="关联项目">
|
|
||||||
{config?.value?.model?.project_name || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="合同对接人">
|
|
||||||
{config?.value?.model?.contract_liaison || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="合同有效期" span={2}>
|
|
||||||
{config?.value?.model?.start_time?.substring(0, 10)}至
|
|
||||||
{config?.value?.model?.end_time?.substring(0, 10)}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="申请人" span={2}>
|
|
||||||
{props?.item?.applicant?.name || '-'}:
|
|
||||||
{props?.item?.applicant?.phone || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="申请时间" span={2}>
|
|
||||||
{props?.item?.created_at || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="附件" span={2}>
|
|
||||||
{config?.value?.model?.attachments.map((item: any) => {
|
|
||||||
const handleDownload = async (
|
|
||||||
e: React.MouseEvent,
|
|
||||||
) => {
|
|
||||||
e.preventDefault();
|
|
||||||
try {
|
|
||||||
const response = await fetch(item.url);
|
|
||||||
const blob = await response.blob();
|
|
||||||
const url = window.URL.createObjectURL(blob);
|
|
||||||
const a = document.createElement('a');
|
|
||||||
a.href = url;
|
|
||||||
a.download = item.name;
|
|
||||||
document.body.appendChild(a);
|
|
||||||
a.click();
|
|
||||||
window.URL.revokeObjectURL(url);
|
|
||||||
document.body.removeChild(a);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('下载失败:', error);
|
|
||||||
// 如果下载失败,则在新窗口打开
|
|
||||||
window.open(item.url, '_blank');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div key={item.url}>
|
|
||||||
<a href={item.url} onClick={handleDownload}>
|
|
||||||
{item.name};
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
</ProDescriptions>
|
|
||||||
</ProCard>
|
|
||||||
)}
|
|
||||||
<ProCard>
|
|
||||||
<ProDescriptions>
|
|
||||||
<ProDescriptions.Item label="审核记录">
|
|
||||||
<Space direction="vertical" style={{ width: '100%' }}>
|
|
||||||
<Steps
|
|
||||||
progressDot
|
|
||||||
direction="vertical"
|
|
||||||
current={config?.value?.approval_records.length}
|
|
||||||
items={config?.value?.approval_records.map(
|
|
||||||
(item: any) =>
|
|
||||||
item?.node_type === 'Approver'
|
|
||||||
? {
|
|
||||||
title: `${
|
|
||||||
item.company_employee?.name || '-'
|
|
||||||
}-${item?.company_employee?.phone}`,
|
|
||||||
description: `${
|
|
||||||
item.status === 'Approved'
|
|
||||||
? `通过 - ${item.opinion || '-'} - ${
|
|
||||||
item.created_at || '-'
|
|
||||||
}`
|
|
||||||
: '待审核'
|
|
||||||
}`,
|
|
||||||
}
|
|
||||||
: '',
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
</ProDescriptions>
|
|
||||||
</ProCard>
|
|
||||||
</div>
|
|
||||||
</Space>
|
|
||||||
),
|
|
||||||
colProps: { span: 24 },
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
64
src/pages/approval/common_info/ApprovalRecord.tsx
Normal file
64
src/pages/approval/common_info/ApprovalRecord.tsx
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import { MyBetaModalFormProps } from '@/common';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { ProCard, ProDescriptions } from '@ant-design/pro-components';
|
||||||
|
import { useNavigate } from '@umijs/max';
|
||||||
|
import { Form, Space, Steps } from 'antd';
|
||||||
|
|
||||||
|
export default function Update(props: MyBetaModalFormProps) {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Space direction="vertical" style={{ width: '100%' }}>
|
||||||
|
<ProCard title="审批流程" size="small">
|
||||||
|
<ProDescriptions.Item label="审核记录">
|
||||||
|
<Space direction="vertical" style={{ width: '100%' }}>
|
||||||
|
<Steps
|
||||||
|
progressDot
|
||||||
|
direction="vertical"
|
||||||
|
current={props?.item?.approval_records.length - 1}
|
||||||
|
items={props?.item?.approval_records.map((item: any) =>
|
||||||
|
item?.node_type === 'Approver'
|
||||||
|
? {
|
||||||
|
title: `${item.company_employee?.name || '-'}-${
|
||||||
|
item?.company_employee?.phone
|
||||||
|
}`,
|
||||||
|
description: `${
|
||||||
|
item.status === 'Approved'
|
||||||
|
? `通过 - ${item.opinion || '-'} - ${
|
||||||
|
item.created_at || '-'
|
||||||
|
}`
|
||||||
|
: item.status === 'Rejected'
|
||||||
|
? `拒绝 - ${item.opinion || '-'} - ${
|
||||||
|
item.created_at || '-'
|
||||||
|
}`
|
||||||
|
: '待审核'
|
||||||
|
}`,
|
||||||
|
}
|
||||||
|
: '',
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Space>
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
{props?.item?.approval_records?.filter(
|
||||||
|
(item: any) => item?.node_type === 'CC',
|
||||||
|
).length > 0 && (
|
||||||
|
<ProDescriptions.Item label="抄送对象">
|
||||||
|
{props?.item?.approval_records
|
||||||
|
.filter((item: any) => item?.node_type === 'CC')
|
||||||
|
.map((item: any, index: number) => (
|
||||||
|
<React.Fragment key={index}>
|
||||||
|
{index > 0 && ';'}
|
||||||
|
{item.company_employee?.name || '-'}-
|
||||||
|
{item?.company_employee?.phone || '-'}
|
||||||
|
</React.Fragment>
|
||||||
|
))}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
)}
|
||||||
|
</ProCard>
|
||||||
|
</Space>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
57
src/pages/approval/common_info/ArchiveBorrowInfo.tsx
Normal file
57
src/pages/approval/common_info/ArchiveBorrowInfo.tsx
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import { MyBetaModalFormProps } from '@/common';
|
||||||
|
|
||||||
|
import ArchiveShow from '@/pages/contract/contract_archives/modals/Show';
|
||||||
|
import ArchiveBorrowShow from '@/pages/contract/contract_borrows/borrows/modals/Show';
|
||||||
|
import { ProCard, ProDescriptions } from '@ant-design/pro-components';
|
||||||
|
import { useNavigate } from '@umijs/max';
|
||||||
|
import { Form, Space } from 'antd';
|
||||||
|
|
||||||
|
export default function Update(props: MyBetaModalFormProps) {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Space direction="vertical" style={{ width: '100%' }}>
|
||||||
|
<ProCard title="基本信息" size="small">
|
||||||
|
<ProDescriptions size="small" column={2}>
|
||||||
|
<ProDescriptions.Item label="档案id">
|
||||||
|
{props?.item?.model?.contract_archives_id}
|
||||||
|
<ArchiveShow
|
||||||
|
item={{
|
||||||
|
id: props?.item?.model?.contract_archives_id,
|
||||||
|
type: 'link',
|
||||||
|
}}
|
||||||
|
title="查看档案"
|
||||||
|
/>
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="借阅人">
|
||||||
|
{props?.item?.model?.borrower_name}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="借阅日期">
|
||||||
|
{props?.item?.model?.borrow_date}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="是否需要归还">
|
||||||
|
{props?.item?.model?.is_need_return ? '是' : '否'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="预计归还日期">
|
||||||
|
{props?.item?.model?.expected_return_date}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="申请说明" span={2}>
|
||||||
|
{props?.item?.model?.remark}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="借阅文件" span={2}>
|
||||||
|
<ArchiveBorrowShow
|
||||||
|
item={{
|
||||||
|
id: props?.item?.model?.id,
|
||||||
|
type: 'link',
|
||||||
|
}}
|
||||||
|
title="查看详情"
|
||||||
|
/>
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
</ProDescriptions>
|
||||||
|
</ProCard>
|
||||||
|
</Space>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
86
src/pages/approval/common_info/AuditShow.tsx
Normal file
86
src/pages/approval/common_info/AuditShow.tsx
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
import { MyBetaModalFormProps, MyButtons, MyModalFormProps } from '@/common';
|
||||||
|
|
||||||
|
import { Apis } from '@/gen/Apis';
|
||||||
|
import { BetaSchemaForm } from '@ant-design/pro-components';
|
||||||
|
import { useNavigate } from '@umijs/max';
|
||||||
|
import { Form, Space } from 'antd';
|
||||||
|
import ApprovalRecord from './ApprovalRecord';
|
||||||
|
import ArchiveBorrowInfo from './ArchiveBorrowInfo';
|
||||||
|
import ChargeStandardInfo from './ChargeStandardInfo';
|
||||||
|
import ContractInfo from './ContractInfo';
|
||||||
|
import ContractPaymentInfo from './ContractPaymentInfo';
|
||||||
|
import ContractTerminationInfo from './ContractTerminationInfo';
|
||||||
|
import RefundInfo from './RefundInfo';
|
||||||
|
import SealInfo from './SealInfo';
|
||||||
|
import {
|
||||||
|
default as BillUpdateInfo,
|
||||||
|
default as TemporaryBillUpdateInfo,
|
||||||
|
} from './TemporaryBillUpdateInfo';
|
||||||
|
|
||||||
|
export default function AuditShow(props: MyBetaModalFormProps) {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<BetaSchemaForm<ApiTypes.Approval.ApprovalInstances.Show>
|
||||||
|
{...MyModalFormProps.props}
|
||||||
|
title={props.title}
|
||||||
|
trigger={<MyButtons.Default title="查看" type="primary" />}
|
||||||
|
wrapperCol={{ span: 24 }}
|
||||||
|
width="600px"
|
||||||
|
key={new Date().getTime()}
|
||||||
|
form={form}
|
||||||
|
onOpenChange={() => {
|
||||||
|
if (props?.item?.id) {
|
||||||
|
Apis.Approval.ApprovalInstances.Show({
|
||||||
|
id: props.item?.id,
|
||||||
|
}).then((res) => {
|
||||||
|
form.setFieldsValue({
|
||||||
|
info_display: res?.data,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
columns={[
|
||||||
|
{
|
||||||
|
// title: '登记信息',
|
||||||
|
dataIndex: 'info_display',
|
||||||
|
valueType: 'text',
|
||||||
|
renderFormItem: (_, config) => (
|
||||||
|
<Space direction="vertical" style={{ width: '100%' }}>
|
||||||
|
{config?.value?.type === 'Contract' && (
|
||||||
|
<ContractInfo item={config?.value} />
|
||||||
|
)}
|
||||||
|
{config?.value?.type === 'ContractTermination' && (
|
||||||
|
<ContractTerminationInfo item={config?.value} />
|
||||||
|
)}
|
||||||
|
{config?.value?.type === 'ContractPayment' && (
|
||||||
|
<ContractPaymentInfo item={config?.value} />
|
||||||
|
)}
|
||||||
|
{config?.value?.type === 'Refund' && (
|
||||||
|
<RefundInfo item={config?.value} />
|
||||||
|
)}
|
||||||
|
{config?.value?.type === 'ContractBorrow' && (
|
||||||
|
<ArchiveBorrowInfo item={config?.value} />
|
||||||
|
)}
|
||||||
|
{config?.value?.type === 'OtherContractSeal' && (
|
||||||
|
<SealInfo item={config?.value} />
|
||||||
|
)}
|
||||||
|
{config?.value?.type === 'HouseBillUpdate' && (
|
||||||
|
<BillUpdateInfo item={config?.value} />
|
||||||
|
)}
|
||||||
|
{config?.value?.type === 'ChargeStandardModification' && (
|
||||||
|
<ChargeStandardInfo item={config?.value} />
|
||||||
|
)}
|
||||||
|
{config?.value?.type === 'BillUpdate' && (
|
||||||
|
<TemporaryBillUpdateInfo item={config?.value} />
|
||||||
|
)}
|
||||||
|
<ApprovalRecord item={config?.value} />
|
||||||
|
</Space>
|
||||||
|
),
|
||||||
|
colProps: { span: 24 },
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
82
src/pages/approval/common_info/BillUpdateInfo.tsx
Normal file
82
src/pages/approval/common_info/BillUpdateInfo.tsx
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
import { MyBetaModalFormProps, renderTextHelper } from '@/common';
|
||||||
|
import { HouseBillsTypeEnum } from '@/gen/Enums';
|
||||||
|
import BIllInfo from '@/pages/bills/house_bills/modals/BIllInfo';
|
||||||
|
|
||||||
|
import { ProCard, ProDescriptions } from '@ant-design/pro-components';
|
||||||
|
import { Space } from 'antd';
|
||||||
|
|
||||||
|
export default function BillUpdateInfo(props: MyBetaModalFormProps) {
|
||||||
|
const originalData = props?.item?.model?.original_data;
|
||||||
|
const newData = props?.item?.model?.new_data;
|
||||||
|
|
||||||
|
// 格式化金额
|
||||||
|
const formatAmount = (amount: any) => {
|
||||||
|
if (!amount || amount === '-') return '-';
|
||||||
|
return parseFloat(amount).toFixed(2) + ' 元';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 渲染数据项
|
||||||
|
const renderDataItems = (data: any) => (
|
||||||
|
<ProDescriptions size="small" column={1}>
|
||||||
|
<ProDescriptions.Item label="账单类型">
|
||||||
|
<renderTextHelper.Tag Enums={HouseBillsTypeEnum} value={data?.type} />
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="账单金额">
|
||||||
|
{formatAmount(data?.amount)}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="优惠金额">
|
||||||
|
{formatAmount(data?.discount_amount)}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="滞纳金">
|
||||||
|
{formatAmount(data?.late_fee)}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="账单月份">
|
||||||
|
{data?.year}-{String(data?.month || 1).padStart(2, '0')}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="计费周期">
|
||||||
|
{data?.start_date} 至 {data?.end_date}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="备注">
|
||||||
|
{data?.remark || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
</ProDescriptions>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Space direction="vertical" style={{ width: '100%' }}>
|
||||||
|
<ProCard title="基本信息" size="small">
|
||||||
|
<ProDescriptions size="small" column={2}>
|
||||||
|
<ProDescriptions.Item label="申请事项">
|
||||||
|
{props?.item?.title || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="关联原账单">
|
||||||
|
<BIllInfo
|
||||||
|
item={{
|
||||||
|
id: props?.item?.model?.model_id,
|
||||||
|
type: 'link',
|
||||||
|
}}
|
||||||
|
title="查看账单"
|
||||||
|
/>
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="申请人">
|
||||||
|
{props?.item?.applicant_name || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="申请时间">
|
||||||
|
{props?.item?.created_at || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
</ProDescriptions>
|
||||||
|
</ProCard>
|
||||||
|
|
||||||
|
<ProCard title="修改内容对比" size="small" split="vertical">
|
||||||
|
<ProCard title="修改前" type="inner" bordered headerBordered>
|
||||||
|
{renderDataItems(originalData)}
|
||||||
|
</ProCard>
|
||||||
|
<ProCard title="修改后" type="inner" bordered headerBordered>
|
||||||
|
{renderDataItems(newData)}
|
||||||
|
</ProCard>
|
||||||
|
</ProCard>
|
||||||
|
</Space>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
119
src/pages/approval/common_info/ChargeStandardInfo.tsx
Normal file
119
src/pages/approval/common_info/ChargeStandardInfo.tsx
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
import { MyBetaModalFormProps, renderTextHelper } from '@/common';
|
||||||
|
import {
|
||||||
|
HouseBillsTypeEnum,
|
||||||
|
HouseChargeStandardsApportionmentMethodEnum,
|
||||||
|
HouseChargeStandardsCalculationMethodEnum,
|
||||||
|
HouseChargeStandardsCalculationModeEnum,
|
||||||
|
HouseChargeStandardsCalculationPeriodEnum,
|
||||||
|
HouseChargeStandardsPriceAlgorithmEnum,
|
||||||
|
} from '@/gen/Enums';
|
||||||
|
|
||||||
|
import { ProCard, ProDescriptions } from '@ant-design/pro-components';
|
||||||
|
import { Space } from 'antd';
|
||||||
|
|
||||||
|
export default function ChargeStandardInfo(props: MyBetaModalFormProps) {
|
||||||
|
const model = props?.item?.model?.new_data;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Space direction="vertical" style={{ width: '100%' }}>
|
||||||
|
<ProCard title="收费标准申请信息" size="small">
|
||||||
|
<ProDescriptions size="small" column={2}>
|
||||||
|
<ProDescriptions.Item label="申请事项" span={2}>
|
||||||
|
{props?.item?.title || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="关联项目">
|
||||||
|
{props?.item?.asset_project?.name || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="收费标准名称">
|
||||||
|
{model?.name || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="收款帐号">
|
||||||
|
{model?.company_receipt_account?.company_bank}:
|
||||||
|
{model?.company_receipt_account?.company_account || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="收费类型">
|
||||||
|
<renderTextHelper.Tag
|
||||||
|
Enums={HouseBillsTypeEnum}
|
||||||
|
value={model?.charge_type}
|
||||||
|
/>
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="是否公摊">
|
||||||
|
{model?.is_apportionment ? '是' : '否'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
{model?.apportionment_method && (
|
||||||
|
<ProDescriptions.Item label="分摊方式">
|
||||||
|
<renderTextHelper.Tag
|
||||||
|
Enums={HouseChargeStandardsApportionmentMethodEnum}
|
||||||
|
value={model?.apportionment_method}
|
||||||
|
/>
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
)}
|
||||||
|
<ProDescriptions.Item label="计量单位">
|
||||||
|
<renderTextHelper.Tag
|
||||||
|
Enums={HouseChargeStandardsCalculationMethodEnum}
|
||||||
|
value={model?.calculation_method}
|
||||||
|
/>
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="计费模式">
|
||||||
|
<renderTextHelper.Tag
|
||||||
|
Enums={HouseChargeStandardsCalculationModeEnum}
|
||||||
|
value={model?.calculation_mode}
|
||||||
|
/>
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="计费算法">
|
||||||
|
<renderTextHelper.Tag
|
||||||
|
Enums={HouseChargeStandardsPriceAlgorithmEnum}
|
||||||
|
value={model?.price_algorithm}
|
||||||
|
/>
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="价格">
|
||||||
|
{model?.price_algorithm === 'Fixed'
|
||||||
|
? `${model?.price || '-'} 元`
|
||||||
|
: model?.tiered_rates?.map((rate: any, index: number) => (
|
||||||
|
<div key={index}>
|
||||||
|
{rate?.min_quantity} - {rate?.max_quantity}: {rate?.price}{' '}
|
||||||
|
元
|
||||||
|
</div>
|
||||||
|
)) || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="计费周期">
|
||||||
|
<renderTextHelper.Tag
|
||||||
|
Enums={HouseChargeStandardsCalculationPeriodEnum}
|
||||||
|
value={model?.calculation_period}
|
||||||
|
/>
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="生成日期">
|
||||||
|
{model?.auto_date || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="启用滞纳金">
|
||||||
|
{model?.has_late_fee ? '是' : '否'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
{model?.has_late_fee && (
|
||||||
|
<>
|
||||||
|
<ProDescriptions.Item label="滞纳金起算天数">
|
||||||
|
{model?.late_fee_start_days || '-'} 天
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="滞纳金费率">
|
||||||
|
{model?.late_fee_rate || '-'} %/天
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="滞纳金封顶天数">
|
||||||
|
{model?.late_fee_cap_days || '-'} 天
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
<ProDescriptions.Item label="申请人">
|
||||||
|
{props?.item?.applicant_name || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="申请时间">
|
||||||
|
{props?.item?.created_at || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="备注" span={2}>
|
||||||
|
{model?.remark || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
</ProDescriptions>
|
||||||
|
</ProCard>
|
||||||
|
</Space>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
129
src/pages/approval/common_info/ContractInfo.tsx
Normal file
129
src/pages/approval/common_info/ContractInfo.tsx
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
import { MyBetaModalFormProps, MyButtons, renderTextHelper } from '@/common';
|
||||||
|
|
||||||
|
import {
|
||||||
|
ContractsContractNatureEnum,
|
||||||
|
ContractsSettlementModeEnum,
|
||||||
|
ContractTemplatesIncomeExpenseTypeEnum,
|
||||||
|
} from '@/gen/Enums';
|
||||||
|
import { ProCard, ProDescriptions } from '@ant-design/pro-components';
|
||||||
|
import { useNavigate } from '@umijs/max';
|
||||||
|
import { Form, Space } from 'antd';
|
||||||
|
|
||||||
|
export default function Update(props: MyBetaModalFormProps) {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Space direction="vertical" style={{ width: '100%' }}>
|
||||||
|
<ProCard title="基本信息" size="small">
|
||||||
|
<ProDescriptions size="small" column={2}>
|
||||||
|
<ProDescriptions.Item label="合同名称" span={2}>
|
||||||
|
{props?.item?.model?.name || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
|
||||||
|
<ProDescriptions.Item label="合同编号" span={2}>
|
||||||
|
<Space>
|
||||||
|
{props?.item?.model?.code || '-'}
|
||||||
|
<MyButtons.View
|
||||||
|
title="查看详情"
|
||||||
|
key="configInfo"
|
||||||
|
onClick={() => {
|
||||||
|
navigate(
|
||||||
|
`/contract/contracts/show/${props?.item?.model?.id}`,
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Space>
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="收支类型">
|
||||||
|
<renderTextHelper.Tag
|
||||||
|
Enums={ContractTemplatesIncomeExpenseTypeEnum}
|
||||||
|
value={props?.item?.model?.income_expense_type}
|
||||||
|
/>
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="合同性质">
|
||||||
|
<renderTextHelper.Tag
|
||||||
|
Enums={ContractsContractNatureEnum}
|
||||||
|
value={props?.item?.model?.contract_nature}
|
||||||
|
/>
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="合同类型">
|
||||||
|
{props?.item?.model?.contract_type_name || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="结算模式">
|
||||||
|
<renderTextHelper.Tag
|
||||||
|
Enums={ContractsSettlementModeEnum}
|
||||||
|
value={props?.item?.model?.settlement_mode}
|
||||||
|
/>
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="合同金额">
|
||||||
|
{props?.item?.model?.total_amount &&
|
||||||
|
props?.item?.model?.total_amount !== '-'
|
||||||
|
? parseFloat(props?.item?.model?.total_amount).toFixed(2)
|
||||||
|
: '-'}
|
||||||
|
元
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="保证金金额">
|
||||||
|
{props?.item?.model?.deposit_amount &&
|
||||||
|
props?.item?.model?.deposit_amount !== '-'
|
||||||
|
? parseFloat(props?.item?.model?.deposit_amount).toFixed(2)
|
||||||
|
: '-'}
|
||||||
|
元
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="签约主体">
|
||||||
|
{props?.item?.model?.sign_subject || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="签约部门">
|
||||||
|
{props?.item?.model?.sign_department || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="关联项目">
|
||||||
|
{props?.item?.model?.project_name || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="合同对接人">
|
||||||
|
{props?.item?.model?.contract_liaison || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="合同有效期" span={2}>
|
||||||
|
{props?.item?.model?.start_time?.substring(0, 10)}至
|
||||||
|
{props?.item?.model?.end_time?.substring(0, 10)}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="申请时间" span={2}>
|
||||||
|
{props?.item?.created_at || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="附件" span={2}>
|
||||||
|
{props?.item?.model?.attachments.map((item: any) => {
|
||||||
|
const handleDownload = async (e: React.MouseEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
try {
|
||||||
|
const response = await fetch(item.url);
|
||||||
|
const blob = await response.blob();
|
||||||
|
const url = window.URL.createObjectURL(blob);
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = item.name;
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
window.URL.revokeObjectURL(url);
|
||||||
|
document.body.removeChild(a);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('下载失败:', error);
|
||||||
|
// 如果下载失败,则在新窗口打开
|
||||||
|
window.open(item.url, '_blank');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div key={item.url}>
|
||||||
|
<a href={item.url} onClick={handleDownload}>
|
||||||
|
{item.name};
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
</ProDescriptions>
|
||||||
|
</ProCard>
|
||||||
|
</Space>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
162
src/pages/approval/common_info/ContractPaymentInfo.tsx
Normal file
162
src/pages/approval/common_info/ContractPaymentInfo.tsx
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
import { MyBetaModalFormProps, MyButtons, renderTextHelper } from '@/common';
|
||||||
|
import { ContractBillsIncomeExpenseTypeEnum } from '@/gen/Enums';
|
||||||
|
|
||||||
|
import { ProCard, ProDescriptions } from '@ant-design/pro-components';
|
||||||
|
import { useNavigate } from '@umijs/max';
|
||||||
|
import { Form, Space } from 'antd';
|
||||||
|
|
||||||
|
export default function Update(props: MyBetaModalFormProps) {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Space direction="vertical" style={{ width: '100%' }}>
|
||||||
|
<ProCard title="基本信息" size="small">
|
||||||
|
<ProDescriptions size="small" column={2}>
|
||||||
|
<ProDescriptions.Item label="标的名称" span={2}>
|
||||||
|
<Space>
|
||||||
|
{props?.item?.model?.name || '-'}
|
||||||
|
<MyButtons.View
|
||||||
|
title="查看合同"
|
||||||
|
key="configInfo"
|
||||||
|
onClick={() => {
|
||||||
|
navigate(
|
||||||
|
`/contract/contracts/show/${props?.item?.model?.contracts_id}`,
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Space>
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
|
||||||
|
<ProDescriptions.Item label="支付金额">
|
||||||
|
{props?.item?.model?.amount && props?.item?.model?.amount !== '-'
|
||||||
|
? (parseFloat(props?.item?.model?.amount) / 100).toFixed(2)
|
||||||
|
: '-'}
|
||||||
|
元
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="账单变更">
|
||||||
|
<renderTextHelper.Tag
|
||||||
|
Enums={ContractBillsIncomeExpenseTypeEnum}
|
||||||
|
value={props?.item?.model?.cost_type}
|
||||||
|
/>
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="变更金额">
|
||||||
|
{props?.item?.model?.cost_amount &&
|
||||||
|
props?.item?.model?.cost_amount !== '-'
|
||||||
|
? (parseFloat(props?.item?.model?.cost_amount) / 100).toFixed(2)
|
||||||
|
: '-'}
|
||||||
|
元
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="变更后金额">
|
||||||
|
{(() => {
|
||||||
|
const amount = props?.item?.model?.amount
|
||||||
|
? parseFloat(props?.item?.model?.amount) / 100
|
||||||
|
: 0;
|
||||||
|
const costAmount = props?.item?.model?.cost_amount
|
||||||
|
? parseFloat(props?.item?.model?.cost_amount) / 100
|
||||||
|
: 0;
|
||||||
|
const costType = props?.item?.model?.cost_type;
|
||||||
|
|
||||||
|
let finalAmount = amount;
|
||||||
|
if (costType === 'Increase') {
|
||||||
|
finalAmount = amount + costAmount;
|
||||||
|
} else if (costType === 'Decrease') {
|
||||||
|
finalAmount = amount - costAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
return finalAmount >= 0 ? finalAmount.toFixed(2) : '0.00';
|
||||||
|
})()}
|
||||||
|
元
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="申请人" span={2}>
|
||||||
|
{props?.item?.applicant_name || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="申请时间" span={2}>
|
||||||
|
{props?.item?.created_at || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="标的说明" span={2}>
|
||||||
|
{props?.item?.model?.completed_description || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="标的附件" span={2}>
|
||||||
|
{props?.item?.model?.completed_attachments &&
|
||||||
|
props?.item?.model?.completed_attachments.length > 0 && (
|
||||||
|
<div style={{ marginBottom: 8 }}>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
props?.item?.model?.completed_attachments.forEach(
|
||||||
|
(file: any, index: number) => {
|
||||||
|
setTimeout(async () => {
|
||||||
|
const fileName = file?.name || `文件${index + 1}`;
|
||||||
|
try {
|
||||||
|
const response = await fetch(file?.url);
|
||||||
|
const blob = await response.blob();
|
||||||
|
const url = window.URL.createObjectURL(blob);
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = fileName;
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
window.URL.revokeObjectURL(url);
|
||||||
|
document.body.removeChild(a);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('下载失败:', error);
|
||||||
|
window.open(file?.url, '_blank');
|
||||||
|
}
|
||||||
|
}, index * 100); // 延迟100ms避免浏览器阻塞
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
padding: '4px 12px',
|
||||||
|
marginBottom: '8px',
|
||||||
|
backgroundColor: '#1890ff',
|
||||||
|
color: 'white',
|
||||||
|
border: 'none',
|
||||||
|
borderRadius: '4px',
|
||||||
|
cursor: 'pointer',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
全部下载
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{props?.item?.model?.completed_attachments?.map(
|
||||||
|
(file: any, index: number) => {
|
||||||
|
const fileName = file?.name || `文件${index + 1}`;
|
||||||
|
|
||||||
|
const handleDownload = async (e: React.MouseEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
try {
|
||||||
|
const response = await fetch(file?.url);
|
||||||
|
const blob = await response.blob();
|
||||||
|
const url = window.URL.createObjectURL(blob);
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = fileName;
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
window.URL.revokeObjectURL(url);
|
||||||
|
document.body.removeChild(a);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('下载失败:', error);
|
||||||
|
// 如果下载失败,则在新窗口打开
|
||||||
|
window.open(file?.url, '_blank');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div key={index}>
|
||||||
|
<a href={file?.url} onClick={handleDownload}>
|
||||||
|
{fileName}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
) || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
</ProDescriptions>
|
||||||
|
</ProCard>
|
||||||
|
</Space>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
94
src/pages/approval/common_info/ContractTerminationInfo.tsx
Normal file
94
src/pages/approval/common_info/ContractTerminationInfo.tsx
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
import { MyBetaModalFormProps, MyButtons, renderTextHelper } from '@/common';
|
||||||
|
|
||||||
|
import {
|
||||||
|
ContractsContractNatureEnum,
|
||||||
|
ContractsSettlementModeEnum,
|
||||||
|
ContractTemplatesIncomeExpenseTypeEnum,
|
||||||
|
} from '@/gen/Enums';
|
||||||
|
import { ProCard, ProDescriptions } from '@ant-design/pro-components';
|
||||||
|
import { useNavigate } from '@umijs/max';
|
||||||
|
import { Form, Space } from 'antd';
|
||||||
|
|
||||||
|
export default function Update(props: MyBetaModalFormProps) {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Space direction="vertical" style={{ width: '100%' }}>
|
||||||
|
<ProCard title="基本信息" size="small">
|
||||||
|
<ProDescriptions size="small" column={2}>
|
||||||
|
<ProDescriptions.Item label="合同名称" span={2}>
|
||||||
|
{props?.item?.model?.name || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
|
||||||
|
<ProDescriptions.Item label="合同编号" span={2}>
|
||||||
|
<Space>
|
||||||
|
{props?.item?.model?.code || '-'}
|
||||||
|
<MyButtons.View
|
||||||
|
title="查看详情"
|
||||||
|
key="configInfo"
|
||||||
|
onClick={() => {
|
||||||
|
navigate(
|
||||||
|
`/contract/contracts/show/${props?.item?.model?.id}`,
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Space>
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="收支类型">
|
||||||
|
<renderTextHelper.Tag
|
||||||
|
Enums={ContractTemplatesIncomeExpenseTypeEnum}
|
||||||
|
value={props?.item?.model?.income_expense_type}
|
||||||
|
/>
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="合同性质">
|
||||||
|
<renderTextHelper.Tag
|
||||||
|
Enums={ContractsContractNatureEnum}
|
||||||
|
value={props?.item?.model?.contract_nature}
|
||||||
|
/>
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="合同类型">
|
||||||
|
{props?.item?.model?.contract_type_name || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="结算模式">
|
||||||
|
<renderTextHelper.Tag
|
||||||
|
Enums={ContractsSettlementModeEnum}
|
||||||
|
value={props?.item?.model?.settlement_mode}
|
||||||
|
/>
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="合同金额">
|
||||||
|
{props?.item?.model?.total_amount || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="保证金金额">
|
||||||
|
{props?.item?.model?.deposit_amount || '无'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="签约主体">
|
||||||
|
{props?.item?.model?.sign_subject || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
|
||||||
|
<ProDescriptions.Item label="关联项目">
|
||||||
|
{props?.item?.model?.project_name || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
|
||||||
|
<ProDescriptions.Item label="合同有效期" span={2}>
|
||||||
|
{props?.item?.model?.start_time?.substring(0, 10)}至
|
||||||
|
{props?.item?.model?.end_time?.substring(0, 10)}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
|
||||||
|
<ProDescriptions.Item label="申请人" span={2}>
|
||||||
|
{props?.item?.model?.applicant?.name || '-'}
|
||||||
|
{props?.item?.model?.applicant?.phone || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="申请时间" span={2}>
|
||||||
|
{props?.item?.created_at || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="申请说明" span={2}>
|
||||||
|
{props?.item?.model?.remark || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
</ProDescriptions>
|
||||||
|
</ProCard>
|
||||||
|
</Space>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
64
src/pages/approval/common_info/RefundInfo.tsx
Normal file
64
src/pages/approval/common_info/RefundInfo.tsx
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import { MyBetaModalFormProps, renderTextHelper } from '@/common';
|
||||||
|
import { RefundsTypeEnum } from '@/gen/Enums';
|
||||||
|
import BIllInfo from '@/pages/bills/house_bills/modals/BIllInfo';
|
||||||
|
|
||||||
|
import { ProCard, ProDescriptions } from '@ant-design/pro-components';
|
||||||
|
import { useNavigate } from '@umijs/max';
|
||||||
|
import { Form, Space } from 'antd';
|
||||||
|
|
||||||
|
export default function Update(props: MyBetaModalFormProps) {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Space direction="vertical" style={{ width: '100%' }}>
|
||||||
|
<ProCard title="基本信息" size="small">
|
||||||
|
<ProDescriptions size="small" column={2}>
|
||||||
|
<ProDescriptions.Item label="申请事项" span={2}>
|
||||||
|
{props?.item?.title || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="账单类型">
|
||||||
|
<renderTextHelper.Tag
|
||||||
|
Enums={RefundsTypeEnum}
|
||||||
|
value={props?.item?.model?.type}
|
||||||
|
/>
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="退款金额">
|
||||||
|
<Space>
|
||||||
|
{props?.item?.model?.refund_amount &&
|
||||||
|
props?.item?.model?.refund_amount !== '-'
|
||||||
|
? (
|
||||||
|
parseFloat(props?.item?.model?.refund_amount) / 100
|
||||||
|
).toFixed(2)
|
||||||
|
: '-'}
|
||||||
|
元
|
||||||
|
<BIllInfo
|
||||||
|
item={{
|
||||||
|
id: props?.item?.model?.refundable_id,
|
||||||
|
type: 'link',
|
||||||
|
}}
|
||||||
|
title="查看账单"
|
||||||
|
/>
|
||||||
|
</Space>
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="付款信息" span={2}>
|
||||||
|
{props?.item?.model?.payer_name || '-'}|
|
||||||
|
{props?.item?.model?.payer_bank || '-'}|
|
||||||
|
{props?.item?.model?.payer_account || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="收款信息" span={2}>
|
||||||
|
{props?.item?.model?.payee_name || '-'}
|
||||||
|
{props?.item?.model?.payee_bank || '-'}
|
||||||
|
{props?.item?.model?.payee_account || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
|
||||||
|
<ProDescriptions.Item label="申请时间">
|
||||||
|
{props?.item?.created_at || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
</ProDescriptions>
|
||||||
|
</ProCard>
|
||||||
|
</Space>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
149
src/pages/approval/common_info/SealInfo.tsx
Normal file
149
src/pages/approval/common_info/SealInfo.tsx
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
import { MyBetaModalFormProps, renderTextHelper } from '@/common';
|
||||||
|
import { CompanySealsTypeEnum } from '@/gen/Enums';
|
||||||
|
|
||||||
|
// import SealInfo from '@/pages/contract/contracts_other/modals/Show';
|
||||||
|
import { ProCard, ProDescriptions } from '@ant-design/pro-components';
|
||||||
|
import { useNavigate } from '@umijs/max';
|
||||||
|
import { Form, Space } from 'antd';
|
||||||
|
|
||||||
|
export default function Update(props: MyBetaModalFormProps) {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Space direction="vertical" style={{ width: '100%' }}>
|
||||||
|
<ProCard title="基本信息" size="small">
|
||||||
|
<ProDescriptions size="small" column={2}>
|
||||||
|
<ProDescriptions.Item label="申请事项" span={2}>
|
||||||
|
<Space>
|
||||||
|
{props?.item?.title || '-'}
|
||||||
|
{/* <SealInfo
|
||||||
|
item={{
|
||||||
|
id: props?.item?.model?.id,
|
||||||
|
type: 'link',
|
||||||
|
}}
|
||||||
|
title="查看详情"
|
||||||
|
/> */}
|
||||||
|
</Space>
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
|
||||||
|
{/* 基本信息 */}
|
||||||
|
<ProDescriptions.Item label="关联项目">
|
||||||
|
{props?.item?.asset_project?.name || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="申请人">
|
||||||
|
{props?.item?.model?.company_employee_name || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
|
||||||
|
{/* 用印详情 */}
|
||||||
|
<ProDescriptions.Item label="申请份数">
|
||||||
|
{props?.item?.model?.copies ||
|
||||||
|
props?.item?.model?.number_contract_copies ||
|
||||||
|
'-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="申请时间">
|
||||||
|
{props?.item?.created_at || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="简要说明" span={2}>
|
||||||
|
{props?.item?.model?.reason || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
{/* 印章信息 */}
|
||||||
|
<ProDescriptions.Item label="申请印章" span={2}>
|
||||||
|
{(props?.item?.model?.seals || props?.item?.model?.seals)?.map(
|
||||||
|
(sealId: string, index: number) => (
|
||||||
|
<Space key={index} style={{ marginRight: 16 }}>
|
||||||
|
{props?.item?.model?.seals?.[index]?.company_supplier
|
||||||
|
?.name || '-'}
|
||||||
|
<renderTextHelper.Tag
|
||||||
|
Enums={CompanySealsTypeEnum}
|
||||||
|
value={props?.item?.model?.seals?.[index]?.type || '-'}
|
||||||
|
key={`seal_id_${index}`}
|
||||||
|
/>
|
||||||
|
</Space>
|
||||||
|
),
|
||||||
|
) || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
|
||||||
|
{/* 申请信息 */}
|
||||||
|
|
||||||
|
<ProDescriptions.Item label="附件" span={3}>
|
||||||
|
{props?.item?.model?.files &&
|
||||||
|
props?.item?.model?.files.length > 0 && (
|
||||||
|
<div style={{ marginBottom: 8 }}>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
props?.item?.model?.files.forEach(
|
||||||
|
(file: any, index: number) => {
|
||||||
|
setTimeout(async () => {
|
||||||
|
const fileName = file?.name || `文件${index + 1}`;
|
||||||
|
try {
|
||||||
|
const response = await fetch(file?.url);
|
||||||
|
const blob = await response.blob();
|
||||||
|
const url = window.URL.createObjectURL(blob);
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = fileName;
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
window.URL.revokeObjectURL(url);
|
||||||
|
document.body.removeChild(a);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('下载失败:', error);
|
||||||
|
window.open(file?.url, '_blank');
|
||||||
|
}
|
||||||
|
}, index * 100); // 延迟100ms避免浏览器阻塞
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
padding: '4px 12px',
|
||||||
|
marginBottom: '8px',
|
||||||
|
backgroundColor: '#1890ff',
|
||||||
|
color: 'white',
|
||||||
|
border: 'none',
|
||||||
|
borderRadius: '4px',
|
||||||
|
cursor: 'pointer',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
全部下载
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{props?.item?.model?.files?.map((file: any, index: number) => {
|
||||||
|
const fileName = file?.name || `文件${index + 1}`;
|
||||||
|
|
||||||
|
const handleDownload = async (e: React.MouseEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
try {
|
||||||
|
const response = await fetch(file?.url);
|
||||||
|
const blob = await response.blob();
|
||||||
|
const url = window.URL.createObjectURL(blob);
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = fileName;
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
window.URL.revokeObjectURL(url);
|
||||||
|
document.body.removeChild(a);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('下载失败:', error);
|
||||||
|
// 如果下载失败,则在新窗口打开
|
||||||
|
window.open(file?.url, '_blank');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div key={index}>
|
||||||
|
<a href={file?.url} onClick={handleDownload}>
|
||||||
|
{fileName}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}) || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
</ProDescriptions>
|
||||||
|
</ProCard>
|
||||||
|
</Space>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
69
src/pages/approval/common_info/TemporaryBillUpdateInfo.tsx
Normal file
69
src/pages/approval/common_info/TemporaryBillUpdateInfo.tsx
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import { MyBetaModalFormProps } from '@/common';
|
||||||
|
import BIllInfo from '@/pages/bills/temporary/modals/BIllInfo';
|
||||||
|
|
||||||
|
import { ProCard, ProDescriptions } from '@ant-design/pro-components';
|
||||||
|
import { Space } from 'antd';
|
||||||
|
|
||||||
|
export default function BillUpdateInfo(props: MyBetaModalFormProps) {
|
||||||
|
const originalData = props?.item?.model?.original_data;
|
||||||
|
const newData = props?.item?.model?.new_data;
|
||||||
|
|
||||||
|
// 格式化金额
|
||||||
|
const formatAmount = (amount: any) => {
|
||||||
|
if (!amount || amount === '-') return '-';
|
||||||
|
return parseFloat(amount).toFixed(2) + ' 元';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 渲染数据项
|
||||||
|
const renderDataItems = (data: any) => (
|
||||||
|
<ProDescriptions size="small" column={1}>
|
||||||
|
<ProDescriptions.Item label="账单金额">
|
||||||
|
{formatAmount(data?.amount)}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="账单月份">
|
||||||
|
{data?.year}-{String(data?.month).padStart(2, '0')}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="备注">
|
||||||
|
{data?.remark || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
</ProDescriptions>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Space direction="vertical" style={{ width: '100%' }}>
|
||||||
|
<ProCard title="基本信息" size="small">
|
||||||
|
<ProDescriptions size="small" column={2}>
|
||||||
|
<ProDescriptions.Item label="申请事项">
|
||||||
|
{props?.item?.title || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="关联原账单">
|
||||||
|
<BIllInfo
|
||||||
|
item={{
|
||||||
|
id: props?.item?.model?.model_id,
|
||||||
|
type: 'link',
|
||||||
|
}}
|
||||||
|
title="查看账单"
|
||||||
|
/>
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="申请人">
|
||||||
|
{props?.item?.applicant_name || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="申请时间">
|
||||||
|
{props?.item?.created_at || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
</ProDescriptions>
|
||||||
|
</ProCard>
|
||||||
|
|
||||||
|
<ProCard title="修改内容对比" size="small" split="vertical">
|
||||||
|
<ProCard title="修改前" type="inner" bordered headerBordered>
|
||||||
|
{renderDataItems(originalData)}
|
||||||
|
</ProCard>
|
||||||
|
<ProCard title="修改后" type="inner" bordered headerBordered>
|
||||||
|
{renderDataItems(newData)}
|
||||||
|
</ProCard>
|
||||||
|
</ProCard>
|
||||||
|
</Space>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -11,7 +11,9 @@ import {
|
|||||||
} from '@/gen/Enums';
|
} from '@/gen/Enums';
|
||||||
import { ProTable } from '@ant-design/pro-components';
|
import { ProTable } from '@ant-design/pro-components';
|
||||||
import { Space } from 'antd';
|
import { Space } from 'antd';
|
||||||
export default function Index({ title = '我的发起' }) {
|
import AuditShow from '../common_info/AuditShow';
|
||||||
|
|
||||||
|
export default function Index({ title = '我发起的' }) {
|
||||||
return (
|
return (
|
||||||
<MyPageContainer
|
<MyPageContainer
|
||||||
title={title}
|
title={title}
|
||||||
@ -61,21 +63,11 @@ export default function Index({ title = '我的发起' }) {
|
|||||||
item?.approval_records?.[0]?.company_employee?.phone || ''
|
item?.approval_records?.[0]?.company_employee?.phone || ''
|
||||||
}`,
|
}`,
|
||||||
},
|
},
|
||||||
// {
|
|
||||||
// title: '项目ID',
|
|
||||||
// dataIndex: 'asset_projects_id',
|
|
||||||
// hidden: true,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// title: '申请人',
|
|
||||||
// dataIndex: 'applicant_name',
|
|
||||||
// search: false,
|
|
||||||
// },
|
|
||||||
MyColumns.CreatedAt(),
|
MyColumns.CreatedAt(),
|
||||||
MyColumns.Option({
|
MyColumns.Option({
|
||||||
render: (_, item: any, index, action) => (
|
render: (_, item: any, index, action) => (
|
||||||
<Space key={index}>
|
<Space key={index}>
|
||||||
{/* <Update item={item} reload={action?.reload} title={title} /> */}
|
<AuditShow item={item} reload={action?.reload} title={title} />
|
||||||
<MyButtons.Default
|
<MyButtons.Default
|
||||||
title="撤销"
|
title="撤销"
|
||||||
isConfirm
|
isConfirm
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { MyColumns, MyPageContainer, MyProTableProps } from '@/common';
|
import { MyColumns, MyPageContainer, MyProTableProps } from '@/common';
|
||||||
|
import { Selects } from '@/components/Select';
|
||||||
import { Apis } from '@/gen/Apis';
|
import { Apis } from '@/gen/Apis';
|
||||||
import {
|
import {
|
||||||
ApprovalInstancesStatusEnum,
|
ApprovalInstancesStatusEnum,
|
||||||
@ -6,8 +7,8 @@ import {
|
|||||||
} from '@/gen/Enums';
|
} from '@/gen/Enums';
|
||||||
import { ProTable } from '@ant-design/pro-components';
|
import { ProTable } from '@ant-design/pro-components';
|
||||||
import { Space } from 'antd';
|
import { Space } from 'antd';
|
||||||
import Show from './modals/Show';
|
import AuditShow from '../common_info/AuditShow';
|
||||||
export default function Index({ title = '我的已办' }) {
|
export default function Index({ title = '我的发起' }) {
|
||||||
return (
|
return (
|
||||||
<MyPageContainer
|
<MyPageContainer
|
||||||
title={title}
|
title={title}
|
||||||
@ -27,6 +28,11 @@ export default function Index({ title = '我的已办' }) {
|
|||||||
headerTitle={title}
|
headerTitle={title}
|
||||||
columns={[
|
columns={[
|
||||||
MyColumns.ID({ search: false }),
|
MyColumns.ID({ search: false }),
|
||||||
|
Selects?.AssetProjects({
|
||||||
|
title: '选择项目',
|
||||||
|
key: 'asset_projects_id',
|
||||||
|
hidden: true,
|
||||||
|
}),
|
||||||
{
|
{
|
||||||
title: '申请事项',
|
title: '申请事项',
|
||||||
dataIndex: 'title',
|
dataIndex: 'title',
|
||||||
@ -41,18 +47,19 @@ export default function Index({ title = '我的已办' }) {
|
|||||||
title: '状态',
|
title: '状态',
|
||||||
dataIndex: 'status',
|
dataIndex: 'status',
|
||||||
valueEnum: ApprovalInstancesStatusEnum,
|
valueEnum: ApprovalInstancesStatusEnum,
|
||||||
|
search: false,
|
||||||
}),
|
}),
|
||||||
MyColumns.EnumTag({
|
MyColumns.EnumTag({
|
||||||
dataIndex: 'type',
|
dataIndex: 'type',
|
||||||
title: '业务类型',
|
title: '业务类型',
|
||||||
valueEnum: ApprovalTemplatesTypeEnum,
|
valueEnum: ApprovalTemplatesTypeEnum,
|
||||||
search: false,
|
|
||||||
}),
|
}),
|
||||||
MyColumns.CreatedAt(),
|
// MyColumns.CreatedAt(),
|
||||||
|
MyColumns.UpdatedAt(),
|
||||||
MyColumns.Option({
|
MyColumns.Option({
|
||||||
render: (_, item: any, index, action) => (
|
render: (_, item: any, index, action) => (
|
||||||
<Space key={index}>
|
<Space key={index}>
|
||||||
<Show item={item} reload={action?.reload} title={title} />
|
<AuditShow item={item} reload={action?.reload} title={title} />
|
||||||
</Space>
|
</Space>
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
|
|||||||
@ -1,250 +0,0 @@
|
|||||||
import { MyBetaModalFormProps, MyButtons, MyModalFormProps } from '@/common';
|
|
||||||
|
|
||||||
import { Apis } from '@/gen/Apis';
|
|
||||||
// import {
|
|
||||||
// ContractsContractNatureEnum,
|
|
||||||
// ContractsSettlementModeEnum,
|
|
||||||
// ContractTemplatesIncomeExpenseTypeEnum,
|
|
||||||
// RefundsTypeEnum,
|
|
||||||
// } from '@/gen/Enums';
|
|
||||||
import BIllInfo from '@/pages/bills/house_bills/modals/BIllInfo';
|
|
||||||
import {
|
|
||||||
BetaSchemaForm,
|
|
||||||
ProCard,
|
|
||||||
ProDescriptions,
|
|
||||||
} from '@ant-design/pro-components';
|
|
||||||
import { useNavigate } from '@umijs/max';
|
|
||||||
import { Form, Space, Steps } from 'antd';
|
|
||||||
|
|
||||||
export default function Update(props: MyBetaModalFormProps) {
|
|
||||||
const [form] = Form.useForm();
|
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<BetaSchemaForm<ApiTypes.Archive.HouseRegisters.Update>
|
|
||||||
{...MyModalFormProps.props}
|
|
||||||
title={props.title}
|
|
||||||
trigger={<MyButtons.Default title="查看" type="primary" />}
|
|
||||||
wrapperCol={{ span: 24 }}
|
|
||||||
width="600px"
|
|
||||||
key={new Date().getTime()}
|
|
||||||
form={form}
|
|
||||||
onOpenChange={() => {
|
|
||||||
if (props?.item?.id) {
|
|
||||||
Apis.Approval.ApprovalInstances.Show({
|
|
||||||
id: props.item?.model_id,
|
|
||||||
}).then((res) => {
|
|
||||||
form.setFieldsValue({
|
|
||||||
info_display: res?.data,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
columns={[
|
|
||||||
{
|
|
||||||
// title: '登记信息',
|
|
||||||
dataIndex: 'info_display',
|
|
||||||
valueType: 'text',
|
|
||||||
renderFormItem: (_, config) => (
|
|
||||||
<Space direction="vertical" style={{ width: '100%' }}>
|
|
||||||
<div>
|
|
||||||
{/* 退款详情 */}
|
|
||||||
{config?.value?.type === 'Refund' && (
|
|
||||||
<ProCard size="small">
|
|
||||||
<ProDescriptions size="small" column={2}>
|
|
||||||
<ProDescriptions.Item label="申请事项" span={2}>
|
|
||||||
{config?.value?.title || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
{/* <ProDescriptions.Item label="账单类型">
|
|
||||||
<renderTextHelper.Tag
|
|
||||||
Enums={RefundsTypeEnum}
|
|
||||||
value={config?.value?.model?.type}
|
|
||||||
/>
|
|
||||||
</ProDescriptions.Item> */}
|
|
||||||
<ProDescriptions.Item label="退款金额">
|
|
||||||
<Space>
|
|
||||||
{config?.value?.model?.refund_amount || '-'}
|
|
||||||
元
|
|
||||||
<BIllInfo
|
|
||||||
item={{
|
|
||||||
id: config?.value?.model?.refundable_id,
|
|
||||||
type: 'link',
|
|
||||||
}}
|
|
||||||
title="查看账单"
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="付款信息" span={2}>
|
|
||||||
{config?.value?.model?.payer_name || '-'}|
|
|
||||||
{config?.value?.model?.payer_bank || '-'}|
|
|
||||||
{config?.value?.model?.payer_account || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="收款信息" span={2}>
|
|
||||||
{config?.value?.model?.payee_name || '-'}
|
|
||||||
{config?.value?.model?.payee_bank || '-'}
|
|
||||||
{config?.value?.model?.payee_account || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="申请人" span={2}>
|
|
||||||
{props?.item?.applicant?.name || '-'}:
|
|
||||||
{props?.item?.applicant?.phone || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="申请时间" span={2}>
|
|
||||||
{props?.item?.created_at || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
</ProDescriptions>
|
|
||||||
</ProCard>
|
|
||||||
)}
|
|
||||||
{/* 合同详情 */}
|
|
||||||
{config?.value?.type === 'Contract' && (
|
|
||||||
<ProCard size="small">
|
|
||||||
<ProDescriptions size="small" column={2}>
|
|
||||||
<ProDescriptions.Item label="合同名称" span={2}>
|
|
||||||
{config?.value?.model?.name || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
|
|
||||||
<ProDescriptions.Item label="合同编号" span={2}>
|
|
||||||
<Space>
|
|
||||||
{config?.value?.model?.code || '-'}
|
|
||||||
<BIllInfo
|
|
||||||
item={{
|
|
||||||
id: config?.value?.model?.refundable_id,
|
|
||||||
type: 'Contract',
|
|
||||||
}}
|
|
||||||
title="查看合同"
|
|
||||||
/>
|
|
||||||
<MyButtons.View
|
|
||||||
title="查看"
|
|
||||||
key="configInfo"
|
|
||||||
onClick={() => {
|
|
||||||
navigate(
|
|
||||||
`/contract/contracts/show/${config?.value?.model?.id}`,
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
{/* <ProDescriptions.Item label="收支类型">
|
|
||||||
<renderTextHelper.Tag
|
|
||||||
Enums={ContractTemplatesIncomeExpenseTypeEnum}
|
|
||||||
value={config?.value?.model?.income_expense_type}
|
|
||||||
/>
|
|
||||||
</ProDescriptions.Item> */}
|
|
||||||
{/* <ProDescriptions.Item label="合同性质">
|
|
||||||
<renderTextHelper.Tag
|
|
||||||
Enums={ContractsContractNatureEnum}
|
|
||||||
value={config?.value?.model?.contract_nature}
|
|
||||||
/>
|
|
||||||
</ProDescriptions.Item> */}
|
|
||||||
<ProDescriptions.Item label="合同类型">
|
|
||||||
{config?.value?.model?.contract_type_name || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
{/* <ProDescriptions.Item label="结算模式">
|
|
||||||
<renderTextHelper.Tag
|
|
||||||
Enums={ContractsSettlementModeEnum}
|
|
||||||
value={config?.value?.model?.settlement_mode}
|
|
||||||
/>
|
|
||||||
</ProDescriptions.Item> */}
|
|
||||||
<ProDescriptions.Item label="合同金额">
|
|
||||||
{config?.value?.model?.total_amount || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="保证金金额">
|
|
||||||
{config?.value?.model?.deposit_amount || '无'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="签约主体">
|
|
||||||
{config?.value?.model?.sign_subject || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="签约部门">
|
|
||||||
{config?.value?.model?.sign_department || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="关联项目">
|
|
||||||
{config?.value?.model?.project_name || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="合同对接人">
|
|
||||||
{config?.value?.model?.contract_liaison || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="合同有效期" span={2}>
|
|
||||||
{config?.value?.model?.start_time?.substring(0, 10)}至
|
|
||||||
{config?.value?.model?.end_time?.substring(0, 10)}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="申请人" span={2}>
|
|
||||||
{props?.item?.applicant?.name || '-'}:
|
|
||||||
{props?.item?.applicant?.phone || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="申请时间" span={2}>
|
|
||||||
{props?.item?.created_at || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="附件" span={2}>
|
|
||||||
{config?.value?.model?.attachments.map((item: any) => {
|
|
||||||
const handleDownload = async (
|
|
||||||
e: React.MouseEvent,
|
|
||||||
) => {
|
|
||||||
e.preventDefault();
|
|
||||||
try {
|
|
||||||
const response = await fetch(item.url);
|
|
||||||
const blob = await response.blob();
|
|
||||||
const url = window.URL.createObjectURL(blob);
|
|
||||||
const a = document.createElement('a');
|
|
||||||
a.href = url;
|
|
||||||
a.download = item.name;
|
|
||||||
document.body.appendChild(a);
|
|
||||||
a.click();
|
|
||||||
window.URL.revokeObjectURL(url);
|
|
||||||
document.body.removeChild(a);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('下载失败:', error);
|
|
||||||
// 如果下载失败,则在新窗口打开
|
|
||||||
window.open(item.url, '_blank');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div key={item.url}>
|
|
||||||
<a href={item.url} onClick={handleDownload}>
|
|
||||||
{item.name};
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
</ProDescriptions>
|
|
||||||
</ProCard>
|
|
||||||
)}
|
|
||||||
<ProCard>
|
|
||||||
<ProDescriptions>
|
|
||||||
<ProDescriptions.Item label="审核记录">
|
|
||||||
<Space direction="vertical" style={{ width: '100%' }}>
|
|
||||||
<Steps
|
|
||||||
progressDot
|
|
||||||
direction="vertical"
|
|
||||||
current={config?.value?.approval_records?.length}
|
|
||||||
items={config?.value?.approval_records?.map(
|
|
||||||
(item: any) =>
|
|
||||||
item?.node_type === 'Approver'
|
|
||||||
? {
|
|
||||||
title: `${
|
|
||||||
item.company_employee?.name || '-'
|
|
||||||
}-${item?.company_employee?.phone}`,
|
|
||||||
description: `${
|
|
||||||
item.status === 'Approved'
|
|
||||||
? `通过 - ${item.opinion || '-'} - ${
|
|
||||||
item.created_at || '-'
|
|
||||||
}`
|
|
||||||
: '待审核'
|
|
||||||
}`,
|
|
||||||
}
|
|
||||||
: '',
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
</ProDescriptions>
|
|
||||||
</ProCard>
|
|
||||||
</div>
|
|
||||||
</Space>
|
|
||||||
),
|
|
||||||
colProps: { span: 24 },
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,9 +1,4 @@
|
|||||||
import {
|
import { MyColumns, MyPageContainer, MyProTableProps } from '@/common';
|
||||||
MyButtons,
|
|
||||||
MyColumns,
|
|
||||||
MyPageContainer,
|
|
||||||
MyProTableProps,
|
|
||||||
} from '@/common';
|
|
||||||
import { Apis } from '@/gen/Apis';
|
import { Apis } from '@/gen/Apis';
|
||||||
import {
|
import {
|
||||||
ApprovalInstancesStatusEnum,
|
ApprovalInstancesStatusEnum,
|
||||||
@ -11,6 +6,7 @@ import {
|
|||||||
} from '@/gen/Enums';
|
} from '@/gen/Enums';
|
||||||
import { ProTable } from '@ant-design/pro-components';
|
import { ProTable } from '@ant-design/pro-components';
|
||||||
import { Space } from 'antd';
|
import { Space } from 'antd';
|
||||||
|
|
||||||
import Audit from './modals/Audit';
|
import Audit from './modals/Audit';
|
||||||
import Forwarded from './modals/Forwarded';
|
import Forwarded from './modals/Forwarded';
|
||||||
export default function Index({ title = '我的待办' }) {
|
export default function Index({ title = '我的待办' }) {
|
||||||
@ -62,20 +58,7 @@ export default function Index({ title = '我的待办' }) {
|
|||||||
render: (_, item: any, index, action) => (
|
render: (_, item: any, index, action) => (
|
||||||
<Space key={index}>
|
<Space key={index}>
|
||||||
<Audit item={item} reload={action?.reload} title={title} />
|
<Audit item={item} reload={action?.reload} title={title} />
|
||||||
<Forwarded item={item} reload={action?.reload} title="转办" />
|
<Forwarded item={item} reload={action?.reload} title="转交" />
|
||||||
<MyButtons.Default
|
|
||||||
title="撤销"
|
|
||||||
isConfirm
|
|
||||||
description="确认撤销该申请吗?"
|
|
||||||
disabled={item.status !== 'Pending'}
|
|
||||||
color="danger"
|
|
||||||
variant="solid"
|
|
||||||
onConfirm={() =>
|
|
||||||
Apis.Approval.ApprovalInstances.Cancel({
|
|
||||||
id: item.id,
|
|
||||||
}).then(() => action?.reload())
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Space>
|
</Space>
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
|
|||||||
@ -3,20 +3,24 @@ import {
|
|||||||
MyButtons,
|
MyButtons,
|
||||||
MyFormItems,
|
MyFormItems,
|
||||||
MyModalFormProps,
|
MyModalFormProps,
|
||||||
renderTextHelper,
|
|
||||||
rulesHelper,
|
rulesHelper,
|
||||||
} from '@/common';
|
} from '@/common';
|
||||||
|
|
||||||
import { Apis } from '@/gen/Apis';
|
import { Apis } from '@/gen/Apis';
|
||||||
import { HouseRegistersStatusEnum, RefundsTypeEnum } from '@/gen/Enums';
|
import { HouseRegistersStatusEnum } from '@/gen/Enums';
|
||||||
import BIllInfo from '@/pages/bills/house_bills/modals/BIllInfo';
|
import { BetaSchemaForm } from '@ant-design/pro-components';
|
||||||
import {
|
|
||||||
BetaSchemaForm,
|
|
||||||
ProCard,
|
|
||||||
ProDescriptions,
|
|
||||||
} from '@ant-design/pro-components';
|
|
||||||
import { useNavigate } from '@umijs/max';
|
import { useNavigate } from '@umijs/max';
|
||||||
import { Form, message, Space, Steps } from 'antd';
|
import { Form, message, Space } from 'antd';
|
||||||
|
import ApprovalRecord from '../../common_info/ApprovalRecord';
|
||||||
|
import ArchiveBorrowInfo from '../../common_info/ArchiveBorrowInfo';
|
||||||
|
import BillUpdateInfo from '../../common_info/BillUpdateInfo';
|
||||||
|
import ChargeStandardInfo from '../../common_info/ChargeStandardInfo';
|
||||||
|
import ContractInfo from '../../common_info/ContractInfo';
|
||||||
|
import ContractPaymentInfo from '../../common_info/ContractPaymentInfo';
|
||||||
|
import ContractTerminationInfo from '../../common_info/ContractTerminationInfo';
|
||||||
|
import RefundInfo from '../../common_info/RefundInfo';
|
||||||
|
import SealInfo from '../../common_info/SealInfo';
|
||||||
|
import TemporaryBillUpdateInfo from '../../common_info/TemporaryBillUpdateInfo';
|
||||||
|
|
||||||
export default function Update(props: MyBetaModalFormProps) {
|
export default function Update(props: MyBetaModalFormProps) {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
@ -68,7 +72,7 @@ export default function Update(props: MyBetaModalFormProps) {
|
|||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
props.reload?.();
|
props.reload?.();
|
||||||
message.success(props.title + '成功');
|
message.success('审核成功!');
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.catch(() => false)
|
.catch(() => false)
|
||||||
@ -80,192 +84,34 @@ export default function Update(props: MyBetaModalFormProps) {
|
|||||||
valueType: 'text',
|
valueType: 'text',
|
||||||
renderFormItem: (_, config) => (
|
renderFormItem: (_, config) => (
|
||||||
<Space direction="vertical" style={{ width: '100%' }}>
|
<Space direction="vertical" style={{ width: '100%' }}>
|
||||||
<div>
|
{config?.value?.type === 'Contract' && (
|
||||||
{/* 退款详情 */}
|
<ContractInfo item={config?.value} />
|
||||||
{config?.value?.type === 'Refund' && (
|
)}
|
||||||
<ProCard size="small">
|
{config?.value?.type === 'ContractTermination' && (
|
||||||
<ProDescriptions size="small" column={2}>
|
<ContractTerminationInfo item={config?.value} />
|
||||||
<ProDescriptions.Item label="申请事项" span={2}>
|
)}
|
||||||
{config?.value?.title || '-'}
|
{config?.value?.type === 'ContractPayment' && (
|
||||||
</ProDescriptions.Item>
|
<ContractPaymentInfo item={config?.value} />
|
||||||
<ProDescriptions.Item label="账单类型">
|
)}
|
||||||
<renderTextHelper.Tag
|
{config?.value?.type === 'Refund' && (
|
||||||
Enums={RefundsTypeEnum}
|
<RefundInfo item={config?.value} />
|
||||||
value={config?.value?.model?.type}
|
)}
|
||||||
/>
|
{config?.value?.type === 'ContractBorrow' && (
|
||||||
</ProDescriptions.Item>
|
<ArchiveBorrowInfo item={config?.value} />
|
||||||
<ProDescriptions.Item label="退款金额">
|
)}
|
||||||
<Space>
|
{config?.value?.type === 'OtherContractSeal' && (
|
||||||
{config?.value?.model?.refund_amount || '-'}
|
<SealInfo item={config?.value} />
|
||||||
元
|
)}
|
||||||
<BIllInfo
|
{config?.value?.type === 'HouseBillUpdate' && (
|
||||||
item={{
|
<BillUpdateInfo item={config?.value} />
|
||||||
id: config?.value?.model?.refundable_id,
|
)}
|
||||||
type: 'link',
|
{config?.value?.type === 'ChargeStandardModification' && (
|
||||||
}}
|
<ChargeStandardInfo item={config?.value} />
|
||||||
title="查看账单"
|
)}
|
||||||
/>
|
{config?.value?.type === 'BillUpdate' && (
|
||||||
</Space>
|
<TemporaryBillUpdateInfo item={config?.value} />
|
||||||
</ProDescriptions.Item>
|
)}
|
||||||
<ProDescriptions.Item label="付款信息" span={2}>
|
<ApprovalRecord item={config?.value} />
|
||||||
{config?.value?.model?.payer_name || '-'}|
|
|
||||||
{config?.value?.model?.payer_bank || '-'}|
|
|
||||||
{config?.value?.model?.payer_account || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="收款信息" span={2}>
|
|
||||||
{config?.value?.model?.payee_name || '-'}
|
|
||||||
{config?.value?.model?.payee_bank || '-'}
|
|
||||||
{config?.value?.model?.payee_account || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
|
|
||||||
<ProDescriptions.Item label="申请时间">
|
|
||||||
{props?.item?.created_at || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
</ProDescriptions>
|
|
||||||
</ProCard>
|
|
||||||
)}
|
|
||||||
{/* 合同详情 */}
|
|
||||||
{config?.value?.type === 'Contract' && (
|
|
||||||
<ProCard size="small">
|
|
||||||
<ProDescriptions size="small" column={2}>
|
|
||||||
<ProDescriptions.Item label="合同名称" span={2}>
|
|
||||||
{config?.value?.model?.name || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
|
|
||||||
<ProDescriptions.Item label="合同编号" span={2}>
|
|
||||||
<Space>
|
|
||||||
{config?.value?.model?.code || '-'}
|
|
||||||
<BIllInfo
|
|
||||||
item={{
|
|
||||||
id: config?.value?.model?.refundable_id,
|
|
||||||
type: 'Contract',
|
|
||||||
}}
|
|
||||||
title="查看合同"
|
|
||||||
/>
|
|
||||||
<MyButtons.View
|
|
||||||
title="查看"
|
|
||||||
key="configInfo"
|
|
||||||
onClick={() => {
|
|
||||||
navigate(
|
|
||||||
`/contract/contracts/show/${config?.value?.model?.id}`,
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
{/* <ProDescriptions.Item label="收支类型">
|
|
||||||
<renderTextHelper.Tag
|
|
||||||
Enums={ContractTemplatesIncomeExpenseTypeEnum}
|
|
||||||
value={config?.value?.model?.income_expense_type}
|
|
||||||
/>
|
|
||||||
</ProDescriptions.Item> */}
|
|
||||||
{/* <ProDescriptions.Item label="合同性质">
|
|
||||||
<renderTextHelper.Tag
|
|
||||||
Enums={ContractsContractNatureEnum}
|
|
||||||
value={config?.value?.model?.contract_nature}
|
|
||||||
/>
|
|
||||||
</ProDescriptions.Item> */}
|
|
||||||
<ProDescriptions.Item label="合同类型">
|
|
||||||
{config?.value?.model?.contract_type_name || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
{/* <ProDescriptions.Item label="结算模式">
|
|
||||||
<renderTextHelper.Tag
|
|
||||||
Enums={ContractsSettlementModeEnum}
|
|
||||||
value={config?.value?.model?.settlement_mode}
|
|
||||||
/>
|
|
||||||
</ProDescriptions.Item> */}
|
|
||||||
<ProDescriptions.Item label="合同金额">
|
|
||||||
{config?.value?.model?.total_amount || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="保证金金额">
|
|
||||||
{config?.value?.model?.deposit_amount || '无'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="签约主体">
|
|
||||||
{config?.value?.model?.sign_subject || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="签约部门">
|
|
||||||
{config?.value?.model?.sign_department || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="关联项目">
|
|
||||||
{config?.value?.model?.project_name || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="合同对接人">
|
|
||||||
{config?.value?.model?.contract_liaison || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="合同有效期" span={2}>
|
|
||||||
{config?.value?.model?.start_time?.substring(0, 10)}至
|
|
||||||
{config?.value?.model?.end_time?.substring(0, 10)}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="申请时间" span={2}>
|
|
||||||
{props?.item?.created_at || '-'}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
<ProDescriptions.Item label="附件" span={2}>
|
|
||||||
{config?.value?.model?.attachments.map((item: any) => {
|
|
||||||
const handleDownload = async (
|
|
||||||
e: React.MouseEvent,
|
|
||||||
) => {
|
|
||||||
e.preventDefault();
|
|
||||||
try {
|
|
||||||
const response = await fetch(item.url);
|
|
||||||
const blob = await response.blob();
|
|
||||||
const url = window.URL.createObjectURL(blob);
|
|
||||||
const a = document.createElement('a');
|
|
||||||
a.href = url;
|
|
||||||
a.download = item.name;
|
|
||||||
document.body.appendChild(a);
|
|
||||||
a.click();
|
|
||||||
window.URL.revokeObjectURL(url);
|
|
||||||
document.body.removeChild(a);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('下载失败:', error);
|
|
||||||
// 如果下载失败,则在新窗口打开
|
|
||||||
window.open(item.url, '_blank');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div key={item.url}>
|
|
||||||
<a href={item.url} onClick={handleDownload}>
|
|
||||||
{item.name};
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
</ProDescriptions>
|
|
||||||
</ProCard>
|
|
||||||
)}
|
|
||||||
<ProCard>
|
|
||||||
<ProDescriptions>
|
|
||||||
<ProDescriptions.Item label="审核记录">
|
|
||||||
<Space direction="vertical" style={{ width: '100%' }}>
|
|
||||||
<Steps
|
|
||||||
progressDot
|
|
||||||
direction="vertical"
|
|
||||||
current={config?.value?.approval_records.length}
|
|
||||||
items={config?.value?.approval_records.map(
|
|
||||||
(item: any) =>
|
|
||||||
item?.node_type === 'Approver'
|
|
||||||
? {
|
|
||||||
title: `${
|
|
||||||
item.company_employee?.name || '-'
|
|
||||||
}-${item?.company_employee?.phone}`,
|
|
||||||
description: `${
|
|
||||||
item.status === 'Approved'
|
|
||||||
? `通过 - ${item.opinion || '-'} - ${
|
|
||||||
item.created_at || '-'
|
|
||||||
}`
|
|
||||||
: '待审核'
|
|
||||||
}`,
|
|
||||||
}
|
|
||||||
: '',
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Space>
|
|
||||||
</ProDescriptions.Item>
|
|
||||||
</ProDescriptions>
|
|
||||||
</ProCard>
|
|
||||||
</div>
|
|
||||||
</Space>
|
</Space>
|
||||||
),
|
),
|
||||||
colProps: { span: 24 },
|
colProps: { span: 24 },
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import { ApprovalTemplatesTypeEnum } from '@/gen/Enums';
|
|||||||
import { ProTable } from '@ant-design/pro-components';
|
import { ProTable } from '@ant-design/pro-components';
|
||||||
import BatchModifyApprover from './modals/BatchModifyApprover';
|
import BatchModifyApprover from './modals/BatchModifyApprover';
|
||||||
import Create from './modals/Create';
|
import Create from './modals/Create';
|
||||||
|
import Show from './modals/Show';
|
||||||
import Update from './modals/Update';
|
import Update from './modals/Update';
|
||||||
|
|
||||||
export default function Index({ title = '审批模板' }) {
|
export default function Index({ title = '审批模板' }) {
|
||||||
@ -76,6 +77,9 @@ export default function Index({ title = '审批模板' }) {
|
|||||||
render: (_, item: any, _index, action) => (
|
render: (_, item: any, _index, action) => (
|
||||||
<MyTableActions
|
<MyTableActions
|
||||||
actions={{
|
actions={{
|
||||||
|
show: (
|
||||||
|
<Show item={item} reload={action?.reload} title={title} />
|
||||||
|
),
|
||||||
update: (
|
update: (
|
||||||
<Update item={item} reload={action?.reload} title={title} />
|
<Update item={item} reload={action?.reload} title={title} />
|
||||||
),
|
),
|
||||||
|
|||||||
@ -12,7 +12,31 @@ import {
|
|||||||
ApprovalTemplatesTypeEnum,
|
ApprovalTemplatesTypeEnum,
|
||||||
} from '@/gen/Enums';
|
} from '@/gen/Enums';
|
||||||
import { BetaSchemaForm } from '@ant-design/pro-components';
|
import { BetaSchemaForm } from '@ant-design/pro-components';
|
||||||
import { Form, message } from 'antd';
|
import { Button, Form, message } from 'antd';
|
||||||
|
|
||||||
|
// 默认的4个节点配置
|
||||||
|
const getDefaultNodes = () => [
|
||||||
|
{
|
||||||
|
node_type: ApprovalTemplateNodesNodeTypeEnum.Approver.value,
|
||||||
|
name: '',
|
||||||
|
members: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
node_type: ApprovalTemplateNodesNodeTypeEnum.Approver.value,
|
||||||
|
name: '',
|
||||||
|
members: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
node_type: ApprovalTemplateNodesNodeTypeEnum.Approver.value,
|
||||||
|
name: '',
|
||||||
|
members: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
node_type: ApprovalTemplateNodesNodeTypeEnum.CC.value,
|
||||||
|
name: '抄送对象',
|
||||||
|
members: [],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
export default function Create(props: MyBetaModalFormProps) {
|
export default function Create(props: MyBetaModalFormProps) {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
@ -27,12 +51,44 @@ export default function Create(props: MyBetaModalFormProps) {
|
|||||||
onOpenChange={(open: any) => {
|
onOpenChange={(open: any) => {
|
||||||
if (open) {
|
if (open) {
|
||||||
form.resetFields(); // 清空表单数据
|
form.resetFields(); // 清空表单数据
|
||||||
|
// 设置默认的4个节点
|
||||||
|
form.setFieldsValue({
|
||||||
|
nodes: getDefaultNodes(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
trigger={<MyButtons.Create title={`${props.title}`} />}
|
trigger={<MyButtons.Create title={`${props.title}`} />}
|
||||||
onFinish={async (values) =>
|
onFinish={async (values) => {
|
||||||
Apis.Approval.ApprovalTemplates.Store({
|
const { nodes } = values;
|
||||||
|
|
||||||
|
// 校验:只能提交一行 node_type 为 "cc" 的数据
|
||||||
|
const ccNodes = nodes?.filter(
|
||||||
|
(node: any) =>
|
||||||
|
node?.node_type === ApprovalTemplateNodesNodeTypeEnum.CC.value,
|
||||||
|
);
|
||||||
|
if (ccNodes?.length > 1) {
|
||||||
|
message.error('只能提交一行抄送节点');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 过滤掉 node_type 为 "cc" 且 members 为空的行
|
||||||
|
const filteredNodes = nodes?.filter((node: any) => {
|
||||||
|
if (node?.node_type === ApprovalTemplateNodesNodeTypeEnum.CC.value) {
|
||||||
|
return node?.members?.length > 0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
const nodeNames = filteredNodes?.map((node: any) => node?.name);
|
||||||
|
const hasDuplicate = nodeNames?.length !== new Set(nodeNames).size;
|
||||||
|
if (hasDuplicate) {
|
||||||
|
message.error('节点名称不能重复');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Apis.Approval.ApprovalTemplates.Store({
|
||||||
...values,
|
...values,
|
||||||
|
nodes: filteredNodes,
|
||||||
is_enabled: true,
|
is_enabled: true,
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@ -40,27 +96,35 @@ export default function Create(props: MyBetaModalFormProps) {
|
|||||||
message.success(props.title + '成功');
|
message.success(props.title + '成功');
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.catch(() => false)
|
.catch(() => false);
|
||||||
}
|
}}
|
||||||
columns={[
|
columns={[
|
||||||
MyFormItems.EnumRadio({
|
MyFormItems.EnumSelect({
|
||||||
key: 'type',
|
key: 'type',
|
||||||
title: '业务类型',
|
title: '业务类型',
|
||||||
valueEnum: ApprovalTemplatesTypeEnum,
|
// valueEnum: ApprovalTemplatesTypeEnum,
|
||||||
|
valueEnum: () => {
|
||||||
|
const obj: Record<string, any> = JSON.parse(
|
||||||
|
JSON.stringify(ApprovalTemplatesTypeEnum),
|
||||||
|
);
|
||||||
|
delete obj.Finance;
|
||||||
|
delete obj.BillModification;
|
||||||
|
return obj;
|
||||||
|
},
|
||||||
required: true,
|
required: true,
|
||||||
colProps: { span: 24 },
|
colProps: { span: 8 },
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
key: 'name',
|
key: 'name',
|
||||||
title: '模板名称',
|
title: '模板名称',
|
||||||
formItemProps: { ...rulesHelper.text },
|
formItemProps: { ...rulesHelper.text },
|
||||||
colProps: { span: 12 },
|
colProps: { span: 8 },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'code',
|
key: 'code',
|
||||||
title: '模板编码',
|
title: '模板编码',
|
||||||
formItemProps: { ...rulesHelper.text },
|
formItemProps: { ...rulesHelper.text },
|
||||||
colProps: { span: 12 },
|
colProps: { span: 8 },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
valueType: 'formList',
|
valueType: 'formList',
|
||||||
@ -68,7 +132,52 @@ export default function Create(props: MyBetaModalFormProps) {
|
|||||||
title: '设置审批节点',
|
title: '设置审批节点',
|
||||||
fieldProps: {
|
fieldProps: {
|
||||||
copyIconProps: false,
|
copyIconProps: false,
|
||||||
// deleteIconProps: false,
|
creatorButtonProps: {
|
||||||
|
creatorButtonText: '添加节点',
|
||||||
|
},
|
||||||
|
actionRender: (field: any, action: any) => [
|
||||||
|
<Button
|
||||||
|
key="add"
|
||||||
|
type="link"
|
||||||
|
size="small"
|
||||||
|
onClick={() => {
|
||||||
|
const currentNodeType = form.getFieldValue([
|
||||||
|
'nodes',
|
||||||
|
field.name,
|
||||||
|
'node_type',
|
||||||
|
]);
|
||||||
|
if (
|
||||||
|
currentNodeType ===
|
||||||
|
ApprovalTemplateNodesNodeTypeEnum.CC.value
|
||||||
|
) {
|
||||||
|
message.warning('抄送节点不允许添加');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
action.add(
|
||||||
|
{
|
||||||
|
node_type:
|
||||||
|
ApprovalTemplateNodesNodeTypeEnum.Approver.value,
|
||||||
|
name: '',
|
||||||
|
members: [],
|
||||||
|
},
|
||||||
|
field.name + 1,
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
添加
|
||||||
|
</Button>,
|
||||||
|
<Button
|
||||||
|
key="delete"
|
||||||
|
type="link"
|
||||||
|
size="small"
|
||||||
|
danger
|
||||||
|
onClick={() => {
|
||||||
|
action.remove(field.name);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</Button>,
|
||||||
|
],
|
||||||
},
|
},
|
||||||
formItemProps: {
|
formItemProps: {
|
||||||
...rulesHelper.array,
|
...rulesHelper.array,
|
||||||
@ -113,13 +222,17 @@ export default function Create(props: MyBetaModalFormProps) {
|
|||||||
key: 'members',
|
key: 'members',
|
||||||
title: `审批人员`,
|
title: `审批人员`,
|
||||||
colProps: { span: 13 },
|
colProps: { span: 13 },
|
||||||
|
// formItemProps: {
|
||||||
|
// ...rulesHelper.array,
|
||||||
|
// },
|
||||||
fieldProps: {
|
fieldProps: {
|
||||||
mode: 'multiple',
|
mode: 'multiple',
|
||||||
|
showSearch: true,
|
||||||
maxCount:
|
maxCount:
|
||||||
node_type ===
|
node_type ===
|
||||||
ApprovalTemplateNodesNodeTypeEnum.Approver.value
|
ApprovalTemplateNodesNodeTypeEnum.Approver.value
|
||||||
? 1
|
? 1
|
||||||
: 9,
|
: 99,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
@ -133,7 +246,7 @@ export default function Create(props: MyBetaModalFormProps) {
|
|||||||
title: '备注',
|
title: '备注',
|
||||||
key: 'description',
|
key: 'description',
|
||||||
colProps: { span: 24 },
|
colProps: { span: 24 },
|
||||||
valueType: 'textarea',
|
// valueType: 'textarea',
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
|||||||
104
src/pages/approval/templates/modals/Show.tsx
Normal file
104
src/pages/approval/templates/modals/Show.tsx
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
import { MyBetaModalFormProps, renderTextHelper } from '@/common';
|
||||||
|
import { MyModal } from '@/components/MyModal';
|
||||||
|
import { Apis } from '@/gen/Apis';
|
||||||
|
import {
|
||||||
|
ApprovalTemplateNodesNodeTypeEnum,
|
||||||
|
ApprovalTemplatesTypeEnum,
|
||||||
|
} from '@/gen/Enums';
|
||||||
|
import { ProCard, ProDescriptions, ProTable } from '@ant-design/pro-components';
|
||||||
|
import { Space, Spin } from 'antd';
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
|
export default function Show(props: MyBetaModalFormProps) {
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [data, setData] = useState<any>({});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MyModal
|
||||||
|
title={props.title || '查看'}
|
||||||
|
type={'primary'}
|
||||||
|
width="800px"
|
||||||
|
onOpen={() => {
|
||||||
|
if (props?.item?.id) {
|
||||||
|
setLoading(true);
|
||||||
|
Apis.Approval.ApprovalTemplates.Show({ id: props.item.id })
|
||||||
|
.then((res) => {
|
||||||
|
setData(res?.data || {});
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
node={
|
||||||
|
<Space direction="vertical" style={{ width: '100%' }}>
|
||||||
|
<ProCard extra={props.extra} title="基础信息">
|
||||||
|
<Spin spinning={loading}>
|
||||||
|
<ProDescriptions column={2}>
|
||||||
|
<ProDescriptions.Item label="业务类型">
|
||||||
|
<renderTextHelper.Tag
|
||||||
|
Enums={ApprovalTemplatesTypeEnum}
|
||||||
|
value={data?.type}
|
||||||
|
/>
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="模板名称">
|
||||||
|
{data?.name}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="模板编码">
|
||||||
|
{data?.code}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="备注" span={2}>
|
||||||
|
{data?.description || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
</ProDescriptions>
|
||||||
|
</Spin>
|
||||||
|
</ProCard>
|
||||||
|
<ProCard title="审批节点">
|
||||||
|
<Spin spinning={loading}>
|
||||||
|
<ProTable
|
||||||
|
search={false}
|
||||||
|
toolBarRender={false}
|
||||||
|
pagination={false}
|
||||||
|
dataSource={data?.approval_template_nodes || []}
|
||||||
|
rowKey="id"
|
||||||
|
columns={[
|
||||||
|
{
|
||||||
|
title: '类型',
|
||||||
|
dataIndex: 'node_type',
|
||||||
|
render: (_, record) => (
|
||||||
|
<renderTextHelper.Tag
|
||||||
|
Enums={ApprovalTemplateNodesNodeTypeEnum}
|
||||||
|
value={record?.node_type}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '节点名称',
|
||||||
|
dataIndex: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '审批人员',
|
||||||
|
dataIndex: 'members',
|
||||||
|
render: (_, record) => {
|
||||||
|
if (
|
||||||
|
record?.approval_template_node_members &&
|
||||||
|
record?.approval_template_node_members.length > 0
|
||||||
|
) {
|
||||||
|
return record.approval_template_node_members
|
||||||
|
.map(
|
||||||
|
(m: any) => m?.company_employee?.name || '未知人员',
|
||||||
|
)
|
||||||
|
.join(',');
|
||||||
|
}
|
||||||
|
return '-';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</Spin>
|
||||||
|
</ProCard>
|
||||||
|
</Space>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -12,7 +12,7 @@ import {
|
|||||||
ApprovalTemplatesTypeEnum,
|
ApprovalTemplatesTypeEnum,
|
||||||
} from '@/gen/Enums';
|
} from '@/gen/Enums';
|
||||||
import { BetaSchemaForm } from '@ant-design/pro-components';
|
import { BetaSchemaForm } from '@ant-design/pro-components';
|
||||||
import { Form, message } from 'antd';
|
import { Button, Form, message } from 'antd';
|
||||||
let showInfo: any = [];
|
let showInfo: any = [];
|
||||||
export default function Update(props: MyBetaModalFormProps) {
|
export default function Update(props: MyBetaModalFormProps) {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
@ -43,9 +43,37 @@ export default function Update(props: MyBetaModalFormProps) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onFinish={async (values) =>
|
onFinish={async (values) => {
|
||||||
Apis.Approval.ApprovalTemplates.Update({
|
const { nodes } = values;
|
||||||
|
|
||||||
|
// 校验:只能提交一行 node_type 为 "cc" 的数据
|
||||||
|
const ccNodes = nodes?.filter(
|
||||||
|
(node: any) =>
|
||||||
|
node?.node_type === ApprovalTemplateNodesNodeTypeEnum.CC.value,
|
||||||
|
);
|
||||||
|
if (ccNodes?.length > 1) {
|
||||||
|
message.error('只能提交一行抄送节点');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 过滤掉 node_type 为 "cc" 且 members 为空的行
|
||||||
|
const filteredNodes = nodes?.filter((node: any) => {
|
||||||
|
if (node?.node_type === ApprovalTemplateNodesNodeTypeEnum.CC.value) {
|
||||||
|
return node?.members?.length > 0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
const nodeNames = filteredNodes?.map((node: any) => node?.name);
|
||||||
|
const hasDuplicate = nodeNames?.length !== new Set(nodeNames).size;
|
||||||
|
if (hasDuplicate) {
|
||||||
|
message.error('节点名称不能重复');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Apis.Approval.ApprovalTemplates.Update({
|
||||||
...values,
|
...values,
|
||||||
|
nodes: filteredNodes,
|
||||||
id: props.item?.id ?? 0,
|
id: props.item?.id ?? 0,
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@ -53,27 +81,35 @@ export default function Update(props: MyBetaModalFormProps) {
|
|||||||
message.success(props.title + '编辑成功');
|
message.success(props.title + '编辑成功');
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.catch(() => false)
|
.catch(() => false);
|
||||||
}
|
}}
|
||||||
columns={[
|
columns={[
|
||||||
MyFormItems.EnumRadio({
|
MyFormItems.EnumSelect({
|
||||||
key: 'type',
|
key: 'type',
|
||||||
title: '业务类型',
|
title: '业务类型',
|
||||||
valueEnum: ApprovalTemplatesTypeEnum,
|
// valueEnum: ApprovalTemplatesTypeEnum,
|
||||||
|
valueEnum: () => {
|
||||||
|
const obj: Record<string, any> = JSON.parse(
|
||||||
|
JSON.stringify(ApprovalTemplatesTypeEnum),
|
||||||
|
);
|
||||||
|
delete obj.Finance;
|
||||||
|
delete obj.BillModification;
|
||||||
|
return obj;
|
||||||
|
},
|
||||||
required: true,
|
required: true,
|
||||||
colProps: { span: 24 },
|
colProps: { span: 8 },
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
key: 'name',
|
key: 'name',
|
||||||
title: '名称',
|
title: '名称',
|
||||||
formItemProps: { ...rulesHelper.text },
|
formItemProps: { ...rulesHelper.text },
|
||||||
colProps: { span: 12 },
|
colProps: { span: 8 },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'code',
|
key: 'code',
|
||||||
title: '模板编码',
|
title: '模板编码',
|
||||||
formItemProps: { ...rulesHelper.text },
|
formItemProps: { ...rulesHelper.text },
|
||||||
colProps: { span: 12 },
|
colProps: { span: 8 },
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -82,7 +118,52 @@ export default function Update(props: MyBetaModalFormProps) {
|
|||||||
title: '审批节点',
|
title: '审批节点',
|
||||||
fieldProps: {
|
fieldProps: {
|
||||||
copyIconProps: false,
|
copyIconProps: false,
|
||||||
// deleteIconProps: false,
|
creatorButtonProps: {
|
||||||
|
creatorButtonText: '添加节点',
|
||||||
|
},
|
||||||
|
actionRender: (field: any, action: any) => [
|
||||||
|
<Button
|
||||||
|
key="add"
|
||||||
|
type="link"
|
||||||
|
size="small"
|
||||||
|
onClick={() => {
|
||||||
|
const currentNodeType = form.getFieldValue([
|
||||||
|
'nodes',
|
||||||
|
field.name,
|
||||||
|
'node_type',
|
||||||
|
]);
|
||||||
|
if (
|
||||||
|
currentNodeType ===
|
||||||
|
ApprovalTemplateNodesNodeTypeEnum.CC.value
|
||||||
|
) {
|
||||||
|
message.warning('抄送节点不允许添加');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
action.add(
|
||||||
|
{
|
||||||
|
node_type:
|
||||||
|
ApprovalTemplateNodesNodeTypeEnum.Approver.value,
|
||||||
|
name: '',
|
||||||
|
members: [],
|
||||||
|
},
|
||||||
|
field.name + 1,
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
添加
|
||||||
|
</Button>,
|
||||||
|
<Button
|
||||||
|
key="delete"
|
||||||
|
type="link"
|
||||||
|
size="small"
|
||||||
|
danger
|
||||||
|
onClick={() => {
|
||||||
|
action.remove(field.name);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</Button>,
|
||||||
|
],
|
||||||
},
|
},
|
||||||
formItemProps: {
|
formItemProps: {
|
||||||
...rulesHelper.array,
|
...rulesHelper.array,
|
||||||
@ -160,7 +241,7 @@ export default function Update(props: MyBetaModalFormProps) {
|
|||||||
title: '备注',
|
title: '备注',
|
||||||
key: 'description',
|
key: 'description',
|
||||||
colProps: { span: 24 },
|
colProps: { span: 24 },
|
||||||
valueType: 'textarea',
|
// valueType: 'textarea',
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import { useNavigate } from '@umijs/max';
|
|||||||
import { Modal, Space, Tooltip } from 'antd';
|
import { Modal, Space, Tooltip } from 'antd';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import Update from './modals/Update';
|
import Update from './modals/Update';
|
||||||
|
import ViewCalendar from './modals/ViewCalendar';
|
||||||
|
|
||||||
export default function Index({ title = '排班管理' }) {
|
export default function Index({ title = '排班管理' }) {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@ -78,29 +79,41 @@ export default function Index({ title = '排班管理' }) {
|
|||||||
// search: false,
|
// search: false,
|
||||||
// }),
|
// }),
|
||||||
|
|
||||||
Selects?.AssetProjects({
|
Selects?.OrganizationsTree({
|
||||||
title: '选择项目',
|
title: '选择组织',
|
||||||
key: 'asset_projects_id',
|
key: 'organizations_id',
|
||||||
hidden: true,
|
search: {
|
||||||
|
transform: (value) => {
|
||||||
|
return { organizations_id: value[value.length - 1] };
|
||||||
|
},
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
title: '排班日期',
|
title: '排班日期',
|
||||||
dataIndex: 'schedule_date',
|
dataIndex: 'schedule_date',
|
||||||
valueType: 'date',
|
valueType: 'date',
|
||||||
|
sorter: (a, b) =>
|
||||||
|
new Date(a.schedule_date).getTime() -
|
||||||
|
new Date(b.schedule_date).getTime(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '关联项目',
|
title: '所在组织',
|
||||||
dataIndex: ['asset_project', 'name'],
|
dataIndex: 'organization_path',
|
||||||
|
search: false,
|
||||||
// search: {
|
// search: {
|
||||||
// transform: (value) => {
|
// transform: (value) => {
|
||||||
// return { project_name: value };
|
// return { organization_name: value };
|
||||||
// },
|
// },
|
||||||
// },
|
// },
|
||||||
search: false,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
title: '员工',
|
title: '员工',
|
||||||
dataIndex: ['company_employee', 'name'],
|
dataIndex: ['company_employee', 'name'],
|
||||||
|
sorter: (a, b) =>
|
||||||
|
a?.company_employee?.name?.localeCompare?.(
|
||||||
|
b?.company_employee?.name ?? '',
|
||||||
|
) ?? 0,
|
||||||
search: {
|
search: {
|
||||||
transform: (value) => {
|
transform: (value) => {
|
||||||
return { employee_name: value };
|
return { employee_name: value };
|
||||||
@ -161,12 +174,13 @@ export default function Index({ title = '排班管理' }) {
|
|||||||
dataIndex: ['created_employee', 'name'],
|
dataIndex: ['created_employee', 'name'],
|
||||||
search: false,
|
search: false,
|
||||||
},
|
},
|
||||||
// MyColumns.CreatedAt(),
|
MyColumns.UpdatedAt(),
|
||||||
MyColumns.Option({
|
MyColumns.Option({
|
||||||
render: (_, item: any, index, action) => (
|
render: (_, item: any, index, action) => (
|
||||||
<Space key={index}>
|
<Space key={index}>
|
||||||
<MyTableActions
|
<MyTableActions
|
||||||
actions={{
|
actions={{
|
||||||
|
view: <ViewCalendar item={item} reload={action?.reload} />,
|
||||||
update: (
|
update: (
|
||||||
<Update
|
<Update
|
||||||
item={item}
|
item={item}
|
||||||
|
|||||||
@ -0,0 +1,252 @@
|
|||||||
|
import { MyButtons } from '@/common';
|
||||||
|
import { Apis } from '@/gen/Apis';
|
||||||
|
import { AttendanceSchedulesStatusEnum } from '@/gen/Enums';
|
||||||
|
import { Calendar, message, Modal, Popconfirm, Select } from 'antd';
|
||||||
|
import dayjs, { Dayjs } from 'dayjs';
|
||||||
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
|
const yearOptions = Array.from({ length: 10 }, (_, i) => {
|
||||||
|
const y = dayjs().year() - 5 + i;
|
||||||
|
return { label: `${y}年`, value: y };
|
||||||
|
});
|
||||||
|
|
||||||
|
const monthOptions = Array.from({ length: 12 }, (_, i) => ({
|
||||||
|
label: `${i + 1}月`,
|
||||||
|
value: i,
|
||||||
|
}));
|
||||||
|
|
||||||
|
interface ScheduleItem {
|
||||||
|
id: number;
|
||||||
|
schedule_date: string;
|
||||||
|
attendance_shifts_id?: number;
|
||||||
|
attendance_shift?: { name: string; id: number };
|
||||||
|
asset_projects_id?: number;
|
||||||
|
status?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function ViewCalendar({
|
||||||
|
item,
|
||||||
|
reload: reloadList,
|
||||||
|
}: {
|
||||||
|
item: Record<string, any>;
|
||||||
|
reload?: () => void;
|
||||||
|
}) {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const [schedules, setSchedules] = useState<ScheduleItem[]>([]);
|
||||||
|
const [currentMonth, setCurrentMonth] = useState(dayjs());
|
||||||
|
const [shiftOptions, setShiftOptions] = useState<
|
||||||
|
{ label: string; value: number }[]
|
||||||
|
>([]);
|
||||||
|
const monthRef = useRef(dayjs());
|
||||||
|
|
||||||
|
const employeeId = item?.company_employees_id;
|
||||||
|
const projectId = item?.asset_projects_id;
|
||||||
|
const organizationId = item?.organizations_id;
|
||||||
|
const scheduleDates = item?.schedule_date;
|
||||||
|
|
||||||
|
const fetchSchedules = useCallback(
|
||||||
|
(month: Dayjs) => {
|
||||||
|
const startDate = month.startOf('month').format('YYYY-MM-DD');
|
||||||
|
const endDate = month.endOf('month').format('YYYY-MM-DD');
|
||||||
|
Apis.Attendance.AttendanceSchedules.List({
|
||||||
|
company_employees_id: employeeId,
|
||||||
|
status: AttendanceSchedulesStatusEnum.Active.value,
|
||||||
|
schedule_dates: [startDate, endDate],
|
||||||
|
perPage: 100,
|
||||||
|
} as any).then((res) => {
|
||||||
|
const list: ScheduleItem[] = res?.data || [];
|
||||||
|
const start = month.startOf('month');
|
||||||
|
const end = month.endOf('month');
|
||||||
|
const filtered = list.filter((s) => {
|
||||||
|
const d = dayjs(s.schedule_date);
|
||||||
|
return (
|
||||||
|
(d.isAfter(start) || d.isSame(start, 'day')) &&
|
||||||
|
(d.isBefore(end) || d.isSame(end, 'day'))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
setSchedules(filtered);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[employeeId],
|
||||||
|
);
|
||||||
|
|
||||||
|
const reload = useCallback(() => {
|
||||||
|
fetchSchedules(monthRef.current);
|
||||||
|
}, [fetchSchedules]);
|
||||||
|
|
||||||
|
const fetchShiftOptions = useCallback(() => {
|
||||||
|
Apis.Attendance.AttendanceShifts.Select({}).then((res) => {
|
||||||
|
const list = (res?.data || []) as { name: string; id: number }[];
|
||||||
|
setShiftOptions(list.map((s) => ({ label: s.name, value: s.id })));
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (open) {
|
||||||
|
const now = dayjs();
|
||||||
|
monthRef.current = now;
|
||||||
|
setCurrentMonth(now);
|
||||||
|
fetchSchedules(now);
|
||||||
|
fetchShiftOptions();
|
||||||
|
} else {
|
||||||
|
setSchedules([]);
|
||||||
|
}
|
||||||
|
}, [open]);
|
||||||
|
|
||||||
|
const handleShiftChange = (
|
||||||
|
scheduleId: number,
|
||||||
|
shiftId: number,
|
||||||
|
date: Dayjs,
|
||||||
|
isNew: boolean,
|
||||||
|
) => {
|
||||||
|
if (!isNew) {
|
||||||
|
Apis.Attendance.AttendanceSchedules.Update({
|
||||||
|
id: scheduleId,
|
||||||
|
attendance_shifts_id: shiftId,
|
||||||
|
}).then(() => {
|
||||||
|
message.success('修改成功');
|
||||||
|
reload();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Apis.Attendance.AttendanceSchedules.Store({
|
||||||
|
company_employees_id: employeeId!,
|
||||||
|
attendance_shifts_id: shiftId,
|
||||||
|
asset_projects_id: projectId!,
|
||||||
|
organizations_id: organizationId,
|
||||||
|
schedule_date: date.format('YYYY-MM-DD') as unknown as Date,
|
||||||
|
} as any).then(() => {
|
||||||
|
message.success('添加成功');
|
||||||
|
reload();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDelete = (scheduleId: number) => {
|
||||||
|
Apis.Attendance.AttendanceSchedules.Cancel({
|
||||||
|
id: scheduleId,
|
||||||
|
}).then(() => {
|
||||||
|
message.success('取消成功');
|
||||||
|
reload();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const dateCellRender = (date: Dayjs) => {
|
||||||
|
const matched = schedules.filter((s) =>
|
||||||
|
dayjs(s.schedule_date).isSame(date, 'day'),
|
||||||
|
);
|
||||||
|
|
||||||
|
const isCancelled = (status?: string) =>
|
||||||
|
status === 'Cancelled' || status === 'cancelled';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{matched.map((s) => (
|
||||||
|
<div
|
||||||
|
key={s.id}
|
||||||
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
opacity: isCancelled(s.status) ? 0.4 : 1,
|
||||||
|
lineHeight: '18px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Select
|
||||||
|
size="small"
|
||||||
|
variant="borderless"
|
||||||
|
value={s.attendance_shifts_id || s.attendance_shift?.id}
|
||||||
|
options={shiftOptions}
|
||||||
|
style={{ flex: 1, fontSize: 12 }}
|
||||||
|
disabled={isCancelled(s.status)}
|
||||||
|
onChange={(val) =>
|
||||||
|
val != null && handleShiftChange(s.id, val, date, false)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
{!isCancelled(s.status) && (
|
||||||
|
<Popconfirm
|
||||||
|
title="是否取消该班次?"
|
||||||
|
onConfirm={() => handleDelete(s.id)}
|
||||||
|
okText="是"
|
||||||
|
cancelText="否"
|
||||||
|
>
|
||||||
|
<a style={{ fontSize: 12, color: '#ff4d4f', flexShrink: 0 }}>
|
||||||
|
×
|
||||||
|
</a>
|
||||||
|
</Popconfirm>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
{matched.length === 0 && (
|
||||||
|
<Select
|
||||||
|
size="small"
|
||||||
|
variant="borderless"
|
||||||
|
placeholder="+"
|
||||||
|
value={undefined}
|
||||||
|
options={shiftOptions}
|
||||||
|
style={{ width: '100%', fontSize: 12 }}
|
||||||
|
onChange={(val) =>
|
||||||
|
val != null && handleShiftChange(0, val, date, true)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<MyButtons.Default
|
||||||
|
type="link"
|
||||||
|
size="small"
|
||||||
|
title="查看"
|
||||||
|
onClick={() => setOpen(true)}
|
||||||
|
/>
|
||||||
|
<Modal
|
||||||
|
title={`${item?.company_employee?.name || ''} - 排班日历`}
|
||||||
|
open={open}
|
||||||
|
onCancel={() => {
|
||||||
|
setOpen(false);
|
||||||
|
reloadList?.();
|
||||||
|
}}
|
||||||
|
footer={null}
|
||||||
|
width={1000}
|
||||||
|
>
|
||||||
|
<Calendar
|
||||||
|
value={currentMonth}
|
||||||
|
onPanelChange={(date) => {
|
||||||
|
monthRef.current = date;
|
||||||
|
setCurrentMonth(date);
|
||||||
|
fetchSchedules(date);
|
||||||
|
}}
|
||||||
|
headerRender={() => (
|
||||||
|
<div style={{ display: 'flex', gap: 8, padding: '8px 0' }}>
|
||||||
|
<Select
|
||||||
|
options={yearOptions}
|
||||||
|
value={currentMonth.year()}
|
||||||
|
onChange={(y) => {
|
||||||
|
const next = monthRef.current.year(y);
|
||||||
|
monthRef.current = next;
|
||||||
|
setCurrentMonth(next);
|
||||||
|
fetchSchedules(next);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Select
|
||||||
|
options={monthOptions}
|
||||||
|
value={currentMonth.month()}
|
||||||
|
onChange={(m) => {
|
||||||
|
const next = monthRef.current.month(m);
|
||||||
|
monthRef.current = next;
|
||||||
|
setCurrentMonth(next);
|
||||||
|
fetchSchedules(next);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
cellRender={(date, info) => {
|
||||||
|
if (info.type === 'date') return dateCellRender(date);
|
||||||
|
return info.originNode;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Modal>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -5,7 +5,6 @@ import {
|
|||||||
MyTableActions,
|
MyTableActions,
|
||||||
MyToolBarActions,
|
MyToolBarActions,
|
||||||
} from '@/common';
|
} from '@/common';
|
||||||
import { Selects } from '@/components/Select';
|
|
||||||
import { Apis } from '@/gen/Apis';
|
import { Apis } from '@/gen/Apis';
|
||||||
import { ProTable } from '@ant-design/pro-components';
|
import { ProTable } from '@ant-design/pro-components';
|
||||||
import { Space, Tooltip } from 'antd';
|
import { Space, Tooltip } from 'antd';
|
||||||
@ -58,11 +57,11 @@ export default function Index({
|
|||||||
MyColumns.ID({
|
MyColumns.ID({
|
||||||
search: false,
|
search: false,
|
||||||
}),
|
}),
|
||||||
Selects?.AssetProjects({
|
// Selects?.AssetProjects({
|
||||||
title: '选择项目',
|
// title: '选择项目',
|
||||||
key: 'asset_projects_id',
|
// key: 'asset_projects_id',
|
||||||
hidden: true,
|
// hidden: true,
|
||||||
}),
|
// }),
|
||||||
// {
|
// {
|
||||||
// title: '关联项目',
|
// title: '关联项目',
|
||||||
// dataIndex: ['asset_project', 'name'],
|
// dataIndex: ['asset_project', 'name'],
|
||||||
@ -144,7 +143,7 @@ export default function Index({
|
|||||||
<Space key={index}>
|
<Space key={index}>
|
||||||
<MyTableActions
|
<MyTableActions
|
||||||
actions={{
|
actions={{
|
||||||
update: (
|
shift_update: (
|
||||||
<Update
|
<Update
|
||||||
key="Update"
|
key="Update"
|
||||||
item={item}
|
item={item}
|
||||||
@ -152,7 +151,7 @@ export default function Index({
|
|||||||
title={title}
|
title={title}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
delete: (
|
shift_delete: (
|
||||||
<MyButtons.Delete
|
<MyButtons.Delete
|
||||||
onConfirm={() =>
|
onConfirm={() =>
|
||||||
Apis.Attendance.AttendanceShifts.Delete({
|
Apis.Attendance.AttendanceShifts.Delete({
|
||||||
|
|||||||
@ -16,9 +16,12 @@ import {
|
|||||||
HouseBillsBillStatusEnum,
|
HouseBillsBillStatusEnum,
|
||||||
HouseBillsTypeEnum,
|
HouseBillsTypeEnum,
|
||||||
} from '@/gen/Enums';
|
} from '@/gen/Enums';
|
||||||
|
import { CopyOutlined } from '@ant-design/icons';
|
||||||
import { ProTable } from '@ant-design/pro-components';
|
import { ProTable } from '@ant-design/pro-components';
|
||||||
import { useNavigate } from '@umijs/max';
|
import { useNavigate } from '@umijs/max';
|
||||||
|
import { message, Space } from 'antd';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
import BillCopy from './modals/BillCopy';
|
||||||
import BillCreate from './modals/BillCreate';
|
import BillCreate from './modals/BillCreate';
|
||||||
import BIllInfo from './modals/BIllInfo';
|
import BIllInfo from './modals/BIllInfo';
|
||||||
import BillRefund from './modals/BillRefund';
|
import BillRefund from './modals/BillRefund';
|
||||||
@ -44,7 +47,18 @@ export default function Index({ title = '账单明细' }) {
|
|||||||
request={async (params, sort) => {
|
request={async (params, sort) => {
|
||||||
setParams(params);
|
setParams(params);
|
||||||
return MyProTableProps.request(
|
return MyProTableProps.request(
|
||||||
params,
|
{
|
||||||
|
...params,
|
||||||
|
types: [
|
||||||
|
HouseBillsTypeEnum.MaintenanceFund.value,
|
||||||
|
HouseBillsTypeEnum.PropertyFee.value,
|
||||||
|
HouseBillsTypeEnum.WaterFee.value,
|
||||||
|
HouseBillsTypeEnum.ElectricityFee.value,
|
||||||
|
HouseBillsTypeEnum.SharedWaterFee.value,
|
||||||
|
HouseBillsTypeEnum.SharedElectricityFee.value,
|
||||||
|
HouseBillsTypeEnum.CarPortFee.value,
|
||||||
|
],
|
||||||
|
},
|
||||||
sort,
|
sort,
|
||||||
Apis.Bill.HouseBills.List,
|
Apis.Bill.HouseBills.List,
|
||||||
);
|
);
|
||||||
@ -145,20 +159,67 @@ export default function Index({ title = '账单明细' }) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
render: (_, record) => {
|
render: (_, record) => {
|
||||||
|
const name = record?.asset_house?.full_name;
|
||||||
return record.asset_houses_id ? (
|
return record.asset_houses_id ? (
|
||||||
<MyButtons.View
|
<Space size={4}>
|
||||||
title={`${record?.asset_house?.full_name || '-'}`}
|
<MyButtons.View
|
||||||
type="link"
|
title={name || '-'}
|
||||||
onClick={() => {
|
type="link"
|
||||||
navigate(`/bills/summary/show/${record.asset_houses_id}`);
|
onClick={() => {
|
||||||
}}
|
navigate(`/bills/summary/show/${record.asset_houses_id}`);
|
||||||
/>
|
}}
|
||||||
|
/>
|
||||||
|
{name && (
|
||||||
|
<CopyOutlined
|
||||||
|
style={{ color: '#999' }}
|
||||||
|
onClick={() => {
|
||||||
|
navigator.clipboard.writeText(name);
|
||||||
|
message.success('已复制');
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Space>
|
||||||
) : (
|
) : (
|
||||||
'车位| ' + record.asset_car_port.full_name
|
'-'
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '关联车位',
|
||||||
|
dataIndex: ['asset_car_port', 'full_name'],
|
||||||
|
search: {
|
||||||
|
transform: (value) => {
|
||||||
|
return { car_port_name: value };
|
||||||
|
},
|
||||||
|
},
|
||||||
|
render: (_, record) => {
|
||||||
|
const name = record?.asset_car_port?.full_name;
|
||||||
|
return record.asset_car_ports_id ? (
|
||||||
|
<Space size={4}>
|
||||||
|
<MyButtons.View
|
||||||
|
title={name || '-'}
|
||||||
|
type="link"
|
||||||
|
onClick={() => {
|
||||||
|
navigate(
|
||||||
|
`/bills/summary/car_port_show/${record.asset_car_ports_id}`,
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{name && (
|
||||||
|
<CopyOutlined
|
||||||
|
style={{ color: '#999' }}
|
||||||
|
onClick={() => {
|
||||||
|
navigator.clipboard.writeText(name);
|
||||||
|
message.success('已复制');
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Space>
|
||||||
|
) : (
|
||||||
|
'-'
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
title: '账单月份',
|
title: '账单月份',
|
||||||
render: (_, record) => {
|
render: (_, record) => {
|
||||||
@ -267,6 +328,16 @@ export default function Index({ title = '账单明细' }) {
|
|||||||
title={title}
|
title={title}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
|
copy: (
|
||||||
|
<BillCopy
|
||||||
|
key="Copy"
|
||||||
|
item={{
|
||||||
|
...item,
|
||||||
|
}}
|
||||||
|
reload={action?.reload}
|
||||||
|
title="复制"
|
||||||
|
/>
|
||||||
|
),
|
||||||
delete: (
|
delete: (
|
||||||
<MyButtons.Delete
|
<MyButtons.Delete
|
||||||
disabled={
|
disabled={
|
||||||
|
|||||||
216
src/pages/bills/house_bills/modals/BillCopy.tsx
Normal file
216
src/pages/bills/house_bills/modals/BillCopy.tsx
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
import {
|
||||||
|
MyBetaModalFormProps,
|
||||||
|
MyButtons,
|
||||||
|
MyFormItems,
|
||||||
|
MyModalFormProps,
|
||||||
|
rulesHelper,
|
||||||
|
} from '@/common';
|
||||||
|
import { Selects } from '@/components/Select';
|
||||||
|
import { Apis } from '@/gen/Apis';
|
||||||
|
import { HouseBillsTypeEnum } from '@/gen/Enums';
|
||||||
|
import { BetaSchemaForm } from '@ant-design/pro-components';
|
||||||
|
import { Form, message } from 'antd';
|
||||||
|
|
||||||
|
export default function Copy(props: MyBetaModalFormProps) {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const isCarPortFee =
|
||||||
|
props.item?.type === 'CarPortFee' || props.item?.type === 'CarPortDeposit';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<BetaSchemaForm<ApiTypes.Bill.HouseBills.Store>
|
||||||
|
{...MyModalFormProps.props}
|
||||||
|
title={`账单复制`}
|
||||||
|
trigger={<MyButtons.Default title="复制" type="primary" size="small" />}
|
||||||
|
wrapperCol={{ span: 24 }}
|
||||||
|
width="800px"
|
||||||
|
key={new Date().getTime()}
|
||||||
|
form={form}
|
||||||
|
onOpenChange={(open: any) => {
|
||||||
|
if (open && props.item) {
|
||||||
|
const formValues = {
|
||||||
|
type: props.item?.type,
|
||||||
|
amount: props.item?.amount,
|
||||||
|
discount_amount: props.item?.discount_amount,
|
||||||
|
late_fee: props.item?.late_fee,
|
||||||
|
company_receipt_accounts_id:
|
||||||
|
props.item?.company_receipt_accounts_id,
|
||||||
|
remark: props.item?.remark,
|
||||||
|
};
|
||||||
|
form.setFieldsValue(formValues);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onFinish={async (values) => {
|
||||||
|
const isCarPortFee =
|
||||||
|
props.item?.type === 'CarPortFee' ||
|
||||||
|
props.item?.type === 'CarPortDeposit';
|
||||||
|
return Apis.Bill.HouseBills.Store({
|
||||||
|
...values,
|
||||||
|
type: props.item?.type,
|
||||||
|
asset_car_ports_id: isCarPortFee
|
||||||
|
? props.item?.asset_car_ports_id
|
||||||
|
: undefined,
|
||||||
|
asset_houses_id: !isCarPortFee
|
||||||
|
? props.item?.asset_houses_id
|
||||||
|
: undefined,
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
props.reload?.();
|
||||||
|
message.success('手动添加账单成功');
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.catch(() => false);
|
||||||
|
}}
|
||||||
|
columns={[
|
||||||
|
{
|
||||||
|
valueType: 'dependency',
|
||||||
|
name: ['type'],
|
||||||
|
columns: ({ type }) => {
|
||||||
|
const field =
|
||||||
|
type === 'CarPortFee' || type === 'CarPortDeposit'
|
||||||
|
? {
|
||||||
|
key: 'asset_car_port_full_name',
|
||||||
|
title: '车位信息',
|
||||||
|
colProps: { span: 18 },
|
||||||
|
fieldProps: {
|
||||||
|
disabled: true,
|
||||||
|
},
|
||||||
|
initialValue: props.item?.asset_car_port?.full_name,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
key: 'asset_house_full_name',
|
||||||
|
title: '房屋信息',
|
||||||
|
colProps: { span: 18 },
|
||||||
|
fieldProps: {
|
||||||
|
disabled: true,
|
||||||
|
},
|
||||||
|
initialValue: props.item?.asset_house?.full_name,
|
||||||
|
};
|
||||||
|
return [field];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MyFormItems.EnumSelect({
|
||||||
|
key: 'type',
|
||||||
|
title: '类型',
|
||||||
|
colProps: { span: 6 },
|
||||||
|
valueEnum: HouseBillsTypeEnum,
|
||||||
|
required: true,
|
||||||
|
fieldProps: {
|
||||||
|
disabled: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
key: 'amount',
|
||||||
|
title: '金额',
|
||||||
|
valueType: 'digit',
|
||||||
|
colProps: { span: 8 },
|
||||||
|
fieldProps: {
|
||||||
|
style: {
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
formItemProps: { ...rulesHelper.number },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'discount_amount',
|
||||||
|
title: '优惠金额',
|
||||||
|
valueType: 'digit',
|
||||||
|
fieldProps: {
|
||||||
|
style: {
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
colProps: { span: 8 },
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
key: 'late_fee',
|
||||||
|
title: '滞纳金',
|
||||||
|
valueType: 'digit',
|
||||||
|
fieldProps: {
|
||||||
|
style: {
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
colProps: { span: 8 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'month',
|
||||||
|
title: '账单月份',
|
||||||
|
valueType: 'date',
|
||||||
|
colProps: { span: 8 },
|
||||||
|
fieldProps: {
|
||||||
|
picker: 'month',
|
||||||
|
format: 'YYYY-MM',
|
||||||
|
valueFormat: 'YYYY-MM',
|
||||||
|
style: {
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
onChange: (e: any, dateString: string) => {
|
||||||
|
form.setFieldsValue({
|
||||||
|
start_date: rulesHelper.getMonthStartDate(dateString),
|
||||||
|
end_date: rulesHelper.getMonthEndDate(dateString),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
formItemProps: { ...rulesHelper.text },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'start_date',
|
||||||
|
title: '计费开始日期',
|
||||||
|
valueType: 'date',
|
||||||
|
colProps: { span: 8 },
|
||||||
|
fieldProps: {
|
||||||
|
style: {
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
formItemProps: { ...rulesHelper.text },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'end_date',
|
||||||
|
title: '计费结束日期',
|
||||||
|
valueType: 'date',
|
||||||
|
colProps: { span: 8 },
|
||||||
|
fieldProps: {
|
||||||
|
style: {
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
formItemProps: { ...rulesHelper.text },
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
valueType: 'dependency',
|
||||||
|
name: ['asset_projects_id'],
|
||||||
|
columns: ({ asset_projects_id }) => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
valueType: 'group',
|
||||||
|
columns: [
|
||||||
|
Selects?.ProjectAccounts({
|
||||||
|
key: 'company_receipt_accounts_id',
|
||||||
|
title: '选择收款账户',
|
||||||
|
params: {
|
||||||
|
projects_id: asset_projects_id,
|
||||||
|
},
|
||||||
|
colProps: { span: 24 },
|
||||||
|
formItemProps: { ...rulesHelper.number },
|
||||||
|
fieldProps: {
|
||||||
|
showSearch: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '备注',
|
||||||
|
key: 'remark',
|
||||||
|
valueType: 'textarea',
|
||||||
|
colProps: { span: 24 },
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -7,20 +7,39 @@ import {
|
|||||||
} from '@/common';
|
} from '@/common';
|
||||||
import { Selects } from '@/components/Select';
|
import { Selects } from '@/components/Select';
|
||||||
import { Apis } from '@/gen/Apis';
|
import { Apis } from '@/gen/Apis';
|
||||||
import { HouseBillsTypeEnum } from '@/gen/Enums';
|
import {
|
||||||
|
ApprovalTemplateNodesNodeTypeEnum,
|
||||||
|
ApprovalTemplatesTypeEnum,
|
||||||
|
HouseBillsBillStatusEnum,
|
||||||
|
HouseBillsTypeEnum,
|
||||||
|
} from '@/gen/Enums';
|
||||||
import { BetaSchemaForm } from '@ant-design/pro-components';
|
import { BetaSchemaForm } from '@ant-design/pro-components';
|
||||||
import { Form, message } from 'antd';
|
import { Button, Form, message } from 'antd';
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
export default function Update(props: MyBetaModalFormProps) {
|
export default function Update(props: MyBetaModalFormProps) {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
const [ApprovalTemplates, setApprovalTemplates] = useState<any>([]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BetaSchemaForm<ApiTypes.Bill.HouseBills.Update>
|
<BetaSchemaForm<ApiTypes.Bill.HouseBills.Update>
|
||||||
{...MyModalFormProps.props}
|
{...MyModalFormProps.props}
|
||||||
title={`${props.title}编辑`}
|
title={`${props.title}编辑`}
|
||||||
trigger={<MyButtons.Edit />}
|
trigger={
|
||||||
|
<MyButtons.Default
|
||||||
|
title="编辑"
|
||||||
|
type="primary"
|
||||||
|
size="small"
|
||||||
|
disabled={
|
||||||
|
props?.item?.bill_status === HouseBillsBillStatusEnum.Paid.value ||
|
||||||
|
props?.item?.bill_status ===
|
||||||
|
HouseBillsBillStatusEnum.Cancelled.value
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
}
|
||||||
wrapperCol={{ span: 24 }}
|
wrapperCol={{ span: 24 }}
|
||||||
width="800px"
|
width="800px"
|
||||||
key={new Date().getTime()}
|
key={props.item?.id}
|
||||||
form={form}
|
form={form}
|
||||||
onOpenChange={(open: any) => {
|
onOpenChange={(open: any) => {
|
||||||
if (open && props.item) {
|
if (open && props.item) {
|
||||||
@ -37,15 +56,64 @@ export default function Update(props: MyBetaModalFormProps) {
|
|||||||
form.setFieldsValue(formValues);
|
form.setFieldsValue(formValues);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onFinish={async (values) =>
|
onFinish={async (values: any) => {
|
||||||
Apis.Bill.HouseBills.Update({ ...values, id: props.item?.id ?? 0 })
|
const { node_approvers } = values;
|
||||||
|
|
||||||
|
if (ApprovalTemplates?.length > 0 && node_approvers?.length > 0) {
|
||||||
|
// 遍历模板节点,通过名称找到对应的提交节点进行校验
|
||||||
|
for (const templateNode of ApprovalTemplates) {
|
||||||
|
// 通过名称找到对应的提交节点
|
||||||
|
const submittedNode = node_approvers.find(
|
||||||
|
(node: any) => node?.name === templateNode?.name,
|
||||||
|
);
|
||||||
|
|
||||||
|
// 如果模板节点在提交数据中不存在,说明被删除了,报错
|
||||||
|
if (!submittedNode) {
|
||||||
|
message.error(`节点"${templateNode?.name}"不能删除`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 校验审批人
|
||||||
|
if (
|
||||||
|
templateNode?.node_type ===
|
||||||
|
ApprovalTemplateNodesNodeTypeEnum.Approver.value
|
||||||
|
) {
|
||||||
|
const originalMembers =
|
||||||
|
templateNode?.approval_template_node_members?.map(
|
||||||
|
(member: any) => member?.company_employees_id,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (originalMembers?.length > 0) {
|
||||||
|
const submittedMembers = submittedNode?.members || [];
|
||||||
|
|
||||||
|
const isMatch =
|
||||||
|
originalMembers.length === submittedMembers.length &&
|
||||||
|
originalMembers.every((memberId: number) =>
|
||||||
|
submittedMembers.includes(memberId),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!isMatch) {
|
||||||
|
message.error(
|
||||||
|
`节点"${templateNode?.name}"的审批人必须与审批模板设置保持一致`,
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Apis.Bill.HouseBills.Update({
|
||||||
|
...values,
|
||||||
|
id: props.item?.id ?? 0,
|
||||||
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
props.reload?.();
|
props.reload?.();
|
||||||
message.success(props.title + '成功');
|
message.success(props.title + '成功');
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.catch(() => false)
|
.catch(() => false);
|
||||||
}
|
}}
|
||||||
columns={[
|
columns={[
|
||||||
MyFormItems.EnumRadio({
|
MyFormItems.EnumRadio({
|
||||||
key: 'type',
|
key: 'type',
|
||||||
@ -166,6 +234,182 @@ export default function Update(props: MyBetaModalFormProps) {
|
|||||||
valueType: 'textarea',
|
valueType: 'textarea',
|
||||||
colProps: { span: 24 },
|
colProps: { span: 24 },
|
||||||
},
|
},
|
||||||
|
Selects?.ApprovalTemplates({
|
||||||
|
key: 'approval_templates_id',
|
||||||
|
title: '审批模版',
|
||||||
|
params: {
|
||||||
|
type: ApprovalTemplatesTypeEnum.HouseBillUpdate.value,
|
||||||
|
is_enabled: '1',
|
||||||
|
},
|
||||||
|
colProps: { span: 24 },
|
||||||
|
formItemProps: { ...rulesHelper.number },
|
||||||
|
fieldProps: {
|
||||||
|
onChange: (e: any) => {
|
||||||
|
if (e) {
|
||||||
|
const templateId = typeof e === 'object' ? e.value : e;
|
||||||
|
Apis.Approval.ApprovalTemplates.Show({
|
||||||
|
id: templateId,
|
||||||
|
}).then((res) => {
|
||||||
|
setApprovalTemplates(res?.data?.approval_template_nodes);
|
||||||
|
form.setFieldsValue({
|
||||||
|
approval_templates_id: templateId,
|
||||||
|
node_approvers: res?.data?.approval_template_nodes?.map(
|
||||||
|
(item: any) => ({
|
||||||
|
...item,
|
||||||
|
members: item?.approval_template_node_members?.map(
|
||||||
|
(member: any) => member?.company_employees_id,
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
valueType: 'dependency',
|
||||||
|
name: ['approval_templates_id'],
|
||||||
|
columns: ({ approval_templates_id }) => {
|
||||||
|
return approval_templates_id
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
valueType: 'formList',
|
||||||
|
dataIndex: 'node_approvers',
|
||||||
|
fieldProps: {
|
||||||
|
creatorButtonProps: false,
|
||||||
|
actionRender: (field: any, action: any) => [
|
||||||
|
<Button
|
||||||
|
key="add"
|
||||||
|
type="link"
|
||||||
|
size="small"
|
||||||
|
onClick={() => {
|
||||||
|
const currentNodeType = form.getFieldValue([
|
||||||
|
'node_approvers',
|
||||||
|
field.name,
|
||||||
|
'node_type',
|
||||||
|
]);
|
||||||
|
if (
|
||||||
|
currentNodeType ===
|
||||||
|
ApprovalTemplateNodesNodeTypeEnum.CC.value
|
||||||
|
) {
|
||||||
|
message.warning('抄送节点不允许添加');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
action.add(
|
||||||
|
{
|
||||||
|
node_type:
|
||||||
|
ApprovalTemplateNodesNodeTypeEnum.Approver
|
||||||
|
.value,
|
||||||
|
},
|
||||||
|
field.name + 1,
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
添加
|
||||||
|
</Button>,
|
||||||
|
<Button
|
||||||
|
key="delete"
|
||||||
|
type="link"
|
||||||
|
size="small"
|
||||||
|
danger
|
||||||
|
onClick={() => {
|
||||||
|
action.remove(field.name);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</Button>,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
formItemProps: {
|
||||||
|
...rulesHelper.array,
|
||||||
|
wrapperCol: { span: 24 },
|
||||||
|
},
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
valueType: 'group',
|
||||||
|
colProps: { span: 24 },
|
||||||
|
columns: [
|
||||||
|
MyFormItems.EnumSelect({
|
||||||
|
key: 'node_type',
|
||||||
|
valueEnum: ApprovalTemplateNodesNodeTypeEnum,
|
||||||
|
colProps: { span: 5 },
|
||||||
|
formItemProps: {
|
||||||
|
...rulesHelper.text,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
key: 'name',
|
||||||
|
colProps: { span: 6 },
|
||||||
|
formItemProps: {
|
||||||
|
...rulesHelper.text,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
valueType: 'dependency',
|
||||||
|
name: ['node_type'],
|
||||||
|
columns: ({ node_type }) => {
|
||||||
|
return [
|
||||||
|
Selects.Employees({
|
||||||
|
key: 'members',
|
||||||
|
title: ``,
|
||||||
|
colProps: { span: 13 },
|
||||||
|
formItemProps: {
|
||||||
|
...rulesHelper.array,
|
||||||
|
},
|
||||||
|
fieldProps: {
|
||||||
|
mode: 'multiple',
|
||||||
|
showSearch: true,
|
||||||
|
maxCount:
|
||||||
|
node_type ===
|
||||||
|
ApprovalTemplateNodesNodeTypeEnum.Approver
|
||||||
|
.value
|
||||||
|
? 1
|
||||||
|
: 9,
|
||||||
|
maxTagTextLength: 20,
|
||||||
|
labelRender: (res: any) => {
|
||||||
|
if (res?.label) {
|
||||||
|
return res?.label;
|
||||||
|
} else {
|
||||||
|
return ApprovalTemplates?.map(
|
||||||
|
(item: any) => {
|
||||||
|
if (
|
||||||
|
item?.node_type === node_type &&
|
||||||
|
item
|
||||||
|
?.approval_template_node_members
|
||||||
|
?.length
|
||||||
|
) {
|
||||||
|
return item?.approval_template_node_members?.map(
|
||||||
|
(i: any) => {
|
||||||
|
if (
|
||||||
|
i?.company_employees_id ===
|
||||||
|
res?.value
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
i?.company_employee
|
||||||
|
?.name || ''
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: [];
|
||||||
|
},
|
||||||
|
},
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -119,6 +119,7 @@ export default function PayCreate(props: PayCreateProps): React.ReactElement {
|
|||||||
delete obj.Alipay;
|
delete obj.Alipay;
|
||||||
delete obj.TongLian;
|
delete obj.TongLian;
|
||||||
delete obj.Prepayment;
|
delete obj.Prepayment;
|
||||||
|
delete obj.CCB;
|
||||||
return obj;
|
return obj;
|
||||||
},
|
},
|
||||||
required: true,
|
required: true,
|
||||||
|
|||||||
@ -1,7 +1,12 @@
|
|||||||
import { MyBetaModalFormProps, MyButtons, MyModalFormProps } from '@/common';
|
import {
|
||||||
|
MyBetaModalFormProps,
|
||||||
|
MyButtons,
|
||||||
|
MyModalFormProps,
|
||||||
|
renderTextHelper,
|
||||||
|
} from '@/common';
|
||||||
import { Apis } from '@/gen/Apis';
|
import { Apis } from '@/gen/Apis';
|
||||||
import { HouseBillsBillStatusEnum } from '@/gen/Enums';
|
import { HouseBillsBillStatusEnum, HouseBillsTypeEnum } from '@/gen/Enums';
|
||||||
import { BetaSchemaForm } from '@ant-design/pro-components';
|
import { BetaSchemaForm, ProDescriptions } from '@ant-design/pro-components';
|
||||||
import { Form, QRCode, Tabs } from 'antd';
|
import { Form, QRCode, Tabs } from 'antd';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
|
||||||
@ -10,7 +15,6 @@ export default function ShowQrCode(props: MyBetaModalFormProps) {
|
|||||||
const [activeTab, setActiveTab] = useState<string>('wechat');
|
const [activeTab, setActiveTab] = useState<string>('wechat');
|
||||||
const [wechatQrCode, setWechatQrCode] = useState<string>('');
|
const [wechatQrCode, setWechatQrCode] = useState<string>('');
|
||||||
const [alipayQrCode, setAlipayQrCode] = useState<string>('');
|
const [alipayQrCode, setAlipayQrCode] = useState<string>('');
|
||||||
const [orderInfo, setOrderInfo] = useState<any>(null);
|
|
||||||
|
|
||||||
const fetchQrCode = (type: 'wechat' | 'alipay') => {
|
const fetchQrCode = (type: 'wechat' | 'alipay') => {
|
||||||
if (props?.item?.amount && props?.item?.accept_amount) {
|
if (props?.item?.amount && props?.item?.accept_amount) {
|
||||||
@ -24,13 +28,10 @@ export default function ShowQrCode(props: MyBetaModalFormProps) {
|
|||||||
if (type === 'wechat') {
|
if (type === 'wechat') {
|
||||||
Apis.HouseOrder.HouseOrders.GetPayCode(params).then((res: any) => {
|
Apis.HouseOrder.HouseOrders.GetPayCode(params).then((res: any) => {
|
||||||
setWechatQrCode(res?.data?.qr_code || '');
|
setWechatQrCode(res?.data?.qr_code || '');
|
||||||
setOrderInfo(res?.data?.order);
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
Apis.HouseOrder.HouseOrders.AlipayQrCode(params).then((res: any) => {
|
Apis.HouseOrder.HouseOrders.AlipayQrCode(params).then((res: any) => {
|
||||||
// 支付宝返回的 qr_code 是对象,实际链接在 payinfo 字段
|
setAlipayQrCode(res?.data?.payinfo || '');
|
||||||
setAlipayQrCode(res?.data?.qr_code?.payinfo || '');
|
|
||||||
setOrderInfo(res?.data?.order);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,7 +61,6 @@ export default function ShowQrCode(props: MyBetaModalFormProps) {
|
|||||||
if (open) {
|
if (open) {
|
||||||
setWechatQrCode('');
|
setWechatQrCode('');
|
||||||
setAlipayQrCode('');
|
setAlipayQrCode('');
|
||||||
setOrderInfo(null);
|
|
||||||
setActiveTab('wechat');
|
setActiveTab('wechat');
|
||||||
fetchQrCode('wechat');
|
fetchQrCode('wechat');
|
||||||
}
|
}
|
||||||
@ -72,10 +72,31 @@ export default function ShowQrCode(props: MyBetaModalFormProps) {
|
|||||||
key: 'qrcode',
|
key: 'qrcode',
|
||||||
renderFormItem() {
|
renderFormItem() {
|
||||||
return (
|
return (
|
||||||
<div style={{ textAlign: 'center' }}>
|
<div style={{ textAlign: 'left' }}>
|
||||||
<div style={{ fontSize: '16px', fontWeight: 'bold', marginBottom: '16px' }}>
|
<ProDescriptions
|
||||||
{props?.item?.asset_house?.full_name}
|
column={2}
|
||||||
</div>
|
size="small"
|
||||||
|
bordered
|
||||||
|
style={{ marginBottom: '16px' }}
|
||||||
|
>
|
||||||
|
<ProDescriptions.Item label="关联房屋/车位" span={2}>
|
||||||
|
{props?.item?.asset_houses_id
|
||||||
|
? ` ${props?.item?.asset_house?.full_name || ''}`
|
||||||
|
: props?.item?.asset_car_port?.full_name
|
||||||
|
? ` ${props?.item?.asset_car_port?.full_name}`
|
||||||
|
: ''}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="费用类型">
|
||||||
|
<renderTextHelper.Tag
|
||||||
|
Enums={HouseBillsTypeEnum}
|
||||||
|
value={props?.item?.type}
|
||||||
|
key="type"
|
||||||
|
/>
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="应收金额">
|
||||||
|
¥{props?.item?.total_payable_amount || 0}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
</ProDescriptions>
|
||||||
<Tabs
|
<Tabs
|
||||||
activeKey={activeTab}
|
activeKey={activeTab}
|
||||||
onChange={(key) => {
|
onChange={(key) => {
|
||||||
@ -105,7 +126,15 @@ export default function ShowQrCode(props: MyBetaModalFormProps) {
|
|||||||
alt="微信支付二维码"
|
alt="微信支付二维码"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<div style={{ width: '220px', height: '220px', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
<div
|
||||||
|
style={{
|
||||||
|
width: '220px',
|
||||||
|
height: '220px',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
加载中...
|
加载中...
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@ -114,7 +143,7 @@ export default function ShowQrCode(props: MyBetaModalFormProps) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'alipay',
|
key: 'alipay',
|
||||||
label: '支付宝支付',
|
label: '支付宝',
|
||||||
children: (
|
children: (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
@ -126,7 +155,15 @@ export default function ShowQrCode(props: MyBetaModalFormProps) {
|
|||||||
{alipayQrCode ? (
|
{alipayQrCode ? (
|
||||||
<QRCode value={alipayQrCode} size={220} />
|
<QRCode value={alipayQrCode} size={220} />
|
||||||
) : (
|
) : (
|
||||||
<div style={{ width: '220px', height: '220px', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
<div
|
||||||
|
style={{
|
||||||
|
width: '220px',
|
||||||
|
height: '220px',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
加载中...
|
加载中...
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@ -135,17 +172,6 @@ export default function ShowQrCode(props: MyBetaModalFormProps) {
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<div style={{ fontSize: '16px', fontWeight: 'bold' }}>
|
|
||||||
支付金额:
|
|
||||||
<span style={{ color: '#f00' }}>
|
|
||||||
¥
|
|
||||||
{(
|
|
||||||
parseFloat(orderInfo?.total_payable_amount || '0') || 0
|
|
||||||
).toFixed(2)}
|
|
||||||
元
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div>收款单ID:{orderInfo?.id || ''}</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
62
src/pages/bills/summary/car_port_show/$id.tsx
Normal file
62
src/pages/bills/summary/car_port_show/$id.tsx
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import { MyPageContainer } from '@/common';
|
||||||
|
import { Apis } from '@/gen/Apis';
|
||||||
|
import { ProCard } from '@ant-design/pro-components';
|
||||||
|
import { useParams } from '@umijs/max';
|
||||||
|
import { Tabs } from 'antd';
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
import CarPortBillInfo from '../components/CarPortBillInfo';
|
||||||
|
import PaidBill from '../table/PaidBill';
|
||||||
|
import UnpaidBill from '../table/UnpaidBill';
|
||||||
|
|
||||||
|
export default function CarPortShow({ title = '车位账单详情' }) {
|
||||||
|
const { id } = useParams<{ id: string }>();
|
||||||
|
const [data, setData] = useState<any>({});
|
||||||
|
|
||||||
|
const loadShow = () => {
|
||||||
|
Apis.Asset.AssetCarPorts.Show({ id: Number(id) }).then((res) => {
|
||||||
|
setData(res?.data);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
loadShow();
|
||||||
|
}, [id]);
|
||||||
|
|
||||||
|
const billItem = { ...data, asset_car_ports_id: id };
|
||||||
|
|
||||||
|
const items = [
|
||||||
|
{
|
||||||
|
label: '未缴账单',
|
||||||
|
key: '1',
|
||||||
|
closable: false,
|
||||||
|
children: <UnpaidBill item={billItem} />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '已缴账单',
|
||||||
|
key: '2',
|
||||||
|
closable: false,
|
||||||
|
children: <PaidBill item={billItem} />,
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// label: '退款账单',
|
||||||
|
// key: '4',
|
||||||
|
// closable: false,
|
||||||
|
// children: <MyRefund item={{ id, asset_car_ports_id: id }} />,
|
||||||
|
// },
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MyPageContainer
|
||||||
|
title={title}
|
||||||
|
enableTabs
|
||||||
|
tabKey={`car-port-bill-detail-${id}`}
|
||||||
|
tabLabel={data?.full_name || title}
|
||||||
|
>
|
||||||
|
<CarPortBillInfo item={data} reload={loadShow} />
|
||||||
|
<ProCard style={{ marginTop: 16 }}>
|
||||||
|
<Tabs type="card" items={items} defaultActiveKey="1" />
|
||||||
|
</ProCard>
|
||||||
|
</MyPageContainer>
|
||||||
|
);
|
||||||
|
}
|
||||||
19
src/pages/bills/summary/components/CarPortBillInfo.tsx
Normal file
19
src/pages/bills/summary/components/CarPortBillInfo.tsx
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { MyBetaModalFormProps } from '@/common';
|
||||||
|
import { ProCard, ProDescriptions } from '@ant-design/pro-components';
|
||||||
|
|
||||||
|
export default function CarPortBillInfo(props: MyBetaModalFormProps) {
|
||||||
|
const { item } = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ProCard title="基本信息">
|
||||||
|
<ProDescriptions bordered>
|
||||||
|
<ProDescriptions.Item label="车位名称" span={2}>
|
||||||
|
{item?.full_name || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="所属项目">
|
||||||
|
{item?.asset_project?.name || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
</ProDescriptions>
|
||||||
|
</ProCard>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -2,7 +2,9 @@ import { MyColumns, MyProTableProps } from '@/common';
|
|||||||
import { Apis } from '@/gen/Apis';
|
import { Apis } from '@/gen/Apis';
|
||||||
import { HouseBillsBillStatusEnum, HouseBillsTypeEnum } from '@/gen/Enums';
|
import { HouseBillsBillStatusEnum, HouseBillsTypeEnum } from '@/gen/Enums';
|
||||||
import { ProTable } from '@ant-design/pro-components';
|
import { ProTable } from '@ant-design/pro-components';
|
||||||
|
import { Space } from 'antd';
|
||||||
import { useEffect, useRef, useState } from 'react';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
|
import BillCopy from '../../house_bills/modals/BillCopy';
|
||||||
import PayCreate from './modals/PayCreate';
|
import PayCreate from './modals/PayCreate';
|
||||||
import ShowQrCode from './modals/ShowQrCode';
|
import ShowQrCode from './modals/ShowQrCode';
|
||||||
|
|
||||||
@ -122,13 +124,21 @@ export default function Index({ ...rest }) {
|
|||||||
},
|
},
|
||||||
search: false,
|
search: false,
|
||||||
},
|
},
|
||||||
// MyColumns.Option({
|
MyColumns.Option({
|
||||||
// render: (_, item: any, index, action) => (
|
width: 100,
|
||||||
// <Space key={index}>
|
render: (_, item: any, index, action) => (
|
||||||
// <BillUpdate item={item} reload={action?.reload} title="编辑" />
|
<Space key={index}>
|
||||||
// </Space>
|
<BillCopy
|
||||||
// ),
|
key="Copy"
|
||||||
// }),
|
item={{
|
||||||
|
...item,
|
||||||
|
}}
|
||||||
|
reload={action?.reload}
|
||||||
|
title="复制"
|
||||||
|
/>
|
||||||
|
</Space>
|
||||||
|
),
|
||||||
|
}),
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { MyBetaModalFormProps, MyButtons, MyModalFormProps } from '@/common';
|
import { MyBetaModalFormProps, MyButtons, MyModalFormProps } from '@/common';
|
||||||
import { Apis } from '@/gen/Apis';
|
import { Apis } from '@/gen/Apis';
|
||||||
import { BetaSchemaForm } from '@ant-design/pro-components';
|
import { BetaSchemaForm, ProDescriptions } from '@ant-design/pro-components';
|
||||||
import { Form, QRCode, Tabs } from 'antd';
|
import { Form, QRCode, Tabs } from 'antd';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
|
||||||
@ -9,7 +9,6 @@ export default function ShowQrCode(props: MyBetaModalFormProps) {
|
|||||||
const [activeTab, setActiveTab] = useState<string>('wechat');
|
const [activeTab, setActiveTab] = useState<string>('wechat');
|
||||||
const [wechatQrCode, setWechatQrCode] = useState<string>('');
|
const [wechatQrCode, setWechatQrCode] = useState<string>('');
|
||||||
const [alipayQrCode, setAlipayQrCode] = useState<string>('');
|
const [alipayQrCode, setAlipayQrCode] = useState<string>('');
|
||||||
const [orderInfo, setOrderInfo] = useState<any>(null);
|
|
||||||
|
|
||||||
const fetchQrCode = (type: 'wechat' | 'alipay') => {
|
const fetchQrCode = (type: 'wechat' | 'alipay') => {
|
||||||
let total_amount = 0;
|
let total_amount = 0;
|
||||||
@ -26,12 +25,10 @@ export default function ShowQrCode(props: MyBetaModalFormProps) {
|
|||||||
if (type === 'wechat') {
|
if (type === 'wechat') {
|
||||||
Apis.HouseOrder.HouseOrders.GetPayCode(params).then((res: any) => {
|
Apis.HouseOrder.HouseOrders.GetPayCode(params).then((res: any) => {
|
||||||
setWechatQrCode(res?.data?.qr_code || '');
|
setWechatQrCode(res?.data?.qr_code || '');
|
||||||
setOrderInfo(res?.data?.order);
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
Apis.HouseOrder.HouseOrders.AlipayQrCode(params).then((res: any) => {
|
Apis.HouseOrder.HouseOrders.AlipayQrCode(params).then((res: any) => {
|
||||||
setAlipayQrCode(res?.data?.qr_code?.payinfo || '');
|
setAlipayQrCode(res?.data?.payinfo || '');
|
||||||
setOrderInfo(res?.data?.order);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -57,7 +54,6 @@ export default function ShowQrCode(props: MyBetaModalFormProps) {
|
|||||||
if (open) {
|
if (open) {
|
||||||
setWechatQrCode('');
|
setWechatQrCode('');
|
||||||
setAlipayQrCode('');
|
setAlipayQrCode('');
|
||||||
setOrderInfo(null);
|
|
||||||
setActiveTab('wechat');
|
setActiveTab('wechat');
|
||||||
fetchQrCode('wechat');
|
fetchQrCode('wechat');
|
||||||
}
|
}
|
||||||
@ -69,10 +65,29 @@ export default function ShowQrCode(props: MyBetaModalFormProps) {
|
|||||||
key: 'qrcode',
|
key: 'qrcode',
|
||||||
renderFormItem() {
|
renderFormItem() {
|
||||||
return (
|
return (
|
||||||
<div style={{ textAlign: 'center' }}>
|
<div style={{ textAlign: 'left' }}>
|
||||||
<div style={{ fontSize: '16px', fontWeight: 'bold', marginBottom: '16px' }}>
|
<ProDescriptions
|
||||||
{props?.item?.asset_house?.full_name}
|
column={2}
|
||||||
</div>
|
size="small"
|
||||||
|
bordered
|
||||||
|
style={{ marginBottom: '16px' }}
|
||||||
|
>
|
||||||
|
<ProDescriptions.Item label="关联房屋/车位" span={2}>
|
||||||
|
{props?.item?.asset_houses_id
|
||||||
|
? props?.item?.asset_house?.full_name || ''
|
||||||
|
: props?.item?.asset_car_port?.full_name || ''}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="应收金额">
|
||||||
|
¥
|
||||||
|
{props?.item?.list
|
||||||
|
?.reduce(
|
||||||
|
(sum: number, item: any) =>
|
||||||
|
sum + Number(item?.total_payable_amount || 0),
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
.toFixed(2) || 0}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
</ProDescriptions>
|
||||||
<Tabs
|
<Tabs
|
||||||
activeKey={activeTab}
|
activeKey={activeTab}
|
||||||
onChange={(key) => {
|
onChange={(key) => {
|
||||||
@ -102,7 +117,15 @@ export default function ShowQrCode(props: MyBetaModalFormProps) {
|
|||||||
alt="微信支付二维码"
|
alt="微信支付二维码"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<div style={{ width: '220px', height: '220px', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
<div
|
||||||
|
style={{
|
||||||
|
width: '220px',
|
||||||
|
height: '220px',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
加载中...
|
加载中...
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@ -111,7 +134,7 @@ export default function ShowQrCode(props: MyBetaModalFormProps) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'alipay',
|
key: 'alipay',
|
||||||
label: '支付宝支付',
|
label: '支付宝',
|
||||||
children: (
|
children: (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
@ -123,7 +146,15 @@ export default function ShowQrCode(props: MyBetaModalFormProps) {
|
|||||||
{alipayQrCode ? (
|
{alipayQrCode ? (
|
||||||
<QRCode value={alipayQrCode} size={220} />
|
<QRCode value={alipayQrCode} size={220} />
|
||||||
) : (
|
) : (
|
||||||
<div style={{ width: '220px', height: '220px', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
<div
|
||||||
|
style={{
|
||||||
|
width: '220px',
|
||||||
|
height: '220px',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
加载中...
|
加载中...
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@ -132,15 +163,6 @@ export default function ShowQrCode(props: MyBetaModalFormProps) {
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<div style={{ fontSize: '16px', fontWeight: 'bold' }}>
|
|
||||||
支付金额:
|
|
||||||
<span style={{ color: '#f00' }}>
|
|
||||||
¥
|
|
||||||
{parseFloat(orderInfo?.total_payable_amount || '0').toFixed(2)}
|
|
||||||
元
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div>收款单ID:{orderInfo?.id || ''}</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
256
src/pages/bills/temporary/index.tsx
Normal file
256
src/pages/bills/temporary/index.tsx
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
import {
|
||||||
|
MyButtons,
|
||||||
|
MyColumns,
|
||||||
|
MyPageContainer,
|
||||||
|
MyProTableProps,
|
||||||
|
MyTableActions,
|
||||||
|
MyToolBarActions,
|
||||||
|
} from '@/common';
|
||||||
|
|
||||||
|
import { MyExport } from '@/components/MyExport';
|
||||||
|
import { Selects } from '@/components/Select';
|
||||||
|
import { Apis } from '@/gen/Apis';
|
||||||
|
import {
|
||||||
|
ApprovalTemplatesTypeEnum,
|
||||||
|
BillPaymentsTypeEnum,
|
||||||
|
BillsStatusEnum,
|
||||||
|
} from '@/gen/Enums';
|
||||||
|
import { ProTable } from '@ant-design/pro-components';
|
||||||
|
import { useNavigate } from '@umijs/max';
|
||||||
|
import { Tooltip } from 'antd';
|
||||||
|
import { useState } from 'react';
|
||||||
|
import AuditPayment from './modals/AuditPayment';
|
||||||
|
import BillCopy from './modals/BillCopy';
|
||||||
|
import BillCreate from './modals/BillCreate';
|
||||||
|
import BIllInfo from './modals/BIllInfo';
|
||||||
|
import BillRefund from './modals/BillRefund';
|
||||||
|
import BillUpdate from './modals/BillUpdate';
|
||||||
|
import PayCreate from './modals/Pay';
|
||||||
|
import ShowQrCode from './modals/QrCode';
|
||||||
|
|
||||||
|
export default function Index({ title = '临时收费' }) {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const [getParams, setParams] = useState({});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MyPageContainer
|
||||||
|
title={title}
|
||||||
|
enableTabs={true}
|
||||||
|
tabKey="bills"
|
||||||
|
tabLabel={title}
|
||||||
|
>
|
||||||
|
<ProTable
|
||||||
|
{...MyProTableProps.props}
|
||||||
|
headerTitle={title}
|
||||||
|
request={async (params, sort) => {
|
||||||
|
setParams(params);
|
||||||
|
return MyProTableProps.request(params, sort, Apis.Bill.Bills.List);
|
||||||
|
}}
|
||||||
|
toolBarRender={(action: any) => [
|
||||||
|
<MyToolBarActions
|
||||||
|
key="toolbar"
|
||||||
|
actions={{
|
||||||
|
export: (
|
||||||
|
<MyExport
|
||||||
|
key="export"
|
||||||
|
title="账单导出"
|
||||||
|
item={getParams}
|
||||||
|
download={Apis.Bill.Bills}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
add: (
|
||||||
|
<BillCreate
|
||||||
|
key="Create"
|
||||||
|
reload={action?.reload}
|
||||||
|
title={title}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>,
|
||||||
|
]}
|
||||||
|
columns={[
|
||||||
|
MyColumns.ID({ search: false }),
|
||||||
|
Selects?.AssetProjects({
|
||||||
|
title: '选择项目',
|
||||||
|
key: 'asset_projects_id',
|
||||||
|
hidden: true,
|
||||||
|
}),
|
||||||
|
|
||||||
|
{
|
||||||
|
key: 'year',
|
||||||
|
title: '账单年',
|
||||||
|
valueType: 'date',
|
||||||
|
fieldProps: {
|
||||||
|
picker: 'year',
|
||||||
|
format: 'YYYY',
|
||||||
|
valueFormat: 'YYYY',
|
||||||
|
style: {
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
hidden: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'month',
|
||||||
|
title: '账单月',
|
||||||
|
valueType: 'date',
|
||||||
|
fieldProps: {
|
||||||
|
picker: 'month',
|
||||||
|
format: 'YYYY-MM',
|
||||||
|
valueFormat: 'YYYY/MM',
|
||||||
|
style: {
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
search: {
|
||||||
|
transform: (value) => {
|
||||||
|
let month = value.split('-');
|
||||||
|
return { year: month[0], month: month[1] };
|
||||||
|
},
|
||||||
|
},
|
||||||
|
hidden: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '所属项目',
|
||||||
|
dataIndex: ['asset_project', 'name'],
|
||||||
|
search: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '账单月份',
|
||||||
|
render: (_, record) => {
|
||||||
|
return `${record.year}-${String(record.month).padStart(2, '0')}`;
|
||||||
|
},
|
||||||
|
search: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
MyColumns.EnumTag({
|
||||||
|
title: '类型',
|
||||||
|
dataIndex: 'type',
|
||||||
|
valueEnum: BillPaymentsTypeEnum,
|
||||||
|
}),
|
||||||
|
MyColumns.EnumTag({
|
||||||
|
title: '状态',
|
||||||
|
dataIndex: 'status',
|
||||||
|
valueEnum: BillsStatusEnum,
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
title: '账单金额',
|
||||||
|
dataIndex: 'amount',
|
||||||
|
search: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '账单备注',
|
||||||
|
dataIndex: 'remark',
|
||||||
|
search: false,
|
||||||
|
render: (_, item: any) => {
|
||||||
|
const text = item?.remark || '';
|
||||||
|
if (text.length > 4) {
|
||||||
|
return <Tooltip title={text}>{text.slice(0, 10)}...</Tooltip>;
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '已收金额',
|
||||||
|
dataIndex: ['bill_payment', 'amount'],
|
||||||
|
search: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '收款日期',
|
||||||
|
dataIndex: ['bill_payment', 'paid_time'],
|
||||||
|
render: (_, item: any) => {
|
||||||
|
return item?.bill_payment?.paid_time?.slice(0, 10) || '-';
|
||||||
|
},
|
||||||
|
search: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '收款人',
|
||||||
|
render: (_, record) => {
|
||||||
|
return `${record?.reconciliation_person || ''}-${
|
||||||
|
record?.reconciliation_person_phone || ''
|
||||||
|
}`;
|
||||||
|
},
|
||||||
|
search: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
MyColumns.Boolean({
|
||||||
|
title: '退款申请',
|
||||||
|
dataIndex: 'has_refunding',
|
||||||
|
}),
|
||||||
|
|
||||||
|
MyColumns.Option({
|
||||||
|
render: (_, item: any, _index, action) => (
|
||||||
|
<MyTableActions
|
||||||
|
actions={{
|
||||||
|
show: (
|
||||||
|
<BIllInfo
|
||||||
|
item={{ ...item, type: 'primary' }}
|
||||||
|
reload={action?.reload}
|
||||||
|
title="查看"
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
qrcode: (
|
||||||
|
<ShowQrCode key="ShowQrCode" item={item} title="收款码" />
|
||||||
|
),
|
||||||
|
pay: (
|
||||||
|
<PayCreate
|
||||||
|
item={{ ...item, size: 'small' }}
|
||||||
|
reload={action?.reload}
|
||||||
|
title={title}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
update: (
|
||||||
|
<BillUpdate
|
||||||
|
item={item}
|
||||||
|
reload={action?.reload}
|
||||||
|
title={title}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
refund: (
|
||||||
|
<BillRefund
|
||||||
|
item={{
|
||||||
|
...item,
|
||||||
|
type: item?.type,
|
||||||
|
approval_type: ApprovalTemplatesTypeEnum.Refund.value,
|
||||||
|
total_paid_amount: item.total_paid_amount,
|
||||||
|
}}
|
||||||
|
reload={action?.reload}
|
||||||
|
title={title}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
audit_payment: (
|
||||||
|
<AuditPayment item={item} reload={action?.reload} />
|
||||||
|
),
|
||||||
|
copy: (
|
||||||
|
<BillCopy
|
||||||
|
key="Copy"
|
||||||
|
item={{
|
||||||
|
...item,
|
||||||
|
}}
|
||||||
|
reload={action?.reload}
|
||||||
|
title="复制"
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
delete: (
|
||||||
|
<MyButtons.Delete
|
||||||
|
disabled={
|
||||||
|
item.status === BillsStatusEnum.Paid.value ||
|
||||||
|
item.status === BillsStatusEnum.ToBeConfirmed.value ||
|
||||||
|
item.status === BillsStatusEnum.UnderApproval.value
|
||||||
|
}
|
||||||
|
onConfirm={() =>
|
||||||
|
Apis.Bill.Bills.Delete({ id: item.id }).then(() =>
|
||||||
|
action?.reload(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</MyPageContainer>
|
||||||
|
);
|
||||||
|
}
|
||||||
161
src/pages/bills/temporary/modals/AuditPayment.tsx
Normal file
161
src/pages/bills/temporary/modals/AuditPayment.tsx
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
import {
|
||||||
|
MyBetaModalFormProps,
|
||||||
|
MyButtons,
|
||||||
|
MyFormItems,
|
||||||
|
MyModalFormProps,
|
||||||
|
renderTextHelper,
|
||||||
|
rulesHelper,
|
||||||
|
} from '@/common';
|
||||||
|
import { Apis } from '@/gen/Apis';
|
||||||
|
import { BillsStatusEnum, HouseOrdersPaymentMethodEnum } from '@/gen/Enums';
|
||||||
|
import { BetaSchemaForm } from '@ant-design/pro-components';
|
||||||
|
import { request } from '@umijs/max';
|
||||||
|
import { Image as AntImage, Descriptions, Form, message } from 'antd';
|
||||||
|
import * as React from 'react';
|
||||||
|
|
||||||
|
const AuditStatusEnum = {
|
||||||
|
Approved: { text: '通过', value: 'Approved' },
|
||||||
|
Rejected: { text: '驳回', value: 'Rejected' },
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function AuditPayment(
|
||||||
|
props: MyBetaModalFormProps,
|
||||||
|
): React.ReactElement {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<BetaSchemaForm<ApiTypes.Bill.Bills.AuditPayment>
|
||||||
|
{...MyModalFormProps.props}
|
||||||
|
title="审核线下收款"
|
||||||
|
trigger={
|
||||||
|
<MyButtons.Default
|
||||||
|
title="审核收款"
|
||||||
|
size="small"
|
||||||
|
disabled={props.item?.status !== BillsStatusEnum.ToBeConfirmed.value}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
width="600px"
|
||||||
|
form={form}
|
||||||
|
key={new Date().getTime()}
|
||||||
|
onOpenChange={(open: boolean): void => {
|
||||||
|
if (open) {
|
||||||
|
form.resetFields();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onFinish={async (values: any) => {
|
||||||
|
if (values.status === 'Approved' && values.serial_number) {
|
||||||
|
await request('company/bill/bills/update_serial_number', {
|
||||||
|
data: {
|
||||||
|
id: props.item?.id ?? 0,
|
||||||
|
serial_number: values.serial_number,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return Apis.Bill.Bills.AuditPayment({
|
||||||
|
...values,
|
||||||
|
id: props.item?.id ?? 0,
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
props.reload?.();
|
||||||
|
message.success('审核成功');
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.catch(() => false);
|
||||||
|
}}
|
||||||
|
columns={[
|
||||||
|
{
|
||||||
|
valueType: 'divider',
|
||||||
|
fieldProps: {
|
||||||
|
orientation: 'left',
|
||||||
|
children: '收款信息',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
colProps: { span: 24 },
|
||||||
|
renderFormItem: () => (
|
||||||
|
<Descriptions
|
||||||
|
column={2}
|
||||||
|
size="small"
|
||||||
|
bordered
|
||||||
|
style={{ marginBottom: '12px' }}
|
||||||
|
>
|
||||||
|
<Descriptions.Item label="账单ID">
|
||||||
|
{props.item?.id || '-'}
|
||||||
|
</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="关联项目">
|
||||||
|
{props.item?.asset_project?.name || '-'}
|
||||||
|
</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="收款金额">
|
||||||
|
¥ {props.item?.bill_payment?.amount || 0} 元
|
||||||
|
</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="收款方式">
|
||||||
|
{renderTextHelper.Tag({
|
||||||
|
Enums: HouseOrdersPaymentMethodEnum,
|
||||||
|
value: props.item?.bill_payment?.payment_method,
|
||||||
|
}) || '-'}
|
||||||
|
</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="收款日期">
|
||||||
|
{props.item?.bill_payment?.paid_time?.slice(0, 10) || '-'}
|
||||||
|
</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="备注">
|
||||||
|
{props.item?.bill_payment?.remark || '-'}
|
||||||
|
</Descriptions.Item>
|
||||||
|
{props.item?.bill_payment?.pay_certificate?.length > 0 && (
|
||||||
|
<Descriptions.Item label="收款凭证" span={2}>
|
||||||
|
<AntImage.PreviewGroup>
|
||||||
|
{props.item?.bill_payment?.pay_certificate?.map(
|
||||||
|
(img: any) => (
|
||||||
|
<AntImage
|
||||||
|
key={img.uid}
|
||||||
|
height={30}
|
||||||
|
src={img.url}
|
||||||
|
style={{ marginRight: 12 }}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
)}
|
||||||
|
</AntImage.PreviewGroup>
|
||||||
|
</Descriptions.Item>
|
||||||
|
)}
|
||||||
|
</Descriptions>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
MyFormItems.EnumRadio({
|
||||||
|
key: 'status',
|
||||||
|
title: '审核意见',
|
||||||
|
valueEnum: AuditStatusEnum,
|
||||||
|
colProps: { span: 24 },
|
||||||
|
formItemProps: { ...rulesHelper.text },
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
valueType: 'dependency',
|
||||||
|
name: ['status'],
|
||||||
|
columns: ({ status }) => {
|
||||||
|
if (status === 'Approved') {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
title: '流水号',
|
||||||
|
valueType: 'text',
|
||||||
|
key: 'serial_number',
|
||||||
|
formItemProps: { ...rulesHelper.text },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '审核备注',
|
||||||
|
valueType: 'textarea',
|
||||||
|
key: 'rejected_reason',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
title: '驳回理由',
|
||||||
|
valueType: 'textarea',
|
||||||
|
key: 'rejected_reason',
|
||||||
|
formItemProps: { ...rulesHelper.text },
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
114
src/pages/bills/temporary/modals/BIllInfo.tsx
Normal file
114
src/pages/bills/temporary/modals/BIllInfo.tsx
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
import { MyBetaModalFormProps, renderTextHelper } from '@/common';
|
||||||
|
import { MyModal } from '@/components/MyModal';
|
||||||
|
import { Apis } from '@/gen/Apis';
|
||||||
|
import {
|
||||||
|
BillPaymentsTypeEnum,
|
||||||
|
HouseOrdersPaymentMethodEnum,
|
||||||
|
} from '@/gen/Enums';
|
||||||
|
import { ProCard, ProDescriptions } from '@ant-design/pro-components';
|
||||||
|
import { Image as AntImage, Space, Spin } from 'antd';
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
|
export default function BillInfo(props: MyBetaModalFormProps) {
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [data, setData] = useState<any>({});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MyModal
|
||||||
|
title={props.title || '查看账单'}
|
||||||
|
type={props.item?.type || 'primary'}
|
||||||
|
width="600px"
|
||||||
|
onOpen={() => {
|
||||||
|
if (props?.item?.id) {
|
||||||
|
setLoading(true);
|
||||||
|
Apis.Bill.Bills.Show({ id: props.item.id })
|
||||||
|
.then((res) => {
|
||||||
|
setData(res?.data || {});
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
node={
|
||||||
|
<Space direction="vertical" style={{ width: '100%' }}>
|
||||||
|
<ProCard extra={props.extra}>
|
||||||
|
<Spin spinning={loading}>
|
||||||
|
<ProDescriptions column={2}>
|
||||||
|
{/* 项目相关信息 */}
|
||||||
|
<ProDescriptions.Item label="项目名称" span={2}>
|
||||||
|
{data?.asset_project?.name || ''}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
|
||||||
|
{/* 账单基本信息 */}
|
||||||
|
<ProDescriptions.Item label="账单月份">
|
||||||
|
{data?.year || ''}-{data?.month || ''}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="费用类型">
|
||||||
|
<renderTextHelper.Tag
|
||||||
|
Enums={BillPaymentsTypeEnum}
|
||||||
|
value={data?.type}
|
||||||
|
key="type"
|
||||||
|
/>
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="账单金额">
|
||||||
|
{data?.amount || 0} 元
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="应收金额">
|
||||||
|
{data?.mount || 0} 元
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="账单月份" span={2}>
|
||||||
|
{data?.year || ''}-{data?.month || ''}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
{/* 其他信息 */}
|
||||||
|
<ProDescriptions.Item label="收款账户" span={2}>
|
||||||
|
{data?.receipt_account?.company_name || ''} |{' '}
|
||||||
|
{data?.receipt_account?.company_bank || ''} |{' '}
|
||||||
|
{data?.receipt_account?.company_account || ''}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="账单备注" span={3}>
|
||||||
|
{data?.remark || ''}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
{/* 收款信息 */}
|
||||||
|
<ProDescriptions.Item label="收款金额">
|
||||||
|
¥ {data?.bill_payment?.amount || '-'} 元
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="收款方式">
|
||||||
|
{renderTextHelper.Tag({
|
||||||
|
Enums: HouseOrdersPaymentMethodEnum,
|
||||||
|
value: data?.bill_payment?.payment_method,
|
||||||
|
}) || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="收款日期">
|
||||||
|
{data?.bill_payment?.paid_time?.slice(0, 10) || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
|
||||||
|
<ProDescriptions.Item label="收款人">
|
||||||
|
{data?.reconciliation_person || '-'}-
|
||||||
|
{data?.reconciliation_person_phone || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="收款备注" span={3}>
|
||||||
|
{data?.bill_payment?.remark || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
{data?.bill_payment?.pay_certificate?.length > 0 && (
|
||||||
|
<ProDescriptions.Item label="收款凭证" span={2}>
|
||||||
|
<AntImage.PreviewGroup>
|
||||||
|
{data?.bill_payment?.pay_certificate?.map((img: any) => (
|
||||||
|
<AntImage
|
||||||
|
key={img.uid}
|
||||||
|
height={30}
|
||||||
|
src={img.url}
|
||||||
|
style={{ marginRight: 12 }}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</AntImage.PreviewGroup>
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
)}
|
||||||
|
</ProDescriptions>
|
||||||
|
</Spin>
|
||||||
|
</ProCard>
|
||||||
|
</Space>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
214
src/pages/bills/temporary/modals/BillCopy.tsx
Normal file
214
src/pages/bills/temporary/modals/BillCopy.tsx
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
import {
|
||||||
|
MyBetaModalFormProps,
|
||||||
|
MyButtons,
|
||||||
|
MyFormItems,
|
||||||
|
MyModalFormProps,
|
||||||
|
rulesHelper,
|
||||||
|
} from '@/common';
|
||||||
|
import { Selects } from '@/components/Select';
|
||||||
|
import { Apis } from '@/gen/Apis';
|
||||||
|
import { HouseBillsTypeEnum } from '@/gen/Enums';
|
||||||
|
import { BetaSchemaForm } from '@ant-design/pro-components';
|
||||||
|
import { Form, message } from 'antd';
|
||||||
|
|
||||||
|
export default function Copy(props: MyBetaModalFormProps) {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const isCarPortFee =
|
||||||
|
props.item?.type === 'CarPortFee' || props.item?.type === 'CarPortDeposit';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<BetaSchemaForm<ApiTypes.Bill.HouseBills.Store>
|
||||||
|
{...MyModalFormProps.props}
|
||||||
|
title={`账单复制`}
|
||||||
|
trigger={<MyButtons.Default title="复制" type="primary" size="small" />}
|
||||||
|
wrapperCol={{ span: 24 }}
|
||||||
|
width="800px"
|
||||||
|
key={new Date().getTime()}
|
||||||
|
form={form}
|
||||||
|
onOpenChange={(open: any) => {
|
||||||
|
if (open && props.item) {
|
||||||
|
const formValues = {
|
||||||
|
type: props.item?.type,
|
||||||
|
amount: props.item?.amount,
|
||||||
|
company_receipt_accounts_id:
|
||||||
|
props.item?.company_receipt_accounts_id,
|
||||||
|
remark: props.item?.remark,
|
||||||
|
};
|
||||||
|
form.setFieldsValue(formValues);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onFinish={async (values) => {
|
||||||
|
const isCarPortFee =
|
||||||
|
props.item?.type === 'CarPortFee' ||
|
||||||
|
props.item?.type === 'CarPortDeposit';
|
||||||
|
return Apis.Bill.HouseBills.Store({
|
||||||
|
...values,
|
||||||
|
type: props.item?.type,
|
||||||
|
asset_car_ports_id: isCarPortFee
|
||||||
|
? props.item?.asset_car_ports_id
|
||||||
|
: undefined,
|
||||||
|
asset_houses_id: !isCarPortFee
|
||||||
|
? props.item?.asset_houses_id
|
||||||
|
: undefined,
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
props.reload?.();
|
||||||
|
message.success('手动添加账单成功');
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.catch(() => false);
|
||||||
|
}}
|
||||||
|
columns={[
|
||||||
|
{
|
||||||
|
valueType: 'dependency',
|
||||||
|
name: ['type'],
|
||||||
|
columns: ({ type }) => {
|
||||||
|
const field =
|
||||||
|
type === 'CarPortFee' || type === 'CarPortDeposit'
|
||||||
|
? {
|
||||||
|
key: 'asset_car_port_full_name',
|
||||||
|
title: '车位信息',
|
||||||
|
colProps: { span: 18 },
|
||||||
|
fieldProps: {
|
||||||
|
disabled: true,
|
||||||
|
},
|
||||||
|
initialValue: props.item?.asset_car_port?.full_name,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
key: 'asset_house_full_name',
|
||||||
|
title: '房屋信息',
|
||||||
|
colProps: { span: 18 },
|
||||||
|
fieldProps: {
|
||||||
|
disabled: true,
|
||||||
|
},
|
||||||
|
initialValue: props.item?.asset_house?.full_name,
|
||||||
|
};
|
||||||
|
return [field];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MyFormItems.EnumSelect({
|
||||||
|
key: 'type',
|
||||||
|
title: '类型',
|
||||||
|
colProps: { span: 6 },
|
||||||
|
valueEnum: HouseBillsTypeEnum,
|
||||||
|
required: true,
|
||||||
|
fieldProps: {
|
||||||
|
disabled: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
key: 'amount',
|
||||||
|
title: '金额',
|
||||||
|
valueType: 'digit',
|
||||||
|
colProps: { span: 8 },
|
||||||
|
fieldProps: {
|
||||||
|
style: {
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
formItemProps: { ...rulesHelper.number },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'discount_amount',
|
||||||
|
title: '优惠金额',
|
||||||
|
valueType: 'digit',
|
||||||
|
fieldProps: {
|
||||||
|
style: {
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
colProps: { span: 8 },
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
key: 'late_fee',
|
||||||
|
title: '滞纳金',
|
||||||
|
valueType: 'digit',
|
||||||
|
fieldProps: {
|
||||||
|
style: {
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
colProps: { span: 8 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'month',
|
||||||
|
title: '账单月份',
|
||||||
|
valueType: 'date',
|
||||||
|
colProps: { span: 8 },
|
||||||
|
fieldProps: {
|
||||||
|
picker: 'month',
|
||||||
|
format: 'YYYY-MM',
|
||||||
|
valueFormat: 'YYYY-MM',
|
||||||
|
style: {
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
onChange: (e: any, dateString: string) => {
|
||||||
|
form.setFieldsValue({
|
||||||
|
start_date: rulesHelper.getMonthStartDate(dateString),
|
||||||
|
end_date: rulesHelper.getMonthEndDate(dateString),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
formItemProps: { ...rulesHelper.text },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'start_date',
|
||||||
|
title: '计费开始日期',
|
||||||
|
valueType: 'date',
|
||||||
|
colProps: { span: 8 },
|
||||||
|
fieldProps: {
|
||||||
|
style: {
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
formItemProps: { ...rulesHelper.text },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'end_date',
|
||||||
|
title: '计费结束日期',
|
||||||
|
valueType: 'date',
|
||||||
|
colProps: { span: 8 },
|
||||||
|
fieldProps: {
|
||||||
|
style: {
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
formItemProps: { ...rulesHelper.text },
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
valueType: 'dependency',
|
||||||
|
name: ['asset_projects_id'],
|
||||||
|
columns: ({ asset_projects_id }) => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
valueType: 'group',
|
||||||
|
columns: [
|
||||||
|
Selects?.ProjectAccounts({
|
||||||
|
key: 'company_receipt_accounts_id',
|
||||||
|
title: '选择收款账户',
|
||||||
|
params: {
|
||||||
|
projects_id: asset_projects_id,
|
||||||
|
},
|
||||||
|
colProps: { span: 24 },
|
||||||
|
formItemProps: { ...rulesHelper.number },
|
||||||
|
fieldProps: {
|
||||||
|
showSearch: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '备注',
|
||||||
|
key: 'remark',
|
||||||
|
valueType: 'textarea',
|
||||||
|
colProps: { span: 24 },
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
124
src/pages/bills/temporary/modals/BillCreate.tsx
Normal file
124
src/pages/bills/temporary/modals/BillCreate.tsx
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
import {
|
||||||
|
MyBetaModalFormProps,
|
||||||
|
MyButtons,
|
||||||
|
MyFormItems,
|
||||||
|
MyModalFormProps,
|
||||||
|
rulesHelper,
|
||||||
|
} from '@/common';
|
||||||
|
import { Selects } from '@/components/Select';
|
||||||
|
import { Apis } from '@/gen/Apis';
|
||||||
|
import { BillPaymentsTypeEnum, BillsFlowTypeEnum } from '@/gen/Enums';
|
||||||
|
import { BetaSchemaForm } from '@ant-design/pro-components';
|
||||||
|
import { Form, message } from 'antd';
|
||||||
|
|
||||||
|
export default function Create(props: MyBetaModalFormProps) {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
return (
|
||||||
|
<BetaSchemaForm<ApiTypes.Bill.Bills.Store>
|
||||||
|
{...MyModalFormProps.props}
|
||||||
|
title={`手动添加账单`}
|
||||||
|
layout="horizontal"
|
||||||
|
labelCol={{ span: 4 }}
|
||||||
|
wrapperCol={{ span: 20 }}
|
||||||
|
// wrapperCol={{ span: 24 }}
|
||||||
|
width="600px"
|
||||||
|
trigger={<MyButtons.Create title={`手动添加账单`} />}
|
||||||
|
key={new Date().getTime()}
|
||||||
|
form={form}
|
||||||
|
onOpenChange={(open: any) => {
|
||||||
|
if (open) {
|
||||||
|
form.resetFields(); // 清空表单数据
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onFinish={async (values: any) =>
|
||||||
|
Apis.Bill.Bills.Store({
|
||||||
|
...values,
|
||||||
|
flow_type: BillsFlowTypeEnum.Income.value,
|
||||||
|
year: parseInt(values.year_month.split('-')[0]),
|
||||||
|
month: parseInt(values.year_month.split('-')[1]),
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
props.reload?.();
|
||||||
|
message.success('手动添加账单成功');
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.catch(() => false)
|
||||||
|
}
|
||||||
|
columns={[
|
||||||
|
Selects?.AssetProjects({
|
||||||
|
title: '选择项目',
|
||||||
|
key: 'asset_projects_id',
|
||||||
|
colProps: { span: 24 },
|
||||||
|
formItemProps: { ...rulesHelper.text },
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
valueType: 'dependency',
|
||||||
|
name: ['asset_projects_id'],
|
||||||
|
columns: ({ asset_projects_id }) => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
valueType: 'group',
|
||||||
|
columns: [
|
||||||
|
Selects?.ProjectAccounts({
|
||||||
|
key: 'company_receipt_accounts_id',
|
||||||
|
title: '收款账户',
|
||||||
|
params: {
|
||||||
|
projects_id: asset_projects_id,
|
||||||
|
},
|
||||||
|
colProps: { span: 24 },
|
||||||
|
formItemProps: { ...rulesHelper.number },
|
||||||
|
fieldProps: {
|
||||||
|
showSearch: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
MyFormItems.EnumRadio({
|
||||||
|
key: 'type',
|
||||||
|
title: '费用类型',
|
||||||
|
colProps: { span: 24 },
|
||||||
|
valueEnum: BillPaymentsTypeEnum,
|
||||||
|
required: true,
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
key: 'amount',
|
||||||
|
title: '账单金额',
|
||||||
|
valueType: 'digit',
|
||||||
|
colProps: { span: 24 },
|
||||||
|
fieldProps: {
|
||||||
|
addonAfter: '元',
|
||||||
|
style: {
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
formItemProps: { ...rulesHelper.number },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'year_month',
|
||||||
|
title: '账单月份',
|
||||||
|
valueType: 'date',
|
||||||
|
colProps: { span: 24 },
|
||||||
|
fieldProps: {
|
||||||
|
picker: 'month',
|
||||||
|
format: 'YYYY-MM',
|
||||||
|
valueFormat: 'YYYY-MM',
|
||||||
|
style: {
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
formItemProps: { ...rulesHelper.text },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '备注',
|
||||||
|
key: 'remark',
|
||||||
|
valueType: 'textarea',
|
||||||
|
colProps: { span: 24 },
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
253
src/pages/bills/temporary/modals/BillRefund.tsx
Normal file
253
src/pages/bills/temporary/modals/BillRefund.tsx
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
import {
|
||||||
|
MyBetaModalFormProps,
|
||||||
|
MyButtons,
|
||||||
|
MyFormItems,
|
||||||
|
MyModalFormProps,
|
||||||
|
rulesHelper,
|
||||||
|
} from '@/common';
|
||||||
|
import { Selects } from '@/components/Select';
|
||||||
|
import { Apis } from '@/gen/Apis';
|
||||||
|
import { ApprovalTemplateNodesNodeTypeEnum } from '@/gen/Enums';
|
||||||
|
import { BetaSchemaForm } from '@ant-design/pro-components';
|
||||||
|
import { Form, message } from 'antd';
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
|
export default function Update(props: MyBetaModalFormProps) {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const [ApprovalTemplates, setApprovalTemplates] = useState<any>([]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<BetaSchemaForm<ApiTypes.Bill.BillRefunds.Store>
|
||||||
|
{...MyModalFormProps.props}
|
||||||
|
title={`退款申请单`}
|
||||||
|
trigger={
|
||||||
|
<MyButtons.Default
|
||||||
|
title="申请退款"
|
||||||
|
// disabled={props?.item?.bill_status !== 'Paid'}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
layout="horizontal"
|
||||||
|
labelCol={{ span: 4 }}
|
||||||
|
wrapperCol={{ span: 20 }}
|
||||||
|
labelAlign="left"
|
||||||
|
width="600px"
|
||||||
|
form={form}
|
||||||
|
key={new Date().getDate()}
|
||||||
|
onOpenChange={(open: any) => {
|
||||||
|
if (open && props.item) {
|
||||||
|
form.resetFields();
|
||||||
|
form.setFieldsValue({
|
||||||
|
...props.item,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onFinish={async (values: any) =>
|
||||||
|
Apis.Refund.Refunds.Store({
|
||||||
|
...values,
|
||||||
|
business_id: props.item?.id ?? '',
|
||||||
|
type: 'Bill',
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
props.reload?.();
|
||||||
|
message.success(props.title + '成功');
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.catch(() => false)
|
||||||
|
}
|
||||||
|
columns={[
|
||||||
|
Selects?.CompanyAccounts({
|
||||||
|
key: 'company_receipt_accounts_id',
|
||||||
|
title: '付款账户',
|
||||||
|
colProps: { span: 24 },
|
||||||
|
formItemProps: { ...rulesHelper.number },
|
||||||
|
fieldProps: {
|
||||||
|
showSearch: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
key: 'refund_amount',
|
||||||
|
title: '退款金额',
|
||||||
|
valueType: 'digit',
|
||||||
|
colProps: { span: 24 },
|
||||||
|
fieldProps: {
|
||||||
|
style: {
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
addonAfter: '元',
|
||||||
|
max: props.item?.total_paid_amount,
|
||||||
|
placeholder: `请输入退款金额(最大${props.item?.total_paid_amount}元)`,
|
||||||
|
},
|
||||||
|
formItemProps: { ...rulesHelper.number },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'payee_name',
|
||||||
|
title: '收款人',
|
||||||
|
colProps: { span: 24 },
|
||||||
|
formItemProps: { ...rulesHelper.text },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'payee_bank',
|
||||||
|
title: '收款银行',
|
||||||
|
colProps: { span: 24 },
|
||||||
|
formItemProps: { ...rulesHelper.text },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'payee_account',
|
||||||
|
title: '收款账号',
|
||||||
|
colProps: { span: 24 },
|
||||||
|
formItemProps: { ...rulesHelper.text },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '退款原因',
|
||||||
|
key: 'remark',
|
||||||
|
valueType: 'textarea',
|
||||||
|
colProps: { span: 24 },
|
||||||
|
formItemProps: { ...rulesHelper.text },
|
||||||
|
},
|
||||||
|
Selects?.ApprovalTemplates({
|
||||||
|
key: 'approval_templates_id',
|
||||||
|
title: '审批模版',
|
||||||
|
params: { type: props.item?.approval_type || '', is_enabled: '1' },
|
||||||
|
colProps: { span: 24 },
|
||||||
|
formItemProps: { ...rulesHelper.number },
|
||||||
|
fieldProps: {
|
||||||
|
onChange: (e: any) => {
|
||||||
|
// 确保e是有效值,并且使用正确的value字段
|
||||||
|
if (e) {
|
||||||
|
const templateId = typeof e === 'object' ? e.value : e;
|
||||||
|
Apis.Approval.ApprovalTemplates.Show({
|
||||||
|
id: templateId,
|
||||||
|
}).then((res) => {
|
||||||
|
setApprovalTemplates(res?.data?.approval_template_nodes);
|
||||||
|
form.setFieldsValue({
|
||||||
|
approval_templates_id: templateId,
|
||||||
|
node_approvers: res?.data?.approval_template_nodes?.map(
|
||||||
|
(item: any) => ({
|
||||||
|
...item,
|
||||||
|
members: item?.approval_template_node_members?.map(
|
||||||
|
(member: any) => member?.company_employees_id,
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 不返回任何值,防止默认行为
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
valueType: 'dependency',
|
||||||
|
name: ['approval_templates_id'],
|
||||||
|
columns: ({ approval_templates_id }) => {
|
||||||
|
return approval_templates_id
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
valueType: 'formList',
|
||||||
|
dataIndex: 'node_approvers',
|
||||||
|
// title: '审批节点',
|
||||||
|
fieldProps: {
|
||||||
|
copyIconProps: false,
|
||||||
|
deleteIconProps: false,
|
||||||
|
},
|
||||||
|
formItemProps: {
|
||||||
|
...rulesHelper.array,
|
||||||
|
wrapperCol: { span: 24 },
|
||||||
|
},
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
valueType: 'group',
|
||||||
|
colProps: { span: 24 },
|
||||||
|
columns: [
|
||||||
|
MyFormItems.EnumSelect({
|
||||||
|
key: 'node_type',
|
||||||
|
// title: `类型`,
|
||||||
|
valueEnum: ApprovalTemplateNodesNodeTypeEnum,
|
||||||
|
colProps: { span: 5 },
|
||||||
|
formItemProps: {
|
||||||
|
...rulesHelper.text,
|
||||||
|
},
|
||||||
|
fieldProps: {
|
||||||
|
disabled: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
// title: '节点名称',
|
||||||
|
key: 'name',
|
||||||
|
colProps: { span: 6 },
|
||||||
|
formItemProps: {
|
||||||
|
...rulesHelper.text,
|
||||||
|
},
|
||||||
|
fieldProps: {
|
||||||
|
disabled: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
valueType: 'dependency',
|
||||||
|
name: ['node_type'],
|
||||||
|
columns: ({}) => {
|
||||||
|
return [
|
||||||
|
Selects.Employees({
|
||||||
|
key: 'members',
|
||||||
|
title: ``,
|
||||||
|
colProps: { span: 13 },
|
||||||
|
formItemProps: {
|
||||||
|
...rulesHelper.array,
|
||||||
|
},
|
||||||
|
fieldProps: {
|
||||||
|
mode: 'multiple',
|
||||||
|
showSearch: true,
|
||||||
|
// maxCount:
|
||||||
|
// node_type ===
|
||||||
|
// ApprovalTemplateNodesNodeTypeEnum.Approver
|
||||||
|
// .value
|
||||||
|
// ? 1
|
||||||
|
// : 9,
|
||||||
|
maxTagTextLength: 3,
|
||||||
|
labelRender: (res: any) => {
|
||||||
|
console.log(res, '222');
|
||||||
|
if (res?.label) {
|
||||||
|
return res?.label;
|
||||||
|
} else {
|
||||||
|
return ApprovalTemplates?.map(
|
||||||
|
(item: any) => {
|
||||||
|
if (
|
||||||
|
item
|
||||||
|
?.approval_template_node_members
|
||||||
|
?.length
|
||||||
|
) {
|
||||||
|
return item?.approval_template_node_members?.map(
|
||||||
|
(i: any) => {
|
||||||
|
if (
|
||||||
|
i?.company_employees_id ===
|
||||||
|
res?.value
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
i?.company_employee
|
||||||
|
?.name || ''
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: [];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
372
src/pages/bills/temporary/modals/BillUpdate.tsx
Normal file
372
src/pages/bills/temporary/modals/BillUpdate.tsx
Normal file
@ -0,0 +1,372 @@
|
|||||||
|
import {
|
||||||
|
MyBetaModalFormProps,
|
||||||
|
MyButtons,
|
||||||
|
MyFormItems,
|
||||||
|
MyModalFormProps,
|
||||||
|
rulesHelper,
|
||||||
|
} from '@/common';
|
||||||
|
import { Selects } from '@/components/Select';
|
||||||
|
import { Apis } from '@/gen/Apis';
|
||||||
|
import {
|
||||||
|
ApprovalTemplateNodesNodeTypeEnum,
|
||||||
|
ApprovalTemplatesTypeEnum,
|
||||||
|
BillPaymentsTypeEnum,
|
||||||
|
BillsFlowTypeEnum,
|
||||||
|
BillsStatusEnum,
|
||||||
|
} from '@/gen/Enums';
|
||||||
|
import { BetaSchemaForm } from '@ant-design/pro-components';
|
||||||
|
import { Button, Form, message } from 'antd';
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
|
export default function Update(props: MyBetaModalFormProps) {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const [ApprovalTemplates, setApprovalTemplates] = useState<any>([]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<BetaSchemaForm<ApiTypes.Bill.Bills.Update>
|
||||||
|
{...MyModalFormProps.props}
|
||||||
|
title={`${props.title}编辑`}
|
||||||
|
trigger={
|
||||||
|
<MyButtons.Default
|
||||||
|
title="编辑"
|
||||||
|
type="primary"
|
||||||
|
size="small"
|
||||||
|
disabled={
|
||||||
|
props?.item?.status === BillsStatusEnum.Paid.value ||
|
||||||
|
props?.item?.status === BillsStatusEnum.Cancelled.value ||
|
||||||
|
props?.item?.status === BillsStatusEnum.UnderApproval.value ||
|
||||||
|
props?.item?.status === BillsStatusEnum.ToBeConfirmed.value
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
layout="horizontal"
|
||||||
|
labelCol={{ span: 4 }}
|
||||||
|
wrapperCol={{ span: 20 }}
|
||||||
|
width="800px"
|
||||||
|
key={props.item?.id}
|
||||||
|
form={form}
|
||||||
|
onOpenChange={(open: any) => {
|
||||||
|
if (open && props.item) {
|
||||||
|
const formValues = {
|
||||||
|
...props.item,
|
||||||
|
company_receipt_accounts_id: props.item?.receipt_account?.id || [],
|
||||||
|
year_month:
|
||||||
|
props.item.year && props.item.month
|
||||||
|
? `${props.item.year}-${String(props.item.month).padStart(
|
||||||
|
2,
|
||||||
|
'0',
|
||||||
|
)}`
|
||||||
|
: props.item.month,
|
||||||
|
};
|
||||||
|
form.setFieldsValue(formValues);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onFinish={async (values: any) => {
|
||||||
|
const { node_approvers } = values;
|
||||||
|
|
||||||
|
if (ApprovalTemplates?.length > 0 && node_approvers?.length > 0) {
|
||||||
|
// 遍历模板节点,通过名称找到对应的提交节点进行校验
|
||||||
|
for (const templateNode of ApprovalTemplates) {
|
||||||
|
// 通过名称找到对应的提交节点
|
||||||
|
const submittedNode = node_approvers.find(
|
||||||
|
(node: any) => node?.name === templateNode?.name,
|
||||||
|
);
|
||||||
|
|
||||||
|
// 如果模板节点在提交数据中不存在,说明被删除了,报错
|
||||||
|
if (!submittedNode) {
|
||||||
|
message.error(`节点"${templateNode?.name}"不能删除`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 校验审批人
|
||||||
|
if (
|
||||||
|
templateNode?.node_type ===
|
||||||
|
ApprovalTemplateNodesNodeTypeEnum.Approver.value
|
||||||
|
) {
|
||||||
|
const originalMembers =
|
||||||
|
templateNode?.approval_template_node_members?.map(
|
||||||
|
(member: any) => member?.company_employees_id,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (originalMembers?.length > 0) {
|
||||||
|
const submittedMembers = submittedNode?.members || [];
|
||||||
|
|
||||||
|
const isMatch =
|
||||||
|
originalMembers.length === submittedMembers.length &&
|
||||||
|
originalMembers.every((memberId: number) =>
|
||||||
|
submittedMembers.includes(memberId),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!isMatch) {
|
||||||
|
message.error(
|
||||||
|
`节点"${templateNode?.name}"的审批人必须与审批模板设置保持一致`,
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Apis.Bill.Bills.Update({
|
||||||
|
...values,
|
||||||
|
id: props.item?.id ?? 0,
|
||||||
|
year: parseInt(values.year_month.split('-')[0]),
|
||||||
|
month: parseInt(values.year_month.split('-')[1]),
|
||||||
|
flow_type: BillsFlowTypeEnum.Income.value,
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
props.reload?.();
|
||||||
|
message.success(props.title + '成功');
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.catch(() => false);
|
||||||
|
}}
|
||||||
|
columns={[
|
||||||
|
{
|
||||||
|
valueType: 'dependency',
|
||||||
|
name: ['asset_projects_id'],
|
||||||
|
columns: ({ asset_projects_id }) => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
valueType: 'group',
|
||||||
|
columns: [
|
||||||
|
Selects?.ProjectAccounts({
|
||||||
|
key: 'company_receipt_accounts_id',
|
||||||
|
title: '选择收款账户',
|
||||||
|
params: {
|
||||||
|
projects_id: asset_projects_id,
|
||||||
|
},
|
||||||
|
colProps: { span: 24 },
|
||||||
|
formItemProps: { ...rulesHelper.number },
|
||||||
|
fieldProps: {
|
||||||
|
showSearch: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MyFormItems.EnumRadio({
|
||||||
|
key: 'type',
|
||||||
|
title: '类型',
|
||||||
|
colProps: { span: 24 },
|
||||||
|
valueEnum: BillPaymentsTypeEnum,
|
||||||
|
required: true,
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
key: 'amount',
|
||||||
|
title: '金额',
|
||||||
|
valueType: 'digit',
|
||||||
|
colProps: { span: 24 },
|
||||||
|
fieldProps: {
|
||||||
|
style: {
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
formItemProps: { ...rulesHelper.number },
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
key: 'year_month',
|
||||||
|
title: '账单月份',
|
||||||
|
valueType: 'date',
|
||||||
|
colProps: { span: 24 },
|
||||||
|
fieldProps: {
|
||||||
|
picker: 'month',
|
||||||
|
format: 'YYYY-MM',
|
||||||
|
valueFormat: 'YYYY-MM',
|
||||||
|
style: {
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
formItemProps: { ...rulesHelper.text },
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
title: '备注',
|
||||||
|
key: 'remark',
|
||||||
|
valueType: 'textarea',
|
||||||
|
colProps: { span: 24 },
|
||||||
|
},
|
||||||
|
Selects?.ApprovalTemplates({
|
||||||
|
key: 'approval_templates_id',
|
||||||
|
title: '审批模版',
|
||||||
|
params: {
|
||||||
|
type: ApprovalTemplatesTypeEnum.BillUpdate.value,
|
||||||
|
is_enabled: '1',
|
||||||
|
},
|
||||||
|
colProps: { span: 24 },
|
||||||
|
formItemProps: { ...rulesHelper.number },
|
||||||
|
fieldProps: {
|
||||||
|
onChange: (e: any) => {
|
||||||
|
if (e) {
|
||||||
|
const templateId = typeof e === 'object' ? e.value : e;
|
||||||
|
Apis.Approval.ApprovalTemplates.Show({
|
||||||
|
id: templateId,
|
||||||
|
}).then((res) => {
|
||||||
|
setApprovalTemplates(res?.data?.approval_template_nodes);
|
||||||
|
form.setFieldsValue({
|
||||||
|
approval_templates_id: templateId,
|
||||||
|
node_approvers: res?.data?.approval_template_nodes?.map(
|
||||||
|
(item: any) => ({
|
||||||
|
...item,
|
||||||
|
members: item?.approval_template_node_members?.map(
|
||||||
|
(member: any) => member?.company_employees_id,
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
valueType: 'dependency',
|
||||||
|
name: ['approval_templates_id'],
|
||||||
|
columns: ({ approval_templates_id }) => {
|
||||||
|
return approval_templates_id
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
valueType: 'formList',
|
||||||
|
dataIndex: 'node_approvers',
|
||||||
|
fieldProps: {
|
||||||
|
creatorButtonProps: false,
|
||||||
|
actionRender: (field: any, action: any) => [
|
||||||
|
<Button
|
||||||
|
key="add"
|
||||||
|
type="link"
|
||||||
|
size="small"
|
||||||
|
onClick={() => {
|
||||||
|
const currentNodeType = form.getFieldValue([
|
||||||
|
'node_approvers',
|
||||||
|
field.name,
|
||||||
|
'node_type',
|
||||||
|
]);
|
||||||
|
if (
|
||||||
|
currentNodeType ===
|
||||||
|
ApprovalTemplateNodesNodeTypeEnum.CC.value
|
||||||
|
) {
|
||||||
|
message.warning('抄送节点不允许添加');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
action.add(
|
||||||
|
{
|
||||||
|
node_type:
|
||||||
|
ApprovalTemplateNodesNodeTypeEnum.Approver
|
||||||
|
.value,
|
||||||
|
},
|
||||||
|
field.name + 1,
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
添加
|
||||||
|
</Button>,
|
||||||
|
<Button
|
||||||
|
key="delete"
|
||||||
|
type="link"
|
||||||
|
size="small"
|
||||||
|
danger
|
||||||
|
onClick={() => {
|
||||||
|
action.remove(field.name);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</Button>,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
formItemProps: {
|
||||||
|
...rulesHelper.array,
|
||||||
|
wrapperCol: { span: 24 },
|
||||||
|
},
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
valueType: 'group',
|
||||||
|
colProps: { span: 24 },
|
||||||
|
columns: [
|
||||||
|
MyFormItems.EnumSelect({
|
||||||
|
key: 'node_type',
|
||||||
|
valueEnum: ApprovalTemplateNodesNodeTypeEnum,
|
||||||
|
colProps: { span: 5 },
|
||||||
|
formItemProps: {
|
||||||
|
...rulesHelper.text,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
key: 'name',
|
||||||
|
colProps: { span: 6 },
|
||||||
|
formItemProps: {
|
||||||
|
...rulesHelper.text,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
valueType: 'dependency',
|
||||||
|
name: ['node_type'],
|
||||||
|
columns: ({ node_type }) => {
|
||||||
|
return [
|
||||||
|
Selects.Employees({
|
||||||
|
key: 'members',
|
||||||
|
title: ``,
|
||||||
|
colProps: { span: 13 },
|
||||||
|
formItemProps: {
|
||||||
|
...rulesHelper.array,
|
||||||
|
},
|
||||||
|
fieldProps: {
|
||||||
|
mode: 'multiple',
|
||||||
|
showSearch: true,
|
||||||
|
maxCount:
|
||||||
|
node_type ===
|
||||||
|
ApprovalTemplateNodesNodeTypeEnum.Approver
|
||||||
|
.value
|
||||||
|
? 1
|
||||||
|
: 9,
|
||||||
|
maxTagTextLength: 20,
|
||||||
|
labelRender: (res: any) => {
|
||||||
|
if (res?.label) {
|
||||||
|
return res?.label;
|
||||||
|
} else {
|
||||||
|
return ApprovalTemplates?.map(
|
||||||
|
(item: any) => {
|
||||||
|
if (
|
||||||
|
item?.node_type === node_type &&
|
||||||
|
item
|
||||||
|
?.approval_template_node_members
|
||||||
|
?.length
|
||||||
|
) {
|
||||||
|
return item?.approval_template_node_members?.map(
|
||||||
|
(i: any) => {
|
||||||
|
if (
|
||||||
|
i?.company_employees_id ===
|
||||||
|
res?.value
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
i?.company_employee
|
||||||
|
?.name || ''
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: [];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
153
src/pages/bills/temporary/modals/Pay.tsx
Normal file
153
src/pages/bills/temporary/modals/Pay.tsx
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
import {
|
||||||
|
MyBetaModalFormProps,
|
||||||
|
MyButtons,
|
||||||
|
MyFormItems,
|
||||||
|
MyModalFormProps,
|
||||||
|
rulesHelper,
|
||||||
|
} from '@/common';
|
||||||
|
import { Apis } from '@/gen/Apis';
|
||||||
|
import { BillsStatusEnum, HouseOrdersPaymentMethodEnum } from '@/gen/Enums';
|
||||||
|
import { BetaSchemaForm } from '@ant-design/pro-components';
|
||||||
|
import { Form, message } from 'antd';
|
||||||
|
import * as React from 'react';
|
||||||
|
|
||||||
|
export interface PayCreateProps extends MyBetaModalFormProps {
|
||||||
|
// 单个账单收款,不需要选择多个账单
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function PayCreate(props: PayCreateProps): React.ReactElement {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<BetaSchemaForm<ApiTypes.Bill.Bills.OfflinePayment>
|
||||||
|
{...MyModalFormProps.props}
|
||||||
|
title="录入收款信息"
|
||||||
|
trigger={
|
||||||
|
<MyButtons.Default
|
||||||
|
type="primary"
|
||||||
|
size="small"
|
||||||
|
title="线下收款"
|
||||||
|
disabled={
|
||||||
|
props?.item?.status === BillsStatusEnum.Paid.value ||
|
||||||
|
props?.item?.status === BillsStatusEnum.Cancelled.value ||
|
||||||
|
props?.item?.status === BillsStatusEnum.UnderApproval.value ||
|
||||||
|
props?.item?.status === BillsStatusEnum.ToBeConfirmed.value
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
labelAlign="left"
|
||||||
|
width="800px"
|
||||||
|
form={form}
|
||||||
|
key={new Date().getTime()}
|
||||||
|
onOpenChange={(open: boolean): void => {
|
||||||
|
if (open) {
|
||||||
|
form.resetFields(); // 清空表单数据
|
||||||
|
form.setFieldsValue({
|
||||||
|
item: props.item,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onFinish={async (values: any) =>
|
||||||
|
Apis.Bill.Bills.OfflinePayment({
|
||||||
|
...values,
|
||||||
|
total_paid_amount: parseFloat(props?.item?.payable_amount || 0),
|
||||||
|
id: props.item?.id || '',
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
props.reload?.();
|
||||||
|
message.success('手动添加账单成功');
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.catch(() => false)
|
||||||
|
}
|
||||||
|
columns={[
|
||||||
|
{
|
||||||
|
valueType: 'divider',
|
||||||
|
fieldProps: {
|
||||||
|
orientation: 'left',
|
||||||
|
children: '账单信息',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
colProps: { span: 24 },
|
||||||
|
renderFormItem: () => (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
padding: '12px',
|
||||||
|
backgroundColor: '#f5f5f5',
|
||||||
|
borderRadius: '6px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<p>账单ID:{props.item?.id || '-'}</p>
|
||||||
|
<p>
|
||||||
|
关联项目:
|
||||||
|
{props.item?.asset_project?.name || '-'}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
收款金额:¥ {parseFloat(props?.item?.payable_amount || 0)} 元
|
||||||
|
</p>
|
||||||
|
<p>账单备注:{props.item?.remark || '-'}</p>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
MyFormItems.EnumRadio({
|
||||||
|
key: 'payment_method',
|
||||||
|
title: '收款方式',
|
||||||
|
colProps: { span: 12 },
|
||||||
|
valueEnum: () => {
|
||||||
|
const obj: Record<string, any> = JSON.parse(
|
||||||
|
JSON.stringify(HouseOrdersPaymentMethodEnum),
|
||||||
|
);
|
||||||
|
delete obj.WeChat;
|
||||||
|
delete obj.Alipay;
|
||||||
|
delete obj.TongLian;
|
||||||
|
delete obj.Prepayment;
|
||||||
|
delete obj.CCB;
|
||||||
|
return obj;
|
||||||
|
},
|
||||||
|
required: true,
|
||||||
|
}),
|
||||||
|
// {
|
||||||
|
// key: 'total_paid_amount',
|
||||||
|
// title: '收款金额',
|
||||||
|
// valueType: 'digit',
|
||||||
|
// colProps: { span: 6 },
|
||||||
|
// fieldProps: {
|
||||||
|
// style: { width: '100%' },
|
||||||
|
// addonAfter: '元',
|
||||||
|
// disabled: true,
|
||||||
|
// },
|
||||||
|
// formItemProps: { ...rulesHelper.number },
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
key: 'paid_time',
|
||||||
|
title: '收款日期',
|
||||||
|
valueType: 'date',
|
||||||
|
formItemProps: { ...rulesHelper.text },
|
||||||
|
colProps: { span: 8 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '收款备注',
|
||||||
|
dataIndex: 'remark',
|
||||||
|
colProps: { span: 24 },
|
||||||
|
},
|
||||||
|
MyFormItems.UploadImages({
|
||||||
|
key: 'pay_certificate',
|
||||||
|
title: '收款凭证图片',
|
||||||
|
uploadType: 'file',
|
||||||
|
colProps: { span: 24 },
|
||||||
|
max: 10,
|
||||||
|
}),
|
||||||
|
|
||||||
|
{
|
||||||
|
colProps: { span: 24 },
|
||||||
|
renderFormItem: () => (
|
||||||
|
<span style={{ color: '#5b5b5bff' }}>
|
||||||
|
提示:确认后,需财务审核。
|
||||||
|
</span>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
174
src/pages/bills/temporary/modals/QrCode.tsx
Normal file
174
src/pages/bills/temporary/modals/QrCode.tsx
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
import {
|
||||||
|
MyBetaModalFormProps,
|
||||||
|
MyButtons,
|
||||||
|
MyModalFormProps,
|
||||||
|
renderTextHelper,
|
||||||
|
} from '@/common';
|
||||||
|
import { Apis } from '@/gen/Apis';
|
||||||
|
import { BillPaymentsTypeEnum, BillsStatusEnum } from '@/gen/Enums';
|
||||||
|
import { BetaSchemaForm, ProDescriptions } from '@ant-design/pro-components';
|
||||||
|
import { Form, QRCode, Tabs } from 'antd';
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
|
export default function ShowQrCode(props: MyBetaModalFormProps) {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const [activeTab, setActiveTab] = useState<string>('wechat');
|
||||||
|
const [wechatQrCode, setWechatQrCode] = useState<string>('');
|
||||||
|
const [alipayQrCode, setAlipayQrCode] = useState<string>('');
|
||||||
|
|
||||||
|
const fetchQrCode = (type: 'wechat' | 'alipay') => {
|
||||||
|
if (!props?.item?.id) return;
|
||||||
|
const params = {
|
||||||
|
id: props.item.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (type === 'wechat') {
|
||||||
|
Apis.Bill.Bills.GetPayCode(params).then((res: any) => {
|
||||||
|
setWechatQrCode(res?.data?.qr_code || '');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Apis.Bill.Bills.AlipayQrCode(params).then((res: any) => {
|
||||||
|
setAlipayQrCode(res?.data?.payinfo || '');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<BetaSchemaForm<ApiTypes.Bill.Bills.GetPayCode>
|
||||||
|
{...MyModalFormProps.props}
|
||||||
|
title={props.title}
|
||||||
|
width="500px"
|
||||||
|
wrapperCol={{ span: 24 }}
|
||||||
|
trigger={
|
||||||
|
<MyButtons.Default
|
||||||
|
type="primary"
|
||||||
|
size="small"
|
||||||
|
title={props.title}
|
||||||
|
disabled={
|
||||||
|
props?.item?.status === BillsStatusEnum.Paid.value ||
|
||||||
|
props?.item?.status === BillsStatusEnum.Cancelled.value ||
|
||||||
|
props?.item?.status === BillsStatusEnum.UnderApproval.value ||
|
||||||
|
props?.item?.status === BillsStatusEnum.ToBeConfirmed.value
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
form={form}
|
||||||
|
submitter={false}
|
||||||
|
onOpenChange={(open: any) => {
|
||||||
|
if (open) {
|
||||||
|
setWechatQrCode('');
|
||||||
|
setAlipayQrCode('');
|
||||||
|
setActiveTab('wechat');
|
||||||
|
fetchQrCode('wechat');
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
columns={[
|
||||||
|
{
|
||||||
|
title: '',
|
||||||
|
colProps: { span: 24 },
|
||||||
|
key: 'qrcode',
|
||||||
|
renderFormItem() {
|
||||||
|
return (
|
||||||
|
<div style={{ textAlign: 'left' }}>
|
||||||
|
<ProDescriptions
|
||||||
|
column={2}
|
||||||
|
size="small"
|
||||||
|
bordered
|
||||||
|
style={{ marginBottom: '16px' }}
|
||||||
|
>
|
||||||
|
<ProDescriptions.Item label="项目" span={2}>
|
||||||
|
{props?.item?.asset_project?.name || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="费用类型">
|
||||||
|
<renderTextHelper.Tag
|
||||||
|
Enums={BillPaymentsTypeEnum}
|
||||||
|
value={props?.item?.type}
|
||||||
|
key="type"
|
||||||
|
/>
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="支付金额">
|
||||||
|
¥{props?.item?.amount || 0}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
<ProDescriptions.Item label="说明">
|
||||||
|
{props?.item?.remark || '-'}
|
||||||
|
</ProDescriptions.Item>
|
||||||
|
</ProDescriptions>
|
||||||
|
<Tabs
|
||||||
|
activeKey={activeTab}
|
||||||
|
onChange={(key) => {
|
||||||
|
setActiveTab(key);
|
||||||
|
fetchQrCode(key as 'wechat' | 'alipay');
|
||||||
|
}}
|
||||||
|
items={[
|
||||||
|
{
|
||||||
|
key: 'wechat',
|
||||||
|
label: '微信支付',
|
||||||
|
children: (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
padding: '20px 0',
|
||||||
|
justifyContent: 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{wechatQrCode ? (
|
||||||
|
<img
|
||||||
|
style={{ width: '220px', height: '220px' }}
|
||||||
|
src={wechatQrCode}
|
||||||
|
alt="微信支付二维码"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
width: '220px',
|
||||||
|
height: '220px',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
加载中...
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'alipay',
|
||||||
|
label: '支付宝',
|
||||||
|
children: (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
padding: '20px 0',
|
||||||
|
justifyContent: 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{alipayQrCode ? (
|
||||||
|
<QRCode value={alipayQrCode} size={220} />
|
||||||
|
) : (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
width: '220px',
|
||||||
|
height: '220px',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
加载中...
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
84
src/pages/bills/temporary/modals/RefundComplete.tsx
Normal file
84
src/pages/bills/temporary/modals/RefundComplete.tsx
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
import {
|
||||||
|
MyBetaModalFormProps,
|
||||||
|
MyButtons,
|
||||||
|
MyFormItems,
|
||||||
|
MyModalFormProps,
|
||||||
|
rulesHelper,
|
||||||
|
} from '@/common';
|
||||||
|
import { Apis } from '@/gen/Apis';
|
||||||
|
import { BetaSchemaForm } from '@ant-design/pro-components';
|
||||||
|
import { Form, message } from 'antd';
|
||||||
|
|
||||||
|
export default function Create(props: MyBetaModalFormProps) {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
return (
|
||||||
|
<BetaSchemaForm<ApiTypes.Refund.Refunds.Complete>
|
||||||
|
{...MyModalFormProps.props}
|
||||||
|
title={`添加${props.title}`}
|
||||||
|
wrapperCol={{ span: 24 }}
|
||||||
|
width="700px"
|
||||||
|
key={new Date().getTime()}
|
||||||
|
form={form}
|
||||||
|
onOpenChange={(open: any) => {
|
||||||
|
if (open) {
|
||||||
|
form.resetFields(); // 清空表单数据
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
trigger={
|
||||||
|
<MyButtons.Default
|
||||||
|
type="primary"
|
||||||
|
size="small"
|
||||||
|
title="退款登记"
|
||||||
|
disabled={!props.item?.has_refunding}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
onFinish={async (values) =>
|
||||||
|
Apis.Refund.Refunds.Complete({
|
||||||
|
...values,
|
||||||
|
id: props.item?.id ?? '',
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
props.reload?.();
|
||||||
|
message.success(props.title + '成功');
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.catch(() => false)
|
||||||
|
}
|
||||||
|
columns={[
|
||||||
|
// Selects?.CompanyAccounts({
|
||||||
|
// key: 'company_receipt_accounts_id',
|
||||||
|
// title: '付款账户',
|
||||||
|
// colProps: { span: 24 },
|
||||||
|
// formItemProps: { ...rulesHelper.number },
|
||||||
|
// fieldProps: {
|
||||||
|
// showSearch: true,
|
||||||
|
// },
|
||||||
|
// }),
|
||||||
|
{
|
||||||
|
key: 'refund_time',
|
||||||
|
title: '退款日期',
|
||||||
|
valueType: 'date',
|
||||||
|
formItemProps: { ...rulesHelper.text },
|
||||||
|
colProps: { span: 24 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'serial_number',
|
||||||
|
title: '退款流水号',
|
||||||
|
formItemProps: { ...rulesHelper.text },
|
||||||
|
colProps: { span: 24 },
|
||||||
|
},
|
||||||
|
|
||||||
|
MyFormItems.UploadImages({
|
||||||
|
key: 'voucher',
|
||||||
|
title: '上传退款凭证',
|
||||||
|
tooltip: '支持上传任意格式的文件',
|
||||||
|
uploadType: 'file',
|
||||||
|
colProps: { span: 24 },
|
||||||
|
// accept: '.docx,.doc,.pdf',
|
||||||
|
max: 100,
|
||||||
|
required: true,
|
||||||
|
}),
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -267,6 +267,8 @@ export default function Index({ title = '账单生成' }) {
|
|||||||
>
|
>
|
||||||
<Select
|
<Select
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
|
showSearch
|
||||||
|
optionFilterProp="children"
|
||||||
value={selectedProject || undefined}
|
value={selectedProject || undefined}
|
||||||
onChange={(value) => {
|
onChange={(value) => {
|
||||||
setSelectedProject(value);
|
setSelectedProject(value);
|
||||||
@ -291,6 +293,8 @@ export default function Index({ title = '账单生成' }) {
|
|||||||
>
|
>
|
||||||
<Select
|
<Select
|
||||||
style={{ width: '100%' }}
|
style={{ width: '100%' }}
|
||||||
|
showSearch
|
||||||
|
optionFilterProp="children"
|
||||||
value={selectedStandard || undefined}
|
value={selectedStandard || undefined}
|
||||||
onChange={(value, option) => {
|
onChange={(value, option) => {
|
||||||
console.log(value, option);
|
console.log(value, option);
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import { Apis } from '@/gen/Apis';
|
|||||||
import {
|
import {
|
||||||
HouseOccupantsCardTypeEnum,
|
HouseOccupantsCardTypeEnum,
|
||||||
HouseOccupantsHouseRelationEnum,
|
HouseOccupantsHouseRelationEnum,
|
||||||
HouseRegistersCustomerTypeEnum,
|
|
||||||
} from '@/gen/Enums';
|
} from '@/gen/Enums';
|
||||||
import { BetaSchemaForm, ProCard } from '@ant-design/pro-components';
|
import { BetaSchemaForm, ProCard } from '@ant-design/pro-components';
|
||||||
import { Form, message } from 'antd';
|
import { Form, message } from 'antd';
|
||||||
@ -37,6 +36,14 @@ export default function Create(props: MyBetaModalFormProps) {
|
|||||||
...values,
|
...values,
|
||||||
asset_houses_id: props?.item?.id,
|
asset_houses_id: props?.item?.id,
|
||||||
type: 'Transfer',
|
type: 'Transfer',
|
||||||
|
customer_info: values.customer_info?.map((res: any) => {
|
||||||
|
return {
|
||||||
|
...res,
|
||||||
|
house_relation: 'Owner',
|
||||||
|
relation_with_owner: 'Self',
|
||||||
|
residential_relation: 'PropertyOwner',
|
||||||
|
};
|
||||||
|
}),
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
props.reload?.();
|
props.reload?.();
|
||||||
@ -60,12 +67,12 @@ export default function Create(props: MyBetaModalFormProps) {
|
|||||||
// valueEnum: HouseRegistersUsagePlanEnum,
|
// valueEnum: HouseRegistersUsagePlanEnum,
|
||||||
// formItemProps: { ...rulesHelper.text },
|
// formItemProps: { ...rulesHelper.text },
|
||||||
// }),
|
// }),
|
||||||
MyFormItems.EnumSelect({
|
// MyFormItems.EnumSelect({
|
||||||
key: 'customer_type',
|
// key: 'customer_type',
|
||||||
title: '产权归属',
|
// title: '产权归属',
|
||||||
colProps: { span: 6 },
|
// colProps: { span: 6 },
|
||||||
valueEnum: HouseRegistersCustomerTypeEnum,
|
// valueEnum: HouseRegistersCustomerTypeEnum,
|
||||||
}),
|
// }),
|
||||||
MyFormItems.UploadImages({
|
MyFormItems.UploadImages({
|
||||||
key: 'ownership_info',
|
key: 'ownership_info',
|
||||||
title: '产权文件',
|
title: '产权文件',
|
||||||
@ -153,6 +160,7 @@ export default function Create(props: MyBetaModalFormProps) {
|
|||||||
key: 'card_front_image',
|
key: 'card_front_image',
|
||||||
title: '证件正面',
|
title: '证件正面',
|
||||||
uploadType: 'file',
|
uploadType: 'file',
|
||||||
|
required: true,
|
||||||
max: 1,
|
max: 1,
|
||||||
colProps: { span: 6 },
|
colProps: { span: 6 },
|
||||||
}),
|
}),
|
||||||
@ -160,6 +168,7 @@ export default function Create(props: MyBetaModalFormProps) {
|
|||||||
key: 'card_back_image',
|
key: 'card_back_image',
|
||||||
title: '证件反面',
|
title: '证件反面',
|
||||||
uploadType: 'file',
|
uploadType: 'file',
|
||||||
|
required: true,
|
||||||
max: 1,
|
max: 1,
|
||||||
colProps: { span: 6 },
|
colProps: { span: 6 },
|
||||||
}),
|
}),
|
||||||
|
|||||||
@ -37,6 +37,7 @@ export default function Index({ title = '登记审核' }) {
|
|||||||
HouseRegistersTypeEnum.MoveIn.value,
|
HouseRegistersTypeEnum.MoveIn.value,
|
||||||
HouseRegistersTypeEnum.UpdateInfo.value,
|
HouseRegistersTypeEnum.UpdateInfo.value,
|
||||||
HouseRegistersTypeEnum.UpdatePhone.value,
|
HouseRegistersTypeEnum.UpdatePhone.value,
|
||||||
|
HouseRegistersTypeEnum.Transfer.value,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
sort,
|
sort,
|
||||||
|
|||||||
@ -33,7 +33,7 @@ export default function Create(props: MyBetaModalFormProps) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onFinish={async (values) =>
|
onFinish={async (values: any) =>
|
||||||
Apis.Banner.Banners.Store(values)
|
Apis.Banner.Banners.Store(values)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
props.reload?.();
|
props.reload?.();
|
||||||
|
|||||||
@ -23,7 +23,10 @@ export default function TaskShow(props: MyBetaModalFormProps) {
|
|||||||
{...MyProTableProps.props}
|
{...MyProTableProps.props}
|
||||||
request={async (params, sort) =>
|
request={async (params, sort) =>
|
||||||
MyProTableProps.request(
|
MyProTableProps.request(
|
||||||
{ ...params, house_meter_task_id: props?.item?.id },
|
{
|
||||||
|
...params,
|
||||||
|
house_meter_task_id: props?.item?.house_meter_task_id,
|
||||||
|
},
|
||||||
sort,
|
sort,
|
||||||
Apis.Meter.HouseMeterTaskDetails.List,
|
Apis.Meter.HouseMeterTaskDetails.List,
|
||||||
)
|
)
|
||||||
|
|||||||
@ -89,7 +89,7 @@ export default function Index(props: MyBetaModalFormProps) {
|
|||||||
formItemProps: { ...rulesHelper.array },
|
formItemProps: { ...rulesHelper.array },
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
title: '证件有效期-开始',
|
title: '开始通行时间',
|
||||||
colProps: { span: 12 },
|
colProps: { span: 12 },
|
||||||
valueType: 'date',
|
valueType: 'date',
|
||||||
key: 'valid_from',
|
key: 'valid_from',
|
||||||
@ -97,7 +97,7 @@ export default function Index(props: MyBetaModalFormProps) {
|
|||||||
formItemProps: { ...rulesHelper.text },
|
formItemProps: { ...rulesHelper.text },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '证件有效期-结束',
|
title: '结束通行时间',
|
||||||
colProps: { span: 12 },
|
colProps: { span: 12 },
|
||||||
valueType: 'date',
|
valueType: 'date',
|
||||||
key: 'valid_to',
|
key: 'valid_to',
|
||||||
|
|||||||
@ -23,7 +23,7 @@ export default function SurveysList({ title = '问卷设置' }) {
|
|||||||
type="primary"
|
type="primary"
|
||||||
icon={<PlusOutlined />}
|
icon={<PlusOutlined />}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
navigate('/quality/marketing/survey/pages/create_surveys');
|
navigate('/quality/survey/pages/create_surveys');
|
||||||
}}
|
}}
|
||||||
title="新增问卷"
|
title="新增问卷"
|
||||||
/>,
|
/>,
|
||||||
|
|||||||
@ -6,9 +6,10 @@ import {
|
|||||||
MyTableActions,
|
MyTableActions,
|
||||||
} from '@/common';
|
} from '@/common';
|
||||||
import { Apis } from '@/gen/Apis';
|
import { Apis } from '@/gen/Apis';
|
||||||
|
import { VisitorAppliesStatusEnum } from '@/gen/Enums';
|
||||||
import { ProTable } from '@ant-design/pro-components';
|
import { ProTable } from '@ant-design/pro-components';
|
||||||
import { message, Space } from 'antd';
|
import { message, Space } from 'antd';
|
||||||
import Review from './modals/Review';
|
import Reject from './modals/Reject';
|
||||||
|
|
||||||
export default function Index({ title = '访客预约' }) {
|
export default function Index({ title = '访客预约' }) {
|
||||||
return (
|
return (
|
||||||
@ -35,7 +36,7 @@ export default function Index({ title = '访客预约' }) {
|
|||||||
MyColumns.EnumTag({
|
MyColumns.EnumTag({
|
||||||
title: '申请状态',
|
title: '申请状态',
|
||||||
dataIndex: 'status',
|
dataIndex: 'status',
|
||||||
// valueEnum: VisitorAppliesStatusEnum,
|
valueEnum: VisitorAppliesStatusEnum,
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
title: '房屋',
|
title: '房屋',
|
||||||
@ -74,7 +75,8 @@ export default function Index({ title = '访客预约' }) {
|
|||||||
render: (_, item: any) => {
|
render: (_, item: any) => {
|
||||||
return (
|
return (
|
||||||
<Space>
|
<Space>
|
||||||
{item?.visit_start_time}至{item?.code_expired_at}
|
{item?.visit_start_time?.slice(0, 10)}至
|
||||||
|
{item?.code_expired_at?.slice(0, 10)}
|
||||||
</Space>
|
</Space>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -117,8 +119,8 @@ export default function Index({ title = '访客预约' }) {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
view: (
|
reject: (
|
||||||
<Review item={item} reload={action?.reload} title={title} />
|
<Reject item={item} reload={action?.reload} title={title} />
|
||||||
),
|
),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import { Apis } from '@/gen/Apis';
|
|||||||
import { BetaSchemaForm } from '@ant-design/pro-components';
|
import { BetaSchemaForm } from '@ant-design/pro-components';
|
||||||
import { message } from 'antd';
|
import { message } from 'antd';
|
||||||
|
|
||||||
export default function Update(props: MyBetaModalFormProps) {
|
export default function Reject(props: MyBetaModalFormProps) {
|
||||||
return (
|
return (
|
||||||
<BetaSchemaForm<ApiTypes.Visitor.VisitorApplies.Reject>
|
<BetaSchemaForm<ApiTypes.Visitor.VisitorApplies.Reject>
|
||||||
{...MyModalFormProps.props}
|
{...MyModalFormProps.props}
|
||||||
Loading…
x
Reference in New Issue
Block a user