feat-实现数据分析-原始数据AI标记筛选和数据导出功能
This commit is contained in:
2
.env.dev
2
.env.dev
@@ -3,7 +3,7 @@ VUE_APP_CURRENTMODE = 'dev'
|
||||
|
||||
VUE_APP_BASEOSS = 'https://diaoyan-files.automark.cc'
|
||||
#VUE_APP_BASEURL = 'http://planetg-java.test.automark.cc/'
|
||||
VUE_APP_BASEURL = 'http://yls-api-uat.dctest.digitalyili.com/'
|
||||
VUE_APP_BASEURL = 'https://yls-api-uat.dctest.digitalyili.com'
|
||||
|
||||
VUE_APP_DELiVERY_BASEURL='https://javaxq.test.automark.cc/'
|
||||
VUE_APP_MESSAGE_CENTER ='http://gtech-gateway.dcin-test.digitalyili.com/apigtech/message-send-center/';
|
||||
|
||||
3
.env.sit
3
.env.sit
@@ -2,7 +2,8 @@ NODE_ENV = 'production'
|
||||
VUE_APP_CURRENTMODE = 'sit'
|
||||
|
||||
VUE_APP_BASEOSS = 'https://test-cxp-pubcos.yili.com/uat-yls'
|
||||
VUE_APP_BASEURL = 'https://yls-api-uat.dctest.digitalyili.com'
|
||||
|
||||
VUE_APP_BASEURL = 'https://ylst-api-sit.dctest.digitalyili.com'
|
||||
|
||||
VUE_APP_JAVA_DELiVERY_BASEURL='https://ylsdist-net-uat.dctest.digitalyili.com'
|
||||
|
||||
|
||||
@@ -311,12 +311,12 @@ const toAiInspection = () => {
|
||||
console.log('questions', questionInfo.questions);
|
||||
if (!questionInfo.questions || questionInfo.questions.length === 0) {
|
||||
// 未设计问卷,不允许质检
|
||||
message.error('请先设计问卷');
|
||||
message.error('您还没添加任何问题,请添加后再进行AI质检。');
|
||||
return;
|
||||
}
|
||||
const questions = questionInfo.questions;
|
||||
emitter.emit('app-loading', { visible: true, description: '正在 AI 质检...请您稍候~' });
|
||||
aiQualityInspection(sn)
|
||||
aiQualityInspection(route.query.sn, { sn})
|
||||
.then((res) => {
|
||||
if (!res || !res.code === 0 || !res.data) {
|
||||
// 质检接口调用失败
|
||||
@@ -338,11 +338,11 @@ const toAiInspection = () => {
|
||||
questions.forEach((question) => {
|
||||
questionMap[question.title] = question;
|
||||
});
|
||||
resultList.forEach((resultQuestion) => {
|
||||
const question = questionMap[resultQuestion.title];
|
||||
resultList.forEach((result) => {
|
||||
const question = questionMap[result.title];
|
||||
if (question) {
|
||||
// 有匹配上的问题,将质检结果合并到问题中
|
||||
question.ai_inspection_result = resultQuestion;
|
||||
question.ai_inspection_result = result.advice;
|
||||
}
|
||||
});
|
||||
store.commit('common/M_COMMON_SET_QUESTION_INFO', questionInfo);
|
||||
|
||||
@@ -5,22 +5,46 @@
|
||||
v-if="[12, 13, 14].includes(question_type)"
|
||||
v-html="content"
|
||||
></div>
|
||||
<div v-else-if="titleInfo.titleType === 'withIcon'" class="icon-title">
|
||||
<a-tooltip placement="topLeft">
|
||||
<template #title>
|
||||
<div class="custom-head-preview">{{ titleInfo.title }}</div>
|
||||
</template>
|
||||
<!--带有图标的标题(AI/人工样本标记)-->
|
||||
<div class="common-text">{{ titleInfo.title }}</div>
|
||||
</a-tooltip>
|
||||
<a-tooltip placement="topLeft">
|
||||
<template #title>
|
||||
<div class="custom-head-preview">{{ titleInfo.titleIconTip }}</div>
|
||||
</template>
|
||||
<!--带有图标的标题(AI/人工样本标记)-->
|
||||
<img class="icon-title__icon" :src="titleInfo.titleIconSrc" alt="" @click="onIconClicked" />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<a-tooltip placement="topLeft" v-else>
|
||||
<template #title>
|
||||
<div class="custom-head-preview" v-html="content"></div>
|
||||
</template>
|
||||
<div class="custom-head-main">
|
||||
<!-- 下载题型-->
|
||||
<div class="file-question" v-if="question_type === 18" :style="{ width: data.width + 'px' }">
|
||||
<div
|
||||
class="file-question"
|
||||
v-if="question_type === 18"
|
||||
:style="{ width: data.width + 'px' }"
|
||||
>
|
||||
<div class="label">{{ content }}</div>
|
||||
<i class="iconfont icon-xiazai" style="color: #70b936; cursor: pointer" @click="download"></i>
|
||||
<i
|
||||
class="iconfont icon-xiazai"
|
||||
style="color: #70b936; cursor: pointer"
|
||||
@click="download"
|
||||
></i>
|
||||
<!-- <a-button size="mini" @click="download">下载全部附件333</a-button>-->
|
||||
</div>
|
||||
<!-- 图文题-->
|
||||
|
||||
<div class="common-text" v-else>{{ content }}</div>
|
||||
</div>
|
||||
</a-tooltip>
|
||||
|
||||
<!-- 下载中心 -->
|
||||
<DownloadCenter v-model:visible="downloadVisible" v-if="downloadVisible"></DownloadCenter>
|
||||
</div>
|
||||
@@ -47,6 +71,8 @@ const props = defineProps({
|
||||
type: String
|
||||
}
|
||||
});
|
||||
const emit = defineEmits(['iconClick']);
|
||||
const titleInfo = ref({});
|
||||
const content = ref('');
|
||||
const question_index = ref(null);
|
||||
const question_type = ref(null);
|
||||
@@ -90,7 +116,15 @@ function downloadCenter() {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击标题图标,发送事件
|
||||
*/
|
||||
function onIconClicked() {
|
||||
emit('iconClick', titleInfo.value);
|
||||
}
|
||||
|
||||
watchEffect(() => {
|
||||
titleInfo.value = props.data;
|
||||
content.value = props.data.title;
|
||||
question_index.value = props.data.question_index;
|
||||
question_type.value = props.data.question_type;
|
||||
@@ -137,5 +171,15 @@ watchEffect(() => {
|
||||
align-items: center;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.icon-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
&__icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -12,7 +12,12 @@
|
||||
<template v-for="col in tableHeaders" :key="col.dataIndex" #[col.dataIndex]="{ record, text }">
|
||||
<template v-if="col.dataIndex === 'is_mark'">
|
||||
<slot name="is_mark" v-bind:record="record">
|
||||
<i v-if="record.is_mark == 1" class="icon iconfont show-sign curror" @click="hideSign(record)"></i>
|
||||
<i
|
||||
v-if="record.is_mark == 1"
|
||||
class="icon iconfont show-sign curror"
|
||||
@click="hideSign(record)"
|
||||
></i
|
||||
>
|
||||
<i v-else class="icon iconfont hide-sign curror" @click="showSign(record)"></i>
|
||||
</slot>
|
||||
</template>
|
||||
@@ -126,7 +131,7 @@ const props = defineProps({
|
||||
default: ''
|
||||
}
|
||||
});
|
||||
const emit = defineEmits(['change', 'select']);
|
||||
const emit = defineEmits(['change', 'select', 'headerClick']);
|
||||
const store = useStore();
|
||||
const data = ref([]);
|
||||
const columns = ref(null);
|
||||
@@ -134,7 +139,9 @@ const searchParams = ref(props.params);
|
||||
const { perPage: per_page, total, page, rowKey } = toRefs(props);
|
||||
const { pagination } = usePagination(per_page, total, page);
|
||||
const { tableHeaders } = useGeneratorTableColumns(columns);
|
||||
const { customHeaders } = useCustomHeaderTitle(tableHeaders, props.sn, searchParams);
|
||||
const { customHeaders } = useCustomHeaderTitle(tableHeaders, props.sn, searchParams, (column) => {
|
||||
emit('headerClick', column);
|
||||
});
|
||||
|
||||
// 页码&分页条数,改变时候触发
|
||||
const handlePageChange = (data) => {
|
||||
@@ -187,6 +194,7 @@ const showSign = (item) => {
|
||||
const hideSign = (item) => {
|
||||
emit('sign', [item], false);
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.params,
|
||||
(val) => {
|
||||
|
||||
@@ -11,7 +11,10 @@
|
||||
<img class="suffix-icon" :src="require('@/assets/img/select-arrow-down.png')" alt="">
|
||||
</template>
|
||||
</a-select> -->
|
||||
<a-dropdown class="searchSelect operChd" :getPopupContainer="(triggerNode) => triggerNode.parentNode">
|
||||
<a-dropdown
|
||||
class="searchSelect operChd"
|
||||
:getPopupContainer="(triggerNode) => triggerNode.parentNode"
|
||||
>
|
||||
<template #overlay>
|
||||
<a-menu @click="opChange">
|
||||
<a-menu-item v-for="item in opList" :key="item.value">
|
||||
@@ -24,7 +27,11 @@
|
||||
<img class="suffix-icon" :src="require('@/assets/img/select-arrow-down.png')" alt="" />
|
||||
</a-button>
|
||||
</a-dropdown>
|
||||
<a-button class="operChd custom-button" @click="emit('cleanAllBtn', true)">清空数据</a-button>
|
||||
|
||||
<!-- delete by zhangweiwei 20250331_ai 无效样本标记-不显示清空数据按钮 start -->
|
||||
<!-- <a-button class="operChd custom-button" @click="emit('cleanAllBtn', true)">清空数据</a-button> -->
|
||||
<!-- delete by zhangweiwei 20250331_ai 无效样本标记-不显示清空数据按钮 end -->
|
||||
|
||||
<!-- <a-button class="operChd" @click="handleDownload">下载全部答卷</a-button> -->
|
||||
<!-- <a-dropdown class="searchSelect operChd" :getPopupContainer="(triggerNode) => triggerNode.parentNode">
|
||||
<template #overlay>
|
||||
@@ -40,7 +47,9 @@
|
||||
<CaretDownOutlined class="suffix-icon" />
|
||||
</a-button>
|
||||
</a-dropdown> -->
|
||||
<a-button type="primary" class="operChd custom-button" @click="dataChange({ key: 2 })">全量数据导出</a-button>
|
||||
<a-button type="primary" class="operChd custom-button" @click="dataChange({ key: 2 })"
|
||||
>全量数据导出</a-button
|
||||
>
|
||||
<!-- <a-select
|
||||
:getPopupContainer="triggerNode=>triggerNode.parentNode"
|
||||
class="searchSelect operChd"
|
||||
@@ -51,8 +60,14 @@
|
||||
<img class="suffix-icon" :src="require('@/assets/img/select-arrow-down.png')" alt="">
|
||||
</template>
|
||||
</a-select> -->
|
||||
<a-button type="primary" class="operChd custom-button" @click="noData">无效样本处理</a-button>
|
||||
<a-button type="primary" class="operChd custom-button" @click="configVisible = true">列表配置</a-button>
|
||||
|
||||
<!-- delete by zhangweiwei 20250331_ai 无效样本标记-不显示无效样本处理按钮 start -->
|
||||
<!-- <a-button type="primary" class="operChd custom-button" @click="noData">无效样本处理</a-button> -->
|
||||
<!-- delete by zhangweiwei 20250331_ai 无效样本标记-不显示无效样本处理按钮 end -->
|
||||
|
||||
<a-button type="primary" class="operChd custom-button" @click="configVisible = true"
|
||||
>列表配置</a-button
|
||||
>
|
||||
<!-- 同步数据 -->
|
||||
<a-tooltip :overlayStyle="{ 'max-width': 'none' }">
|
||||
<template v-slot:title> 产品测试模块会同步该列表数据并作统计展示 </template>
|
||||
@@ -68,7 +83,12 @@
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<!-- 配置 -->
|
||||
<ColumnConfig v-model:visible="configVisible" :data="answer_columns" :sn="sn" @ok="handleConfig" />
|
||||
<ColumnConfig
|
||||
v-model:visible="configVisible"
|
||||
:data="answer_columns"
|
||||
:sn="sn"
|
||||
@ok="handleConfig"
|
||||
/>
|
||||
<!-- 导出 -->
|
||||
<DownloadData
|
||||
v-model:visible="downloadVisible"
|
||||
@@ -78,7 +98,10 @@
|
||||
@ok="handleDownload"
|
||||
/>
|
||||
<!-- 下载中心 -->
|
||||
<DownloadCenter v-model:visible="downloadCenterVisible" v-if="downloadCenterVisible"></DownloadCenter>
|
||||
<DownloadCenter
|
||||
v-model:visible="downloadCenterVisible"
|
||||
v-if="downloadCenterVisible"
|
||||
></DownloadCenter>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, toRefs, reactive, defineProps, watch, onMounted, computed, nextTick } from 'vue';
|
||||
@@ -115,13 +138,15 @@ const searchData = ref({
|
||||
test1: null,
|
||||
test2: null
|
||||
});
|
||||
|
||||
/** modify by zhangweiwei 20250331_ai 无效样本标记-批量操作中标记和取消标记按钮删除 start */
|
||||
const opList = ref([
|
||||
{ value: '3', label: '标记' },
|
||||
{ value: '4', label: '取消标记' },
|
||||
{ value: '0', label: '下载答卷' },
|
||||
{ value: '1', label: '导出数据' },
|
||||
{ value: '2', label: '删除' }
|
||||
]);
|
||||
/** modify by zhangweiwei 20250331_ai 无效样本标记-批量操作中标记和取消标记按钮删除 end */
|
||||
|
||||
const syncDataLoading = ref(false);
|
||||
|
||||
// 导出选中答卷
|
||||
|
||||
@@ -76,10 +76,19 @@
|
||||
</div>
|
||||
</a-modal>
|
||||
<!-- 导出框 -->
|
||||
<a-modal class="custom-modal" v-model:visible="dataExportVis" title="数据导出" @ok="dataExportOk">
|
||||
<a-modal
|
||||
class="custom-modal"
|
||||
v-model:visible="dataExportVis"
|
||||
title="数据导出"
|
||||
@ok="dataExportOk"
|
||||
>
|
||||
<a-form ref="formRef" :model="formState" :rules="rules" :labelCol="{ span: 5 }">
|
||||
<a-form-item ref="type" label="文件格式" name="type">
|
||||
<a-radio-group v-model:value="formState.type" @change="changeType" class="custom-radio-group">
|
||||
<a-radio-group
|
||||
v-model:value="formState.type"
|
||||
@change="changeType"
|
||||
class="custom-radio-group"
|
||||
>
|
||||
<a-radio class="custom-radio" value="1">Excel(.xlsx)</a-radio>
|
||||
<a-radio class="custom-radio" value="2">CSV(.csv)</a-radio>
|
||||
<a-radio class="custom-radio" value="3">SPSS(.sav)</a-radio>
|
||||
@@ -96,7 +105,9 @@
|
||||
|
||||
<a-form-item ref="header_column_type" label="题目行格式" @change="changeHeaderColumnType">
|
||||
<a-radio-group v-model:value="formState.header_column_type" class="custom-radio-group">
|
||||
<a-radio class="custom-radio" value="0" :disabled="formState.type === '3'">文本</a-radio>
|
||||
<a-radio class="custom-radio" value="0" :disabled="formState.type === '3'"
|
||||
>文本</a-radio
|
||||
>
|
||||
<a-radio class="custom-radio" value="1">序号</a-radio>
|
||||
</a-radio-group>
|
||||
<!--<a-select class="custom-select" v-model:value="formState.header_column_type" placeholder="请选择">-->
|
||||
@@ -126,6 +137,14 @@
|
||||
<a-switch v-model:checked="formState.contains_base" />
|
||||
</div>
|
||||
</a-form-item>
|
||||
<!-- modify by zhangweiwei 20250331_ai 无效样本标记-数据导出弹窗,增加【导出有效样本】录入项 start -->
|
||||
<a-form-item label="导出有效样本" name="is_mark">
|
||||
<div class="switchBox">
|
||||
<span></span>
|
||||
<a-switch v-model:checked="formState.is_mark" />
|
||||
</div>
|
||||
</a-form-item>
|
||||
<!-- modify by zhangweiwei 20250331_ai 无效样本标记-数据导出弹窗,增加【导出有效样本】录入项 end -->
|
||||
<a-form-item v-if="formState.contains_base">
|
||||
<a-select
|
||||
class="custom-select"
|
||||
@@ -139,7 +158,9 @@
|
||||
<template #dropdownRender="{ menuNode: VNodes }">
|
||||
<div style="padding: 4px 12px; cursor: pointer">
|
||||
<a-button size="small" type="primary" @click="selectAll()">全选</a-button>
|
||||
<a-button style="margin-left: 6px" size="small" @click="cancelSelectAll()">清空</a-button>
|
||||
<a-button style="margin-left: 6px" size="small" @click="cancelSelectAll()"
|
||||
>清空</a-button
|
||||
>
|
||||
</div>
|
||||
<a-divider style="margin: 4px 0" />
|
||||
<v-nodes :vnodes="VNodes" />
|
||||
@@ -154,7 +175,12 @@
|
||||
</a-form-item> -->
|
||||
<a-form-item ref="name" label="数据导出范围" v-if="operType !== 1">
|
||||
<a-radio-group v-model:value="formState.isFilter" class="custom-radio-group">
|
||||
<a-radio class="custom-radio" v-for="radio in isFilterData" :key="radio.value" :value="radio.value">
|
||||
<a-radio
|
||||
class="custom-radio"
|
||||
v-for="radio in isFilterData"
|
||||
:key="radio.value"
|
||||
:value="radio.value"
|
||||
>
|
||||
{{ radio.label }}
|
||||
</a-radio>
|
||||
</a-radio-group>
|
||||
@@ -202,7 +228,10 @@
|
||||
<a-menu-item @click="putSurveysAnswersTop(item.id)" v-if="item.id">
|
||||
<div>置顶方案</div>
|
||||
</a-menu-item>
|
||||
<a-menu-item @click="postSurveysAnswersClone(item.id)" v-if="planList.length < 10 && item.id">
|
||||
<a-menu-item
|
||||
@click="postSurveysAnswersClone(item.id)"
|
||||
v-if="planList.length < 10 && item.id"
|
||||
>
|
||||
<div>复制方案</div>
|
||||
</a-menu-item>
|
||||
<a-menu-item>
|
||||
@@ -472,6 +501,10 @@ const getSurveysAnswersDown = async () => {
|
||||
let subData = formState;
|
||||
subData.contains_base = subData.contains_base === true ? 1 : 0;
|
||||
subData.include_open = subData.include_open === true ? 1 : 0;
|
||||
/** modify by zhangweiwei 20250331_ai 无效样本标记-数据导出弹窗,增加【导出有效样本】录入项 start */
|
||||
subData.is_mark = subData.is_mark === true ? '0' : '0,1,2'; //导出有效样本就是只传”0”;导出全部就是”0,1,2”
|
||||
/** modify by zhangweiwei 20250331_ai 无效样本标记-数据导出弹窗,增加【导出有效样本】录入项 end */
|
||||
|
||||
//subData.is_import = subData.is_import===true?1:0
|
||||
subData.contains_columns.push('id');
|
||||
subData.sn = sn;
|
||||
@@ -580,6 +613,7 @@ const formState = reactive({
|
||||
header_column_type: '0', //答案行格式
|
||||
column_type: '0', //答案行格式
|
||||
contains_base: true, //作答信息开关
|
||||
is_mark: true, // 有效样本开关
|
||||
contains_columns: [], //作答信息多选
|
||||
//is_import:true,//导入数据开关
|
||||
isFilter: '1',
|
||||
@@ -775,7 +809,9 @@ const onSearch = (e) => {
|
||||
const planList = ref([]);
|
||||
// 当前页数据
|
||||
const nowPlanList = computed(() => {
|
||||
return planList.value.filter((el, i) => i >= (nowPage.value - 1) * 5 && i + 1 <= nowPage.value * 5);
|
||||
return planList.value.filter(
|
||||
(el, i) => i >= (nowPage.value - 1) * 5 && i + 1 <= nowPage.value * 5
|
||||
);
|
||||
});
|
||||
// 方案列表
|
||||
const getSurveysAnswerFilter = async () => {
|
||||
|
||||
@@ -87,8 +87,12 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="addBtn">
|
||||
<div class="addBtnLi" @click="addList"><PlusSquareOutlined class="addIcon" />添加筛选条件</div>
|
||||
<div class="addBtnLi" @click="addGroup"><PlusSquareOutlined class="addIcon" />添加条件集合</div>
|
||||
<div class="addBtnLi" @click="addList">
|
||||
<PlusSquareOutlined class="addIcon" />添加筛选条件
|
||||
</div>
|
||||
<div class="addBtnLi" @click="addGroup">
|
||||
<PlusSquareOutlined class="addIcon" />添加条件集合
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -109,9 +113,15 @@
|
||||
@input="timeLang"
|
||||
placeholder="请输入"
|
||||
/>
|
||||
<template v-if="searchData.useTimeVal == 'between' || searchData.useTimeVal == 'notBetween'">
|
||||
<template
|
||||
v-if="searchData.useTimeVal == 'between' || searchData.useTimeVal == 'notBetween'"
|
||||
>
|
||||
<p class="betweenSymbol">-</p>
|
||||
<a-input style="width: 80px" v-model:value="searchData.useTimeInputValL" placeholder="请输入" />
|
||||
<a-input
|
||||
style="width: 80px"
|
||||
v-model:value="searchData.useTimeInputValL"
|
||||
placeholder="请输入"
|
||||
/>
|
||||
</template>
|
||||
<a-select
|
||||
:getPopupContainer="(triggerNode) => triggerNode.parentNode"
|
||||
@@ -182,8 +192,15 @@
|
||||
>
|
||||
<template #dropdownRender="{ menuNode: VNodes }">
|
||||
<div style="padding: 4px 12px; cursor: pointer">
|
||||
<a-button size="small" type="primary" @click="selectAll('publish')">全选</a-button>
|
||||
<a-button style="margin-left: 6px" size="small" @click="cancelSelectAll('publish')">清空</a-button>
|
||||
<a-button size="small" type="primary" @click="selectAll('publish')"
|
||||
>全选</a-button
|
||||
>
|
||||
<a-button
|
||||
style="margin-left: 6px"
|
||||
size="small"
|
||||
@click="cancelSelectAll('publish')"
|
||||
>清空</a-button
|
||||
>
|
||||
</div>
|
||||
<a-divider style="margin: 4px 0" />
|
||||
<v-nodes :vnodes="VNodes" />
|
||||
@@ -206,8 +223,13 @@
|
||||
>
|
||||
<template #dropdownRender="{ menuNode: VNodes }">
|
||||
<div style="padding: 4px 12px; cursor: pointer">
|
||||
<a-button size="small" type="primary" @click="selectAll('answerStatus')">全选</a-button>
|
||||
<a-button style="margin-left: 6px" size="small" @click="cancelSelectAll('answerStatus')"
|
||||
<a-button size="small" type="primary" @click="selectAll('answerStatus')"
|
||||
>全选</a-button
|
||||
>
|
||||
<a-button
|
||||
style="margin-left: 6px"
|
||||
size="small"
|
||||
@click="cancelSelectAll('answerStatus')"
|
||||
>清空</a-button
|
||||
>
|
||||
</div>
|
||||
@@ -233,8 +255,15 @@
|
||||
>
|
||||
<template #dropdownRender="{ menuNode: VNodes }">
|
||||
<div style="padding: 4px 12px; cursor: pointer">
|
||||
<a-button size="small" type="primary" @click="selectAll('version')">全选</a-button>
|
||||
<a-button style="margin-left: 6px" size="small" @click="cancelSelectAll('version')">清空</a-button>
|
||||
<a-button size="small" type="primary" @click="selectAll('version')"
|
||||
>全选</a-button
|
||||
>
|
||||
<a-button
|
||||
style="margin-left: 6px"
|
||||
size="small"
|
||||
@click="cancelSelectAll('version')"
|
||||
>清空</a-button
|
||||
>
|
||||
</div>
|
||||
<a-divider style="margin: 4px 0" />
|
||||
<v-nodes :vnodes="VNodes" />
|
||||
@@ -271,8 +300,15 @@
|
||||
>
|
||||
<template #dropdownRender="{ menuNode: VNodes }">
|
||||
<div style="padding: 4px 12px; cursor: pointer">
|
||||
<a-button size="small" type="primary" @click="selectAll('logics')">全选</a-button>
|
||||
<a-button style="margin-left: 6px" size="small" @click="cancelSelectAll('logics')">清空</a-button>
|
||||
<a-button size="small" type="primary" @click="selectAll('logics')"
|
||||
>全选</a-button
|
||||
>
|
||||
<a-button
|
||||
style="margin-left: 6px"
|
||||
size="small"
|
||||
@click="cancelSelectAll('logics')"
|
||||
>清空</a-button
|
||||
>
|
||||
</div>
|
||||
<a-divider style="margin: 4px 0" />
|
||||
<v-nodes :vnodes="VNodes" />
|
||||
@@ -297,8 +333,15 @@
|
||||
>
|
||||
<template #dropdownRender="{ menuNode: VNodes }">
|
||||
<div style="padding: 4px 12px; cursor: pointer">
|
||||
<a-button size="small" type="primary" @click="selectAll('isMark')">全选</a-button>
|
||||
<a-button style="margin-left: 6px" size="small" @click="cancelSelectAll('isMark')">清空</a-button>
|
||||
<a-button size="small" type="primary" @click="selectAll('isMark')"
|
||||
>全选</a-button
|
||||
>
|
||||
<a-button
|
||||
style="margin-left: 6px"
|
||||
size="small"
|
||||
@click="cancelSelectAll('isMark')"
|
||||
>清空</a-button
|
||||
>
|
||||
</div>
|
||||
<a-divider style="margin: 4px 0" />
|
||||
<v-nodes :vnodes="VNodes" />
|
||||
@@ -323,7 +366,12 @@
|
||||
<div class="codeInput" @click="isFocus = true" v-else>
|
||||
<div class="codeContent">
|
||||
<span v-if="inputValue.length == 0">{{ placeholder }}</span>
|
||||
<div v-else v-for="(item, index) in inputValue" :key="index" style="display: inline-block">
|
||||
<div
|
||||
v-else
|
||||
v-for="(item, index) in inputValue"
|
||||
:key="index"
|
||||
style="display: inline-block"
|
||||
>
|
||||
<span class="codeSpan">{{ item }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -351,8 +399,13 @@
|
||||
>
|
||||
<template #dropdownRender="{ menuNode: VNodes }">
|
||||
<div style="padding: 4px 12px; cursor: pointer">
|
||||
<a-button size="small" type="primary" @click="selectAll('answer_type')">全选</a-button>
|
||||
<a-button style="margin-left: 6px" size="small" @click="cancelSelectAll('answer_type')"
|
||||
<a-button size="small" type="primary" @click="selectAll('answer_type')"
|
||||
>全选</a-button
|
||||
>
|
||||
<a-button
|
||||
style="margin-left: 6px"
|
||||
size="small"
|
||||
@click="cancelSelectAll('answer_type')"
|
||||
>清空</a-button
|
||||
>
|
||||
</div>
|
||||
@@ -412,7 +465,18 @@
|
||||
<newModal ref="newModalRef" @newSave="newSave" />
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, toRefs, toRaw, reactive, defineProps, onBeforeMount, onMounted, watch, nextTick, computed } from 'vue';
|
||||
import {
|
||||
ref,
|
||||
toRefs,
|
||||
toRaw,
|
||||
reactive,
|
||||
defineProps,
|
||||
onBeforeMount,
|
||||
onMounted,
|
||||
watch,
|
||||
nextTick,
|
||||
computed
|
||||
} from 'vue';
|
||||
import { useRouter, useRoute } from 'vue-router';
|
||||
import { useStore } from 'vuex';
|
||||
import moment from 'moment';
|
||||
@@ -498,6 +562,9 @@ const logics = computed(() => {
|
||||
return nVre;
|
||||
});
|
||||
const mark = [
|
||||
/** add by zhangweiwei 20250331_ai 无效样本标记-筛选标记状态新增【AI标记】选项 start */
|
||||
{ label: 'AI标记', value: '2' },
|
||||
/** add by zhangweiwei 20250331_ai 无效样本标记-筛选标记状态新增【AI标记】选项 start */
|
||||
{ label: '已标记', value: '1' },
|
||||
{ label: '未标记', value: '0' }
|
||||
];
|
||||
@@ -711,7 +778,10 @@ const showData = {
|
||||
// 配额逻辑
|
||||
logics: [],
|
||||
// 标记状态
|
||||
isMark: ['1', '0'],
|
||||
/** modify by zhangweiwei 20250331_ai 无效样本标记-筛选标记状态新增【AI标记】选项 start */
|
||||
isMark: ['2', '1', '0'],
|
||||
/** modify by zhangweiwei 20250331_ai 无效样本标记-筛选标记状态新增【AI标记】选项 start */
|
||||
|
||||
// 数据类型
|
||||
answer_type: ['0', '1']
|
||||
};
|
||||
@@ -1119,7 +1189,8 @@ const answerAss = (el) => {
|
||||
//大于等于啥的
|
||||
if (el.operVal) data.operator = el.operVal;
|
||||
// 最后那个答案
|
||||
if (el.asVal || el.asVal == 0) data.answer = typeof el.asVal == 'object' ? el.asVal.join() : el.asVal;
|
||||
if (el.asVal || el.asVal == 0)
|
||||
data.answer = typeof el.asVal == 'object' ? el.asVal.join() : el.asVal;
|
||||
// 最后那个答案如果是时间
|
||||
if (el?.answerType == 'datetime') {
|
||||
data.answer = {};
|
||||
|
||||
@@ -4,7 +4,7 @@ const defaultOptions = {
|
||||
left_fixed_key: 'id', // 左侧固定列
|
||||
right_fixed_key: 'operation', //右侧固定列
|
||||
show_operator: true, // 是否显示操作列
|
||||
show_check: true,
|
||||
show_check: false, // 去除标记和标记原因列
|
||||
fixed: 'left'
|
||||
};
|
||||
|
||||
@@ -21,39 +21,9 @@ export default function useGeneratorTableColumns(columns, options = {}) {
|
||||
options = { ...defaultOptions, ...options };
|
||||
const tableHeaders = ref([]);
|
||||
function flatData(columns) {
|
||||
let columnsSing = {};
|
||||
let columnsType = {};
|
||||
let columnsMemo = {};
|
||||
if (options.show_check) {
|
||||
columnsSing = {
|
||||
title: '',
|
||||
key: 'is_mark',
|
||||
dataIndex: 'is_mark',
|
||||
align: 'left',
|
||||
width: 50,
|
||||
slots: { customRender: 'is_mark' },
|
||||
fixed: 'left'
|
||||
};
|
||||
// columnsType = {
|
||||
// title: '数据类型',
|
||||
// key: 'type',
|
||||
// dataIndex: 'type',
|
||||
// align: 'center',
|
||||
// width: 100,
|
||||
// slots: { customRender: 'type' },
|
||||
// fixed: 'left'
|
||||
// }
|
||||
columnsMemo = {
|
||||
title: '标记原因',
|
||||
key: 'mark_des',
|
||||
dataIndex: 'mark_des',
|
||||
align: 'left',
|
||||
width: 150,
|
||||
slots: { customRender: 'mark_des' },
|
||||
fixed: 'left'
|
||||
};
|
||||
}
|
||||
|
||||
let result = columns.reduce((previousValue, currentValue) => {
|
||||
console.log('useGeneratorTableColumns currentValue---->', currentValue);
|
||||
const arr = Object.entries(currentValue).map(([key, value]) => ({
|
||||
...value,
|
||||
key,
|
||||
@@ -63,17 +33,48 @@ export default function useGeneratorTableColumns(columns, options = {}) {
|
||||
// align: 'center',
|
||||
slots: { customRender: key }
|
||||
}));
|
||||
console.log('useGeneratorTableColumns arr---->', arr);
|
||||
return previousValue.concat(arr);
|
||||
}, []);
|
||||
console.log('useGeneratorTableColumns result---->', result);
|
||||
// 手动修改作答ID数组位置
|
||||
const snData = result.find((el) => el.key == 'id');
|
||||
result = result.filter((el) => el.key != 'id');
|
||||
// 手动修改数据类型数组位置
|
||||
const typeData = result.find((el) => el.key == 'answer_type');
|
||||
result = result.filter((el) => el.key != 'answer_type');
|
||||
|
||||
result.unshift(columnsMemo);
|
||||
// result.unshift(columnsType)
|
||||
|
||||
/** add by zhangweiwei 20250331_ai 无效样本标记-列表新增AI/人工样本标记 start */
|
||||
// 添加人工样本标记
|
||||
const manualSampleMark = {
|
||||
title: '人工样本标记',
|
||||
titleType:'withIcon', // 标题类型,带图标
|
||||
titleIconSrc: require('@/assets/img/mxd/rate2.png'), // 图标资源
|
||||
titleIconTip: 'AI智筛,精准标记', // 图标hover提示
|
||||
key: 'manual_mark',
|
||||
dataIndex: 'manual_mark',
|
||||
align: 'left',
|
||||
width: 150,
|
||||
slots: { customRender: 'manual_mark' },
|
||||
fixed: 'left'
|
||||
};
|
||||
result.unshift(manualSampleMark);
|
||||
|
||||
// 添加AI样本标记
|
||||
const aiSampleMark = {
|
||||
title: 'AI样本标记',
|
||||
titleType:'withIcon', // 标题类型,带图标
|
||||
titleIconSrc: require('@/assets/img/mxd/rate1.png'), // 图标资源
|
||||
titleIconTip: '批量处理,方便快捷', // 图标hover提示
|
||||
key: 'ai_mark',
|
||||
dataIndex: 'ai_mark',
|
||||
align: 'left',
|
||||
width: 150,
|
||||
slots: { customRender: 'ai_mark' },
|
||||
fixed: 'left'
|
||||
};
|
||||
result.unshift(aiSampleMark);
|
||||
/** add by zhangweiwei 20250331_ai 无效样本标记-列表新增AI/人工样本标记 end */
|
||||
if (typeData) {
|
||||
typeData.fixed = 'left';
|
||||
typeData.width = 100;
|
||||
@@ -84,7 +85,6 @@ export default function useGeneratorTableColumns(columns, options = {}) {
|
||||
snData.fixed = 'left';
|
||||
result.unshift(snData);
|
||||
}
|
||||
result.unshift(columnsSing);
|
||||
if (options.show_operator) {
|
||||
result.push({
|
||||
title: '操作',
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
import { ref, watch } from 'vue';
|
||||
import CustomTableHeaderCell from '@/views/DataAnalyse/components/CustomTableHeaderCell';
|
||||
export default function renderCustomHeader(columns, sn, search_params) {
|
||||
export default function renderCustomHeader(columns, sn, search_params, iconClickFunc) {
|
||||
const customHeaders = ref([]);
|
||||
|
||||
function renderCell(data, sn, search_params) {
|
||||
return <CustomTableHeaderCell data={data} sn={sn} search_params={search_params} />;
|
||||
function renderCell(data, sn, search_params, iconClickFunc) {
|
||||
return (
|
||||
<CustomTableHeaderCell
|
||||
data={data}
|
||||
sn={sn}
|
||||
search_params={search_params}
|
||||
onIconClick={iconClickFunc}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
watch(
|
||||
columns,
|
||||
(data) => {
|
||||
@@ -13,7 +21,7 @@ export default function renderCustomHeader(columns, sn, search_params) {
|
||||
customHeaders.value = data.map((item) => {
|
||||
return {
|
||||
...item,
|
||||
title: renderCell(item, sn, search_params.value)
|
||||
title: renderCell(item, sn, search_params.value, iconClickFunc)
|
||||
};
|
||||
});
|
||||
}
|
||||
@@ -29,7 +37,7 @@ export default function renderCustomHeader(columns, sn, search_params) {
|
||||
customHeaders.value = columns.value.map((item) => {
|
||||
return {
|
||||
...item,
|
||||
title: renderCell(item, sn, data)
|
||||
title: renderCell(item, sn, data, iconClickFunc)
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@@ -80,6 +80,7 @@
|
||||
@change="onPageChange"
|
||||
@select="onSelectChange"
|
||||
@sign="Sign"
|
||||
@headerClick="onHeaderClick"
|
||||
>
|
||||
<template #operation="{ record }">
|
||||
<a @click="openDetailModal(record)" style="margin-right: 5px">查看</a>
|
||||
@@ -112,7 +113,10 @@
|
||||
</DataTable>
|
||||
</div>
|
||||
</div>
|
||||
<sign-invalid-modal v-model:visible="invalidVisible" @ok="handleSignInvalid"></sign-invalid-modal>
|
||||
<sign-invalid-modal
|
||||
v-model:visible="invalidVisible"
|
||||
@ok="handleSignInvalid"
|
||||
></sign-invalid-modal>
|
||||
<download-data
|
||||
v-model:visible="downloadVisible"
|
||||
:params="queryState"
|
||||
@@ -126,7 +130,13 @@
|
||||
:sn="sn"
|
||||
@ok="handleConfig"
|
||||
></column-config> -->
|
||||
<qs-detail v-model:visible="detailVisible" :data="tableData" :detailId="detailId" :sn="sn" :type="0"></qs-detail>
|
||||
<qs-detail
|
||||
v-model:visible="detailVisible"
|
||||
:data="tableData"
|
||||
:detailId="detailId"
|
||||
:sn="sn"
|
||||
:type="0"
|
||||
></qs-detail>
|
||||
</div>
|
||||
</a-spin>
|
||||
<newModal
|
||||
@@ -142,8 +152,17 @@
|
||||
@resShowFlag="resShowFlag"
|
||||
/>
|
||||
<!-- 下载中心 -->
|
||||
<DownloadCenter v-model:visible="downloadCenterVisible" v-if="downloadCenterVisible"></DownloadCenter>
|
||||
<a-modal v-model:visible="visible" title="标记原因" ok-text="确认" cancel-text="取消" @ok="hideModal">
|
||||
<DownloadCenter
|
||||
v-model:visible="downloadCenterVisible"
|
||||
v-if="downloadCenterVisible"
|
||||
></DownloadCenter>
|
||||
<a-modal
|
||||
v-model:visible="visible"
|
||||
title="标记原因"
|
||||
ok-text="确认"
|
||||
cancel-text="取消"
|
||||
@ok="hideModal"
|
||||
>
|
||||
<a-input placeholder="请输入标记原因" :maxlength="30" v-model:value="singDesc">
|
||||
<template #prefix>
|
||||
<user-outlined type="user" />
|
||||
@@ -173,7 +192,13 @@ import ColumnConfig from './components/ColumnConfig';
|
||||
import countIcon from '@/assets/img/data_count_icon.png';
|
||||
import increaseIcon from '@/assets/img/newly_increase_icon.png';
|
||||
import { answers_export, getParticularList, delParticularItem } from '@/api/data-analyse';
|
||||
import { getNullDealConfig, answer_mark_batch, nullDeal, answer_mark, answer_mark_del } from '@/api/qc';
|
||||
import {
|
||||
getNullDealConfig,
|
||||
answer_mark_batch,
|
||||
nullDeal,
|
||||
answer_mark,
|
||||
answer_mark_del
|
||||
} from '@/api/qc';
|
||||
import { convertQueryToString } from '@utils/httpFormat';
|
||||
import DataTable from '@views/DataAnalyse/components/DataTable';
|
||||
import newDataTable from '@views/DataAnalyse/components/newDataTable';
|
||||
@@ -262,7 +287,9 @@ const selectedRowKeys = ref([]);
|
||||
|
||||
const selectedSns = computed(() => {
|
||||
return selectedRowKeys.value?.length
|
||||
? tableData.value.filter((item, index) => selectedRowKeys.value.includes(index)).map((i) => i.sn) || []
|
||||
? tableData.value
|
||||
.filter((item, index) => selectedRowKeys.value.includes(index))
|
||||
.map((i) => i.sn) || []
|
||||
: [];
|
||||
});
|
||||
|
||||
@@ -578,6 +605,21 @@ function onPageChange(data) {
|
||||
per_page.value = data.pageSize;
|
||||
getData({ page: page.value, per_page: per_page.value });
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听表头点击事件
|
||||
* @param column
|
||||
*/
|
||||
function onHeaderClick(column) {
|
||||
console.log('onHeaderClick', column);
|
||||
if (column.key === 'ai_mark') {
|
||||
console.log('AI 标记');
|
||||
} else if (column.key === 'manual_mark') {
|
||||
console.log('人工标记');
|
||||
noData();
|
||||
}
|
||||
}
|
||||
|
||||
const hideModal = (call) => {
|
||||
let memo = (singDesc.value ??= '');
|
||||
saveSing(memo);
|
||||
|
||||
@@ -179,7 +179,7 @@
|
||||
@update="editLabelUpdata"
|
||||
/>
|
||||
</a-modal>
|
||||
<!-- add by zhangweiwei 20250331_ai 智能创建助手 start -->
|
||||
<!-- add by zhangweiwei 20250331_ai 智能创建助手 start -->
|
||||
<!-- <el-drawer
|
||||
v-model="aiDrawerVisible"
|
||||
:with-header="false"
|
||||
@@ -194,21 +194,22 @@
|
||||
>
|
||||
</iframe>
|
||||
</el-drawer> -->
|
||||
<a-modal
|
||||
v-model:visible="aiDialogVisible"
|
||||
:closable="false"
|
||||
:footer="null"
|
||||
wrapClassName="ai-assistant-dialog-wrap"
|
||||
dialogClass="ai-assistant-dialog"
|
||||
>
|
||||
<iframe
|
||||
:src="aiAssistantUrl"
|
||||
style="width: 100%; height: 100%; min-height: 500px"
|
||||
frameborder="0"
|
||||
<div ref="aiAssistantWrapper" class="ai-assistant-wrapper">
|
||||
<a-modal
|
||||
v-model:visible="aiAssistantVisible"
|
||||
:getContainer="() => $refs.aiAssistantWrapper"
|
||||
:closable="false"
|
||||
:footer="null"
|
||||
>
|
||||
</iframe>
|
||||
</a-modal>
|
||||
<!-- add by zhangweiwei 20250331_ai 智能创建助手 end -->
|
||||
<iframe
|
||||
:src="aiAssistantUrl"
|
||||
style="width: 100%; height: 100%; min-height: 500px"
|
||||
frameborder="0"
|
||||
>
|
||||
</iframe>
|
||||
</a-modal>
|
||||
</div>
|
||||
<!-- add by zhangweiwei 20250331_ai 智能创建助手 end -->
|
||||
<!-- 产品测试(口味和包装) -->
|
||||
<CreateSurveyProduct
|
||||
ref="createSurveyProductRef"
|
||||
@@ -279,7 +280,7 @@ const normalRef = ref([]);
|
||||
const count = ref(5);
|
||||
const tempVisible = ref(false);
|
||||
/** add by zhangweiwei 20250331_ai 智能创建助手 start */
|
||||
const aiDialogVisible = ref(false); // AI iFrame 是否显示
|
||||
const aiAssistantVisible = ref(false); // AI iFrame 是否显示
|
||||
// const aiDrawerOpened = ref(false); // AI iFrame 是否打开
|
||||
/** add by zhangweiwei 20250331_ai 智能创建助手 end */
|
||||
const visible = ref(false);
|
||||
@@ -469,7 +470,7 @@ function createCustom(itemId) {
|
||||
if (itemId === 1) {
|
||||
console.log('智能创建');
|
||||
// 显示AI iFrame
|
||||
aiDialogVisible.value = true;
|
||||
aiAssistantVisible.value = true;
|
||||
} else if (itemId === 2) {
|
||||
console.log('空白创建');
|
||||
onCreate();
|
||||
@@ -941,13 +942,20 @@ function professionalPrev() {
|
||||
// }
|
||||
// }
|
||||
|
||||
.ant-modal-root .ant-modal-mask .ant-modal-wrap .ant-modal {
|
||||
top: 24px !important;
|
||||
width: 780px !important;
|
||||
.ant-modal-body {
|
||||
height: calc(100vh - 24px) !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
$ai-assistant-modal-top: 24px;
|
||||
|
||||
.ai-assistant-wrapper {
|
||||
:deep(.ant-modal) {
|
||||
top: $ai-assistant-modal-top !important;
|
||||
width: auto !important;
|
||||
max-width: 780px !important;
|
||||
|
||||
.ant-modal-body {
|
||||
height: calc(100vh - $ai-assistant-modal-top * 2);
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** add by zhangweiwei 20250331_ai 智能创建助手 end */
|
||||
</style>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<!-- add by zhangweiwei 20250331_ai AI 质检 新增 质检结果组件 start -->
|
||||
<template>
|
||||
<div class="ai-inspection-result" >
|
||||
<div class="ai-inspection-result">
|
||||
<i class="iconfont icon-yulan"></i>
|
||||
<div class="result-content">
|
||||
<div class="result-item" v-for="(item, index) in result" :key="index">
|
||||
<div class="result-wrap">
|
||||
<div class="result-item" v-for="(advice, index) in result" :key="index">
|
||||
<span class="result-item__index">{{ index + 1 }}</span>
|
||||
<span class="result-item__text">{{ item.text }}</span>
|
||||
<span class="result-item__text">{{ advice }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -22,34 +22,36 @@ const props = defineProps({
|
||||
.ai-inspection-result {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: first baseline;
|
||||
padding-left: calc(16px + 20px);
|
||||
color: red;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.esult-content {
|
||||
.result-wrap {
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
.result-item {
|
||||
.result-item {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin-top: 5px;
|
||||
align-items: first center;
|
||||
|
||||
&__index {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin-top: 5px;
|
||||
|
||||
&__index {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
white-space: nowrap;
|
||||
width: 18px;
|
||||
min-width: 18px;
|
||||
height: 18px;
|
||||
border: 1px solid red;
|
||||
border-radius: 50%;
|
||||
font-size: 12px;
|
||||
}
|
||||
&__text {
|
||||
margin-left: 6px;
|
||||
}
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
white-space: nowrap;
|
||||
width: 15px;
|
||||
min-width: 15px;
|
||||
height: 15px;
|
||||
border: 1px solid red;
|
||||
border-radius: 50%;
|
||||
font-size: 12px;
|
||||
}
|
||||
&__text {
|
||||
margin-left: 6px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user