建立生成器功能
Some checks failed
Node CI / build (14.x, macOS-latest) (push) Has been cancelled
Node CI / build (14.x, ubuntu-latest) (push) Has been cancelled
Node CI / build (14.x, windows-latest) (push) Has been cancelled
Node CI / build (16.x, macOS-latest) (push) Has been cancelled
Node CI / build (16.x, ubuntu-latest) (push) Has been cancelled
Node CI / build (16.x, windows-latest) (push) Has been cancelled
coverage CI / build (push) Has been cancelled
Node pnpm CI / build (16.x, macOS-latest) (push) Has been cancelled
Node pnpm CI / build (16.x, ubuntu-latest) (push) Has been cancelled
Node pnpm CI / build (16.x, windows-latest) (push) Has been cancelled
Some checks failed
Node CI / build (14.x, macOS-latest) (push) Has been cancelled
Node CI / build (14.x, ubuntu-latest) (push) Has been cancelled
Node CI / build (14.x, windows-latest) (push) Has been cancelled
Node CI / build (16.x, macOS-latest) (push) Has been cancelled
Node CI / build (16.x, ubuntu-latest) (push) Has been cancelled
Node CI / build (16.x, windows-latest) (push) Has been cancelled
coverage CI / build (push) Has been cancelled
Node pnpm CI / build (16.x, macOS-latest) (push) Has been cancelled
Node pnpm CI / build (16.x, ubuntu-latest) (push) Has been cancelled
Node pnpm CI / build (16.x, windows-latest) (push) Has been cancelled
This commit is contained in:
@@ -6,6 +6,7 @@ import { PlusOutlined, SendOutlined, StarOutlined, StarFilled, FileTextOutlined
|
||||
import { getDictValueEnum } from '@/services/system/dict';
|
||||
import DictTag from '@/components/DictTag';
|
||||
import { applyAgree, delHrTalentCollect, exportCmsAppUserExport, getCmsAppUserList, getHrTalentCollectList } from '@/services/mobileusers/list';
|
||||
import { getJobTitleTreeSelect } from '@/services/common/jobTitle';
|
||||
import InterviewInvite from '@/pages/Management/List/ResumeRecommend/InterviewInvite';
|
||||
import CollectTalent from './CollectTalent';
|
||||
|
||||
@@ -36,6 +37,8 @@ function ManagementList() {
|
||||
const [sexEnum, setSexEnum] = useState<any>([]);
|
||||
const [hotEnum, setHotEnum] = useState<any>([]);
|
||||
const [politicalEnum, setPoliticalEnum] = useState<any>([]);
|
||||
const [nationEnum, setNationEnum] = useState<any>([]);
|
||||
const [userTypeEnum, setUserTypeEnum] = useState<any>([]);
|
||||
const [currentRow, setCurrentRow] = useState<API.MobileUser.ListRow>();
|
||||
const [modalVisible, setModalVisible] = useState<boolean>(false);
|
||||
const [inviteVisible, setInviteVisible] = useState<boolean>(false);
|
||||
@@ -62,6 +65,12 @@ function ManagementList() {
|
||||
getDictValueEnum('is_publish', true).then((data) => {
|
||||
setIsPublishEnum(data);
|
||||
});
|
||||
getDictValueEnum('nation', false, true).then((data) => {
|
||||
setNationEnum(data);
|
||||
});
|
||||
getDictValueEnum('user_type', false, true).then((data) => {
|
||||
setUserTypeEnum(data);
|
||||
});
|
||||
// getDictValueEnum('job_hot',true).then((data) => {
|
||||
// setHotEnum(data)
|
||||
// })
|
||||
@@ -145,6 +154,25 @@ function ManagementList() {
|
||||
valueType: 'text',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '求职期望',
|
||||
dataIndex: 'jobTitleId',
|
||||
valueType: 'treeSelect',
|
||||
hideInTable: true,
|
||||
width: 240,
|
||||
fieldProps: {
|
||||
showSearch: true,
|
||||
filterTreeNode: (input: string, node: any) => node.label?.includes(input),
|
||||
treeNodeFilterProp: 'label',
|
||||
placeholder: '请选择求职期望',
|
||||
style: { width: 240 },
|
||||
fieldNames: { label: 'label', value: 'id', children: 'children' },
|
||||
},
|
||||
request: async () => {
|
||||
const res = await getJobTitleTreeSelect();
|
||||
return res?.data || [];
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '期望薪资',
|
||||
dataIndex: 'minSalary',
|
||||
@@ -166,6 +194,57 @@ function ManagementList() {
|
||||
format: 'YYYY-MM-DD',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '年龄',
|
||||
dataIndex: 'age',
|
||||
valueType: 'text',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '毕业院校',
|
||||
dataIndex: 'schoolName',
|
||||
valueType: 'text',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '毕业时间',
|
||||
dataIndex: 'endTime',
|
||||
valueType: 'date',
|
||||
align: 'center',
|
||||
fieldProps: {
|
||||
format: 'YYYY-MM-DD',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '民族',
|
||||
dataIndex: 'nation',
|
||||
valueType: 'select',
|
||||
align: 'center',
|
||||
valueEnum: nationEnum,
|
||||
render: (_, record) => {
|
||||
return <DictTag enums={nationEnum} value={record.nation} />;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '个人标签',
|
||||
dataIndex: 'userType',
|
||||
valueType: 'select',
|
||||
align: 'center',
|
||||
valueEnum: userTypeEnum,
|
||||
render: (_, record) => {
|
||||
return <DictTag enums={userTypeEnum} value={record.userType} />;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '工作经验',
|
||||
dataIndex: 'workExperience',
|
||||
valueType: 'select',
|
||||
align: 'center',
|
||||
valueEnum: experienceEnum,
|
||||
render: (_, record) => {
|
||||
return <DictTag enums={experienceEnum} value={record.workExperience} />;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '学历要求',
|
||||
dataIndex: 'education',
|
||||
@@ -302,6 +381,7 @@ function ManagementList() {
|
||||
rowKey="applyId"
|
||||
key="index"
|
||||
columns={columns}
|
||||
search={{ defaultCollapsed: false }}
|
||||
request={(params) => {
|
||||
const { current, pageSize, ...searchParams } = params;
|
||||
// 过滤空值,避免空字符串干扰后端查询
|
||||
|
||||
@@ -23,6 +23,8 @@ function AppUserList() {
|
||||
const [areaEnum, setAreaEnum] = useState<Record<string, any>>({});
|
||||
const [politicalEnum, setPoliticalEnum] = useState<Record<string, any>>({});
|
||||
const [nationEnum, setNationEnum] = useState<Record<string, any>>({});
|
||||
const [userTypeEnum, setUserTypeEnum] = useState<Record<string, any>>({});
|
||||
const [workExperienceEnum, setWorkExperienceEnum] = useState<Record<string, any>>({});
|
||||
|
||||
/** 修改身份证 Modal 状态 */
|
||||
const [idCardModalOpen, setIdCardModalOpen] = useState(false);
|
||||
@@ -40,6 +42,8 @@ function AppUserList() {
|
||||
getDictValueEnum('area', true, true).then(setAreaEnum);
|
||||
getDictValueEnum('political_affiliation', true, true).then(setPoliticalEnum);
|
||||
getDictValueEnum('nation', false, true).then(setNationEnum);
|
||||
getDictValueEnum('user_type', false, true).then(setUserTypeEnum);
|
||||
getDictValueEnum('experience', false, true).then(setWorkExperienceEnum);
|
||||
}, []);
|
||||
|
||||
const columns: ProColumns<API.CmsAppUser.AppUserRow>[] = [
|
||||
@@ -80,7 +84,14 @@ function AppUserList() {
|
||||
valueType: 'text',
|
||||
align: 'center',
|
||||
width: 70,
|
||||
hideInSearch: true,
|
||||
},
|
||||
{
|
||||
title: '出生年月',
|
||||
dataIndex: 'birthDate',
|
||||
valueType: 'date',
|
||||
align: 'center',
|
||||
width: 120,
|
||||
fieldProps: { format: 'YYYY-MM-DD' },
|
||||
},
|
||||
{
|
||||
title: '学历',
|
||||
@@ -91,6 +102,21 @@ function AppUserList() {
|
||||
valueEnum: educationEnum,
|
||||
render: (_, record) => <DictTag enums={educationEnum} value={record.education} />,
|
||||
},
|
||||
{
|
||||
title: '毕业院校',
|
||||
dataIndex: 'schoolName',
|
||||
valueType: 'text',
|
||||
align: 'center',
|
||||
width: 160,
|
||||
},
|
||||
{
|
||||
title: '毕业时间',
|
||||
dataIndex: 'endTime',
|
||||
valueType: 'date',
|
||||
align: 'center',
|
||||
width: 120,
|
||||
fieldProps: { format: 'YYYY-MM-DD' },
|
||||
},
|
||||
{
|
||||
title: '地区',
|
||||
dataIndex: 'area',
|
||||
@@ -118,6 +144,24 @@ function AppUserList() {
|
||||
valueEnum: nationEnum,
|
||||
render: (_, record) => <DictTag enums={nationEnum} value={record.nation ?? undefined} />,
|
||||
},
|
||||
{
|
||||
title: '个人标签',
|
||||
dataIndex: 'userType',
|
||||
valueType: 'select',
|
||||
align: 'center',
|
||||
width: 110,
|
||||
valueEnum: userTypeEnum,
|
||||
render: (_, record) => <DictTag enums={userTypeEnum} value={record.userType ?? undefined} />,
|
||||
},
|
||||
{
|
||||
title: '工作经验',
|
||||
dataIndex: 'workExperience',
|
||||
valueType: 'select',
|
||||
align: 'center',
|
||||
width: 110,
|
||||
valueEnum: workExperienceEnum,
|
||||
render: (_, record) => <DictTag enums={workExperienceEnum} value={record.workExperience ?? undefined} />,
|
||||
},
|
||||
{
|
||||
title: '期望薪资',
|
||||
dataIndex: 'salaryRange',
|
||||
@@ -267,7 +311,7 @@ function AppUserList() {
|
||||
success: true,
|
||||
}));
|
||||
}}
|
||||
search={{ labelWidth: 'auto' }}
|
||||
search={{ labelWidth: 'auto', defaultCollapsed: false }}
|
||||
scroll={{ x: 'max-content' }}
|
||||
pagination={{ defaultPageSize: 10, showSizeChanger: true }}
|
||||
headerTitle="个人用户管理"
|
||||
|
||||
@@ -80,6 +80,22 @@ function toGeneratorFormat(data: API.CmsAppUser.ResumeData, dicts: { sex: DictMa
|
||||
? `${data.salaryMin || ''}${data.salaryMax ? '-' + data.salaryMax : ''}`
|
||||
: '';
|
||||
|
||||
// 将生成器不支持的标准字段放入 customSections,确保用户可见
|
||||
const supplementaryItems: any[] = [];
|
||||
let itemIndex = 0;
|
||||
if (nationLabel) supplementaryItems.push({ id: `sup_${itemIndex++}`, label: '民族', value: nationLabel });
|
||||
if (data.birthDate) supplementaryItems.push({ id: `sup_${itemIndex++}`, label: '出生日期', value: data.birthDate });
|
||||
if (data.age) supplementaryItems.push({ id: `sup_${itemIndex++}`, label: '年龄', value: data.age });
|
||||
if (politicalLabel) supplementaryItems.push({ id: `sup_${itemIndex++}`, label: '政治面貌', value: politicalLabel });
|
||||
if (salaryStr) supplementaryItems.push({ id: `sup_${itemIndex++}`, label: '期望薪资', value: salaryStr });
|
||||
if (data.area) supplementaryItems.push({ id: `sup_${itemIndex++}`, label: '所在区域', value: dicts.area[data.area] || data.area });
|
||||
|
||||
const customSections: any[] = [];
|
||||
if (supplementaryItems.length > 0) {
|
||||
customSections.push({ id: 'supplementary', title: '补充信息', items: supplementaryItems });
|
||||
sections.push({ id: 'supplementary', type: 'customSection', title: '补充信息', hidden: false });
|
||||
}
|
||||
|
||||
return {
|
||||
basics: {
|
||||
name: data.name || '',
|
||||
@@ -87,17 +103,17 @@ function toGeneratorFormat(data: API.CmsAppUser.ResumeData, dicts: { sex: DictMa
|
||||
email: data.email || '',
|
||||
avatarUrl: data.avatar || '',
|
||||
title: data.jobTitle?.[0] || '',
|
||||
ethnicity: nationLabel,
|
||||
birthDate: data.birthDate || '',
|
||||
age: data.age || '',
|
||||
politicalStatus: politicalLabel,
|
||||
expectedPosition: data.jobTitle?.[0] || '',
|
||||
expectedSalary: salaryStr,
|
||||
location: data.area ? (dicts.area[data.area] || data.area) : '',
|
||||
summary: summaryParts.join(' | '),
|
||||
// 以下为自定义扩展字段,生成器 Zod schema 会丢弃,但 save 时从 summary 回读
|
||||
_gender: sexLabel,
|
||||
_educationLevel: educationLabel,
|
||||
_yearsOfExperience: data.workExperience || '',
|
||||
_politicalStatus: politicalLabel,
|
||||
_ethnicity: nationLabel,
|
||||
_age: data.age || '',
|
||||
_birthDate: data.birthDate || '',
|
||||
_expectedSalary: salaryStr,
|
||||
},
|
||||
education,
|
||||
experience,
|
||||
@@ -105,7 +121,7 @@ function toGeneratorFormat(data: API.CmsAppUser.ResumeData, dicts: { sex: DictMa
|
||||
projects: [],
|
||||
skills,
|
||||
certificates: [],
|
||||
customSections: [],
|
||||
customSections,
|
||||
settings: {
|
||||
templateId: 'modern',
|
||||
primaryColor: '#0f766e',
|
||||
@@ -129,6 +145,14 @@ function fromGeneratorFormat(resume: any, dicts: { sex: DictMap; education: Dict
|
||||
} {
|
||||
const basics = resume?.basics || {};
|
||||
|
||||
// 从 customSections 中按 label 查找值(作为 Zod 丢弃字段后的回退方案)
|
||||
const getCustomSectionValue = (label: string): string => {
|
||||
const supSection = (resume?.customSections || []).find((s: any) => s.id === 'supplementary');
|
||||
if (!supSection?.items) return '';
|
||||
const item = supSection.items.find((i: any) => i.label === label);
|
||||
return item?.value || '';
|
||||
};
|
||||
|
||||
// 反向 lookup:汉字 → code
|
||||
const reverseLookup = (map: DictMap, text: string): string => {
|
||||
if (!text) return '';
|
||||
@@ -145,8 +169,11 @@ function fromGeneratorFormat(resume: any, dicts: { sex: DictMap; education: Dict
|
||||
|
||||
// 学历:优先从 _educationLevel,回退到 summary 中的学历标签
|
||||
const educationText = basics._educationLevel || '';
|
||||
const politicalText = basics.politicalStatus || '';
|
||||
const nationText = basics.ethnicity || '';
|
||||
const politicalText = basics._politicalStatus || getCustomSectionValue('政治面貌') || '';
|
||||
const nationText = basics._ethnicity || getCustomSectionValue('民族') || '';
|
||||
const ageText = basics._age || getCustomSectionValue('年龄') || '';
|
||||
const birthDateText = basics._birthDate || getCustomSectionValue('出生日期') || '';
|
||||
const salaryText = basics._expectedSalary || getCustomSectionValue('期望薪资') || '';
|
||||
|
||||
// 工作年限:从 _yearsOfExperience 或 summary 中匹配 "X年工作经验"
|
||||
const yearsFromField = basics._yearsOfExperience || '';
|
||||
@@ -160,13 +187,15 @@ function fromGeneratorFormat(resume: any, dicts: { sex: DictMap; education: Dict
|
||||
email: basics.email || undefined,
|
||||
avatar: basics.avatarUrl || undefined,
|
||||
sex: reverseLookup(dicts.sex, sexFinal) || (sexFinal === '男' ? '0' : sexFinal === '女' ? '1' : '') || undefined,
|
||||
age: basics.age || undefined,
|
||||
birthDate: basics.birthDate || undefined,
|
||||
age: ageText || undefined,
|
||||
birthDate: birthDateText || undefined,
|
||||
education: reverseLookup(dicts.education, educationText) || educationText || undefined,
|
||||
workExperience: workExperienceFinal || undefined,
|
||||
politicalAffiliation: reverseLookup(dicts.political, politicalText) || politicalText || undefined,
|
||||
nation: reverseLookup(dicts.nation, nationText) || nationText || undefined,
|
||||
address: basics.location || undefined,
|
||||
salaryMin: salaryText ? salaryText.split('-')[0] : undefined,
|
||||
salaryMax: salaryText ? salaryText.split('-')[1] : undefined,
|
||||
},
|
||||
appUserEducations: (resume?.education || []).map((e: any) => ({
|
||||
id: e.id ? Number(e.id) : undefined,
|
||||
@@ -278,6 +307,8 @@ function AppUserResume() {
|
||||
} else {
|
||||
console.warn('简历data为空,该用户可能没有简历信息');
|
||||
resumeDataRef.current = null;
|
||||
setResumeData(null);
|
||||
message.info('该用户暂无简历信息,生成器将显示空白模板');
|
||||
}
|
||||
} else {
|
||||
message.error('获取简历数据失败: ' + (res?.msg || '未知错误'));
|
||||
@@ -290,9 +321,11 @@ function AppUserResume() {
|
||||
.finally(() => setLoading(false));
|
||||
}, [userId]);
|
||||
|
||||
// 初始化 iframe-js 通信(独立于数据加载)
|
||||
const initIframe = useCallback(() => {
|
||||
if (!iframeRef.current || hostRef.current) return;
|
||||
// 初始化 iframe-js 通信(通过 ref callback 在 DOM 插入时同步执行,确保监听器在 iframe 加载前就位)
|
||||
const initHost = useCallback((el: HTMLIFrameElement) => {
|
||||
if (!el || hostRef.current) return;
|
||||
|
||||
iframeRef.current = el;
|
||||
|
||||
const generatorUrl = window.location.origin + '/resumegenerator';
|
||||
console.log('[Resume] 开始创建iframe通信,URL:', generatorUrl);
|
||||
@@ -300,7 +333,7 @@ function AppUserResume() {
|
||||
let host;
|
||||
try {
|
||||
host = new Iframe({
|
||||
container: iframeRef.current,
|
||||
container: el,
|
||||
url: generatorUrl,
|
||||
whiteList: [location.origin],
|
||||
timeout: 15000,
|
||||
@@ -373,19 +406,43 @@ function AppUserResume() {
|
||||
}
|
||||
});
|
||||
|
||||
// 超时保护:15秒内未收到 ready 则报错
|
||||
const readyTimeout = setTimeout(() => {
|
||||
if (!hostRef.current) return;
|
||||
console.error('[Resume] 简历生成器加载超时(15秒)');
|
||||
message.error('简历生成器加载失败,请检查网络连接后刷新页面重试');
|
||||
setGeneratorReady(false);
|
||||
}, 15000);
|
||||
|
||||
// 生成器就绪
|
||||
let readyFired = false;
|
||||
host.action('resume:ready', () => {
|
||||
if (readyFired) return; // 防止重复触发
|
||||
readyFired = true;
|
||||
clearTimeout(readyTimeout);
|
||||
|
||||
console.log('[Resume] 简历生成器已就绪');
|
||||
setGeneratorReady(true);
|
||||
// 有数据就加载
|
||||
const data = resumeDataRef.current;
|
||||
if (data) {
|
||||
const genData = toGeneratorFormat(data, dictsRef.current);
|
||||
console.log('加载简历数据到生成器:', genData);
|
||||
host.callRemote('resume:load', { resume: genData }, 8000).catch((err: any) => {
|
||||
console.error('[Resume] resume:load 失败:', err);
|
||||
});
|
||||
}
|
||||
|
||||
// 推送数据到生成器(如果数据已加载)
|
||||
const tryLoadData = (attempts: number = 0) => {
|
||||
const data = resumeDataRef.current;
|
||||
if (data) {
|
||||
const genData = toGeneratorFormat(data, dictsRef.current);
|
||||
console.log('[Resume] 加载简历数据到生成器:', genData);
|
||||
host.callRemote('resume:load', { resume: genData }, 8000).catch((err: any) => {
|
||||
console.error('[Resume] resume:load 失败:', err);
|
||||
message.warning('简历数据加载失败,请点击"重新加载"按钮重试');
|
||||
});
|
||||
} else if (attempts < 20) {
|
||||
// 数据还没加载完,轮询等待(最多 10 秒,每 500ms 一次)
|
||||
setTimeout(() => tryLoadData(attempts + 1), 500);
|
||||
} else {
|
||||
console.warn('[Resume] 等待简历数据超时(10秒),生成器将显示空模板');
|
||||
}
|
||||
};
|
||||
tryLoadData();
|
||||
|
||||
if (readOnly) {
|
||||
host.callRemote('resume:setReadOnly', { readOnly: true }, 8000).catch((err: any) => {
|
||||
console.error('[Resume] resume:setReadOnly 失败:', err);
|
||||
@@ -426,7 +483,7 @@ function AppUserResume() {
|
||||
host.action('resume:change', (event: any) => {
|
||||
console.log('简历内容已更新', event?.data?.resume);
|
||||
});
|
||||
}, [readOnly, userId]);
|
||||
}, []); // 仅在首次挂载时初始化,readOnly 和 userId 通过 ref 获取最新值
|
||||
|
||||
// 当 resumeData 变化且生成器已就绪时,推送新数据到生成器
|
||||
useEffect(() => {
|
||||
@@ -439,22 +496,15 @@ function AppUserResume() {
|
||||
}
|
||||
}, [resumeData, generatorReady]);
|
||||
|
||||
// 页面加载时初始化 iframe
|
||||
// 页面卸载时清理 iframe-js 实例
|
||||
useEffect(() => {
|
||||
// 先清理旧实例
|
||||
if (hostRef.current) {
|
||||
try { hostRef.current.destroy(); } catch (e) {}
|
||||
hostRef.current = null;
|
||||
}
|
||||
console.log('[Resume] useEffect触发 initIframe');
|
||||
initIframe();
|
||||
return () => {
|
||||
if (hostRef.current) {
|
||||
try { hostRef.current.destroy(); } catch (e) {}
|
||||
hostRef.current = null;
|
||||
}
|
||||
};
|
||||
}, []); // 只在 mount 时执行一次
|
||||
}, []);
|
||||
|
||||
// 切换只读模式
|
||||
const toggleReadOnly = async (checked: boolean) => {
|
||||
@@ -511,14 +561,25 @@ function AppUserResume() {
|
||||
</Card>
|
||||
|
||||
{/* 简历生成器 iframe 区域 */}
|
||||
{loading && <div style={{ textAlign: 'center', padding: 20 }}>正在加载简历数据...</div>}
|
||||
<iframe
|
||||
ref={iframeRef}
|
||||
id="resume-generator"
|
||||
title="简历生成器"
|
||||
src="/resumegenerator"
|
||||
style={{ width: '100%', height: 'calc(100vh - 110px)', border: '1px solid #f0f0f0', borderRadius: 4 }}
|
||||
/>
|
||||
<div style={{ position: 'relative', width: '100%', height: 'calc(100vh - 110px)' }}>
|
||||
{loading && (
|
||||
<div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', background: '#fff', zIndex: 1 }}>
|
||||
正在加载简历数据...
|
||||
</div>
|
||||
)}
|
||||
{!generatorReady && !loading && (
|
||||
<div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', background: '#fff', zIndex: 1, color: '#999' }}>
|
||||
正在加载简历生成器...
|
||||
</div>
|
||||
)}
|
||||
<iframe
|
||||
ref={initHost}
|
||||
id="resume-generator"
|
||||
title="简历生成器"
|
||||
src="/resumegenerator"
|
||||
style={{ width: '100%', height: '100%', border: '1px solid #f0f0f0', borderRadius: 4 }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -44,14 +44,16 @@ function patchRouteItems(route: any, menu: any, parentPath: string) {
|
||||
if (path.length > 0) {
|
||||
path += '/';
|
||||
}
|
||||
if (name !== 'index') {
|
||||
path += name.at(0)?.toUpperCase() + name.substr(1);
|
||||
// 不区分大小写判断 "index",避免服务端返回 "Index"(大写I)时在 Linux 上找不到模块
|
||||
// 统一输出小写 "index" 以匹配 webpack 模块注册路径
|
||||
if (name.toLowerCase() === 'index') {
|
||||
path += 'index';
|
||||
} else {
|
||||
path += name;
|
||||
path += name.at(0)?.toUpperCase() + name.substr(1);
|
||||
}
|
||||
})
|
||||
});
|
||||
if (!path.endsWith('.tsx')) {
|
||||
path += '.tsx'
|
||||
path += '.tsx';
|
||||
}
|
||||
if (route.routes === undefined) {
|
||||
route.routes = [];
|
||||
|
||||
9
src/types/cms/appuser.d.ts
vendored
9
src/types/cms/appuser.d.ts
vendored
@@ -38,6 +38,8 @@ declare namespace API.CmsAppUser {
|
||||
unionid: string | null;
|
||||
nation: string | null;
|
||||
workExperience: string | null;
|
||||
schoolName: string | null;
|
||||
endTime: string | null;
|
||||
company: string | null;
|
||||
experiencesList: any;
|
||||
appSkillsList: any;
|
||||
@@ -59,10 +61,17 @@ declare namespace API.CmsAppUser {
|
||||
name?: string;
|
||||
phone?: string;
|
||||
sex?: string;
|
||||
age?: string;
|
||||
birthDate?: string;
|
||||
education?: string;
|
||||
schoolName?: string;
|
||||
endTime?: string;
|
||||
area?: string;
|
||||
status?: string;
|
||||
politicalAffiliation?: string;
|
||||
nation?: string;
|
||||
userType?: string;
|
||||
workExperience?: string;
|
||||
idCard?: string;
|
||||
orderByColumn?: string;
|
||||
isAsc?: string;
|
||||
|
||||
12
src/types/mobileusers/list.d.ts
vendored
12
src/types/mobileusers/list.d.ts
vendored
@@ -33,6 +33,11 @@ declare namespace API.MobileUser {
|
||||
idCard?:string;
|
||||
interviewStatus?: string;
|
||||
interviewId?: number;
|
||||
schoolName?: string;
|
||||
endTime?: string;
|
||||
nation?: string;
|
||||
userType?: string;
|
||||
workExperience?: string;
|
||||
}
|
||||
|
||||
export interface ListParams {
|
||||
@@ -44,5 +49,12 @@ declare namespace API.MobileUser {
|
||||
politicalAffiliation?: string;
|
||||
phone?: string;
|
||||
jobName?: string;
|
||||
jobTitleId?: string;
|
||||
schoolName?: string;
|
||||
endTime?: string;
|
||||
nation?: string;
|
||||
userType?: string;
|
||||
workExperience?: string;
|
||||
area?: string;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user