detail.vue 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214
  1. <template>
  2. <view>
  3. <view style="color: #000;">
  4. <tn-nav-bar backgroundColor="#F5FFFD" :bottomShadow="false">提问模板</tn-nav-bar>
  5. <view :style="{ height: tobheight + 'px' }"></view>
  6. </view>
  7. <wike-skeleton :count="5" v-if="!info.title"></wike-skeleton>
  8. <view class="directask">
  9. <view class="helpme">
  10. <view class="title">{{ info.title }}</view>
  11. {{ info.sub_title }}
  12. </view>
  13. <view class="expand u-flex flex-wrap">
  14. <view @click="showsheet = true" style="background: linear-gradient(to right, #00ca88, #00BCD4);" class="surplus u-flex align-center">
  15. <u-icon name="grid-fill" color="#f1f1f1" size="18" top="1"></u-icon>
  16. <view v-if="showchat4" class="item">{{currentmodel}}{{userData.vip_info&&userData.is_validity>0?(userData.vip_info.gpt4_type == 'time'?' - 今日':' - 会员')+'剩余提问:'+(userData.vip_info.gpt4_times == -1?'无限量':userData.vip_info.gpt4_times-userData.vip_info.gpt4_used+'次'):''}} ></view>
  17. <view v-else class="item">{{currentmodel}}{{userData.vip_info&&userData.is_validity>0?(userData.vip_info.gpt35_type == 'time'?' - 今日':' - 会员')+'剩余提问:'+(userData.vip_info.gpt35_times == -1?'无限量':userData.vip_info.gpt35_times-userData.vip_info.gpt35_used+'次'):''}} ></view>
  18. </view>
  19. <!-- <block v-if="!showchat4"> -->
  20. <navigator @click="getroute" :url="isLogin ?'/pages/user/member/member?id=2':'/pages/user/signin'"
  21. class="surplus u-flex align-center" v-if="appInfo.time_member && appInfo.time_member == 1">
  22. <u-icon name="clock-fill" color="#f1f1f1" size="18" top="1"></u-icon>
  23. <view class="item">会员套餐:{{ userData.is_validity == 1 ? (userData.vip_time == 9999?'永久':userData.countdown+'天') : '0天'}}</view>
  24. </navigator>
  25. <!-- </block> -->
  26. <block v-if="appInfo.number_member">
  27. <navigator v-if="appInfo.number_member == 1" @click="getroute"
  28. :url="isLogin ?'/pages/user/member/member?id=1':'/pages/user/signin'"
  29. class="surplus u-flex align-center">
  30. <u-icon name="question-circle-fill" color="#f1f1f1" size="18" top="1"></u-icon>
  31. <view class="item">{{appInfo.number_alias?appInfo.number_alias+':':'点数:'}}{{ userData.coin ? userData.coin : 0 }}</view>
  32. </navigator>
  33. </block>
  34. <block v-else>
  35. <navigator @click="getroute" :url="isLogin ?'/pages/user/member/member?id=1':'/pages/user/signin'"
  36. class="surplus u-flex align-center">
  37. <u-icon name="question-circle-fill" color="#f1f1f1" size="18" top="1"></u-icon>
  38. <view class="item">{{appInfo.number_alias?appInfo.number_alias+':':'点数:'}}{{ userData.coin ? userData.coin : 0 }}</view>
  39. </navigator>
  40. </block>
  41. <navigator @click="getroute" :url="isLogin ?'/pages/user/member/member?id=3':'/pages/user/signin'" class="surplus u-flex align-center">
  42. <u-icon name="more-circle-fill" color="#f1f1f1" size="18" top="1"></u-icon>
  43. <view class="item">免费领{{appInfo.number_alias?appInfo.number_alias:'点数'}}</view>
  44. </navigator>
  45. </view>
  46. <view class="textarea">
  47. <u--textarea v-model="valuechat" maxlength="-1" height="120" placeholder="请输入关键词或问题..."></u--textarea>
  48. <view class="operate u-flex align-center ">
  49. <!-- <view class="surpluss">随机示例</view> -->
  50. <view class="u-flex">
  51. <view @click="getempty" class="empty">清空</view>
  52. <!-- <view class="u_button">
  53. <u-button type="primary" :plain="true" text="清空" color="#9E9E9E"></u-button>
  54. </view> -->
  55. <view class="submit" hover-class="hoversubmit" @click="init(valuechat)">立即提交</view>
  56. <!-- <view class="u_button">
  57. <u-button type="primary" text="立即提交" color="#26B3A0"></u-button>
  58. </view> -->
  59. </view>
  60. </view>
  61. </view>
  62. <view class="answer-container" v-if="answer">
  63. <view class="answer u-flex align-center flex-wrap">
  64. <text
  65. v-if="answer == '正在思考中...'||answer == '请等我几秒钟,正在输入回答...'">{{answer}}</text>
  66. <u-parse v-else :content="answer" scrollTable selectable :tag-style="parse_style" style="width: 100%;"></u-parse>
  67. <!-- <text>{{ answer }}</text> -->
  68. <text v-if="answer == '正在思考中...'">{{ second }}s</text>
  69. <!-- <text class="flash" v-if="show_flash">│</text> -->
  70. <view
  71. :style="{marginLeft: answer == '正在思考中...'||answer == '请等我几秒钟,正在输入回答...'?20+'rpx':0+'rpx',marginTop: answer != '正在思考中...'||answer != '请等我几秒钟,正在输入回答...'?10+'rpx':0+'rpx'}"
  72. v-if="show_flash">
  73. <view style="margin-top: -5rpx;">
  74. <u-loading-icon size="17" mode="circle" color="#00ca88" :duration="300"></u-loading-icon>
  75. </view>
  76. </view>
  77. </view>
  78. <button hover-class="hoversubmit" class="duplicate u-flex justify-center" :disabled="!done"
  79. @click="copyText(backups)">一键复制</button>
  80. </view>
  81. <!-- #ifdef MP-WEIXIN -->
  82. <view class="wxad" v-if="appInfo.wxad_template_detail && appInfo.wxad_template_detail >= 1">
  83. <view style="100%">
  84. <wike-flow-main :flowtype="appInfo.wxad_template_detail" :banner_id="appInfo.banner_id"
  85. :video_banner_id="appInfo.video_banner_id" :native_id="appInfo.native_id"></wike-flow-main>
  86. </view>
  87. </view>
  88. <!-- #endif -->
  89. <view style="margin-top: 20rpx;"><wike-ad></wike-ad></view>
  90. </view>
  91. <u-action-sheet @select="selectClick" :round="10" :actions="sheetlist" :title="titlesheet" :show="showsheet" safeAreaInsetBottom @close="showsheet = false" cancelText="关闭"></u-action-sheet>
  92. <wike-model v-if="signShow"
  93. :authorize="false"
  94. :title="signTitle"
  95. btnText="立即获取"
  96. @save="signSign"
  97. @close="signShow = false"
  98. ></wike-model>
  99. <wike-modal-qrcode :qrcode="gzhqrcode" :showconcern="showconcern" @concernclose="concernclose"></wike-modal-qrcode>
  100. </view>
  101. </template>
  102. <script>
  103. import {
  104. mapMutations,
  105. mapActions,
  106. mapState,
  107. mapGetters
  108. } from 'vuex';
  109. import {
  110. API_STEROOT,
  111. } from '@/common/request/request';
  112. let interstitialAd = null,
  113. timer,
  114. time2,
  115. down,
  116. delay;
  117. const {
  118. marked
  119. } = require('marked');
  120. import hljs from "highlight.js";
  121. import "highlight.js/scss/atom-one-dark.scss";
  122. export default {
  123. data() {
  124. return {
  125. signShow:false,
  126. signTitle:'',
  127. info: {},
  128. tobheight: 45,
  129. platform: this.$platform.get(),
  130. backups:'',
  131. answer: '',
  132. valuechat: '',
  133. thevaluechat: '',
  134. down: 0,
  135. done: false,
  136. second: 11,
  137. showanswer: false,
  138. show_flash: false,
  139. selectornot: 0,
  140. haddressurl: '',
  141. haddresssk: '',
  142. eights: false,
  143. thecontent: '',
  144. //通道
  145. thoroughfare: 0,
  146. showdirect: true,
  147. //模型
  148. showsheet:false,
  149. titlesheet:'切换模型',
  150. //是否为gpt4模型
  151. showchat4:false,
  152. //模型数据
  153. // #ifdef MP-WEIXIN
  154. sheetlist: [
  155. // {
  156. // index: 0,
  157. // name: 'ChatGPT 4.0',
  158. // subname: "超级高效沟通·简单提问",
  159. // disabled: false
  160. // },
  161. {
  162. index: 1,
  163. name: 'ChatGPT 3.5',
  164. subname: "高效沟通·简单提问",
  165. color: '#26b3a0d6',
  166. disabled: false
  167. },
  168. ],
  169. // #endif
  170. // #ifdef H5
  171. sheetlist:[
  172. {
  173. index:0,
  174. name:'ChatGPT 4.0',
  175. subname:"超级高效沟通·简单提问",
  176. disabled:false
  177. },
  178. {
  179. index:1,
  180. name:'ChatGPT 3.5',
  181. subname:"高效沟通·简单提问",
  182. color:'#26b3a0d6',
  183. disabled:false
  184. },
  185. ],
  186. // #endif
  187. // 消耗
  188. plan:{},
  189. currentmodel:'',
  190. chatgpturl:'',
  191. templateid:'',
  192. showconcern:false,
  193. gzhqrcode:'',
  194. parse_style: {
  195. // 字符串的形式
  196. p: 'margin-bottom:0rpx;',
  197. // 一级标题
  198. h1: `
  199. margin:25px 0;
  200. font-size: 24px;
  201. text-align: center;
  202. font-weight: bold;
  203. color: #00ca88;
  204. padding:3px 10px 1px;
  205. border-bottom: 2px solid #00ca88;
  206. border-top-right-radius:3px;
  207. border-top-left-radius:3px;
  208. `,
  209. // 二级标题
  210. h2: `
  211. margin:40px 0 20px 0;
  212. font-size: 20px;
  213. text-align:center;
  214. color:#00ca88;
  215. font-weight:bolder;
  216. padding-left:10px;
  217. border:1px solid #00ca88;
  218. `,
  219. // 三级标题
  220. h3: `
  221. margin:30px 0 10px 0;
  222. font-size: 18px;
  223. color: #00ca88;
  224. padding-left:10px;
  225. border-left:3px solid #00ca88;
  226. `,
  227. // 四级标题
  228. h4: `
  229. margin:20px 0 10px 0;
  230. font-size: 16px;
  231. color: #00ca88;
  232. padding-left:10px;
  233. border-left:3px solid #00ca88;
  234. `,
  235. // 五级标题
  236. h5: `
  237. margin:10px 0 10px 0;
  238. font-size: 14px;
  239. color: #00ca88;
  240. padding-left:10px;
  241. border-left:3px solid #00ca88;
  242. `,
  243. // 六级标题
  244. h6: `
  245. margin:10px 0 10px 0;
  246. font-size: 12px;
  247. color: #00ca88;
  248. padding-left:10px;
  249. border-left:3px solid #00ca88;
  250. `,
  251. ul: 'margin:24rpx;color: #555;',
  252. ol: 'margin:12rpx;color:#555;',
  253. li: `
  254. margin: 12rpx 0;
  255. color: #555;
  256. `,
  257. // 链接
  258. a: `
  259. color: #00ca88;`,
  260. // 加粗
  261. strong: `
  262. font-weight: border;
  263. color: #00ca88;
  264. `,
  265. // 斜体
  266. em: `
  267. color: #00ca88;
  268. letter-spacing:0.3em;
  269. `,
  270. blockquote: 'padding: 15rpx;margin:0 0 12rpx 0;border-radius: 6rpx;color: #555;border-left: 4px solid #dddddd;',
  271. hr: `height:1px;padding:0;border:none;text-align:center;background-image:linear-gradient(to right,rgba(248,57,41,0),${'#9e9e9e'},rgba(248,57,41,0));`,
  272. table: 'border-spacing:0;overflow:auto;min-width:100%;margin:10px 0;border-collapse: collapse;',
  273. th: 'background-color: whitesmoke;border: 1px solid #2d2d2d;padding:10rpx;',
  274. td: 'border: 1px solid #2d2d2d;padding:10rpx;',
  275. pre: `
  276. color: #c7254e;
  277. padding: 20rpx;
  278. border-radius: 5px;
  279. white-space: pre;
  280. overflow: auto;
  281. margin:12rpx 0;
  282. font-size:13px;
  283. background: #2d2d2d;
  284. `,
  285. },
  286. };
  287. },
  288. computed: {
  289. ...mapGetters(['appInfo', 'userInfo', 'userData', 'isLogin', 'homeTemplate'])
  290. },
  291. onShow: function() {
  292. // if (!this.$ws.socketStatus()) {
  293. // this.$ws.init();
  294. // }
  295. if (this.isLogin) {
  296. this.getUserData();
  297. }
  298. this.getPlan();
  299. this.systemwechat()
  300. },
  301. onLoad() {
  302. if (this.platform == 'wxMiniProgram') {
  303. var menumtop = uni.getMenuButtonBoundingClientRect().top - uni.getSystemInfoSync().statusBarHeight;
  304. var paddingtop = uni.getSystemInfoSync().statusBarHeight + menumtop;
  305. this.tobheight = menumtop + paddingtop + uni.getMenuButtonBoundingClientRect().height;
  306. }
  307. this.templateid = this.$Route.query.id
  308. // console.log(this.templateid);
  309. this.getInfo();
  310. this.onmessage();
  311. // this.init()
  312. // #ifdef H5
  313. this.aigetAddress();
  314. // #endif
  315. this.initHighLight();
  316. },
  317. onReady() {
  318. let that = this;
  319. // #ifdef MP-WEIXIN
  320. clearTimeout(timer);
  321. // 在适合的场景显示插屏广告
  322. timer = setTimeout(function() {
  323. // 在页面onLoad回调事件中创建插屏广告实例
  324. if (wx.createInterstitialAd && that.appInfo.interstitial_status == 1) {
  325. interstitialAd = wx.createInterstitialAd({
  326. adUnitId: that.appInfo.interstitial_id
  327. });
  328. interstitialAd.onLoad(() => {});
  329. interstitialAd.onError(err => {});
  330. interstitialAd.onClose(() => {
  331. if (that.appInfo.interstitial_infinite_status && that.appInfo.interstitial_infinite_status == 1) {
  332. that.showInterstitial();
  333. }else{
  334. interstitialAd.show().catch(err => {
  335. console.error(err);
  336. });
  337. }
  338. });
  339. interstitialAd.show().catch(err => {
  340. // console.error(err);
  341. });
  342. }
  343. }, 4000);
  344. // #endif
  345. },
  346. onUnload() {
  347. if (this.$ws.socketStatus()) {
  348. this.$ws.completeClose();
  349. }
  350. clearInterval(time2);
  351. },
  352. onHide() {
  353. // console.log('onHide');
  354. if (this.$ws.socketStatus()) {
  355. this.$ws.completeClose();
  356. }
  357. },
  358. methods: {
  359. ...mapActions(['getUserInfo', 'showAuthModal', 'getUserData']),
  360. onmessage() {
  361. let that = this,
  362. message = '';
  363. uni.onSocketMessage(function(res) {
  364. // console.log(2);
  365. that.showanswer = true;
  366. let a = res.data;
  367. if (a.indexOf('wike_err:') != -1) {
  368. uni.showToast({
  369. title: '报错:' + a,
  370. icon: 'none'
  371. });
  372. that.answer = '报错:' + a;
  373. that.show_flash = false;
  374. return;
  375. }
  376. if (!that.$ws.socketStatus()) {
  377. uni.showToast({
  378. title: '连接错误,正在重新思考'
  379. });
  380. that.onSubmit(that.valuechat);
  381. return;
  382. }
  383. if (a.indexOf('[DONE]') != -1) {
  384. that.record(that.valuechat, message);
  385. message = '';
  386. that.done = true;
  387. that.show_flash = false;
  388. // that.$ws.completeClose()
  389. if (that.$ws.socketStatus()) {
  390. that.$ws.completeClose();
  391. }
  392. } else {
  393. var b = a.split('data:').filter(w => !!w.trim() && w.trim() !== '[DONE]');
  394. var c = '';
  395. b.map(w => JSON.parse(w))
  396. .map(w => (c = w.choices[0].delta.content))
  397. .join('');
  398. // console.log(c);
  399. if (c != undefined) {
  400. message += c;
  401. }
  402. if (that.thoroughfare == 1) {
  403. that.backups = message;
  404. that.answer = marked(message);
  405. }
  406. uni.hideLoading();
  407. }
  408. });
  409. },
  410. initHighLight() {
  411. hljs.configure({
  412. useBR: true,
  413. tabReplace: " ",
  414. });
  415. marked.setOptions({
  416. renderer: new marked.Renderer(),
  417. gfm: true,
  418. tables: true,
  419. breaks: false,
  420. pedantic: false,
  421. highlight: function(code, lang) {
  422. if (lang && hljs.getLanguage(lang)) {
  423. return hljs.highlight(lang, code, true).value;
  424. } else {
  425. return hljs.highlightAuto(code).value;
  426. }
  427. },
  428. });
  429. },
  430. systemwechat(){
  431. this.$http('conf.getGroupConf', { group: 'system.wechat' }).then(res => {
  432. if (res.code == 0) {
  433. this.gzhqrcode = res.data.qrcode_path
  434. const focuson = uni.getStorageSync('focuson');
  435. // console.log(focuson);
  436. if(!focuson){
  437. if(this.gzhqrcode){
  438. if(this.isLogin&&this.appInfo.is_show_logged_qrcode == 1 ){
  439. this.showconcern = true
  440. }
  441. }
  442. }
  443. }
  444. })
  445. },
  446. concernclose(){
  447. this.showconcern = false
  448. },
  449. //选择模型
  450. selectClick(index){
  451. for( var a=0;a< this.sheetlist.length;a++){
  452. this.sheetlist[a].color = '#000'
  453. }
  454. // #ifdef H5
  455. this.sheetlist[index.index].color = '#26b3a0d6'
  456. // #endif
  457. // #ifdef MP-WEIXIN
  458. this.sheetlist[index.index - 1].color = '#26b3a0d6'
  459. // #endif
  460. if(index.index == 0){
  461. this.showchat4 = true
  462. this.paintingmode = false
  463. }else{
  464. this.paintingmode = false
  465. this.showchat4 = false
  466. }
  467. // this.switcmode()
  468. // uni.showToast({
  469. // title:'已切换模型'
  470. // })
  471. // console.log(index)
  472. this.getcurrentmodel()
  473. },
  474. getroute() {
  475. if (!this.isLogin) {
  476. uni.setStorageSync('route', '/pages/template/detail?id='+this.templateid);
  477. }
  478. },
  479. waitWss() {
  480. return new Promise((resolve, reject) => {
  481. uni.onSocketOpen(function(res) {
  482. // console.log('WebSocket连接已打开!');
  483. resolve(1);
  484. });
  485. });
  486. },
  487. waitClose() {
  488. return new Promise((resolve, reject) => {
  489. uni.onSocketClose(function(res) {
  490. // console.log('WebSocket 已关闭!');
  491. resolve(1);
  492. });
  493. });
  494. },
  495. record(question, answer) {
  496. let that = this,type = that.showchat4 ? 'gpt4' : 'gpt35';;
  497. this.$http('question.add', {
  498. question,
  499. answer,
  500. type
  501. }).then(res => {
  502. if (res.code == 0) {
  503. that.getUserData();
  504. // console.log(that.question_index);
  505. } else {
  506. that.valuechat = '该问题已被隐藏!';
  507. that.answer = res.msg;
  508. that.done = true;
  509. that.show_flash = false;
  510. }
  511. });
  512. },
  513. getPlan() {
  514. let that = this;
  515. this.$http('conf.getGroupConf', {
  516. group: 'system.plan'
  517. }).then(res => {
  518. if (res.code == 0) {
  519. this.plan = res.data
  520. let gpt = this.appInfo;
  521. // #ifdef MP-WEIXIN
  522. this.sheetlist[0].name = gpt.gpt35_alias?gpt.gpt35_alias:'ChatGPT 3.5'
  523. this.sheetlist[0].subname = gpt.gpt35_intro?gpt.gpt35_intro:'高效沟通·简单提问'
  524. // #endif
  525. // #ifdef H5
  526. this.sheetlist[0].disabled = gpt.is_gpt4 == 1?false:true
  527. this.sheetlist[0].name = gpt.gpt4_alias?gpt.gpt4_alias:'ChatGPT 4.0'
  528. this.sheetlist[0].subname = gpt.gpt4_intro?gpt.gpt4_intro:'高效沟通·简单提问'
  529. this.sheetlist[1].name = gpt.gpt35_alias?gpt.gpt35_alias:'ChatGPT 3.5'
  530. this.sheetlist[1].subname = gpt.gpt35_intro?gpt.gpt35_intro:'高效沟通·简单提问'
  531. // #endif
  532. this.getcurrentmodel()
  533. }
  534. })
  535. },
  536. getcurrentmodel(){
  537. let gpt = this.appInfo;
  538. if(this.showchat4){
  539. this.currentmodel = gpt.gpt4_alias ? gpt.gpt4_alias : 'ChatGPT 4.0'
  540. }else{
  541. this.currentmodel = gpt.gpt35_alias ? gpt.gpt35_alias : 'ChatGPT 3.5'
  542. }
  543. },
  544. aigetAddress() {
  545. var that = this;
  546. let uniacid = uni.getStorageSync("uniacid") || "";
  547. that.chatgpturl = API_STEROOT+'api.ai/chatgpt?uniacid='+uniacid;
  548. // if(that.appInfo.connect_lines && that.appInfo.connect_lines == 2){
  549. // that.$http('ai.getAddress').then(res => {
  550. // if (res.code == 0) {
  551. // that.haddressurl = res.data.url;
  552. // that.haddresssk = res.data.sk;
  553. // that.chatgpturl = API_STEROOT+'api.ai/chatgpt?uniacid='+uniacid;
  554. // }else{
  555. // uni.showToast({
  556. // title: '未正确配置key',
  557. // icon: 'none'
  558. // });
  559. // return;
  560. // }
  561. // });
  562. // }else{
  563. // that.chatgpturl = API_STEROOT+'api.ai/chatgpt?uniacid='+uniacid;
  564. // }
  565. },
  566. getInfo() {
  567. this.$http('template.info', {
  568. id: this.$Route.query.id
  569. }).then(res => {
  570. if (res.code == 0) {
  571. // uni.setNavigationBarTitle({
  572. // title: res.data.title
  573. // });
  574. this.info = res.data;
  575. uni.setNavigationBarTitle({
  576. title: this.appInfo.site_name
  577. });
  578. }
  579. });
  580. },
  581. copyText(text) {
  582. uni.setClipboardData({
  583. data: text,
  584. success: function() {
  585. // console.log('success');
  586. uni.showToast({
  587. title: '复制成功'
  588. });
  589. }
  590. });
  591. },
  592. countdown() {
  593. var that = this;
  594. that.second--;
  595. if (that.second == 0) {
  596. // console.log('15秒定时结束');
  597. if (!that.showanswer) {
  598. if(!that.showchat4){
  599. uni.showLoading({
  600. title: '加载中...'
  601. });
  602. }
  603. clearTimeout(down);
  604. if (that.showdirect) {
  605. setTimeout(() => {
  606. uni.hideLoading();
  607. that.second = 11;
  608. that.directGpt(that.valuechat);
  609. }, 1500);
  610. } else {
  611. uni.hideLoading();
  612. that.second = 11;
  613. if (that.answer == '正在思考中...') {
  614. that.answer = '请等我几秒钟,正在输入回答...';
  615. }
  616. }
  617. return;
  618. } else {
  619. that.second = 11;
  620. clearTimeout(down);
  621. }
  622. return;
  623. }
  624. down = setTimeout(() => {
  625. if (that.showanswer) {
  626. clearTimeout(down);
  627. that.second = 11;
  628. return;
  629. }
  630. that.countdown();
  631. }, 1000);
  632. },
  633. getempty() {
  634. var that = this;
  635. if (that.answer && !that.done) {
  636. uni.showToast({
  637. title: '正在输入回答,请等待输入完成',
  638. icon: 'none'
  639. });
  640. return;
  641. }
  642. that.valuechat = '';
  643. that.answer = '';
  644. },
  645. getcheckText() {
  646. var that = this;
  647. return new Promise((resolve, reject) => {
  648. that.$http('ai.checkText', {
  649. prompt: that.thecontent
  650. }).then(res => {
  651. if (res.code == 0) {
  652. resolve(1);
  653. } else {
  654. that.valuechat = '该问题已被隐藏!';
  655. that.answer = res.msg;
  656. that.done = true;
  657. that.show_flash = false;
  658. }
  659. })
  660. });
  661. },
  662. signSign(){
  663. uni.navigateTo({
  664. url: '/pages/user/member/member'
  665. });
  666. this.signShow = false
  667. },
  668. async init(e) {
  669. let that = this;
  670. if (!that.isLogin) {
  671. uni.navigateTo({
  672. url: '/pages/user/signin'
  673. });
  674. uni.setStorageSync('route', '/pages/template/detail?id='+this.templateid);
  675. return;
  676. }
  677. if (!e) {
  678. uni.showToast({
  679. title: '请输入关键词或问题',
  680. icon: 'none'
  681. });
  682. return;
  683. }
  684. this.thecontent = e;
  685. if (that.appInfo.time_member && that.appInfo.time_member == 1) {
  686. if (that.showchat4) {
  687. if (that.userData.vip_info && that.userData.is_validity > 0 && that.userData.vip_info.gpt4_used ==
  688. that.userData.vip_info.gpt4_times && that.userData.coin < that.plan.lock_gpt4) {
  689. var alias = that.appInfo.number_alias ? that.appInfo.number_alias : '点数';
  690. // this.signTitle = "<p style='font-weight: 550;font-size: 16px;'>您的提问<span>" + alias +
  691. // "</span>不足或会员套餐内剩余次数不足,无法发起提问</p>"
  692. this.signTitle =
  693. "<p style='font-weight: 550;font-size: 16px;'>提问需要<span style='color: #26b3a0;padding: 0 4px;'>" +
  694. that.plan.lock_gpt4 + "</span><span>" + alias +
  695. "</span></p><p style='padding-top: 10px;'>您的提问<span>" + alias +"</span>不足或会员套餐内剩余次数不足,无法发起提问</p>"
  696. this.signShow = true
  697. return;
  698. }
  699. if (that.userData.is_validity == 0&&that.userData.coin < that.plan.lock_gpt4) {
  700. var alias = that.appInfo.number_alias ? that.appInfo.number_alias : '点数';
  701. this.signTitle =
  702. "<p style='font-weight: 550;font-size: 16px;'>提问需要<span style='color: #26b3a0;padding: 0 4px;'>" +
  703. that.plan.lock_gpt4 + "</span><span>" + alias +
  704. "</span></p><p style='padding-top: 10px;'>您的提问<span>" + alias +"</span>不足或会员套餐内剩余次数不足,无法发起提问</p>"
  705. this.signShow = true
  706. return;
  707. }
  708. } else {
  709. if (that.userData.is_validity > 0 && that.userData.vip_info.gpt35_used == that.userData.vip_info
  710. .gpt35_times && that.userData.coin <= 0) {
  711. var alias = that.appInfo.number_alias ? that.appInfo.number_alias : '点数';
  712. // this.signTitle = "<p style='font-weight: 550;font-size: 16px;'>您的提问<span>" + alias +
  713. // "</span>不足或会员套餐内剩余次数不足,无法发起提问</p>"
  714. this.signTitle =
  715. "<p style='font-weight: 550;font-size: 16px;'>提问需要<span style='color: #26b3a0;padding: 0 4px;'>" +
  716. 1 + "</span><span>" + alias +
  717. "</span></p><p style='padding-top: 10px;'>您的提问<span>" + alias +"</span>不足或会员套餐内剩余次数不足,无法发起提问</p>"
  718. this.signShow = true
  719. return;
  720. }
  721. if (that.userData.is_validity == 0&&that.userData.coin <= 0) {
  722. var alias = that.appInfo.number_alias ? that.appInfo.number_alias : '点数';
  723. this.signTitle =
  724. "<p style='font-weight: 550;font-size: 16px;'>提问需要<span style='color: #26b3a0;padding: 0 4px;'>" +
  725. 1 + "</span><span>" + alias +
  726. "</span></p><p style='padding-top: 10px;'>您的提问<span>" + alias +"</span>不足或会员套餐内剩余次数不足,无法发起提问</p>"
  727. this.signShow = true
  728. return;
  729. }
  730. }
  731. } else {
  732. if (that.showchat4 && that.userData.coin < that.plan.lock_gpt4) {
  733. var alias = that.appInfo.number_alias ? that.appInfo.number_alias : '点数';
  734. this.signTitle =
  735. "<p style='font-weight: 550;font-size: 16px;'>提问需要<span style='color: #26b3a0;padding: 0 4px;'>" +
  736. that.plan.lock_gpt4 + "</span><span>" + alias +
  737. "</span></p><p style='padding-top: 10px;'>您当前有<span style='color: #26b3a0;padding: 0 4px;'>" +
  738. that.userData.coin + "</span><span>" + alias + "</span>,无法发起提问,快去获取<span>" + alias +
  739. "</span>吧</p>"
  740. this.signShow = true
  741. return;
  742. }
  743. if (!that.showchat4 && that.userData.coin <= 0) {
  744. var alias = that.appInfo.number_alias ? that.appInfo.number_alias : '点数';
  745. this.signTitle =
  746. "<p style='font-weight: 550;font-size: 16px;'>提问需要<span style='color: #26b3a0;padding: 0 4px;'>" +
  747. 1 + "</span><span>" + alias +
  748. "</span></p><p style='padding-top: 10px;'>您当前有<span style='color: #26b3a0;padding: 0 4px;'>" +
  749. that.userData.coin + "</span><span>" + alias + "</span>,无法发起提问,快去获取<span>" + alias +
  750. "</span>吧</p>"
  751. this.signShow = true
  752. return;
  753. }
  754. }
  755. // if(that.showchat4){
  756. // if(that.userData.coin < that.plan.lock_gpt4){
  757. // var alias = that.appInfo.number_alias ? that.appInfo.number_alias : '点数';
  758. // this.signTitle = "<p style='font-weight: 550;font-size: 16px;'>提问需要<span style='color: #26b3a0;padding: 0 4px;'>"+that.plan.lock_gpt4+"</span><span>"+alias+"</span></p><p style='padding-top: 10px;'>您当前有<span style='color: #26b3a0;padding: 0 4px;'>"+that.userData.coin+"</span><span>"+alias+"</span>,此模型不支持会员套餐,无法发起提问,快去获取<span>"+alias+"</span>吧</p>"
  759. // this.signShow = true
  760. // return;
  761. // }
  762. // }
  763. // if (this.appInfo.time_member && this.appInfo.time_member == 1) {
  764. // if (that.userData.is_validity > 0 && that.userData.vip_info.gpt35_used == that.userData.vip_info.gpt35_times && that.userData.coin <= 0) {
  765. // var alias = that.appInfo.number_alias ? that.appInfo.number_alias : '点数';
  766. // this.signTitle = "<p style='font-weight: 550;font-size: 16px;'>您的提问<span>"+alias+"</span>/会员套餐内剩余次数不足</p>"
  767. // this.signShow = true
  768. // return;
  769. // }
  770. // if (that.userData.is_validity == 0) {
  771. // if (that.userData.coin <= 0) {
  772. // var alias = that.appInfo.number_alias?that.appInfo.number_alias:'点数';
  773. // this.signTitle = "<p style='font-weight: 550;font-size: 16px;'>您的提问<span>"+alias+"</span>/会员套餐不足</p>"
  774. // this.signShow = true
  775. // return;
  776. // }
  777. // }
  778. // } else {
  779. // if (that.userData.coin <= 0) {
  780. // var alias = that.appInfo.number_alias?that.appInfo.number_alias:'点数';
  781. // this.signTitle = "<p style='font-weight: 550;font-size: 16px;'>您的提问<span>"+alias+"</span>不足</p>"
  782. // this.signShow = true
  783. // return;
  784. // }
  785. // }
  786. // if (!that.haddresssk && that.appInfo.connect_lines && that.appInfo.connect_lines == 2) {
  787. // uni.showToast({
  788. // title: '未正确配置key',
  789. // icon: 'none'
  790. // });
  791. // return;
  792. // }
  793. if (that.answer && !that.done) {
  794. uni.showToast({
  795. title: '正在输入回答,请等待输入完成',
  796. icon: 'none'
  797. });
  798. return;
  799. }
  800. uni.showLoading({})
  801. // #ifdef H5
  802. let check = this.appInfo.is_h5_filter && this.appInfo.is_h5_filter == 1 ? await this.getcheckText() :
  803. 1;
  804. // #endif
  805. // #ifdef MP-WEIXIN
  806. let check = await this.getcheckText();
  807. // #endif
  808. if (check == 1) {
  809. uni.hideLoading();
  810. that.done = false;
  811. that.answer = '正在思考中...';
  812. that.show_flash = true;
  813. that.showanswer = false;
  814. that.countdown();
  815. // #ifdef MP-WEIXIN
  816. if(this.showchat4){
  817. this.directGpt(this.thecontent);
  818. return;
  819. }
  820. // #endif
  821. // #ifdef MP-WEIXIN
  822. if (!that.$ws.socketStatus()) {
  823. that.$ws.init();
  824. that.showdirect = true;
  825. let re = await that.waitWss();
  826. if (re == 1) {
  827. that.onSubmit(e);
  828. }
  829. } else {
  830. that.$ws.completeClose();
  831. that.showdirect = false;
  832. that.directGpt(this.thecontent);
  833. }
  834. // #endif
  835. // #ifdef H5
  836. that.showdirect = true;
  837. that.fetchmodel(that.thecontent);
  838. // #endif
  839. }
  840. },
  841. async onSubmit(e) {
  842. let that = this;
  843. that.thoroughfare = 1
  844. var ty = {
  845. prompt: e,
  846. guide: that.info.guide,
  847. key: that.haddresssk ? that.haddresssk : '',
  848. lines: that.appInfo.connect_lines ? this.appInfo.connect_lines : 1,
  849. temperature: that.appInfo.temperature ? this.appInfo.temperature : 0,
  850. presence_penalty: that.appInfo.presence_penalty ? this.appInfo.presence_penalty : 0,
  851. frequency_penalty: that.appInfo.frequency_penalty ? this.appInfo.frequency_penalty : 0,
  852. };
  853. var json = JSON.stringify(ty);
  854. that.$ws.send(json);
  855. },
  856. directGpt(e) {
  857. let that = this;
  858. // console.log('s');
  859. if (that.showdirect) {
  860. that.answer = '请等我几秒钟,正在输入回答...';
  861. }
  862. that.showanswer = that.showdirect;
  863. that.thoroughfare = 3
  864. that.$http(that.showchat4?'ai.chat4':'ai.chat', {
  865. prompt: e,
  866. guide: that.info.guide,
  867. }).then(res => {
  868. if (res.code == 0) {
  869. if (that.thoroughfare == 3) {
  870. that.backups = res.data.trim();
  871. that.answer = marked(res.data.trim());
  872. that.show_flash = false;
  873. that.done = true;
  874. that.second = 11;
  875. that.getUserData();
  876. } else if (res.code == 3) {
  877. that.answer = res.msg;
  878. that.show_flash = false;
  879. that.second = 11;
  880. that.done = true;
  881. // that.showanswer = true
  882. } else {
  883. that.answer = res.msg;
  884. that.valuechat = '该问题已被隐藏!';
  885. that.show_flash = false;
  886. that.second = 11;
  887. that.done = true;
  888. // that.showanswer = true
  889. }
  890. }else{
  891. that.answer = res.msg;
  892. that.show_flash = false;
  893. that.second = 11;
  894. that.done = true;
  895. }
  896. });
  897. },
  898. fetchmodel(e) {
  899. var that = this;
  900. let i = 1,
  901. message = '';
  902. let param = {
  903. // max_tokens: 3000,
  904. // model: 'gpt-3.5-turbo-0301',
  905. // stream: true,
  906. type:that.showchat4?'gpt4':'gpt35',
  907. prompt: e,
  908. guide: that.info.guide
  909. // messages: [{
  910. // role: 'system',
  911. // content: that.info.guide
  912. // },
  913. // {
  914. // role: 'user',
  915. // content: e
  916. // }
  917. // ]
  918. };
  919. let headers = {};
  920. headers = {
  921. 'token': uni.getStorageSync("token") || "",
  922. 'platform': this.platform,
  923. 'Content-Type': 'application/json',
  924. }
  925. // if(that.appInfo.connect_lines == 2){
  926. // headers = {
  927. // 'Content-Type': 'application/json',
  928. // Authorization: 'Bearer' + ' ' + that.haddresssk
  929. // }
  930. // }
  931. that.thoroughfare = 2
  932. // console.log(that.chatgpturl);
  933. fetch(that.chatgpturl, {
  934. method: 'POST',
  935. body: JSON.stringify(param),
  936. headers: headers
  937. })
  938. .then(x => {
  939. if (x.status === 404) {
  940. this.showdirect = false;
  941. that.directGpt(e)
  942. return;
  943. }
  944. if (x.status === 200) return x.body;
  945. throw x;
  946. })
  947. .then(x => {
  948. const k = x.getReader();
  949. return new ReadableStream({
  950. start(V) {
  951. function F() {
  952. k.read().then(({
  953. done: E,
  954. value: U
  955. }) => {
  956. that.showanswer = true;
  957. if (E) {
  958. that.done = true;
  959. that.show_flash = false;
  960. // that.record(that.valuechat, message);
  961. return;
  962. }
  963. V.enqueue(U);
  964. const L = new TextDecoder().decode(U);
  965. const N = L;
  966. if (N != undefined) {
  967. message += N;
  968. }
  969. if (that.thoroughfare == 2) {
  970. if(N == '内容包含敏感信息,不予展示。'){
  971. // console.log('5');
  972. that.valuechat = '该问题已被隐藏!';
  973. that.answer = '内容包含敏感信息,不予展示。';
  974. that.done = true;
  975. that.show_flash = false;
  976. return;
  977. }
  978. that.backups = message;
  979. that.answer = marked(message);
  980. }
  981. // try {
  982. // const G = L.match(/data:\s/g),
  983. // j = L.split('data:').filter(w => !!w.trim() && w
  984. // .trim() !== '[DONE]');
  985. // var N = null;
  986. // N = j
  987. // .map(w => JSON.parse(w))
  988. // .map(w => (N = w.choices[0].delta.content))
  989. // .join('');
  990. // if (N != undefined) {
  991. // message += N;
  992. // }
  993. // if (that.thoroughfare == 2) {
  994. // that.answer = message;
  995. // }
  996. // let C = j
  997. // .map(w => JSON.parse(w))
  998. // .map(w => (N = w.choices[0].finish_reason))
  999. // .join('');
  1000. // if (C == 'stop') {
  1001. // that.done = true;
  1002. // that.show_flash = false;
  1003. // that.record(that.valuechat, message);
  1004. // return;
  1005. // }
  1006. // } catch (G) {
  1007. // }
  1008. F();
  1009. });
  1010. }
  1011. F();
  1012. }
  1013. });
  1014. })
  1015. .then(x =>
  1016. new Response(x, {
  1017. headers: {
  1018. 'Content-Type': 'text/html'
  1019. }
  1020. }).text()
  1021. );
  1022. },
  1023. showInterstitial() {
  1024. time2 = setInterval(
  1025. function() {
  1026. interstitialAd.show().catch(err => {
  1027. // console.error(err);
  1028. });
  1029. },
  1030. this.appInfo.gap ? this.appInfo.gap * 1000 : 12000
  1031. );
  1032. }
  1033. }
  1034. };
  1035. </script>
  1036. <style lang="scss">
  1037. .directask {
  1038. padding: 30rpx;
  1039. border-top: 1px solid #ededed;
  1040. .helpme {
  1041. color: #9e9e9e;
  1042. font-size: 26rpx;
  1043. .title {
  1044. font-size: 35rpx;
  1045. font-weight: bold;
  1046. margin-bottom: 18rpx;
  1047. color: #000;
  1048. }
  1049. }
  1050. .expand {
  1051. // padding: 20rpx;
  1052. margin: 30rpx 0;
  1053. // padding-bottom: env(safe-area-inset-bottom);
  1054. .surplus {
  1055. color: #fff;
  1056. font-size: 26rpx;
  1057. background: #03a9f4;
  1058. border-radius: 50rpx;
  1059. padding: 8rpx 12rpx;
  1060. margin-right: 20rpx;
  1061. margin-bottom: 15rpx;
  1062. .item {
  1063. margin-left: 10rpx;
  1064. }
  1065. // display: inline-block;
  1066. }
  1067. }
  1068. .textarea {
  1069. // box-shadow: 0px 0px 10px 5px #9e9e9e36;
  1070. margin-top: 30rpx;
  1071. margin-bottom: 30rpx;
  1072. border-radius: 20rpx;
  1073. // padding: 20rpx 30rpx 30rpx 12rpx;
  1074. .u-textarea {
  1075. border-radius: 20rpx;
  1076. padding: 24rpx;
  1077. }
  1078. .operate {
  1079. justify-content: flex-end;
  1080. margin-top: 30rpx;
  1081. .surpluss {
  1082. height: 66rpx;
  1083. line-height: 66rpx;
  1084. font-size: 28rpx;
  1085. padding: 0 42rpx;
  1086. border-radius: 10rpx;
  1087. // border: 1px solid #26B3A0;
  1088. background: linear-gradient(to right, #FFCA28, #FFA726);
  1089. color: #fff;
  1090. }
  1091. .empty {
  1092. margin-right: 30rpx;
  1093. border: 1px solid #9e9e9e;
  1094. color: #9e9e9e;
  1095. padding: 12rpx 42rpx;
  1096. border-radius: 10rpx;
  1097. }
  1098. .submit {
  1099. height: 66rpx;
  1100. line-height: 66rpx;
  1101. font-size: 28rpx;
  1102. padding: 0 42rpx;
  1103. border-radius: 10rpx;
  1104. // border: 1px solid #26B3A0;
  1105. background: linear-gradient(to right, #00ca88, #00BCD4);
  1106. color: #fff;
  1107. }
  1108. .hoversubmit {
  1109. background: #f7f7f7;
  1110. color: #acacb3;
  1111. }
  1112. }
  1113. }
  1114. .answer {
  1115. border-radius: 18rpx;
  1116. padding: 26rpx;
  1117. border-width: 0.5px !important;
  1118. border-color: #dadbde !important;
  1119. border-style: solid;
  1120. }
  1121. .duplicate {
  1122. width: 100%;
  1123. height: 80rpx;
  1124. line-height: 80rpx;
  1125. border-radius: 10rpx;
  1126. font-weight: bold;
  1127. color: #fff;
  1128. background: linear-gradient(to right, #00ca88, #00BCD4);
  1129. margin-top: 30rpx;
  1130. font-size: 30rpx;
  1131. }
  1132. }
  1133. .flash {
  1134. margin-left: 2px;
  1135. animation: flash 0.8s linear infinite;
  1136. }
  1137. // 实现光标闪烁
  1138. @keyframes flash {
  1139. from {
  1140. opacity: 0;
  1141. }
  1142. to {
  1143. opacity: 1;
  1144. }
  1145. }
  1146. .wxad {
  1147. border-radius: 20rpx;
  1148. overflow: hidden;
  1149. margin-bottom: 30rpx;
  1150. // margin: 30rpx;
  1151. }
  1152. </style>