detail.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849
  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="0" 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. <block v-if="appInfo.number_member">
  15. <navigator v-if="appInfo.number_member == 1" @click="getroute"
  16. :url="isLogin ?'/pages/user/member/member?id=1':'/pages/user/signin'"
  17. class="surplus u-flex align-center">
  18. <u-icon name="question-circle-fill" color="#f1f1f1" size="18" top="1"></u-icon>
  19. <view class="item">{{appInfo.number_alias?appInfo.number_alias+':':'点数:'}}{{ userData.coin ? userData.coin : 0 }}</view>
  20. </navigator>
  21. </block>
  22. <block v-else>
  23. <navigator @click="getroute" :url="isLogin ?'/pages/user/member/member?id=1':'/pages/user/signin'"
  24. class="surplus u-flex align-center">
  25. <u-icon name="question-circle-fill" color="#f1f1f1" size="18" top="1"></u-icon>
  26. <view class="item">{{appInfo.number_alias?appInfo.number_alias+':':'点数:'}}{{ userData.coin ? userData.coin : 0 }}</view>
  27. </navigator>
  28. </block>
  29. <navigator @click="getroute" :url="isLogin ?'/pages/user/member/member?id=2':'/pages/user/signin'"
  30. class="surplus u-flex align-center" v-if="appInfo.time_member && appInfo.time_member == 1">
  31. <u-icon name="clock-fill" color="#f1f1f1" size="18" top="1"></u-icon>
  32. <view class="item">会员时长:{{ userData.is_validity == 1 ? userData.countdown : 0 }}天</view>
  33. </navigator>
  34. <navigator @click="getroute" :url="isLogin ?'/pages/user/member/member?id=3':'/pages/user/signin'" class="surplus u-flex align-center">
  35. <u-icon name="more-circle-fill" color="#f1f1f1" size="18" top="1"></u-icon>
  36. <view class="item">免费领{{appInfo.number_alias?appInfo.number_alias:'点数'}}</view>
  37. </navigator>
  38. </view>
  39. <view class="textarea">
  40. <u--textarea v-model="valuechat" maxlength="-1" height="120" placeholder="请输入关键词或问题..."></u--textarea>
  41. <view class="operate u-flex align-center">
  42. <!-- <view class="surplus">剩余次数:{{userData.coin}}次</view> -->
  43. <!-- <view class="u-flex"> -->
  44. <view @click="getempty" class="empty">清空</view>
  45. <!-- <view class="u_button">
  46. <u-button type="primary" :plain="true" text="清空" color="#9E9E9E"></u-button>
  47. </view> -->
  48. <view class="submit" hover-class="hoversubmit" @click="init(valuechat)">立即提交</view>
  49. <!-- <view class="u_button">
  50. <u-button type="primary" text="立即提交" color="#26B3A0"></u-button>
  51. </view> -->
  52. <!-- </view> -->
  53. </view>
  54. </view>
  55. <view class="answer-container" v-if="answer">
  56. <view class="answer">
  57. <text>{{ answer }}</text>
  58. <text v-if="answer == '正在思考中...'">{{ second }}s</text>
  59. <text class="flash" v-if="show_flash">│</text>
  60. </view>
  61. <button hover-class="hoversubmit" class="duplicate u-flex justify-center" :disabled="!done"
  62. @click="copyText(answer)">一键复制</button>
  63. </view>
  64. <!-- #ifdef MP-WEIXIN -->
  65. <view class="wxad" v-if="appInfo.wxad_template_detail && appInfo.wxad_template_detail >= 1">
  66. <view style="100%">
  67. <wike-flow-main :flowtype="appInfo.wxad_template_detail" :banner_id="appInfo.banner_id"
  68. :video_banner_id="appInfo.video_banner_id" :native_id="appInfo.native_id"></wike-flow-main>
  69. </view>
  70. </view>
  71. <!-- #endif -->
  72. <view style="margin-top: 20rpx;"><wike-ad></wike-ad></view>
  73. </view>
  74. </view>
  75. </template>
  76. <script>
  77. import {
  78. mapMutations,
  79. mapActions,
  80. mapState,
  81. mapGetters
  82. } from 'vuex';
  83. let interstitialAd = null,
  84. timer,
  85. time2,
  86. down,
  87. delay;
  88. export default {
  89. data() {
  90. return {
  91. info: {},
  92. tobheight: 45,
  93. platform: this.$platform.get(),
  94. answer: '',
  95. valuechat: '',
  96. thevaluechat: '',
  97. down: 0,
  98. done: false,
  99. second: 15,
  100. showanswer: false,
  101. show_flash: false,
  102. selectornot: 0,
  103. haddressurl: '',
  104. haddresssk: '',
  105. eights: false,
  106. thecontent: '',
  107. //通道
  108. thoroughfare: 0,
  109. showdirect: true,
  110. };
  111. },
  112. computed: {
  113. ...mapGetters(['appInfo', 'userInfo', 'userData', 'isLogin', 'homeTemplate'])
  114. },
  115. onShow: function() {
  116. // if (!this.$ws.socketStatus()) {
  117. // this.$ws.init();
  118. // }
  119. if (this.isLogin) {
  120. this.getUserData();
  121. }
  122. },
  123. onLoad() {
  124. if (this.platform == 'wxMiniProgram') {
  125. var menumtop = uni.getMenuButtonBoundingClientRect().top - uni.getSystemInfoSync().statusBarHeight;
  126. var paddingtop = uni.getSystemInfoSync().statusBarHeight + menumtop;
  127. this.tobheight = menumtop + paddingtop + uni.getMenuButtonBoundingClientRect().height;
  128. }
  129. this.getInfo();
  130. this.onmessage();
  131. // this.init()
  132. this.aigetAddress();
  133. },
  134. onReady() {
  135. let that = this;
  136. // #ifdef MP-WEIXIN
  137. clearTimeout(timer);
  138. // 在适合的场景显示插屏广告
  139. timer = setTimeout(function() {
  140. // 在页面onLoad回调事件中创建插屏广告实例
  141. if (wx.createInterstitialAd && that.appInfo.interstitial_status == 1) {
  142. interstitialAd = wx.createInterstitialAd({
  143. adUnitId: that.appInfo.interstitial_id
  144. });
  145. interstitialAd.onLoad(() => {});
  146. interstitialAd.onError(err => {});
  147. interstitialAd.onClose(() => {
  148. if (that.appInfo.interstitial_infinite_status == 1) {
  149. that.showInterstitial();
  150. }
  151. });
  152. interstitialAd.show().catch(err => {
  153. // console.error(err);
  154. });
  155. }
  156. }, 4000);
  157. // #endif
  158. },
  159. onUnload() {
  160. if (this.$ws.socketStatus()) {
  161. this.$ws.completeClose();
  162. }
  163. clearInterval(time2);
  164. },
  165. onHide() {
  166. // console.log('onHide');
  167. if (this.$ws.socketStatus()) {
  168. this.$ws.completeClose();
  169. }
  170. },
  171. methods: {
  172. ...mapActions(['getUserInfo', 'showAuthModal', 'getUserData']),
  173. onmessage() {
  174. let that = this,
  175. message = '';
  176. uni.onSocketMessage(function(res) {
  177. // console.log(2);
  178. that.showanswer = true;
  179. let a = res.data;
  180. if (a.indexOf('wike_err:') != -1) {
  181. uni.showToast({
  182. title: '报错:' + a,
  183. icon: 'none'
  184. });
  185. that.answer = '报错:' + a;
  186. that.show_flash = false;
  187. return;
  188. }
  189. if (!that.$ws.socketStatus()) {
  190. uni.showToast({
  191. title: '连接错误,正在重新思考'
  192. });
  193. that.onSubmit(that.valuechat);
  194. return;
  195. }
  196. if (a.indexOf('[DONE]') != -1) {
  197. that.record(that.valuechat, message);
  198. message = '';
  199. that.done = true;
  200. that.show_flash = false;
  201. // that.$ws.completeClose()
  202. if (that.$ws.socketStatus()) {
  203. that.$ws.completeClose();
  204. }
  205. } else {
  206. var b = a.split('data:').filter(w => !!w.trim() && w.trim() !== '[DONE]');
  207. var c = '';
  208. b.map(w => JSON.parse(w))
  209. .map(w => (c = w.choices[0].delta.content))
  210. .join('');
  211. // console.log(c);
  212. if (c != undefined) {
  213. message += c;
  214. }
  215. if (that.thoroughfare == 1) {
  216. that.answer = message;
  217. }
  218. uni.hideLoading();
  219. }
  220. });
  221. },
  222. getroute() {
  223. if (!this.isLogin) {
  224. uni.setStorageSync('route', '/pages/template/detail');
  225. }
  226. },
  227. waitWss() {
  228. return new Promise((resolve, reject) => {
  229. uni.onSocketOpen(function(res) {
  230. // console.log('WebSocket连接已打开!');
  231. resolve(1);
  232. });
  233. });
  234. },
  235. waitClose() {
  236. return new Promise((resolve, reject) => {
  237. uni.onSocketClose(function(res) {
  238. // console.log('WebSocket 已关闭!');
  239. resolve(1);
  240. });
  241. });
  242. },
  243. record(question, answer) {
  244. let that = this;
  245. this.$http('question.add', {
  246. question,
  247. answer
  248. }).then(res => {
  249. if (res.code == 0) {
  250. that.getUserData();
  251. // console.log(that.question_index);
  252. } else {
  253. that.valuechat = '该问题已被隐藏!';
  254. that.answer = res.msg;
  255. that.done = true;
  256. that.show_flash = false;
  257. }
  258. });
  259. },
  260. aigetAddress() {
  261. var that = this;
  262. that.$http('ai.getAddress').then(res => {
  263. if (res.code == 0) {
  264. that.haddressurl = res.data.url;
  265. that.haddresssk = res.data.sk;
  266. // that.hAddress = res.data
  267. }
  268. });
  269. },
  270. getInfo() {
  271. this.$http('template.info', {
  272. id: this.$Route.query.id
  273. }).then(res => {
  274. if (res.code == 0) {
  275. // uni.setNavigationBarTitle({
  276. // title: res.data.title
  277. // });
  278. this.info = res.data;
  279. uni.setNavigationBarTitle({
  280. title: this.appInfo.site_name
  281. });
  282. }
  283. });
  284. },
  285. copyText(text) {
  286. uni.setClipboardData({
  287. data: text,
  288. success: function() {
  289. // console.log('success');
  290. uni.showToast({
  291. title: '复制成功'
  292. });
  293. }
  294. });
  295. },
  296. countdown() {
  297. var that = this;
  298. that.second--;
  299. if (that.second == 0) {
  300. // console.log('15秒定时结束');
  301. if (!that.showanswer) {
  302. uni.showLoading({
  303. title: '加载中...'
  304. });
  305. clearTimeout(down);
  306. // #ifdef MP-WEIXIN
  307. // console.log('关闭定时器');
  308. // if (that.$ws.socketStatus()) {
  309. // that.$ws.completeClose();
  310. // }
  311. // #endif
  312. // console.log('关闭直连');
  313. // setTimeout(() => {
  314. // uni.hideLoading();
  315. // that.second = 15;
  316. // that.directGpt(this.valuechat);
  317. // }, 1500);
  318. if (that.showdirect) {
  319. setTimeout(() => {
  320. uni.hideLoading();
  321. that.second = 15;
  322. that.directGpt(that.valuechat);
  323. }, 1500);
  324. } else {
  325. uni.hideLoading();
  326. that.second = 15;
  327. if (that.answer == '正在思考中...') {
  328. that.answer = '请等我几秒钟,正在输入回答...';
  329. }
  330. }
  331. return;
  332. } else {
  333. that.second = 15;
  334. clearTimeout(down);
  335. // console.log('关闭定时器');
  336. }
  337. // clearTimeout(down);
  338. return;
  339. }
  340. // #ifdef H5
  341. if (that.second == 8 && !that.eights) {
  342. // console.log('8秒定时结束');
  343. if (!that.showanswer) {
  344. // if (that.$ws.socketStatus()) {
  345. that.$ws.completeClose();
  346. // }
  347. // console.log('关闭直连');
  348. that.fetchmodel(that.thecontent);
  349. } else {
  350. that.second = 15;
  351. clearTimeout(down);
  352. // console.log('关闭定时器');
  353. }
  354. }
  355. // #endif
  356. down = setTimeout(() => {
  357. if (that.showanswer) {
  358. clearTimeout(down);
  359. // console.log('关闭定时器');
  360. that.second = 15;
  361. return;
  362. }
  363. that.countdown();
  364. }, 1000);
  365. // console.log(second);
  366. },
  367. getempty() {
  368. var that = this;
  369. if (that.answer && !that.done) {
  370. uni.showToast({
  371. title: '正在输入回答,请等待输入完成',
  372. icon: 'none'
  373. });
  374. return;
  375. }
  376. that.valuechat = '';
  377. that.answer = '';
  378. },
  379. getcheckText() {
  380. var that = this;
  381. return new Promise((resolve, reject) => {
  382. that.$http('ai.checkText', {
  383. prompt: that.thecontent
  384. }).then(res => {
  385. if (res.code == 0) {
  386. resolve(1);
  387. } else {
  388. that.valuechat = '该问题已被隐藏!';
  389. that.answer = res.msg;
  390. that.done = true;
  391. that.show_flash = false;
  392. }
  393. })
  394. });
  395. },
  396. async init(e) {
  397. let that = this;
  398. if (!that.isLogin) {
  399. uni.navigateTo({
  400. url: '/pages/user/signin'
  401. });
  402. uni.setStorageSync('route', '/pages/template/detail');
  403. return;
  404. }
  405. if (!e) {
  406. uni.showToast({
  407. title: '请输入关键词或问题',
  408. icon: 'none'
  409. });
  410. return;
  411. }
  412. this.thecontent = e;
  413. if (this.appInfo.time_member && this.appInfo.time_member == 1) {
  414. if (that.userData.is_validity == 0) {
  415. if (that.userData.coin <= 0) {
  416. var alias = that.appInfo.number_alias?that.appInfo.number_alias:'点数';
  417. uni.showModal({
  418. confirmText: '获取获取',
  419. confirmColor: '#26B3A0',
  420. content: '您的提问'+alias+'/会员时长不足',
  421. title: '提示',
  422. success(res) {
  423. if (res.confirm) {
  424. uni.navigateTo({
  425. url: '/pages/user/member/member'
  426. });
  427. }
  428. }
  429. });
  430. return;
  431. }
  432. }
  433. } else {
  434. if (that.userData.coin <= 0) {
  435. var alias = that.appInfo.number_alias?that.appInfo.number_alias:'点数';
  436. uni.showModal({
  437. confirmText: '立即获取',
  438. confirmColor: '#26B3A0',
  439. content: '您的提问'+alias+'/会员时长不足',
  440. title: '提示',
  441. success(res) {
  442. if (res.confirm) {
  443. uni.navigateTo({
  444. url: '/pages/user/member/member'
  445. });
  446. }
  447. }
  448. });
  449. return;
  450. }
  451. }
  452. if (!this.appInfo.sk && this.appInfo.connect_lines && this.appInfo.connect_lines == 2) {
  453. uni.showToast({
  454. title: '未正确配置key',
  455. icon: 'none'
  456. });
  457. return;
  458. }
  459. if (that.answer && !that.done) {
  460. uni.showToast({
  461. title: '正在输入回答,请等待输入完成',
  462. icon: 'none'
  463. });
  464. return;
  465. }
  466. uni.showLoading({})
  467. // #ifdef H5
  468. let check = this.appInfo.is_h5_filter && this.appInfo.is_h5_filter == 1 ? await this.getcheckText() :
  469. 1;
  470. // #endif
  471. // #ifdef MP-WEIXIN
  472. let check = await this.getcheckText();
  473. // #endif
  474. if (check == 1) {
  475. uni.hideLoading();
  476. // this.$ws.init();
  477. that.done = false;
  478. that.answer = '正在思考中...';
  479. that.show_flash = true;
  480. that.showanswer = false;
  481. // delay = setTimeout(() => {
  482. // that.countdown();
  483. // that.onSubmit(e)
  484. // clearTimeout(delay);
  485. // }, 1000);
  486. that.countdown();
  487. // #ifdef MP-WEIXIN
  488. if (!that.$ws.socketStatus()) {
  489. // console.log('重连');
  490. that.$ws.init();
  491. that.showdirect = true;
  492. let re = await that.waitWss();
  493. if (re == 1) {
  494. // console.log('等待wss打开后执行');
  495. that.onSubmit(e);
  496. }
  497. } else {
  498. // let wai = await that.waitClose();
  499. // if (wai == 1) {
  500. // console.log('先关闭再重连');
  501. // that.$ws.init();
  502. // }
  503. // console.log('wss未完全关闭,走直连模式并再次关闭wss');
  504. that.$ws.completeClose();
  505. // #ifdef H5
  506. // 不再8秒走fetch模式
  507. // that.eights = true
  508. // console.log('走方案2');
  509. // that.fetchmodel(that.thecontent);
  510. // #endif
  511. // #ifdef MP-WEIXIN
  512. that.showdirect = false;
  513. that.directGpt(this.thecontent);
  514. // #endif
  515. }
  516. // #endif
  517. // #ifdef H5
  518. // 不再8秒走fetch模式
  519. that.eights = true
  520. // console.log('走方案2');
  521. that.fetchmodel(that.thecontent);
  522. // #endif
  523. }
  524. },
  525. async onSubmit(e) {
  526. let that = this;
  527. that.eights = false;
  528. that.thoroughfare = 1
  529. var ty = {
  530. prompt: e,
  531. guide: that.info.guide,
  532. key: that.appInfo.sk ? that.appInfo.sk : '',
  533. lines: that.appInfo.connect_lines ? this.appInfo.connect_lines : 1
  534. };
  535. var json = JSON.stringify(ty);
  536. that.$ws.send(json);
  537. },
  538. directGpt(e) {
  539. let that = this;
  540. // console.log('s');
  541. if (that.showdirect) {
  542. that.answer = '请等我几秒钟,正在输入回答...';
  543. }
  544. that.showanswer = that.showdirect;
  545. that.thoroughfare = 3
  546. that.$http('ai.chat', {
  547. prompt: e,
  548. guide: that.info.guide,
  549. answer: ''
  550. }).then(res => {
  551. if (res.code == 0) {
  552. if (that.thoroughfare == 3) {
  553. that.answer = res.data.trim();
  554. that.show_flash = false;
  555. that.done = true;
  556. that.second = 15;
  557. that.getUserData();
  558. } else if (res.code == 3) {
  559. that.answer = res.msg;
  560. that.show_flash = false;
  561. that.second = 15;
  562. that.done = true;
  563. // that.showanswer = true
  564. } else {
  565. that.answer = res.msg;
  566. that.valuechat = '该问题已被隐藏!';
  567. that.show_flash = false;
  568. that.second = 15;
  569. that.done = true;
  570. // that.showanswer = true
  571. }
  572. }
  573. });
  574. },
  575. fetchmodel(e) {
  576. // console.log('走方案2');
  577. // console.log(e);
  578. var that = this;
  579. let i = 1,
  580. message = '';
  581. // that.question_index = that.talkList.length - 1;
  582. // that.answer_index = that.talkList.length - 2;
  583. let param = {
  584. max_tokens: 3000,
  585. model: 'gpt-3.5-turbo-0301',
  586. stream: true,
  587. messages: [{
  588. role: 'system',
  589. content: that.info.guide
  590. },
  591. {
  592. role: 'user',
  593. content: e
  594. }
  595. ]
  596. };
  597. let headers = {};
  598. if(that.appInfo.connect_lines == 2){
  599. headers = {
  600. 'Content-Type': 'application/json',
  601. Authorization: 'Bearer' + ' ' + that.haddresssk
  602. }
  603. }
  604. that.thoroughfare = 2
  605. fetch(that.haddressurl, {
  606. method: 'POST',
  607. body: JSON.stringify(param),
  608. headers: headers
  609. })
  610. .then(x => {
  611. if (x.status === 200) return x.body;
  612. throw x;
  613. })
  614. .then(x => {
  615. const k = x.getReader();
  616. return new ReadableStream({
  617. start(V) {
  618. function F() {
  619. k.read().then(({
  620. done: E,
  621. value: U
  622. }) => {
  623. // console.log(E);
  624. that.showanswer = true;
  625. // uni.hideLoading();
  626. if (E) {
  627. // console.log('done', E), V.close();
  628. that.done = true;
  629. that.show_flash = false;
  630. that.record(that.valuechat, message);
  631. return;
  632. }
  633. V.enqueue(U);
  634. const L = new TextDecoder().decode(U);
  635. try {
  636. const G = L.match(/data:\s/g),
  637. j = L.split('data:').filter(w => !!w.trim() && w
  638. .trim() !== '[DONE]');
  639. var N = null;
  640. N = j
  641. .map(w => JSON.parse(w))
  642. .map(w => (N = w.choices[0].delta.content))
  643. .join('');
  644. // console.log(N);
  645. if (N != undefined) {
  646. message += N;
  647. }
  648. if (that.thoroughfare == 2) {
  649. that.answer = message;
  650. }
  651. let C = j
  652. .map(w => JSON.parse(w))
  653. .map(w => (N = w.choices[0].finish_reason))
  654. .join('');
  655. if (C == 'stop') {
  656. that.done = true;
  657. that.show_flash = false;
  658. that.record(that.valuechat, message);
  659. return;
  660. }
  661. } catch (G) {
  662. // console.error(G);
  663. }
  664. F();
  665. });
  666. }
  667. F();
  668. }
  669. });
  670. })
  671. .then(x =>
  672. new Response(x, {
  673. headers: {
  674. 'Content-Type': 'text/html'
  675. }
  676. }).text()
  677. );
  678. },
  679. showInterstitial() {
  680. time2 = setInterval(
  681. function() {
  682. interstitialAd.show().catch(err => {
  683. // console.error(err);
  684. });
  685. },
  686. this.appInfo.gap ? this.appInfo.gap * 1000 : 12000
  687. );
  688. }
  689. }
  690. };
  691. </script>
  692. <style lang="scss">
  693. .directask {
  694. padding: 30rpx;
  695. border-top: 1px solid #ededed;
  696. .helpme {
  697. color: #9e9e9e;
  698. font-size: 26rpx;
  699. .title {
  700. font-size: 35rpx;
  701. font-weight: bold;
  702. margin-bottom: 18rpx;
  703. color: #000;
  704. }
  705. }
  706. .expand {
  707. // padding: 20rpx;
  708. margin: 30rpx 0;
  709. // padding-bottom: env(safe-area-inset-bottom);
  710. .surplus {
  711. color: #fff;
  712. font-size: 26rpx;
  713. background: #03a9f4;
  714. border-radius: 50rpx;
  715. padding: 8rpx 12rpx;
  716. margin-right: 20rpx;
  717. margin-bottom: 15rpx;
  718. .item {
  719. margin-left: 10rpx;
  720. }
  721. // display: inline-block;
  722. }
  723. }
  724. .textarea {
  725. // box-shadow: 0px 0px 10px 5px #9e9e9e36;
  726. margin-top: 30rpx;
  727. margin-bottom: 30rpx;
  728. border-radius: 20rpx;
  729. // padding: 20rpx 30rpx 30rpx 12rpx;
  730. .u-textarea {
  731. border-radius: 20rpx;
  732. padding: 24rpx;
  733. }
  734. .operate {
  735. justify-content: flex-end;
  736. margin-top: 30rpx;
  737. .surplus {
  738. height: 66rpx;
  739. line-height: 66rpx;
  740. font-size: 28rpx;
  741. padding: 0 20rpx;
  742. border-radius: 10rpx;
  743. // border: 1px solid #26B3A0;
  744. background-color: #ff9800;
  745. color: #fff;
  746. max-width: 286rpx;
  747. }
  748. .empty {
  749. margin-right: 30rpx;
  750. border: 1px solid #9e9e9e;
  751. color: #9e9e9e;
  752. padding: 12rpx 42rpx;
  753. border-radius: 10rpx;
  754. }
  755. .submit {
  756. height: 66rpx;
  757. line-height: 66rpx;
  758. font-size: 28rpx;
  759. padding: 0 42rpx;
  760. border-radius: 10rpx;
  761. // border: 1px solid #26B3A0;
  762. background-color: #26b3a0;
  763. color: #fff;
  764. }
  765. .hoversubmit {
  766. background: #f7f7f7;
  767. color: #acacb3;
  768. }
  769. }
  770. }
  771. .answer {
  772. border-radius: 18rpx;
  773. padding: 18rpx;
  774. border-width: 0.5px !important;
  775. border-color: #dadbde !important;
  776. border-style: solid;
  777. }
  778. .duplicate {
  779. width: 100%;
  780. height: 80rpx;
  781. line-height: 80rpx;
  782. border-radius: 10rpx;
  783. font-weight: bold;
  784. color: #fff;
  785. background: #26b3a0;
  786. margin-top: 30rpx;
  787. font-size: 30rpx;
  788. }
  789. }
  790. .flash {
  791. margin-left: 2px;
  792. animation: flash 0.8s linear infinite;
  793. }
  794. // 实现光标闪烁
  795. @keyframes flash {
  796. from {
  797. opacity: 0;
  798. }
  799. to {
  800. opacity: 1;
  801. }
  802. }
  803. .wxad {
  804. border-radius: 20rpx;
  805. overflow: hidden;
  806. margin-bottom: 30rpx;
  807. // margin: 30rpx;
  808. }
  809. </style>