This commit is contained in:
linxd
2025-07-24 09:41:42 +08:00
7 changed files with 109 additions and 63 deletions

View File

@ -0,0 +1,58 @@
import React, { useState, useEffect } from 'react';
import { Cascader, Spin } from 'antd';
import type { DefaultOptionType } from 'antd/es/cascader';
import { getChild } from './services';
// 只用函数式组件的 props不声明泛型
const DictRegionSelect: React.FC<Partial<import('antd').CascaderProps<DefaultOptionType>>> = (props) => {
const [options, setOptions] = useState<DefaultOptionType[]>([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
setLoading(true);
fetchRegionOptions('0').then(data => {
setOptions(data);
setLoading(false);
});
}, []);
const loadData = async (selectedOptions: DefaultOptionType[]) => {
const targetOption = selectedOptions[selectedOptions.length - 1];
targetOption.loading = true;
const children = await fetchRegionOptions(targetOption.value!);
targetOption.loading = false;
targetOption.children = children;
setOptions([...options]);
};
const fetchRegionOptions = async (pId: string | number): Promise<DefaultOptionType[]> => {
console.log(pId,'pId');
const res = await getChild({ pId });
if (res && res.code === 200 && Array.isArray(res.data)) {
return res.data.map((item: any) => ({
value: item.id,
label: item.name,
isLeaf: item.level === '2',
}));
}
return [];
};
// 明确指定 loadData 类型,解决 ts 推断
const cascaderProps = {
changeOnSelect: true,
options,
loadData: loadData as (selectedOptions: DefaultOptionType[]) => void, // 关键类型断言!
placeholder: "请选择地区",
...props,
};
return (
<Spin spinning={loading}>
<Cascader {...cascaderProps as any} />
</Spin>
);
};
export default DictRegionSelect;

View File

@ -0,0 +1,11 @@
import request from '@/utils/request';
/**
* 地市
*/
interface getChildParams {
pId: string | number;
}
export const getChild = (params: getChildParams) => request.get(`/v1/dictRegion/getChild`, {params});

View File

@ -1,18 +1,10 @@
import React, { useEffect, useState } from 'react';
import { Modal, Form, Input, message, Row, Col, Descriptions, Cascader, Select } from 'antd';
import { Modal, Form, Input, message, Row, Col, Descriptions, Select } from 'antd';
import { getDictList } from '@/servers/api/dicts';
import { bankView, bankAdd, bankEdit } from '../services';
import { getRegionTree } from '@/servers/api/register';
import type { DictItem } from '@/servers/api/dicts';
import DictRegionSelect from '@/components/CommonSelect/DictRegionSelect'
// 地区字段转换
function convertToCascaderOptions(data: any[]): any[] {
return data.map(item => ({
label: item.name,
value: item.id,
children: item.children && item.children.length > 0 ? convertToCascaderOptions(item.children) : undefined,
}));
}
interface props {
visible: boolean;
onOk: () => void;
@ -54,8 +46,6 @@ const InvoiceFormModal: React.FC<props> = ({
const [form] = Form.useForm();
//查看
const [viewData, setViewData] = useState<viewDataData>({});
// 地区
const [addressOptions, setAddressOptions] = useState<API.RegionOption[]>([]);
//提交防抖
const [submitting, setSubmitting] = useState(false);
const [currency, setCurrency] = useState<DictItem[]>([]);
@ -82,14 +72,8 @@ const InvoiceFormModal: React.FC<props> = ({
}
});
} else {
form.resetFields(); // ✅ 只有无 initialValues 才重置
form.resetFields();
}
getRegionTree().then(res => {
if (res.code === 200) {
setAddressOptions(convertToCascaderOptions(res.data));
}
});
getDictList('currency').then((res) => {
if (res.code === 200) {
@ -190,22 +174,7 @@ const InvoiceFormModal: React.FC<props> = ({
<Col span={24}>
<Form.Item name="address" label="地址" rules={[{ required: true }]}>
<Cascader
options={addressOptions}
placeholder="请选择地址"
showSearch={{
filter: (inputValue, path) => {
return path.some((option) => {
if (typeof option.label === 'string') {
return (
option.label.toLowerCase().indexOf(inputValue.toLowerCase()) > -1
);
}
return false;
});
},
}}
/>
<DictRegionSelect />
</Form.Item>
</Col>
{/* <Col span={24}>

View File

@ -26,19 +26,28 @@ const LoginPage: React.FC = () => {
useEffect(() => {
fetchCaptcha();
if(!sessionStorage.getItem('dict')) {
refreshDictCache().then((res) => {
if(res.code == 200) {
sessionStorage.setItem('dict', JSON.stringify(res.data))
}
})
}
}, [activeKey]);
// 组件挂载时,检查是否有记住的用户名
useEffect(() => {
const savedUser = localStorage.getItem('remember_user');
if (savedUser) {
const user = JSON.parse(savedUser);
form.setFieldsValue({
username: user.username,
password: user.password,
remember: true,
});
}
// const savedUser = localStorage.getItem('remember_user');
// if (savedUser) {
// const user = JSON.parse(savedUser);
// form.setFieldsValue({
// username: user.username,
// password: user.password,
// remember: true,
// });
// }
}, [form]);
const onFinish = async (values: any) => {
setLoading(true);
@ -80,12 +89,7 @@ const LoginPage: React.FC = () => {
}
sessionStorage.setItem('currentUser', JSON.stringify(loginRes.data));
refreshDictCache().then((res) => {
if(res.code == 200) {
sessionStorage.setItem('dict', JSON.stringify(res.data))
}
})
getUserinfo().then(async (res) => {
// if(res.code == 200) {
const roleIdList = res.authorityList.map((item: any) => {

View File

@ -25,6 +25,7 @@ import { getRegionTree, getregionInternational } from '@/servers/api/register';
import { getDictList } from '@/servers/api/dicts';
import type { DictItem } from '@/servers/api/dicts';
import FileUpload from '@/components/FileUpload/FileUpload';
import DictRegionSelect from '@/components/CommonSelect/DictRegionSelect'
const { Option } = Select;
@ -407,12 +408,12 @@ export const BankAccountSection: React.FC<CommonFormSectionsProps> = ({ form, su
}, []);
useEffect(() => {
if (supplierType) {
const submitInterface = supplierType === 'dvs' ? getRegionTree : getregionInternational;
submitInterface().then((res) => {
if (res.code === 200) {
setAddressOptions(convertToCascaderOptions(res.data));
}
});
// const submitInterface = supplierType === 'dvs' ? getRegionTree : getregionInternational;
// submitInterface({ pId: 0 }).then((res) => {
// if (res.code === 200) {
// setAddressOptions(convertToCascaderOptions(res.data));
// }
// });
}
}, [supplierType]);
@ -592,7 +593,8 @@ export const BankAccountSection: React.FC<CommonFormSectionsProps> = ({ form, su
noStyle
rules={[{ required: true, message: '请选择地址' }]}
>
<Cascader
<DictRegionSelect onChange={(value:any) => handleAddressChange(value as string[], record)} />
{/* <Cascader
options={addressOptions}
placeholder="请选择地址"
onChange={(value) => handleAddressChange(value, record)}
@ -608,7 +610,7 @@ export const BankAccountSection: React.FC<CommonFormSectionsProps> = ({ form, su
});
},
}}
/>
/> */}
</Form.Item>
</>
),

View File

@ -53,7 +53,7 @@ const ForeignForm: React.FC<ForeignFormProps> = ({
}
});
getregionInternational().then((res) => {
getregionInternational({ pId: 0 }).then((res) => {
if (res.code === 200) {
setRegionOptions(res.data);
}

View File

@ -28,11 +28,13 @@ export async function getRegionTree(){
method: 'GET',
})
}
// 获取全球
export async function getregionInternational(){
return request('/api/cosco/dictRegion/regionInternational', {
interface getregionInternationalParams {
pId: string | number;
}
export async function getregionInternational(params:getregionInternationalParams){
return request('/api/v1/dictRegionInternational/getChild', {
method: 'GET',
params
})
}
export async function getAllAreaList(){