diff --git a/vetti-admin/src/main/java/com/vetti/web/controller/ai/HotakeAiCommonToolsController.java b/vetti-admin/src/main/java/com/vetti/web/controller/ai/HotakeAiCommonToolsController.java index 664fe99..8c7a112 100644 --- a/vetti-admin/src/main/java/com/vetti/web/controller/ai/HotakeAiCommonToolsController.java +++ b/vetti-admin/src/main/java/com/vetti/web/controller/ai/HotakeAiCommonToolsController.java @@ -6,10 +6,8 @@ import com.vetti.hotake.domain.HotakeInitialScreeningQuestionsInfo; import com.vetti.hotake.domain.dto.HotakeCvOptimizeDto; import com.vetti.hotake.domain.dto.HotakeInitialQuestionEliminationScoreDto; import com.vetti.hotake.domain.dto.HotakeJobDescriptionGeneratorDto; -import com.vetti.hotake.domain.vo.HotakeInitialScreeningQuestionsVo; -import com.vetti.hotake.domain.vo.HotakeJobDescriptionGeneratorVo; -import com.vetti.hotake.domain.vo.HotakeResumeJobMatchingScoreVo; -import com.vetti.hotake.domain.vo.HotakeWebInfoExtractVo; +import com.vetti.hotake.domain.dto.HotakePersonalProfileGeneratorDto; +import com.vetti.hotake.domain.vo.*; import com.vetti.hotake.service.IHotakeAiCommonToolsService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -135,4 +133,14 @@ public class HotakeAiCommonToolsController extends BaseController { return R.ok(); } + /** + * 个人简介生成器 + */ + @ApiOperation("个人简介生成器") + @PostMapping(value = "/personalProfileGenerator") + public R handlePersonalProfileGenerator(@RequestBody HotakePersonalProfileGeneratorVo personalProfileGeneratorVo) + { + return R.ok(hotakeAiCommonToolsService.getPersonalProfileGenerator(personalProfileGeneratorVo)); + } + } diff --git a/vetti-common/src/main/java/com/vetti/common/constant/AiCommonPromptConstants.java b/vetti-common/src/main/java/com/vetti/common/constant/AiCommonPromptConstants.java index d7775ae..34e93a2 100644 --- a/vetti-common/src/main/java/com/vetti/common/constant/AiCommonPromptConstants.java +++ b/vetti-common/src/main/java/com/vetti/common/constant/AiCommonPromptConstants.java @@ -1247,4 +1247,277 @@ public class AiCommonPromptConstants { return promptStr; } + + + /** + * 初始化生个人简介生成器提示词 + * @return + */ + public static String initializationPersonalProfileGeneratorPrompt(){ + String promptStr = "You are a professional resume writing expert specializing in creating personal summaries for candidates in traditional industries including construction, logistics, manufacturing, hospitality, and mining.\n" + + "\n" + + "## Core Task\n" + + "Generate a professional and compelling personal summary based on the candidate's basic information to enrich and enhance the personal profile section of their resume.\n" + + "\n" + + "## Input Information Fields\n" + + "- **Full Name**: Candidate's full name\n" + + "- **Birthday**: Date of birth (used to estimate work experience and seniority level)\n" + + "- **Job Position**: Target position or current position\n" + + "- **Location**: Geographic location\n" + + "- **Email**: Email address\n" + + "- **Phone Number**: Contact phone number\n" + + "- **LinkedIn**: LinkedIn profile URL\n" + + "- **Website**: Personal website or portfolio URL\n" + + "\n" + + "## Generation Principles\n" + + "\n" + + "### 1. Professionalism Principle\n" + + "- Use industry-specific terminology and keywords\n" + + "- Highlight core competencies relevant to the target position\n" + + "- Demonstrate professional expertise and work attitude\n" + + "\n" + + "### 2. Personalization Principle\n" + + "- Adapt expression style based on regional characteristics\n" + + "- Combine age to estimate reasonable experience levels\n" + + "- Reflect the candidate's unique value proposition\n" + + "\n" + + "### 3. Appeal Principle\n" + + "- Create an engaging opening that highlights core strengths\n" + + "- Use positive and proactive language\n" + + "- Avoid empty adjectives, focus on specific descriptions\n" + + "\n" + + "### 4. Conciseness Principle\n" + + "- Keep within 80-120 words\n" + + "- High information density with every sentence adding value\n" + + "- Avoid redundancy and repetitive expressions\n" + + "\n" + + "## Traditional Industry Focus\n" + + "\n" + + "### Construction Industry Highlights\n" + + "- Emphasize project management and on-site experience\n" + + "- Highlight safety awareness and compliance capabilities\n" + + "- Demonstrate teamwork and communication skills\n" + + "- Keywords: project management, site supervision, quality control, safety compliance\n" + + "\n" + + "### Logistics Industry Highlights\n" + + "- Emphasize supply chain management and efficiency optimization\n" + + "- Highlight customer service and cost control\n" + + "- Demonstrate data analysis and process improvement abilities\n" + + "- Keywords: supply chain, transportation management, inventory optimization, customer service\n" + + "\n" + + "### Manufacturing Industry Highlights\n" + + "- Emphasize production management and quality control\n" + + "- Highlight technical skills and equipment operation\n" + + "- Demonstrate continuous improvement and safety awareness\n" + + "- Keywords: production management, quality control, equipment maintenance, process improvement\n" + + "\n" + + "### Hospitality Industry Highlights\n" + + "- Emphasize customer service and team management\n" + + "- Highlight multilingual abilities and cultural adaptability\n" + + "- Demonstrate sales skills and revenue management\n" + + "- Keywords: customer service, team management, multilingual, revenue optimization\n" + + "\n" + + "### Mining Industry Highlights\n" + + "- Emphasize safety operations and environmental protection\n" + + "- Highlight equipment operation and technical skills\n" + + "- Demonstrate teamwork and emergency response\n" + + "- Keywords: safety operations, equipment maintenance, environmental compliance, team collaboration\n" + + "\n" + + "## Regional Considerations\n" + + "\n" + + "### Australia Region\n" + + "- Emphasize multicultural adaptability\n" + + "- Highlight safety and compliance awareness\n" + + "- Demonstrate team collaboration spirit\n" + + "- Use Australian English expressions\n" + + "\n" + + "### China Region\n" + + "- Emphasize learning ability and adaptability\n" + + "- Highlight team spirit and execution capability\n" + + "- Demonstrate innovative thinking and problem-solving skills\n" + + "- Use concise and professional Chinese expressions\n" + + "\n" + + "### Other Regions\n" + + "- Adapt based on local culture and industry characteristics\n" + + "- Consider local workplace culture and expression habits\n" + + "\n" + + "## Age and Experience Estimation\n" + + "\n" + + "### 22-28 years (Graduate-Entry Level)\n" + + "- Emphasize learning ability and development potential\n" + + "- Highlight educational background and internship experience\n" + + "- Demonstrate positive attitude and adaptability\n" + + "\n" + + "### 29-35 years (Mid-Level)\n" + + "- Emphasize professional skills and project experience\n" + + "- Highlight teamwork and problem-solving abilities\n" + + "- Demonstrate career development and growth trajectory\n" + + "\n" + + "### 36-45 years (Senior Level)\n" + + "- Emphasize management experience and leadership abilities\n" + + "- Highlight industry expertise and strategic thinking\n" + + "- Demonstrate mentoring capabilities and business impact\n" + + "\n" + + "### 46+ years (Veteran)\n" + + "- Emphasize extensive experience and industry insights\n" + + "- Highlight mentoring abilities and knowledge transfer\n" + + "- Demonstrate stability and reliability\n" + + "\n" + + "## Output Format\n" + + "\n" + + "Please return results strictly in the following JSON format:\n" + + "\n" + + "```json\n" + + "{\n" + + " \"personal_summary\": {\n" + + " \"generated_text\": \"Generated personal summary text\",\n" + + " \"word_count\": 95,\n" + + " \"language\": \"en-AU|en-US|zh-CN\",\n" + + " \"target_audience\": \"Construction industry recruiters\",\n" + + " \"key_highlights\": [\n" + + " \"Core highlight 1\",\n" + + " \"Core highlight 2\",\n" + + " \"Core highlight 3\"\n" + + " ]\n" + + " },\n" + + " \"generation_analysis\": {\n" + + " \"input_utilization\": {\n" + + " \"name_used\": true,\n" + + " \"age_estimated\": \"29 years old\",\n" + + " \"position_focused\": true,\n" + + " \"location_considered\": true,\n" + + " \"contact_info_relevant\": false\n" + + " },\n" + + " \"industry_adaptation\": {\n" + + " \"target_industry\": \"Construction\",\n" + + " \"keywords_included\": [\"project management\", \"site supervision\", \"quality control\"],\n" + + " \"regional_adaptation\": \"Australian localized expressions\"\n" + + " },\n" + + " \"enhancement_suggestions\": [\n" + + " \"Could add specific project experience data\",\n" + + " \"Recommend supplementing relevant certification information\",\n" + + " \"Could strengthen team management experience description\"\n" + + " ]\n" + + " },\n" + + " \"alternative_versions\": [\n" + + " {\n" + + " \"version_type\": \"Concise\",\n" + + " \"text\": \"More concise version text\",\n" + + " \"word_count\": 75\n" + + " },\n" + + " {\n" + + " \"version_type\": \"Detailed\",\n" + + " \"text\": \"More detailed version text\",\n" + + " \"word_count\": 115\n" + + " }\n" + + " ]\n" + + "}\n" + + "```\n" + + "\n" + + "## Generation Examples\n" + + "\n" + + "### Input Example\n" + + "```\n" + + "Full Name: John Smith\n" + + "Birthday: 1990-05-15\n" + + "Job Position: Project Manager\n" + + "Location: Sydney, Australia\n" + + "Email: johnsmith@email.com\n" + + "Phone: +61 400 123 456\n" + + "LinkedIn: linkedin.com/in/johnsmith\n" + + "Website: None\n" + + "```\n" + + "\n" + + "### Output Example\n" + + "```json\n" + + "{\n" + + " \"personal_summary\": {\n" + + " \"generated_text\": \"Experienced Project Manager with 8+ years in construction industry, specializing in residential and commercial project delivery. Successfully managed multiple large-scale projects in Sydney region with strong cross-cultural team collaboration and client communication skills. Committed to staying current with industry innovations and sustainable building practices, dedicated to creating maximum value for clients through efficient project management.\",\n" + + " \"word_count\": 98,\n" + + " \"language\": \"en-AU\",\n" + + " \"target_audience\": \"Construction industry recruiters\",\n" + + " \"key_highlights\": [\n" + + " \"8+ years project management experience\",\n" + + " \"Sydney local project experience\",\n" + + " \"Cross-cultural team collaboration skills\"\n" + + " ]\n" + + " }\n" + + "}\n" + + "```\n" + + "\n" + + "## Quality Standards\n" + + "\n" + + "- Fluent and natural language with no grammatical errors\n" + + "- Accurate information with clear logic\n" + + "- Highlight core competitive advantages\n" + + "- Align with target industry and regional characteristics\n" + + "- Maintain appropriate word count\n" + + "\n" + + "## Important Notes\n" + + "\n" + + "1. **Privacy Protection**: Do not include contact information directly in the generated summary\n" + + "2. **Authenticity**: Make reasonable inferences based on provided information, avoid exaggeration\n" + + "3. **Targeting**: Adjust focus and expression based on target position\n" + + "4. **Cultural Sensitivity**: Consider cultural differences and expression habits in different regions\n" + + "5. **Keyword Optimization**: Naturally incorporate industry-relevant keywords to improve ATS pass rate\n" + + "\n" + + "## Professional Standards\n" + + "\n" + + "### Language Quality\n" + + "- Grammar accuracy: 100%\n" + + "- Professional terminology usage: Appropriate and accurate\n" + + "- Sentence structure: Varied and engaging\n" + + "- Tone: Professional yet personable\n" + + "\n" + + "### Content Quality\n" + + "- Relevance: Directly related to target position\n" + + "- Specificity: Concrete examples and achievements\n" + + "- Impact: Demonstrates value proposition\n" + + "- Authenticity: Realistic and believable claims\n" + + "\n" + + "### ATS Optimization\n" + + "- Include industry-specific keywords naturally\n" + + "- Use standard job titles and terminology\n" + + "- Maintain proper keyword density (2-3%)\n" + + "- Avoid keyword stuffing\n" + + "\n" + + "### Regional Adaptation\n" + + "- **Australian English**: Use \"ise\" endings, local terminology\n" + + "- **American English**: Use \"ize\" endings, US terminology\n" + + "- **International**: Neutral English suitable for global audience\n" + + "\n" + + "## Industry-Specific Templates\n" + + "\n" + + "### Construction Template Elements\n" + + "- Project scale and complexity\n" + + "- Safety certifications and compliance\n" + + "- Team leadership and coordination\n" + + "- Quality control and delivery metrics\n" + + "\n" + + "### Logistics Template Elements\n" + + "- Supply chain optimization\n" + + "- Cost reduction achievements\n" + + "- Customer satisfaction metrics\n" + + "- Technology and system proficiency\n" + + "\n" + + "### Manufacturing Template Elements\n" + + "- Production efficiency improvements\n" + + "- Quality management systems\n" + + "- Equipment operation expertise\n" + + "- Continuous improvement initiatives\n" + + "\n" + + "### Hospitality Template Elements\n" + + "- Customer service excellence\n" + + "- Revenue generation achievements\n" + + "- Multilingual capabilities\n" + + "- Cultural competency\n" + + "\n" + + "### Mining Template Elements\n" + + "- Safety record and certifications\n" + + "- Equipment operation expertise\n" + + "- Environmental compliance\n" + + "- Emergency response capabilities"; + + return promptStr; + } } diff --git a/vetti-hotakes/src/main/java/com/vetti/hotake/domain/dto/HotakeCvInfoDto.java b/vetti-hotakes/src/main/java/com/vetti/hotake/domain/dto/HotakeCvInfoDto.java index bfdb445..e94dfe1 100644 --- a/vetti-hotakes/src/main/java/com/vetti/hotake/domain/dto/HotakeCvInfoDto.java +++ b/vetti-hotakes/src/main/java/com/vetti/hotake/domain/dto/HotakeCvInfoDto.java @@ -19,6 +19,8 @@ public class HotakeCvInfoDto { @ApiModelProperty("姓名") private String name; + @ApiModelProperty("出生日期") + private String birthday; @ApiModelProperty("电话") private String phone; @ApiModelProperty("邮箱") diff --git a/vetti-hotakes/src/main/java/com/vetti/hotake/domain/dto/HotakePersonalProfileGeneratorDto.java b/vetti-hotakes/src/main/java/com/vetti/hotake/domain/dto/HotakePersonalProfileGeneratorDto.java new file mode 100644 index 0000000..743efbf --- /dev/null +++ b/vetti-hotakes/src/main/java/com/vetti/hotake/domain/dto/HotakePersonalProfileGeneratorDto.java @@ -0,0 +1,19 @@ +package com.vetti.hotake.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 个人简介生成器 返回对象 + * + * @author wangxiangshun + * @date 2025-11-30 + */ +@Data +@Accessors(chain = true) +public class HotakePersonalProfileGeneratorDto { + + @ApiModelProperty("自我介绍") + private String about; +} diff --git a/vetti-hotakes/src/main/java/com/vetti/hotake/domain/dto/VcDto/VcLinksDto.java b/vetti-hotakes/src/main/java/com/vetti/hotake/domain/dto/VcDto/VcLinksDto.java index 759aef7..aaa6ec2 100644 --- a/vetti-hotakes/src/main/java/com/vetti/hotake/domain/dto/VcDto/VcLinksDto.java +++ b/vetti-hotakes/src/main/java/com/vetti/hotake/domain/dto/VcDto/VcLinksDto.java @@ -16,4 +16,7 @@ public class VcLinksDto { @ApiModelProperty("内容") private String content; + + @ApiModelProperty("类型(例如:LinkedIn,Website)") + private String dataType; } diff --git a/vetti-hotakes/src/main/java/com/vetti/hotake/domain/vo/HotakePersonalProfileGeneratorVo.java b/vetti-hotakes/src/main/java/com/vetti/hotake/domain/vo/HotakePersonalProfileGeneratorVo.java new file mode 100644 index 0000000..4800c19 --- /dev/null +++ b/vetti-hotakes/src/main/java/com/vetti/hotake/domain/vo/HotakePersonalProfileGeneratorVo.java @@ -0,0 +1,35 @@ +package com.vetti.hotake.domain.vo; + +import com.vetti.hotake.domain.dto.VcDto.VcLinksDto; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.List; + +/** + * 个人简介生成器 对象 + * + * @author wangxiangshun + * @date 2025-12-14 + */ +@Data +@Accessors(chain = true) +public class HotakePersonalProfileGeneratorVo { + + @ApiModelProperty("姓名") + private String name; + @ApiModelProperty("出生日期") + private String birthday; + @ApiModelProperty("电话") + private String phone; + @ApiModelProperty("邮箱") + private String email; + @ApiModelProperty("岗位") + private String position; + @ApiModelProperty("地点") + private String location; + @ApiModelProperty("链接对象集合") + private List links; + +} diff --git a/vetti-hotakes/src/main/java/com/vetti/hotake/service/IHotakeAiCommonToolsService.java b/vetti-hotakes/src/main/java/com/vetti/hotake/service/IHotakeAiCommonToolsService.java index 254e636..2e4b944 100644 --- a/vetti-hotakes/src/main/java/com/vetti/hotake/service/IHotakeAiCommonToolsService.java +++ b/vetti-hotakes/src/main/java/com/vetti/hotake/service/IHotakeAiCommonToolsService.java @@ -5,10 +5,8 @@ import com.vetti.hotake.domain.HotakeInitialScreeningQuestionsInfo; import com.vetti.hotake.domain.dto.HotakeCvOptimizeDto; import com.vetti.hotake.domain.dto.HotakeInitialQuestionEliminationScoreDto; import com.vetti.hotake.domain.dto.HotakeJobDescriptionGeneratorDto; -import com.vetti.hotake.domain.vo.HotakeInitialQuestionEliminationScoreVo; -import com.vetti.hotake.domain.vo.HotakeInitialScreeningQuestionsVo; -import com.vetti.hotake.domain.vo.HotakeResumeJobMatchingScoreVo; -import com.vetti.hotake.domain.vo.HotakeWebInfoExtractVo; +import com.vetti.hotake.domain.dto.HotakePersonalProfileGeneratorDto; +import com.vetti.hotake.domain.vo.*; import java.util.List; @@ -92,6 +90,12 @@ public interface IHotakeAiCommonToolsService { public String handleWebInfoEnhancedProcessing(String webContent); + /** + * 个人简介生成器 + * @param personalProfileGeneratorVo 个人信息 + * @return + */ + public HotakePersonalProfileGeneratorDto getPersonalProfileGenerator(HotakePersonalProfileGeneratorVo personalProfileGeneratorVo); } diff --git a/vetti-hotakes/src/main/java/com/vetti/hotake/service/impl/HotakeAiCommonToolsServiceImpl.java b/vetti-hotakes/src/main/java/com/vetti/hotake/service/impl/HotakeAiCommonToolsServiceImpl.java index ef6018d..a021e3c 100644 --- a/vetti-hotakes/src/main/java/com/vetti/hotake/service/impl/HotakeAiCommonToolsServiceImpl.java +++ b/vetti-hotakes/src/main/java/com/vetti/hotake/service/impl/HotakeAiCommonToolsServiceImpl.java @@ -11,25 +11,18 @@ import com.vetti.common.utils.html.ReadHtmlByOkHttp; import com.vetti.hotake.domain.HotakeInitScreQuestionsReplyRecordInfo; import com.vetti.hotake.domain.HotakeInitialScreeningQuestionsInfo; import com.vetti.hotake.domain.HotakeRolesInfo; -import com.vetti.hotake.domain.dto.AnswerOptionsDto; -import com.vetti.hotake.domain.dto.HotakeCvOptimizeDto; -import com.vetti.hotake.domain.dto.HotakeInitialQuestionEliminationScoreDto; -import com.vetti.hotake.domain.dto.HotakeJobDescriptionGeneratorDto; +import com.vetti.hotake.domain.dto.*; import com.vetti.hotake.domain.dto.VcDto.*; import com.vetti.hotake.domain.dto.roleDto.NiceToHaveSkillsDto; import com.vetti.hotake.domain.dto.roleDto.RequiredSkillsDto; import com.vetti.hotake.domain.dto.roleDto.ResponsibilitiesDto; -import com.vetti.hotake.domain.vo.HotakeInitialQuestionEliminationScoreVo; -import com.vetti.hotake.domain.vo.HotakeInitialScreeningQuestionsVo; -import com.vetti.hotake.domain.vo.HotakeResumeJobMatchingScoreVo; -import com.vetti.hotake.domain.vo.HotakeWebInfoExtractVo; +import com.vetti.hotake.domain.vo.*; import com.vetti.hotake.mapper.HotakeInitialScreeningQuestionsInfoMapper; import com.vetti.hotake.mapper.HotakeRolesApplyInfoMapper; import com.vetti.hotake.mapper.HotakeRolesInfoMapper; import com.vetti.hotake.service.IHotakeAiCommonToolsService; import com.vetti.system.mapper.SysUserMapper; import lombok.extern.slf4j.Slf4j; -import org.apache.catalina.security.SecurityUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -644,5 +637,54 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I return resultJson; } + /** + * 个人简介生成器 + * @param personalProfileGeneratorVo 个人信息 + * @return + */ + @Override + public HotakePersonalProfileGeneratorDto getPersonalProfileGenerator(HotakePersonalProfileGeneratorVo personalProfileGeneratorVo) { + String prompt = AiCommonPromptConstants.initializationPersonalProfileGeneratorPrompt(); + + String linedIn = ""; + String website = ""; + if(CollectionUtil.isNotEmpty(personalProfileGeneratorVo.getLinks())){ + List linedInList = personalProfileGeneratorVo.getLinks().stream().filter(e->"LinkedIn".equals(e.getDataType())).toList(); + if(CollectionUtil.isNotEmpty(linedInList)){ + linedIn = linedInList.get(0).getContent(); + } + List websiteList = personalProfileGeneratorVo.getLinks().stream().filter(e->"Website".equals(e.getDataType())).toList(); + + if(CollectionUtil.isNotEmpty(websiteList)){ + website = websiteList.get(0).getContent(); + } + } + String candidateText = " Full Name: "+personalProfileGeneratorVo.getName()+" Birthday: "+personalProfileGeneratorVo.getBirthday()+" Job Position: "+personalProfileGeneratorVo.getPosition() + +"Location: "+personalProfileGeneratorVo.getLocation()+" Email: "+personalProfileGeneratorVo.getEmail()+" Phone Number: "+personalProfileGeneratorVo.getPhone() + +"LinkedIn: "+linedIn+" Website: "+website; + + String userPrompt = "Please generate a professional personal summary based on the following candidate information:\\n\\n"+candidateText; + List> list = new LinkedList(); + Map mapEntity = new HashMap<>(); + mapEntity.put("role", "system"); + mapEntity.put("content",prompt); + list.add(mapEntity); + Map mapUserEntity = new HashMap<>(); + mapUserEntity.put("role", "user"); + mapUserEntity.put("content",userPrompt); + list.add(mapUserEntity); + String promptJson = JSONUtil.toJsonStr(list); + String resultStr = chatGPTClient.handleAiChat(promptJson,"WEBAITQ"); + String resultJson = resultStr.replaceAll("```json","").replaceAll("```",""); + log.info("个人简介生成器:{}",resultJson); + + Map dataMap = JSONUtil.toBean(resultJson,Map.class); + HotakePersonalProfileGeneratorDto generatorDto = new HotakePersonalProfileGeneratorDto(); + + Map personalSummaryMap = (Map)dataMap.get("personal_summary"); + generatorDto.setAbout(personalSummaryMap.get("generated_text").toString()); + return generatorDto; + } + }