smarter.vue 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404
  1. <template>
  2. <div class="pb_content">
  3. <div style="width:100%;padding:0;box-sizing: border-box;">
  4. <div class="pb_head top">
  5. <div class="pb_head_t_left">
  6. <span class="subClick" @click="
  7. goTo(
  8. '/test?userid=' +
  9. userid +
  10. '&oid=' +
  11. oid +
  12. '&org=' +
  13. org +
  14. '&role=' +
  15. role
  16. )
  17. ">表单管理</span>
  18. <!-- v-show="oid == '4c686762-1d0a-11ed-8c78-005056b86db5'" -->
  19. <span class="subClick" @click="
  20. goTo(
  21. '/trainCourse?userid=' +
  22. userid +
  23. '&oid=' +
  24. oid +
  25. '&org=' +
  26. org +
  27. '&role=' +
  28. role
  29. )
  30. ">培训管理</span>
  31. <span class="subClick" v-if="examineData.length" @click="
  32. goTo(
  33. '/testDataBoard?userid=' +
  34. userid +
  35. '&oid=' +
  36. oid +
  37. '&org=' +
  38. org +
  39. '&role=' +
  40. role
  41. )
  42. ">数据看板</span>
  43. <span class="sub_head">智能助手</span>
  44. </div>
  45. <!-- <div class="pb_head_t_right">
  46. <el-tooltip class="item" effect="dark" content="预览" placement="bottom">
  47. <span class="preview_icon"></span>
  48. </el-tooltip>
  49. <el-tooltip class="item" effect="dark" content="文件" placement="bottom">
  50. <span class="case_icon"></span>
  51. </el-tooltip>
  52. <el-tooltip class="item" effect="dark" content="问题" placement="bottom">
  53. <span class="problem_icon"></span>
  54. </el-tooltip>
  55. </div> -->
  56. </div>
  57. </div>
  58. <div class="cc_bottom">
  59. <div class="cc_b_left" :style="`width:${openLeft?'13%':'50px'}`">
  60. <div class="menu_container" v-if="openLeft">
  61. <div @click="activeMenu = 1" :class="{active: activeMenu === 1}">
  62. <span :class="['session_icon',{active: activeMenu === 1}]"></span>
  63. <div>当前会话</div>
  64. </div>
  65. <div @click="activeMenu = 2" :class="{active: activeMenu === 2}">
  66. <span :class="['history_icon',{active: activeMenu === 2}]"></span>
  67. <div>历史会话</div>
  68. </div>
  69. <!-- <div :class="['cc_b_l_menu', { active: activeMenu === 1 }]" @click="activeMenu = 1">
  70. <span :class="['session_icon', { active: activeMenu === 1 }]"></span>
  71. <div v-if="openLeft" style="margin-left: 10px;margin-top: 1px;font-size: 15px;">当前会话</div>
  72. </div>
  73. <div :class="['cc_b_l_menu', { active: activeMenu === 2 }]" @click="activeMenu = 2">
  74. <span :class="['history_icon', { active: activeMenu === 2 }]"></span>
  75. <div v-if="openLeft" style="margin-left: 10px;margin-top: 1px;font-size: 15px;">历史会话</div>
  76. </div> -->
  77. <!--<div :class="['cc_b_l_menu', { active: activeMenu === 3 }]" @click="activeMenu = 3">
  78. <span :class="['mysql_icon', { active: activeMenu === 3 }]"></span>
  79. <div style="margin-left: 10px;margin-top: 1px;font-size: 15px;">数据库管理</div>
  80. </div> -->
  81. </div>
  82. <div class="menu_container" v-if="!openLeft">
  83. <span @click="activeMenu = 1" :class="{active: activeMenu === 1}"><span :class="['session_icon',{active: activeMenu === 1}]"></span></span>
  84. <span @click="activeMenu = 2" :class="{active: activeMenu === 2}"><span :class="['history_icon',{active: activeMenu === 2}]"></span></span>
  85. </div>
  86. <div class="fold_btn">
  87. <span class="more_icon" :style="`transform: rotate(${openLeft?0:180}deg);`" @click="openLeft=!openLeft"></span>
  88. </div>
  89. </div>
  90. <div v-show="activeMenu == 1" style="width:100%;display: flex;">
  91. <div class="cc_b_middle">
  92. <div style="width:100%;height: 100%;">
  93. <aiLeader :courseId="aiBoxRightCid" :worksArray="courseInfoList" :formList="menuList" ref="aiChat"
  94. @pushFileData="pushFileData" @clearFileData="clearFileData"></aiLeader>
  95. </div>
  96. </div>
  97. <div class="cc_b_right">
  98. <div v-if="showFileUrl" style="width: 100%;height: 100%;">
  99. <div style="display: flex;">
  100. <div :class="['preview_file', { active: fileMenu === 1 }]" @click="fileMenu = 1">文件预览</div>
  101. <div :class="['bianji_file', { active: fileMenu === 2 }]" @click="fileMenu = 2">文案编辑</div>
  102. </div>
  103. <div v-show="fileMenu == 1" style=" width: 100%;height: calc(100% - 40px);">
  104. <div class="cc_b_r_menu">
  105. <div v-for="(item, index) in menuList" @click="changeMenuIndex(index)" :key="index"
  106. :class="{ 'cc_b_r_menu_active': menuIndex == index }">
  107. <el-tooltip class="item" effect="dark" :content="item.name" placement="top">
  108. <span>{{ item.name }}</span>
  109. </el-tooltip>
  110. <!-- <div class="cc_b_r_btn"> -->
  111. <span class="close_icon" :class="{ active: menuIndex == index }"
  112. @click="deleteMenuItem(index)"></span>
  113. <!-- </div> -->
  114. </div>
  115. </div>
  116. <div class="cc_b_r_content">
  117. <csvTableView v-if="showFileUrl" :url="showFileUrl" />
  118. </div>
  119. </div>
  120. <div v-show="fileMenu == 2" style="width: 100%;height: calc(100% - 40px)">
  121. <div class="bianji_area">
  122. <span>
  123. <img @click="downUserAsk" src="../../../assets/icon/test/down_icon.svg">
  124. </span>
  125. <Editor @change="(value)=>userAsk = value" style="width: 100%;height: 100%;" :value="userAsk"/>
  126. <!-- <span contenteditable="true" class="userAsk">{{ userAsk }}</span> -->
  127. <!-- <span class="aiText" contenteditable="true" v-html="bianjiText"></span>
  128. <span v-if="!userAsk" style="display: flex;justify-content: center;">暂无数据</span> -->
  129. </div>
  130. </div>
  131. </div>
  132. <div v-else style="margin: 40px 0px 0px 20px">
  133. <div>--官方能力演示--</div>
  134. <div class="b_r_menu">
  135. <div class="b_r_menu_content">
  136. <div class="m_c_title">数据处理</div>
  137. <div class="m_c_item">缺失值处理</div>
  138. <div class="m_c_item">无效样本处理</div>
  139. <div class="m_c_item">数据降维</div>
  140. </div>
  141. <div class="b_r_menu_content">
  142. <div class="m_c_title">数据分析</div>
  143. <div class="m_c_item">线性回归</div>
  144. <div class="m_c_item">相关性分析</div>
  145. <div class="m_c_item">关联分心</div>
  146. </div>
  147. <div class="b_r_menu_content">
  148. <div class="m_c_title">图标生成</div>
  149. <div class="m_c_item">箱线图</div>
  150. <div class="m_c_item">雷达图</div>
  151. </div>
  152. </div>
  153. </div>
  154. </div>
  155. </div>
  156. <div v-show="activeMenu == 2" style="width:calc(100% - 148px);">
  157. <div class="history_talk">
  158. <div class="h_t_head">
  159. <div class="t_h_left">
  160. <span style="font-weight: bold;font-size: 18px;">历史回溯</span>
  161. <span>共计{{ tableData.length }}个会话</span>
  162. </div>
  163. <div class="t_h_right">
  164. <div style="margin-right: 10px;position: relative;">
  165. <el-input v-model="talkName" class="student_input" placeholder="检索会话名称"></el-input>
  166. <span class="serach_icon" @click="historyTalk()"></span>
  167. </div>
  168. </div>
  169. </div>
  170. <div class="h_t_table">
  171. <el-table :data="tableData" style="width: 100%;cursor: pointer" @row-click="handleRowClick">
  172. <el-table-column prop="name" label="会话名称" >
  173. </el-table-column>
  174. <el-table-column prop="ctime" label="创建时间" width="180">
  175. </el-table-column>
  176. <el-table-column prop="utime" label="更新时间" width="180">
  177. </el-table-column>
  178. <el-table-column prop="control" label="操作" width="200">
  179. <template slot-scope="scope">
  180. <div style="display: flex;">
  181. <div class="bianji">
  182. <i class="el-icon-edit"></i>
  183. <span @click.stop="openUpdate(scope.row.name, scope.row.id)">重命名</span>
  184. </div>
  185. <div class="bianji">
  186. <i class="el-icon-delete"></i>
  187. <span @click.stop="delete_talk(scope.row.id)">删除</span>
  188. </div>
  189. </div>
  190. </template>
  191. </el-table-column>
  192. </el-table>
  193. </div>
  194. <div class="h_t_bottom">
  195. <span>共{{ tableData.length }}条</span>
  196. <el-pagination background layout="prev, pager, next" :page-size="pageSize" :current-page="page"
  197. :total="total" @current-change="handleCurrentChange"></el-pagination>
  198. <!-- <el-select v-model="value" placeholder="请选择页数" size="mini" class="el_select">
  199. <el-option v-for="item in options" :key="item.value" :label="item.label"
  200. :value="item.value">
  201. </el-option>
  202. </el-select> -->
  203. </div>
  204. </div>
  205. </div>
  206. </div>
  207. <el-dialog title="修改会话名称" :visible.sync="dialogVisibleUpdate" :append-to-body="true" :before-close="handleClose"
  208. class="dialog_diy">
  209. <el-form>
  210. <el-form-item label="会话名称" :label-width="formLabelWidth">
  211. <el-input v-model="talkName1" auto-complete="off" placeholder="请输入会话名称..."></el-input>
  212. </el-form-item>
  213. </el-form>
  214. <span class="rename_btn">
  215. <el-button @click="dialogVisibleUpdate = false">取 消</el-button>
  216. <el-button type="primary" @click="UpdateTalkName()">确 定</el-button>
  217. </span>
  218. </el-dialog>
  219. </div>
  220. </template>
  221. <script>
  222. // var OpenCC = require("opencc-js");
  223. // let converter = OpenCC.Converter({
  224. // from: 'hk',
  225. // to: 'cn'
  226. // })
  227. import radarZong from "./dataCom/radarZong.vue";
  228. import radarTeacher from "./dataCom/radarTeacher.vue";
  229. import aiLeader from "./checkAi/aiLeader.vue";
  230. import Cascader from "./dataCom/cascader.vue";
  231. // import smartMenu from "./smartBox/smartMenu.vue";
  232. import csvTableView from "./choseCheck/csvTableView.vue";
  233. import Editor from './checkAi/wangEnduit.vue';
  234. import htmlDocx from "html-docx-js/dist/html-docx";
  235. import { saveAs } from "file-saver";
  236. export default {
  237. name: 'smarter',
  238. components: {
  239. radarZong, radarTeacher, Cascader,
  240. aiLeader, csvTableView,Editor
  241. },
  242. data() {
  243. return {
  244. // 组件数据
  245. userid: this.$route.query.userid,
  246. oid: this.$route.query.oid,
  247. org: this.$route.query.org,
  248. role: this.$route.query.role,
  249. cid: this.$route.query.cid,
  250. menuList: [],
  251. aiContentArea: [],
  252. menuIndex: 0,
  253. courseInfoList: [],
  254. page: 1,
  255. total: 0,
  256. talkName: '',
  257. talkName1: '',
  258. chatId: '',
  259. formLabelWidth: "100px",
  260. pageSize: 8,
  261. loading: true,
  262. activeMenu: 1, // 默认激活第一个
  263. fileMenu: 1,
  264. cutNumber: 1,
  265. dialogVisibleUpdate: false,
  266. // bianjiText:"",
  267. userAsk:"",
  268. examineData: [],
  269. tableData: [],
  270. options: [{
  271. value: '1',
  272. label: '20条/页'
  273. }, {
  274. value: '2',
  275. label: '双皮奶'
  276. }],
  277. value: '1',
  278. openLeft:true,
  279. };
  280. },
  281. methods: {
  282. handleRowClick(row, column, event) {
  283. this.activeMenu = 1;
  284. console.log(JSON.stringify(row))
  285. this.$nextTick(() => {
  286. // 调试输出
  287. console.log(this.$refs.aiChat);
  288. if (this.$refs.aiChat) {
  289. this.$refs.aiChat.getChatList(row.chatid);
  290. let obj = JSON.parse(row.json)
  291. this.menuList = obj;
  292. this.$refs.aiChat.fileList = obj.map(i=>i.url)
  293. this.menuIndex = 0;
  294. } else {
  295. console.error('aiChat ref is not available');
  296. }
  297. });
  298. },
  299. openUpdate(name, id) {
  300. this.talkName1 = name;
  301. this.chatId = id;
  302. this.dialogVisibleUpdate = true;
  303. },
  304. UpdateTalkName() {
  305. const j = this.menuList.map(i => i.url).join(",")
  306. let params = [{
  307. id: this.chatId,
  308. name: this.talkName1,
  309. j:j
  310. }];
  311. this.ajax
  312. .post(this.$store.state.api + "updateChat", params)
  313. .then(res => {
  314. if (this.talkName1 == '') {
  315. this.$message({
  316. message: "不能为空",
  317. type: "error",
  318. });
  319. } else {
  320. this.$message({
  321. message: "修改成功",
  322. type: "success",
  323. });
  324. this.dialogVisibleUpdate = false;
  325. this.historyTalk();
  326. this.talkName1 = '';
  327. }
  328. })
  329. .catch((err) => {
  330. console.error(err);
  331. })
  332. },
  333. delete_talk(id) {
  334. let params = [{
  335. id: id
  336. }]
  337. this.$confirm("确定删除此会话吗?", "提示", {
  338. confirmButtonText: "确定",
  339. cancelButtonText: "取消",
  340. type: "warning",
  341. })
  342. .then(() => {
  343. this.ajax
  344. .post(this.$store.state.api + "deleteChat", params)
  345. .then((res) => {
  346. this.$message({
  347. message: "删除成功",
  348. type: "success",
  349. });
  350. this.historyTalk();
  351. })
  352. .catch((err) => {
  353. this.$message.error("删除失败");
  354. console.error(err);
  355. });
  356. })
  357. .catch(() => { });
  358. },
  359. handleCurrentChange(newPage) {
  360. this.page = newPage;
  361. this.historyTalk();
  362. },
  363. handleClose(done) {
  364. done();
  365. },
  366. // 获取基础页面数据
  367. getPageBase() {
  368. let params = {
  369. typ: 2,
  370. org: this.org,
  371. oid: this.oid
  372. };
  373. // console.log(params);
  374. this.ajax
  375. .get(this.$store.state.api + "selectTestExamineBase", params)
  376. .then(res => {
  377. console.log('selectTestExamineBase', res.data[0]);
  378. this.examineData = res.data[0]
  379. })
  380. .catch(error => {
  381. console.log(error);
  382. });
  383. },
  384. deleteMenuItem(index) {
  385. this.menuList.splice(index, 1);
  386. this.menuIndex = 0
  387. this.$refs.aiChat.delFileList(index)
  388. this.$forceUpdate()
  389. console.log('menuList', this.menuList);
  390. },
  391. historyTalk() {
  392. let params = {
  393. uid: this.userid,
  394. n: this.talkName,
  395. page: this.page,
  396. num: this.pageSize
  397. };
  398. this.ajax
  399. .get(this.$store.state.api + "getChatHistory", params)
  400. .then((res) => {
  401. this.tableData = res.data[0]
  402. console.log("tableData", this.tableData);
  403. this.total = res.data[0].length > 0 ? res.data[0][0].num : 0;
  404. console.log("111111", this.total);
  405. })
  406. .catch((err) => {
  407. console.error(err);
  408. });
  409. },
  410. pushFileData(data) {
  411. this.menuList.push(data)
  412. console.log("menuList", this.menuList);
  413. },
  414. // pushAiContent(aitext,userText){
  415. // this.bianjiText = aitext
  416. // this.userAsk = userText
  417. // console.log("ai回答👉",this.bianjiText);
  418. // if(this.bianjiText){
  419. // this.fileMenu = 2
  420. // }
  421. // },
  422. // pushAiContent(data){
  423. // this.aiContentArea.push(...data),
  424. // console.log("aiContentArea",this.aiContentArea);
  425. // },
  426. clearFileData() {
  427. this.menuList = []
  428. },
  429. changeMenuIndex(index) {
  430. this.menuIndex = index
  431. },
  432. goTo(path) {
  433. this.$router.push(path);
  434. },
  435. getData() {
  436. if (this.cid) {
  437. this.loading = true
  438. let cidList = this.cid.split(',')
  439. let promiseList = []
  440. cidList.forEach(el => {
  441. promiseList.push(this.getCourseData(el))
  442. })
  443. Promise.all(promiseList).then(res => {
  444. this.courseInfoList = res
  445. console.log("courseInfoList", this.courseInfoList)
  446. this.loading = false
  447. }).catch(err => {
  448. console.error("Error occurred:", err);
  449. this.loading = false; // 如果有错误,也要停止loading
  450. });
  451. }
  452. },
  453. getCourseData(courseId) {
  454. return new Promise((resolve) => {
  455. let params = {
  456. cid: courseId,
  457. cn: "",
  458. tim: "",
  459. tea: ""
  460. };
  461. this.ajax
  462. .get(this.$store.state.api + "getTestWorksNoPageCopy", params)
  463. .then(async (res) => {
  464. let testJson = res.data[0][0]
  465. let works = res.data[1]
  466. let chapters = this.setJSON(this.setJson2(JSON.parse(JSON.stringify(JSON.parse(res.data[0][0].chapters)))))
  467. let courseCount11 = []
  468. let array = []
  469. let courseIds = []; // 初始化一个空数组来存储所有的courseId
  470. for (let i = 0; i < works.length; i++) {
  471. let cJson = this.setJSON(JSON.parse(JSON.stringify(JSON.parse(works[i].courseJson))))
  472. if (JSON.stringify(cJson) == JSON.stringify(chapters)) {
  473. let _json = this.JSONSetting(JSON.parse(JSON.stringify(JSON.parse(works[i].courseJson))))
  474. for (var ja = 0; ja < _json.length; ja++) {
  475. let _json2 = _json[ja].json;
  476. if (_json[ja].type == 6) {
  477. let courseId = _json2.answer2;
  478. courseIds.push(courseId); // 将type为6的courseId添加到数组中
  479. }
  480. if (_json[ja].type == 11) {
  481. let _answer = _json2.answer2;
  482. _answer.length ? courseCount11 = courseCount11.concat(_answer) : '';
  483. _json[ja].json.courseId = _answer ? _answer : [];
  484. courseIds = courseIds.concat(_answer); // 将type为11的courseId添加到数组中
  485. }
  486. }
  487. }
  488. }
  489. // 将所有的courseId去重
  490. courseIds = Array.from(new Set(courseIds));
  491. // 使用一个数组来存储所有的courseId后,执行getCourseInfoTestAll
  492. let courseTitles = {}; // 初始化一个空对象来存储所有的courseTitles
  493. let params2 = [{
  494. cid: courseIds.join(",")
  495. }]
  496. let data2 = await this.ajax.post(this.$store.state.api + 'getCourseInfoTestAll2', params2);
  497. let result2 = data2.data[0];
  498. result2.forEach(i => {
  499. courseTitles[i.courseId] = i.title;
  500. });
  501. for (let i = 0; i < works.length; i++) {
  502. let cJson = this.setJSON(JSON.parse(JSON.stringify(JSON.parse(works[i].courseJson))))
  503. if (JSON.stringify(cJson) == JSON.stringify(chapters)) {
  504. let _json = this.JSONSetting(JSON.parse(JSON.stringify(JSON.parse(works[i].courseJson))))
  505. _json.forEach(item => {
  506. if (item.type == 11) {
  507. let cid = item.json.answer2
  508. let _title = []
  509. for (var i = 0; i < cid.length; i++) {
  510. _title.push(courseTitles[cid[i]])
  511. }
  512. item.json.answer2 = _title.length ? _title.join(",") : '';
  513. }
  514. if (item.type == 6) {
  515. let courseId = item.json.answer2;
  516. item.json.answer2 = courseTitles[courseId] || '';
  517. }
  518. });
  519. // 更新对应的_json对象的answer2
  520. array.push({
  521. courseid: works[i].courseid,
  522. id: works[i].id,
  523. userid: works[i].userid,
  524. name: works[i].username ? works[i].username : '匿名',
  525. time: works[i].time,
  526. array: _json,
  527. cut: 0,
  528. uteaName: works[i].uteaName,
  529. courseJson: JSON.parse(works[i].courseJson),
  530. })
  531. }
  532. }
  533. let obj = { courseId: testJson.courseId, name: testJson.title, worksArray: array }
  534. this.courseInfoList.push(obj)
  535. resolve(obj)
  536. })
  537. .catch((err) => {
  538. resolve();
  539. console.error(err);
  540. });
  541. })
  542. },
  543. async downUserAsk(){
  544. // console.log(this.userAsk)
  545. // console.log(this.userAsk)
  546. await this.generateDocx("文案编辑",this.userAsk);
  547. this.$message.success("下载成功")
  548. },
  549. // 导出docx
  550. async generateDocx(name, html) {
  551. // 将html文件中需要用到的数据挂载到store上
  552. const content = `<!DOCTYPE html>
  553. <html xmlns:v='urn:schemas-microsoft-com
  554. :vml'xmlns:o='urn:schemas-microsoft-com:office
  555. :office'xmlns:w='urn:schemas-microsoft-com:office
  556. :word'xmlns:m='http://schemas.microsoft.com/office/2004/12/omml'
  557. xmlns='http://www.w3.org/TR/REC-html40'
  558. xmlns='http://www.w3.org/1999/xhtml'>
  559. <head>
  560. <meta charset="UTF-8">
  561. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  562. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  563. <title>${name}</title>
  564. <style>
  565. *{
  566. font-family: '宋体';
  567. margin:0;
  568. padding:0;
  569. line-height:1;
  570. }
  571. table {
  572. border-collapse: collapse; /* 折叠边框 */
  573. width: 100%;
  574. font-size:10.5pt;
  575. }
  576. th, td {
  577. border: 1px solid black; /* 线条样式 */
  578. padding: 8px;
  579. text-align: left;
  580. font-size:10.5pt;
  581. }
  582. ol,ul{
  583. margin:0;
  584. padding:0;
  585. margin-right:-1in;
  586. }
  587. li{
  588. margin-bottom:0.1in
  589. margin-right:-1in;
  590. }
  591. p{
  592. line-height:1;
  593. margin:0;
  594. padding:0
  595. }
  596. .vue-office-docx{height:100%;overflow-y:auto}
  597. .vue-office-docx .docx-wrapper>section.docx{margin-bottom:5px}
  598. @media screen and (max-width: 800px){
  599. .vue-office-docx .docx-wrapper{padding:10px}
  600. .vue-office-docx .docx-wrapper>section.docx{padding:10px!important;width:100%!important}
  601. }
  602. .docx-wrapper { background: gray; padding: 30px; padding-bottom: 0px; display: flex; flex-flow: column; align-items: center; }
  603. .docx-wrapper>section.docx { background: white; box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); margin-bottom: 30px; }
  604. .docx { color: black; hyphens: auto; text-underline-position: from-font; }
  605. section.docx { box-sizing: border-box; display: flex; flex-flow: column nowrap; position: relative; overflow: hidden; }
  606. section.docx>article { margin-bottom: auto; z-index: 1; }
  607. section.docx>footer { z-index: 1; }
  608. .docx table { border-collapse: collapse; }
  609. .docx table td, .docx table th { vertical-align: top; }
  610. .docx p { margin: 0pt; min-height: 1em; }
  611. .docx span { white-space: pre-wrap; overflow-wrap: break-word; }
  612. .docx a { color: inherit; text-decoration: inherit; }
  613. .docx svg { fill: transparent; }
  614. .docx {
  615. --docx-majorHAnsi-font: Calibri Light;
  616. --docx-minorHAnsi-font: Calibri;
  617. --docx-dk1-color: #000000;
  618. --docx-lt1-color: #FFFFFF;
  619. --docx-dk2-color: #44546A;
  620. --docx-lt2-color: #E7E6E6;
  621. --docx-accent1-color: #5B9BD5;
  622. --docx-accent2-color: #ED7D31;
  623. --docx-accent3-color: #A5A5A5;
  624. --docx-accent4-color: #FFC000;
  625. --docx-accent5-color: #4472C4;
  626. --docx-accent6-color: #70AD47;
  627. --docx-hlink-color: #0563C1;
  628. --docx-folHlink-color: #954F72;
  629. }
  630. .docx span {
  631. font-family: Times New Roman;
  632. }
  633. .docx p, p.docx_1 {
  634. text-align: justify;
  635. }
  636. .docx p, p.docx_1 span {
  637. font-family: var(--docx-minorHAnsi-font);
  638. min-height: 10.50pt;
  639. font-size: 10.50pt;
  640. }
  641. .docx table, table.docx_2 td {
  642. padding-top: 0.00pt;
  643. padding-left: 5.40pt;
  644. padding-bottom: 0.00pt;
  645. padding-right: 5.40pt;
  646. }
  647. table.docx_3 p {
  648. text-align: justify;
  649. }
  650. table.docx_3 td {
  651. border-top: 0.50pt solid black;
  652. border-left: 0.50pt solid black;
  653. border-bottom: 0.50pt solid black;
  654. border-right: 0.50pt solid black;
  655. padding-top: 0.00pt;
  656. padding-left: 5.40pt;
  657. padding-bottom: 0.00pt;
  658. padding-right: 5.40pt;
  659. }
  660. p.docx-num-2-0:before {
  661. content: ""counter(docx-num-2-0, decimal)"、";
  662. counter-increment: docx-num-2-0;
  663. }
  664. p.docx-num-2-0 {
  665. display: list-item;
  666. list-style-position: inside;
  667. list-style-type: none;
  668. }
  669. p.docx-num-1-0:before {
  670. content: ""counter(docx-num-1-0, decimal)"、";
  671. counter-increment: docx-num-1-0;
  672. }
  673. p.docx-num-1-0 {
  674. display: list-item;
  675. list-style-position: inside;
  676. list-style-type: none;
  677. }
  678. .docx-wrapper {
  679. counter-reset: docx-num-2-0 4 docx-num-1-0 0;
  680. }
  681. </style>
  682. </head>
  683. <body>
  684. ${html}
  685. </body>
  686. </html>`;
  687. // console.log(content)
  688. // return console.log(content)
  689. // debugger
  690. let blob = htmlDocx.asBlob(content);
  691. // const uploadFile = new File([blob], `${name}.docx`, {
  692. // type:
  693. // "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
  694. // });
  695. saveAs(blob, `${name}.docx`);
  696. return true;
  697. // this.beforeUploadHtml(uploadFile);
  698. },
  699. },
  700. computed: {
  701. showFileUrl() {
  702. if (this.menuList.length) {
  703. if(this.menuList[this.menuIndex]){
  704. return this.menuList[this.menuIndex].url
  705. }else {
  706. return ""
  707. }
  708. } else {
  709. return "";
  710. }
  711. },
  712. aiBoxRightCid() {
  713. let _result = this.cid;
  714. let _cidList = _result.split(',');
  715. if (_cidList.length > 1) {
  716. _cidList.sort((a, b) => parseInt(b) - parseInt(a));
  717. _result = _cidList.join(',');
  718. }
  719. console.log("我是cid", _result);
  720. return _result
  721. }
  722. },
  723. mounted() {
  724. this.getData();
  725. this.getPageBase();
  726. this.historyTalk();
  727. },
  728. watch: {
  729. activeMenu(newValue) {
  730. if (newValue === 2) {
  731. console.log("HelloWorld");
  732. this.historyTalk();
  733. }
  734. },
  735. }
  736. };
  737. </script>
  738. <style scoped>
  739. .pb_content {
  740. width: 100vw;
  741. height: 100vh;
  742. box-sizing: border-box;
  743. padding: 0 20px;
  744. }
  745. .bbox_serch {
  746. width: 100%;
  747. margin-bottom: 10px;
  748. display: flex;
  749. align-items: center;
  750. }
  751. .top {
  752. display: flex;
  753. justify-content: space-between;
  754. width: 100% !important;
  755. box-sizing: border-box;
  756. margin: 0px auto;
  757. padding: 10px 0;
  758. height: 54px;
  759. align-items: center;
  760. }
  761. .pb_head_t_left {
  762. display: flex;
  763. align-items: center;
  764. }
  765. /* .pb_head_t_right {} */
  766. .preview_icon {
  767. background: url('../../../assets/icon/test/test_preview.png') no-repeat;
  768. width: 22px;
  769. height: 22px;
  770. display: inline-block;
  771. background-size: contain;
  772. cursor: pointer;
  773. margin-right: 20px;
  774. }
  775. .case_icon {
  776. background: url('../../../assets/icon/test/test_case.png') no-repeat;
  777. width: 22px;
  778. height: 22px;
  779. display: inline-block;
  780. background-size: contain;
  781. cursor: pointer;
  782. margin-right: 15px;
  783. }
  784. .problem_icon {
  785. background: url('../../../assets/icon/test/test_problem.png') no-repeat;
  786. width: 22px;
  787. height: 22px;
  788. display: inline-block;
  789. background-size: contain;
  790. cursor: pointer;
  791. margin-right: 10px;
  792. }
  793. .subClick {
  794. font-size: 16px;
  795. cursor: pointer;
  796. margin-left: 10px;
  797. /* color: #ab582f; */
  798. color: #409eff;
  799. }
  800. .sub_head {
  801. position: relative;
  802. font-size: 20px;
  803. font-weight: bold;
  804. padding: 0 15px;
  805. }
  806. .sub_head::after {
  807. content: "";
  808. width: 100%;
  809. background: #3681FC;
  810. height: 2px;
  811. position: absolute;
  812. left: 0;
  813. bottom: -8px;
  814. }
  815. .subClick {
  816. /* font-size: 16px; */
  817. font-size: 20px;
  818. cursor: pointer;
  819. /* margin-left: 17.5px; */
  820. /* color: #ab582f; */
  821. /* color: #409eff; */
  822. color: #999;
  823. padding: 0 15px;
  824. }
  825. .subClick:hover {
  826. color: #000;
  827. }
  828. .sub_head+.subClick,
  829. .subClick+.subClick,
  830. .subClick+.sub_head {
  831. margin-left: 17.5px;
  832. }
  833. .bbox {
  834. background: #fff;
  835. border-radius: 0 5px 5px 5px;
  836. padding: 15px 0;
  837. box-sizing: border-box;
  838. min-height: 900px;
  839. }
  840. .bbox_nav {
  841. display: flex;
  842. width: 100%;
  843. box-sizing: border-box;
  844. padding: 0 20px;
  845. align-items: center;
  846. }
  847. .teaLis {
  848. display: flex;
  849. }
  850. .teal {
  851. padding: 10px 20px;
  852. cursor: pointer;
  853. }
  854. .Tbor {
  855. border-bottom: 2px rgba(54, 129, 252, 1) solid;
  856. font-weight: 600;
  857. }
  858. .randarZong {
  859. max-width: 100%;
  860. width: 500px;
  861. height: 500px;
  862. margin: 0 auto;
  863. }
  864. .randarBox {
  865. padding: 20px;
  866. width: 100%;
  867. box-sizing: border-box;
  868. display: flex;
  869. flex-wrap: wrap;
  870. }
  871. .randarBox .title {
  872. width: 100%;
  873. font-size: 18px;
  874. font-weight: 700;
  875. margin-bottom: 20px;
  876. }
  877. .randarTeacher {
  878. width: calc(100% / 4 - 20px);
  879. margin-right: 20px;
  880. margin-bottom: 20px;
  881. }
  882. .randarTitle {
  883. display: flex;
  884. align-items: center;
  885. justify-content: space-between;
  886. margin-bottom: 10px;
  887. }
  888. .randarTitle>span:nth-child(1) {}
  889. .randarTitle>span:nth-child(2) {}
  890. .randar {
  891. width: calc(100%);
  892. height: 350px;
  893. border: 1px solid #e4e4e4;
  894. border-radius: 5px;
  895. }
  896. @media screen and (max-width: 1280px) {
  897. .randarTeacher {
  898. width: calc(100% / 2 - 20px);
  899. }
  900. }
  901. @media screen and (max-width: 800px) {
  902. .randarTeacher {
  903. width: calc(100%);
  904. margin-right: 0;
  905. }
  906. }
  907. .iconfont {
  908. font-family: "iconfont" !important;
  909. font-size: 22px;
  910. font-style: normal;
  911. -webkit-font-smoothing: antialiased;
  912. -moz-osx-font-smoothing: grayscale;
  913. }
  914. .dialog_diy>>>.el-dialog__header {
  915. background: #3d67bc !important;
  916. padding: 15px 20px;
  917. }
  918. .dialog_diy>>>.el-dialog__title {
  919. color: #fff;
  920. }
  921. .student_table>>>.el-table--border td {
  922. border-right: 0px !important;
  923. }
  924. .dialog_diy>>>.el-dialog__headerbtn {
  925. top: 19px;
  926. }
  927. .dialog_diy>>>.el-dialog__headerbtn .el-dialog__close {
  928. color: #fff;
  929. }
  930. .dialog_diy>>>.el-dialog__headerbtn .el-dialog__close:hover {
  931. color: #fff;
  932. }
  933. .cc_bottom {
  934. width: 100%;
  935. height: calc(100% - 66px - 10px);
  936. background-color: #fff;
  937. border-radius: 5px;
  938. display: flex;
  939. }
  940. .cc_b_middle {
  941. width: 50%;
  942. height: 100%;
  943. border-right: 1px solid #E4E7ED;
  944. }
  945. .cc_b_middle>div {
  946. width: 100%;
  947. height: 100%;
  948. }
  949. .cc_b_left {
  950. border-right: 1px solid #E4E7ED;
  951. display: flex;
  952. flex-direction: column;
  953. justify-content: space-between;
  954. height: 100%;
  955. width: 13%;
  956. overflow: hidden;
  957. border-radius: 5px;
  958. }
  959. .menu_container {
  960. width: 100%;
  961. flex: 1;
  962. display: flex;
  963. flex-direction: column;
  964. align-items: center;
  965. /* 占据除折叠按钮外的所有空间 */
  966. }
  967. .menu_container>div{
  968. display: flex;
  969. align-items: center;
  970. width: calc(100% - 20px - 20px);
  971. height: 40px;
  972. background-color: #fff;
  973. margin: 20px 20px 0 20px;
  974. border-radius: 8px;
  975. box-sizing: border-box;
  976. padding-left: 10px;
  977. color: #828282;
  978. cursor: pointer;
  979. }
  980. .menu_container>div>span{
  981. width: 18px;
  982. height: 18px;
  983. margin-right: 10px;
  984. }
  985. .menu_container>span{
  986. display: flex;
  987. align-items: center;
  988. justify-content: center;
  989. width: 100%;
  990. height: 40px;
  991. padding: 5px;
  992. background-color: #fff;
  993. box-sizing: border-box;
  994. color: #828282;
  995. cursor: pointer;
  996. /* margin-top: 10px; */
  997. }
  998. .menu_container>span>span{
  999. width: 18px;
  1000. height: 18px;
  1001. display: flex;
  1002. }
  1003. .cc_b_l_menu {
  1004. padding: 10px;
  1005. margin: 17px;
  1006. border-radius: 7px;
  1007. color: #828282;
  1008. cursor: pointer;
  1009. display: flex;
  1010. }
  1011. .menu_container .active {
  1012. background-color: #3681fc !important;
  1013. color: #fff;
  1014. }
  1015. .session_icon {
  1016. background: url('../../../assets/icon/test/test_session.png') no-repeat center;
  1017. display: inline-block;
  1018. background-size: contain;
  1019. }
  1020. .session_icon.active {
  1021. background: url('../../../assets/icon/test/test_session_active.png') no-repeat center;
  1022. display: inline-block;
  1023. background-size: contain;
  1024. }
  1025. .history_icon {
  1026. background: url('../../../assets/icon/test/test_history.svg') no-repeat center;
  1027. display: inline-block;
  1028. background-size: contain;
  1029. }
  1030. .history_icon.active {
  1031. background: url('../../../assets/icon/test/test_history_active.svg') no-repeat center;
  1032. display: inline-block;
  1033. background-size: contain;
  1034. }
  1035. /* .mysql_icon{
  1036. background:url('../../../../assets/icon/test/test_mysql.png') no-repeat;
  1037. width: 18px;
  1038. height: 18px;
  1039. display: inline-block;
  1040. background-size: contain;
  1041. }
  1042. .mysql_icon.active{
  1043. background:url('../../../../assets/icon/test/test_mysql_active.png') no-repeat;
  1044. width: 18px;
  1045. height: 18px;
  1046. display: inline-block;
  1047. background-size: contain;
  1048. } */
  1049. .fold_btn {
  1050. width: 100%;
  1051. height: 60px;
  1052. border-top: 1px solid #E4E7ED;
  1053. box-sizing: border-box;
  1054. display: flex;
  1055. align-items: center;
  1056. padding-left: 15px;
  1057. /* padding: 27px 20px;
  1058. cursor: pointer;
  1059. border-top: 1px solid #E4E7ED;
  1060. margin-top: auto; */
  1061. /* 确保折叠按钮在底部 */
  1062. }
  1063. .more_icon {
  1064. background: url('../../../assets/icon/test/test_fold.svg') no-repeat;
  1065. background-size: 100%;
  1066. width: 18px;
  1067. height: 18px;
  1068. display: inline-block;
  1069. background-size: contain;
  1070. cursor: pointer;
  1071. }
  1072. .cc_b_right {
  1073. width: 50%;
  1074. height: 100%;
  1075. box-sizing: border-box;
  1076. }
  1077. .preview_file,
  1078. .bianji_file {
  1079. margin: 10px;
  1080. width: 65px;
  1081. cursor: pointer;
  1082. }
  1083. .preview_file.active {
  1084. font-weight: bold;
  1085. border-bottom: 2px solid blue;
  1086. }
  1087. .bianji_file.active {
  1088. font-weight: bold;
  1089. border-bottom: 2px solid blue;
  1090. }
  1091. [contenteditable="true"]:focus {
  1092. outline: none;
  1093. border: none;
  1094. }
  1095. .bianji_area {
  1096. margin: 0;
  1097. width: 100%;
  1098. height: 100%;
  1099. position: relative;
  1100. }
  1101. .bianji_area>span{
  1102. width: 25px;
  1103. height: 25px;
  1104. position: absolute;
  1105. right: 15px;
  1106. top: 8px;
  1107. z-index: 999;
  1108. /* background-color: red; */
  1109. }
  1110. .bianji_area>span>img{
  1111. width: 100%;
  1112. height: 100%;
  1113. cursor: pointer;
  1114. }
  1115. .aiText{
  1116. margin-top:10px;
  1117. }
  1118. .userAsk{
  1119. font-size: 20px;
  1120. font-weight: bold;
  1121. }
  1122. /* .aiText>p{
  1123. margin-top: 0;
  1124. margin-bottom: 16px;
  1125. }
  1126. .aiText>ol{
  1127. padding-left: 2em;
  1128. margin-top: 0;
  1129. margin-bottom: 0;
  1130. } */
  1131. .cc_b_r_menu {
  1132. width: 100%;
  1133. height: 50px;
  1134. display: flex;
  1135. align-items: center;
  1136. box-sizing: border-box;
  1137. border-bottom: 1px solid #E4E7ED;
  1138. overflow: auto;
  1139. }
  1140. .cc_b_r_menu>div {
  1141. height: 100%;
  1142. max-width: 100px;
  1143. padding: 0 15px;
  1144. display: flex;
  1145. text-align: center;
  1146. /* justify-content: center; */
  1147. align-items: center;
  1148. cursor: pointer;
  1149. transition: all 0.3s;
  1150. /* text-overflow: ellipsis;
  1151. overflow: hidden;
  1152. white-space: nowrap; */
  1153. }
  1154. .cc_b_r_menu>div:hover {
  1155. background-color: #F5F7FA;
  1156. }
  1157. .cc_b_r_menu>div>span {
  1158. width: 100%;
  1159. text-overflow: ellipsis;
  1160. white-space: nowrap;
  1161. overflow: hidden;
  1162. }
  1163. .cc_b_r_menu_active {
  1164. background-color: #3681FC !important;
  1165. color: #fff;
  1166. }
  1167. .cc_b_r_content {
  1168. width: 100%;
  1169. overflow-y: auto;
  1170. overflow-x: auto;
  1171. max-height: calc(100% - 50px);
  1172. }
  1173. .cc_b_r_btn {
  1174. display: flex;
  1175. align-items: center;
  1176. }
  1177. .close_icon {
  1178. width: 0 !important;
  1179. height: 22px;
  1180. display: inline-block;
  1181. background-size: contain;
  1182. cursor: pointer;
  1183. }
  1184. .close_icon.active {
  1185. background: url('../../../assets/icon/test/test_close_active.png') no-repeat;
  1186. width: 40px !important;
  1187. height: 22px;
  1188. display: inline-block;
  1189. background-size: contain;
  1190. cursor: pointer;
  1191. }
  1192. .b_r_menu {
  1193. display: flex;
  1194. justify-content: space-around;
  1195. }
  1196. .b_r_menu_content {
  1197. display: flex;
  1198. flex-direction: column;
  1199. background: linear-gradient(to bottom, #dfeaff, #ffffff, #f6f9ff);
  1200. border-radius: 9px;
  1201. margin-top: 15px;
  1202. width: 50%;
  1203. margin-right: 14px
  1204. }
  1205. .m_c_title {
  1206. margin: 10px 7px 7px 21px;
  1207. font-size: 16px;
  1208. font-weight: bold;
  1209. }
  1210. .m_c_item {
  1211. border-radius: 5px;
  1212. padding: 8px 8px 8px 13px;
  1213. margin: 7px;
  1214. border: 1px solid #E4E7ED;
  1215. }
  1216. .history_talk {
  1217. background: linear-gradient(to bottom, #dfeaff, #ffffff, #f6f9ff);
  1218. margin: 13px;
  1219. padding: 10px;
  1220. }
  1221. .h_t_head {
  1222. display: flex;
  1223. justify-content: space-between;
  1224. }
  1225. .t_h_left {
  1226. margin-left: 13px;
  1227. font-size: 13px;
  1228. }
  1229. .h_t_table {
  1230. margin: 10px;
  1231. box-shadow: 0px 0px 12px rgb(190 193 199);
  1232. }
  1233. .h_t_table>>>.el-table td,
  1234. .el-table th {
  1235. padding: 9px 0;
  1236. }
  1237. .bianji {
  1238. display: flex;
  1239. align-items: center;
  1240. margin-right: 10px;
  1241. }
  1242. .bianji:hover {
  1243. color: rgb(14, 173, 236);
  1244. cursor: pointer;
  1245. }
  1246. .rename_btn {
  1247. display: flex;
  1248. justify-content: flex-end;
  1249. }
  1250. .h_t_bottom {
  1251. display: flex;
  1252. justify-content: flex-end;
  1253. align-items: center;
  1254. margin-right: 9px;
  1255. }
  1256. .el_select {
  1257. width: 89px;
  1258. }
  1259. .table_title {
  1260. background-color: gray;
  1261. }
  1262. .student_input>>>.el-input__inner {
  1263. height: 30px;
  1264. width: 179px;
  1265. font-size: 13px;
  1266. padding: 0 10px;
  1267. }
  1268. .serach_icon {
  1269. position: absolute;
  1270. right: 12px;
  1271. top: 50%;
  1272. transform: translateY(-50%);
  1273. width: 13px;
  1274. height: 13px;
  1275. background: url("../../../assets/icon/test/test_search.png") no-repeat;
  1276. background-size: 100% 100%;
  1277. cursor: pointer;
  1278. }
  1279. .el-input {
  1280. position: relative;
  1281. font-size: 14px;
  1282. display: inline-block;
  1283. width: 100%;
  1284. }
  1285. .editor>>>.text{
  1286. height: calc( 100% - 42px);
  1287. }
  1288. </style>