index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. <template>
  2. <view class="feedback-modal" v-if="isShowFeedback">
  3. <view class="feedback">
  4. <view class="feedback-header">感谢您的宝贵反馈,我们会不断改进服务</view>
  5. <view class="feedback-body">
  6. <view class="item-box">
  7. <view class="item-title">评分</view>
  8. <view style="display: flex; gap: 14rpx">
  9. <block v-for="(item, index) in [1, 2, 3, 4, 5]" :key="index">
  10. <image
  11. :src="item <= score ? '/static/components/agent-ui/imgs/star-highlight.svg' : '/static/components/agent-ui/imgs/star.svg'"
  12. mode="aspectFill"
  13. class="star"
  14. @touchend="onChangeScore"
  15. :data-score="item"
  16. />
  17. </block>
  18. </view>
  19. </view>
  20. <view class="item-box">
  21. <view class="item-title">回答内容</view>
  22. <view>
  23. <block v-for="(item, index) in feedbackType === 'upvote' ? upVote : downVote" :key="index">
  24. <view :class="item.selected ? 'vote-item-highlight' : 'vote-item-normal'" @tap="onSelect" :data-item="item">{{ item.value }}</view>
  25. </block>
  26. </view>
  27. </view>
  28. <view class="item-box">
  29. <view class="item-title">反馈建议</view>
  30. <view>
  31. <textarea :value="message" class="feedback-textarea" maxlength="140" @input="inputChange" />
  32. </view>
  33. </view>
  34. </view>
  35. <view class="feedback-footer">
  36. <view class="btn-cancel" @tap="closeShowFeedback">取消</view>
  37. <view class="btn-submit" @tap="submitFeedback">提交反馈</view>
  38. </view>
  39. </view>
  40. </view>
  41. </template>
  42. <script>
  43. // pages/components/feedback/index.js
  44. export default {
  45. data() {
  46. return {
  47. upVote: [
  48. {
  49. selected: false,
  50. value: '准确有效'
  51. },
  52. {
  53. selected: false,
  54. value: '回答全面'
  55. },
  56. {
  57. selected: false,
  58. value: '立场正确'
  59. },
  60. {
  61. selected: false,
  62. value: '格式规范'
  63. },
  64. {
  65. selected: false,
  66. value: '专业性强'
  67. },
  68. {
  69. selected: false,
  70. value: '富有创意'
  71. },
  72. {
  73. selected: false,
  74. value: '表达清晰'
  75. },
  76. {
  77. selected: false,
  78. value: '值得信赖'
  79. },
  80. {
  81. selected: false,
  82. value: '高效'
  83. },
  84. {
  85. selected: false,
  86. value: '满意'
  87. }
  88. ],
  89. downVote: [
  90. {
  91. selected: false,
  92. value: '理解错误'
  93. },
  94. {
  95. selected: false,
  96. value: '未识别问题'
  97. },
  98. {
  99. selected: false,
  100. value: '事实错误'
  101. },
  102. {
  103. selected: false,
  104. value: '推理错误'
  105. },
  106. {
  107. selected: false,
  108. value: '内容不完整'
  109. },
  110. {
  111. selected: false,
  112. value: '不专业'
  113. },
  114. {
  115. selected: false,
  116. value: '违法有害'
  117. },
  118. {
  119. selected: false,
  120. value: '格式错误'
  121. },
  122. {
  123. selected: false,
  124. value: '乱码'
  125. },
  126. {
  127. selected: false,
  128. value: '内容重复'
  129. }
  130. ],
  131. score: 5,
  132. message: ''
  133. };
  134. },
  135. /**
  136. * 组件的属性列表
  137. */
  138. props: {
  139. isShowFeedback: {
  140. type: Boolean,
  141. default: false
  142. },
  143. feedbackRecordId: {
  144. type: String,
  145. default: ''
  146. },
  147. feedbackType: {
  148. type: String,
  149. default: ''
  150. },
  151. botId: {
  152. type: String,
  153. default: ''
  154. },
  155. input: {
  156. type: String,
  157. default: ''
  158. },
  159. aiAnswer: {
  160. type: String,
  161. default: ''
  162. }
  163. },
  164. watch: {
  165. feedbackType: function (value) {
  166. this.setData({
  167. score: value === 'upvote' ? 5 : 1
  168. });
  169. }
  170. },
  171. /**
  172. * 组件的方法列表
  173. */
  174. methods: {
  175. reset: function () {
  176. this.setData({
  177. upVote: [
  178. {
  179. selected: false,
  180. value: '准确有效'
  181. },
  182. {
  183. selected: false,
  184. value: '回答全面'
  185. },
  186. {
  187. selected: false,
  188. value: '立场正确'
  189. },
  190. {
  191. selected: false,
  192. value: '格式规范'
  193. },
  194. {
  195. selected: false,
  196. value: '专业性强'
  197. },
  198. {
  199. selected: false,
  200. value: '富有创意'
  201. },
  202. {
  203. selected: false,
  204. value: '表达清晰'
  205. },
  206. {
  207. selected: false,
  208. value: '值得信赖'
  209. },
  210. {
  211. selected: false,
  212. value: '高效'
  213. },
  214. {
  215. selected: false,
  216. value: '满意'
  217. }
  218. ],
  219. downVote: [
  220. {
  221. selected: false,
  222. value: '理解错误'
  223. },
  224. {
  225. selected: false,
  226. value: '未识别问题'
  227. },
  228. {
  229. selected: false,
  230. value: '事实错误'
  231. },
  232. {
  233. selected: false,
  234. value: '推理错误'
  235. },
  236. {
  237. selected: false,
  238. value: '内容不完整'
  239. },
  240. {
  241. selected: false,
  242. value: '不专业'
  243. },
  244. {
  245. selected: false,
  246. value: '违法有害'
  247. },
  248. {
  249. selected: false,
  250. value: '格式错误'
  251. },
  252. {
  253. selected: false,
  254. value: '乱码'
  255. },
  256. {
  257. selected: false,
  258. value: '内容重复'
  259. }
  260. ],
  261. score: 5,
  262. message: ''
  263. });
  264. },
  265. onChangeScore: function (e) {
  266. const { score } = e.currentTarget.dataset;
  267. this.setData({
  268. score
  269. });
  270. },
  271. onSelect: function (e) {
  272. const { item } = e.currentTarget.dataset;
  273. const newArr = [...(this.feedbackType === 'upvote' ? this.upVote : this.downVote)];
  274. const [selectedItem] = newArr.filter((i) => i.value === item.value);
  275. selectedItem.selected = !selectedItem.selected;
  276. if (this.feedbackType === 'upvote') {
  277. this.setData({
  278. upVote: newArr
  279. });
  280. } else {
  281. this.setData({
  282. downVote: newArr
  283. });
  284. }
  285. },
  286. inputChange: function (e) {
  287. const value = e.detail.value;
  288. this.setData({
  289. message: value
  290. });
  291. },
  292. closeShowFeedback: function () {
  293. this.$emit('close');
  294. },
  295. submitFeedback: async function () {
  296. const res = await wx.cloud.extend.AI.bot.sendFeedback({
  297. userFeedback: {
  298. botId: this.botId,
  299. recordId: this.feedbackRecordId,
  300. comment: this.message,
  301. rating: this.score,
  302. tags:
  303. this.feedbackType === 'upvote'
  304. ? this.upVote.filter((item) => item.selected).map((item) => item.value)
  305. : this.downVote.filter((item) => item.selected).map((item) => item.value),
  306. aiAnswer: this.aiAnswer,
  307. input: this.input,
  308. type: this.feedbackType === 'upvote' ? 'upvote' : 'downvote'
  309. },
  310. botId: this.botId
  311. });
  312. if (res.status === 'success') {
  313. uni.showToast({
  314. title: '感谢反馈',
  315. icon: 'success'
  316. });
  317. } else {
  318. uni.showToast({
  319. title: '反馈失败',
  320. icon: 'fail'
  321. });
  322. }
  323. this.reset();
  324. // console.log(res)
  325. this.$emit('close');
  326. }
  327. },
  328. created: function () {}
  329. };
  330. </script>
  331. <style>
  332. /* pages/components/feedback/index.wxss */
  333. .feedback-modal {
  334. position: fixed;
  335. top: 0px;
  336. left: 0px;
  337. width: 750rpx;
  338. height: 100%;
  339. background-color: rgba(0, 0, 0, 0.7);
  340. display: flex;
  341. justify-content: center;
  342. align-items: center;
  343. }
  344. .feedback {
  345. width: 520rpx;
  346. max-height: 70%;
  347. overflow-y: auto;
  348. background-color: #fff;
  349. border-radius: 24rpx;
  350. padding: 40rpx;
  351. }
  352. .feedback-header {
  353. font-weight: 500;
  354. font-size: 32rpx;
  355. text-align: justify;
  356. }
  357. .feedback-body {
  358. font-size: 28rpx;
  359. }
  360. .item-box {
  361. padding: 28rpx 0px;
  362. }
  363. .item-title {
  364. font-size: 28rpx;
  365. padding-bottom: 28rpx;
  366. }
  367. .star {
  368. width: 40rpx;
  369. height: 40rpx;
  370. }
  371. .vote-item-normal {
  372. display: inline-block;
  373. background-color: rgba(243, 243, 243, 1);
  374. height: 48rpx;
  375. line-height: 48rpx;
  376. border-radius: 24rpx;
  377. padding: 4rpx 24rpx;
  378. margin-right: 16rpx;
  379. margin-bottom: 16rpx;
  380. }
  381. .vote-item-highlight {
  382. display: inline-block;
  383. background-color: rgba(0, 82, 217, 0.1);
  384. height: 48rpx;
  385. line-height: 48rpx;
  386. border-radius: 24rpx;
  387. padding: 4rpx 24rpx;
  388. margin-right: 16rpx;
  389. margin-bottom: 16rpx;
  390. color: rgb(0, 82, 217);
  391. }
  392. .feedback-textarea {
  393. width: 100%;
  394. height: 150rpx;
  395. border-radius: 16rpx;
  396. border: 1px solid #ccc;
  397. box-sizing: border-box;
  398. padding: 16rpx;
  399. }
  400. .feedback-footer {
  401. font-size: 28rpx;
  402. display: flex;
  403. justify-content: flex-end;
  404. gap: 24rpx;
  405. }
  406. .btn-cancel {
  407. box-sizing: border-box;
  408. background-color: #fff;
  409. border: 1px solid #eee;
  410. padding: 6rpx 24rpx;
  411. border-radius: 6rpx;
  412. line-height: 48rpx;
  413. }
  414. .btn-submit {
  415. box-sizing: border-box;
  416. padding: 6rpx 24rpx;
  417. border-radius: 6rpx;
  418. color: #fff;
  419. background-color: #0052d9;
  420. line-height: 48rpx;
  421. }
  422. </style>