prompt-list.vue 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. <template>
  2. <view>
  3. <cu-custom bgColor="bg-cyan" :isBack="true">
  4. <block slot="backText">返回</block>
  5. <block slot="content">提示词分类</block>
  6. </cu-custom>
  7. <scroll-view scroll-x class="bg-white nav margin-bottom-xs" scroll-with-animation :scroll-left="scrollLeft">
  8. <view class="cu-item" :class="item.value == tabCur ? 'text-cyan cur' : ''"
  9. v-for="(item, index) in navList" :key="index" @tap="e => tabSelect(e, item, index)" :data-id="item.value">
  10. {{ item.label }}
  11. </view>
  12. </scroll-view>
  13. <PromptList :promptList="promptList"></PromptList>
  14. <view v-if="loadStatus !== 'none'" class="cu-load text-grey" :class="loadStatus === 'loading' ? 'loading' : 'over'"></view>
  15. <view v-else class="cu-load text-grey info"></view>
  16. </view>
  17. </template>
  18. <script>
  19. import PromptList from '@/components/prompt-list/prompt-list.vue'
  20. import { findPromptListApi } from '@/api/chat.js'
  21. export default {
  22. components: { PromptList },
  23. data() {
  24. return {
  25. tabCur: 'personal',
  26. scrollLeft: 0,
  27. contentScrollWidth: 0,
  28. // Array.prototype.slice.call($(".checkboxList_autc").getElementsByTagName("li")).map(x => ({value: x.getElementsByTagName("label")[0].getAttribute("for").replaceAll("showcase_checkbox_id_", ""), label: x.getElementsByTagName("label")[0].childNodes[0].data}));
  29. navList: [
  30. // {
  31. // "value": "favorite",
  32. // "label": "常用"
  33. // },
  34. {
  35. "value": "latest",
  36. "label": "最新"
  37. },
  38. {
  39. "value": "personal",
  40. "label": "个人"
  41. },
  42. {
  43. "value": "contribute",
  44. "label": "投稿"
  45. },
  46. {
  47. "value": "write",
  48. "label": "写作辅助"
  49. },
  50. {
  51. "value": "language",
  52. "label": "语言/翻译"
  53. },
  54. {
  55. "value": "article",
  56. "label": "文章/报告"
  57. },
  58. {
  59. "value": "code",
  60. "label": "IT/编程"
  61. },
  62. {
  63. "value": "social",
  64. "label": "心理/社交"
  65. },
  66. {
  67. "value": "tool",
  68. "label": "工具"
  69. },
  70. {
  71. "value": "mind",
  72. "label": "发散思维"
  73. },
  74. {
  75. "value": "ai",
  76. "label": "AI"
  77. },
  78. {
  79. "value": "interesting",
  80. "label": "趣味知识"
  81. },
  82. {
  83. "value": "life",
  84. "label": "自助百科"
  85. },
  86. {
  87. "value": "living",
  88. "label": "生活质量"
  89. },
  90. {
  91. "value": "speech",
  92. "label": "辩论/演讲"
  93. },
  94. {
  95. "value": "music",
  96. "label": "音乐"
  97. },
  98. {
  99. "value": "philosophy",
  100. "label": "哲学/宗教"
  101. },
  102. {
  103. "value": "comments",
  104. "label": "点评/评鉴"
  105. },
  106. {
  107. "value": "company",
  108. "label": "企业职位"
  109. },
  110. {
  111. "value": "pedagogy",
  112. "label": "教育/学生"
  113. },
  114. {
  115. "value": "academic",
  116. "label": "学术/教师"
  117. },
  118. {
  119. "value": "professional",
  120. "label": "行业顾问"
  121. },
  122. {
  123. "value": "doctor",
  124. "label": "医生"
  125. },
  126. {
  127. "value": "finance",
  128. "label": "金融顾问"
  129. },
  130. {
  131. "value": "games",
  132. "label": "游戏"
  133. },
  134. {
  135. "value": "interpreter",
  136. "label": "终端/解释器"
  137. },
  138. {
  139. "value": "seo",
  140. "label": "SEO"
  141. },
  142. {
  143. "value": "text",
  144. "label": "文本/词语"
  145. }
  146. ],
  147. promptList: [],
  148. current: 1,
  149. loadStatus: 'none' // none/loading/over
  150. }
  151. },
  152. created() {
  153. this.findList()
  154. },
  155. mounted() {
  156. this.getScrollWidth()
  157. },
  158. onReachBottom() {
  159. if (this.loadStatus === 'over') {
  160. return
  161. }
  162. this.current ++
  163. this.fetchData()
  164. },
  165. methods: {
  166. findList() {
  167. this.loadStatus = 'none'
  168. this.promptList = []
  169. this.current = 1
  170. this.fetchData()
  171. },
  172. fetchData() {
  173. this.loadStatus = 'loading'
  174. findPromptListApi({
  175. current: this.current,
  176. tags: this.tabCur
  177. }).then(({ status, data }) => {
  178. if (status === 'success') {
  179. if(data.records && data.records.length > 0) {
  180. this.promptList.push(...data.records)
  181. if (data.records.length < 20) {
  182. this.loadStatus = 'over'
  183. } else {
  184. this.loadStatus = 'none'
  185. }
  186. } else {
  187. this.loadStatus = 'over'
  188. }
  189. }
  190. })
  191. },
  192. tabSelect(e, item, index) {
  193. this.tabCur = e.currentTarget.dataset.id
  194. // 当前点击子元素距离左边栏的距离 - scroll-view 宽度的一半 + 当前点击子元素一半的宽度 实现居中展示
  195. this.scrollLeft = this.navList[index].left - this.contentScrollWidth / 2 + this.navList[index].width / 2
  196. this.findList()
  197. },
  198. getScrollWidth() {
  199. const query = uni.createSelectorQuery().in(this)
  200. query.select('.nav').boundingClientRect(data => {
  201. // 拿到 scroll-view 组件宽度
  202. this.contentScrollWidth = data.width
  203. }).exec()
  204. query.selectAll('.cu-item').boundingClientRect(data => {
  205. let dataLen = data.length;
  206. for (let i = 0; i < dataLen; i++) {
  207. // scroll-view 子元素组件距离左边栏的距离
  208. this.navList[i].left = data[i].left
  209. // scroll-view 子元素组件宽度
  210. this.navList[i].width = data[i].width
  211. }
  212. }).exec()
  213. },
  214. }
  215. }
  216. </script>
  217. <style lang="scss">
  218. </style>