Merge branch 'claude/sweet-swanson-772e08'
This commit is contained in:
@@ -37,8 +37,9 @@ public class OaAiReviewController extends BaseController {
|
|||||||
@PostMapping(value = "/analyze", consumes = "multipart/form-data")
|
@PostMapping(value = "/analyze", consumes = "multipart/form-data")
|
||||||
public R<OaAiReviewVo> analyze(@RequestParam("file") MultipartFile file,
|
public R<OaAiReviewVo> analyze(@RequestParam("file") MultipartFile file,
|
||||||
@RequestParam("reviewType") String reviewType,
|
@RequestParam("reviewType") String reviewType,
|
||||||
@RequestParam(value = "position", required = false) String position) {
|
@RequestParam(value = "position", required = false) String position,
|
||||||
return R.ok("审核完成", service.analyze(file, reviewType, position));
|
@RequestParam(value = "requirements", required = false) String requirements) {
|
||||||
|
return R.ok("审核完成", service.analyze(file, reviewType, position, requirements));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -48,8 +49,9 @@ public class OaAiReviewController extends BaseController {
|
|||||||
@PostMapping(value = "/analyzeStream", consumes = "multipart/form-data", produces = "text/event-stream;charset=UTF-8")
|
@PostMapping(value = "/analyzeStream", consumes = "multipart/form-data", produces = "text/event-stream;charset=UTF-8")
|
||||||
public SseEmitter analyzeStream(@RequestParam("file") MultipartFile file,
|
public SseEmitter analyzeStream(@RequestParam("file") MultipartFile file,
|
||||||
@RequestParam("reviewType") String reviewType,
|
@RequestParam("reviewType") String reviewType,
|
||||||
@RequestParam(value = "position", required = false) String position) {
|
@RequestParam(value = "position", required = false) String position,
|
||||||
return service.analyzeStream(file, reviewType, position);
|
@RequestParam(value = "requirements", required = false) String requirements) {
|
||||||
|
return service.analyzeStream(file, reviewType, position, requirements);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
@@ -57,7 +59,8 @@ public class OaAiReviewController extends BaseController {
|
|||||||
return service.queryPageList(bo, pageQuery);
|
return service.queryPageList(bo, pageQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/{id}")
|
// 限定为数字,避免 /analyzeStream 等子路径被 {id} 误匹配(否则 POST 会得到 405)
|
||||||
|
@GetMapping("/{id:\\d+}")
|
||||||
public R<OaAiReviewVo> getInfo(@NotNull @PathVariable Long id) {
|
public R<OaAiReviewVo> getInfo(@NotNull @PathVariable Long id) {
|
||||||
return R.ok(service.queryById(id));
|
return R.ok(service.queryById(id));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,9 @@ public class OaAiReview extends BaseEntity {
|
|||||||
/** 简历审核的目标岗位 */
|
/** 简历审核的目标岗位 */
|
||||||
private String position;
|
private String position;
|
||||||
|
|
||||||
|
/** 本次审核的附加要求/审核重点 */
|
||||||
|
private String requirements;
|
||||||
|
|
||||||
/** 简历匹配度评分 0-100(合同为空) */
|
/** 简历匹配度评分 0-100(合同为空) */
|
||||||
private Integer matchScore;
|
private Integer matchScore;
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ public class OaAiReviewVo implements Serializable {
|
|||||||
private Long ossId;
|
private Long ossId;
|
||||||
private String fileUrl;
|
private String fileUrl;
|
||||||
private String position;
|
private String position;
|
||||||
|
private String requirements;
|
||||||
private Integer matchScore;
|
private Integer matchScore;
|
||||||
private String riskLevel;
|
private String riskLevel;
|
||||||
private String summary;
|
private String summary;
|
||||||
|
|||||||
@@ -14,16 +14,17 @@ public interface IOaAiReviewService {
|
|||||||
/**
|
/**
|
||||||
* 上传合同/简历并进行 AI 审核,落库并返回结果
|
* 上传合同/简历并进行 AI 审核,落库并返回结果
|
||||||
*
|
*
|
||||||
* @param file PDF / Word 文件
|
* @param file PDF / Word 文件
|
||||||
* @param reviewType contract / resume
|
* @param reviewType contract / resume
|
||||||
* @param position 简历审核的目标岗位(合同可空)
|
* @param position 简历审核的目标岗位(合同可空)
|
||||||
|
* @param requirements 附加审核要求/重点(可空)
|
||||||
*/
|
*/
|
||||||
OaAiReviewVo analyze(MultipartFile file, String reviewType, String position);
|
OaAiReviewVo analyze(MultipartFile file, String reviewType, String position, String requirements);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 流式审核:边生成边推送(SSE),结束后落库
|
* 流式审核:边生成边推送(SSE),结束后落库
|
||||||
*/
|
*/
|
||||||
SseEmitter analyzeStream(MultipartFile file, String reviewType, String position);
|
SseEmitter analyzeStream(MultipartFile file, String reviewType, String position, String requirements);
|
||||||
|
|
||||||
TableDataInfo<OaAiReviewVo> queryPageList(OaAiReviewBo bo, PageQuery pageQuery);
|
TableDataInfo<OaAiReviewVo> queryPageList(OaAiReviewBo bo, PageQuery pageQuery);
|
||||||
|
|
||||||
|
|||||||
@@ -57,8 +57,8 @@ public class OaAiReviewServiceImpl implements IOaAiReviewService {
|
|||||||
private static final Pattern RISK_PATTERN = Pattern.compile("风险评级[::\\s]*([高中低])");
|
private static final Pattern RISK_PATTERN = Pattern.compile("风险评级[::\\s]*([高中低])");
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OaAiReviewVo analyze(MultipartFile file, String reviewType, String position) {
|
public OaAiReviewVo analyze(MultipartFile file, String reviewType, String position, String requirements) {
|
||||||
Prepared p = prepareSync(file, reviewType, position);
|
Prepared p = prepareSync(file, reviewType, position, requirements);
|
||||||
buildPrompt(p);
|
buildPrompt(p);
|
||||||
String result = p.images != null
|
String result = p.images != null
|
||||||
? miMoClient.chatMultimodal(p.system, p.userText, p.images)
|
? miMoClient.chatMultimodal(p.system, p.userText, p.images)
|
||||||
@@ -70,11 +70,11 @@ public class OaAiReviewServiceImpl implements IOaAiReviewService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SseEmitter analyzeStream(MultipartFile file, String reviewType, String position) {
|
public SseEmitter analyzeStream(MultipartFile file, String reviewType, String position, String requirements) {
|
||||||
// 只在同步阶段做轻量校验 + 读取字节(multipart 必须在请求线程内消费);
|
// 只在同步阶段做轻量校验 + 读取字节(multipart 必须在请求线程内消费);
|
||||||
// 文档解析、渲染、大模型调用全部放到异步线程,任何异常都以 SSE error 事件返回,
|
// 文档解析、渲染、大模型调用全部放到异步线程,任何异常都以 SSE error 事件返回,
|
||||||
// 避免在返回 SseEmitter 之前抛异常被全局处理器包成 JSON(前端按流读取会“静默失败”)。
|
// 避免在返回 SseEmitter 之前抛异常被全局处理器包成 JSON(前端按流读取会“静默失败”)。
|
||||||
Prepared p = prepareSync(file, reviewType, position);
|
Prepared p = prepareSync(file, reviewType, position, requirements);
|
||||||
String username = currentUsername();
|
String username = currentUsername();
|
||||||
long timeoutMs = ((miMoProps.getTimeout() == null ? 180 : miMoProps.getTimeout()) + 60) * 1000L;
|
long timeoutMs = ((miMoProps.getTimeout() == null ? 180 : miMoProps.getTimeout()) + 60) * 1000L;
|
||||||
SseEmitter emitter = new SseEmitter(timeoutMs);
|
SseEmitter emitter = new SseEmitter(timeoutMs);
|
||||||
@@ -129,7 +129,7 @@ public class OaAiReviewServiceImpl implements IOaAiReviewService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 同步阶段:校验 + 读取字节(不解析,快) */
|
/** 同步阶段:校验 + 读取字节(不解析,快) */
|
||||||
private Prepared prepareSync(MultipartFile file, String reviewType, String position) {
|
private Prepared prepareSync(MultipartFile file, String reviewType, String position, String requirements) {
|
||||||
if (file == null || file.isEmpty()) {
|
if (file == null || file.isEmpty()) {
|
||||||
throw new ServiceException("请上传文件");
|
throw new ServiceException("请上传文件");
|
||||||
}
|
}
|
||||||
@@ -153,6 +153,7 @@ public class OaAiReviewServiceImpl implements IOaAiReviewService {
|
|||||||
Prepared p = new Prepared();
|
Prepared p = new Prepared();
|
||||||
p.reviewType = reviewType;
|
p.reviewType = reviewType;
|
||||||
p.position = position;
|
p.position = position;
|
||||||
|
p.requirements = StringUtils.trimToNull(requirements);
|
||||||
p.fileName = fileName;
|
p.fileName = fileName;
|
||||||
p.bytes = bytes;
|
p.bytes = bytes;
|
||||||
return p;
|
return p;
|
||||||
@@ -160,7 +161,12 @@ public class OaAiReviewServiceImpl implements IOaAiReviewService {
|
|||||||
|
|
||||||
/** 解析文档 + 构建提示词(耗时/可能抛异常的部分) */
|
/** 解析文档 + 构建提示词(耗时/可能抛异常的部分) */
|
||||||
private void buildPrompt(Prepared p) {
|
private void buildPrompt(Prepared p) {
|
||||||
p.system = "contract".equals(p.reviewType) ? contractSystemPrompt() : resumeSystemPrompt(p.position);
|
String base = "contract".equals(p.reviewType) ? contractSystemPrompt() : resumeSystemPrompt(p.position);
|
||||||
|
if (StringUtils.isNotBlank(p.requirements)) {
|
||||||
|
base += "\n\n【本次额外审核要求 / 重点】请在上述固定结构基础上,务必额外重点关注并逐条回应以下要求:\n"
|
||||||
|
+ p.requirements;
|
||||||
|
}
|
||||||
|
p.system = base;
|
||||||
String text = truncate(DocumentParseUtil.extractText(p.fileName, p.bytes));
|
String text = truncate(DocumentParseUtil.extractText(p.fileName, p.bytes));
|
||||||
if (StringUtils.length(text) >= MIN_TEXT_LEN) {
|
if (StringUtils.length(text) >= MIN_TEXT_LEN) {
|
||||||
p.userText = "contract".equals(p.reviewType)
|
p.userText = "contract".equals(p.reviewType)
|
||||||
@@ -189,6 +195,7 @@ public class OaAiReviewServiceImpl implements IOaAiReviewService {
|
|||||||
entity.setFileUrl(oss.getUrl());
|
entity.setFileUrl(oss.getUrl());
|
||||||
}
|
}
|
||||||
entity.setPosition(p.position);
|
entity.setPosition(p.position);
|
||||||
|
entity.setRequirements(p.requirements);
|
||||||
entity.setResultMd(result);
|
entity.setResultMd(result);
|
||||||
entity.setSummary(buildSummary(result));
|
entity.setSummary(buildSummary(result));
|
||||||
entity.setModel(miMoProps.getModel());
|
entity.setModel(miMoProps.getModel());
|
||||||
@@ -242,6 +249,7 @@ public class OaAiReviewServiceImpl implements IOaAiReviewService {
|
|||||||
private static class Prepared {
|
private static class Prepared {
|
||||||
String reviewType;
|
String reviewType;
|
||||||
String position;
|
String position;
|
||||||
|
String requirements;
|
||||||
String fileName;
|
String fileName;
|
||||||
byte[] bytes;
|
byte[] bytes;
|
||||||
String system;
|
String system;
|
||||||
|
|||||||
@@ -30,6 +30,23 @@
|
|||||||
: '评估候选人,分析与目标岗位的匹配度、优势、短板与面试建议。' }}
|
: '评估候选人,分析与目标岗位的匹配度、优势、短板与面试建议。' }}
|
||||||
支持 PDF / Word(.doc/.docx),≤ 20MB。
|
支持 PDF / Word(.doc/.docx),≤ 20MB。
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 审核重点 / 附加要求 -->
|
||||||
|
<div class="req-area">
|
||||||
|
<div class="req-line">
|
||||||
|
<span class="req-label">审核重点</span>
|
||||||
|
<el-checkbox-group v-model="checkedItems" size="mini" :disabled="streaming" class="req-items">
|
||||||
|
<el-checkbox v-for="it in itemOptions" :key="it.value" :label="it.label" border>{{ it.label }}</el-checkbox>
|
||||||
|
</el-checkbox-group>
|
||||||
|
<span class="req-tip">可在「系统管理→字典管理」增删审核项</span>
|
||||||
|
</div>
|
||||||
|
<div class="req-line">
|
||||||
|
<span class="req-label">附加要求</span>
|
||||||
|
<el-input v-model="extraText" type="textarea" :rows="2" :disabled="streaming"
|
||||||
|
class="req-extra" maxlength="500" show-word-limit
|
||||||
|
placeholder="可补充本次审核的特殊关注点,例如:重点核查付款比例是否对我方有利、是否有自动续约陷阱…" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<el-row :gutter="12" class="body">
|
<el-row :gutter="12" class="body">
|
||||||
@@ -96,6 +113,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getToken } from '@/utils/auth'
|
import { getToken } from '@/utils/auth'
|
||||||
|
import { getDicts } from '@/api/system/dict/data'
|
||||||
const marked = require('marked')
|
const marked = require('marked')
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -107,6 +125,11 @@ export default {
|
|||||||
rawFile: null,
|
rawFile: null,
|
||||||
fileName: '',
|
fileName: '',
|
||||||
|
|
||||||
|
// 审核重点(字典) + 附加要求(自由文本)
|
||||||
|
itemDicts: { contract: [], resume: [] },
|
||||||
|
checkedItems: [],
|
||||||
|
extraText: '',
|
||||||
|
|
||||||
streaming: false,
|
streaming: false,
|
||||||
done: false,
|
done: false,
|
||||||
reasoning: '',
|
reasoning: '',
|
||||||
@@ -124,15 +147,37 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
renderedMd () {
|
renderedMd () {
|
||||||
try { return marked(this.content) } catch (e) { return this.content }
|
try { return marked(this.content) } catch (e) { return this.content }
|
||||||
|
},
|
||||||
|
itemOptions () {
|
||||||
|
return this.itemDicts[this.reviewType] || []
|
||||||
|
},
|
||||||
|
requirements () {
|
||||||
|
const parts = []
|
||||||
|
if (this.checkedItems.length) parts.push('重点审核项:' + this.checkedItems.join('、'))
|
||||||
|
if (this.extraText && this.extraText.trim()) parts.push('其他要求:' + this.extraText.trim())
|
||||||
|
return parts.join('\n')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
// 切换类型时清空已选审核项(两套字典不同)
|
||||||
|
reviewType () { this.checkedItems = [] }
|
||||||
|
},
|
||||||
created () {
|
created () {
|
||||||
marked.setOptions({ breaks: true })
|
marked.setOptions({ breaks: true })
|
||||||
|
this.loadItemDicts()
|
||||||
},
|
},
|
||||||
beforeDestroy () {
|
beforeDestroy () {
|
||||||
if (this.previewUrl) URL.revokeObjectURL(this.previewUrl)
|
if (this.previewUrl) URL.revokeObjectURL(this.previewUrl)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
loadItemDicts () {
|
||||||
|
getDicts('oa_ai_review_item_contract').then(res => {
|
||||||
|
this.itemDicts = { ...this.itemDicts, contract: (res.data || []).map(d => ({ label: d.dictLabel, value: d.dictValue })) }
|
||||||
|
})
|
||||||
|
getDicts('oa_ai_review_item_resume').then(res => {
|
||||||
|
this.itemDicts = { ...this.itemDicts, resume: (res.data || []).map(d => ({ label: d.dictLabel, value: d.dictValue })) }
|
||||||
|
})
|
||||||
|
},
|
||||||
goBack () { this.$router.push('/hint/aiReview') },
|
goBack () { this.$router.push('/hint/aiReview') },
|
||||||
goDetail () { if (this.savedId) this.$router.push('/hint/aiReview/detail/' + this.savedId) },
|
goDetail () { if (this.savedId) this.$router.push('/hint/aiReview/detail/' + this.savedId) },
|
||||||
riskTagType (r) { return r === '高' ? 'danger' : (r === '中' ? 'warning' : 'success') },
|
riskTagType (r) { return r === '高' ? 'danger' : (r === '中' ? 'warning' : 'success') },
|
||||||
@@ -167,6 +212,7 @@ export default {
|
|||||||
fd.append('file', this.rawFile)
|
fd.append('file', this.rawFile)
|
||||||
fd.append('reviewType', this.reviewType)
|
fd.append('reviewType', this.reviewType)
|
||||||
if (this.reviewType === 'resume' && this.position) fd.append('position', this.position)
|
if (this.reviewType === 'resume' && this.position) fd.append('position', this.position)
|
||||||
|
if (this.requirements) fd.append('requirements', this.requirements)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const resp = await fetch(process.env.VUE_APP_BASE_API + '/oa/aiReview/analyzeStream', {
|
const resp = await fetch(process.env.VUE_APP_BASE_API + '/oa/aiReview/analyzeStream', {
|
||||||
@@ -264,6 +310,18 @@ export default {
|
|||||||
}
|
}
|
||||||
.bar-hint { font-size: 12px; color: #909399; margin-top: 8px; }
|
.bar-hint { font-size: 12px; color: #909399; margin-top: 8px; }
|
||||||
|
|
||||||
|
.req-area { margin-top: 10px; border-top: 1px dashed #ebeef5; padding-top: 8px; }
|
||||||
|
.req-line { display: flex; align-items: flex-start; gap: 8px; margin-bottom: 8px;
|
||||||
|
&:last-child { margin-bottom: 0; }
|
||||||
|
}
|
||||||
|
.req-label { flex: 0 0 56px; font-size: 12px; color: #606266; padding-top: 5px; font-weight: 600; }
|
||||||
|
.req-items { flex: 1; display: flex; flex-wrap: wrap; gap: 6px 0;
|
||||||
|
::v-deep .el-checkbox { margin-right: 8px; margin-left: 0; }
|
||||||
|
::v-deep .el-checkbox.is-bordered { padding: 4px 10px 4px 8px; height: auto; }
|
||||||
|
}
|
||||||
|
.req-tip { flex: 0 0 auto; font-size: 11px; color: #c0c4cc; padding-top: 5px; }
|
||||||
|
.req-extra { flex: 1; }
|
||||||
|
|
||||||
.body { margin-top: 0; }
|
.body { margin-top: 0; }
|
||||||
.panel { ::v-deep .el-card__header { padding: 9px 14px; } }
|
.panel { ::v-deep .el-card__header { padding: 9px 14px; } }
|
||||||
.hd { display: flex; justify-content: space-between; align-items: center;
|
.hd { display: flex; justify-content: space-between; align-items: center;
|
||||||
|
|||||||
@@ -29,6 +29,9 @@
|
|||||||
<el-descriptions-item label="模型">{{ info.model || '—' }}</el-descriptions-item>
|
<el-descriptions-item label="模型">{{ info.model || '—' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="审核时间">{{ info.createTime }}</el-descriptions-item>
|
<el-descriptions-item label="审核时间">{{ info.createTime }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="审核人">{{ info.createBy || '—' }}</el-descriptions-item>
|
<el-descriptions-item label="审核人">{{ info.createBy || '—' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item v-if="info.requirements" label="审核重点 / 附加要求" :span="3">
|
||||||
|
<span style="white-space: pre-wrap">{{ info.requirements }}</span>
|
||||||
|
</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
|
|
||||||
<div v-if="info" class="md-body" v-html="renderedMd" />
|
<div v-if="info" class="md-body" v-html="renderedMd" />
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ CREATE TABLE IF NOT EXISTS `oa_ai_review` (
|
|||||||
`oss_id` bigint(20) DEFAULT NULL COMMENT 'OSS文件ID(原件留存)',
|
`oss_id` bigint(20) DEFAULT NULL COMMENT 'OSS文件ID(原件留存)',
|
||||||
`file_url` varchar(500) DEFAULT NULL COMMENT 'OSS文件地址',
|
`file_url` varchar(500) DEFAULT NULL COMMENT 'OSS文件地址',
|
||||||
`position` varchar(255) DEFAULT NULL COMMENT '简历目标岗位',
|
`position` varchar(255) DEFAULT NULL COMMENT '简历目标岗位',
|
||||||
|
`requirements` varchar(1000) DEFAULT NULL COMMENT '本次审核的附加要求/审核重点',
|
||||||
`match_score` int(11) DEFAULT NULL COMMENT '简历匹配度评分 0-100',
|
`match_score` int(11) DEFAULT NULL COMMENT '简历匹配度评分 0-100',
|
||||||
`risk_level` varchar(10) DEFAULT NULL COMMENT '合同风险评级 高/中/低',
|
`risk_level` varchar(10) DEFAULT NULL COMMENT '合同风险评级 高/中/低',
|
||||||
`summary` varchar(500) DEFAULT NULL COMMENT 'AI审核结论摘要(列表展示)',
|
`summary` varchar(500) DEFAULT NULL COMMENT 'AI审核结论摘要(列表展示)',
|
||||||
@@ -31,8 +32,38 @@ CREATE TABLE IF NOT EXISTS `oa_ai_review` (
|
|||||||
KEY `idx_create_time` (`create_time`)
|
KEY `idx_create_time` (`create_time`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='AI 审核记录(合同/简历)';
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='AI 审核记录(合同/简历)';
|
||||||
|
|
||||||
-- 若表已存在(旧版本),补加 summary 列(MySQL 不支持 ADD COLUMN IF NOT EXISTS,重复执行报错可忽略):
|
-- 若表已存在(旧版本),补加列(MySQL 不支持 ADD COLUMN IF NOT EXISTS,已存在则报错可忽略):
|
||||||
-- ALTER TABLE `oa_ai_review` ADD COLUMN `summary` varchar(500) DEFAULT NULL COMMENT 'AI审核结论摘要(列表展示)' AFTER `risk_level`;
|
-- ALTER TABLE `oa_ai_review` ADD COLUMN `summary` varchar(500) DEFAULT NULL COMMENT 'AI审核结论摘要(列表展示)' AFTER `risk_level`;
|
||||||
|
-- ALTER TABLE `oa_ai_review` ADD COLUMN `requirements` varchar(1000) DEFAULT NULL COMMENT '本次审核的附加要求/审核重点' AFTER `position`;
|
||||||
|
|
||||||
|
-- ---------------- 字典:可选审核重点(合同 / 简历),用户可在字典管理增删 ----------------
|
||||||
|
INSERT IGNORE INTO `sys_dict_type` (`dict_id`, `dict_name`, `dict_type`, `status`, `create_by`, `create_time`, `remark`)
|
||||||
|
VALUES (2063920000000000001, 'AI合同审核项', 'oa_ai_review_item_contract', '0', 'admin', NOW(), 'AI合同审核可选审核重点'),
|
||||||
|
(2063920000000000002, 'AI简历审核项', 'oa_ai_review_item_resume', '0', 'admin', NOW(), 'AI简历审核可选审核重点');
|
||||||
|
|
||||||
|
INSERT IGNORE INTO `sys_dict_data`
|
||||||
|
(`dict_code`, `dict_sort`, `dict_label`, `dict_value`, `dict_type`, `css_class`, `list_class`, `is_default`, `status`, `create_by`, `create_time`, `remark`)
|
||||||
|
VALUES
|
||||||
|
(2063920000000000010, 1, '付款条款与节点', '付款条款与节点', 'oa_ai_review_item_contract', '', 'default', 'N', '0', 'admin', NOW(), ''),
|
||||||
|
(2063920000000000011, 2, '违约责任与赔偿', '违约责任与赔偿', 'oa_ai_review_item_contract', '', 'default', 'N', '0', 'admin', NOW(), ''),
|
||||||
|
(2063920000000000012, 3, '知识产权归属', '知识产权归属', 'oa_ai_review_item_contract', '', 'default', 'N', '0', 'admin', NOW(), ''),
|
||||||
|
(2063920000000000013, 4, '保密义务', '保密义务', 'oa_ai_review_item_contract', '', 'default', 'N', '0', 'admin', NOW(), ''),
|
||||||
|
(2063920000000000014, 5, '交付与验收标准', '交付与验收标准', 'oa_ai_review_item_contract', '', 'default', 'N', '0', 'admin', NOW(), ''),
|
||||||
|
(2063920000000000015, 6, '质保与售后', '质保与售后', 'oa_ai_review_item_contract', '', 'default', 'N', '0', 'admin', NOW(), ''),
|
||||||
|
(2063920000000000016, 7, '价格与税费', '价格与税费', 'oa_ai_review_item_contract', '', 'default', 'N', '0', 'admin', NOW(), ''),
|
||||||
|
(2063920000000000017, 8, '争议解决与管辖', '争议解决与管辖', 'oa_ai_review_item_contract', '', 'default', 'N', '0', 'admin', NOW(), ''),
|
||||||
|
(2063920000000000018, 9, '不可抗力', '不可抗力', 'oa_ai_review_item_contract', '', 'default', 'N', '0', 'admin', NOW(), ''),
|
||||||
|
(2063920000000000019, 10,'合同解除条件', '合同解除条件', 'oa_ai_review_item_contract', '', 'default', 'N', '0', 'admin', NOW(), ''),
|
||||||
|
(2063920000000000040, 1, '技术能力匹配', '技术能力匹配', 'oa_ai_review_item_resume', '', 'default', 'N', '0', 'admin', NOW(), ''),
|
||||||
|
(2063920000000000041, 2, '项目经验深度', '项目经验深度', 'oa_ai_review_item_resume', '', 'default', 'N', '0', 'admin', NOW(), ''),
|
||||||
|
(2063920000000000042, 3, '工作稳定性', '工作稳定性', 'oa_ai_review_item_resume', '', 'default', 'N', '0', 'admin', NOW(), ''),
|
||||||
|
(2063920000000000043, 4, '团队协作与管理', '团队协作与管理', 'oa_ai_review_item_resume', '', 'default', 'N', '0', 'admin', NOW(), ''),
|
||||||
|
(2063920000000000044, 5, '学历与专业背景', '学历与专业背景', 'oa_ai_review_item_resume', '', 'default', 'N', '0', 'admin', NOW(), ''),
|
||||||
|
(2063920000000000045, 6, '行业相关经验', '行业相关经验', 'oa_ai_review_item_resume', '', 'default', 'N', '0', 'admin', NOW(), ''),
|
||||||
|
(2063920000000000046, 7, '薪资期望匹配', '薪资期望匹配', 'oa_ai_review_item_resume', '', 'default', 'N', '0', 'admin', NOW(), ''),
|
||||||
|
(2063920000000000047, 8, '成长潜力', '成长潜力', 'oa_ai_review_item_resume', '', 'default', 'N', '0', 'admin', NOW(), ''),
|
||||||
|
(2063920000000000048, 9, '离职风险', '离职风险', 'oa_ai_review_item_resume', '', 'default', 'N', '0', 'admin', NOW(), ''),
|
||||||
|
(2063920000000000049, 10,'外语能力', '外语能力', 'oa_ai_review_item_resume', '', 'default', 'N', '0', 'admin', NOW(), '');
|
||||||
|
|
||||||
-- ---------------- 菜单:信息 > AI审核 ----------------
|
-- ---------------- 菜单:信息 > AI审核 ----------------
|
||||||
-- 父菜单 1774989374680858626 = 「信息」
|
-- 父菜单 1774989374680858626 = 「信息」
|
||||||
|
|||||||
Reference in New Issue
Block a user