markScore.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. <template>
  2. <div>
  3. <div v-loading="loading" style="cursor: pointer;" @click.stop="markScoreDigBtn">
  4. <div class="scoreTit">
  5. <div>任务得分</div>
  6. <div>{{ totalScore ? totalScore : 0 }}分</div>
  7. </div>
  8. <div class="allD">
  9. <div class="scoreStarBack2">
  10. <div
  11. v-for="(e, index) in scoTitList"
  12. :key="index"
  13. style="height: 30px;"
  14. >
  15. <img
  16. class="rootImg"
  17. v-if="e.isai == 1 || !e.isai"
  18. src="../../../assets/icon/newIcons/blueRoot.png"
  19. alt=""
  20. />
  21. </div>
  22. </div>
  23. <div class="scoreStar">
  24. <div v-for="(e, index) in scoTitList" :key="index">
  25. <div class="scoreStarBack">
  26. <el-tooltip
  27. class="item"
  28. effect="dark"
  29. :content="e.detail"
  30. placement="top"
  31. >
  32. <div class="briefTit">
  33. {{ e.detail }}
  34. </div>
  35. </el-tooltip>
  36. <el-rate
  37. disabled
  38. disabled-void-color="#ccc"
  39. v-model="e.cog"
  40. ></el-rate>
  41. </div>
  42. </div>
  43. </div>
  44. </div>
  45. <div class="AreaCss">
  46. {{ textarea }}
  47. <!-- <el-input
  48. type="textarea"
  49. disabled
  50. placeholder="您可在此输入评语"
  51. v-model="textarea"
  52. style="padding-bottom: 10px;"
  53. >
  54. </el-input> -->
  55. </div>
  56. <!-- <div style="width:100%;display:flex;justify-content: flex-end;">
  57. <el-button size="mini" @click="reset">重置</el-button>
  58. <el-button type="primary" size="mini" @click="submit">确认</el-button>
  59. <el-button type="primary" size="mini" @click="AIsubmit"
  60. >AI评分</el-button
  61. >
  62. </div> -->
  63. </div>
  64. </div>
  65. </template>
  66. <script>
  67. import { v4 as uuidv4 } from "uuid";
  68. export default {
  69. name: "PblStudentTableMarkScore",
  70. props: [
  71. "scoTit",
  72. "scoCon",
  73. "task",
  74. "stage",
  75. "loading",
  76. "wIndex",
  77. "toolIndex",
  78. "tool",
  79. "markScoreVisible"
  80. ],
  81. data() {
  82. return {
  83. homeworkVal: [],
  84. scoTitList: [],
  85. markScoPopover: false,
  86. id: this.$route.query.courseId,
  87. stUid: this.scoCon.userid,
  88. userid: this.$route.query.userid,
  89. total: 0,
  90. textarea:''
  91. };
  92. },
  93. computed: {
  94. totalScore() {
  95. let a = 0;
  96. let isPing = 0;
  97. this.scoTitList.forEach(e => {
  98. if (e.cog || e.cog == "0") {
  99. a += e.cog * 1;
  100. } else {
  101. isPing += 1;
  102. }
  103. });
  104. let data = 0;
  105. if (isPing == this.scoTitList.length) {
  106. this.$emit("updateDocSco", {
  107. val: this.toolIndex,
  108. val2: this.wIndex,
  109. val3: null
  110. });
  111. } else {
  112. data = (a / this.scoTitList.length).toFixed(1);
  113. this.$emit("updateDocSco", {
  114. val: this.toolIndex,
  115. val2: this.wIndex,
  116. val3: data
  117. });
  118. }
  119. return data;
  120. }
  121. },
  122. mounted() {
  123. if (this.tool.eList && this.tool.eList.length) {
  124. this.scoTitList = JSON.parse(JSON.stringify(this.tool.eList));
  125. }else{
  126. this.scoTitList = JSON.parse(JSON.stringify(this.scoTit));
  127. }
  128. this.getData();
  129. },
  130. methods: {
  131. // // 获取文档id
  132. createFileid(url) {
  133. let _this = this;
  134. return new Promise((resolve, reject) => {
  135. try {
  136. _this.ajax
  137. .put("https://gpt4.cocorobo.cn/upload_file_knowledge", {
  138. url: url
  139. })
  140. .then(res => {
  141. let _data = res.data.FunctionResponse;
  142. if (_data.result && _data.result.id) {
  143. resolve(_data.result.id);
  144. } else {
  145. resolve(1);
  146. }
  147. })
  148. .catch(function(error) {
  149. resolve(1);
  150. });
  151. } catch (e) {
  152. resolve(1);
  153. }
  154. });
  155. },
  156. // 获取单个数据
  157. getData() {
  158. let params = {
  159. uid: this.scoCon.userid,
  160. cid: this.id,
  161. s:this.stage,
  162. t:this.task,
  163. tool:this.toolIndex ? this.toolIndex :''
  164. };
  165. this.ajax
  166. .get(this.$store.state.api + "selectWorksEvaScoreTwo", params)
  167. .then(res => {
  168. // console.log("res", res.data);
  169. if (res.data[0].length > 0) {
  170. var data2 = [];
  171. res.data[0].forEach((val, index) => {
  172. if (val.task == this.task) {
  173. data2 = res.data[0][index];
  174. this.homeworkVal = res.data[0][index];
  175. }
  176. });
  177. if (data2.length == 0) {
  178. if (this.tool.eList && this.tool.eList.length) {
  179. this.scoTitList = JSON.parse(JSON.stringify(this.tool.eList));
  180. }else{
  181. this.scoTitList = JSON.parse(JSON.stringify(this.scoTit));
  182. }
  183. } else {
  184. let data = JSON.parse(data2.rate);
  185. this.scoTitList.forEach((e, index) => {
  186. e.cog = null;
  187. for (const key in data) {
  188. if (isNaN(parseFloat(e.detail)) && e.detail) {
  189. var result = e.detail.match(/[\u4e00-\u9fa5a-zA-Z]+/g).join("");
  190. }else{
  191. var result = e.detail
  192. }
  193. if (isNaN(parseFloat(key)) && key) {
  194. var key2 = key.match(/[\u4e00-\u9fa5a-zA-Z]+/g).join("");
  195. }else{
  196. var key2 = key
  197. }
  198. // let result = e.detail.match(/[\u4e00-\u9fa5a-zA-Z]+/g).join("");
  199. // let key2 = key.match(/[\u4e00-\u9fa5a-zA-Z]+/g).join("");
  200. if (result.indexOf(key2) != -1) {
  201. e.cog = data[key];
  202. }
  203. if ("content" == key) {
  204. this.textarea = data[key];
  205. }
  206. }
  207. });
  208. this.scoTitList = JSON.parse(JSON.stringify(this.scoTitList));
  209. // console.log(this.scoTitList);
  210. }
  211. } else {
  212. this.scoTitList.forEach((e, index) => {
  213. e.cog = null;
  214. })
  215. this.scoTitList = JSON.parse(JSON.stringify(this.scoTitList));
  216. }
  217. })
  218. .catch(err => {
  219. console.error(err);
  220. });
  221. },
  222. markScoreDigBtn() {
  223. if (this.tool.eList && this.tool.eList.length) {
  224. this.$emit("markScoreDig", {
  225. val: this.stUid,
  226. val2: this.toolIndex,
  227. tit: this.tool.eList,
  228. uname:this.scoCon.sName
  229. });
  230. }else{
  231. this.$emit("markScoreDig", {
  232. val: this.stUid,
  233. val2: this.toolIndex,
  234. tit: this.scoTit,
  235. uname:this.scoCon.sName
  236. });
  237. }
  238. },
  239. // 重置
  240. reset() {
  241. this.scoTitList.forEach(e => {
  242. e.cog = 0;
  243. // console.log(e.cog);
  244. });
  245. },
  246. // ai循环评分
  247. async aiupdetaSco(messages, uid, stage, task,_fileid,work) {
  248. let _this = this;
  249. let params = {
  250. assistant_id: "6063369f-289a-11ef-8bf4-12e77c4cb76b",
  251. message: [
  252. {
  253. type: "text",
  254. text: messages.replaceAll("\n", " ").replaceAll("*", "")
  255. }
  256. ],
  257. session_name: uuidv4(),
  258. userId: this.userid,
  259. file_ids: _fileid ? [_fileid] : [],
  260. isImage: work == 0 ? true : '',
  261. model: _fileid ? "gpt-4o-2024-11-20" : "gpt-4o-2024-11-20"
  262. };
  263. return new Promise((resolve,reject) => {
  264. this.ajax
  265. .post("https://gpt4.cocorobo.cn/ai_agent_park_chat", params)
  266. .then( response => {
  267. let data = response.data.FunctionResponse;
  268. console.log(data);
  269. if (data.message) {
  270. let dArray = {};
  271. try {
  272. dArray = JSON.parse(
  273. data.message.replaceAll("```json", "").replaceAll("```", "")
  274. );
  275. } catch (error) {
  276. console.log("error_________________" + error);
  277. try {
  278. let regex = new RegExp("(?<=```json)([\\s\\S]*?)(?=```)");
  279. let match = data.message.match(regex);
  280. // console.log("dArray2", match);
  281. dArray = JSON.parse(
  282. match[0]
  283. .replace(/\n/g, "")
  284. .replace(/\s{2,}/g, "")
  285. .replace(/\'/g, '"')
  286. );
  287. // dArray = data.choices[0].message.content
  288. } catch (error) {
  289. try {
  290. dArray = JSON.parse(
  291. data.message
  292. .replaceAll("```json", "")
  293. .replaceAll("```javascript", "")
  294. .replaceAll("# Solution", "")
  295. .replaceAll("```", "")
  296. .replace(/\n/g, "")
  297. .replace(/\s{2,}/g, "")
  298. .replace(/\'/g, '"')
  299. );
  300. } catch (error) {
  301. console.log("error_________________" + error);
  302. }
  303. console.log("error_________________" + error);
  304. }
  305. }
  306. let processedData = {};
  307. dArray.forEach(function(item) {
  308. let key = Object.keys(item)[0];
  309. let value = item[key];
  310. processedData[key] = value;
  311. });
  312. let IsAIsuccess = 0
  313. for (let tKey in this.scoTitList) {
  314. for (let key in processedData) {
  315. if (isNaN(parseFloat(this.scoTitList[tKey].detail)) && this.scoTitList[tKey].detail) {
  316. var result = this.scoTitList[tKey].detail.match(/[\u4e00-\u9fa5a-zA-Z]+/g).join("");
  317. }else{
  318. var result = this.scoTitList[tKey].detail
  319. }
  320. if (isNaN(parseFloat(key)) && key) {
  321. var key2 = key.match(/[\u4e00-\u9fa5a-zA-Z]+/g).join("");
  322. }else{
  323. var key2 = key
  324. }
  325. // let result = this.scoTitList[tKey].detail.match(/[\u4e00-\u9fa5a-zA-Z]+/g).join("");
  326. // let key2 = key.match(/[\u4e00-\u9fa5a-zA-Z]+/g).join("");
  327. if (key != "comment") {
  328. let isNumK = /^\d+(\.\d+)?$/.test(processedData[key]);
  329. if (result.indexOf(key2) != -1 && isNumK) {
  330. key = this.scoTitList[tKey].detail
  331. IsAIsuccess++
  332. }
  333. continue;
  334. }
  335. }
  336. continue;
  337. }
  338. let scotNum = 0
  339. this.scoTitList.forEach(e=>{
  340. if (e.isai == 1 || !e.isai) {
  341. scotNum++
  342. }
  343. })
  344. if (IsAIsuccess != scotNum) {
  345. console.log("评价失败");
  346. _this.ScLoading = false;
  347. return _this.aiupdetaSco(messages, uid, stage, task,_fileid).then(_=>{
  348. resolve();
  349. })
  350. }
  351. let processedDataCopy = {}
  352. for (const tKey in _this.scoTitList) {
  353. for (const key in processedData) {
  354. if (isNaN(parseFloat(_this.scoTitList[tKey].detail)) && _this.scoTitList[tKey].detail) {
  355. var result = _this.scoTitList[tKey].detail.match(/[\u4e00-\u9fa5a-zA-Z]+/g).join("");
  356. }else{
  357. var result = _this.scoTitList[tKey].detail
  358. }
  359. if (isNaN(parseFloat(key)) && key) {
  360. var key2 = key.match(/[\u4e00-\u9fa5a-zA-Z]+/g).join("");
  361. }else{
  362. var key2 = key
  363. }
  364. // let result = _this.scoTitList[tKey].detail.match(/[\u4e00-\u9fa5a-zA-Z]+/g).join("");
  365. // let key2 = key.match(/[\u4e00-\u9fa5a-zA-Z]+/g).join("");
  366. if (result.indexOf(key2) != -1) {
  367. let aaa = _this.scoTitList[tKey].detail
  368. processedDataCopy[aaa] = processedData[key]
  369. }
  370. }
  371. }
  372. for (const key in processedData) {
  373. if (key == "comment") {
  374. processedDataCopy.content = processedData[key];
  375. }
  376. }
  377. let params = {
  378. cid: _this.id,
  379. s: stage,
  380. t: task,
  381. tool: this.toolIndex ? this.toolIndex : '',
  382. rate: JSON.stringify(processedDataCopy),
  383. uid: uid
  384. };
  385. // console.log("params", params);
  386. _this.ajax
  387. .get(_this.$store.state.api + "updateWorksEvaTwo", params)
  388. .then(res => {
  389. console.log('999999999999999999999999999999999999999999999999999');
  390. this.getData()
  391. this.$emit('refreshOther',{tid:this.toolIndex,wid:this.wIndex})
  392. return resolve(1);
  393. })
  394. .catch(err => {
  395. console.error(err);
  396. return _this.aiupdetaSco(messages, uid, stage, task,_fileid).then(_=>{
  397. resolve();
  398. })
  399. });
  400. }
  401. })
  402. .catch(error => {
  403. console.log(error);
  404. return _this.aiupdetaSco(messages, uid, stage, task,_fileid).then(_=>{
  405. resolve();
  406. })
  407. });
  408. });
  409. },
  410. }
  411. };
  412. </script>
  413. <style scoped>
  414. .scoreTit {
  415. font-size: 16px;
  416. font-weight: 600;
  417. display: flex;
  418. justify-content: space-between;
  419. box-sizing: border-box;
  420. }
  421. .allD {
  422. margin: 5px 0;
  423. display: flex;
  424. width: 100%;
  425. overflow: auto;
  426. max-height: 100px;
  427. min-height: 60px;
  428. }
  429. .scoreStar {
  430. background-color: #f3f7fd;
  431. padding: 10px;
  432. height: 100%;
  433. flex: 1;
  434. }
  435. .scoreStar > div:last-child > .scoreStarBack {
  436. margin-bottom: 0;
  437. }
  438. .scoreStarBack {
  439. flex: 1;
  440. display: flex;
  441. justify-content: space-between;
  442. margin-bottom: 10px;
  443. }
  444. .rootImg {
  445. padding-top: 1px;
  446. box-sizing: border-box;
  447. display: block;
  448. }
  449. .scoreStarBack2 {
  450. padding: 10px 0;
  451. margin-right: 2px;
  452. }
  453. .AreaCss {
  454. margin-bottom: 5px;
  455. -webkit-line-clamp: 2;
  456. display: -webkit-box;
  457. -webkit-box-orient: vertical;
  458. overflow: hidden;
  459. text-overflow: ellipsis;
  460. /* margin-left: 20px; */
  461. }
  462. .AreaCss >>> .el-textarea__inner {
  463. min-height: 60px;
  464. max-height: 150px;
  465. padding-bottom: 20px;
  466. }
  467. .briefTit {
  468. width: 150px;
  469. text-overflow: ellipsis;
  470. overflow: hidden;
  471. white-space: nowrap;
  472. }
  473. </style>