markScore.vue 15 KB

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