@@ -4,7 +4,8 @@ | |||
"pages/logs/logs", | |||
"pages/payOrder/payOrder", | |||
"pages/payHistory/payHistory", | |||
"pages/chat/chat" | |||
"pages/chat/chat", | |||
"pages/orderDetail/orderDetail" | |||
], | |||
"window": { | |||
"backgroundTextStyle": "light", | |||
@@ -1,4 +1,4 @@ | |||
// pages/chat/chat.ts | |||
import { scrollToID } from '../../utils/util' | |||
Page({ | |||
/** | |||
@@ -9,7 +9,7 @@ Page({ | |||
message: "", | |||
waitingMessage: "", | |||
isResponing: false, | |||
reLoadSocket: false, | |||
chatOver: false, | |||
messageFlag: true | |||
}, | |||
@@ -113,7 +113,7 @@ Page({ | |||
success: function (res) { | |||
console.log(res) | |||
if (!that.data.reLoadSocket) { | |||
that.sayHello('Hello,我是GPT-Agent,你可以和我聊天,😘😘😘(出现这条消息,则WebSocket连接已成功)') | |||
that.sayHello('Hello,我是小闲聊,你可以和我聊天,😘😘😘') | |||
} | |||
if (that.data.waitingMessage) { | |||
@@ -35,7 +35,7 @@ page { | |||
position: absolute; | |||
top: 0; | |||
left: -25rpx; | |||
height: 100rpx; | |||
height: 80rpx; | |||
border-radius: 50% 50%; | |||
&.isResponing { | |||
@@ -50,7 +50,7 @@ page { | |||
text-align: left; | |||
&.left { | |||
left: 100rpx; | |||
left: 80rpx; | |||
color: #000000; | |||
background-color: #ffffff; | |||
padding: 20rpx; | |||
@@ -58,7 +58,7 @@ page { | |||
} | |||
&.right { | |||
right: 100rpx; | |||
right: 80rpx; | |||
color: #ffffff; | |||
background-color: #07c160; | |||
padding: 20rpx; | |||
@@ -70,11 +70,21 @@ page { | |||
position: absolute; | |||
top: 0; | |||
right: -25rpx; | |||
height: 100rpx; | |||
height: 80rpx; | |||
border-radius: 50% 50%; | |||
} | |||
} | |||
} | |||
.over { | |||
width: 170rpx; | |||
font-size: 23rpx; | |||
border-radius: 12rpx; | |||
background-color: #0000001c; | |||
padding: 10rpx 0; | |||
text-align: center; | |||
margin: 0 auto; | |||
} | |||
} | |||
.chatBox { | |||
@@ -86,21 +96,25 @@ page { | |||
padding-top: 20rpx; | |||
background-color: #f5f5f5; | |||
.inputBox { | |||
display: inline-block; | |||
width: 500rpx; | |||
height: 60rpx; | |||
border-radius: 10rpx; | |||
margin-right: 15rpx; | |||
padding-left: 10rpx; | |||
background-color: #ffffff; | |||
} | |||
.boxOutside { | |||
margin-bottom: 20rpx; | |||
.inputBox { | |||
display: inline-block; | |||
width: 500rpx; | |||
height: 60rpx; | |||
border-radius: 10rpx; | |||
margin-right: 15rpx; | |||
padding-left: 10rpx; | |||
background-color: #ffffff; | |||
} | |||
.sendBtn { | |||
display: inline-block; | |||
width: 150rpx; | |||
height: 60rpx; | |||
line-height: 50rpx; | |||
padding: 5rpx 0; | |||
.sendBtn { | |||
display: inline-block; | |||
width: 150rpx; | |||
height: 60rpx; | |||
line-height: 50rpx; | |||
padding: 5rpx 0; | |||
} | |||
} | |||
} |
@@ -2,14 +2,17 @@ | |||
<view class="content"> | |||
<view class="chatItem" wx:for="{{chatList}}" wx:key="index"> | |||
<view class="{{item.id == 1 ? 'chatContent right' : 'chatContent left'}}"> | |||
<image class="{{isResponing ? 'chatGpt isResponing' : 'chatGpt'}}" wx:if="{{!item.id}}" src="../../asset/icon/chatGpt.png" mode="heightFix" /> | |||
<image class="{{isResponing ? 'chatGpt isResponing' : 'chatGpt'}}" wx:if="{{!item.id}}" src="../../asset/icon/tiny-Chat-rotate.png" mode="heightFix" /> | |||
<text class="{{item.id == 1 ? 'message right' : 'message left'}}">{{item.message}}</text> | |||
<image class="userAvatar" wx:if="{{item.id && item.id == 1}}" src="../../asset/icon/user.png" mode="heightFix" /> | |||
</view> | |||
</view> | |||
<view class='over' wx:if="{{reLoadSocket}}">聊天已结束</view> | |||
</view> | |||
<view class="chatBox"> | |||
<input class="inputBox" type="text" bindinput="input" value="{{message}}" /> | |||
<button class="sendBtn" type="primary" bindtap="send">发送</button> | |||
<view class="boxOutside"> | |||
<input class="inputBox" type="text" bindinput="input" value="{{message}}" /> | |||
<button class="sendBtn" type="primary" bindtap="send">发送</button> | |||
</view> | |||
</view> |
@@ -15,9 +15,9 @@ | |||
.introduction { | |||
width: 600rpx; | |||
height: 900rpx; | |||
height: 830rpx; | |||
margin: 50rpx auto; | |||
padding-top: 20rpx; | |||
padding: 0 20rpx; | |||
border: 1px dashed #747474; | |||
border-radius: 60rpx; | |||
@@ -25,43 +25,47 @@ | |||
text-align: center; | |||
font-size: 45rpx; | |||
color: #585858; | |||
margin-bottom: 0rpx; | |||
margin-bottom: 10rpx; | |||
margin-top: 20rpx; | |||
} | |||
.contain { | |||
width: 500rpx; | |||
height: 600rpx; | |||
height: 520rpx; | |||
font-size: 30rpx; | |||
color: #585858; | |||
text-indent: 1cm; | |||
margin: auto; | |||
margin: 0 auto; | |||
padding: 20rpx; | |||
font-family: Verdana, Geneva, Tahoma, sans-serif; | |||
} | |||
.chatGptICon { | |||
position: relative; | |||
text-align: center; | |||
image { | |||
position: absolute; | |||
left: 50%; | |||
top: 50%; | |||
transform: translate(-50%, 50%); | |||
width: 80rpx; | |||
} | |||
} | |||
.notice { | |||
text-indent: 44rpx; | |||
font-size: 22rpx; | |||
color: #929292; | |||
padding: 0 50rpx; | |||
margin-top: 80rpx; | |||
margin-top: 20rpx; | |||
} | |||
} | |||
.tinyChatICon { | |||
position: relative; | |||
top: -85rpx; | |||
text-align: center; | |||
image { | |||
position: absolute; | |||
left: 50%; | |||
transform: translate(-50%, 50%); | |||
width: 100rpx; | |||
} | |||
} | |||
.buttons { | |||
font-size: 25rpx; | |||
margin-top: 150rpx; | |||
.userPhone { | |||
text-align: center; | |||
margin-bottom: 15rpx; | |||
@@ -1,27 +1,23 @@ | |||
<!--index.wxml--> | |||
<view class="content"> | |||
<view class="logo"> | |||
𝑮𝑷𝑻-𝑨𝒈𝒆𝒏𝒕 | |||
𝑺𝒎𝒂𝒓𝒕-𝑪𝒉𝒂𝒕 | |||
</view> | |||
<view class="introduction"> | |||
<view class="title">欢迎使用𝑮𝑷𝑻</view> | |||
<view class="title">欢迎使用小闲聊</view> | |||
<view class="contain"> | |||
<view> | |||
ChatGPT是一个基于大规模预训练语言模型的对话系统,由OpenAI开发。 | |||
"小闲聊"是一款基于人工智能技术开发的智能聊天机器人应用,用户可以通过文字聊天方式与机器人进行交互。该小程序不仅可以与用户进行简单的闲聊,还可以通过学习用户的行为和偏好,提供个性化的推荐服务。例如,如果用户喜欢科技内容,"小闲聊"可以根据用户的兴趣爱好,为用户推荐相关的科技内容。总之,"小闲聊"是一款功能全面、交互便捷、智能化的聊天小程序,让用户可以随时随地与机器人或好友进行交流,获得各种信息和娱乐。 | |||
</view> | |||
<view> | |||
它的核心技术是GPT模型,英文全称为(Generative Pre-trained Transformer)是一种基于深度学习的自然语言处理技术。GPT模型采用Transformer架构,利用无监督学习从大规模语料库中学习语言知识,具有强大的语言理解和生成能力。 | |||
</view> | |||
<view> | |||
ChatGPT将GPT模型应用于对话生成,可以进行自然流畅的对话,具有人类般的语言交互能力。 | |||
</view> | |||
<view class="chatGptICon"> | |||
<image src="../../asset/icon/chatGpt.png" mode="widthFix" /> | |||
</view> | |||
<view class="notice">严格遵守国家法律法规,自觉遵守中国互联网协会《文明上网自律公约》,不发布危害国家安全、违反法律法规、影响社会和谐稳定的有害信息</view> | |||
</view> | |||
<view class="notice">严格遵守国家法律法规,自觉遵守中国互联网协会《文明上网自律公约》,不发布危害国家安全、违反法律法规、影响社会和谐稳定的有害信息</view> | |||
</view> | |||
<view class="tinyChatICon"> | |||
<image src="../../asset/icon/tiny-Chat.png" mode="widthFix" /> | |||
</view> | |||
<view class="buttons"> | |||
<block wx:if="{{!userInfo.phone}}"> | |||
<button type="primary" open-type="getPhoneNumber" bindgetphonenumber="getUserPhone">申请使用</button> | |||
@@ -44,4 +40,5 @@ | |||
<button type="primary" bindtap="goToBuy">购买会员</button> | |||
</block> | |||
</view> | |||
</view> |
@@ -0,0 +1,70 @@ | |||
// pages/orderDetail/orderDetail.ts | |||
Page({ | |||
/** | |||
* 页面的初始数据 | |||
*/ | |||
data: { | |||
detail: null | |||
}, | |||
/** | |||
* 生命周期函数--监听页面加载 | |||
*/ | |||
onLoad(option) { | |||
if (option.detail && typeof option.detail == 'string') { | |||
this.setData({ | |||
detail: JSON.parse(option.detail) | |||
}) | |||
} | |||
}, | |||
/** | |||
* 生命周期函数--监听页面初次渲染完成 | |||
*/ | |||
onReady() { | |||
}, | |||
/** | |||
* 生命周期函数--监听页面显示 | |||
*/ | |||
onShow() { | |||
}, | |||
/** | |||
* 生命周期函数--监听页面隐藏 | |||
*/ | |||
onHide() { | |||
}, | |||
/** | |||
* 生命周期函数--监听页面卸载 | |||
*/ | |||
onUnload() { | |||
}, | |||
/** | |||
* 页面相关事件处理函数--监听用户下拉动作 | |||
*/ | |||
onPullDownRefresh() { | |||
}, | |||
/** | |||
* 页面上拉触底事件的处理函数 | |||
*/ | |||
onReachBottom() { | |||
}, | |||
/** | |||
* 用户点击右上角分享 | |||
*/ | |||
onShareAppMessage() { | |||
} | |||
}) |
@@ -0,0 +1,4 @@ | |||
{ | |||
"navigationBarTitleText": "订单详情", | |||
"usingComponents": {} | |||
} |
@@ -0,0 +1,33 @@ | |||
page { | |||
background-color: #f4f5f9; | |||
font-size: 28rpx; | |||
} | |||
.detail { | |||
padding: 40rpx; | |||
background-color: #fff; | |||
border-radius: 20rpx; | |||
font-weight: 600; | |||
view { | |||
margin-bottom: 50rpx; | |||
color: #a5a5a5; | |||
} | |||
.flex { | |||
display: flex; | |||
justify-content: space-between; | |||
} | |||
.black { | |||
color: #000; | |||
} | |||
.green { | |||
color: #07c160; | |||
} | |||
.red { | |||
color: #ff0000; | |||
} | |||
} |
@@ -0,0 +1,32 @@ | |||
<!--pages/orderDetail/orderDetail.wxml--> | |||
<view style="padding: 30rpx;"> | |||
<view class="detail"> | |||
<view> | |||
用户手机号:<text class="black">{{detail.cUserPhone}}</text> | |||
</view> | |||
<view> | |||
支付金额:<text class="black">{{detail.payAmount / 100}} 元</text> | |||
</view> | |||
<view> | |||
支付时间:<text class="black">{{detail.payTime}}</text> | |||
</view> | |||
<view> | |||
创建时间:<text class="black">{{detail.createTime}}</text> | |||
</view> | |||
<view> | |||
更新时间:<text class="black">{{detail.updateTime}}</text> | |||
</view> | |||
<view> | |||
生效开始时间:<text class="green">{{detail.validStartTime}}</text> | |||
</view> | |||
<view> | |||
生效结束时间:<text class="red">{{detail.validEndTime}}</text> | |||
</view> | |||
<view> | |||
备注:<text class="black">{{detail.remark}}</text> | |||
</view> | |||
<view> | |||
订单号:<text class="black">{{detail.transactionId}}</text> | |||
</view> | |||
</view> | |||
</view> |
@@ -1,5 +1,6 @@ | |||
const app = getApp() | |||
import request from '../../utils/request' | |||
import { timestampToTime } from '../../utils/util' | |||
Page({ | |||
@@ -18,6 +19,13 @@ Page({ | |||
this.getPayOrderList(1) | |||
}, | |||
goCheckDetail(e) { | |||
const item = JSON.stringify(e.currentTarget.dataset.item) | |||
wx.navigateTo({ | |||
url: `/pages/orderDetail/orderDetail?detail=${item}`, | |||
}) | |||
}, | |||
getPayOrderList(pageNum) { | |||
const that = this | |||
request.get({ | |||
@@ -27,11 +35,28 @@ Page({ | |||
pageSize: 10 | |||
} | |||
}).then(res => { | |||
wx.stopPullDownRefresh() | |||
wx.hideLoading() | |||
console.log(res, 'getPayOrderList'); | |||
res.data.list.forEach(item => { | |||
item.payTime = timestampToTime(item.payTime, 'YYYY-MM-DD hh:mm:ss') | |||
item.validStartTime = timestampToTime(item.validStartTime, 'YYYY-MM-DD hh:mm:ss') | |||
item.validEndTime = timestampToTime(item.validEndTime, 'YYYY-MM-DD hh:mm:ss') | |||
item.createTime = timestampToTime(item.createTime, 'YYYY-MM-DD hh:mm:ss') | |||
item.updateTime = timestampToTime(item.updateTime, 'YYYY-MM-DD hh:mm:ss') | |||
}) | |||
if (res.data.list && res.data.list.length > 0) { | |||
that.setData({ | |||
orderList: res.data.list | |||
}) | |||
if (pageNum == 1) { | |||
const tempArr = res.data.list | |||
that.setData({ | |||
orderList: res.data.list | |||
}) | |||
} else { | |||
const tempArr = that.data.orderList | |||
that.setData({ | |||
orderList: tempArr | |||
}) | |||
} | |||
} | |||
}).catch(err => { | |||
console.log(err, 'err'); | |||
@@ -70,14 +95,20 @@ Page({ | |||
* 页面相关事件处理函数--监听用户下拉动作 | |||
*/ | |||
onPullDownRefresh() { | |||
wx.showLoading() | |||
this.getPayOrderList(1) | |||
}, | |||
/** | |||
* 页面上拉触底事件的处理函数 | |||
*/ | |||
onReachBottom() { | |||
const that = this; | |||
that.data.pageNum++; | |||
that.setData({ | |||
pageNum: that.data.pageNum | |||
}); | |||
that.getPayOrderList(that.data.pageNum); | |||
}, | |||
/** | |||
@@ -1,4 +1,5 @@ | |||
{ | |||
"navigationBarTitleText": "购买历史", | |||
"usingComponents": {} | |||
"usingComponents": {}, | |||
"enablePullDownRefresh": true | |||
} |
@@ -1,19 +1,26 @@ | |||
.content { | |||
padding-top: 50rpx; | |||
padding: 50rpx 0; | |||
.list { | |||
padding: 0 50rpx; | |||
font-size: 25rpx; | |||
color: #747474; | |||
.item { | |||
position: relative; | |||
border: 1px solid #000; | |||
border: 1px dashed #999999; | |||
padding: 20rpx; | |||
border-radius: 10rpx; | |||
margin-bottom: 25rpx; | |||
.payAmount { | |||
margin-bottom: 15rpx; | |||
} | |||
.payTime { | |||
margin-bottom: 15rpx; | |||
} | |||
.check { | |||
position: absolute; | |||
width: 100rpx; | |||
@@ -1,10 +1,11 @@ | |||
<view class="content"> | |||
<view class="list"> | |||
<block wx:if="{{orderList && orderList.length > 0}}"> | |||
<view class="item" wx:for="{{orderList}}"> | |||
<view class="payAmount">支付金额:{{item.payAmount}}</view> | |||
<view>支付时间:{{item.payTime}}</view> | |||
<button class="check" type="primary" data-id="{{item.id}}" bindtap="goCheckDetail">查看</button> | |||
<view class="item" wx:for="{{orderList}}" wx:key="index"> | |||
<view class="payAmount">支付金额:{{item.payAmount / 100}} 元</view> | |||
<view class="payTime">支付时间:{{item.payTime}}</view> | |||
<view>到期时间:{{item.validEndTime}}</view> | |||
<button class="check" type="primary" data-item="{{item}}" bindtap="goCheckDetail">查看</button> | |||
</view> | |||
</block> | |||
<block wx:else> | |||
@@ -71,8 +71,8 @@ Page({ | |||
duration: 2000 | |||
}) | |||
setTimeout(() => { | |||
wx.navigateTo({ | |||
url: '/pages/payHistory/payHistory', | |||
wx.redirectTo({ | |||
url: '/pages/index/index', | |||
}) | |||
}, 2000); | |||
wx.hideLoading(); | |||
@@ -1,19 +1,58 @@ | |||
export const formatTime = (date) => { | |||
const year = date.getFullYear() | |||
const month = date.getMonth() + 1 | |||
const day = date.getDate() | |||
const hour = date.getHours() | |||
const minute = date.getMinutes() | |||
const second = date.getSeconds() | |||
return ( | |||
[year, month, day].map(formatNumber).join('/') + | |||
' ' + | |||
[hour, minute, second].map(formatNumber).join(':') | |||
) | |||
/** | |||
* @description 根据时间戳获取时间 | |||
* @param {*} timestamp 必传,number类型,时间戳数据(10位及以下,10位至13位);若不传,则返回:“无时间戳” | |||
* @param {*} format 选传,string类型,提供以下时间格式:YYYY-MM-DD hh:mm:ss、YYYY/MM/DD hh:mm:ss、YYYY.MM.DD hh:mm:ss、YYYY MM DD hh:mm:ss、YYYY年MM月DD日 hh:mm:ss、YYYY-MM-DD、YYYY/MM/DD、YYYY.MM.DD、YYYY MM DD、YYYY年MM月DD日;若不传,则默认为:YYYY-MM-DD | |||
* @returns 根据要求的时间格式 | |||
* @version V 1.0, Created by YWQ, 2022.10.20 | |||
*/ | |||
export const timestampToTime = (timestamp, format) => { | |||
//时间戳为10位需*1000,时间戳为13位不需乘1000 | |||
const length = timestamp.length | |||
if (length <= 10) { | |||
var date = new Date(timestamp * 1000) | |||
} else { | |||
var date = new Date(timestamp) | |||
} | |||
let Y = String(date.getFullYear()) | |||
let M = String(date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) | |||
let D = String(date.getDate() + 1 < 10 ? '0' + (date.getDate()) : date.getDate()) | |||
let h = String(date.getHours() + 1 < 10 ? '0' + (date.getHours()) : date.getHours()) | |||
let m = String(date.getMinutes() + 1 < 10 ? '0' + (date.getMinutes()) : date.getMinutes()) | |||
let s = String(date.getSeconds() + 1 < 10 ? '0' + (date.getSeconds()) : date.getSeconds()) | |||
// return Y + M + D + h + m + s | |||
if (format == "YYYY-MM-DD hh:mm:ss") { | |||
return Y + "-" + M + "-" + D + " " + h + ":" + m + ":" + s | |||
} else if (format == "YYYY/MM/DD hh:mm:ss") { | |||
return Y + "/" + M + "/" + D + " " + h + ":" + m + ":" + s | |||
} else if (format == "YYYY.MM.DD hh:mm:ss") { | |||
return Y + "." + M + "." + D + " " + h + ":" + m + ":" + s | |||
} else if (format == "YYYY MM DD hh:mm:ss") { | |||
return Y + " " + M + " " + D + " " + h + ":" + m + ":" + s | |||
} else if (format == "YYYY年MM月DD日 hh:mm:ss") { | |||
return Y + "年" + M + "月" + D + "日" + " " + h + ":" + m + ":" + s | |||
} else if (format == "YYYY-MM-DD") { | |||
return Y + "-" + M + "-" + D | |||
} else if (format == "YYYY/MM/DD") { | |||
return Y + "/" + M + "/" + D | |||
} else if (format == "YYYY.MM.DD") { | |||
return Y + "." + M + "." + D | |||
} else if (format == "YYYY MM DD") { | |||
return Y + " " + M + " " + D | |||
} else if (format == "YYYY年MM月DD日") { | |||
return Y + "年" + M + "月" + D + "日" | |||
} else { | |||
return Y + "-" + M + "-" + D | |||
} | |||
} | |||
const formatNumber = (n) => { | |||
const s = n.toString() | |||
return s[1] ? s : '0' + s | |||
/** | |||
* @description:滚动到对应id的位置 | |||
* @param {type} id | |||
*/ | |||
export const scrollToID = id => { | |||
wx.createSelectorQuery().select("#" + id).scrollIntoView({ | |||
behavior: "smooth", | |||
block: "start", | |||
inline: "nearest", | |||
}); | |||
} |
@@ -33,6 +33,7 @@ | |||
"miniprogram/pages/payOrder/payOrder.js", | |||
"miniprogram/pages/payHistory/payHistory.js", | |||
"miniprogram/pages/chat/chat.js", | |||
"miniprogram/pages/orderDetail/orderDetail.js", | |||
], | |||
"exclude": [ | |||
"node_modules" | |||