fix:更新

This commit is contained in:
Your Name 2026-02-04 12:32:17 +08:00
parent 3255c9deb6
commit 96f0ac68de
26 changed files with 709 additions and 106 deletions

View File

@ -1,12 +1,13 @@
import { Apis } from '@/gen/Apis';
import {
DownOutlined,
LogoutOutlined,
UnlockOutlined,
UserOutlined,
} from '@ant-design/icons';
import { history } from '@umijs/max';
import { Avatar, Dropdown, MenuProps, Space } from 'antd';
import { useState } from 'react';
import { useEffect, useState } from 'react';
import { stateActions } from '../../libs/valtio/actions';
import AvatarIcon from './AvatarIcon.png';
import ChangePassword from './ChangePassword';
@ -52,6 +53,15 @@ export default function AvatarProps({ user }: { user: any }) {
},
];
useEffect(() => {
let loginUserInfo = sessionStorage.getItem('loginUserInfo');
console.log(loginUserInfo, 'loginUserInfo');
if (loginUserInfo === 'dW5kZWZpbmVkXzAx') {
setOpen(true);
console.log('登录成功');
}
}, []);
return (
<>
<Dropdown menu={{ items }} trigger={['click']}>
@ -59,6 +69,7 @@ export default function AvatarProps({ user }: { user: any }) {
<Space>
<Avatar icon={<UserOutlined />} src={AvatarIcon} size={28} />
<span>{user?.name}</span>
<DownOutlined />
</Space>
</a>
</Dropdown>

View File

@ -1,7 +1,8 @@
import { Apis } from '@/gen/Apis';
import { ModalForm, ProFormText } from '@ant-design/pro-components';
import { history } from '@umijs/max';
import { message } from 'antd';
import { stateActions } from '../../libs/valtio/actions';
export default function ChangePassword({
open,
setOpen,
@ -14,12 +15,17 @@ export default function ChangePassword({
open={open}
wrapperCol={{ span: 24 }}
width="500px"
title="修改密码"
title="修改初始密码"
onFinish={async (values) => {
return Apis.Common.Auth.ChangePassword(values)
.then(() => {
message.success('修改密码成功');
Apis.Common.Auth.Logout().then(() => {
stateActions.setLogout();
sessionStorage.removeItem('loginUserInfo');
history.push('/login');
setOpen(false);
});
})
.catch(() => false);
}}

View File

@ -1,15 +1,16 @@
import { MyIcons, MyIconsType, PermissionsType, useMyState } from '@/common';
import AvatarProps from '@/common/components/layout/AvatarProps';
import { SettingOutlined } from '@ant-design/icons';
import { Apis } from '@/gen/Apis';
import { Link, RuntimeConfig, history, useNavigate } from '@umijs/max';
import { AutoComplete, Button, Input, Menu, MenuProps, Space } from 'antd';
import { useState } from 'react';
import { AutoComplete, Input, Menu, MenuProps, Select, Space } from 'antd';
import { useEffect, useState } from 'react';
import './allConfig.scss';
// import Logo from './logo.png';
interface LevelKeysProps {
key?: string;
children?: LevelKeysProps[];
}
const loopMenu = (permissions: PermissionsType[] | undefined) => {
let tree: PermissionsType[] = [];
let map: Record<number, PermissionsType> = {};
@ -57,6 +58,7 @@ const loopMenu = (permissions: PermissionsType[] | undefined) => {
};
export const LayoutConfig: RuntimeConfig['layout'] = () => {
const [getSelectProject, setSelectProject] = useState<LevelKeysProps[]>([]);
const { snap } = useMyState();
const navigate = useNavigate();
const permissionsList = (snap.session.permissions || [])
@ -69,12 +71,20 @@ export const LayoutConfig: RuntimeConfig['layout'] = () => {
{ label: '收费Bi', path: '/charge/charge_bi' },
{ label: '项目Bi', path: '/asset/asset_bi' },
];
const handleLoadProject = async () => {
let res = await Apis.Common.Auth.GetProjects();
setSelectProject(
res?.data?.map((item) => ({
value: item.id,
label: item.name,
})),
);
};
const [stateOpenKeys, setStateOpenKeys] = useState(['2', '23']);
const getLevelKeys: any = (items1: LevelKeysProps[]) => {
const key: Record<string, number> = {};
const func = (items2: LevelKeysProps[], level = 1) => {
console.log(items2, 'level');
items2?.forEach((item) => {
if (item.key) {
key[item.key] = level;
@ -88,18 +98,22 @@ export const LayoutConfig: RuntimeConfig['layout'] = () => {
return key;
};
useEffect(() => {
handleLoadProject('');
}, []);
return {
title: '',
// 首页 logo
logo: (
<div style={{ width: 181 }}>
<div style={{ width: 136, display: 'flex', justifyContent: 'center' }}>
<img
src={
snap.session?.company_configs?.config_value?.admin_logo
? snap.session?.company_configs?.config_value?.admin_logo[0]?.url
: ''
}
style={{ height: '42px' }}
style={{ width: 'auto', height: '42px' }}
/>
</div>
),
@ -114,45 +128,29 @@ export const LayoutConfig: RuntimeConfig['layout'] = () => {
<div className="headerContentRender">
<div style={{ display: 'flex', alignItems: 'center', gap: 20 }}>
<HeaderSearch permissionsList={permissionsList} />
{/* <Space size={20} style={{ color: '#666' }}>
:
{quickLinks.map((q) => (
<a
key={q.path}
onClick={() => history.push(q.path)}
className="quick_link"
>
{q.label}
</a>
))}
</Space> */}
</div>
<Space size={10}>
{/* <Popover
placement="bottom"
title="小程序二维码"
content={
<Space style={{ textAlign: 'center' }} size="large">
<div>
<Image src={ImgEmployeeWxApp} style={{ height: '120px' }} />
<div style={{ marginTop: 10 }}></div>
</div>
<div>
<Image src={ImgCustomerWxApp} style={{ height: '120px' }} />
<div style={{ marginTop: 10 }}></div>
</div>
</Space>
}
>
<Button type="default" shape="circle" icon={<TabletOutlined />} />
</Popover>
<Button type="default" shape="circle" icon={<BellOutlined />} /> */}
<Button
{/* <Button
type="default"
shape="circle"
icon={<SettingOutlined />}
onClick={() => history.push('/system/sys_permissions')}
/> */}
<Select
onSearch={handleLoadProject}
options={getSelectProject}
allowClear
style={{ width: 160 }}
defaultValue={snap.session.current_project?.id}
onChange={(e: any) => {
Apis.Common.Auth.SwitchProject({
project_id: e ? e?.toString() : 'all',
}).then(() => {
window.location.reload();
});
console.log(e, 'e');
}}
placeholder="选择项目"
/>
</Space>
</div>
@ -202,7 +200,6 @@ export const LayoutConfig: RuntimeConfig['layout'] = () => {
const repeatIndex = openKeys
.filter((key) => key !== currentOpenKey)
.findIndex((key) => levelKeys[key] === levelKeys[currentOpenKey]);
setStateOpenKeys(
openKeys
// remove repeat key

View File

@ -41,7 +41,9 @@ export const requestConfig: RequestConfig = {
// 错误接收及处理
errorHandler: (error: any) => {
if (error) {
if (error.errorMessage !== '用户未登录') {
message.error(error.errorMessage);
}
switch (error.errorCode) {
case 10000:
if (history.location.pathname !== '/login') history.push('/login');

View File

@ -17,6 +17,7 @@ export const stateActions = {
state.session.campus = res.data.campus;
state.session.company_configs = res.data.company_configs;
state.session.permissions = res.data.permissions;
state.session.current_project = res.data.current_project;
if (res.data?.token?.access_token)
state.storage.access_token = res.data?.token?.access_token;
// 解析apis

View File

@ -48,6 +48,10 @@ type SessionType = {
permissions?: any;
apiKeys: string[];
loading: number;
current_project?: {
id: number;
name: string;
};
};
const session: SessionType = proxy({
@ -58,6 +62,7 @@ const session: SessionType = proxy({
company_configs: {},
apiKeys: [],
loading: 0,
current_project: undefined,
});
export const state = proxy({

View File

@ -59,7 +59,9 @@ export function MyLoginPage() {
...values,
...{ captcha_key: getCaptcha?.key },
})
.then(async (res) => {
.then(async (res: any) => {
let pass = btoa(`${res?.password}_01`);
sessionStorage.setItem('loginUserInfo', pass);
await stateActions.setLogin(res);
navigate('/');
})

View File

@ -34,6 +34,7 @@ export function MyModal(props?: any) {
type={props.type || 'primary'}
size={props.size || 'small'}
onClick={() => setOpen(true)}
{...props?.modal?.btnProps}
/>
)
) : (

157
src/gen/ApiTypes.d.ts vendored
View File

@ -667,6 +667,156 @@ declare namespace ApiTypes {
};
}
}
namespace Attendance {
namespace AttendanceConfigs {
type List = {
"page"?: number; // -
"per_page"?: number; // -
};
type Store = {
"asset_projects_id": number; // 项目ID
"check_in_range": number; // 打卡范围(米)
"require_photo": boolean; // 是否要求拍照打卡
"allow_out_range_checkin"?: boolean; // 是否允许范围外打卡
};
type UpdateConfig = {
"id": number; // id
"check_in_range": number; // 打卡范围(米)
"require_photo": boolean; // 是否要求拍照打卡
"allow_out_range_checkin"?: boolean; // 是否允许范围外打卡
};
type Enable = {
"id": number; // id
"is_enabled": boolean; // 是否启用: 1:启用 0:禁用
};
}
namespace AttendanceEmployeeTracks {
type List = {
"company_employees_id"?: number; // 员工ID
"asset_projects_id"?: number; // 项目ID
"start_date"?: Date; // 开始日期
"end_date"?: Date; // 结束日期
};
type Detail = {
"company_employees_id": number; // 员工ID
"start_date": Date; // 开始日期
"end_date": Date; // 结束日期
"asset_projects_id"?: number; // 项目ID
};
type Heatmap = {
"company_employees_id": number; // 员工ID
"date": Date; // 日期
};
}
namespace AttendanceRecords {
type List = {
"company_employees_id"?: number; // 员工ID
"asset_projects_id"?: number; // 项目ID
"status"?: string; // 状态
"checkin_type"?: string; // 打卡类型
"checkin_time"?: string[]; // 打卡时间
};
type Show = {
"id": number; // 记录ID
};
type Export = {
"company_employees_id"?: number; // 员工ID
"asset_projects_id"?: number; // 项目ID
"status"?: string; // 状态
"checkin_type"?: string; // 打卡类型
"checkin_time"?: string[]; // 打卡时间
};
}
namespace AttendanceSchedules {
type List = {
"company_employees_id"?: number; // 员工ID
"asset_projects_id"?: number; // 项目ID
"schedule_date"?: Date; // 排班日期
"status"?: string; // 状态,[enum:AttendanceSchedulesStatusEnum]
"project_name"?: string; // 项目名称
"employee_name"?: string; // -
};
type Store = {
"company_employees_id": number; // 员工ID
"attendance_shifts_id": number; // 班次ID
"asset_projects_id": number; // 项目ID
"schedule_date": Date; // 排班日期
"remark"?: string; // 备注
};
type BatchStore = {
"schedules": string[]; // 排班列表
};
type ShiftList = {
"organizations_id": number; // 组织ID
"schedule_date": Date; // 排班日期
};
type Update = {
"id": number; // id
"company_employees_id"?: number; // 员工ID
"attendance_shifts_id"?: number; // 班次ID
"asset_projects_id"?: number; // 项目ID
"schedule_date"?: Date; // 排班日期
"remark"?: string; // 备注
};
type ChangeStatus = {
"id": number; // id
"status": string; // 状态,[enum:AttendanceSchedulesStatusEnum]
};
type Cancel = {
"id": number; // id
};
type Show = {
"id": number; // id
};
type SoftDelete = {
"id": number; // id
};
type Restore = {
"id": number; // id
};
type Delete = {
"id": number; // id
};
}
namespace AttendanceShifts {
type List = {
"name"?: string; // 班次名称
"is_enabled"?: boolean; // 状态
"asset_projects_id"?: number; // 项目ID
"project_name"?: string; // 项目名称
};
type Store = {
"name": string; // 班次名称
"asset_projects_id": number; // 关联项目IDs
"allow_checkin_start": date_format:H:i:s; // 可打卡开始时间
"allow_checkin_end": date_format:H:i:s; // 可打卡结束时间
"is_enabled"?: boolean; // 状态
"remark"?: string; // 备注
"periods": string[]; // 时段列表
};
type Update = {
"id": number; // id
"name"?: string; // 班次名称
"asset_projects_id"?: number; // 关联项目IDs
"allow_checkin_start"?: date_format:H:i:s; // 可打卡开始时间
"allow_checkin_end"?: date_format:H:i:s; // 可打卡结束时间
"is_enabled"?: boolean; // 状态
"remark"?: string; // 备注
"periods"?: string[]; // 时段列表
};
type Show = {
"id": number; // id
};
type Delete = {
"id": number; // id
};
type Select = {
"name"?: string; // 班次名称
"asset_projects_id"?: number; // 项目ID
"project_name"?: string; // 项目名称
};
}
}
namespace Bill {
namespace HouseBills {
type List = {
@ -790,6 +940,9 @@ declare namespace ApiTypes {
type TemporaryUrl = {
"filename": string; // 文件名称
};
type SwitchProject = {
"project_id": string; // 项目ID all-查看所有
};
}
namespace ConvenienceServices {
type List = {
@ -1784,6 +1937,10 @@ declare namespace ApiTypes {
};
}
}
namespace Statistics {
namespace IndexCount {
}
}
namespace Visitor {
namespace VisitorApplies {
type List = {

View File

@ -315,6 +315,102 @@ export const Apis = {
},
},
},
Attendance: {
AttendanceConfigs: {
List(data?: ApiTypes.Attendance.AttendanceConfigs.List): Promise<MyResponseType> {
return request('company/attendance/attendance_configs/list', { data });
},
Store(data: ApiTypes.Attendance.AttendanceConfigs.Store): Promise<MyResponseType> {
return request('company/attendance/attendance_configs/store', { data });
},
UpdateConfig(data: ApiTypes.Attendance.AttendanceConfigs.UpdateConfig): Promise<MyResponseType> {
return request('company/attendance/attendance_configs/update_config', { data });
},
Enable(data: ApiTypes.Attendance.AttendanceConfigs.Enable): Promise<MyResponseType> {
return request('company/attendance/attendance_configs/enable', { data });
},
},
AttendanceEmployeeTracks: {
List(data?: ApiTypes.Attendance.AttendanceEmployeeTracks.List): Promise<MyResponseType> {
return request('company/attendance/attendance_employee_tracks/list', { data });
},
Detail(data: ApiTypes.Attendance.AttendanceEmployeeTracks.Detail): Promise<MyResponseType> {
return request('company/attendance/attendance_employee_tracks/detail', { data });
},
Heatmap(data: ApiTypes.Attendance.AttendanceEmployeeTracks.Heatmap): Promise<MyResponseType> {
return request('company/attendance/attendance_employee_tracks/heatmap', { data });
},
Cleanup(): Promise<MyResponseType> {
return request('company/attendance/attendance_employee_tracks/cleanup', {});
},
},
AttendanceRecords: {
List(data?: ApiTypes.Attendance.AttendanceRecords.List): Promise<MyResponseType> {
return request('company/attendance/attendance_records/list', { data });
},
Show(data: ApiTypes.Attendance.AttendanceRecords.Show): Promise<MyResponseType> {
return request('company/attendance/attendance_records/show', { data });
},
Export(data?: ApiTypes.Attendance.AttendanceRecords.Export): Promise<MyResponseType> {
return request('company/attendance/attendance_records/export', { responseType: 'blob',data });
},
},
AttendanceSchedules: {
List(data?: ApiTypes.Attendance.AttendanceSchedules.List): Promise<MyResponseType> {
return request('company/attendance/attendance_schedules/list', { data });
},
Store(data: ApiTypes.Attendance.AttendanceSchedules.Store): Promise<MyResponseType> {
return request('company/attendance/attendance_schedules/store', { data });
},
BatchStore(data: ApiTypes.Attendance.AttendanceSchedules.BatchStore): Promise<MyResponseType> {
return request('company/attendance/attendance_schedules/batch_store', { data });
},
ShiftList(data: ApiTypes.Attendance.AttendanceSchedules.ShiftList): Promise<MyResponseType> {
return request('company/attendance/attendance_schedules/shift_list', { data });
},
Update(data: ApiTypes.Attendance.AttendanceSchedules.Update): Promise<MyResponseType> {
return request('company/attendance/attendance_schedules/update', { data });
},
ChangeStatus(data: ApiTypes.Attendance.AttendanceSchedules.ChangeStatus): Promise<MyResponseType> {
return request('company/attendance/attendance_schedules/change_status', { data });
},
Cancel(data: ApiTypes.Attendance.AttendanceSchedules.Cancel): Promise<MyResponseType> {
return request('company/attendance/attendance_schedules/cancel', { data });
},
Show(data: ApiTypes.Attendance.AttendanceSchedules.Show): Promise<MyResponseType> {
return request('company/attendance/attendance_schedules/show', { data });
},
SoftDelete(data: ApiTypes.Attendance.AttendanceSchedules.SoftDelete): Promise<MyResponseType> {
return request('company/attendance/attendance_schedules/soft_delete', { data });
},
Restore(data: ApiTypes.Attendance.AttendanceSchedules.Restore): Promise<MyResponseType> {
return request('company/attendance/attendance_schedules/restore', { data });
},
Delete(data: ApiTypes.Attendance.AttendanceSchedules.Delete): Promise<MyResponseType> {
return request('company/attendance/attendance_schedules/delete', { data });
},
},
AttendanceShifts: {
List(data?: ApiTypes.Attendance.AttendanceShifts.List): Promise<MyResponseType> {
return request('company/attendance/attendance_shifts/list', { data });
},
Store(data: ApiTypes.Attendance.AttendanceShifts.Store): Promise<MyResponseType> {
return request('company/attendance/attendance_shifts/store', { data });
},
Update(data: ApiTypes.Attendance.AttendanceShifts.Update): Promise<MyResponseType> {
return request('company/attendance/attendance_shifts/update', { data });
},
Show(data: ApiTypes.Attendance.AttendanceShifts.Show): Promise<MyResponseType> {
return request('company/attendance/attendance_shifts/show', { data });
},
Delete(data: ApiTypes.Attendance.AttendanceShifts.Delete): Promise<MyResponseType> {
return request('company/attendance/attendance_shifts/delete', { data });
},
Select(data?: ApiTypes.Attendance.AttendanceShifts.Select): Promise<MyResponseType> {
return request('company/attendance/attendance_shifts/select', { data });
},
},
},
Bill: {
HouseBills: {
List(data?: ApiTypes.Bill.HouseBills.List): Promise<MyResponseType> {
@ -390,6 +486,12 @@ export const Apis = {
TemporaryUrl(data: ApiTypes.Common.Auth.TemporaryUrl): Promise<MyResponseType> {
return request('company/common/auth/temporary_url', { data });
},
SwitchProject(data: ApiTypes.Common.Auth.SwitchProject): Promise<MyResponseType> {
return request('company/common/auth/switch_project', { data });
},
GetProjects(): Promise<MyResponseType> {
return request('company/common/auth/get_projects', {});
},
},
ConvenienceServices: {
List(data?: ApiTypes.Common.ConvenienceServices.List): Promise<MyResponseType> {
@ -1019,6 +1121,13 @@ export const Apis = {
},
},
},
Statistics: {
IndexCount: {
FinancialAnalysis(): Promise<MyResponseType> {
return request('company/statistics/index_count/financial_analysis', {});
},
},
},
Visitor: {
VisitorApplies: {
List(data?: ApiTypes.Visitor.VisitorApplies.List): Promise<MyResponseType> {

View File

@ -227,6 +227,37 @@ export const AssetUnitsBuildingTypeEnum= {
'Tower': {"text":"塔楼","color":"#ffc107","value":"Tower"},
};
// AttendanceRecordsCheckinTypeEnum
export const AttendanceRecordsCheckinTypeEnum= {
'CheckIn': {"text":"上班","color":"#1890ff","value":"CheckIn"},
'CheckOut': {"text":"下班","color":"#52c41a","value":"CheckOut"},
};
// AttendanceRecordsStatusEnum
export const AttendanceRecordsStatusEnum= {
'Normal': {"text":"正常","color":"#52c41a","value":"Normal"},
'Late': {"text":"迟到","color":"#faad14","value":"Late"},
'EarlyLeave': {"text":"早退","color":"#fa8c16","value":"EarlyLeave"},
'OutOfRange': {"text":"范围外","color":"#ff4d4f","value":"OutOfRange"},
'Reissue': {"text":"补卡","color":"#1890ff","value":"Reissue"},
};
// AttendanceSchedulesStatusEnum
export const AttendanceSchedulesStatusEnum= {
'Pending': {"text":"待生效","color":"#faad14","value":"Pending"},
'Active': {"text":"生效中","color":"#52c41a","value":"Active"},
'Cancelled': {"text":"已取消","color":"#ff4d4f","value":"Cancelled"},
};
// 打卡状态枚举
export const AttendanceStatusEnum= {
'Normal': {"text":"正常","color":"#52c41a","value":"Normal"},
'Late': {"text":"迟到","color":"#faad14","value":"Late"},
'Early': {"text":"早退","color":"#faad14","value":"Early"},
'OutOfRange': {"text":"范围外","color":"#ff4d4f","value":"OutOfRange"},
'MakeUp': {"text":"补卡","color":"#722ed1","value":"MakeUp"},
};
// BannerSpacesTypeEnum
export const BannerSpacesTypeEnum= {
'Popup': {"text":"弹窗","color":"#ff0000","value":"Popup"},
@ -251,7 +282,7 @@ export const BannersTypeEnum= {
// 缓存类型
export const CacheTypeEnum= {
'MobilePhoneVerificationCode': {"text":"手机验证码","color":"#e482d3","value":"MobilePhoneVerificationCode"},
'MobilePhoneVerificationCode': {"text":"手机验证码","color":"#ba2dfa","value":"MobilePhoneVerificationCode"},
};
// CompaniesMerchantTypeEnum
@ -297,6 +328,13 @@ export const CompanyEmployeeBacklogsTypeEnum= {
'MomentTask': {"text":"朋友圈任务","color":"#FF6600","value":"MomentTask"},
};
// CompanyEmployeesTypeEnum
export const CompanyEmployeesTypeEnum= {
'Staff': {"text":"员工","color":"#1890ff","value":"Staff"},
'WeCom': {"text":"企微","color":"#2196f3","value":"WeCom"},
'External': {"text":"外部","color":"#4caf50","value":"External"},
};
// CompanyReceiptAccountsPayChannelEnum
export const CompanyReceiptAccountsPayChannelEnum= {
'WeChat': {"text":"微信","color":"#07c160","value":"WeChat"},
@ -762,6 +800,12 @@ export const HouseWorkOrdersTypeEnum= {
'Complaint': {"text":"投诉","color":"#aa00ff","value":"Complaint"},
};
// 公告阅读者类型
export const MsgPropertyAnnouncementReadsReaderTypeEnum= {
'Customer': {"text":"客户","color":"#3b82f6","value":"Customer"},
'Employee': {"text":"员工","color":"#10b981","value":"Employee"},
};
// 公告接收对象
export const MsgPropertyAnnouncementsObjectEnum= {
'Customer': {"text":"客户","color":"#3b82f6","value":"Customer"},

View File

@ -38,13 +38,7 @@ export default function Index({ title = '项目活动' }) {
// title={title}
/>
),
enrolls: (
<>
{item.is_enroll === 1 && (
<EnrollsList item={item} title="报名" reload={action?.reload} />
)}
</>
),
enrolls: <EnrollsList item={item} title="报名" reload={action?.reload} />,
publish: (
<MyButtons.Default
title={
@ -199,7 +193,6 @@ export default function Index({ title = '项目活动' }) {
render: (_, item: any, index, action) => (
<Space key={index}>
<ActivityShow item={item} />
<>{tableRender(item, action)}</>
</Space>
),

View File

@ -16,6 +16,11 @@ export default function EnrollsList(props: MyBetaModalFormProps) {
title={props.title || '报名'}
type={props.item?.type || 'primary'}
width="800px"
modal={{
btnProps: {
disabled: !props?.item.is_enroll,
},
}}
node={
<ProTable
{...MyProTableProps.props}

View File

@ -88,9 +88,7 @@ export default function Index({ title = '登记审核' }) {
MyColumns.Option({
render: (_, item: any, index, action) => (
<Space key={index}>
{item?.status === HouseRegistersStatusEnum.Pending.value && (
<Audit item={item} reload={action?.reload} title={title} />
)}
</Space>
),
}),

View File

@ -32,7 +32,15 @@ export default function Update(props: MyBetaModalFormProps) {
<BetaSchemaForm<ApiTypes.Archive.HouseRegisters.Update>
{...MyModalFormProps.props}
title={props.title}
trigger={<MyButtons.Default title="审核" type="primary" />}
trigger={
<MyButtons.Default
title="审核"
disabled={
props.item?.status !== HouseRegistersStatusEnum.Pending.value
}
type="primary"
/>
}
wrapperCol={{ span: 24 }}
width="800px"
modalProps={{

View File

@ -106,7 +106,7 @@ export default function Index({ title = '客户列表' }) {
search: false,
}),
MyColumns.Option({
render: (_, item: any, index, action) => (
render: (_, item: any, index) => (
<Space key={index}>
<MyButtons.View
title="查看"

View File

@ -0,0 +1,68 @@
import { Line } from '@ant-design/plots';
import { useEffect, useState } from 'react';
export default function FinancialAnalysisLine() {
const [houseBillsCount, setHouseBillsCount] = useState<any>({});
const config = {
data: [
{
name: '收缴率',
: '01',
金额: 79.0,
},
{
name: '月收款(万元)',
: '01',
金额: 69.0,
},
{
name: '收缴率',
: '02',
金额: 89.0,
},
{
name: '月收款(万元)',
: '02',
金额: 62.0,
},
],
xField: '月份',
yField: '金额',
colorField: 'name',
point: {
size: 7,
},
legend: {
position: 'top',
},
tooltip: {},
style: {
// 矩形四个方向的内边距
inset: 5,
},
// 使用双Y轴因为两个指标数值范围差异大
yAxis: [
{
title: {
text: '月收款(万元)',
},
},
{
title: {
text: '收缴率(%)',
},
grid: null,
},
],
};
useEffect(() => {
setHouseBillsCount({ ...config, data: [] });
}, []);
return (
<div style={{ height: 290 }}>
<Line {...config} />
</div>
);
}

View File

@ -0,0 +1,174 @@
import { ProCard } from '@ant-design/pro-components';
import { Col, Row, Space } from 'antd';
import MyFinancialAnalysisLine from '../charts/FinancialAnalysisLine';
export default function LayoutLeft() {
return (
<div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
<Space>
<ProCard title="财务分析" style={{ width: '450px', color: '#fff' }}>
<Space direction="vertical" style={{ width: '100%' }}>
<div
style={{
background:
'linear-gradient(115deg, #6499FF 45%, #95B8FF 100%)',
padding: '20px 0',
borderRadius: '10px',
}}
>
<Row>
<Col span={8}>
<div
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
color: 'white',
}}
>
<div
style={{
fontSize: '18px',
fontWeight: 'bold',
marginBottom: '5px',
}}
>
79.00
</div>
<div style={{ fontSize: '14px' }}></div>
</div>
</Col>
<Col span={8}>
<div
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
color: 'white',
}}
>
<div
style={{
fontSize: '18px',
fontWeight: 'bold',
marginBottom: '5px',
}}
>
79.00
</div>
<div style={{ fontSize: '14px' }}></div>
</div>
</Col>
<Col span={8}>
<div
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
color: 'white',
}}
>
<div
style={{
fontSize: '18px',
fontWeight: 'bold',
marginBottom: '5px',
}}
>
79.00%
</div>
<div style={{ fontSize: '14px' }}></div>
</div>
</Col>
</Row>
</div>
<div
style={{
background:
'linear-gradient(115deg, #6499FF 45%, #95B8FF 100%)',
padding: '20px 0',
borderRadius: '10px',
}}
>
<Row>
<Col span={8}>
<div
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
color: 'white',
}}
>
<div
style={{
fontSize: '18px',
fontWeight: 'bold',
marginBottom: '5px',
}}
>
79.00
</div>
<div style={{ fontSize: '14px' }}></div>
</div>
</Col>
<Col span={8}>
<div
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
color: 'white',
}}
>
<div
style={{
fontSize: '18px',
fontWeight: 'bold',
marginBottom: '5px',
}}
>
79.00
</div>
<div style={{ fontSize: '14px' }}></div>
</div>
</Col>
<Col span={8}>
<div
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
color: 'white',
}}
>
<div
style={{
fontSize: '18px',
fontWeight: 'bold',
marginBottom: '5px',
}}
>
79.00%
</div>
<div style={{ fontSize: '14px' }}></div>
</div>
</Col>
</Row>
</div>
<MyFinancialAnalysisLine />
</Space>
</ProCard>
</Space>
<div
style={{
flex: 1,
padding: '15px',
backgroundColor: '#f0f0f0',
borderRadius: '4px',
}}
>
</div>
</div>
);
}

View File

@ -0,0 +1,3 @@
export default function LayoutRight() {
return <div>LayoutRight</div>;
}

View File

@ -1,5 +1,16 @@
// import MyModalsMapLeaflet from '@/components/ModalsMapLeaflet';
import LayoutLeft from './components/LayoutLeft';
import LayoutRight from './components/LayoutRight';
import './style.scss';
export default function Index() {
return <div className="overview_content">2</div>;
return (
<div className="overview_content">
<div className="overview_left">
<LayoutLeft />
</div>
<div className="overview_right">
<LayoutRight />
</div>
</div>
);
}

View File

@ -6,9 +6,11 @@
justify-content: space-between;
gap: 15px;
}
.overview_left,
.overview_left {
flex: 3;
}
.overview_right {
width: 500px;
flex: 1;
}
.overview_center {
flex: 1;

View File

@ -197,7 +197,6 @@ export default function Create(props: MyBetaModalFormProps) {
value: 'value',
},
labelRender: (res: any) => {
console.log(res, '222');
if (res?.label) {
return res?.label;
} else {

View File

@ -16,7 +16,7 @@ import {
} from '@/gen/Enums';
import { ProTable } from '@ant-design/pro-components';
import { useSearchParams } from '@umijs/max';
import { Space, Tooltip } from 'antd';
import { Dropdown, Space, Tooltip } from 'antd';
import WorkOrderAssign from './modals/WorkOrderAssign';
import WorkOrderCreate from './modals/WorkOrderCreate';
import WorkOrderShow from './modals/WorkOrderShow';
@ -52,40 +52,31 @@ export default function Index({ title = '报修报事' }) {
});
};
let tableRender = (item: any, action: any) => {
return getCurrentPermissions({
show: <WorkOrderShow item={item} title="详情" reload={action?.reload} />,
update: (
<>
{item.status === 'Pending' && (
<WorkOrderUpdate
item={item}
reload={action?.reload}
title={title}
/>
)}
</>
),
let permissions = getCurrentPermissions({
assign: (
<>
{item.assign_status === 'Unassigned' &&
item.type !== 'SecurityInspection' &&
item.status !== 'Closed' && (
<WorkOrderAssign
item={item}
reload={action?.reload}
title="指派"
/>
)}
</>
<WorkOrderAssign item={item} reload={action?.reload} title="指派" />
),
completed: (
<>
{item.status === 'Completed' && item.is_visited === 0 && (
<WorkOrderShow item={item} title="回访" reload={action?.reload} />
)}
</>
),
delete: (
});
let permissionsSpace = getCurrentPermissions({
show: {
key: '1',
label: (
<WorkOrderShow item={item} title="详情" reload={action?.reload} />
),
},
update: {
key: '2',
label: (
<WorkOrderUpdate item={item} reload={action?.reload} title={title} />
),
},
delete: {
key: '3',
label: (
<MyButtons.Delete
onConfirm={() =>
Apis.WorkOrder.HouseWorkOrders.Delete({
@ -94,7 +85,15 @@ export default function Index({ title = '报修报事' }) {
}
/>
),
},
});
let Others = (
<Dropdown menu={{ items: permissionsSpace }} trigger={['click']}>
<MyButtons.Default title="更多" />
</Dropdown>
);
return [...permissions, ...[Others]];
};
return (

View File

@ -33,7 +33,15 @@ export default function WorkOrderAssign(
labelCol={{ span: 5 }}
labelAlign="left"
trigger={
<MyButtons.Default title={props.title || '指派'} type="primary" />
<MyButtons.Default
title={props.title || '指派'}
disabled={
props?.item.assign_status !== 'Unassigned' ||
props?.item.type === 'SecurityInspection' ||
props?.item.status === 'Closed'
}
type="primary"
/>
}
key={new Date().getTime()}
form={form}

View File

@ -41,7 +41,7 @@ export default function WorkOrderShow({
<>
<MyButtons.Default
onClick={handleOpen}
disabled={item?.is_visited}
disabled={item?.is_visited || item.status !== 'Completed'}
type={'primary'}
title={title}
/>

View File

@ -27,7 +27,7 @@ export default function WorkOrderUpdate(
width="600px"
layout="horizontal"
key={new Date().getTime()}
trigger={<MyButtons.Edit title={`编辑`} />}
trigger={<MyButtons.Edit title={`编辑`} disabled={props.item?.status !== 'Pending'} />}
onOpenChange={(open: any) => {
if (open && props.item) {
const formValues = {