choiceQuestionDetailDialog.vue 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240
  1. <template>
  2. <div class="choiceQuestionDetailDialog">
  3. <div
  4. class="content"
  5. :style="{
  6. width: slideWidth + 'px',
  7. height: slideHeight + 'px',
  8. }"
  9. >
  10. <span class="closeIcon" @click="closeSlideIndex()">
  11. <img src="../../../assets/img/close.png" />
  12. </span>
  13. <!-- 选择题 -->
  14. <div
  15. class="c_t45"
  16. v-if="workDetail && workDetail.type === '45' && props.showData"
  17. >
  18. <div class="c_t45_title">
  19. <div>{{
  20. props.showData.choiceQuestionListData[props.showData.workIndex]
  21. .teststitle
  22. }}</div>
  23. <span class="c_t45_t_btn" :class="{'c_t45_t_btn_noActive': props.showData.workIndex <= 0}" @click="changeWorkIndex(0)">上一题</span>
  24. <span class="c_t45_t_btn" :class="{'c_t45_t_btn_noActive': props.showData.workIndex >= props.showData.choiceQuestionListData.length - 1}" @click="changeWorkIndex(1)">下一题</span>
  25. </div>
  26. <img
  27. class="c_t45_img"
  28. :src="
  29. props.showData.choiceQuestionListData[props.showData.workIndex]
  30. .timuList[0].src
  31. "
  32. v-if="
  33. props.showData.choiceQuestionListData[props.showData.workIndex]
  34. .timuList.length > 0
  35. "
  36. />
  37. <span
  38. class="c_t45_type"
  39. v-if="
  40. props.showData.choiceQuestionListData[props.showData.workIndex]
  41. .type === '1'
  42. "
  43. >单选题</span
  44. >
  45. <span
  46. class="c_t45_type"
  47. v-if="
  48. props.showData.choiceQuestionListData[props.showData.workIndex]
  49. .type === '2'
  50. "
  51. >多选项</span
  52. >
  53. <div
  54. class="c_t45_echarts"
  55. :style="{
  56. width: slideWidth - 40 + 'px',
  57. }"
  58. >
  59. <div id="echartsArea1" ref="echartsArea1"></div>
  60. </div>
  61. </div>
  62. <!-- 问答题 -->
  63. <div
  64. class="c_t15"
  65. v-if="workDetail && workDetail.type === '15' && props.showData"
  66. >
  67. <div class="c_t15_title">{{ workDetail.json.answerQ }}</div>
  68. <span class="c_t15_type">问答题</span>
  69. <div class="c_t15_content" v-show="!lookWorkData">
  70. <div
  71. class="c_t15_c_item"
  72. v-for="item in workArray"
  73. :key="item.id"
  74. @click="lookWork(item.id)"
  75. >
  76. <div class="c_t15_c_i_top">
  77. <span>S</span>
  78. <div>{{ item.name }}</div>
  79. </div>
  80. <div class="c_t15_c_i_bottom">
  81. <span v-html="item.content.answer"></span>
  82. </div>
  83. </div>
  84. </div>
  85. <div class="c_t15_workDetail" v-if="lookWorkData">
  86. <div class="c_t15_wd_top">
  87. <img
  88. src="../../../assets/img/arrow_left.png"
  89. @click="lookWork('')"
  90. />
  91. <span>S</span>
  92. <div>{{ lookWorkData.name }}</div>
  93. </div>
  94. <div class="c_t15_wd_content">
  95. <span v-html="lookWorkData.content.answer"></span>
  96. <div
  97. class="c_t15_wd_c_imageList"
  98. v-if="lookWorkData.content.fileList.length > 0"
  99. >
  100. <img
  101. v-for="item in lookWorkData.content.fileList"
  102. :src="item.url"
  103. :key="item.uploadTime"
  104. @click="lookImage(item.url)"
  105. />
  106. </div>
  107. </div>
  108. </div>
  109. </div>
  110. <!-- AI应用 -->
  111. <div
  112. class="c_t72"
  113. v-if="props.showData && props.showData.toolType === 72"
  114. >
  115. <div class="c_t72_title">AI应用</div>
  116. <span class="c_t72_type">AI应用</span>
  117. <div class="c_t72_content" v-show="!lookWorkData">
  118. <div
  119. class="c_t72_c_item"
  120. v-for="item in workArray"
  121. :key="item.id"
  122. @click="lookWork(item.id)"
  123. >
  124. <div class="c_t72_c_i_top">
  125. <span>S</span>
  126. <div>{{ item.name }}</div>
  127. </div>
  128. </div>
  129. </div>
  130. <div class="c_t72_workDetail" v-if="lookWorkData">
  131. <div class="c_t72_wd_top">
  132. <img
  133. src="../../../assets/img/arrow_left.png"
  134. @click="lookWork('')"
  135. />
  136. <span>S</span>
  137. <div>{{ lookWorkData.name }}</div>
  138. </div>
  139. <div class="c_t72_wd_content">
  140. <template
  141. v-for="(item, index) in lookWorkData.content"
  142. :key="item.id"
  143. >
  144. <div class="messageNodeArea" v-if="item.messages.length">
  145. <div class="messageNode">
  146. <div class="mn_title">节点{{ index + 1 }}</div>
  147. <div class="mn_content">
  148. <template
  149. v-for="(item2, index2) in item.messages"
  150. :key="`${index}-${index2}`"
  151. >
  152. <div>
  153. <div
  154. class="na_m_item"
  155. v-if="item2.role == 'user' && item2.content"
  156. >
  157. <div class="na_m_i_name">
  158. {{ item2.sender }}
  159. </div>
  160. <div
  161. class="na_m_i_content"
  162. v-html="item2.content"
  163. ></div>
  164. </div>
  165. <div
  166. class="na_m_item"
  167. v-if="item2.role == 'assistant' && item2.content"
  168. >
  169. <div class="na_m_i_name aiName">
  170. {{ item2.sender }}
  171. </div>
  172. <div
  173. class="na_m_i_content"
  174. v-html="item2.content"
  175. ></div>
  176. </div>
  177. </div>
  178. </template>
  179. </div>
  180. </div>
  181. </div>
  182. </template>
  183. </div>
  184. </div>
  185. </div>
  186. <!-- H5页面 -->
  187. <div
  188. class="c_t73"
  189. v-if="props.showData && props.showData.toolType === 73"
  190. >
  191. <div class="c_t73_title">页面图片</div>
  192. <span class="c_t73_type">H5页面</span>
  193. <div class="c_t73_content" v-show="!lookWorkData">
  194. <div
  195. class="c_t73_c_item"
  196. v-for="item in workArray"
  197. :key="item.id"
  198. @click="lookWork(item.id)"
  199. >
  200. <div class="c_t73_c_i_top">
  201. <span>S</span>
  202. <div>{{ item.name }}</div>
  203. </div>
  204. <div class="c_t73_c_i_bottom">
  205. <img :src="item.content" />
  206. </div>
  207. </div>
  208. </div>
  209. <div class="c_t73_workDetail" v-if="lookWorkData">
  210. <div class="c_t73_wd_top">
  211. <img
  212. src="../../../assets/img/arrow_left.png"
  213. @click="lookWork('')"
  214. />
  215. <span>S</span>
  216. <div>{{ lookWorkData.name }}</div>
  217. </div>
  218. <div class="c_t73_wd_content">
  219. <img :src="lookWorkData.content" />
  220. </div>
  221. </div>
  222. </div>
  223. </div>
  224. <previewImageTool ref="previewImageToolRef" />
  225. </div>
  226. </template>
  227. <script setup lang="ts">
  228. import { computed, ref, watch, onUnmounted, nextTick } from 'vue'
  229. import * as echarts from 'echarts'
  230. import previewImageTool from '../../components/tool/previewImageTool.vue'
  231. import MarkdownIt from 'markdown-it'
  232. const props = defineProps<{
  233. visible: number[];
  234. workIndex: number;
  235. slideWidth: number;
  236. slideHeight: number;
  237. slideIndex: number;
  238. showData: any;
  239. workArray: any[];
  240. }>()
  241. const emit = defineEmits<{
  242. (e: 'update:visible', v: number[]): void;
  243. (e: 'changeWorkIndex', v: number): void;
  244. }>()
  245. const visible = computed({
  246. get: () => props.visible,
  247. set: (v: number[]) => emit('update:visible', v),
  248. })
  249. const workDetail = computed(() => {
  250. if (props.showData) {
  251. return props.showData.workDetail
  252. }
  253. return null
  254. })
  255. // 预览图片组件
  256. const previewImageToolRef = ref<any>(null)
  257. const md = new MarkdownIt()
  258. const workArray = computed(() => {
  259. let _result = []
  260. if (props.workArray) {
  261. const _workArray = JSON.parse(JSON.stringify(props.workArray))
  262. if ([45, 15].includes(props.showData.toolType)) {
  263. _workArray.forEach((i: any) => {
  264. i.content = JSON.parse(decodeURIComponent(i.content))
  265. })
  266. }
  267. if (props.showData.toolType === 72) {
  268. _workArray.forEach((i: any) => {
  269. i.content = JSON.parse(i.content)
  270. i.content.forEach((item: any) => {
  271. if (item.messages.length) {
  272. item.messages.forEach((item2: any) => {
  273. // 如果已经包含html标签则不再渲染
  274. if (
  275. !/^(\s*<[^>]+>.*<\/[^>]+>\s*|<[^>]+\/>\s*)$/s.test(
  276. item2.content.trim()
  277. )
  278. ) {
  279. item2.content = md.render(item2.content)
  280. }
  281. })
  282. }
  283. })
  284. })
  285. }
  286. _result = _workArray
  287. }
  288. return _result
  289. })
  290. // 关闭对应的作业详细页面
  291. const closeSlideIndex = () => {
  292. visible.value = visible.value.filter((v) => v !== props.slideIndex)
  293. }
  294. // 切换题目
  295. const changeWorkIndex = (type:number) => {
  296. emit('changeWorkIndex', type)
  297. // console.log(props.workIndex, props.showData.choiceQuestionListData.length)
  298. // if (type === 0 && props.workIndex > 0) {
  299. // emit('changeWorkIndex', 0)
  300. // }
  301. // else if (type === 1 && props.workIndex < props.showData.choiceQuestionListData.length) {
  302. // emit('changeWorkIndex', props.workIndex + 1)
  303. // }
  304. }
  305. // 选择题图表div
  306. const echartsArea1 = ref<any>(null)
  307. // 查看的作业详细id
  308. const lookWorkDetail = ref<string>('')
  309. // 查看作业详细的数据
  310. const lookWorkData = computed(() => {
  311. let _result = null
  312. if (lookWorkDetail.value && workArray.value.length > 0) {
  313. const _workFind = workArray.value.find(
  314. (i: any) => i.id === lookWorkDetail.value
  315. )
  316. if (_workFind) {
  317. _result = _workFind
  318. }
  319. }
  320. return _result
  321. })
  322. // 查看图片
  323. const lookImage = (url: string) => {
  324. if (previewImageToolRef.value) {
  325. previewImageToolRef.value.previewImage(url)
  326. }
  327. }
  328. // 查看作业
  329. const lookWork = (id: string) => {
  330. lookWorkDetail.value = id
  331. }
  332. // 选择题图表实例
  333. const myChart = ref<any>(null)
  334. // resize防抖定时器
  335. let resizeTimer: ReturnType<typeof setTimeout> | null = null
  336. // 处理ECharts resize
  337. const handleChartResize = () => {
  338. // 清除之前的定时器
  339. if (resizeTimer) {
  340. clearTimeout(resizeTimer)
  341. }
  342. resizeTimer = setTimeout(() => {
  343. nextTick(() => {
  344. if (
  345. myChart.value &&
  346. typeof myChart.value.resize === 'function' &&
  347. !myChart.value.isDisposed()
  348. ) {
  349. try {
  350. myChart.value.resize()
  351. }
  352. catch (e) {
  353. // console.error('myChart resize error:', e)
  354. // 如果resize失败,重新初始化图表
  355. if (
  356. props.showData &&
  357. props.showData.workDetail &&
  358. props.showData.workDetail.type === '45'
  359. ) {
  360. setEchartsArea1()
  361. }
  362. }
  363. }
  364. })
  365. }, 200) // 防抖延迟200ms
  366. }
  367. // 设置选择题图表
  368. const setEchartsArea1 = () => {
  369. // 如果已有实例且未销毁,先销毁
  370. if (myChart.value && !myChart.value.isDisposed()) {
  371. myChart.value.dispose()
  372. }
  373. if (echartsArea1.value) {
  374. myChart.value = echarts.init(echartsArea1.value)
  375. }
  376. else {
  377. myChart.value = null
  378. }
  379. if (myChart.value) {
  380. const _work =
  381. props.showData.choiceQuestionListData[props.showData.workIndex]
  382. // 修正版,处理xAxis.data内为图片对象的case,formatter始终只拿到src或自定义label,保证无[object Object]问题
  383. const option = {
  384. tooltip: {
  385. show: false, // 禁用鼠标移动到柱体时的内容显示
  386. },
  387. yAxis: {
  388. show: false, // 不显示最左边的y轴
  389. },
  390. xAxis: {
  391. data: [],
  392. axisLabel: {
  393. color: 'rgba(0, 0, 0, 0.9)',
  394. fontWeight: 600,
  395. fontSize: 17,
  396. lineHeight: 20,
  397. interval: 0,
  398. formatter: function(value: any, idx: number) {
  399. // 如果是字符串且格式为JSON(图片),则解析处理
  400. if (typeof value === 'string') {
  401. try {
  402. const obj = JSON.parse(value)
  403. if (obj && typeof obj === 'object' && obj.imgType && obj.src) {
  404. return '{img' + idx + '|}'
  405. }
  406. }
  407. catch (e) {
  408. // 非JSON字符串,直接返回
  409. // 如果文本文字超过8个字,换行
  410. if (typeof value === 'string') {
  411. let displayValue = value
  412. if (value.length > 20) {
  413. displayValue = value.substr(0, 20) + '...'
  414. }
  415. // 8个字换行
  416. let output = ''
  417. for (let i = 0; i < displayValue.length; i += 8) {
  418. output += displayValue.substr(i, 8)
  419. if (i + 8 < displayValue.length) {
  420. output += '\n'
  421. }
  422. }
  423. return output
  424. }
  425. return value
  426. }
  427. return value
  428. }
  429. // 兼容老格式(容错):value本身是对象,并有图片信息
  430. if (
  431. value &&
  432. typeof value === 'object' &&
  433. value.imgType &&
  434. value.src
  435. ) {
  436. return '{img' + idx + '|}'
  437. }
  438. // 其他类型直接空
  439. return ''
  440. },
  441. rich: (() => {
  442. // 动态生成所有图片的 rich 格式
  443. const richObj: any = {}
  444. _work.choiceUser.forEach((op: any, idx: number) => {
  445. if (
  446. op.option &&
  447. typeof op.option === 'object' &&
  448. op.option.imgType &&
  449. op.option.src
  450. ) {
  451. richObj['img' + idx] = {
  452. height: 40,
  453. width: 40,
  454. align: 'center',
  455. backgroundColor: {
  456. image: op.option.src,
  457. },
  458. }
  459. }
  460. })
  461. return richObj
  462. })(),
  463. },
  464. },
  465. series: [
  466. {
  467. name: '',
  468. type: 'bar',
  469. data: [],
  470. barWidth: '50%', // 柱体宽度缩小40%
  471. itemStyle: {
  472. color: 'rgba(252, 207, 0, 1)',
  473. },
  474. label: {
  475. show: true,
  476. position: 'top',
  477. color: 'rgba(116, 139, 115, 1)',
  478. fontSize: 22,
  479. fontWeight: 500,
  480. lineHeight: 24,
  481. },
  482. },
  483. ],
  484. }
  485. _work.choiceUser.forEach((i: any, idx: number) => {
  486. // 如果是图片,存src对象,否则为字符串
  487. if (
  488. i.option &&
  489. typeof i.option === 'object' &&
  490. i.option.imgType &&
  491. i.option.src
  492. ) {
  493. (option.xAxis.data as any[]).push(
  494. JSON.stringify({ imgType: i.option.imgType, src: i.option.src })
  495. ) // 仅保留相关字段
  496. }
  497. else if (typeof i.option === 'string') {
  498. (option.xAxis.data as any[]).push(i.option)
  499. }
  500. else {
  501. (option.xAxis.data as any[]).push('')
  502. }
  503. (option.series[0].data as any[]).push(i.user.length)
  504. })
  505. console.log(option)
  506. // {
  507. // title: {
  508. // text: 'ECharts 入门示例'
  509. // },
  510. // tooltip: {},
  511. // xAxis: {
  512. // data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
  513. // },
  514. // yAxis: {},
  515. // series: [
  516. // {
  517. // name: '销量',
  518. // type: 'bar',
  519. // data: [5, 20, 36, 10, 10, 20]
  520. // }
  521. // ]
  522. // }
  523. myChart.value.setOption(option)
  524. }
  525. }
  526. // 监听选择题数据变化
  527. watch(
  528. () => props.showData,
  529. (newVal, oldVal) => {
  530. console.log('发生变化,showData')
  531. if (
  532. newVal &&
  533. newVal.choiceQuestionListData[newVal.workIndex] &&
  534. props.showData.workDetail.type === '45'
  535. ) {
  536. if (
  537. oldVal &&
  538. newVal.choiceQuestionListData[newVal.workIndex] &&
  539. oldVal.choiceQuestionListData[oldVal.workIndex]
  540. ) {
  541. if (
  542. JSON.stringify(newVal.choiceQuestionListData[newVal.workIndex]) !==
  543. JSON.stringify(oldVal.choiceQuestionListData[oldVal.workIndex])
  544. ) {
  545. setEchartsArea1()
  546. }
  547. }
  548. }
  549. else {
  550. myChart.value = null
  551. }
  552. },
  553. { immediate: true, deep: true }
  554. )
  555. // 监听作业变化
  556. watch(
  557. () => props.showData?.choiceQuestionListData,
  558. (newVal, oldVal) => {
  559. console.log('choiceQuestionListData变化了')
  560. if (
  561. (newVal || newVal === 0) &&
  562. props.showData.workDetail &&
  563. props.showData.workDetail.type === '45'
  564. ) {
  565. if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
  566. setEchartsArea1()
  567. }
  568. else {
  569. console.log('choiceQuestionListData没有变化')
  570. }
  571. }
  572. else {
  573. myChart.value = null
  574. }
  575. },
  576. { deep: true }
  577. )
  578. // 监听作业变化
  579. watch(
  580. () => props.showData?.workIndex,
  581. (newVal) => {
  582. if (
  583. (newVal || newVal === 0) &&
  584. props.showData.workDetail &&
  585. props.showData.workDetail.type === '45'
  586. ) {
  587. setEchartsArea1()
  588. }
  589. else {
  590. myChart.value = null
  591. }
  592. }
  593. )
  594. // 监听echartsArea1变化
  595. watch(
  596. () => echartsArea1.value,
  597. (newVal) => {
  598. if (
  599. newVal &&
  600. props.showData &&
  601. props.showData.workDetail &&
  602. props.showData.workDetail.type === '45'
  603. ) {
  604. setEchartsArea1()
  605. }
  606. else {
  607. myChart.value = null
  608. }
  609. }
  610. )
  611. // 监听页面宽度变化
  612. watch(
  613. () => props.slideWidth,
  614. (newVal) => {
  615. if (
  616. newVal &&
  617. props.showData &&
  618. props.showData.workDetail &&
  619. props.showData.workDetail.type === '45'
  620. ) {
  621. handleChartResize()
  622. }
  623. }
  624. )
  625. // 组件卸载时清理ECharts实例
  626. onUnmounted(() => {
  627. // 清除定时器
  628. if (resizeTimer) {
  629. clearTimeout(resizeTimer)
  630. resizeTimer = null
  631. }
  632. // 销毁ECharts实例
  633. if (myChart.value && !myChart.value.isDisposed()) {
  634. myChart.value.dispose()
  635. myChart.value = null
  636. }
  637. })
  638. </script>
  639. <style lang="scss" scoped>
  640. .choiceQuestionDetailDialog {
  641. background: none;
  642. position: relative;
  643. width: 100%;
  644. height: 100%;
  645. z-index: 1;
  646. .content {
  647. width: 100%;
  648. height: 100%;
  649. position: relative;
  650. background: #fff;
  651. box-sizing: border-box;
  652. padding: 40px;
  653. overflow: auto;
  654. .closeIcon {
  655. position: absolute;
  656. right: 20px;
  657. top: 20px;
  658. cursor: pointer;
  659. width: 20px;
  660. height: 20px;
  661. img {
  662. width: 100%;
  663. height: 100%;
  664. }
  665. }
  666. .c_t45 {
  667. width: 100%;
  668. min-height: 100%;
  669. display: flex;
  670. align-items: center;
  671. flex-direction: column;
  672. height: auto;
  673. .c_t45_title {
  674. color: rgba(0, 0, 0, 0.9);
  675. font-weight: 600;
  676. font-size: 24px;
  677. line-height: 24px;
  678. position: relative;
  679. width: 100%;
  680. display: flex;
  681. align-items: center;
  682. justify-content: center;
  683. user-select: none;
  684. &>div{
  685. max-width: calc(100% - 200px);
  686. }
  687. &>span{
  688. position: absolute;
  689. top: 20px;
  690. cursor: pointer;
  691. &:nth-of-type(1){
  692. left: 0;
  693. }
  694. &:nth-of-type(2){
  695. right: 0;
  696. }
  697. }
  698. .c_t45_t_btn_noActive{
  699. color: #CCCCCC;
  700. }
  701. }
  702. .c_t45_img {
  703. max-width: 200px;
  704. object-fit: cover;
  705. margin-top: 20px;
  706. }
  707. .c_t45_type {
  708. font-weight: 400;
  709. font-size: 15px;
  710. line-height: 21px;
  711. letter-spacing: 0.5px;
  712. color: rgba(0, 0, 0, 1);
  713. opacity: 0.5;
  714. margin-top: 20px;
  715. }
  716. .c_t45_echarts {
  717. width: 100%;
  718. flex: 1;
  719. min-height: 400px;
  720. display: flex;
  721. align-items: center;
  722. box-sizing: border-box;
  723. & > div {
  724. width: 100%;
  725. height: 400px;
  726. }
  727. }
  728. }
  729. .c_t15 {
  730. width: 100%;
  731. min-height: 100%;
  732. display: flex;
  733. align-items: center;
  734. flex-direction: column;
  735. height: auto;
  736. padding: 40px;
  737. .c_t15_title {
  738. color: rgba(0, 0, 0, 0.9);
  739. font-weight: 600;
  740. font-size: 24px;
  741. line-height: 24px;
  742. }
  743. .c_t15_type {
  744. font-weight: 400;
  745. font-size: 15px;
  746. line-height: 21px;
  747. letter-spacing: 0.5px;
  748. color: rgba(0, 0, 0, 1);
  749. opacity: 0.5;
  750. margin-top: 20px;
  751. }
  752. .c_t15_content {
  753. width: 100%;
  754. height: auto;
  755. display: grid;
  756. grid-template-columns: repeat(3, 1fr);
  757. gap: 20px;
  758. margin-top: 40px;
  759. .c_t15_c_item {
  760. width: 100%;
  761. height: auto;
  762. box-shadow: 2px 4px 20px 0px rgba(0, 0, 0, 0.2);
  763. box-sizing: border-box;
  764. border-radius: 12px;
  765. padding: 16px;
  766. background: rgba(255, 255, 255, 0.6);
  767. transition: 0.3s;
  768. cursor: pointer;
  769. &:hover {
  770. box-shadow: 4px 4px 14px 0px rgba(252, 207, 0, 0.5);
  771. background: rgba(255, 255, 255, 0.6);
  772. }
  773. .c_t15_c_i_top {
  774. display: flex;
  775. align-items: center;
  776. gap: 10px;
  777. & > span {
  778. display: block;
  779. width: 25px;
  780. height: 25px;
  781. display: flex;
  782. align-items: center;
  783. justify-content: center;
  784. background: rgba(252, 207, 0, 1);
  785. border-radius: 4px;
  786. color: rgba(255, 255, 255, 1);
  787. font-weight: bold;
  788. font-size: 14px;
  789. }
  790. & > div {
  791. color: rgba(0, 0, 0, 0.7);
  792. font-weight: 800;
  793. }
  794. }
  795. .c_t15_c_i_bottom {
  796. margin-top: 15px;
  797. font-weight: 300;
  798. font-size: 14px;
  799. height: 40px;
  800. max-width: 100%;
  801. overflow: hidden;
  802. text-overflow: ellipsis;
  803. display: -webkit-box;
  804. -webkit-line-clamp: 2;
  805. -webkit-box-orient: vertical;
  806. }
  807. }
  808. }
  809. .c_t15_workDetail {
  810. width: 100%;
  811. height: auto;
  812. margin-top: 40px;
  813. box-shadow: 4px 4px 14px 0px rgba(252, 207, 0, 0.5);
  814. box-sizing: border-box;
  815. padding: 16px;
  816. border-radius: 12px;
  817. display: flex;
  818. flex-direction: column;
  819. .c_t15_wd_top {
  820. width: 100%;
  821. display: flex;
  822. align-items: center;
  823. gap: 15px;
  824. & > img {
  825. width: 25px;
  826. height: 25px;
  827. cursor: pointer;
  828. }
  829. & > span {
  830. display: block;
  831. width: 30px;
  832. height: 30px;
  833. display: flex;
  834. align-items: center;
  835. justify-content: center;
  836. background: rgba(252, 207, 0, 1);
  837. border-radius: 4px;
  838. color: rgba(255, 255, 255, 1);
  839. font-weight: bold;
  840. font-size: 16px;
  841. }
  842. & > div {
  843. color: rgba(0, 0, 0, 0.7);
  844. font-weight: 800;
  845. font-size: 18px;
  846. }
  847. }
  848. .c_t15_wd_content {
  849. width: 100%;
  850. margin-top: 20px;
  851. max-height: 100%;
  852. overflow: auto;
  853. flex-wrap: wrap;
  854. .c_t15_wd_c_imageList {
  855. width: 100%;
  856. gap: 20px;
  857. margin-top: 20px;
  858. & > img {
  859. width: 100px;
  860. height: auto;
  861. cursor: pointer;
  862. margin-right: 20px;
  863. object-fit: cover;
  864. }
  865. }
  866. }
  867. }
  868. }
  869. .c_t72 {
  870. width: 100%;
  871. min-height: 100%;
  872. display: flex;
  873. align-items: center;
  874. flex-direction: column;
  875. height: auto;
  876. padding: 40px;
  877. .c_t72_title {
  878. color: rgba(0, 0, 0, 0.9);
  879. font-weight: 600;
  880. font-size: 24px;
  881. line-height: 24px;
  882. }
  883. .c_t72_type {
  884. font-weight: 400;
  885. font-size: 15px;
  886. line-height: 21px;
  887. letter-spacing: 0.5px;
  888. color: rgba(0, 0, 0, 1);
  889. opacity: 0.5;
  890. margin-top: 20px;
  891. }
  892. .c_t72_content {
  893. width: 100%;
  894. height: auto;
  895. display: grid;
  896. grid-template-columns: repeat(4, 1fr);
  897. gap: 20px;
  898. margin-top: 40px;
  899. .c_t72_c_item {
  900. width: 100%;
  901. height: auto;
  902. box-shadow: 2px 4px 20px 0px rgba(0, 0, 0, 0.2);
  903. box-sizing: border-box;
  904. border-radius: 12px;
  905. padding: 16px;
  906. background: rgba(255, 255, 255, 0.6);
  907. transition: 0.3s;
  908. cursor: pointer;
  909. &:hover {
  910. box-shadow: 4px 4px 14px 0px rgba(252, 207, 0, 0.5);
  911. background: rgba(255, 255, 255, 0.6);
  912. }
  913. .c_t72_c_i_top {
  914. display: flex;
  915. align-items: center;
  916. gap: 10px;
  917. & > span {
  918. display: block;
  919. width: 25px;
  920. height: 25px;
  921. display: flex;
  922. align-items: center;
  923. justify-content: center;
  924. background: rgba(252, 207, 0, 1);
  925. border-radius: 4px;
  926. color: rgba(255, 255, 255, 1);
  927. font-weight: bold;
  928. font-size: 14px;
  929. }
  930. & > div {
  931. color: rgba(0, 0, 0, 0.7);
  932. font-weight: 800;
  933. }
  934. }
  935. .c_t72_c_i_bottom {
  936. margin-top: 15px;
  937. font-weight: 300;
  938. font-size: 14px;
  939. // height: 40px;
  940. max-width: 100%;
  941. overflow: hidden;
  942. text-overflow: ellipsis;
  943. display: -webkit-box;
  944. -webkit-line-clamp: 2;
  945. -webkit-box-orient: vertical;
  946. img {
  947. width: 100%;
  948. max-height: 200px;
  949. object-fit: cover;
  950. }
  951. }
  952. }
  953. }
  954. .c_t72_workDetail {
  955. width: 100%;
  956. height: auto;
  957. margin-top: 40px;
  958. box-shadow: 4px 4px 14px 0px rgba(252, 207, 0, 0.5);
  959. box-sizing: border-box;
  960. padding: 16px;
  961. border-radius: 12px;
  962. display: flex;
  963. flex-direction: column;
  964. .c_t72_wd_top {
  965. width: 100%;
  966. display: flex;
  967. align-items: center;
  968. gap: 15px;
  969. & > img {
  970. width: 25px;
  971. height: 25px;
  972. cursor: pointer;
  973. }
  974. & > span {
  975. display: block;
  976. width: 30px;
  977. height: 30px;
  978. display: flex;
  979. align-items: center;
  980. justify-content: center;
  981. background: rgba(252, 207, 0, 1);
  982. border-radius: 4px;
  983. color: rgba(255, 255, 255, 1);
  984. font-weight: bold;
  985. font-size: 16px;
  986. }
  987. & > div {
  988. color: rgba(0, 0, 0, 0.7);
  989. font-weight: 800;
  990. font-size: 18px;
  991. }
  992. }
  993. .c_t72_wd_content {
  994. width: 100%;
  995. margin-top: 20px;
  996. max-height: 100%;
  997. overflow: auto;
  998. flex-wrap: wrap;
  999. display: flex;
  1000. align-items: center;
  1001. justify-content: center;
  1002. .na_m_item {
  1003. width: 100%;
  1004. height: auto;
  1005. margin: 10px 0;
  1006. }
  1007. .na_m_i_name {
  1008. width: fit-content;
  1009. max-width: 100%;
  1010. height: auto;
  1011. box-sizing: border-box;
  1012. padding: 10px 10px;
  1013. display: flex;
  1014. align-items: center;
  1015. border-radius: 10px 10px 0 0;
  1016. background-color: #9747ff;
  1017. color: #fff;
  1018. text-overflow: ellipsis;
  1019. overflow: hidden;
  1020. white-space: nowrap;
  1021. }
  1022. .aiName {
  1023. background-color: #0560fc;
  1024. }
  1025. .na_m_i_content {
  1026. padding: 10px;
  1027. border: solid 1px #e7e7e7;
  1028. box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.1);
  1029. border-radius: 0 0 12px 12px;
  1030. background-color: #fff;
  1031. }
  1032. .messageNode {
  1033. width: 100%;
  1034. height: auto;
  1035. box-sizing: border-box;
  1036. padding: 10px 10px;
  1037. border: 0.5px solid #e7e7e7;
  1038. border-radius: 12px;
  1039. gap: 10px;
  1040. margin-top: 20px;
  1041. }
  1042. .messageNodeArea{
  1043. width: 100%;
  1044. height: auto;
  1045. }
  1046. }
  1047. }
  1048. }
  1049. .c_t73 {
  1050. width: 100%;
  1051. min-height: 100%;
  1052. display: flex;
  1053. align-items: center;
  1054. flex-direction: column;
  1055. height: auto;
  1056. padding: 40px;
  1057. .c_t73_title {
  1058. color: rgba(0, 0, 0, 0.9);
  1059. font-weight: 600;
  1060. font-size: 24px;
  1061. line-height: 24px;
  1062. }
  1063. .c_t73_type {
  1064. font-weight: 400;
  1065. font-size: 15px;
  1066. line-height: 21px;
  1067. letter-spacing: 0.5px;
  1068. color: rgba(0, 0, 0, 1);
  1069. opacity: 0.5;
  1070. margin-top: 20px;
  1071. }
  1072. .c_t73_content {
  1073. width: 100%;
  1074. height: auto;
  1075. display: grid;
  1076. grid-template-columns: repeat(4, 1fr);
  1077. gap: 20px;
  1078. margin-top: 40px;
  1079. .c_t73_c_item {
  1080. width: 100%;
  1081. height: auto;
  1082. box-shadow: 2px 4px 20px 0px rgba(0, 0, 0, 0.2);
  1083. box-sizing: border-box;
  1084. border-radius: 12px;
  1085. padding: 16px;
  1086. background: rgba(255, 255, 255, 0.6);
  1087. transition: 0.3s;
  1088. cursor: pointer;
  1089. &:hover {
  1090. box-shadow: 4px 4px 14px 0px rgba(252, 207, 0, 0.5);
  1091. background: rgba(255, 255, 255, 0.6);
  1092. }
  1093. .c_t73_c_i_top {
  1094. display: flex;
  1095. width: 100%;
  1096. align-items: center;
  1097. gap: 10px;
  1098. & > span {
  1099. display: block;
  1100. width: 25px;
  1101. height: 25px;
  1102. display: flex;
  1103. align-items: center;
  1104. justify-content: center;
  1105. background: rgba(252, 207, 0, 1);
  1106. border-radius: 4px;
  1107. color: rgba(255, 255, 255, 1);
  1108. font-weight: bold;
  1109. font-size: 14px;
  1110. }
  1111. & > div {
  1112. color: rgba(0, 0, 0, 0.7);
  1113. font-weight: 800;
  1114. }
  1115. }
  1116. .c_t73_c_i_bottom {
  1117. margin-top: 15px;
  1118. font-weight: 300;
  1119. font-size: 14px;
  1120. // height: 40px;
  1121. max-width: 100%;
  1122. overflow: hidden;
  1123. text-overflow: ellipsis;
  1124. display: -webkit-box;
  1125. -webkit-line-clamp: 2;
  1126. -webkit-box-orient: vertical;
  1127. img {
  1128. width: 100%;
  1129. max-height: 200px;
  1130. object-fit: cover;
  1131. }
  1132. }
  1133. }
  1134. }
  1135. .c_t73_workDetail {
  1136. width: 100%;
  1137. height: auto;
  1138. margin-top: 40px;
  1139. box-shadow: 4px 4px 14px 0px rgba(252, 207, 0, 0.5);
  1140. box-sizing: border-box;
  1141. padding: 16px;
  1142. border-radius: 12px;
  1143. display: flex;
  1144. flex-direction: column;
  1145. .c_t73_wd_top {
  1146. width: 100%;
  1147. display: flex;
  1148. align-items: center;
  1149. gap: 15px;
  1150. & > img {
  1151. width: 25px;
  1152. height: 25px;
  1153. cursor: pointer;
  1154. }
  1155. & > span {
  1156. display: block;
  1157. width: 30px;
  1158. height: 30px;
  1159. display: flex;
  1160. align-items: center;
  1161. justify-content: center;
  1162. background: rgba(252, 207, 0, 1);
  1163. border-radius: 4px;
  1164. color: rgba(255, 255, 255, 1);
  1165. font-weight: bold;
  1166. font-size: 16px;
  1167. }
  1168. & > div {
  1169. color: rgba(0, 0, 0, 0.7);
  1170. font-weight: 800;
  1171. font-size: 18px;
  1172. }
  1173. }
  1174. .c_t73_wd_content {
  1175. width: 100%;
  1176. margin-top: 20px;
  1177. max-height: 100%;
  1178. overflow: auto;
  1179. flex-wrap: wrap;
  1180. display: flex;
  1181. align-items: center;
  1182. justify-content: center;
  1183. & > img {
  1184. max-width: 100%;
  1185. object-fit: cover;
  1186. }
  1187. }
  1188. }
  1189. }
  1190. }
  1191. }
  1192. </style>