123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849 |
- <template>
- <view>
- <view style="color: #000;">
- <tn-nav-bar backgroundColor="#F5FFFD" :bottomShadow="false">提问模板</tn-nav-bar>
- <view :style="{ height: tobheight + 'px' }"></view>
- </view>
- <wike-skeleton :count="0" v-if="!info.title"></wike-skeleton>
- <view class="directask">
- <view class="helpme">
- <view class="title">{{ info.title }}</view>
- {{ info.sub_title }}
- </view>
- <view class="expand u-flex flex-wrap">
- <block v-if="appInfo.number_member">
- <navigator v-if="appInfo.number_member == 1" @click="getroute"
- :url="isLogin ?'/pages/user/member/member?id=1':'/pages/user/signin'"
- class="surplus u-flex align-center">
- <u-icon name="question-circle-fill" color="#f1f1f1" size="18" top="1"></u-icon>
- <view class="item">{{appInfo.number_alias?appInfo.number_alias+':':'点数:'}}{{ userData.coin ? userData.coin : 0 }}</view>
- </navigator>
- </block>
- <block v-else>
- <navigator @click="getroute" :url="isLogin ?'/pages/user/member/member?id=1':'/pages/user/signin'"
- class="surplus u-flex align-center">
- <u-icon name="question-circle-fill" color="#f1f1f1" size="18" top="1"></u-icon>
- <view class="item">{{appInfo.number_alias?appInfo.number_alias+':':'点数:'}}{{ userData.coin ? userData.coin : 0 }}</view>
- </navigator>
- </block>
- <navigator @click="getroute" :url="isLogin ?'/pages/user/member/member?id=2':'/pages/user/signin'"
- class="surplus u-flex align-center" v-if="appInfo.time_member && appInfo.time_member == 1">
- <u-icon name="clock-fill" color="#f1f1f1" size="18" top="1"></u-icon>
- <view class="item">会员时长:{{ userData.is_validity == 1 ? userData.countdown : 0 }}天</view>
- </navigator>
- <navigator @click="getroute" :url="isLogin ?'/pages/user/member/member?id=3':'/pages/user/signin'" class="surplus u-flex align-center">
- <u-icon name="more-circle-fill" color="#f1f1f1" size="18" top="1"></u-icon>
- <view class="item">免费领{{appInfo.number_alias?appInfo.number_alias:'点数'}}</view>
- </navigator>
- </view>
- <view class="textarea">
- <u--textarea v-model="valuechat" maxlength="-1" height="120" placeholder="请输入关键词或问题..."></u--textarea>
- <view class="operate u-flex align-center">
- <!-- <view class="surplus">剩余次数:{{userData.coin}}次</view> -->
- <!-- <view class="u-flex"> -->
- <view @click="getempty" class="empty">清空</view>
- <!-- <view class="u_button">
- <u-button type="primary" :plain="true" text="清空" color="#9E9E9E"></u-button>
- </view> -->
- <view class="submit" hover-class="hoversubmit" @click="init(valuechat)">立即提交</view>
- <!-- <view class="u_button">
- <u-button type="primary" text="立即提交" color="#26B3A0"></u-button>
- </view> -->
- <!-- </view> -->
- </view>
- </view>
- <view class="answer-container" v-if="answer">
- <view class="answer">
- <text>{{ answer }}</text>
- <text v-if="answer == '正在思考中...'">{{ second }}s</text>
- <text class="flash" v-if="show_flash">│</text>
- </view>
- <button hover-class="hoversubmit" class="duplicate u-flex justify-center" :disabled="!done"
- @click="copyText(answer)">一键复制</button>
- </view>
- <!-- #ifdef MP-WEIXIN -->
- <view class="wxad" v-if="appInfo.wxad_template_detail && appInfo.wxad_template_detail >= 1">
- <view style="100%">
- <wike-flow-main :flowtype="appInfo.wxad_template_detail" :banner_id="appInfo.banner_id"
- :video_banner_id="appInfo.video_banner_id" :native_id="appInfo.native_id"></wike-flow-main>
- </view>
- </view>
- <!-- #endif -->
- <view style="margin-top: 20rpx;"><wike-ad></wike-ad></view>
- </view>
- </view>
- </template>
- <script>
- import {
- mapMutations,
- mapActions,
- mapState,
- mapGetters
- } from 'vuex';
- let interstitialAd = null,
- timer,
- time2,
- down,
- delay;
- export default {
- data() {
- return {
- info: {},
- tobheight: 45,
- platform: this.$platform.get(),
- answer: '',
- valuechat: '',
- thevaluechat: '',
- down: 0,
- done: false,
- second: 15,
- showanswer: false,
- show_flash: false,
- selectornot: 0,
- haddressurl: '',
- haddresssk: '',
- eights: false,
- thecontent: '',
- //通道
- thoroughfare: 0,
- showdirect: true,
- };
- },
- computed: {
- ...mapGetters(['appInfo', 'userInfo', 'userData', 'isLogin', 'homeTemplate'])
- },
- onShow: function() {
- // if (!this.$ws.socketStatus()) {
- // this.$ws.init();
- // }
- if (this.isLogin) {
- this.getUserData();
- }
- },
- onLoad() {
- if (this.platform == 'wxMiniProgram') {
- var menumtop = uni.getMenuButtonBoundingClientRect().top - uni.getSystemInfoSync().statusBarHeight;
- var paddingtop = uni.getSystemInfoSync().statusBarHeight + menumtop;
- this.tobheight = menumtop + paddingtop + uni.getMenuButtonBoundingClientRect().height;
- }
- this.getInfo();
- this.onmessage();
- // this.init()
- this.aigetAddress();
- },
- onReady() {
- let that = this;
- // #ifdef MP-WEIXIN
- clearTimeout(timer);
- // 在适合的场景显示插屏广告
- timer = setTimeout(function() {
- // 在页面onLoad回调事件中创建插屏广告实例
- if (wx.createInterstitialAd && that.appInfo.interstitial_status == 1) {
- interstitialAd = wx.createInterstitialAd({
- adUnitId: that.appInfo.interstitial_id
- });
- interstitialAd.onLoad(() => {});
- interstitialAd.onError(err => {});
- interstitialAd.onClose(() => {
- if (that.appInfo.interstitial_infinite_status == 1) {
- that.showInterstitial();
- }
- });
- interstitialAd.show().catch(err => {
- // console.error(err);
- });
- }
- }, 4000);
- // #endif
- },
- onUnload() {
- if (this.$ws.socketStatus()) {
- this.$ws.completeClose();
- }
- clearInterval(time2);
- },
- onHide() {
- // console.log('onHide');
- if (this.$ws.socketStatus()) {
- this.$ws.completeClose();
- }
- },
- methods: {
- ...mapActions(['getUserInfo', 'showAuthModal', 'getUserData']),
- onmessage() {
- let that = this,
- message = '';
- uni.onSocketMessage(function(res) {
- // console.log(2);
- that.showanswer = true;
- let a = res.data;
- if (a.indexOf('wike_err:') != -1) {
- uni.showToast({
- title: '报错:' + a,
- icon: 'none'
- });
- that.answer = '报错:' + a;
- that.show_flash = false;
- return;
- }
- if (!that.$ws.socketStatus()) {
- uni.showToast({
- title: '连接错误,正在重新思考'
- });
- that.onSubmit(that.valuechat);
- return;
- }
- if (a.indexOf('[DONE]') != -1) {
- that.record(that.valuechat, message);
- message = '';
- that.done = true;
- that.show_flash = false;
- // that.$ws.completeClose()
- if (that.$ws.socketStatus()) {
- that.$ws.completeClose();
- }
- } else {
- var b = a.split('data:').filter(w => !!w.trim() && w.trim() !== '[DONE]');
- var c = '';
- b.map(w => JSON.parse(w))
- .map(w => (c = w.choices[0].delta.content))
- .join('');
- // console.log(c);
- if (c != undefined) {
- message += c;
- }
- if (that.thoroughfare == 1) {
- that.answer = message;
- }
- uni.hideLoading();
- }
- });
- },
- getroute() {
- if (!this.isLogin) {
- uni.setStorageSync('route', '/pages/template/detail');
- }
- },
- waitWss() {
- return new Promise((resolve, reject) => {
- uni.onSocketOpen(function(res) {
- // console.log('WebSocket连接已打开!');
- resolve(1);
- });
- });
- },
- waitClose() {
- return new Promise((resolve, reject) => {
- uni.onSocketClose(function(res) {
- // console.log('WebSocket 已关闭!');
- resolve(1);
- });
- });
- },
- record(question, answer) {
- let that = this;
- this.$http('question.add', {
- question,
- answer
- }).then(res => {
- if (res.code == 0) {
- that.getUserData();
- // console.log(that.question_index);
- } else {
- that.valuechat = '该问题已被隐藏!';
- that.answer = res.msg;
- that.done = true;
- that.show_flash = false;
- }
- });
- },
- aigetAddress() {
- var that = this;
- that.$http('ai.getAddress').then(res => {
- if (res.code == 0) {
- that.haddressurl = res.data.url;
- that.haddresssk = res.data.sk;
- // that.hAddress = res.data
- }
- });
- },
- getInfo() {
- this.$http('template.info', {
- id: this.$Route.query.id
- }).then(res => {
- if (res.code == 0) {
- // uni.setNavigationBarTitle({
- // title: res.data.title
- // });
- this.info = res.data;
- uni.setNavigationBarTitle({
- title: this.appInfo.site_name
- });
- }
- });
- },
- copyText(text) {
- uni.setClipboardData({
- data: text,
- success: function() {
- // console.log('success');
- uni.showToast({
- title: '复制成功'
- });
- }
- });
- },
- countdown() {
- var that = this;
- that.second--;
- if (that.second == 0) {
- // console.log('15秒定时结束');
- if (!that.showanswer) {
- uni.showLoading({
- title: '加载中...'
- });
- clearTimeout(down);
- // #ifdef MP-WEIXIN
- // console.log('关闭定时器');
- // if (that.$ws.socketStatus()) {
- // that.$ws.completeClose();
- // }
- // #endif
- // console.log('关闭直连');
- // setTimeout(() => {
- // uni.hideLoading();
- // that.second = 15;
- // that.directGpt(this.valuechat);
- // }, 1500);
- if (that.showdirect) {
- setTimeout(() => {
- uni.hideLoading();
- that.second = 15;
- that.directGpt(that.valuechat);
- }, 1500);
- } else {
- uni.hideLoading();
- that.second = 15;
- if (that.answer == '正在思考中...') {
- that.answer = '请等我几秒钟,正在输入回答...';
- }
- }
- return;
- } else {
- that.second = 15;
- clearTimeout(down);
- // console.log('关闭定时器');
- }
- // clearTimeout(down);
- return;
- }
- // #ifdef H5
- if (that.second == 8 && !that.eights) {
- // console.log('8秒定时结束');
- if (!that.showanswer) {
- // if (that.$ws.socketStatus()) {
- that.$ws.completeClose();
- // }
- // console.log('关闭直连');
- that.fetchmodel(that.thecontent);
- } else {
- that.second = 15;
- clearTimeout(down);
- // console.log('关闭定时器');
- }
- }
- // #endif
- down = setTimeout(() => {
- if (that.showanswer) {
- clearTimeout(down);
- // console.log('关闭定时器');
- that.second = 15;
- return;
- }
- that.countdown();
- }, 1000);
- // console.log(second);
- },
-
- getempty() {
- var that = this;
- if (that.answer && !that.done) {
- uni.showToast({
- title: '正在输入回答,请等待输入完成',
- icon: 'none'
- });
- return;
- }
- that.valuechat = '';
- that.answer = '';
- },
- getcheckText() {
- var that = this;
- return new Promise((resolve, reject) => {
- that.$http('ai.checkText', {
- prompt: that.thecontent
- }).then(res => {
- if (res.code == 0) {
- resolve(1);
- } else {
- that.valuechat = '该问题已被隐藏!';
- that.answer = res.msg;
- that.done = true;
- that.show_flash = false;
- }
- })
- });
- },
- async init(e) {
- let that = this;
- if (!that.isLogin) {
- uni.navigateTo({
- url: '/pages/user/signin'
- });
- uni.setStorageSync('route', '/pages/template/detail');
- return;
- }
- if (!e) {
- uni.showToast({
- title: '请输入关键词或问题',
- icon: 'none'
- });
- return;
- }
- this.thecontent = e;
- if (this.appInfo.time_member && this.appInfo.time_member == 1) {
- if (that.userData.is_validity == 0) {
- if (that.userData.coin <= 0) {
- var alias = that.appInfo.number_alias?that.appInfo.number_alias:'点数';
- uni.showModal({
- confirmText: '获取获取',
- confirmColor: '#26B3A0',
- content: '您的提问'+alias+'/会员时长不足',
- title: '提示',
- success(res) {
- if (res.confirm) {
- uni.navigateTo({
- url: '/pages/user/member/member'
- });
- }
- }
- });
- return;
- }
- }
- } else {
- if (that.userData.coin <= 0) {
- var alias = that.appInfo.number_alias?that.appInfo.number_alias:'点数';
- uni.showModal({
- confirmText: '立即获取',
- confirmColor: '#26B3A0',
- content: '您的提问'+alias+'/会员时长不足',
- title: '提示',
- success(res) {
- if (res.confirm) {
- uni.navigateTo({
- url: '/pages/user/member/member'
- });
- }
- }
- });
- return;
- }
- }
- if (!this.appInfo.sk && this.appInfo.connect_lines && this.appInfo.connect_lines == 2) {
- uni.showToast({
- title: '未正确配置key',
- icon: 'none'
- });
- return;
- }
- if (that.answer && !that.done) {
- uni.showToast({
- title: '正在输入回答,请等待输入完成',
- icon: 'none'
- });
- return;
- }
- uni.showLoading({})
- // #ifdef H5
- let check = this.appInfo.is_h5_filter && this.appInfo.is_h5_filter == 1 ? await this.getcheckText() :
- 1;
- // #endif
- // #ifdef MP-WEIXIN
- let check = await this.getcheckText();
- // #endif
- if (check == 1) {
- uni.hideLoading();
- // this.$ws.init();
- that.done = false;
- that.answer = '正在思考中...';
- that.show_flash = true;
- that.showanswer = false;
- // delay = setTimeout(() => {
- // that.countdown();
- // that.onSubmit(e)
- // clearTimeout(delay);
- // }, 1000);
- that.countdown();
- // #ifdef MP-WEIXIN
- if (!that.$ws.socketStatus()) {
- // console.log('重连');
- that.$ws.init();
- that.showdirect = true;
- let re = await that.waitWss();
- if (re == 1) {
- // console.log('等待wss打开后执行');
- that.onSubmit(e);
- }
- } else {
- // let wai = await that.waitClose();
- // if (wai == 1) {
- // console.log('先关闭再重连');
- // that.$ws.init();
- // }
- // console.log('wss未完全关闭,走直连模式并再次关闭wss');
- that.$ws.completeClose();
- // #ifdef H5
- // 不再8秒走fetch模式
- // that.eights = true
- // console.log('走方案2');
- // that.fetchmodel(that.thecontent);
- // #endif
- // #ifdef MP-WEIXIN
- that.showdirect = false;
- that.directGpt(this.thecontent);
- // #endif
- }
- // #endif
- // #ifdef H5
- // 不再8秒走fetch模式
- that.eights = true
- // console.log('走方案2');
- that.fetchmodel(that.thecontent);
- // #endif
- }
- },
- async onSubmit(e) {
- let that = this;
- that.eights = false;
- that.thoroughfare = 1
- var ty = {
- prompt: e,
- guide: that.info.guide,
- key: that.appInfo.sk ? that.appInfo.sk : '',
- lines: that.appInfo.connect_lines ? this.appInfo.connect_lines : 1
- };
- var json = JSON.stringify(ty);
- that.$ws.send(json);
- },
- directGpt(e) {
- let that = this;
- // console.log('s');
- if (that.showdirect) {
- that.answer = '请等我几秒钟,正在输入回答...';
- }
- that.showanswer = that.showdirect;
- that.thoroughfare = 3
- that.$http('ai.chat', {
- prompt: e,
- guide: that.info.guide,
- answer: ''
- }).then(res => {
- if (res.code == 0) {
- if (that.thoroughfare == 3) {
- that.answer = res.data.trim();
- that.show_flash = false;
- that.done = true;
- that.second = 15;
- that.getUserData();
- } else if (res.code == 3) {
- that.answer = res.msg;
- that.show_flash = false;
- that.second = 15;
- that.done = true;
- // that.showanswer = true
- } else {
- that.answer = res.msg;
- that.valuechat = '该问题已被隐藏!';
- that.show_flash = false;
- that.second = 15;
- that.done = true;
- // that.showanswer = true
- }
- }
- });
- },
- fetchmodel(e) {
- // console.log('走方案2');
- // console.log(e);
- var that = this;
- let i = 1,
- message = '';
- // that.question_index = that.talkList.length - 1;
- // that.answer_index = that.talkList.length - 2;
- let param = {
- max_tokens: 3000,
- model: 'gpt-3.5-turbo-0301',
- stream: true,
- messages: [{
- role: 'system',
- content: that.info.guide
- },
- {
- role: 'user',
- content: e
- }
- ]
- };
- let headers = {};
- if(that.appInfo.connect_lines == 2){
- headers = {
- 'Content-Type': 'application/json',
- Authorization: 'Bearer' + ' ' + that.haddresssk
- }
- }
- that.thoroughfare = 2
- fetch(that.haddressurl, {
- method: 'POST',
- body: JSON.stringify(param),
- headers: headers
- })
- .then(x => {
- if (x.status === 200) return x.body;
- throw x;
- })
- .then(x => {
- const k = x.getReader();
- return new ReadableStream({
- start(V) {
- function F() {
- k.read().then(({
- done: E,
- value: U
- }) => {
- // console.log(E);
- that.showanswer = true;
- // uni.hideLoading();
- if (E) {
- // console.log('done', E), V.close();
- that.done = true;
- that.show_flash = false;
- that.record(that.valuechat, message);
- return;
- }
- V.enqueue(U);
- const L = new TextDecoder().decode(U);
- try {
- const G = L.match(/data:\s/g),
- j = L.split('data:').filter(w => !!w.trim() && w
- .trim() !== '[DONE]');
- var N = null;
- N = j
- .map(w => JSON.parse(w))
- .map(w => (N = w.choices[0].delta.content))
- .join('');
- // console.log(N);
- if (N != undefined) {
- message += N;
- }
- if (that.thoroughfare == 2) {
- that.answer = message;
- }
- let C = j
- .map(w => JSON.parse(w))
- .map(w => (N = w.choices[0].finish_reason))
- .join('');
- if (C == 'stop') {
- that.done = true;
- that.show_flash = false;
- that.record(that.valuechat, message);
- return;
- }
- } catch (G) {
- // console.error(G);
- }
- F();
- });
- }
- F();
- }
- });
- })
- .then(x =>
- new Response(x, {
- headers: {
- 'Content-Type': 'text/html'
- }
- }).text()
- );
- },
- showInterstitial() {
- time2 = setInterval(
- function() {
- interstitialAd.show().catch(err => {
- // console.error(err);
- });
- },
- this.appInfo.gap ? this.appInfo.gap * 1000 : 12000
- );
- }
- }
- };
- </script>
- <style lang="scss">
- .directask {
- padding: 30rpx;
- border-top: 1px solid #ededed;
- .helpme {
- color: #9e9e9e;
- font-size: 26rpx;
- .title {
- font-size: 35rpx;
- font-weight: bold;
- margin-bottom: 18rpx;
- color: #000;
- }
- }
- .expand {
- // padding: 20rpx;
- margin: 30rpx 0;
- // padding-bottom: env(safe-area-inset-bottom);
- .surplus {
- color: #fff;
- font-size: 26rpx;
- background: #03a9f4;
- border-radius: 50rpx;
- padding: 8rpx 12rpx;
- margin-right: 20rpx;
- margin-bottom: 15rpx;
- .item {
- margin-left: 10rpx;
- }
- // display: inline-block;
- }
- }
- .textarea {
- // box-shadow: 0px 0px 10px 5px #9e9e9e36;
- margin-top: 30rpx;
- margin-bottom: 30rpx;
- border-radius: 20rpx;
- // padding: 20rpx 30rpx 30rpx 12rpx;
- .u-textarea {
- border-radius: 20rpx;
- padding: 24rpx;
- }
- .operate {
- justify-content: flex-end;
- margin-top: 30rpx;
- .surplus {
- height: 66rpx;
- line-height: 66rpx;
- font-size: 28rpx;
- padding: 0 20rpx;
- border-radius: 10rpx;
- // border: 1px solid #26B3A0;
- background-color: #ff9800;
- color: #fff;
- max-width: 286rpx;
- }
- .empty {
- margin-right: 30rpx;
- border: 1px solid #9e9e9e;
- color: #9e9e9e;
- padding: 12rpx 42rpx;
- border-radius: 10rpx;
- }
- .submit {
- height: 66rpx;
- line-height: 66rpx;
- font-size: 28rpx;
- padding: 0 42rpx;
- border-radius: 10rpx;
- // border: 1px solid #26B3A0;
- background-color: #26b3a0;
- color: #fff;
- }
- .hoversubmit {
- background: #f7f7f7;
- color: #acacb3;
- }
- }
- }
- .answer {
- border-radius: 18rpx;
- padding: 18rpx;
- border-width: 0.5px !important;
- border-color: #dadbde !important;
- border-style: solid;
- }
- .duplicate {
- width: 100%;
- height: 80rpx;
- line-height: 80rpx;
- border-radius: 10rpx;
- font-weight: bold;
- color: #fff;
- background: #26b3a0;
- margin-top: 30rpx;
- font-size: 30rpx;
- }
- }
- .flash {
- margin-left: 2px;
- animation: flash 0.8s linear infinite;
- }
- // 实现光标闪烁
- @keyframes flash {
- from {
- opacity: 0;
- }
- to {
- opacity: 1;
- }
- }
- .wxad {
- border-radius: 20rpx;
- overflow: hidden;
- margin-bottom: 30rpx;
- // margin: 30rpx;
- }
- </style>
|