洞察报告;
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
<div id="tinys" class="tiny" :class="{ 'tiny-curtail': curtail, 'popup-menu-align-right': popupMenuAlignRight }">
|
<div id="tinys" class="tiny" :class="{ 'tiny-curtail': curtail, 'popup-menu-align-right': popupMenuAlignRight }">
|
||||||
<Editor
|
<Editor
|
||||||
v-model="content"
|
v-model="content"
|
||||||
|
:disabled="disabled"
|
||||||
:style="{ minHeight: `${curtailMinHeight}px` }"
|
:style="{ minHeight: `${curtailMinHeight}px` }"
|
||||||
:init="init"
|
:init="init"
|
||||||
style="overflow-wrap: break-word; word-break: break-word;"
|
style="overflow-wrap: break-word; word-break: break-word;"
|
||||||
@@ -408,6 +409,10 @@ export default {
|
|||||||
type: String,
|
type: String,
|
||||||
default: "请输入",
|
default: "请输入",
|
||||||
},
|
},
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
defaultFontSize: {
|
defaultFontSize: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 14,
|
default: 14,
|
||||||
@@ -668,6 +673,7 @@ function initTinymce(data) {
|
|||||||
skin_url: `${baseOss}/tinymce/skins/ui/oxide`,
|
skin_url: `${baseOss}/tinymce/skins/ui/oxide`,
|
||||||
menubar: false, // 隐藏菜单栏
|
menubar: false, // 隐藏菜单栏
|
||||||
statusbar: false,
|
statusbar: false,
|
||||||
|
placeholder: props.placeholder,
|
||||||
fixed_toolbar_container: "#tinys",
|
fixed_toolbar_container: "#tinys",
|
||||||
inline: true, // 开启内联模式
|
inline: true, // 开启内联模式
|
||||||
auto_focus: true,
|
auto_focus: true,
|
||||||
@@ -766,6 +772,7 @@ function initTinymce(data) {
|
|||||||
skin_url: `${baseOss}/tinymce/skins/ui/oxide`,
|
skin_url: `${baseOss}/tinymce/skins/ui/oxide`,
|
||||||
menubar: false, // 隐藏菜单栏
|
menubar: false, // 隐藏菜单栏
|
||||||
statusbar: false,
|
statusbar: false,
|
||||||
|
placeholder: props.placeholder,
|
||||||
height: 144,
|
height: 144,
|
||||||
auto_focus: true,
|
auto_focus: true,
|
||||||
max_height: 350,
|
max_height: 350,
|
||||||
@@ -1378,4 +1385,10 @@ function util(store) {
|
|||||||
:deep(.tox-collection__item-label){
|
:deep(.tox-collection__item-label){
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
:deep(.tox .tox-toolbar__overflow) {
|
||||||
|
margin-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
:deep(.tox .tox-toolbar__primary) {
|
||||||
|
border-top: none !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -54,6 +54,48 @@
|
|||||||
<div class="content unicode" style="display: block;">
|
<div class="content unicode" style="display: block;">
|
||||||
<ul class="icon_lists dib-box">
|
<ul class="icon_lists dib-box">
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont"></span>
|
||||||
|
<div class="name">分享报告</div>
|
||||||
|
<div class="code-name">&#xe870;</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont"></span>
|
||||||
|
<div class="name">更新报告</div>
|
||||||
|
<div class="code-name">&#xe873;</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont"></span>
|
||||||
|
<div class="name">洞察报告</div>
|
||||||
|
<div class="code-name">&#xe879;</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont"></span>
|
||||||
|
<div class="name">icon_BPTO</div>
|
||||||
|
<div class="code-name">&#xe86f;</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont"></span>
|
||||||
|
<div class="name">icon_recording</div>
|
||||||
|
<div class="code-name">&#xe86e;</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont"></span>
|
||||||
|
<div class="name">icon_Export Password</div>
|
||||||
|
<div class="code-name">&#xe86d;</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont"></span>
|
||||||
|
<div class="name">icon_autogenerate</div>
|
||||||
|
<div class="code-name">&#xe86b;</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li class="dib">
|
<li class="dib">
|
||||||
<span class="icon iconfont"></span>
|
<span class="icon iconfont"></span>
|
||||||
<div class="name">icon_timer</div>
|
<div class="name">icon_timer</div>
|
||||||
@@ -3510,9 +3552,9 @@
|
|||||||
<pre><code class="language-css"
|
<pre><code class="language-css"
|
||||||
>@font-face {
|
>@font-face {
|
||||||
font-family: 'iconfont';
|
font-family: 'iconfont';
|
||||||
src: url('iconfont.woff2?t=1698731786246') format('woff2'),
|
src: url('iconfont.woff2?t=1726032533651') format('woff2'),
|
||||||
url('iconfont.woff?t=1698731786246') format('woff'),
|
url('iconfont.woff?t=1726032533651') format('woff'),
|
||||||
url('iconfont.ttf?t=1698731786246') format('truetype');
|
url('iconfont.ttf?t=1726032533651') format('truetype');
|
||||||
}
|
}
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
|
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
|
||||||
@@ -3538,6 +3580,69 @@
|
|||||||
<div class="content font-class">
|
<div class="content font-class">
|
||||||
<ul class="icon_lists dib-box">
|
<ul class="icon_lists dib-box">
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont icon-fenxiangbaogao"></span>
|
||||||
|
<div class="name">
|
||||||
|
分享报告
|
||||||
|
</div>
|
||||||
|
<div class="code-name">.icon-fenxiangbaogao
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont icon-gengxinbaogao"></span>
|
||||||
|
<div class="name">
|
||||||
|
更新报告
|
||||||
|
</div>
|
||||||
|
<div class="code-name">.icon-gengxinbaogao
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont icon-shujumingxi2"></span>
|
||||||
|
<div class="name">
|
||||||
|
洞察报告
|
||||||
|
</div>
|
||||||
|
<div class="code-name">.icon-shujumingxi2
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont icon-icon_BPTO"></span>
|
||||||
|
<div class="name">
|
||||||
|
icon_BPTO
|
||||||
|
</div>
|
||||||
|
<div class="code-name">.icon-icon_BPTO
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont icon-icon_recording"></span>
|
||||||
|
<div class="name">
|
||||||
|
icon_recording
|
||||||
|
</div>
|
||||||
|
<div class="code-name">.icon-icon_recording
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont icon-a-icon_ExportPassword"></span>
|
||||||
|
<div class="name">
|
||||||
|
icon_Export Password
|
||||||
|
</div>
|
||||||
|
<div class="code-name">.icon-a-icon_ExportPassword
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<span class="icon iconfont icon-icon_autogenerate"></span>
|
||||||
|
<div class="name">
|
||||||
|
icon_autogenerate
|
||||||
|
</div>
|
||||||
|
<div class="code-name">.icon-icon_autogenerate
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li class="dib">
|
<li class="dib">
|
||||||
<span class="icon iconfont icon-icon_timer"></span>
|
<span class="icon iconfont icon-icon_timer"></span>
|
||||||
<div class="name">
|
<div class="name">
|
||||||
@@ -8722,6 +8827,62 @@
|
|||||||
<div class="content symbol">
|
<div class="content symbol">
|
||||||
<ul class="icon_lists dib-box">
|
<ul class="icon_lists dib-box">
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<svg class="icon svg-icon" aria-hidden="true">
|
||||||
|
<use xlink:href="#icon-fenxiangbaogao"></use>
|
||||||
|
</svg>
|
||||||
|
<div class="name">分享报告</div>
|
||||||
|
<div class="code-name">#icon-fenxiangbaogao</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<svg class="icon svg-icon" aria-hidden="true">
|
||||||
|
<use xlink:href="#icon-gengxinbaogao"></use>
|
||||||
|
</svg>
|
||||||
|
<div class="name">更新报告</div>
|
||||||
|
<div class="code-name">#icon-gengxinbaogao</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<svg class="icon svg-icon" aria-hidden="true">
|
||||||
|
<use xlink:href="#icon-shujumingxi2"></use>
|
||||||
|
</svg>
|
||||||
|
<div class="name">洞察报告</div>
|
||||||
|
<div class="code-name">#icon-shujumingxi2</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<svg class="icon svg-icon" aria-hidden="true">
|
||||||
|
<use xlink:href="#icon-icon_BPTO"></use>
|
||||||
|
</svg>
|
||||||
|
<div class="name">icon_BPTO</div>
|
||||||
|
<div class="code-name">#icon-icon_BPTO</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<svg class="icon svg-icon" aria-hidden="true">
|
||||||
|
<use xlink:href="#icon-icon_recording"></use>
|
||||||
|
</svg>
|
||||||
|
<div class="name">icon_recording</div>
|
||||||
|
<div class="code-name">#icon-icon_recording</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<svg class="icon svg-icon" aria-hidden="true">
|
||||||
|
<use xlink:href="#icon-a-icon_ExportPassword"></use>
|
||||||
|
</svg>
|
||||||
|
<div class="name">icon_Export Password</div>
|
||||||
|
<div class="code-name">#icon-a-icon_ExportPassword</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="dib">
|
||||||
|
<svg class="icon svg-icon" aria-hidden="true">
|
||||||
|
<use xlink:href="#icon-icon_autogenerate"></use>
|
||||||
|
</svg>
|
||||||
|
<div class="name">icon_autogenerate</div>
|
||||||
|
<div class="code-name">#icon-icon_autogenerate</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li class="dib">
|
<li class="dib">
|
||||||
<svg class="icon svg-icon" aria-hidden="true">
|
<svg class="icon svg-icon" aria-hidden="true">
|
||||||
<use xlink:href="#icon-icon_timer"></use>
|
<use xlink:href="#icon-icon_timer"></use>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
@font-face {
|
@font-face {
|
||||||
font-family: "iconfont"; /* Project id 3121635 */
|
font-family: "iconfont"; /* Project id 3121635 */
|
||||||
src: url('iconfont.woff2?t=1698731786246') format('woff2'),
|
src: url('iconfont.woff2?t=1726032533651') format('woff2'),
|
||||||
url('iconfont.woff?t=1698731786246') format('woff'),
|
url('iconfont.woff?t=1726032533651') format('woff'),
|
||||||
url('iconfont.ttf?t=1698731786246') format('truetype');
|
url('iconfont.ttf?t=1726032533651') format('truetype');
|
||||||
}
|
}
|
||||||
|
|
||||||
.iconfont {
|
.iconfont {
|
||||||
@@ -13,6 +13,34 @@
|
|||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-fenxiangbaogao:before {
|
||||||
|
content: "\e870";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-gengxinbaogao:before {
|
||||||
|
content: "\e873";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-shujumingxi2:before {
|
||||||
|
content: "\e879";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-icon_BPTO:before {
|
||||||
|
content: "\e86f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-icon_recording:before {
|
||||||
|
content: "\e86e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-a-icon_ExportPassword:before {
|
||||||
|
content: "\e86d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-icon_autogenerate:before {
|
||||||
|
content: "\e86b";
|
||||||
|
}
|
||||||
|
|
||||||
.icon-icon_timer:before {
|
.icon-icon_timer:before {
|
||||||
content: "\e86c";
|
content: "\e86c";
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -5,6 +5,55 @@
|
|||||||
"css_prefix_text": "icon-",
|
"css_prefix_text": "icon-",
|
||||||
"description": "调研猩球前台icon",
|
"description": "调研猩球前台icon",
|
||||||
"glyphs": [
|
"glyphs": [
|
||||||
|
{
|
||||||
|
"icon_id": "41476175",
|
||||||
|
"name": "分享报告",
|
||||||
|
"font_class": "fenxiangbaogao",
|
||||||
|
"unicode": "e870",
|
||||||
|
"unicode_decimal": 59504
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "41476179",
|
||||||
|
"name": "更新报告",
|
||||||
|
"font_class": "gengxinbaogao",
|
||||||
|
"unicode": "e873",
|
||||||
|
"unicode_decimal": 59507
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "41812315",
|
||||||
|
"name": "洞察报告",
|
||||||
|
"font_class": "shujumingxi2",
|
||||||
|
"unicode": "e879",
|
||||||
|
"unicode_decimal": 59513
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "38184565",
|
||||||
|
"name": "icon_BPTO",
|
||||||
|
"font_class": "icon_BPTO",
|
||||||
|
"unicode": "e86f",
|
||||||
|
"unicode_decimal": 59503
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "38180243",
|
||||||
|
"name": "icon_recording",
|
||||||
|
"font_class": "icon_recording",
|
||||||
|
"unicode": "e86e",
|
||||||
|
"unicode_decimal": 59502
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "37956036",
|
||||||
|
"name": "icon_Export Password",
|
||||||
|
"font_class": "a-icon_ExportPassword",
|
||||||
|
"unicode": "e86d",
|
||||||
|
"unicode_decimal": 59501
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon_id": "37956037",
|
||||||
|
"name": "icon_autogenerate",
|
||||||
|
"font_class": "icon_autogenerate",
|
||||||
|
"unicode": "e86b",
|
||||||
|
"unicode_decimal": 59499
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"icon_id": "37621370",
|
"icon_id": "37621370",
|
||||||
"name": "icon_timer",
|
"name": "icon_timer",
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -217,7 +217,7 @@ export default defineComponent({
|
|||||||
if(checkShowInsightTab({ templateType: store.state.common.surveyInfo.template_type })) {
|
if(checkShowInsightTab({ templateType: store.state.common.surveyInfo.template_type })) {
|
||||||
menus.value.unshift({
|
menus.value.unshift({
|
||||||
name: '洞察报告',
|
name: '洞察报告',
|
||||||
icon: '',
|
icon: '',
|
||||||
children: [],
|
children: [],
|
||||||
path: '/survey/analyse/insight'
|
path: '/survey/analyse/insight'
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue'
|
import { onBeforeUnmount, ref } from 'vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { Modal } from 'ant-design-vue'
|
import { Modal } from 'ant-design-vue'
|
||||||
|
|
||||||
@@ -10,13 +10,17 @@ import InsightShare from './components/InsightShare.vue'
|
|||||||
import Report from './report/Report.vue'
|
import Report from './report/Report.vue'
|
||||||
|
|
||||||
|
|
||||||
import { editInsightReport, getInsightReport, updateInsightReport } from './api'
|
import { editInsightReport, getInsightReport, checkReportStatus, updateInsightReport } from './api'
|
||||||
|
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const sn = route.query.sn || ''
|
const sn = route.query.sn || ''
|
||||||
|
|
||||||
|
const initialized = ref(false)
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
|
const updating = ref(false) // 更新报告
|
||||||
|
let timer = 1
|
||||||
|
|
||||||
const report = ref({})
|
const report = ref({})
|
||||||
|
|
||||||
const saving = ref(0)
|
const saving = ref(0)
|
||||||
@@ -38,6 +42,11 @@ async function getReport() {
|
|||||||
initSaveParams()
|
initSaveParams()
|
||||||
|
|
||||||
loading.value = false
|
loading.value = false
|
||||||
|
|
||||||
|
if(!initialized.value) {
|
||||||
|
startLooping()
|
||||||
|
}
|
||||||
|
initialized.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
function initSaveParams() {
|
function initSaveParams() {
|
||||||
@@ -87,17 +96,14 @@ function onGenerateReport(isInit) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function onConfirmGenerateReport() {
|
async function onConfirmGenerateReport() {
|
||||||
if(loading.value) {
|
if(updating.value) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
loading.value = true
|
updating.value = true
|
||||||
|
|
||||||
const params = { surveySn: sn }
|
const params = { surveySn: sn }
|
||||||
await updateInsightReport(params).catch(() => '')
|
await updateInsightReport(params).catch(() => '')
|
||||||
|
await getReport()
|
||||||
loading.value = false
|
|
||||||
|
|
||||||
getReport()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -127,17 +133,73 @@ function mergeReport(params) {
|
|||||||
Object.keys(params.actions).forEach((key) => result[key] = params.actions[key])
|
Object.keys(params.actions).forEach((key) => result[key] = params.actions[key])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function startLooping() {
|
||||||
|
if(!timer) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
timer = setTimeout(() => {
|
||||||
|
getReportStatus()
|
||||||
|
}, 3e3)
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopLooping() {
|
||||||
|
clearTimeout(timer)
|
||||||
|
timer = null
|
||||||
|
}
|
||||||
|
|
||||||
|
onBeforeUnmount(stopLooping)
|
||||||
|
|
||||||
|
|
||||||
|
async function getReportStatus() {
|
||||||
|
const params = {
|
||||||
|
sn,
|
||||||
|
reportVersion: report.value.reportVersionReal,
|
||||||
|
likeModelWordCloudStatus: report.value.likeModelWordCloudStatus,
|
||||||
|
hateModelWordCloudStatus: report.value.hateModelWordCloudStatus
|
||||||
|
}
|
||||||
|
const data = await checkReportStatus(params).catch(() => '')
|
||||||
|
|
||||||
|
// 0=默认,不需要处理
|
||||||
|
// 1=有新的报告产生,且未完成,不可以进行更新报告,需要置灰
|
||||||
|
// 2=有新的报告产生,已完成,需要重新请求报告展示接口
|
||||||
|
// 3=老报告的词云更新完了,需要重新请求报告展示接口
|
||||||
|
|
||||||
|
switch(data?.data?.code) {
|
||||||
|
case 0:
|
||||||
|
updating.value = false
|
||||||
|
break
|
||||||
|
case 1:
|
||||||
|
updating.value = true
|
||||||
|
break
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
await getReport()
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
startLooping()
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<a-spin v-if="loading" :spinning="loading" tip="加载中" class="spinning" />
|
<a-spin v-if="!initialized"
|
||||||
|
:spinning="true"
|
||||||
|
tip="加载中"
|
||||||
|
class="spinning" />
|
||||||
|
|
||||||
<div v-else class="insight-page">
|
<div v-else class="insight-page">
|
||||||
<InsightEmpty v-if="!report?.id" @generate="onGenerateReport" />
|
<InsightEmpty v-if="!report?.id" @generate="onGenerateReport" />
|
||||||
|
|
||||||
<template v-if="report?.id">
|
<template v-if="report?.id">
|
||||||
<InsightShare :report="report" :saving="saving" @regenerate="onGenerateReport" />
|
<InsightShare :report="report"
|
||||||
|
:saving="saving"
|
||||||
|
:updating="updating"
|
||||||
|
@regenerate="onGenerateReport" />
|
||||||
|
|
||||||
<Report :report="report" @change="editReport" />
|
<Report :report="report" :updating="updating" @change="editReport" />
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -29,6 +29,20 @@ export function getInsightReport(params) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查状态
|
||||||
|
* @param data
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
export function checkReportStatus(data) {
|
||||||
|
return request({
|
||||||
|
url: `/console/insightReport/${ data.sn }/status`,
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改洞察报告
|
* 修改洞察报告
|
||||||
* @param data
|
* @param data
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { defineEmits, defineProps, ref } from 'vue'
|
import { defineEmits, defineProps, ref, watch } from 'vue'
|
||||||
import { message } from 'ant-design-vue'
|
import { message } from 'ant-design-vue'
|
||||||
import { InfoCircleOutlined } from '@ant-design/icons-vue'
|
import { InfoCircleOutlined } from '@ant-design/icons-vue'
|
||||||
|
|
||||||
@@ -11,7 +11,8 @@ import useCopy from '@/composables/useCopy'
|
|||||||
const emits = defineEmits(['regenerate'])
|
const emits = defineEmits(['regenerate'])
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
report: { type: Object, default: () => Object.assign({}) },
|
report: { type: Object, default: () => Object.assign({}) },
|
||||||
saving: { type: Number, default: 0 }
|
saving: { type: Number, default: 0 },
|
||||||
|
updating: { type: Boolean, default: false }
|
||||||
})
|
})
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
@@ -104,7 +105,15 @@ async function onCopy() {
|
|||||||
message.success('复制成功')
|
message.success('复制成功')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const updating = ref(false)
|
||||||
|
watch(() => props.updating, (val) => updating.value = !!val, { immediate: true })
|
||||||
|
|
||||||
function onUpdateReport() {
|
function onUpdateReport() {
|
||||||
|
if(updating.value) {
|
||||||
|
message.info('问卷更新中')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
emits('regenerate')
|
emits('regenerate')
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -162,12 +171,14 @@ function onUpdateReport() {
|
|||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
|
|
||||||
<a-button class="custom-button button mr-20" @click.stop="onShowShare">
|
<a-button class="custom-button button mr-20" @click.stop="onShowShare">
|
||||||
<img src="../img/icon_share.png" alt="" class="icon">
|
<span class="iconfont icon-fenxiangbaogao" />
|
||||||
<span>分享报告</span>
|
<span>分享报告</span>
|
||||||
</a-button>
|
</a-button>
|
||||||
|
|
||||||
<a-button class="custom-button button mr-10" @click="onUpdateReport">
|
<a-button class="custom-button button mr-10"
|
||||||
<img src="../img/icon_refresh.png" alt="" class="icon">
|
:class="{'updating': updating}"
|
||||||
|
@click="onUpdateReport">
|
||||||
|
<span class="iconfont icon-gengxinbaogao" />
|
||||||
<span>更新报告</span>
|
<span>更新报告</span>
|
||||||
</a-button>
|
</a-button>
|
||||||
|
|
||||||
@@ -218,6 +229,42 @@ function onUpdateReport() {
|
|||||||
height: 16px;
|
height: 16px;
|
||||||
margin-right: 4px;
|
margin-right: 4px;
|
||||||
border: none;
|
border: none;
|
||||||
|
animation: all 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconfont {
|
||||||
|
display: block;
|
||||||
|
height: 1em;
|
||||||
|
line-height: 1em;
|
||||||
|
font-size: 16px;
|
||||||
|
margin-right: 4px;
|
||||||
|
animation: all 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.updating {
|
||||||
|
cursor: not-allowed;
|
||||||
|
|
||||||
|
.iconfont {
|
||||||
|
animation-name: icon-rotation;
|
||||||
|
animation-duration: 1.2s;
|
||||||
|
animation-direction: normal;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
animation-timing-function: linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes icon-rotation {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,3 +11,5 @@ export function checkShowInsightTab({ templateType } = {}) {
|
|||||||
return templateType && showInsightTemplateType.includes(templateType)
|
return templateType && showInsightTemplateType.includes(templateType)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export const reportUpdatingMessageText = '报告更新中,不能修改'
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 706 B |
Binary file not shown.
|
Before Width: | Height: | Size: 455 B |
@@ -14,11 +14,13 @@ import ConceptDiagnosis from './section/conceptDiagnosis/ConceptDiagnosis.vue'
|
|||||||
const emits = defineEmits(['change'])
|
const emits = defineEmits(['change'])
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
report: { type: Object, default: () => Object.assign({}) },
|
report: { type: Object, default: () => Object.assign({}) },
|
||||||
readonly: { type: Boolean, default: false }
|
readonly: { type: Boolean, default: false },
|
||||||
|
updating: { type: Boolean, default: false } // 报告更新中
|
||||||
})
|
})
|
||||||
|
|
||||||
const report = computed(() => props.report || {})
|
const report = computed(() => props.report || {})
|
||||||
const readonly = computed(() => props.readonly || false)
|
const readonly = computed(() => props.readonly || false)
|
||||||
|
const updating = computed(() => props.updating || false)
|
||||||
|
|
||||||
// 快测版报告内容和标准版基本一致,区别为快测版没有概念诊断部分
|
// 快测版报告内容和标准版基本一致,区别为快测版没有概念诊断部分
|
||||||
// 看板类型:1=标准版,2=快测版,3=配对版
|
// 看板类型:1=标准版,2=快测版,3=配对版
|
||||||
@@ -56,6 +58,7 @@ function onChange(evt) {
|
|||||||
:is="com"
|
:is="com"
|
||||||
:report="report"
|
:report="report"
|
||||||
:readonly="readonly"
|
:readonly="readonly"
|
||||||
|
:updating="updating"
|
||||||
@change="onChange" />
|
@change="onChange" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ const props = defineProps({
|
|||||||
barTable: { type: Boolean, default: false },
|
barTable: { type: Boolean, default: false },
|
||||||
selectionRowTitle: { type: Array, default: () => ['是否通过概念行动标准'] }, // 表格第一列的值为这几个值的时候,这一样其余列要显示“是”“否”选择框
|
selectionRowTitle: { type: Array, default: () => ['是否通过概念行动标准'] }, // 表格第一列的值为这几个值的时候,这一样其余列要显示“是”“否”选择框
|
||||||
readonly: { type: Boolean, default: false },
|
readonly: { type: Boolean, default: false },
|
||||||
|
updating: { type: Boolean, default: false }, // 报告更新中
|
||||||
|
|
||||||
rowTitleColumnWidth: { type: Number, default: 280 }, // 表格行头部的宽度
|
rowTitleColumnWidth: { type: Number, default: 280 }, // 表格行头部的宽度
|
||||||
rowSecondTitleColumnWidth: { type: Number, default: 280 }, // 表格行头部第二列的宽度
|
rowSecondTitleColumnWidth: { type: Number, default: 280 }, // 表格行头部第二列的宽度
|
||||||
@@ -294,6 +295,7 @@ function updateSelectionChange(record) {
|
|||||||
</template>
|
</template>
|
||||||
<a-select v-else
|
<a-select v-else
|
||||||
v-model:value="record[column.dataIndex]"
|
v-model:value="record[column.dataIndex]"
|
||||||
|
:disabled="props.updating"
|
||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
class="custom-select"
|
class="custom-select"
|
||||||
style="width: 90px;"
|
style="width: 90px;"
|
||||||
|
|||||||
@@ -66,8 +66,6 @@ function initWordCloud() {
|
|||||||
}
|
}
|
||||||
chart.setOption(option)
|
chart.setOption(option)
|
||||||
|
|
||||||
console.log('====', option)
|
|
||||||
|
|
||||||
chart.on('click', (param) => {
|
chart.on('click', (param) => {
|
||||||
emits('change', param.data)
|
emits('change', param.data)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ import Section from '../../components/Section.vue'
|
|||||||
const emits = defineEmits(['change'])
|
const emits = defineEmits(['change'])
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
report: { type: Object, default: () => Object.assign({}) },
|
report: { type: Object, default: () => Object.assign({}) },
|
||||||
readonly: { type: Boolean, default: false }
|
readonly: { type: Boolean, default: false },
|
||||||
|
updating: { type: Boolean, default: false } // 报告更新中
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@@ -36,6 +37,7 @@ function onBlur() {
|
|||||||
</Section>
|
</Section>
|
||||||
<Section v-else class="section">
|
<Section v-else class="section">
|
||||||
<Tinymce v-model:editorData="richText"
|
<Tinymce v-model:editorData="richText"
|
||||||
|
:disabled="props.updating"
|
||||||
:curtail="false"
|
:curtail="false"
|
||||||
:curtail-min-height="140"
|
:curtail-min-height="140"
|
||||||
show
|
show
|
||||||
@@ -57,6 +59,7 @@ function onBlur() {
|
|||||||
:deep(.tiny) {
|
:deep(.tiny) {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
|
background: unset;
|
||||||
|
|
||||||
.tox-tinymce {
|
.tox-tinymce {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { defineEmits, defineProps, ref, watch } from 'vue'
|
import { defineEmits, defineProps, ref, watch } from 'vue'
|
||||||
|
import { message } from 'ant-design-vue'
|
||||||
import { EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons-vue'
|
import { EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons-vue'
|
||||||
|
|
||||||
|
|
||||||
@@ -7,11 +8,14 @@ import SectionTitle from '../../components/SectionTitle.vue'
|
|||||||
import Section from '../../components/Section.vue'
|
import Section from '../../components/Section.vue'
|
||||||
import StyledTable from '../components/StyledTable.vue'
|
import StyledTable from '../components/StyledTable.vue'
|
||||||
|
|
||||||
|
import { reportUpdatingMessageText } from '../../consts'
|
||||||
|
|
||||||
|
|
||||||
const emits = defineEmits(['change'])
|
const emits = defineEmits(['change'])
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
report: { type: Object, default: () => Object.assign({}) },
|
report: { type: Object, default: () => Object.assign({}) },
|
||||||
readonly: { type: Boolean, default: false }
|
readonly: { type: Boolean, default: false },
|
||||||
|
updating: { type: Boolean, default: false } // 报告更新中
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@@ -102,12 +106,22 @@ function getTableCodeRow(tableData) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function toggleVisible(item) {
|
function toggleVisible(item) {
|
||||||
|
if(props.updating) {
|
||||||
|
message.warning(reportUpdatingMessageText)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
item.visible = !item.visible
|
item.visible = !item.visible
|
||||||
|
|
||||||
emits('change', { [item.visibleField]: item.visible ? 1 : 2 })
|
emits('change', { [item.visibleField]: item.visible ? 1 : 2 })
|
||||||
}
|
}
|
||||||
|
|
||||||
function onChange(evt) {
|
function onChange(evt) {
|
||||||
|
if(props.updating) {
|
||||||
|
message.warning(reportUpdatingMessageText)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
emits('change', evt)
|
emits('change', evt)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -121,6 +135,7 @@ function onChange(evt) {
|
|||||||
:row-title-column-width="item.rowTitleColumnWidth"
|
:row-title-column-width="item.rowTitleColumnWidth"
|
||||||
:row-second-title-column-width="item.rowSecondTitleColumnWidth"
|
:row-second-title-column-width="item.rowSecondTitleColumnWidth"
|
||||||
:readonly="props.readonly"
|
:readonly="props.readonly"
|
||||||
|
:updating="props.updating"
|
||||||
@change="onChange" />
|
@change="onChange" />
|
||||||
|
|
||||||
<div class="message">
|
<div class="message">
|
||||||
@@ -135,8 +150,14 @@ function onChange(evt) {
|
|||||||
<template #tab>
|
<template #tab>
|
||||||
<span>{{ item.name }}</span>
|
<span>{{ item.name }}</span>
|
||||||
<template v-if="item.canHide && !props.readonly">
|
<template v-if="item.canHide && !props.readonly">
|
||||||
<EyeOutlined v-if="item.visible" class="icon" @click.stop="toggleVisible(item)" />
|
<EyeOutlined v-if="item.visible"
|
||||||
<EyeInvisibleOutlined v-else class="icon" @click.stop="toggleVisible(item)" />
|
class="icon"
|
||||||
|
:class="{'disabled': props.updating}"
|
||||||
|
@click.stop="toggleVisible(item)" />
|
||||||
|
<EyeInvisibleOutlined v-else
|
||||||
|
class="icon"
|
||||||
|
:class="{'disabled': props.updating}"
|
||||||
|
@click.stop="toggleVisible(item)" />
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -145,6 +166,7 @@ function onChange(evt) {
|
|||||||
:row-title-column-width="item.rowTitleColumnWidth"
|
:row-title-column-width="item.rowTitleColumnWidth"
|
||||||
:row-second-title-column-width="item.rowSecondTitleColumnWidth"
|
:row-second-title-column-width="item.rowSecondTitleColumnWidth"
|
||||||
:readonly="props.readonly"
|
:readonly="props.readonly"
|
||||||
|
:updating="props.updating"
|
||||||
@change="onChange" />
|
@change="onChange" />
|
||||||
|
|
||||||
<div class="message">
|
<div class="message">
|
||||||
@@ -182,6 +204,10 @@ function onChange(evt) {
|
|||||||
margin-left: 6px;
|
margin-left: 6px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #B9B9B9;
|
color: #B9B9B9;
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.message {
|
.message {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { computed, defineEmits, defineProps, ref } from 'vue'
|
import { computed, defineEmits, defineProps, ref } from 'vue'
|
||||||
|
import { message } from 'ant-design-vue'
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
|
|
||||||
import { EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons-vue'
|
import { EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons-vue'
|
||||||
@@ -8,11 +9,14 @@ import { EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons-vue'
|
|||||||
import SectionTitle from '../../components/SectionTitle.vue'
|
import SectionTitle from '../../components/SectionTitle.vue'
|
||||||
import Section from '../../components/Section.vue'
|
import Section from '../../components/Section.vue'
|
||||||
|
|
||||||
|
import { reportUpdatingMessageText } from '../../consts'
|
||||||
|
|
||||||
|
|
||||||
const emits = defineEmits(['change'])
|
const emits = defineEmits(['change'])
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
report: { type: Object, default: () => Object.assign({}) },
|
report: { type: Object, default: () => Object.assign({}) },
|
||||||
readonly: { type: Boolean, default: false }
|
readonly: { type: Boolean, default: false },
|
||||||
|
updating: { type: Boolean, default: false } // 报告更新中
|
||||||
})
|
})
|
||||||
|
|
||||||
const createdAt = computed(() => props.report?.createdAt ? moment(props.report.createdAt).format('YYYY年MM月DD日 HH:mm:ss') : '--')
|
const createdAt = computed(() => props.report?.createdAt ? moment(props.report.createdAt).format('YYYY年MM月DD日 HH:mm:ss') : '--')
|
||||||
@@ -27,6 +31,11 @@ const reportVersion = computed(() => props.report?.reportVersion ?? '--')
|
|||||||
const visible = ref(+props.report.overviewHidden === 1)
|
const visible = ref(+props.report.overviewHidden === 1)
|
||||||
|
|
||||||
function toggleVisibility() {
|
function toggleVisibility() {
|
||||||
|
if(props.updating) {
|
||||||
|
message.warning(reportUpdatingMessageText)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
visible.value = !visible.value
|
visible.value = !visible.value
|
||||||
|
|
||||||
emits('change', { overviewHidden: visible.value ? 1 : 2 })
|
emits('change', { overviewHidden: visible.value ? 1 : 2 })
|
||||||
@@ -38,8 +47,14 @@ function toggleVisibility() {
|
|||||||
<SectionTitle>
|
<SectionTitle>
|
||||||
<span class="text">报告概览</span>
|
<span class="text">报告概览</span>
|
||||||
<template v-if="!props.readonly">
|
<template v-if="!props.readonly">
|
||||||
<EyeOutlined v-if="visible" class="icon" @click="toggleVisibility" />
|
<EyeOutlined v-if="visible"
|
||||||
<EyeInvisibleOutlined v-else class="icon" @click.stop="toggleVisibility" />
|
class="icon"
|
||||||
|
:class="{'disabled': props.updating}"
|
||||||
|
@click="toggleVisibility" />
|
||||||
|
<EyeInvisibleOutlined v-else
|
||||||
|
class="icon"
|
||||||
|
:class="{'disabled': props.updating}"
|
||||||
|
@click.stop="toggleVisibility" />
|
||||||
</template>
|
</template>
|
||||||
</SectionTitle>
|
</SectionTitle>
|
||||||
|
|
||||||
@@ -85,6 +100,10 @@ function toggleVisibility() {
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #B9B9B9;
|
color: #B9B9B9;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.section {
|
.section {
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ import Section from '../../components/Section.vue'
|
|||||||
const emits = defineEmits(['change'])
|
const emits = defineEmits(['change'])
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
report: { type: Object, default: () => Object.assign({}) },
|
report: { type: Object, default: () => Object.assign({}) },
|
||||||
readonly: { type: Boolean, default: false }
|
readonly: { type: Boolean, default: false },
|
||||||
|
updating: { type: Boolean, default: false } // 报告更新中
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@@ -43,6 +44,7 @@ function onBlur() {
|
|||||||
</div>
|
</div>
|
||||||
<div v-else class="value tinymce-wrapper">
|
<div v-else class="value tinymce-wrapper">
|
||||||
<Tinymce v-model:editorData="richText"
|
<Tinymce v-model:editorData="richText"
|
||||||
|
:disabled="props.updating"
|
||||||
:curtail="false"
|
:curtail="false"
|
||||||
:curtail-min-height="140"
|
:curtail-min-height="140"
|
||||||
show
|
show
|
||||||
@@ -84,6 +86,7 @@ function onBlur() {
|
|||||||
:deep(.tiny) {
|
:deep(.tiny) {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
|
background: unset;
|
||||||
|
|
||||||
.tox-tinymce {
|
.tox-tinymce {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|||||||
@@ -90,11 +90,11 @@ watch(() => props.report, () => {
|
|||||||
<a-tabs v-model:activeKey="activeKey" :animated="false">
|
<a-tabs v-model:activeKey="activeKey" :animated="false">
|
||||||
<a-tab-pane v-for="(item) in tabList" :key="item.key" :tab="item.name">
|
<a-tab-pane v-for="(item) in tabList" :key="item.key" :tab="item.name">
|
||||||
<div class="tab-container">
|
<div class="tab-container">
|
||||||
|
<PeopleDislike :type-str="item.name"
|
||||||
|
:data="item.children.find((child) => child.type.indexOf('不喜欢') > -1)" />
|
||||||
<PeopleLike title="消费者喜欢的方面"
|
<PeopleLike title="消费者喜欢的方面"
|
||||||
:type-str="item.name"
|
:type-str="item.name"
|
||||||
:data="item.children.find((child) => child.type.indexOf('喜欢') > -1 && child.type.indexOf('不喜欢') === -1)" />
|
:data="item.children.find((child) => child.type.indexOf('喜欢') > -1 && child.type.indexOf('不喜欢') === -1)" />
|
||||||
<PeopleDislike :type-str="item.name"
|
|
||||||
:data="item.children.find((child) => child.type.indexOf('不喜欢') > -1)" />
|
|
||||||
|
|
||||||
<ProductImage :report="props.report" />
|
<ProductImage :report="props.report" />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user