From 9334290fd6005e3f5467f0f611492268a4a8851a Mon Sep 17 00:00:00 2001 From: lapuda <577732344@qq.com> Date: Mon, 20 Jul 2026 11:30:22 +0800 Subject: [PATCH] feat: Add salary composition, welfare benefits, and work schedule fields to Job model and database --- .../main/java/com/ruoyi/cms/domain/Job.java | 12 ++ .../main/resources/mapper/app/JobMapper.xml | 11 +- .../ruoyi/cms/domain/JobDetailTagsTest.java | 33 ++++++ ...igration_add_job_compensation_benefits.sql | 106 ++++++++++++++++++ 4 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 ruoyi-bussiness/src/test/java/com/ruoyi/cms/domain/JobDetailTagsTest.java create mode 100644 sql/migration_add_job_compensation_benefits.sql diff --git a/ruoyi-bussiness/src/main/java/com/ruoyi/cms/domain/Job.java b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/domain/Job.java index 32a3141..4fbf8a8 100644 --- a/ruoyi-bussiness/src/main/java/com/ruoyi/cms/domain/Job.java +++ b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/domain/Job.java @@ -48,6 +48,18 @@ public class Job extends BaseEntity @ApiModelProperty("最大薪资(元)") private Long maxSalary; + @Excel(name = "薪资范围与构成") + @ApiModelProperty("薪资范围与构成(薪资数值范围使用 minSalary/maxSalary),对应业务字典 salary_composition,多项及手动输入值以英文逗号分隔") + private String salaryComposition; + + @Excel(name = "福利待遇") + @ApiModelProperty("福利待遇,对应业务字典 welfare_benefits,多项及手动输入值以英文逗号分隔") + private String welfareBenefits; + + @Excel(name = "工作时间安排") + @ApiModelProperty("工作时间安排,对应业务字典 work_schedule,多项及手动输入值以英文逗号分隔") + private String workSchedule; + @TableField(exist = false) private Long salaryMin; diff --git a/ruoyi-bussiness/src/main/resources/mapper/app/JobMapper.xml b/ruoyi-bussiness/src/main/resources/mapper/app/JobMapper.xml index 913d525..568329f 100644 --- a/ruoyi-bussiness/src/main/resources/mapper/app/JobMapper.xml +++ b/ruoyi-bussiness/src/main/resources/mapper/app/JobMapper.xml @@ -9,6 +9,9 @@ + + + @@ -113,7 +116,13 @@ - select job_id, job_title, min_salary, max_salary, education, experience, company_name, job_location, posting_date, vacancies, del_flag, create_by, create_time, update_by, update_time, remark, latitude, longitude, "view", company_id , is_hot ,is_urgent,apply_num,is_publish, description,job_location_area_code,data_source,job_url,job_category,is_explain,explain_url,cover,job_type,job_address, review_status,is_key_populations,key_populations from job + select job_id, job_title, min_salary, max_salary, salary_composition, welfare_benefits, + work_schedule, education, experience, company_name, job_location, posting_date, vacancies, + del_flag, create_by, create_time, update_by, update_time, remark, latitude, longitude, "view", + company_id, is_hot, is_urgent, apply_num, is_publish, description, job_location_area_code, + data_source, job_url, job_category, is_explain, explain_url, cover, job_type, job_address, + review_status, is_key_populations, key_populations + from job INSERT INTO row_work ( diff --git a/ruoyi-bussiness/src/test/java/com/ruoyi/cms/domain/JobDetailTagsTest.java b/ruoyi-bussiness/src/test/java/com/ruoyi/cms/domain/JobDetailTagsTest.java new file mode 100644 index 0000000..7420ce8 --- /dev/null +++ b/ruoyi-bussiness/src/test/java/com/ruoyi/cms/domain/JobDetailTagsTest.java @@ -0,0 +1,33 @@ +package com.ruoyi.cms.domain; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class JobDetailTagsTest +{ + private final ObjectMapper objectMapper = new ObjectMapper(); + + @Test + void detailTagsRoundTripAsCommaSeparatedStrings() throws Exception + { + String requestJson = "{" + + "\"salaryComposition\":\"基本工资,绩效工资,项目提成\"," + + "\"welfareBenefits\":\"五险一金,带薪年假,生日福利\"," + + "\"workSchedule\":\"早10点-下午7点,午休2小时,周末双休\"" + + "}"; + + Job job = objectMapper.readValue(requestJson, Job.class); + + assertEquals("基本工资,绩效工资,项目提成", job.getSalaryComposition()); + assertEquals("五险一金,带薪年假,生日福利", job.getWelfareBenefits()); + assertEquals("早10点-下午7点,午休2小时,周末双休", job.getWorkSchedule()); + + JsonNode responseJson = objectMapper.readTree(objectMapper.writeValueAsString(job)); + assertEquals("基本工资,绩效工资,项目提成", responseJson.get("salaryComposition").asText()); + assertEquals("五险一金,带薪年假,生日福利", responseJson.get("welfareBenefits").asText()); + assertEquals("早10点-下午7点,午休2小时,周末双休", responseJson.get("workSchedule").asText()); + } +} diff --git a/sql/migration_add_job_compensation_benefits.sql b/sql/migration_add_job_compensation_benefits.sql new file mode 100644 index 0000000..2885dcb --- /dev/null +++ b/sql/migration_add_job_compensation_benefits.sql @@ -0,0 +1,106 @@ +-- 岗位薪资构成、福利待遇、工作时间安排字段及业务字典初始化。 +-- 执行目标:对应环境 HighGo 数据库的 shz schema。 +-- 可重复执行:字段使用 IF NOT EXISTS,字典类型和字典项分别按 dict_type、dict_value 去重。 + +BEGIN; + +ALTER TABLE "shz"."job" + ADD COLUMN IF NOT EXISTS "salary_composition" VARCHAR(1000), + ADD COLUMN IF NOT EXISTS "welfare_benefits" VARCHAR(1000), + ADD COLUMN IF NOT EXISTS "work_schedule" VARCHAR(1000); + +COMMENT ON COLUMN "shz"."job"."salary_composition" + IS '薪资范围与构成(数值范围使用 min_salary/max_salary),多项及手动输入值以英文逗号分隔,对应业务字典 salary_composition'; +COMMENT ON COLUMN "shz"."job"."welfare_benefits" + IS '福利待遇,多项及手动输入值以英文逗号分隔,对应业务字典 welfare_benefits'; +COMMENT ON COLUMN "shz"."job"."work_schedule" + IS '工作时间安排,多项及手动输入值以英文逗号分隔,对应业务字典 work_schedule'; + +WITH seed("dict_sort", "dict_name", "dict_type", "remark") AS ( + VALUES + (1, '薪资范围与构成', 'salary_composition', '岗位薪资范围与构成,可与手动输入值组合使用'), + (2, '福利待遇', 'welfare_benefits', '岗位福利待遇,可与手动输入值组合使用'), + (3, '工作时间安排', 'work_schedule', '岗位工作时间安排,可与手动输入值组合使用') +), +new_rows AS ( + SELECT + ROW_NUMBER() OVER (ORDER BY seed."dict_sort") AS rn, + seed.* + FROM seed + WHERE NOT EXISTS ( + SELECT 1 + FROM "shz"."bussiness_dict_type" existing_type + WHERE existing_type."dict_type" = seed."dict_type" + ) +), +base AS ( + SELECT COALESCE(MAX("dict_id"), 0) AS max_id + FROM "shz"."bussiness_dict_type" +) +INSERT INTO "shz"."bussiness_dict_type" ( + "dict_id", "dict_name", "dict_type", "status", "create_by", "create_time", "remark" +) +SELECT + base.max_id + new_rows.rn, + new_rows."dict_name", + new_rows."dict_type", + '0', + 'system', + CURRENT_TIMESTAMP, + new_rows."remark" +FROM new_rows +CROSS JOIN base; + +WITH seed("dict_type", "dict_sort", "dict_label", "dict_value") AS ( + VALUES + ('salary_composition', 1, '基本工资', '基本工资'), + ('salary_composition', 2, '绩效工资', '绩效工资'), + ('salary_composition', 3, '奖金', '奖金'), + ('welfare_benefits', 1, '五险一金', '五险一金'), + ('welfare_benefits', 2, '带薪年假', '带薪年假'), + ('welfare_benefits', 3, '节日福利', '节日福利'), + ('welfare_benefits', 4, '定期体检', '定期体检'), + ('welfare_benefits', 5, '培训机会', '培训机会'), + ('welfare_benefits', 6, '员工团建', '员工团建'), + ('welfare_benefits', 7, '餐补', '餐补'), + ('welfare_benefits', 8, '房补', '房补'), + ('work_schedule', 1, '早10点-下午7点', '早10点-下午7点'), + ('work_schedule', 2, '午休2小时', '午休2小时') +), +new_rows AS ( + SELECT + ROW_NUMBER() OVER (ORDER BY seed."dict_type", seed."dict_sort") AS rn, + seed.* + FROM seed + WHERE NOT EXISTS ( + SELECT 1 + FROM "shz"."bussiness_dict_data" data + WHERE data."dict_type" = seed."dict_type" + AND data."dict_value" = seed."dict_value" + ) +), +base AS ( + SELECT COALESCE(MAX("dict_code"), 0) AS max_code + FROM "shz"."bussiness_dict_data" +) +INSERT INTO "shz"."bussiness_dict_data" ( + "dict_code", "dict_sort", "dict_label", "dict_value", "dict_type", + "css_class", "list_class", "is_default", "status", "create_by", "create_time", "remark" +) +SELECT + base.max_code + new_rows.rn, + new_rows."dict_sort", + new_rows."dict_label", + new_rows."dict_value", + new_rows."dict_type", + NULL, + 'default', + 'N', + '0', + 'system', + CURRENT_TIMESTAMP, + '岗位详情标签' +FROM new_rows +CROSS JOIN base; + +COMMIT;