cocoFlowDia.vue 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. <template>
  2. <div>
  3. <el-dialog
  4. :visible.sync="FlowVisible"
  5. width="90%"
  6. class="dialog_diy"
  7. :close-on-click-modal="false"
  8. :fullscreen="markfullscreen"
  9. :before-close="handleClose">
  10. <div slot="title">
  11. <div class="markScore_diyTit">
  12. <div>查看作业</div>
  13. <img @click="markFullScreenBtn" style="cursor: pointer;height: 16px;" src="../../assets/icon/svgImg/nrk_fullscreen.svg" alt="" />
  14. </div>
  15. </div>
  16. <div class="markDialog">
  17. <template v-if="listData.length && showListData(listData)">
  18. <div v-for="(item,index) in listData" :key="index">
  19. <div class="BodyCon" v-if="item.messages.length" >
  20. <div class="BodyConTit">节点{{ index + 1}}</div>
  21. <div class="BodyConChat" v-for="(po, index2) in item.messages" :key="index+'-'+index2">
  22. <div class="left" v-if="po.role == 'assistant'">
  23. <div class="TName" style="background-color: #0560FD;">小可AI助手</div>
  24. <div class="con" v-html="MarkdownT(po.content)"></div>
  25. </div>
  26. <div class="left" v-if="po.role == 'user'">
  27. <div class="TName" style="background-color: #9747FF;">{{ username }}</div>
  28. <div class="con" v-html="po.content"></div>
  29. </div>
  30. </div>
  31. </div>
  32. </div>
  33. </template>
  34. <div v-else style="text-align: center;
  35. display: flex;
  36. justify-content: center;
  37. align-items: center;
  38. height: 100%;
  39. min-height: 500px;">
  40. 作业暂时只能展示对话文字哦~
  41. </div>
  42. </div>
  43. </el-dialog>
  44. </div>
  45. </template>
  46. <script>
  47. import MarkdownIt from "markdown-it";
  48. const getFile = url => {
  49. return new Promise((resolve, reject) => {
  50. var credentials = {
  51. accessKeyId: "AKIATLPEDU37QV5CHLMH",
  52. secretAccessKey: "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"
  53. }; //秘钥形式的登录上传
  54. window.AWS.config.update(credentials);
  55. window.AWS.config.region = "cn-northwest-1"; //设置区域
  56. let url2 = url;
  57. let _url2 = "";
  58. if (
  59. url2.indexOf("https://view.officeapps.live.com/op/view.aspx?src=") != -1
  60. ) {
  61. _url2 = url2.split(
  62. "https://view.officeapps.live.com/op/view.aspx?src="
  63. )[1];
  64. } else {
  65. _url2 = url2;
  66. }
  67. var s3 = new window.AWS.S3({ params: { Bucket: "ccrb" } });
  68. let name = decodeURIComponent(
  69. _url2.split("https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/")[1]
  70. );
  71. var params = {
  72. Bucket: "ccrb",
  73. Key: name
  74. };
  75. s3.getObject(params, function(err, data) {
  76. if (err) {
  77. console.log(err, err.stack);
  78. resolve({ data: 1 });
  79. } else {
  80. const fileContent = data.Body.toString("utf-8");
  81. resolve({ data: fileContent });
  82. } // sxuccessful response
  83. });
  84. // axios({
  85. });
  86. };
  87. export default {
  88. data() {
  89. return {
  90. username:'',
  91. FlowVisible:false,
  92. listData:[],
  93. markfullscreen:false
  94. }
  95. },
  96. computed: {
  97. showListData(){
  98. return function (val) {
  99. let kk = val.map(e=> e.messages).flat()
  100. console.log('kk',kk);
  101. if (kk.length == 0) {
  102. return false
  103. }
  104. return true
  105. };
  106. },
  107. MarkdownT() {
  108. return function (c) {
  109. let md = new MarkdownIt({
  110. html: true, // 允许渲染 HTML
  111. linkify: true, // 自动将URL链接转化为可点击链接
  112. typographer: true, // 启用排版规则(如替换 `"` 为 “)
  113. });
  114. const renderedContent = c ? md.render(c) : "";
  115. // 使用正则表达式替换链接
  116. const result = renderedContent.replace(/<a href="([^"]+)">([^<]*)<\/a>/g, (match, url, text) => {
  117. // 判断链接是否为图片格式
  118. if (/\.(png|jpg|jpeg|gif|bmp|svg)$/i.test(url)) {
  119. // 返回<img>标签
  120. return `<img src="${url}" alt="${text}" />`;
  121. } else {
  122. // 返回原来的<a>标签
  123. return match;
  124. }
  125. });
  126. return result;
  127. }
  128. }
  129. },
  130. methods: {
  131. // 评分弹框全屏
  132. markFullScreenBtn() {
  133. this.markfullscreen = !this.markfullscreen;
  134. },
  135. async openAppWork(val){
  136. console.log(val);
  137. // val.works = 'https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/pptData1764063222122.json'
  138. // let kk = 'https://ccrb.s3.cn-northwest-1.amazonaws.com.cn/pptData1764063222122.json'
  139. // console.log('this.isValidURL(val.works)',this.isValidURL(val.works));
  140. if (this.isValidURL(val.works)) {
  141. await getFile(val.works).then((res) => {
  142. val.works = res.data;
  143. });
  144. }
  145. this.username = val.sName
  146. try {
  147. this.listData = JSON.parse(val.works)
  148. } catch (error) {
  149. this.listData = []
  150. }
  151. this.FlowVisible = true;
  152. },
  153. isValidURL(str){
  154. try {
  155. const url = new URL(str);
  156. return ['http:', 'https:', 'ftp:'].includes(url.protocol) && !!url.hostname;
  157. } catch (e) {
  158. return false;
  159. }
  160. },
  161. handleClose(){
  162. this.listData = []
  163. this.FlowVisible = false;
  164. },
  165. },
  166. }
  167. </script>
  168. <style scoped>
  169. .dialog_diy {
  170. min-width: 800px;
  171. }
  172. .dialog_diy >>> .el-dialog__header {
  173. background: #fff !important;
  174. padding: 15px 20px;
  175. border-radius: 12px 12px 0 0 !important;
  176. border-bottom: 1px #E7E7E7 solid;
  177. }
  178. .dialog_diy >>> .el-dialog{
  179. border-radius: 12px;
  180. overflow: hidden;
  181. }
  182. .dialog_diy >>> .el-dialog__title{
  183. color: #fff;
  184. }
  185. .dialog_diy >>> .el-dialog__headerbtn {
  186. top: 19px;
  187. }
  188. .dialog_diy >>> .el-dialog__headerbtn .el-dialog__close{
  189. color: #000;
  190. }
  191. .dialog_diy >>> .el-dialog__headerbtn .el-dialog__close:hover {
  192. color: #000;
  193. }
  194. .dialog_diy >>> .el-dialog__body{
  195. background: #FFFFFFCC;
  196. border-radius: 12px !important;
  197. overflow: auto;
  198. box-sizing: border-box;
  199. min-height: 70vh;
  200. max-height: calc(100vh - 90px);
  201. padding: 0 !important;
  202. margin: 30px auto 0;
  203. width: 99%;
  204. }
  205. .dialog_diy >>> .el-dialog__body::-webkit-scrollbar-thumb {
  206. background-color: #0560FD; /* 设置滚动条滑块颜色 */
  207. }
  208. .markDialog{
  209. height: 100%;
  210. min-height: 600px;
  211. display: flex;
  212. padding:0 30px 30px;
  213. box-sizing: border-box;
  214. flex-direction: column;
  215. gap: 30px;
  216. }
  217. .markScore_diyTit {
  218. color: #000000;
  219. width: calc(100% - 50px);
  220. display: flex;
  221. height: 24px;
  222. justify-content: space-between;
  223. align-items: center;
  224. font-family: PingFang SC;
  225. }
  226. .TName{
  227. color: #fff;
  228. font-weight: 600;
  229. width: 150px;
  230. flex-shrink: 0;
  231. overflow: hidden;
  232. white-space: nowrap;
  233. text-overflow: ellipsis;
  234. border-radius: 12px 12px 0 0;
  235. height: 28px;
  236. padding: 6px 17px;
  237. box-sizing: border-box;
  238. display: flex;
  239. align-items: center;
  240. }
  241. .con{
  242. color: #000000E5;
  243. border-radius: 0 0 12px 12px;
  244. border: 1px solid #E7E7E7;
  245. padding: 16px;
  246. box-sizing: border-box;
  247. box-shadow: 0px 4px 20px 0px #0000001A;
  248. }
  249. .left{
  250. display: flex;
  251. flex-direction: column;
  252. font-size: 16px !important;
  253. justify-content: flex-start;
  254. line-height: 25px;
  255. }
  256. .BodyCon{
  257. background: #FFFFFF;
  258. border: 0.5px solid #E7E7E7;
  259. border-radius: 12px;
  260. padding: 10px;
  261. box-sizing: border-box;
  262. display: flex;
  263. flex-direction: column;
  264. gap: 10px;
  265. }
  266. .BodyConTit{
  267. font-family: PingFang SC;
  268. font-weight: 500;
  269. font-size: 16px;
  270. line-height: 24px;
  271. color: #000;
  272. }
  273. .BodyConChat{
  274. display: flex;
  275. flex-direction: column;
  276. /* border-radius: 0 0 12px 12px;
  277. border: 1px solid #E7E7E7;
  278. padding: 16px;
  279. box-sizing: border-box; */
  280. }
  281. </style>