@@ -0,0 +1,7 @@
|
||||
const api = require('./utils/api')
|
||||
App({
|
||||
globalData: { user: wx.getStorageSync('user') || null },
|
||||
onLaunch() { this.loginPromise = this.login() },
|
||||
login() { return new Promise((resolve, reject) => wx.login({ success: ({ code }) => api.request('/api/auth/wechat', { method: 'POST', data: { code } }).then(({ token, user }) => { wx.setStorageSync('token', token); wx.setStorageSync('user', user); this.globalData.user = user; resolve(user) }).catch(reject), fail: reject })) },
|
||||
ensureLogin() { return this.loginPromise || this.login() }
|
||||
})
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"pages": ["pages/index/index", "pages/activity/index", "pages/profile/index", "pages/login/index"],
|
||||
"window": {
|
||||
"backgroundColor": "#F5F1EA",
|
||||
"backgroundTextStyle": "light",
|
||||
"navigationBarBackgroundColor": "#F5F1EA",
|
||||
"navigationBarTitleText": "CoffeeChat",
|
||||
"navigationBarTextStyle": "black"
|
||||
},
|
||||
"tabBar": {"color":"#8A7D71","selectedColor":"#2E5B47","backgroundColor":"#FFFDF9","list":[{"pagePath":"pages/index/index","text":"活动","iconPath":"images/icons/home.png","selectedIconPath":"images/icons/home-active.png"},{"pagePath":"pages/profile/index","text":"我的","iconPath":"images/icons/usercenter.png","selectedIconPath":"images/icons/usercenter-active.png"}]},
|
||||
"sitemapLocation": "sitemap.json",
|
||||
"style": "v2",
|
||||
"lazyCodeLoading": "requiredComponents"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
.page{min-height:100vh;background:#f5f1ea;color:#241f1b;font-family:-apple-system,BlinkMacSystemFont,"PingFang SC",sans-serif}.safe{padding:28rpx 30rpx 60rpx}.card{background:#fffdf9;border:1rpx solid #e5dacd;border-radius:28rpx;box-shadow:0 16rpx 42rpx rgba(74,54,38,.08)}.primary{background:#2e5b47!important;color:#fff!important;border-radius:999rpx;font-weight:600}.secondary{background:#eadfd2!important;color:#5d4738!important;border-radius:999rpx}.muted{color:#8a7d71}.tag{display:inline-block;padding:8rpx 16rpx;border-radius:999rpx;background:#ebe4ff;color:#6347c5;font-size:22rpx;margin-right:10rpx}.empty{text-align:center;color:#8a7d71;padding:100rpx 0}button::after{border:none}page{background:#f5f1ea}
|
||||
@@ -0,0 +1,28 @@
|
||||
Component({
|
||||
|
||||
/**
|
||||
* 页面的初始数据
|
||||
*/
|
||||
data: {
|
||||
showTip: false,
|
||||
},
|
||||
properties: {
|
||||
showTipProps: Boolean,
|
||||
title:String,
|
||||
content:String
|
||||
},
|
||||
observers: {
|
||||
showTipProps: function(showTipProps) {
|
||||
this.setData({
|
||||
showTip: showTipProps
|
||||
});
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onClose(){
|
||||
this.setData({
|
||||
showTip: !this.data.showTip
|
||||
});
|
||||
},
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"usingComponents": {},
|
||||
"component": true
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<!--miniprogram/components/cloudTipModal/index.wxml-->
|
||||
<!-- wx:if="{{showUploadTip}}" -->
|
||||
<view class="install_tip" wx:if="{{showTip}}">
|
||||
<view class="install_tip_back"></view>
|
||||
<view class="install_tip_detail">
|
||||
<image class="install_tip_close" bind:tap="onClose" src="../../images/icons/close.png"/>
|
||||
<view class="install_tip_detail_title">{{title}}</view>
|
||||
<view class="install_tip_detail_tip">{{content}}</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -0,0 +1,60 @@
|
||||
.install_tip_back {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background-color: rgba(0,0,0,0.4);
|
||||
z-index: 1;
|
||||
}
|
||||
.install_tip_close{
|
||||
position:absolute;
|
||||
right: 10rpx;
|
||||
top: 10rpx;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
/* background-color: red; */
|
||||
}
|
||||
.install_tip_detail {
|
||||
position: fixed;
|
||||
background-color: white;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
border-radius: 40rpx 40rpx 0 0;
|
||||
padding: 50rpx 50rpx 100rpx 50rpx;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.install_tip_detail_title {
|
||||
font-weight: 400;
|
||||
font-size: 40rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.install_tip_detail_tip {
|
||||
font-size: 25rpx;
|
||||
color: rgba(0,0,0,0.4);
|
||||
margin-top: 20rpx;
|
||||
text-align: left;
|
||||
}
|
||||
.install_tip_detail_buttons {
|
||||
padding-top: 50rpx;
|
||||
display: flex;
|
||||
}
|
||||
.install_tip_detail_button {
|
||||
color: #07C160;
|
||||
font-weight: 500;
|
||||
background-color: rgba(0,0,0,0.1);
|
||||
width: 40%;
|
||||
text-align: center;
|
||||
/* height: 90rpx; */
|
||||
/* line-height: 90rpx; */
|
||||
border-radius: 10rpx;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.install_tip_detail_button_primary {
|
||||
background-color: #07C160;
|
||||
color: #fff;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
module.exports = { apiBaseUrl: 'https://coffeechat.example.com' }
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
const envList = [];
|
||||
const isMac = false;
|
||||
module.exports = {
|
||||
envList,
|
||||
isMac
|
||||
};
|
||||
|
After Width: | Height: | Size: 214 KiB |
|
After Width: | Height: | Size: 63 KiB |
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="8px" height="14px" viewBox="0 0 8 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>☀ iOS/☀ 图标/线型/icons_outlined_arrow@3x</title>
|
||||
<g id="控件" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" fill-opacity="0.3">
|
||||
<g id="4.列表/z.覆盖层/右边/箭头" transform="translate(-334.000000, -21.000000)" fill="#000000">
|
||||
<g id="☀-iOS/☀-图标/线型/icons_outlined_arrow" transform="translate(332.000000, 16.000000)">
|
||||
<path d="M2.45405845,6.58064919 L3.51471863,5.51998901 L9.29361566,11.298886 C9.68374096,11.6890113 9.6872014,12.318069 9.29361566,12.7116547 L3.51471863,18.4905518 L2.45405845,17.4298916 L7.87867966,12.0052704 L2.45405845,6.58064919 Z" id="Combined-Shape"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 906 B |
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 17 KiB |
@@ -0,0 +1,2 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M2 2H15V7.5H13V4H4V13H7.5V15H2V2ZM9 9H22V22H9V9ZM11 11V20H20V11H11Z" fill="#8b8b8b" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 197 B |
|
After Width: | Height: | Size: 305 KiB |
|
After Width: | Height: | Size: 193 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 63 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 875 B |
|
After Width: | Height: | Size: 888 B |
|
After Width: | Height: | Size: 578 B |
|
After Width: | Height: | Size: 666 B |
@@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6.95693 15.75H19.5V6H4.5V17.7974L6.95693 15.75ZM3.73808 20.3849C3.44499 20.6292 3 20.4208 3 20.0392V6C3 5.17157 3.67157 4.5 4.5 4.5H19.5C20.3284 4.5 21 5.17157 21 6V15.75C21 16.5784 20.3284 17.25 19.5 17.25H7.5L3.73808 20.3849Z" fill="black" fill-opacity="0.9"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 376 B |
|
After Width: | Height: | Size: 779 B |
|
After Width: | Height: | Size: 789 B |
|
After Width: | Height: | Size: 917 B |
|
After Width: | Height: | Size: 888 B |
|
After Width: | Height: | Size: 873 B |
|
After Width: | Height: | Size: 879 B |
@@ -0,0 +1,5 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M11.0911 17.4C11.0911 16.9029 11.494 16.5 11.9911 16.5C12.4881 16.5 12.8911 16.9029 12.8911 17.4C12.8911 17.8971 12.4881 18.3 11.9911 18.3C11.494 18.3 11.0911 17.8971 11.0911 17.4Z" fill="black" fill-opacity="0.9"/>
|
||||
<path d="M11.9911 6.00915C9.98467 6.00915 8.35363 7.64019 8.35363 9.64665H9.85363C9.85363 8.46862 10.8131 7.50915 11.9911 7.50915C13.1692 7.50915 14.1286 8.46862 14.1286 9.64665C14.1286 10.4533 13.4619 11.2621 12.5917 11.6156L12.5878 11.6172C11.7935 11.945 11.2412 12.7262 11.2412 13.6387V15H12.7412V13.6387C12.7412 13.3474 12.9142 13.106 13.1585 13.0044C14.3995 12.4993 15.6286 11.248 15.6286 9.64665C15.6286 7.64019 13.9976 6.00915 11.9911 6.00915Z" fill="black" fill-opacity="0.9"/>
|
||||
<path d="M22.4912 12C22.4912 6.20101 17.7902 1.5 11.9912 1.5C6.19222 1.5 1.49121 6.20101 1.49121 12C1.49121 17.799 6.19222 22.5 11.9912 22.5C17.7902 22.5 22.4912 17.799 22.4912 12ZM20.9912 12C20.9912 16.9706 16.9618 21 11.9912 21C7.02065 21 2.99121 16.9706 2.99121 12C2.99121 7.02944 7.02065 3 11.9912 3C16.9618 3 20.9912 7.02944 20.9912 12Z" fill="black" fill-opacity="0.9"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M16.5002 12C16.5002 14.4853 14.4855 16.5 12.0002 16.5C9.51497 16.5 7.50025 14.4853 7.50025 12C7.50025 9.51472 9.51497 7.5 12.0002 7.5C14.4855 7.5 16.5002 9.51472 16.5002 12ZM15.0002 12C15.0002 10.3431 13.6571 9 12.0002 9C10.3434 9 9.00025 10.3431 9.00025 12C9.00025 13.6569 10.3434 15 12.0002 15C13.6571 15 15.0002 13.6569 15.0002 12Z" fill="black" fill-opacity="0.9"/>
|
||||
<path d="M12.0002 1.875L21.0935 6.9375V17.0625L12.0002 22.125L2.90698 17.0625V6.9375L12.0002 1.875ZM4.40698 7.8192V16.1808L12.0002 20.4082L19.5935 16.1808V7.8192L12.0002 3.59179L4.40698 7.8192Z" fill="black" fill-opacity="0.9"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 711 B |
@@ -0,0 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3.43993 20.5601C3.72112 20.8413 4.10234 20.9995 4.5 21H19.5C19.8977 20.9995 20.2789 20.8413 20.5601 20.5601C20.8413 20.2789 20.9995 19.8977 21 19.5V12.75H19.5V19.5H4.5V4.5H11.25V3H4.5C4.10234 3.00054 3.72112 3.15874 3.43993 3.43993C3.15874 3.72112 3.00054 4.10234 3 4.5V19.5C3.00054 19.8977 3.15874 20.2789 3.43993 20.5601Z" fill="black" fill-opacity="0.9"/>
|
||||
<path d="M13.5 4.5V3H20.25C20.6642 3 21 3.33579 21 3.75V10.5H19.5V5.5605L13.0605 12L12 10.9395L18.4395 4.5H13.5Z" fill="black" fill-opacity="0.9"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 620 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 24 KiB |
@@ -0,0 +1,2 @@
|
||||
const api=require('../../utils/api');const app=getApp();
|
||||
Page({data:{id:'',activity:null,user:null,joined:false,purpose:'',showPurpose:false,submitting:false},onLoad({id}){this.setData({id,user:app.globalData.user||wx.getStorageSync('user')});app.ensureLogin().then(user=>{this.setData({user});this.load()}).catch(()=>this.load())},onShow(){if(this.data.activity)this.load()},async load(){try{const activity=await api.request(`/api/activities/${this.data.id}`);const mine=activity.participants.find(p=>this.data.user&&p.id===this.data.user.id);this.setData({activity,joined:!!mine,purpose:mine?mine.purpose:''})}catch(e){wx.showToast({title:e.message,icon:'none'})}},preview(e){const urls=this.data.activity.images.map(x=>x.url);wx.previewImage({current:e.currentTarget.dataset.url,urls})},editPurpose(){this.setData({showPurpose:true})},purposeInput(e){this.setData({purpose:e.detail.value})},closePurpose(){this.setData({showPurpose:false})},async savePurpose(){this.setData({submitting:true});try{await api.request(`/api/activities/${this.data.id}/participations/me`,{method:'PUT',data:{purpose:this.data.purpose}});this.setData({showPurpose:false});await this.load();wx.showToast({title:'已加入'})}catch(e){wx.showToast({title:e.message,icon:'none'})}finally{this.setData({submitting:false})}},leave(){wx.showModal({title:'退出活动?',content:'你的参与目的也会被移除',success:async r=>{if(r.confirm){await api.request(`/api/activities/${this.data.id}/participations/me`,{method:'DELETE'});this.load()}}})},openGroup(e){wx.previewImage({urls:[e.currentTarget.dataset.url]})},submitGroup(){wx.chooseMedia({count:1,mediaType:['image'],success:async r=>{wx.showLoading({title:'上传中'});try{const file=await api.upload(r.tempFiles[0].tempFilePath);await api.request(`/api/activities/${this.data.id}/participations/groups`,{method:'POST',data:{name:`${this.data.activity.title}交流群`,qrImageUrl:file.url,note:'用户提交,待管理员核验'}});wx.showToast({title:'已提交审核'})}catch(e){wx.showToast({title:e.message,icon:'none'})}finally{wx.hideLoading()}}})}})
|
||||
@@ -0,0 +1 @@
|
||||
{"navigationBarTitleText":"活动详情","backgroundColor":"#f5f1ea"}
|
||||
@@ -0,0 +1 @@
|
||||
<view class="page" wx:if="{{activity}}"><swiper wx:if="{{activity.images.length}}" class="gallery" indicator-dots circular><swiper-item wx:for="{{activity.images}}" wx:key="id"><image src="{{item.url}}" mode="aspectFill" data-url="{{item.url}}" bindtap="preview"></image></swiper-item></swiper><view wx:else class="gallery placeholder">CoffeeChat</view><view class="content"><view class="status">{{activity.status==='active'?'正在进行':'即将开始'}}</view><view class="title">{{activity.title}}</view><view class="tags"><text wx:for="{{activity.tags}}" wx:key="id" class="tag">{{item.name}}</text></view><view class="facts card"><view><text>时间</text><b>{{activity.startsAt}}</b></view><view><text>地点</text><b>{{activity.location || activity.exhibition.venue}}</b></view></view><view class="section"><view class="section-title">活动介绍</view><text class="description">{{activity.description}}</text></view><view class="expo card"><text class="overline">所属会展</text><view class="expo-title">{{activity.exhibition.name}}</view><text>{{activity.exhibition.startsAt}} 至 {{activity.exhibition.endsAt}}</text><text>{{activity.exhibition.venue}} · {{activity.exhibition.address}}</text><text class="description">{{activity.exhibition.description}}</text></view><view class="section"><view class="section-head"><view class="section-title">会遇见的人</view><text>{{activity.participants.length}} 人</text></view><view wx:if="{{!activity.participants.length}}" class="muted">成为第一个加入的人吧</view><view wx:for="{{activity.participants}}" wx:key="id" class="person"><image src="{{item.avatarUrl || '/images/avatar.png'}}"></image><view><b>{{item.nickname}}</b><text>{{item.purpose || '期待现场交流'}}</text></view></view></view><view class="section"><view class="section-head"><view class="section-title">活动微信群</view><text bindtap="submitGroup" class="link">提交群二维码</text></view><view wx:if="{{!activity.groups.length}}" class="muted">暂无已审核的群</view><view wx:for="{{activity.groups}}" wx:key="id" class="group card" data-url="{{item.qrImageUrl}}" bindtap="openGroup"><image src="{{item.qrImageUrl}}"></image><view><b>{{item.name}}</b><text>点击查看二维码</text></view></view></view></view><view class="footer"><button wx:if="{{!joined}}" class="primary" bindtap="editPurpose">加入活动</button><block wx:else><button class="secondary" bindtap="editPurpose">编辑参与目的</button><button class="text-btn" bindtap="leave">退出</button></block></view><view wx:if="{{showPurpose}}" class="mask" bindtap="closePurpose"><view class="sheet" catchtap=""><view class="section-title">你为什么想参加?</view><textarea maxlength="300" value="{{purpose}}" bindinput="purposeInput" placeholder="例如:寻找 AI 应用方向的合作伙伴"></textarea><button class="primary" loading="{{submitting}}" bindtap="savePurpose">确认加入</button></view></view></view>
|
||||
@@ -0,0 +1 @@
|
||||
.gallery{height:560rpx;background:#ddd}.gallery image{width:100%;height:100%}.placeholder{display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,#315c49,#9d7256);color:white;font:italic 56rpx serif}.content{padding:34rpx 30rpx 180rpx}.status{color:#a15f3c;font-size:24rpx}.title{font:700 54rpx/1.2 serif;margin:14rpx 0 20rpx}.facts{padding:12rpx 26rpx;margin:30rpx 0}.facts view{display:flex;gap:24rpx;padding:20rpx 0;border-bottom:1rpx solid #eee5db}.facts view:last-child{border:0}.facts text{color:#8a7d71;width:70rpx}.facts b{font-size:27rpx}.section{margin:46rpx 0}.section-title{font-size:34rpx;font-weight:700;margin-bottom:20rpx}.description{line-height:1.8;color:#5f534a;white-space:pre-wrap}.expo{padding:28rpx;display:flex;flex-direction:column;gap:10rpx}.overline{font-size:20rpx;letter-spacing:3rpx;color:#9b7256}.expo-title{font-size:35rpx;font-weight:700}.section-head{display:flex;justify-content:space-between;align-items:center}.link{color:#2e5b47;font-weight:600}.person{display:flex;gap:18rpx;padding:18rpx 0;border-bottom:1rpx solid #e5dbcf}.person image{width:76rpx;height:76rpx;border-radius:50%}.person view{display:flex;flex-direction:column;gap:6rpx}.person text{color:#76695e;font-size:25rpx}.group{display:flex;align-items:center;padding:18rpx;margin:12rpx 0;gap:18rpx}.group image{width:90rpx;height:90rpx;border-radius:12rpx}.group view{display:flex;flex-direction:column;gap:8rpx}.group text{font-size:23rpx;color:#807267}.footer{position:fixed;left:0;right:0;bottom:0;padding:20rpx 30rpx calc(20rpx + env(safe-area-inset-bottom));display:flex;gap:12rpx;background:#fffdf9;border-top:1rpx solid #e2d8cc}.footer button{flex:1}.footer .text-btn{flex:0 0 120rpx;color:#a74b3f}.mask{position:fixed;inset:0;background:#241f1b88;display:flex;align-items:flex-end;z-index:10}.sheet{width:100%;background:#fffdf9;border-radius:32rpx 32rpx 0 0;padding:38rpx 30rpx calc(34rpx + env(safe-area-inset-bottom))}.sheet textarea{width:100%;box-sizing:border-box;background:#f3ede6;border-radius:20rpx;padding:22rpx;margin:10rpx 0 26rpx;height:220rpx}
|
||||
@@ -0,0 +1,606 @@
|
||||
// pages/exampleDetail/index.js
|
||||
Page({
|
||||
data: {
|
||||
type: "",
|
||||
envId: "",
|
||||
showTip: false,
|
||||
title: "",
|
||||
content: "",
|
||||
|
||||
haveGetOpenId: false,
|
||||
openId: "",
|
||||
|
||||
haveGetCodeSrc: false,
|
||||
codeSrc: "",
|
||||
|
||||
haveGetRecord: false,
|
||||
record: [],
|
||||
|
||||
haveGetImgSrc: false,
|
||||
imgSrc: "",
|
||||
|
||||
// ai
|
||||
modelConfig: {
|
||||
modelProvider: "deepseek", // 大模型服务厂商
|
||||
quickResponseModel: "deepseek-v3", // 快速响应模型 (混元 turbo, gpt4 turbo版,deepseek v3等)
|
||||
logo: "https://cloudcache.tencent-cloud.com/qcloud/ui/static/static_source_business/2339414f-2c0d-4537-9618-1812bd14f4af.svg", // model 头像
|
||||
welcomeMsg: "我是deepseek-v3,很高兴见到你!", // model 欢迎语
|
||||
},
|
||||
callcbrCode: "",
|
||||
initEnvCode: "",
|
||||
callOpenIdCode: "",
|
||||
callMiniProgramCode: "",
|
||||
callFunctionCode: "",
|
||||
callCreateCollectionCode: "",
|
||||
callUploadFileCode: "",
|
||||
|
||||
showInsertModal: false,
|
||||
insertRegion: "",
|
||||
insertCity: "",
|
||||
insertSales: "",
|
||||
|
||||
haveGetCallContainerRes: false,
|
||||
callContainerResStr: "",
|
||||
|
||||
ai_page_config: `{
|
||||
"usingComponents": {
|
||||
"agent-ui":"/components/agent-ui/index"
|
||||
},
|
||||
}`,
|
||||
ai_wxml_config: `<agent-ui agentConfig="{{agentConfig}}" showBotAvatar="{{showBotAvatar}}" chatMode="{{chatMode}}" modelConfig="{{modelConfig}}""></agent-ui>`,
|
||||
ai_data_config: `data: {
|
||||
chatMode: "bot", // bot 表示使用agent,model 表示使用大模型
|
||||
showBotAvatar: true, // 是否在对话框左侧显示头像
|
||||
agentConfig: {
|
||||
botId: "your agent id", // agent id,
|
||||
allowWebSearch: true, // 允许客户端选择展示联网搜索按钮
|
||||
allowUploadFile: true, // 允许客户端展示上传文件按钮
|
||||
allowPullRefresh: true, // 允许客户端展示下拉刷新
|
||||
allowUploadImage: true, // 允许客户端展示上传图片按钮
|
||||
allowMultiConversation: true, // 允许客户端展示查看会话列表/新建会话按钮
|
||||
showToolCallDetail: true, // 是否展示 mcp server toolCall 细节
|
||||
allowVoice: true, // 允许客户端展示语音按钮
|
||||
showBotName: true, // 允许展示bot名称
|
||||
},
|
||||
modelConfig: {
|
||||
modelProvider: "hunyuan-open", // 大模型服务厂商
|
||||
quickResponseModel: "hunyuan-lite", // 大模型名称
|
||||
logo: "", // model 头像
|
||||
welcomeMsg: "欢迎语", // model 欢迎语
|
||||
},
|
||||
}`,
|
||||
|
||||
// AI 场景示例数据
|
||||
aiScenarios: [
|
||||
{
|
||||
title: "💡 智能代码生成与补全",
|
||||
examples: [
|
||||
"帮我创建一个商品列表页面,包含图片、标题、价格和加入购物车按钮",
|
||||
"帮我完善这个函数,实现商品搜索功能",
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "🔧 代码优化与重构建议",
|
||||
examples: [
|
||||
"优化这段代码的性能,减少不必要的渲染",
|
||||
"完善云函数调用的错误处理代码",
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
onLoad(options) {
|
||||
if (
|
||||
options.type === "cloudbaserunfunction" ||
|
||||
options.type === "cloudbaserun"
|
||||
) {
|
||||
this.getCallcbrCode();
|
||||
}
|
||||
if (options.type === "getOpenId") {
|
||||
this.getOpenIdCode();
|
||||
}
|
||||
if (options.type === "getMiniProgramCode") {
|
||||
this.getMiniProgramCode();
|
||||
}
|
||||
|
||||
if (options.type === "createCollection") {
|
||||
this.getCreateCollectionCode();
|
||||
}
|
||||
|
||||
if (options.type === "uploadFile") {
|
||||
this.getUploadFileCode();
|
||||
}
|
||||
this.setData({ type: options?.type, envId: options?.envId });
|
||||
},
|
||||
|
||||
copyUrl() {
|
||||
wx.setClipboardData({
|
||||
data: "https://gitee.com/TencentCloudBase/cloudbase-agent-ui/tree/main/apps/miniprogram-agent-ui/miniprogram/components/agent-ui",
|
||||
success: function (res) {
|
||||
wx.showToast({
|
||||
title: "复制成功",
|
||||
icon: "success",
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
copyPluginName() {
|
||||
wx.setClipboardData({
|
||||
data: "微信云开发 AI ToolKit",
|
||||
success: function (res) {
|
||||
wx.showToast({
|
||||
title: "复制成功",
|
||||
icon: "success",
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
copyPrompt(e) {
|
||||
const prompt = e.currentTarget.dataset.prompt;
|
||||
wx.setClipboardData({
|
||||
data: prompt,
|
||||
success: function (res) {
|
||||
wx.showToast({
|
||||
title: "复制成功",
|
||||
icon: "success",
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
insertRecord() {
|
||||
this.setData({
|
||||
showInsertModal: true,
|
||||
insertRegion: "",
|
||||
insertCity: "",
|
||||
insertSales: "",
|
||||
});
|
||||
},
|
||||
|
||||
deleteRecord(e) {
|
||||
// 调用云函数删除记录
|
||||
wx.showLoading({
|
||||
title: "删除中...",
|
||||
});
|
||||
wx.cloud
|
||||
.callFunction({
|
||||
name: "quickstartFunctions",
|
||||
data: {
|
||||
type: "deleteRecord",
|
||||
data: {
|
||||
_id: e.currentTarget.dataset.id,
|
||||
},
|
||||
},
|
||||
})
|
||||
.then((resp) => {
|
||||
wx.showToast({
|
||||
title: "删除成功",
|
||||
});
|
||||
this.getRecord(); // 刷新列表
|
||||
wx.hideLoading();
|
||||
})
|
||||
.catch((e) => {
|
||||
wx.showToast({
|
||||
title: "删除失败",
|
||||
icon: "none",
|
||||
});
|
||||
wx.hideLoading();
|
||||
});
|
||||
},
|
||||
|
||||
// 输入框事件
|
||||
onInsertRegionInput(e) {
|
||||
this.setData({ insertRegion: e.detail.value });
|
||||
},
|
||||
onInsertCityInput(e) {
|
||||
this.setData({ insertCity: e.detail.value });
|
||||
},
|
||||
onInsertSalesInput(e) {
|
||||
this.setData({ insertSales: e.detail.value });
|
||||
},
|
||||
// 取消弹窗
|
||||
onInsertCancel() {
|
||||
this.setData({ showInsertModal: false });
|
||||
},
|
||||
|
||||
// 确认插入
|
||||
async onInsertConfirm() {
|
||||
const { insertRegion, insertCity, insertSales } = this.data;
|
||||
if (!insertRegion || !insertCity || !insertSales) {
|
||||
wx.showToast({ title: "请填写完整信息", icon: "none" });
|
||||
return;
|
||||
}
|
||||
wx.showLoading({ title: "插入中..." });
|
||||
try {
|
||||
await wx.cloud.callFunction({
|
||||
name: "quickstartFunctions",
|
||||
data: {
|
||||
type: "insertRecord",
|
||||
data: {
|
||||
region: insertRegion,
|
||||
city: insertCity,
|
||||
sales: Number(insertSales),
|
||||
},
|
||||
},
|
||||
});
|
||||
wx.showToast({ title: "插入成功" });
|
||||
this.setData({ showInsertModal: false });
|
||||
this.getRecord(); // 刷新列表
|
||||
} catch (e) {
|
||||
wx.showToast({ title: "插入失败", icon: "none" });
|
||||
console.error(e);
|
||||
} finally {
|
||||
wx.hideLoading();
|
||||
}
|
||||
},
|
||||
|
||||
getOpenId() {
|
||||
wx.showLoading({
|
||||
title: "",
|
||||
});
|
||||
wx.cloud
|
||||
.callFunction({
|
||||
name: "quickstartFunctions",
|
||||
data: {
|
||||
type: "getOpenId",
|
||||
},
|
||||
})
|
||||
.then((resp) => {
|
||||
this.setData({
|
||||
haveGetOpenId: true,
|
||||
openId: resp.result.openid,
|
||||
});
|
||||
wx.hideLoading();
|
||||
})
|
||||
.catch((e) => {
|
||||
wx.hideLoading();
|
||||
const { errCode, errMsg } = e;
|
||||
if (errMsg.includes("Environment not found")) {
|
||||
this.setData({
|
||||
showTip: true,
|
||||
title: "云开发环境未找到",
|
||||
content:
|
||||
"如果已经开通云开发,请检查环境ID与 `miniprogram/app.js` 中的 `env` 参数是否一致。",
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (errMsg.includes("FunctionName parameter could not be found")) {
|
||||
this.setData({
|
||||
showTip: true,
|
||||
title: "请上传云函数",
|
||||
content:
|
||||
"在'cloudfunctions/quickstartFunctions'目录右键,选择【上传并部署-云端安装依赖】,等待云函数上传完成后重试。",
|
||||
});
|
||||
return;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
clearOpenId() {
|
||||
this.setData({
|
||||
haveGetOpenId: false,
|
||||
openId: "",
|
||||
});
|
||||
},
|
||||
|
||||
clearCallContainerRes() {
|
||||
this.setData({
|
||||
haveGetCallContainerRes: false,
|
||||
callContainerResStr: "",
|
||||
});
|
||||
},
|
||||
|
||||
getCodeSrc() {
|
||||
wx.showLoading({
|
||||
title: "",
|
||||
});
|
||||
wx.cloud
|
||||
.callFunction({
|
||||
name: "quickstartFunctions",
|
||||
data: {
|
||||
type: "getMiniProgramCode",
|
||||
},
|
||||
})
|
||||
.then((resp) => {
|
||||
this.setData({
|
||||
haveGetCodeSrc: true,
|
||||
codeSrc: resp.result,
|
||||
});
|
||||
wx.hideLoading();
|
||||
})
|
||||
.catch((e) => {
|
||||
wx.hideLoading();
|
||||
console.error(e);
|
||||
const { errCode, errMsg } = e;
|
||||
if (errMsg.includes("Environment not found")) {
|
||||
this.setData({
|
||||
showTip: true,
|
||||
title: "云开发环境未找到",
|
||||
content:
|
||||
"如果已经开通云开发,请检查环境ID与 `miniprogram/app.js` 中的 `env` 参数是否一致。",
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (errMsg.includes("FunctionName parameter could not be found")) {
|
||||
this.setData({
|
||||
showTip: true,
|
||||
title: "请上传云函数",
|
||||
content:
|
||||
"在'cloudfunctions/quickstartFunctions'目录右键,选择【上传并部署-云端安装依赖】,等待云函数上传完成后重试。",
|
||||
});
|
||||
return;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
clearCodeSrc() {
|
||||
this.setData({
|
||||
haveGetCodeSrc: false,
|
||||
codeSrc: "",
|
||||
});
|
||||
},
|
||||
|
||||
bindInput(e) {
|
||||
const index = e.currentTarget.dataset.index;
|
||||
const record = this.data.record;
|
||||
record[index].sales = Number(e.detail.value);
|
||||
this.setData({
|
||||
record,
|
||||
});
|
||||
},
|
||||
|
||||
getRecord() {
|
||||
wx.showLoading({
|
||||
title: "",
|
||||
});
|
||||
wx.cloud
|
||||
.callFunction({
|
||||
name: "quickstartFunctions",
|
||||
data: {
|
||||
type: "selectRecord",
|
||||
},
|
||||
})
|
||||
.then((resp) => {
|
||||
this.setData({
|
||||
haveGetRecord: true,
|
||||
record: resp.result.data,
|
||||
});
|
||||
wx.hideLoading();
|
||||
})
|
||||
.catch((e) => {
|
||||
this.setData({
|
||||
showTip: true,
|
||||
});
|
||||
wx.hideLoading();
|
||||
console.error(e);
|
||||
});
|
||||
},
|
||||
|
||||
clearRecord() {
|
||||
this.setData({
|
||||
haveGetRecord: false,
|
||||
record: [],
|
||||
});
|
||||
},
|
||||
updateRecord() {
|
||||
wx.showLoading({
|
||||
title: "",
|
||||
});
|
||||
wx.cloud
|
||||
.callFunction({
|
||||
name: "quickstartFunctions",
|
||||
data: {
|
||||
type: "updateRecord",
|
||||
data: this.data.record,
|
||||
},
|
||||
})
|
||||
.then((resp) => {
|
||||
wx.showToast({
|
||||
title: "更新成功",
|
||||
});
|
||||
wx.hideLoading();
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e);
|
||||
this.setData({
|
||||
showUploadTip: true,
|
||||
});
|
||||
wx.hideLoading();
|
||||
});
|
||||
},
|
||||
|
||||
uploadImg() {
|
||||
wx.showLoading({
|
||||
title: "",
|
||||
});
|
||||
// 让用户选择一张图片
|
||||
wx.chooseMedia({
|
||||
count: 1,
|
||||
success: (chooseResult) => {
|
||||
// 将图片上传至云存储空间
|
||||
wx.cloud
|
||||
.uploadFile({
|
||||
// 指定上传到的云路径
|
||||
cloudPath: `my-photo-${new Date().getTime()}.png`,
|
||||
// 指定要上传的文件的小程序临时文件路径
|
||||
filePath: chooseResult.tempFiles[0].tempFilePath,
|
||||
})
|
||||
.then((res) => {
|
||||
this.setData({
|
||||
haveGetImgSrc: true,
|
||||
imgSrc: res.fileID,
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log("e", e);
|
||||
});
|
||||
},
|
||||
complete: () => {
|
||||
wx.hideLoading();
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
clearImgSrc() {
|
||||
this.setData({
|
||||
haveGetImgSrc: false,
|
||||
imgSrc: "",
|
||||
});
|
||||
},
|
||||
|
||||
goOfficialWebsite() {
|
||||
const url = "https://docs.cloudbase.net/toolbox/quick-start";
|
||||
wx.navigateTo({
|
||||
url: `../web/index?url=${url}`,
|
||||
});
|
||||
},
|
||||
runCallContainer: async function () {
|
||||
const app = getApp();
|
||||
console.log("globalData", app.globalData);
|
||||
const c1 = new wx.cloud.Cloud({
|
||||
resourceEnv: app.globalData.env,
|
||||
});
|
||||
await c1.init();
|
||||
const r = await c1.callContainer({
|
||||
path: "/api/users", // 填入业务自定义路径
|
||||
header: {
|
||||
"X-WX-SERVICE": "express-test", // 填入服务名称
|
||||
},
|
||||
// 其余参数同 wx.request
|
||||
method: "GET",
|
||||
});
|
||||
console.log(r);
|
||||
this.setData({
|
||||
haveGetCallContainerRes: true,
|
||||
callContainerResStr: `${JSON.stringify(r.data.items, null, 2)}`,
|
||||
});
|
||||
},
|
||||
getCallcbrCode: function () {
|
||||
const app = getApp();
|
||||
this.setData({
|
||||
callcbrCode: `const c1 = new wx.cloud.Cloud({
|
||||
resourceEnv: ${app.globalData.env}
|
||||
})
|
||||
await c1.init()
|
||||
const r = await c1.callContainer({
|
||||
path: '/api/users', // 此处填入业务自定义路径, /api/users 为示例路径
|
||||
header: {
|
||||
'X-WX-SERVICE': 'express-test', // 填入业务服务名称,express-test 为示例服务
|
||||
},
|
||||
// 其余参数同 wx.request
|
||||
method: 'GET',
|
||||
})`,
|
||||
});
|
||||
},
|
||||
getInitEnvCode: function () {
|
||||
const app = getApp();
|
||||
this.setData({
|
||||
initEnvCode: `wx.cloud.init({
|
||||
env: ${app.globalData.env},
|
||||
traceUser: true,
|
||||
});`,
|
||||
});
|
||||
},
|
||||
getCreateCollectionCode: function () {
|
||||
this.setData({
|
||||
callCreateCollectionCode: `const cloud = require('wx-server-sdk');
|
||||
cloud.init({
|
||||
env: cloud.DYNAMIC_CURRENT_ENV
|
||||
});
|
||||
const db = cloud.database();
|
||||
// 创建集合云函数入口函数
|
||||
exports.main = async (event, context) => {
|
||||
try {
|
||||
// 创建集合
|
||||
await db.createCollection('sales');
|
||||
return {
|
||||
success: true
|
||||
};
|
||||
} catch (e) {
|
||||
return {
|
||||
success: true,
|
||||
data: 'create collection success'
|
||||
};
|
||||
}
|
||||
};`,
|
||||
});
|
||||
},
|
||||
getOpenIdCode: function () {
|
||||
this.setData({
|
||||
callOpenIdCode: `const cloud = require('wx-server-sdk');
|
||||
cloud.init({
|
||||
env: cloud.DYNAMIC_CURRENT_ENV
|
||||
});
|
||||
// 获取openId云函数入口函数
|
||||
exports.main = async (event, context) => {
|
||||
// 获取基础信息
|
||||
const wxContext = cloud.getWXContext();
|
||||
return {
|
||||
openid: wxContext.OPENID,
|
||||
appid: wxContext.APPID,
|
||||
unionid: wxContext.UNIONID,
|
||||
};
|
||||
};`,
|
||||
callFunctionCode: `wx.cloud.callFunction({
|
||||
name: 'quickstartFunctions',
|
||||
data: {
|
||||
type: 'getOpenId'
|
||||
}
|
||||
}).then((resp) => console.log(resp))`,
|
||||
});
|
||||
},
|
||||
getMiniProgramCode: function () {
|
||||
this.setData({
|
||||
callMiniProgramCode: `const cloud = require('wx-server-sdk');
|
||||
cloud.init({
|
||||
env: cloud.DYNAMIC_CURRENT_ENV
|
||||
});
|
||||
// 获取小程序二维码云函数入口函数
|
||||
exports.main = async (event, context) => {
|
||||
// 获取小程序二维码的buffer
|
||||
const resp = await cloud.openapi.wxacode.get({
|
||||
path: 'pages/index/index'
|
||||
});
|
||||
const { buffer } = resp;
|
||||
// 将图片上传云存储空间
|
||||
const upload = await cloud.uploadFile({
|
||||
cloudPath: 'code.png',
|
||||
fileContent: buffer
|
||||
});
|
||||
return upload.fileID;
|
||||
};
|
||||
`,
|
||||
callFunctionCode: `wx.cloud.callFunction({
|
||||
name: 'quickstartFunctions',
|
||||
data: {
|
||||
type: 'getMiniProgramCode'
|
||||
}
|
||||
}).then((resp) => console.log(resp))`,
|
||||
});
|
||||
},
|
||||
getUploadFileCode: function () {
|
||||
this.setData({
|
||||
callUploadFileCode: `wx.chooseMedia({
|
||||
count: 1,
|
||||
success: (chooseResult) => {
|
||||
// 将图片上传至云存储空间
|
||||
wx.cloud
|
||||
.uploadFile({
|
||||
// 指定上传到的云路径
|
||||
cloudPath: "my-photo.png",
|
||||
// 指定要上传的文件的小程序临时文件路径
|
||||
filePath: chooseResult.tempFiles[0].tempFilePath,
|
||||
})
|
||||
.then((res) => {
|
||||
console.log(res)
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log('e', e)
|
||||
});
|
||||
}
|
||||
});`,
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"usingComponents": {
|
||||
"cloud-tip-modal": "/components/cloudTipModal/index"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,294 @@
|
||||
<!--pages/exampleDetail/index.wxml-->
|
||||
<block wx:if="{{ type === 'getOpenId' }}">
|
||||
<view class="page-container">
|
||||
<view class="title">功能介绍</view>
|
||||
<view class="info">云函数无需维护鉴权机制及登录票据,仅一行代码即可获得。</view>
|
||||
<view class="title">云函数获取OpenId示例</view>
|
||||
<!-- <view class="info">云函数无需维护鉴权机制及登录票据,仅一行代码即可获得。</view> -->
|
||||
<view class="block">
|
||||
<view class="step-title"><text class="step-left">step</text> <text class="step-right">1 </text>quickStartFunctions 云函数代码</view>
|
||||
<view class="code_zone">
|
||||
<rich-text nodes="<pre style='overflow: scroll;'>{{callOpenIdCode}}</pre>" />
|
||||
</view>
|
||||
<view class="step-title"><text class="step-left">step</text> <text class="step-right">2 </text>小程序代码段</view>
|
||||
<view class="code_zone">
|
||||
<rich-text nodes="<pre style='overflow: scroll;'>{{callFunctionCode}}</pre>" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="block">
|
||||
<view class="btn-full" bind:tap="getOpenId" wx:if="{{!haveGetOpenId}}">运行示例</view>
|
||||
<view class="box_text">{{ openId ? openId : 'OpenID将展示在这里' }}</view>
|
||||
<cloud-tip-modal showTipProps="{{showTip}}" title="{{title}}" content="{{content}}"></cloud-tip-modal>
|
||||
<view class="button_clear" bindtap="clearOpenId" wx:if="{{haveGetOpenId}}">清空</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<block wx:if="{{ type === 'getMiniProgramCode' }}">
|
||||
<view class="page-container">
|
||||
<view class="title">功能介绍</view>
|
||||
<view class="info">可通过云函数免接口调用凭证,直接生成小程序码。</view>
|
||||
<view class="title">云函数获取小程序码示例</view>
|
||||
<view class="block">
|
||||
<view class="step-title"><text class="step-left">step</text> <text class="step-right">1 </text>quickStartFunctions 云函数代码</view>
|
||||
<view class="code_zone">
|
||||
<rich-text nodes="<pre style='overflow: scroll;'>{{callMiniProgramCode}}</pre>" />
|
||||
</view>
|
||||
<view class="step-title"><text class="step-left">step</text> <text class="step-right">2 </text>小程序代码段</view>
|
||||
<view class="code_zone">
|
||||
<rich-text nodes="<pre style='overflow: scroll;'>{{callFunctionCode}}</pre>" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="block">
|
||||
<view class="btn-full" bind:tap="getCodeSrc" wx:if="{{!haveGetCodeSrc}}">运行示例</view>
|
||||
<view class="box_text" wx:if="{{!codeSrc}}">小程序码将展示在这里</view>
|
||||
<view wx:if="{{codeSrc}}" class="code_box">
|
||||
<image class="code_img" src="{{codeSrc}}"></image>
|
||||
</view>
|
||||
<view class="button_clear" bindtap="clearCodeSrc" wx:if="{{haveGetCodeSrc}}">清空</view>
|
||||
<cloud-tip-modal showTipProps="{{showTip}}" title="{{title}}" content="{{content}}"></cloud-tip-modal>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<block wx:if="{{ type === 'createCollection' }}">
|
||||
<view class="page-container">
|
||||
<view class="title">功能介绍</view>
|
||||
<view class="info">集合为常用数据库中表的概念。云开发数据库支持自动备份、无损回档,并且QPS高达3千+。</view>
|
||||
<view class="title">如何体验</view>
|
||||
<view class="info">已自动创建名为“sales”的体验合集,可打开“云开发控制台>数据库>记录列表”中找到该集合。</view>
|
||||
<image class="img" src="../../images/database.png"></image>
|
||||
<view class="title">云函数代码示例</view>
|
||||
<view class="code_zone">
|
||||
<rich-text nodes="<pre style='overflow: scroll;'>{{callCreateCollectionCode}}</pre>" />
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<block wx:if="{{ type === 'selectRecord' }}">
|
||||
<view class="page-container">
|
||||
<view class="title">功能介绍</view>
|
||||
<view class="top_tip">体验查询记录能力,查询数据表中的销量数据。</view>
|
||||
<view class="box_text" wx:if="{{!record}}">销量数据将展示在这里</view>
|
||||
<view class="title">数据库操作示例</view>
|
||||
<view class="top_tip">参考云函数 quickstartFunctions 示例代码</view>
|
||||
<view wx:if="{{record}}" class="code_box">
|
||||
<view class="code_box_title">地区销量统计</view>
|
||||
<view class="code_box_record">
|
||||
<view class="code_box_record_title">地域</view>
|
||||
<view class="code_box_record_title">城市</view>
|
||||
<view class="code_box_record_title">销量</view>
|
||||
<view class="code_box_record_title">操作</view>
|
||||
</view>
|
||||
<view class="line"></view>
|
||||
<view class="code_box_record" wx:for="{{record}}" wx:key="_id">
|
||||
<view class="code_box_record_detail">{{item.region}}</view>
|
||||
<view class="code_box_record_detail">{{item.city}}</view>
|
||||
<!-- <view class="code_box_record_detail">{{item.sales}}</view> -->
|
||||
<input style="background-color: rgba(0, 0, 0, 0.03)" class="code_box_record_detail" bindinput="bindInput" data-index="{{index}}" value="{{item.sales}}" type="number"></input>
|
||||
<view class="code_box_record_detail">
|
||||
<button style="font-size: 12px" bind:tap="deleteRecord" data-id="{{item._id}}">删除</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="btn-full" bind:tap="getRecord" >查询记录</view>
|
||||
<view class="btn-full" bind:tap="updateRecord" >更新记录</view>
|
||||
<view class="btn-full" bind:tap="insertRecord" >新增记录</view>
|
||||
<!-- <view class="button_clear" bindtap="clearRecord" wx:if="{{haveGetRecord}}">清空</view> -->
|
||||
<cloud-tip-modal showTipProps="{{showTip}}"></cloud-tip-modal>
|
||||
</view>
|
||||
<view wx:if="{{showInsertModal}}" class="modal-mask">
|
||||
<view class="modal-content">
|
||||
<view class="modal-title">新增销量记录</view>
|
||||
<input class="modal-input" placeholder="地域" value="{{insertRegion}}" bindinput="onInsertRegionInput"/>
|
||||
<input class="modal-input" placeholder="城市" value="{{insertCity}}" bindinput="onInsertCityInput"/>
|
||||
<input class="modal-input" placeholder="销量" value="{{insertSales}}" bindinput="onInsertSalesInput" type="number"/>
|
||||
<view class="modal-actions">
|
||||
<button bindtap="onInsertCancel">取消</button>
|
||||
<button bindtap="onInsertConfirm" type="primary">确认</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<block wx:if="{{ type === 'uploadFile' }}">
|
||||
<view class="page-container">
|
||||
<view class="title">功能介绍</view>
|
||||
<view class="top_tip">多存储类型,仅需一个云函数即可完成上传。</view>
|
||||
<view class="title">文件上传示例</view>
|
||||
<view class="block">
|
||||
<view class="step-title">小程序代码段</view>
|
||||
<view class="code_zone">
|
||||
<rich-text nodes="<pre style='overflow: scroll;'>{{callUploadFileCode}}</pre>" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="btn-full" bind:tap="uploadImg" wx:if="{{!haveGetImgSrc}}">运行示例</view>
|
||||
<view class="box_text" wx:if="{{!imgSrc}}">上传的图片将展示在这里</view>
|
||||
<view wx:if="{{imgSrc}}" class="code_box">
|
||||
<image class="code_img" src="{{imgSrc}}"></image>
|
||||
<!-- <view class="img_info">
|
||||
<view class="img_info_title">文件路径</view>
|
||||
<view class="img_info_detail">{{imgSrc}}</view>
|
||||
</view> -->
|
||||
</view>
|
||||
<view class="button_clear" bindtap="clearImgSrc" wx:if="{{haveGetImgSrc}}">清空</view>
|
||||
<cloud-tip-modal showTipProps="{{showTip}}"></cloud-tip-modal>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<block wx:if="{{ type === 'model-guide'}}">
|
||||
<view class="page-container">
|
||||
<view class="title">功能介绍</view>
|
||||
<view class="top_tip">腾讯云开发提供 AI 对话能力,支持 Agent,大模型流式对话,可通过 Agent-UI 组件快速集成 AI 能力</view>
|
||||
<view class="title">集成 Agent-UI 组件指引</view>
|
||||
<view class="block">
|
||||
<view class="step-title"><text class="step-left">step</text> <text class="step-right">1 </text>拷贝组件源码包</view>
|
||||
<view style="display: flex;align-items: center;">点击复制查看组件仓库地址 <image mode="widthFix" style="width: 20px;height: 20px" bind:tap="copyUrl" src='../../images/copy.svg'/></view>
|
||||
<view class="step-title"><text class="step-left">step</text> <text class="step-right">2 </text>将组件拷贝至小程序目录中</view>
|
||||
<image class="img" mode="widthFix" src="../../images/ai_example2.png"></image>
|
||||
<view class="step-title"><text class="step-left">step</text> <text class="step-right">3 </text>在页面 .json 配置文件中注册组件</view>
|
||||
<view class="code_zone">
|
||||
<rich-text nodes="<pre style='overflow: scroll;'>{{ai_page_config}}</pre>" />
|
||||
</view>
|
||||
<view class="step-title"><text class="step-left">step</text> <text class="step-right">4 </text>在页面 .wxml 文件中引用组件</view>
|
||||
<view class="code_zone">
|
||||
<rich-text nodes="<pre style='overflow: scroll;'>{{ai_wxml_config}}</pre>" />
|
||||
</view>
|
||||
<view class="step-title"><text class="step-left">step</text> <text class="step-right">4 </text>在页面 .js 文件中编写配置</view>
|
||||
<view class="code_zone">
|
||||
<rich-text nodes="<pre style='overflow: scroll;'>{{ai_data_config}}</pre>" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<block wx:if="{{ type === 'cloudbaserun' }}">
|
||||
<view class="page-container">
|
||||
<view class="title">功能介绍</view>
|
||||
<view class="info">云托管 支持托管用任意语言和框架编写的容器化应用,为开发者提供高可用、自动弹性扩缩的云服务。</view>
|
||||
<view class="title">小程序调用云托管示例</view>
|
||||
<view class="block">
|
||||
<view class="step-title"><text class="step-left">step</text> <text class="step-right">1 </text>前往云开发平台开通云托管</view>
|
||||
<view class="step-title"><text class="step-left">step</text> <text class="step-right">2 </text>新建容器型托管服务,等待部署完成</view>
|
||||
<view class="step-text">
|
||||
此处可使用 Express 示例模板进行安装,此处示例命名为 express-test
|
||||
</view>
|
||||
<view>
|
||||
<image class="img" src="../../images/create_cbr.png" mode="aspectFill"></image>
|
||||
</view>
|
||||
<view class="step-title"><text class="step-left">step</text> <text class="step-right">3</text>小程序端调用</view>
|
||||
<view class="code_zone">
|
||||
<rich-text nodes="<pre style='overflow: scroll;'>{{callcbrCode}}</pre>" />
|
||||
</view>
|
||||
<view class="btn-full" bind:tap="runCallContainer" wx:if="{{!haveGetCallContainerRes}}">运行示例</view>
|
||||
<view class="box_text">{{ callContainerResStr ? callContainerResStr : '云托管调用结果将展示在这里' }}</view>
|
||||
<view class="button_clear" bindtap="clearCallContainerRes" wx:if="{{haveGetCallContainerRes}}">清空</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<block wx:if="{{ type === 'ai-assistant' }}">
|
||||
<view class="page-container">
|
||||
<view class="title">AI 智能开发小程序</view>
|
||||
<view class="info">连接 AI 开发工具与 MCP 开发小程序</view>
|
||||
|
||||
<view class="block">
|
||||
<view class="step-title">
|
||||
<text class="step-left">step</text>
|
||||
<text class="step-right">1 </text>
|
||||
打开扩展面板
|
||||
</view>
|
||||
<view class="step-text">
|
||||
在微信开发者工具中使用快捷键打开扩展面板:
|
||||
</view>
|
||||
<view class="notice-box">
|
||||
<view class="notice-text">
|
||||
<text class="notice-highlight">注意:</text>使用快捷键前需先点击编辑区,将焦点从预览区切换到编辑区。
|
||||
</view>
|
||||
</view>
|
||||
<view class="shortcut-box">
|
||||
<view class="shortcut-item">
|
||||
<view class="shortcut-label">Windows/Linux:</view>
|
||||
<view class="shortcut-key">Ctrl + Shift + X</view>
|
||||
</view>
|
||||
<view class="shortcut-item">
|
||||
<view class="shortcut-label">macOS:</view>
|
||||
<view class="shortcut-key">Shift + Command + X</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="step-title">
|
||||
<text class="step-left">step</text>
|
||||
<text class="step-right">2 </text>
|
||||
搜索并安装插件
|
||||
</view>
|
||||
<view class="step-text">
|
||||
在扩展商店中搜索:
|
||||
</view>
|
||||
<view class="plugin-name-box">
|
||||
<text class="plugin-name">微信云开发 AI ToolKit</text>
|
||||
<view class="copy-btn" bindtap="copyPluginName">
|
||||
<image class="copy-icon" src="../../images/copy.svg" mode="widthFix"></image>
|
||||
<text class="copy-text">复制</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="step-text">
|
||||
找到插件后点击安装并启用
|
||||
</view>
|
||||
|
||||
<view class="step-title">
|
||||
<text class="step-left">step</text>
|
||||
<text class="step-right">3 </text>
|
||||
打开 AI 开发功能
|
||||
</view>
|
||||
<view class="step-text">
|
||||
安装完成后,选中任意文件,点击左上角打开 AI 开发功能即可使用
|
||||
</view>
|
||||
<image class="img step-img" src="https://tcb-advanced-a656fc-1257967285.ap-shanghai.app.tcloudbase.com/imgs/wechat-ide-extension/ide-extension.png" mode="widthFix"></image>
|
||||
|
||||
<view class="divider"></view>
|
||||
|
||||
<view class="feature-section">
|
||||
<view class="feature-title">✨ 场景示例</view>
|
||||
<view class="feature-list">
|
||||
<view class="feature-item-with-examples">
|
||||
<view class="feature-main">💡 智能代码生成与补全</view>
|
||||
<view class="feature-examples">
|
||||
<view class="feature-example-wrapper">
|
||||
<text class="feature-example-text">· 帮我创建一个商品列表页面,包含图片、标题、价格和加入购物车按钮</text>
|
||||
<view class="feature-copy-btn" bindtap="copyPrompt" data-prompt="帮我创建一个商品列表页面,包含图片、标题、价格和加入购物车按钮">
|
||||
<image class="feature-copy-icon" src="../../images/copy.svg" mode="widthFix"></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="feature-example-wrapper">
|
||||
<text class="feature-example-text">· 帮我完善这个函数,实现商品搜索功能</text>
|
||||
<view class="feature-copy-btn" bindtap="copyPrompt" data-prompt="帮我完善这个函数,实现商品搜索功能">
|
||||
<image class="feature-copy-icon" src="../../images/copy.svg" mode="widthFix"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="feature-item-with-examples">
|
||||
<view class="feature-main">🔧 代码优化与重构建议</view>
|
||||
<view class="feature-examples">
|
||||
<view class="feature-example-wrapper">
|
||||
<text class="feature-example-text">· 优化这个页面的间隔,提升信息密度</text>
|
||||
<view class="feature-copy-btn" bindtap="copyPrompt" data-prompt="优化这个页面的间隔,提升信息密度">
|
||||
<image class="feature-copy-icon" src="../../images/copy.svg" mode="widthFix"></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="feature-example-wrapper">
|
||||
<text class="feature-example-text">· 完善云函数调用的错误处理代码</text>
|
||||
<view class="feature-copy-btn" bindtap="copyPrompt" data-prompt="完善云函数调用的错误处理代码">
|
||||
<image class="feature-copy-icon" src="../../images/copy.svg" mode="widthFix"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
|
||||
@@ -0,0 +1,393 @@
|
||||
page {
|
||||
background-color: white;
|
||||
padding-bottom: 50px;
|
||||
font-family: PingFang SC;
|
||||
}
|
||||
|
||||
.page-container {
|
||||
padding: 20rpx 40rpx;
|
||||
}
|
||||
|
||||
.tip {
|
||||
font-size: 23rpx;
|
||||
color: rgba(0, 0, 0, 0.5);
|
||||
width: 90%;
|
||||
text-align: center;
|
||||
margin: 30rpx auto 0 auto;
|
||||
}
|
||||
|
||||
.top_tip {
|
||||
font-size: 28rpx;
|
||||
color: rgba(0, 0, 0, 0.5);
|
||||
width: 90%;
|
||||
text-align: left;
|
||||
margin-top: 30rpx;
|
||||
/* margin-left: 20rpx; */
|
||||
}
|
||||
|
||||
.box_text {
|
||||
background-color: white;
|
||||
text-align: center;
|
||||
padding: 300rpx 0;
|
||||
margin-top: 30rpx;
|
||||
color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.button {
|
||||
width: 300rpx;
|
||||
text-align: center;
|
||||
margin: 250rpx auto 0 auto;
|
||||
height: 80rpx;
|
||||
color: white;
|
||||
border-radius: 5px;
|
||||
line-height: 80rpx;
|
||||
background-color: #07c160;
|
||||
}
|
||||
|
||||
.button_clear {
|
||||
width: 300rpx;
|
||||
text-align: center;
|
||||
margin: 0 auto 0 auto;
|
||||
height: 80rpx;
|
||||
color: #07c160;
|
||||
border-radius: 5px;
|
||||
line-height: 80rpx;
|
||||
background-color: rgba(0, 0, 0, 0.03);
|
||||
}
|
||||
|
||||
.line {
|
||||
height: 1rpx;
|
||||
width: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.code_box {
|
||||
text-align: center;
|
||||
background-color: white;
|
||||
margin-top: 30rpx;
|
||||
padding: 17rpx;
|
||||
}
|
||||
|
||||
.code_box_title {
|
||||
color: rgba(0, 0, 0, 0.5);
|
||||
font-size: 26rpx;
|
||||
margin-bottom: 20rpx;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.code_box_record {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.code_box_record_title {
|
||||
width: 33%;
|
||||
font-size: 26rpx;
|
||||
color: rgba(0, 0, 0, 0.5);
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
|
||||
.code_box_record_detail {
|
||||
width: 25%;
|
||||
font-size: 26rpx;
|
||||
padding: 20rpx 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-top: 16px;
|
||||
margin-bottom: 8px;
|
||||
font-size: 36rpx;
|
||||
font-weight: 500;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.info {
|
||||
margin-top: 12px;
|
||||
font-size: 28rpx;
|
||||
font-weight: 400;
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
line-height: 52rpx;
|
||||
}
|
||||
|
||||
.img {
|
||||
/* margin-top: 16px; */
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.step-img {
|
||||
margin-top: 20rpx;
|
||||
border-radius: 12rpx;
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.code_img {
|
||||
width: 360rpx;
|
||||
height: 360rpx;
|
||||
}
|
||||
|
||||
.block {
|
||||
font-size: 16px;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
.step-left {
|
||||
color: #FFF;
|
||||
background-color: #1aad19;
|
||||
border: #1aad19 solid 1px;
|
||||
padding: 0px 6px;
|
||||
}
|
||||
|
||||
.step-right {
|
||||
color: #1aad19;
|
||||
background-color: #FFF;
|
||||
border: #1aad19 solid 1px;
|
||||
padding: 0px 6px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.code_zone {
|
||||
background-color: #0E190E;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
border-radius: 12rpx;
|
||||
padding: 16rpx 32rpx;
|
||||
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
|
||||
position: relative;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.btn-full {
|
||||
height: 40px;
|
||||
border-radius: 4px;
|
||||
line-height: 40px;
|
||||
color: #fff;
|
||||
background-color: #1aad19;
|
||||
text-align: center;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.step-title {
|
||||
line-height: 37px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.step-text{
|
||||
font-size: 14px;
|
||||
line-height: 24px;
|
||||
padding: 10px 0px;
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
.modal-mask {
|
||||
position: fixed; left: 0; top: 0; right: 0; bottom: 0;
|
||||
background: rgba(0,0,0,0.3); z-index: 1000; display: flex; align-items: center; justify-content: center;
|
||||
}
|
||||
.modal-content {
|
||||
background: #fff; padding: 24px; border-radius: 8px; width: 80%;
|
||||
}
|
||||
.modal-title { font-size: 18px; margin-bottom: 16px; }
|
||||
.modal-input { margin-bottom: 12px; border: 1px solid #eee; padding: 8px; border-radius: 4px; width: 100%; }
|
||||
.modal-actions { display: flex; justify-content: flex-end; gap: 12px; }
|
||||
|
||||
/* AI助手相关样式 */
|
||||
.notice-box {
|
||||
background: linear-gradient(135deg, #fff8e6 0%, #fff3d9 100%);
|
||||
border-left: 4rpx solid #ff9800;
|
||||
border-radius: 8rpx;
|
||||
padding: 20rpx 24rpx;
|
||||
margin: 20rpx 0;
|
||||
box-shadow: 0 2rpx 8rpx rgba(255, 152, 0, 0.1);
|
||||
}
|
||||
|
||||
.notice-text {
|
||||
font-size: 26rpx;
|
||||
color: rgba(0, 0, 0, 0.75);
|
||||
line-height: 40rpx;
|
||||
}
|
||||
|
||||
.notice-highlight {
|
||||
color: #ff6f00;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.shortcut-box {
|
||||
background-color: rgba(0, 0, 0, 0.03);
|
||||
border-radius: 8rpx;
|
||||
padding: 24rpx;
|
||||
margin: 20rpx 0;
|
||||
}
|
||||
|
||||
.shortcut-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.shortcut-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.shortcut-label {
|
||||
font-size: 28rpx;
|
||||
color: rgba(0, 0, 0, 0.7);
|
||||
width: 240rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.shortcut-key {
|
||||
font-size: 28rpx;
|
||||
color: #1aad19;
|
||||
font-weight: 500;
|
||||
background-color: rgba(26, 173, 25, 0.1);
|
||||
padding: 4rpx 12rpx;
|
||||
border-radius: 4rpx;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.plugin-name-box {
|
||||
background-color: rgba(26, 173, 25, 0.05);
|
||||
border-left: 4rpx solid #1aad19;
|
||||
padding: 20rpx;
|
||||
margin: 20rpx 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.plugin-name {
|
||||
font-size: 32rpx;
|
||||
color: #1aad19;
|
||||
font-weight: 500;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.copy-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 6rpx 16rpx;
|
||||
background-color: rgba(26, 173, 25, 0.1);
|
||||
border: 1rpx solid rgba(26, 173, 25, 0.3);
|
||||
border-radius: 8rpx;
|
||||
margin-left: 20rpx;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.copy-btn:active {
|
||||
background-color: rgba(26, 173, 25, 0.2);
|
||||
}
|
||||
|
||||
.copy-icon {
|
||||
width: 24rpx;
|
||||
height: 24rpx;
|
||||
margin-right: 6rpx;
|
||||
filter: invert(52%) sepia(73%) saturate(2034%) hue-rotate(90deg) brightness(92%) contrast(84%);
|
||||
}
|
||||
|
||||
.copy-text {
|
||||
font-size: 24rpx;
|
||||
color: #1aad19;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.divider {
|
||||
height: 1rpx;
|
||||
width: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
margin: 40rpx 0;
|
||||
}
|
||||
|
||||
.feature-section {
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.feature-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.feature-list {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.feature-item {
|
||||
font-size: 28rpx;
|
||||
color: rgba(0, 0, 0, 0.65);
|
||||
line-height: 48rpx;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
/* 带示例的功能项 */
|
||||
.feature-item-with-examples {
|
||||
margin-bottom: 20rpx;
|
||||
padding: 20rpx;
|
||||
background-color: rgba(0, 0, 0, 0.02);
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.feature-item-with-examples:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.feature-main {
|
||||
font-size: 30rpx;
|
||||
font-weight: 500;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
margin-bottom: 12rpx;
|
||||
padding-bottom: 8rpx;
|
||||
border-bottom: 1rpx solid rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.feature-examples {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.feature-example {
|
||||
font-size: 26rpx;
|
||||
color: rgba(0, 0, 0, 0.55);
|
||||
line-height: 44rpx;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.feature-example-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 4rpx;
|
||||
padding: 8rpx 12rpx;
|
||||
}
|
||||
|
||||
.feature-example-text {
|
||||
flex: 1;
|
||||
font-size: 26rpx;
|
||||
color: rgba(0, 0, 0, 0.55);
|
||||
line-height: 40rpx;
|
||||
}
|
||||
|
||||
.feature-copy-btn {
|
||||
padding: 12rpx;
|
||||
border-radius: 8rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-left: 12rpx;
|
||||
flex-shrink: 0;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.feature-copy-btn:active {
|
||||
background-color: rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.feature-copy-icon {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
opacity: 0.5;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
|
||||
.feature-copy-btn:active .feature-copy-icon {
|
||||
opacity: 0.8;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
const api = require('../../utils/api')
|
||||
Page({data:{activities:[],exhibitions:[],tags:[],exhibitionIndex:0,selectedTag:'',time:'available',loading:true},onLoad(){this.loadMeta()},onShow(){if(this.data.exhibitions.length)this.loadActivities()},onPullDownRefresh(){this.loadActivities().finally(wx.stopPullDownRefresh)},async loadMeta(){try{const data=await api.request('/api/activities/meta');this.setData({exhibitions:[{id:'',name:'全部会展'}].concat(data.exhibitions),tags:data.tags});await this.loadActivities()}catch(e){this.fail(e)}},async loadActivities(){this.setData({loading:true});const exhibition=this.data.exhibitions[this.data.exhibitionIndex];const qs=[`time=${this.data.time}`];if(exhibition&&exhibition.id)qs.push(`exhibitionId=${exhibition.id}`);if(this.data.selectedTag)qs.push(`tagId=${this.data.selectedTag}`);try{const activities=await api.request(`/api/activities?${qs.join('&')}`);this.setData({activities,loading:false})}catch(e){this.fail(e)}},changeExhibition(e){this.setData({exhibitionIndex:Number(e.detail.value)});this.loadActivities()},selectTag(e){this.setData({selectedTag:this.data.selectedTag===e.currentTarget.dataset.id?'':e.currentTarget.dataset.id});this.loadActivities()},setTime(e){this.setData({time:e.currentTarget.dataset.value});this.loadActivities()},open(e){wx.navigateTo({url:`/pages/activity/index?id=${e.currentTarget.dataset.id}`})},fail(e){this.setData({loading:false});wx.showToast({title:e.message||'加载失败',icon:'none'})}})
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"navigationBarTitleText": "活动广场",
|
||||
"enablePullDownRefresh": true,
|
||||
"backgroundColor": "#f5f1ea"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<view class="page safe"><view class="hero"><text class="eyebrow">MEET · TALK · CONNECT</text><view class="headline">下一场好对话,\n从这里开始</view><text class="intro">发现会展期间值得加入的活动和有趣的人</text></view><view class="filters"><picker mode="selector" range="{{exhibitions}}" range-key="name" value="{{exhibitionIndex}}" bindchange="changeExhibition"><view class="select">{{exhibitions[exhibitionIndex].name || '全部会展'}}⌄</view></picker><view class="time-switch"><view class="{{time==='upcoming'?'on':''}}" data-value="upcoming" bindtap="setTime">未开始</view><view class="{{time==='available'?'on':''}}" data-value="available" bindtap="setTime">可参加</view></view></view><scroll-view scroll-x class="tags" enable-flex><view class="tag-pill {{!selectedTag?'active':''}}" data-id="" bindtap="selectTag">全部</view><view wx:for="{{tags}}" wx:key="id" class="tag-pill {{selectedTag===item.id?'active':''}}" data-id="{{item.id}}" bindtap="selectTag">{{item.name}}</view></scroll-view><view wx:if="{{loading}}" class="empty">正在寻找好活动…</view><view wx:elif="{{!activities.length}}" class="empty">这个筛选下暂时没有活动</view><view class="feed"><view wx:for="{{activities}}" wx:key="id" class="activity card" data-id="{{item.id}}" bindtap="open"><image wx:if="{{item.images[0]}}" class="cover" src="{{item.images[0].url}}" mode="aspectFill"></image><view wx:else class="cover placeholder">CoffeeChat</view><view class="body"><view class="date">{{item.status==='active'?'正在进行':'即将开始'}} · {{item.startsAt}}</view><view class="title">{{item.title}}</view><view class="expo">{{item.exhibition.name}} · {{item.location || item.exhibition.venue}}</view><view class="tag-row"><text wx:for="{{item.tags}}" wx:key="id" class="tag">{{item.name}}</text><text class="people">{{item.participantCount}} 人参加</text></view></view></view></view></view>
|
||||
@@ -0,0 +1 @@
|
||||
.hero{padding:36rpx 6rpx 42rpx}.eyebrow{font-size:20rpx;letter-spacing:5rpx;color:#8e6c55}.headline{white-space:pre-line;font-family:serif;font-weight:700;font-size:64rpx;line-height:1.13;margin:16rpx 0}.intro{color:#7a6e63;font-size:27rpx}.filters{display:flex;justify-content:space-between;align-items:center;margin-bottom:22rpx}.select{padding:18rpx 24rpx;background:#fffdf9;border-radius:999rpx;font-size:25rpx;max-width:320rpx;overflow:hidden;white-space:nowrap}.time-switch{display:flex;padding:5rpx;background:#e5ddd3;border-radius:999rpx}.time-switch view{padding:13rpx 20rpx;font-size:23rpx;color:#74665b;border-radius:999rpx}.time-switch .on{background:#2e5b47;color:#fff}.tags{white-space:nowrap;margin-bottom:30rpx}.tag-pill{display:inline-block;padding:13rpx 25rpx;border:1rpx solid #d9ccbd;border-radius:999rpx;margin-right:12rpx;color:#756558;font-size:24rpx}.tag-pill.active{background:#8b6248;border-color:#8b6248;color:white}.feed{display:flex;flex-direction:column;gap:26rpx}.activity{overflow:hidden}.cover{width:100%;height:370rpx;display:block}.placeholder{display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,#315c49,#9d7256);color:white;font:italic 52rpx serif;letter-spacing:3rpx}.body{padding:26rpx}.date{font-size:22rpx;color:#a15f3c}.title{font-size:36rpx;font-weight:700;margin:12rpx 0}.expo{color:#75685d;font-size:25rpx}.tag-row{display:flex;align-items:center;margin-top:22rpx}.people{font-size:23rpx;color:#7f7165;margin-left:auto}
|
||||
@@ -0,0 +1 @@
|
||||
Page({retry(){getApp().login().then(()=>wx.switchTab({url:'/pages/index/index'})).catch(e=>wx.showToast({title:e.message,icon:'none'}))}})
|
||||
@@ -0,0 +1 @@
|
||||
{"navigationBarTitleText":"登录"}
|
||||
@@ -0,0 +1 @@
|
||||
<view class="page login"><view class="mark">CoffeeChat</view><view class="title">与值得认识的人,聊杯咖啡</view><text>微信登录仅用于识别你的活动身份</text><button class="primary" bindtap="retry">微信登录</button></view>
|
||||
@@ -0,0 +1 @@
|
||||
.login{padding:180rpx 60rpx;text-align:center}.mark{font:italic 34rpx serif;color:#9b7256}.title{font:700 58rpx/1.3 serif;margin:50rpx 0 24rpx}.login text{color:#817367}.login button{margin-top:70rpx}
|
||||
@@ -0,0 +1 @@
|
||||
const api=require('../../utils/api');const app=getApp();Page({data:{user:null,editing:false,nickname:''},onShow(){app.ensureLogin().then(user=>this.setData({user,nickname:user.nickname})).catch(()=>{})},edit(){this.setData({editing:true})},input(e){this.setData({nickname:e.detail.value})},cancel(){this.setData({editing:false})},async save(){try{const user=await api.request('/api/auth/me',{method:'PATCH',data:{nickname:this.data.nickname,avatarUrl:this.data.user.avatarUrl||''}});wx.setStorageSync('user',user);app.globalData.user=user;this.setData({user,editing:false});wx.showToast({title:'已保存'})}catch(e){wx.showToast({title:e.message,icon:'none'})}},chooseAvatar(e){const avatarUrl=e.detail.avatarUrl;this.setData({'user.avatarUrl':avatarUrl});api.upload(avatarUrl).then(file=>this.setData({'user.avatarUrl':file.url}))}})
|
||||
@@ -0,0 +1 @@
|
||||
{"navigationBarTitleText":"我的","backgroundColor":"#f5f1ea"}
|
||||
@@ -0,0 +1 @@
|
||||
<view class="page safe"><view class="profile card"><button class="avatar-btn" open-type="chooseAvatar" bindchooseavatar="chooseAvatar"><image src="{{user.avatarUrl || '/images/avatar.png'}}"></image></button><view wx:if="{{!editing}}"><view class="name">{{user.nickname || '微信用户'}}</view><text class="muted">CoffeeChat 参与者</text><button class="secondary small" bindtap="edit">编辑资料</button></view><view wx:else class="edit"><input value="{{nickname}}" bindinput="input" placeholder="你的昵称"><view><button class="primary small" bindtap="save">保存</button><button class="small" bindtap="cancel">取消</button></view></view></view><view class="about"><text class="eyebrow">ABOUT</text><view>在会展里找到真正想聊的人。</view><text class="muted">加入活动前写下你的目的,让现场的每次开场更自然。</text></view></view>
|
||||
@@ -0,0 +1 @@
|
||||
.profile{margin-top:30rpx;padding:36rpx;display:flex;gap:28rpx;align-items:center}.avatar-btn{padding:0;width:132rpx;height:132rpx;border-radius:50%;overflow:hidden;flex:none}.avatar-btn image{width:100%;height:100%}.name{font-size:40rpx;font-weight:700;margin-bottom:8rpx}.small{font-size:24rpx;padding:8rpx 22rpx;margin:18rpx 8rpx 0 0;display:inline-block;line-height:1.8}.edit input{background:#f2ece5;border-radius:12rpx;padding:16rpx}.about{margin:70rpx 10rpx}.about view{font:700 46rpx/1.3 serif;margin:16rpx 0}.about .muted{line-height:1.7}.eyebrow{font-size:20rpx;letter-spacing:4rpx;color:#9b7256}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
|
||||
"rules": [{
|
||||
"action": "allow",
|
||||
"page": "*"
|
||||
}]
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
const { apiBaseUrl } = require('../config')
|
||||
function request(path, options = {}) { return new Promise((resolve, reject) => wx.request({ url: apiBaseUrl + path, method: options.method || 'GET', data: options.data, header: { 'content-type': 'application/json', Authorization: `Bearer ${wx.getStorageSync('token') || ''}` }, success: (res) => res.statusCode >= 200 && res.statusCode < 300 ? resolve(res.data) : reject(new Error(res.data && res.data.error || '网络请求失败')), fail: reject })) }
|
||||
function upload(filePath) { return new Promise((resolve, reject) => wx.uploadFile({ url: apiBaseUrl + '/api/uploads', filePath, name: 'files', header: { Authorization: `Bearer ${wx.getStorageSync('token') || ''}` }, success: (res) => { const data = JSON.parse(res.data || '{}'); res.statusCode < 300 ? resolve(data.files[0]) : reject(new Error(data.error || '上传失败')) }, fail: reject })) }
|
||||
module.exports = { request, upload, apiBaseUrl }
|
||||