@ -0,0 +1,14 @@
|
||||
# Windows
|
||||
[Dd]esktop.ini
|
||||
Thumbs.db
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
|
||||
# Node.js
|
||||
node_modules/
|
||||
@ -0,0 +1,12 @@
|
||||
# 云开发 quickstart
|
||||
|
||||
这是云开发的快速启动指引,其中演示了如何上手使用云开发的三大基础能力:
|
||||
|
||||
- 数据库:一个既可在小程序前端操作,也能在云函数中读写的 JSON 文档型数据库
|
||||
- 文件存储:在小程序前端直接上传/下载云端文件,在云开发控制台可视化管理
|
||||
- 云函数:在云端运行的代码,微信私有协议天然鉴权,开发者只需编写业务逻辑代码
|
||||
|
||||
## 参考文档
|
||||
|
||||
- [云开发文档](https://developers.weixin.qq.com/miniprogram/dev/wxcloud/basis/getting-started.html)
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
{
|
||||
"permissions": {
|
||||
"openapi": [
|
||||
"wxacode.get"
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "quickstartFunctions",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"wx-server-sdk": "~2.4.0"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 53 KiB |
@ -0,0 +1,41 @@
|
||||
{
|
||||
"pages": [
|
||||
"pages/index/index",
|
||||
"pages/logs/logs",
|
||||
"pages/register/register",
|
||||
"pages/interests/interests",
|
||||
"pages/main/main",
|
||||
"pages/pricing/pricing",
|
||||
"pages/publish/publish",
|
||||
"pages/buy/buy",
|
||||
"pages/purchase/purchase",
|
||||
"pages/profile/profile"
|
||||
],
|
||||
"window": {
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarTitleText": "校园二手交易",
|
||||
"navigationBarBackgroundColor": "#f5f5f5",
|
||||
"backgroundColor": "#f5f5f5"
|
||||
},
|
||||
"requiredPrivateInfos": [
|
||||
"chooseAddress",
|
||||
"chooseLocation",
|
||||
"choosePoi",
|
||||
"getLocation",
|
||||
"onLocationChange",
|
||||
"startLocationUpdate",
|
||||
"startLocationUpdateBackground"
|
||||
],
|
||||
"requiredBackgroundModes": [
|
||||
"location"
|
||||
],
|
||||
"permission": {
|
||||
"scope.userLocation": {
|
||||
"desc": "你的位置信息将用于小程序位置接口的效果展示"
|
||||
}
|
||||
},
|
||||
"style": "v2",
|
||||
"componentFramework": "glass-easel",
|
||||
"sitemapLocation": "sitemap.json",
|
||||
"lazyCodeLoading": "requiredComponents"
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
/**app.wxss**/
|
||||
/* 全局样式重置 */
|
||||
page {
|
||||
height: 100%;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
/* 容器样式 */
|
||||
/**app.wxss**/
|
||||
.container {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 200rpx 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
|
||||
/* 通用文本样式 */
|
||||
text {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', SimSun, sans-serif;
|
||||
}
|
||||
|
||||
/* 通用按钮样式 */
|
||||
button {
|
||||
border-radius: 8rpx;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
button::after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* 通用输入框样式 */
|
||||
input {
|
||||
font-size: 32rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* 通用图片样式 */
|
||||
image {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* 通用滚动条样式 */
|
||||
::-webkit-scrollbar {
|
||||
width: 0;
|
||||
height: 0;
|
||||
color: transparent;
|
||||
}
|
||||
@ -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,6 @@
|
||||
const envList = [];
|
||||
const isMac = false;
|
||||
module.exports = {
|
||||
envList,
|
||||
isMac
|
||||
};
|
||||
|
After Width: | Height: | Size: 898 KiB |
|
After Width: | Height: | Size: 898 KiB |
|
After Width: | Height: | Size: 898 KiB |
|
After Width: | Height: | Size: 319 KiB |
|
After Width: | Height: | Size: 320 KiB |
|
After Width: | Height: | Size: 147 KiB |
|
After Width: | Height: | Size: 893 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 8.4 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 11 KiB |
@ -0,0 +1,8 @@
|
||||
{
|
||||
"usingComponents": {},
|
||||
"navigationBarTitleText": "商品购买",
|
||||
"navigationBarBackgroundColor": "#4285F4",
|
||||
"navigationBarTextStyle": "black",
|
||||
"enablePullDownRefresh": true,
|
||||
"backgroundTextStyle": "dark"
|
||||
}
|
||||
@ -0,0 +1,166 @@
|
||||
<!-- 商品购买页面 -->
|
||||
<view class="container">
|
||||
<!-- 搜索栏 -->
|
||||
<view class="search-bar">
|
||||
<view class="search-input">
|
||||
<icon type="search" size="30" class="search-icon"></icon>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="搜索商品名称、类别..."
|
||||
bindinput="onSearchInput"
|
||||
value="{{searchKeyword}}"
|
||||
class="search-field"
|
||||
/>
|
||||
<view class="search-cancel" bindtap="onClearSearch" wx:if="{{searchKeyword}}">
|
||||
<text>取消</text>
|
||||
</view>
|
||||
<button class="search-btn" bindtap="onSearch">搜索</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 分类导航 -->
|
||||
<view class="category-nav">
|
||||
<view
|
||||
class="category-item {{selectedCategoryIndex === index ? 'active' : ''}}"
|
||||
wx:for="{{categoryNavItems}}"
|
||||
wx:key="id"
|
||||
bindtap="onCategoryNavTap"
|
||||
data-index="{{index}}"
|
||||
>
|
||||
<text class="category-text">{{item.name}}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 筛选条件 -->
|
||||
<view class="filter-bar">
|
||||
<picker
|
||||
range="{{categories}}"
|
||||
value="{{selectedCategory}}"
|
||||
bindchange="onCategoryChange"
|
||||
class="filter-item"
|
||||
>
|
||||
<view class="filter-display">
|
||||
<text>{{categories[selectedCategory] || '全部分类'}}</text>
|
||||
<icon type="arrow-down" size="12"></icon>
|
||||
</view>
|
||||
</picker>
|
||||
|
||||
<picker
|
||||
range="{{priceRanges}}"
|
||||
value="{{selectedPriceRange}}"
|
||||
bindchange="onPriceRangeChange"
|
||||
class="filter-item"
|
||||
>
|
||||
<view class="filter-display">
|
||||
<text>{{priceRanges[selectedPriceRange] || '价格范围'}}</text>
|
||||
<icon type="arrow-down" size="12"></icon>
|
||||
</view>
|
||||
</picker>
|
||||
|
||||
<view class="filter-item" bindtap="onSortChange">
|
||||
<view class="filter-display">
|
||||
<text>{{sortOptions[selectedSort]}}</text>
|
||||
<icon type="arrow-down" size="12"></icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 商品列表 -->
|
||||
<scroll-view
|
||||
class="product-list"
|
||||
scroll-y
|
||||
bindscrolltolower="onReachBottom"
|
||||
refresher-enabled="true"
|
||||
bindrefresherrefresh="onRefresh"
|
||||
refresher-triggered="{{refreshing}}"
|
||||
>
|
||||
<!-- 商品网格容器 -->
|
||||
<view class="product-grid">
|
||||
<!-- 商品卡片 -->
|
||||
<view
|
||||
class="product-card"
|
||||
wx:for="{{filteredProducts}}"
|
||||
wx:key="id"
|
||||
bindtap="onProductTap"
|
||||
data-product="{{item}}"
|
||||
>
|
||||
<!-- 商品图片 -->
|
||||
<view class="product-image-container">
|
||||
<image
|
||||
src="{{item.image}}"
|
||||
mode="aspectFill"
|
||||
class="product-image"
|
||||
/>
|
||||
<view class="product-status" wx:if="{{item.status === 'sold'}}">
|
||||
<text>已售出</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 商品信息 -->
|
||||
<view class="product-info">
|
||||
<!-- 卖家信息 -->
|
||||
<view class="seller-info">
|
||||
<image
|
||||
src="{{item.sellerAvatar}}"
|
||||
mode="aspectFill"
|
||||
class="seller-avatar"
|
||||
/>
|
||||
<text class="seller-name">{{item.sellerName}}</text>
|
||||
<view class="seller-rating" wx:if="{{item.sellerRating}}">
|
||||
<text class="rating-text">{{item.sellerRating}}</text>
|
||||
<icon type="star" size="12" class="star-icon"></icon>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 商品标题 -->
|
||||
<view class="product-title">
|
||||
<text class="title-text">{{item.name}}</text>
|
||||
</view>
|
||||
|
||||
<!-- 商品描述 -->
|
||||
<view class="product-description">
|
||||
<text class="description-text">{{item.description}}</text>
|
||||
</view>
|
||||
|
||||
<!-- 价格信息 -->
|
||||
<view class="price-info">
|
||||
<text class="current-price">¥{{item.price}}</text>
|
||||
<text class="original-price" wx:if="{{item.originalPrice}}">¥{{item.originalPrice}}</text>
|
||||
<view class="discount-badge" wx:if="{{item.discount}}">
|
||||
<text>{{item.discount}}折</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 商品标签 -->
|
||||
<view class="product-tags">
|
||||
<text class="tag category-tag">{{item.category}}</text>
|
||||
<text class="tag condition-tag">{{item.condition}}</text>
|
||||
<text class="tag location-tag">{{item.location}}</text>
|
||||
</view>
|
||||
|
||||
<!-- 发布时间 -->
|
||||
<view class="publish-time">
|
||||
<text class="time-text">{{item.publishTime}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载更多 -->
|
||||
<view class="load-more" wx:if="{{hasMore}}">
|
||||
<text>加载中...</text>
|
||||
</view>
|
||||
|
||||
<!-- 没有更多数据 -->
|
||||
<view class="no-more" wx:if="{{!hasMore && filteredProducts.length > 0}}">
|
||||
<text>没有更多商品了</text>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<view class="empty-state" wx:if="{{filteredProducts.length === 0}}">
|
||||
<image src="/images/empty-product.png" class="empty-image" />
|
||||
<text class="empty-text">暂无商品</text>
|
||||
<text class="empty-subtext">换个筛选条件试试</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
@ -0,0 +1,349 @@
|
||||
/* 商品购买页面样式 */
|
||||
.container {
|
||||
height: 100vh;
|
||||
background-color: #f5f5f5;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
/* 搜索栏样式 */
|
||||
.search-bar {
|
||||
padding: 0;
|
||||
background-color: #fff;
|
||||
border-bottom: 1rpx solid #e0e0e0;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 0;
|
||||
padding: 20rpx;
|
||||
height: 100rpx;
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
margin-right: 20rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.search-field {
|
||||
flex: 1;
|
||||
font-size: 32rpx;
|
||||
color: #333;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
}
|
||||
|
||||
.search-cancel {
|
||||
padding: 10rpx 20rpx;
|
||||
background-color: #e9ecef;
|
||||
border-radius: 30rpx;
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-right: 20rpx;
|
||||
height: 60rpx;
|
||||
line-height: 40rpx;
|
||||
}
|
||||
|
||||
.search-btn {
|
||||
background-color: #007bff;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 30rpx;
|
||||
padding: 10rpx 30rpx;
|
||||
font-size: 28rpx;
|
||||
line-height: 1;
|
||||
margin-left: 20rpx;
|
||||
height: 60rpx;
|
||||
min-width: 120rpx;
|
||||
}
|
||||
|
||||
/* 分类导航 */
|
||||
.category-nav {
|
||||
display: flex;
|
||||
white-space: nowrap;
|
||||
padding: 24rpx 30rpx;
|
||||
background-color: #fff;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.category-item {
|
||||
padding: 12rpx 32rpx;
|
||||
margin-right: 20rpx;
|
||||
border-radius: 40rpx;
|
||||
background-color: #f8f9fa;
|
||||
border: 1rpx solid #e9ecef;
|
||||
font-size: 28rpx;
|
||||
color: #6c757d;
|
||||
transition: all 0.3s ease;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.category-item.active {
|
||||
background-color: #007bff;
|
||||
border-color: #007bff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.category-text {
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 筛选栏样式 */
|
||||
.filter-bar {
|
||||
display: flex;
|
||||
background-color: #fff;
|
||||
border-bottom: 1rpx solid #e0e0e0;
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.filter-item {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.filter-display {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* 商品列表样式 */
|
||||
.product-list {
|
||||
height: calc(100vh - 180rpx);
|
||||
}
|
||||
|
||||
/* 商品网格容器 */
|
||||
.product-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding: 10rpx;
|
||||
gap: 10rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 商品卡片样式 */
|
||||
.product-card {
|
||||
width: calc(50% - 8rpx);
|
||||
background-color: #fff;
|
||||
border-radius: 8rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
margin-bottom: 10rpx;
|
||||
box-sizing: border-box;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.product-image-container {
|
||||
position: relative;
|
||||
height: 200rpx;
|
||||
}
|
||||
|
||||
.product-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.product-status {
|
||||
position: absolute;
|
||||
top: 10rpx;
|
||||
right: 10rpx;
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
color: #fff;
|
||||
padding: 4rpx 8rpx;
|
||||
border-radius: 10rpx;
|
||||
font-size: 18rpx;
|
||||
}
|
||||
|
||||
/* 商品信息样式 */
|
||||
.product-info {
|
||||
padding: 15rpx;
|
||||
}
|
||||
|
||||
/* 卖家信息样式 */
|
||||
.seller-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.seller-avatar {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
border-radius: 50%;
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
.seller-name {
|
||||
font-size: 22rpx;
|
||||
color: #666;
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
.seller-rating {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #fff8e1;
|
||||
padding: 2rpx 6rpx;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.rating-text {
|
||||
font-size: 18rpx;
|
||||
color: #ff9800;
|
||||
margin-right: 3rpx;
|
||||
}
|
||||
|
||||
.star-icon {
|
||||
color: #ff9800;
|
||||
font-size: 16rpx;
|
||||
}
|
||||
|
||||
/* 商品标题样式 */
|
||||
.product-title {
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.title-text {
|
||||
font-size: 26rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
line-height: 1.3;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 商品描述样式 */
|
||||
.product-description {
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.description-text {
|
||||
font-size: 22rpx;
|
||||
color: #666;
|
||||
line-height: 1.4;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 价格信息样式 */
|
||||
.price-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.current-price {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: #ff4444;
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
.original-price {
|
||||
font-size: 20rpx;
|
||||
color: #999;
|
||||
text-decoration: line-through;
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
.discount-badge {
|
||||
background-color: #ff4444;
|
||||
color: #fff;
|
||||
padding: 2rpx 6rpx;
|
||||
border-radius: 6rpx;
|
||||
font-size: 18rpx;
|
||||
}
|
||||
|
||||
/* 商品标签样式 */
|
||||
.product-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.tag {
|
||||
font-size: 18rpx;
|
||||
padding: 2rpx 6rpx;
|
||||
border-radius: 6rpx;
|
||||
margin-right: 6rpx;
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
|
||||
.category-tag {
|
||||
background-color: #e3f2fd;
|
||||
color: #1976d2;
|
||||
}
|
||||
|
||||
.condition-tag {
|
||||
background-color: #f3e5f5;
|
||||
color: #7b1fa2;
|
||||
}
|
||||
|
||||
.location-tag {
|
||||
background-color: #e8f5e8;
|
||||
color: #388e3c;
|
||||
}
|
||||
|
||||
/* 发布时间样式 */
|
||||
.publish-time {
|
||||
font-size: 18rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* 加载更多样式 */
|
||||
.load-more, .no-more {
|
||||
text-align: center;
|
||||
padding: 40rpx;
|
||||
font-size: 26rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* 空状态样式 */
|
||||
.empty-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 100rpx 40rpx;
|
||||
}
|
||||
|
||||
.empty-image {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 32rpx;
|
||||
color: #666;
|
||||
margin-bottom: 15rpx;
|
||||
}
|
||||
|
||||
.empty-subtext {
|
||||
font-size: 26rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* 响应式调整 */
|
||||
@media (max-width: 750rpx) {
|
||||
.product-card {
|
||||
margin: 15rpx;
|
||||
}
|
||||
|
||||
.product-info {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.product-image-container {
|
||||
height: 250rpx;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,223 @@
|
||||
// index.js
|
||||
Page({
|
||||
data: {
|
||||
studentId: '',
|
||||
password: '',
|
||||
isLoginDisabled: false
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
// 检查本地存储中是否有登录信息
|
||||
this.checkLoginStatus();
|
||||
},
|
||||
|
||||
// 检查登录状态
|
||||
checkLoginStatus() {
|
||||
const token = wx.getStorageSync('token');
|
||||
const userInfo = wx.getStorageSync('userInfo');
|
||||
|
||||
if (token && userInfo) {
|
||||
// 如果已登录,跳转到主页面
|
||||
wx.redirectTo({
|
||||
url: '/pages/main/main'
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 学号/手机号输入处理
|
||||
onInputStudentId(e) {
|
||||
const studentId = e.detail.value.trim();
|
||||
this.setData({
|
||||
studentId: studentId
|
||||
});
|
||||
this.checkLoginButton();
|
||||
},
|
||||
|
||||
// 密码输入处理
|
||||
onInputPassword(e) {
|
||||
const password = e.detail.value.trim();
|
||||
this.setData({
|
||||
password: password
|
||||
});
|
||||
this.checkLoginButton();
|
||||
},
|
||||
|
||||
// 检查登录按钮状态
|
||||
checkLoginButton() {
|
||||
// 按钮始终保持可用状态
|
||||
this.setData({
|
||||
isLoginDisabled: false
|
||||
});
|
||||
},
|
||||
|
||||
// 登录处理
|
||||
onLogin() {
|
||||
const { studentId, password } = this.data;
|
||||
|
||||
// 简单的前端验证
|
||||
if (!this.validateInput(studentId, password)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 显示加载中
|
||||
wx.showLoading({
|
||||
title: '登录中...',
|
||||
mask: true
|
||||
});
|
||||
|
||||
// 调用云数据库进行真实登录验证
|
||||
this.realLogin(studentId, password);
|
||||
},
|
||||
|
||||
// 输入验证
|
||||
validateInput(studentId, password) {
|
||||
if (!studentId) {
|
||||
wx.showToast({
|
||||
title: '请输入学号或手机号',
|
||||
icon: 'none'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!password) {
|
||||
wx.showToast({
|
||||
title: '请输入密码',
|
||||
icon: 'none'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
if (password.length < 6) {
|
||||
wx.showToast({
|
||||
title: '密码长度不能少于6位',
|
||||
icon: 'none'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
// 真实登录验证(查询云数据库)
|
||||
realLogin(loginId, password) {
|
||||
const db = wx.cloud.database();
|
||||
|
||||
// 查询数据库中的T_user表
|
||||
db.collection('T_user').where({
|
||||
$or: [
|
||||
{ phone: loginId }, // 手机号匹配
|
||||
{ sno: loginId } // 学号匹配
|
||||
],
|
||||
password: password // 密码匹配
|
||||
}).get({
|
||||
success: (res) => {
|
||||
wx.hideLoading();
|
||||
|
||||
if (res.data.length > 0) {
|
||||
// 登录成功
|
||||
const userData = res.data[0];
|
||||
const userInfo = {
|
||||
_id: userData._id,
|
||||
sno: userData.sno,
|
||||
sname: userData.sname,
|
||||
phone: userData.phone,
|
||||
major: userData.major,
|
||||
sushe: userData.sushe,
|
||||
grade: userData.年级,
|
||||
avatar: userData.avatar || 'https://via.placeholder.com/100x100/4CAF50/ffffff?text=U'
|
||||
};
|
||||
|
||||
// 保存登录信息到本地存储
|
||||
wx.setStorageSync('token', 'user_token_' + userData._id);
|
||||
wx.setStorageSync('userInfo', userInfo);
|
||||
|
||||
wx.showToast({
|
||||
title: '登录成功',
|
||||
icon: 'success',
|
||||
duration: 1500
|
||||
});
|
||||
|
||||
// 跳转到主页面
|
||||
setTimeout(() => {
|
||||
wx.redirectTo({
|
||||
url: '/pages/main/main'
|
||||
});
|
||||
}, 1500);
|
||||
} else {
|
||||
// 登录失败
|
||||
wx.showToast({
|
||||
title: '账号或密码错误',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
wx.hideLoading();
|
||||
console.error('登录查询失败:', err);
|
||||
wx.showToast({
|
||||
title: '网络错误,请重试',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 注册处理
|
||||
onRegister() {
|
||||
wx.navigateTo({
|
||||
url: '/pages/register/register'
|
||||
});
|
||||
},
|
||||
|
||||
// 忘记密码处理
|
||||
onForgotPassword() {
|
||||
wx.navigateTo({
|
||||
url: '/pages/forgot-password/forgot-password'
|
||||
});
|
||||
},
|
||||
|
||||
// 微信一键登录
|
||||
onGetPhoneNumber(e) {
|
||||
if (e.detail.errMsg === 'getPhoneNumber:ok') {
|
||||
// 用户同意授权
|
||||
const { encryptedData, iv } = e.detail;
|
||||
|
||||
wx.showLoading({
|
||||
title: '登录中...',
|
||||
mask: true
|
||||
});
|
||||
|
||||
// 模拟微信登录
|
||||
setTimeout(() => {
|
||||
const userInfo = {
|
||||
studentId: 'wx_' + Date.now().toString().slice(-6),
|
||||
nickname: '微信用户',
|
||||
avatar: 'https://via.placeholder.com/100x100/07C160/ffffff?text=W',
|
||||
campus: '微信用户',
|
||||
department: '微信用户'
|
||||
};
|
||||
|
||||
wx.setStorageSync('token', 'wx_token_' + Date.now());
|
||||
wx.setStorageSync('userInfo', userInfo);
|
||||
|
||||
wx.hideLoading();
|
||||
wx.showToast({
|
||||
title: '微信登录成功',
|
||||
icon: 'success'
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
wx.redirectTo({
|
||||
url: '/pages/main/main'
|
||||
});
|
||||
}, 1500);
|
||||
}, 1500);
|
||||
} else {
|
||||
// 用户拒绝授权
|
||||
wx.showToast({
|
||||
title: '授权失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"usingComponents": {
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,71 @@
|
||||
<!--index.wxml-->
|
||||
<view class="page-container">
|
||||
<view class="login-container">
|
||||
<!-- 顶部logo和标题 -->
|
||||
<view class="header">
|
||||
<image class="logo" src="https://ts1.tc.mm.bing.net/th/id/R-C.0c942a1a8df6bb32de224a7c78c3af92?rik=SEx%2b%2fzYxnPfqwg&riu=http%3a%2f%2fyuanxiao.mpacc.cc%2fuploadfile%2f2022%2f1109%2f20221109052556257.png&ehk=%2bVL02gwPQzun0%2fzDFjxp5xUoH005t%2bS57Qff156jez8%3d&risl=&pid=ImgRaw&r=0" mode="aspectFit"></image>
|
||||
<text class="title">校园二手交易</text>
|
||||
<text class="subtitle">安全便捷的校园交易平台</text>
|
||||
</view>
|
||||
|
||||
<!-- 登录表单 -->
|
||||
<view class="login-form">
|
||||
<view class="form-group">
|
||||
<text class="label">学号/手机号</text>
|
||||
<input
|
||||
class="input"
|
||||
type="number"
|
||||
placeholder="请输入学号或手机号"
|
||||
bindinput="onInputStudentId"
|
||||
value="{{studentId}}"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view class="form-group">
|
||||
<text class="label">密码</text>
|
||||
<input
|
||||
class="input"
|
||||
type="password"
|
||||
placeholder="请输入密码"
|
||||
bindinput="onInputPassword"
|
||||
value="{{password}}"
|
||||
password
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 登录按钮 -->
|
||||
<button
|
||||
class="login-btn {{isLoginDisabled ? 'disabled' : ''}}"
|
||||
bindtap="onLogin"
|
||||
disabled="{{isLoginDisabled}}"
|
||||
>
|
||||
登录
|
||||
</button>
|
||||
|
||||
<!-- 注册链接 -->
|
||||
<view class="register-link">
|
||||
<text>还没有账号?</text>
|
||||
<text class="link" bindtap="onRegister">立即注册</text>
|
||||
</view>
|
||||
|
||||
<!-- 忘记密码 -->
|
||||
<view class="forgot-password">
|
||||
<text class="link" bindtap="onForgotPassword">忘记密码?</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 快速登录选项 -->
|
||||
<view class="quick-login">
|
||||
<view class="divider">
|
||||
<text class="divider-text">或使用以下方式登录</text>
|
||||
</view>
|
||||
|
||||
<view class="quick-login-buttons">
|
||||
<button class="quick-btn wechat" open-type="getPhoneNumber" bindgetphonenumber="onGetPhoneNumber">
|
||||
<image class="quick-icon" src="https://via.placeholder.com/40x40/07C160/ffffff?text=W" mode="aspectFit"></image>
|
||||
<text>微信一键登录</text>
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@ -0,0 +1,233 @@
|
||||
/**index.wxss**/
|
||||
page {
|
||||
height: 100vh;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.page-container {
|
||||
height: 100vh;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.background-image {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.login-container {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 60rpx 40rpx 40rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 头部样式 */
|
||||
.header {
|
||||
text-align: center;
|
||||
margin-bottom: 80rpx;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
border-radius: 80rpx;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
margin-bottom: 30rpx;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.title {
|
||||
display: block;
|
||||
font-size: 50rpx;
|
||||
font-weight: bold;
|
||||
color: rgb(0, 0, 0);
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
display: block;
|
||||
font-size: 40rpx;
|
||||
color: rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
|
||||
/* 登录表单样式 */
|
||||
.login-form {
|
||||
background: rgba(255, 254, 254, 0.95);
|
||||
border-radius: 24rpx;
|
||||
padding: 60rpx 40rpx;
|
||||
box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.15);
|
||||
margin-bottom: 40rpx;
|
||||
backdrop-filter: blur(10rpx);
|
||||
border: 1rpx solid rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.label {
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
margin-bottom: 20rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.input {
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
border: 2rpx solid #e0e0e0;
|
||||
border-radius: 12rpx;
|
||||
padding: 0 24rpx;
|
||||
font-size: 28rpx;
|
||||
box-sizing: border-box;
|
||||
background: #fafafa;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.input:focus {
|
||||
border-color: #ffffff;
|
||||
background: #ffffff;
|
||||
box-shadow: 0 0 0 4rpx rgba(76, 175, 80, 0.1);
|
||||
}
|
||||
|
||||
/* 登录按钮样式 */
|
||||
.login-btn {
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
background: linear-gradient(135deg, rgb(118, 116, 247) 0%, rgb(148, 125, 250) 100%);
|
||||
border-radius: 44rpx;
|
||||
color: #ffffff;
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
margin-top: 20rpx;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.login-btn:active {
|
||||
transform: scale(0.98);
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.login-btn.disabled {
|
||||
background: #cccccc;
|
||||
color: #999999;
|
||||
transform: none;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
/* 注册链接样式 */
|
||||
.register-link {
|
||||
text-align: center;
|
||||
margin: 40rpx 0 20rpx;
|
||||
font-size: 26rpx;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.link {
|
||||
color: #a4acefff;
|
||||
font-weight: 500;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
|
||||
.link:active {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
/* 忘记密码样式 */
|
||||
.forgot-password {
|
||||
text-align: center;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
/* 快速登录样式 */
|
||||
.quick-login {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 24rpx;
|
||||
padding: 40rpx;
|
||||
backdrop-filter: blur(10rpx);
|
||||
}
|
||||
|
||||
.divider {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.divider::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 1rpx;
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.divider-text {
|
||||
display: inline-block;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
padding: 0 20rpx;
|
||||
font-size: 24rpx;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.quick-login-buttons {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.quick-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
border: none;
|
||||
border-radius: 44rpx;
|
||||
padding: 20rpx 40rpx;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.quick-btn:active {
|
||||
transform: scale(0.95);
|
||||
background: rgba(255, 255, 255, 1);
|
||||
}
|
||||
|
||||
.quick-icon {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.quick-btn.wechat {
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.quick-btn.wechat:active {
|
||||
background: rgba(255, 255, 255, 1);
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 750rpx) {
|
||||
.login-container {
|
||||
padding: 40rpx 30rpx 30rpx;
|
||||
}
|
||||
|
||||
.login-form {
|
||||
padding: 40rpx 30rpx;
|
||||
}
|
||||
|
||||
.header {
|
||||
margin-bottom: 60rpx;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
{
|
||||
"usingComponents": {}
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
<!--pages/interests/interests.wxml-->
|
||||
<view class="page-container">
|
||||
<view class="interests-container">
|
||||
<!-- 顶部引导信息 -->
|
||||
<view class="header">
|
||||
<image class="welcome-icon" src="../" mode="aspectFit"></image>
|
||||
|
||||
<text class="title">欢迎来到校园二手交易平台!</text>
|
||||
<text class="question">请选择您感兴趣的商品类别</text>
|
||||
</view>
|
||||
|
||||
<!-- 商品类别选择区域 -->
|
||||
<view class="interests-section">
|
||||
<text class="section-title">选择您感兴趣的商品类别</text>
|
||||
<text class="section-subtitle">(可多选,用于个性化商品推荐)</text>
|
||||
|
||||
<view class="interests-grid">
|
||||
<view
|
||||
class="interest-card {{categorySelectedMap[category.id] ? 'selected' : ''}}"
|
||||
wx:for="{{categories}}"
|
||||
wx:key="id"
|
||||
bindtap="onCategoryTap"
|
||||
data-id="{{category.id}}"
|
||||
>
|
||||
<image class="interest-icon" src="{{category.icon}}" mode="aspectFit"></image>
|
||||
<text class="interest-name">{{category.name}}</text>
|
||||
<text class="interest-desc">{{category.description}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 选择提示 -->
|
||||
<view class="selection-hint" wx:if="{{selectedInterests.length > 0}}">
|
||||
<text class="hint-text">已选择 {{selectedInterests.length}}/4 个商品类别</text>
|
||||
<text class="hint-tip">系统将根据您的选择为您推荐相关商品</text>
|
||||
</view>
|
||||
|
||||
<!-- 底部操作按钮 -->
|
||||
<view class="action-buttons">
|
||||
<button
|
||||
class="skip-btn"
|
||||
bindtap="onSkip"
|
||||
wx:if="{{selectedInterests.length === 0}}"
|
||||
>
|
||||
暂时跳过
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="confirm-btn {{selectedInterests.length === 0 ? 'disabled' : ''}}"
|
||||
bindtap="onConfirm"
|
||||
disabled="{{selectedInterests.length === 0}}"
|
||||
>
|
||||
{{selectedInterests.length === 0 ? '请至少选择一个' : '完成选择 (' + selectedInterests.length + ')'}}
|
||||
</button>
|
||||
</view>
|
||||
|
||||
<!-- 进度提示 -->
|
||||
<view class="progress-hint">
|
||||
<text class="progress-text">完成此步骤后,即可开始使用平台</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@ -0,0 +1,186 @@
|
||||
/* pages/interests/interests.wxss */
|
||||
.page-container {
|
||||
min-height: 100vh;
|
||||
background: linear-gradient(135deg, #7672fdff 0%, #9bc3ffff 100%);
|
||||
padding: 40rpx 30rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.interests-container {
|
||||
background: white;
|
||||
border-radius: 20rpx;
|
||||
padding: 40rpx 30rpx;
|
||||
box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* 头部样式 */
|
||||
.header {
|
||||
text-align: center;
|
||||
margin-bottom: 50rpx;
|
||||
}
|
||||
|
||||
.welcome-icon {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
display: block;
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
|
||||
.question {
|
||||
display: block;
|
||||
font-size: 32rpx;
|
||||
color: #4285F4;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 商品类别选择区域 */
|
||||
.interests-section {
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
display: block;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.section-subtitle {
|
||||
display: block;
|
||||
font-size: 26rpx;
|
||||
color: #999;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.interests-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.interest-card {
|
||||
background: #f8f9fa;
|
||||
border: 2rpx solid #e9ecef;
|
||||
border-radius: 15rpx;
|
||||
padding: 30rpx 20rpx;
|
||||
text-align: center;
|
||||
transition: all 0.3s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.interest-card.selected {
|
||||
background: #4285F4;
|
||||
border-color: #4285F4;
|
||||
transform: translateY(-5rpx);
|
||||
box-shadow: 0 10rpx 20rpx rgba(66, 133, 244, 0.3);
|
||||
}
|
||||
|
||||
.interest-card.selected .interest-name,
|
||||
.interest-card.selected .interest-desc {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.interest-icon {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
margin-bottom: 15rpx;
|
||||
}
|
||||
|
||||
.interest-name {
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
|
||||
.interest-desc {
|
||||
display: block;
|
||||
font-size: 22rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* 选择提示 */
|
||||
.selection-hint {
|
||||
background: #e8f4fd;
|
||||
border: 1rpx solid #b3e0ff;
|
||||
border-radius: 10rpx;
|
||||
padding: 20rpx;
|
||||
margin-bottom: 30rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.hint-text {
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
color: #0066cc;
|
||||
font-weight: 600;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
|
||||
.hint-tip {
|
||||
display: block;
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* 底部操作按钮 */
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.skip-btn {
|
||||
flex: 1;
|
||||
background: #f8f9fa;
|
||||
color: #666;
|
||||
border: 2rpx solid #e9ecef;
|
||||
border-radius: 50rpx;
|
||||
font-size: 28rpx;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
}
|
||||
|
||||
.confirm-btn {
|
||||
flex: 1;
|
||||
background: #4285F4;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 50rpx;
|
||||
font-size: 28rpx;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.confirm-btn.disabled {
|
||||
background: #ccc;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* 进度提示 */
|
||||
.progress-hint {
|
||||
text-align: center;
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.progress-text {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
// logs.js
|
||||
const util = require('../../utils/util.js')
|
||||
|
||||
Page({
|
||||
data: {
|
||||
logs: []
|
||||
},
|
||||
onLoad() {
|
||||
this.setData({
|
||||
logs: (wx.getStorageSync('logs') || []).map(log => {
|
||||
return {
|
||||
date: util.formatTime(new Date(log)),
|
||||
timeStamp: log
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"usingComponents": {
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
<!--logs.wxml-->
|
||||
<scroll-view class="scrollarea" scroll-y type="list">
|
||||
<block wx:for="{{logs}}" wx:key="timeStamp" wx:for-item="log">
|
||||
<view class="log-item">{{index + 1}}. {{log.date}}</view>
|
||||
</block>
|
||||
</scroll-view>
|
||||
@ -0,0 +1,16 @@
|
||||
page {
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.scrollarea {
|
||||
flex: 1;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
.log-item {
|
||||
margin-top: 20rpx;
|
||||
text-align: center;
|
||||
}
|
||||
.log-item:last-child {
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
{
|
||||
"usingComponents": {},
|
||||
"navigationBarTitleText": "校园二手交易",
|
||||
"navigationBarBackgroundColor": "#4285F4",
|
||||
"navigationBarTextStyle": "white",
|
||||
"enablePullDownRefresh": true
|
||||
}
|
||||
@ -0,0 +1,101 @@
|
||||
<!--pages/main/main.wxml-->
|
||||
<view class="page-container">
|
||||
<!-- 顶部导航栏 -->
|
||||
<view class="header">
|
||||
<view class="search-bar">
|
||||
<image class="search-icon" src="/images/search.png" mode="aspectFit"></image>
|
||||
<input class="search-input" placeholder="搜索商品、求购信息" bindinput="onSearchInput" />
|
||||
</view>
|
||||
<view class="user-info" bindtap="onUserProfile">
|
||||
<image class="avatar" src="{{userInfo.avatar || '/images/default-avatar.png'}}" mode="aspectFit"></image>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 功能导航 -->
|
||||
<view class="nav-section">
|
||||
<!-- 卖家功能 -->
|
||||
<view class="function-group">
|
||||
<text class="group-title">我是卖家</text>
|
||||
<view class="nav-grid">
|
||||
<view class="nav-item" bindtap="onNavigateTo" data-page="pricing">
|
||||
<image class="nav-icon" src="/images/边牧.png" mode="aspectFit"></image>
|
||||
<text class="nav-text">AI定价</text>
|
||||
</view>
|
||||
<view class="nav-item" bindtap="onNavigateTo" data-page="publish">
|
||||
<image class="nav-icon" src="/images/仓鼠.png" mode="aspectFit"></image>
|
||||
<text class="nav-text">发布商品</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 买家功能 -->
|
||||
<view class="function-group">
|
||||
<text class="group-title">我是买家</text>
|
||||
<view class="nav-grid">
|
||||
<view class="nav-item" bindtap="onNavigateTo" data-page="buy">
|
||||
<image class="nav-icon" src="/images/更多犬种.png" mode="aspectFit"></image>
|
||||
<text class="nav-text">商品购买</text>
|
||||
</view>
|
||||
<view class="nav-item" bindtap="onNavigateTo" data-page="wanted">
|
||||
<image class="nav-icon" src="/images/羊.png" mode="aspectFit"></image>
|
||||
<text class="nav-text">求购</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 推荐商品区域 -->
|
||||
<view class="recommend-section">
|
||||
<view class="section-header">
|
||||
<text class="section-title">为您推荐</text>
|
||||
<text class="section-subtitle">基于您的兴趣智能推荐</text>
|
||||
</view>
|
||||
<scroll-view class="recommend-scroll" scroll-x="true">
|
||||
<view class="recommend-list">
|
||||
<view class="product-card" wx:for="{{recommendProducts}}" wx:key="id" bindtap="onProductTap" data-id="{{item.id}}">
|
||||
<image class="product-image" src="{{item.image}}" mode="aspectFill"></image>
|
||||
<view class="product-info">
|
||||
<text class="product-name">{{item.name}}</text>
|
||||
<text class="product-price">¥{{item.price}}</text>
|
||||
<text class="product-tag">{{item.tag}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
<!-- 热门求购 -->
|
||||
<view class="wanted-section">
|
||||
<view class="section-header">
|
||||
<text class="section-title">热门求购</text>
|
||||
<text class="section-subtitle">大家都在找什么</text>
|
||||
</view>
|
||||
<view class="wanted-list">
|
||||
<view class="wanted-item" wx:for="{{hotWanted}}" wx:key="id" bindtap="onWantedTap" data-id="{{item.id}}">
|
||||
<text class="wanted-title">{{item.title}}</text>
|
||||
<text class="wanted-price">预算: ¥{{item.budget}}</text>
|
||||
<text class="wanted-time">{{item.time}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部导航栏 -->
|
||||
<view class="tab-bar">
|
||||
<view class="tab-item {{currentTab === 'home' ? 'active' : ''}}" bindtap="onTabChange" data-tab="home">
|
||||
<image class="tab-icon" src="{{currentTab === 'home' ? '/images/home-active.png' : '/images/home.png'}}"></image>
|
||||
<text class="tab-text">首页</text>
|
||||
</view>
|
||||
<view class="tab-item {{currentTab === 'market' ? 'active' : ''}}" bindtap="onTabChange" data-tab="market">
|
||||
<image class="tab-icon" src="{{currentTab === 'market' ? '/images/market-active.png' : '/images/market.png'}}"></image>
|
||||
<text class="tab-text">市场</text>
|
||||
</view>
|
||||
<view class="tab-item {{currentTab === 'message' ? 'active' : ''}}" bindtap="onTabChange" data-tab="message">
|
||||
<image class="tab-icon" src="{{currentTab === 'message' ? '/images/message-active.png' : '/images/message.png'}}"></image>
|
||||
<text class="tab-text">消息</text>
|
||||
</view>
|
||||
<view class="tab-item {{currentTab === 'profile' ? 'active' : ''}}" bindtap="onTabChange" data-tab="profile">
|
||||
<image class="tab-icon" src="{{currentTab === 'profile' ? '/images/profile-active.png' : '/images/profile.png'}}"></image>
|
||||
<text class="tab-text">我的</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@ -0,0 +1,270 @@
|
||||
/* pages/main/main.wxss */
|
||||
|
||||
.page-container {
|
||||
min-height: 100vh;
|
||||
background-color: #f5f5f5;
|
||||
padding-bottom: 100rpx;
|
||||
}
|
||||
|
||||
/* 顶部导航栏 */
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20rpx 30rpx;
|
||||
background: linear-gradient(135deg, #4285F4 0%, #34A853 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.search-bar {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
border-radius: 50rpx;
|
||||
padding: 15rpx 25rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
margin-right: 15rpx;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
border: 3rpx solid white;
|
||||
}
|
||||
|
||||
/* 功能导航 */
|
||||
.nav-section {
|
||||
background: white;
|
||||
margin: 20rpx;
|
||||
border-radius: 20rpx;
|
||||
padding: 30rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.function-group {
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.function-group:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.group-title {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 20rpx;
|
||||
display: block;
|
||||
padding-left: 10rpx;
|
||||
border-left: 6rpx solid #4285F4;
|
||||
}
|
||||
|
||||
.nav-grid {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 150rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.nav-icon {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
margin-bottom: 15rpx;
|
||||
}
|
||||
|
||||
.nav-text {
|
||||
font-size: 24rpx;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 推荐商品区域 */
|
||||
.recommend-section {
|
||||
background: white;
|
||||
margin: 20rpx;
|
||||
border-radius: 20rpx;
|
||||
padding: 30rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.section-header {
|
||||
margin-bottom: 25rpx;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.section-subtitle {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.recommend-scroll {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.recommend-list {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.product-card {
|
||||
display: inline-block;
|
||||
width: 280rpx;
|
||||
margin-right: 20rpx;
|
||||
background: #f8f9fa;
|
||||
border-radius: 15rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.product-image {
|
||||
width: 100%;
|
||||
height: 200rpx;
|
||||
}
|
||||
|
||||
.product-info {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.product-name {
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.product-price {
|
||||
font-size: 28rpx;
|
||||
color: #FF6B35;
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.product-tag {
|
||||
font-size: 20rpx;
|
||||
color: #666;
|
||||
background: #e9ecef;
|
||||
padding: 4rpx 12rpx;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
/* 热门求购 */
|
||||
.wanted-section {
|
||||
background: white;
|
||||
margin: 20rpx;
|
||||
border-radius: 20rpx;
|
||||
padding: 30rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.wanted-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.wanted-item {
|
||||
background: #f8f9fa;
|
||||
padding: 25rpx;
|
||||
border-radius: 15rpx;
|
||||
border-left: 6rpx solid #4285F4;
|
||||
}
|
||||
|
||||
.wanted-title {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.wanted-price {
|
||||
font-size: 24rpx;
|
||||
color: #FF6B35;
|
||||
display: block;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.wanted-time {
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* 底部导航栏 */
|
||||
.tab-bar {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
background: white;
|
||||
border-top: 1rpx solid #e0e0e0;
|
||||
padding: 15rpx 0;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.tab-item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.tab-icon {
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.tab-text {
|
||||
font-size: 20rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.tab-item.active .tab-text {
|
||||
color: #4285F4;
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 750rpx) {
|
||||
.nav-item {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.product-card {
|
||||
width: 250rpx;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
{
|
||||
"navigationBarTitleText": "AI智能定价",
|
||||
"navigationBarBackgroundColor": "#4285F4",
|
||||
"navigationBarTextStyle": "white",
|
||||
"backgroundColor": "#f5f5f5",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
@ -0,0 +1,137 @@
|
||||
<!-- pages/pricing/pricing.wxml -->
|
||||
<view class="page-container">
|
||||
|
||||
<!-- 商品上传模块 -->
|
||||
<view class="upload-section">
|
||||
<view class="section-header">
|
||||
<text class="section-title">商品上传</text>
|
||||
<text class="section-subtitle">上传商品图片进行AI智能定价</text>
|
||||
</view>
|
||||
|
||||
<!-- 图片上传区域 -->
|
||||
<view class="upload-area">
|
||||
<view class="image-preview" bindtap="onChooseImage">
|
||||
<view class="preview-content" wx:if="{{imagePath}}">
|
||||
<image class="preview-image" src="{{imagePath}}" mode="aspectFit"></image>
|
||||
<view class="preview-overlay">
|
||||
<text class="preview-text">点击更换图片</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="upload-placeholder" wx:else>
|
||||
<image class="camera-icon" src="/images/边牧.png" mode="aspectFit"></image>
|
||||
<text class="placeholder-text">点击上传商品图片</text>
|
||||
<text class="placeholder-hint">支持 JPG、PNG 格式</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 原价输入区域 -->
|
||||
<view class="original-price-section">
|
||||
<view class="price-input-container">
|
||||
<text class="price-label">商品原价</text>
|
||||
<view class="price-input-group">
|
||||
<text class="price-symbol">¥</text>
|
||||
<input
|
||||
class="price-input"
|
||||
type="digit"
|
||||
placeholder="0.00"
|
||||
value="{{originalPrice}}"
|
||||
bindinput="onOriginalPriceInput"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 功能按钮区域 -->
|
||||
<view class="button-group">
|
||||
<button class="camera-btn" bindtap="onTakePhoto">
|
||||
<image class="btn-icon" src="/images/边牧.png" mode="aspectFit"></image>
|
||||
<text>拍照上传</text>
|
||||
</button>
|
||||
<button class="ai-pricing-btn" bindtap="onAIPricing" disabled="{{!imagePath || !originalPrice}}">
|
||||
<image class="btn-icon" src="/images/边牧.png" mode="aspectFit"></image>
|
||||
<text>智能定价</text>
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- AI定价结果及商品信息模块 -->
|
||||
<view class="result-section" wx:if="{{showResult}}">
|
||||
|
||||
<!-- AI定价结果 -->
|
||||
<view class="result-group">
|
||||
<view class="section-header">
|
||||
<text class="section-title">AI定价结果</text>
|
||||
<text class="section-subtitle">基于图像分析和市场数据</text>
|
||||
</view>
|
||||
|
||||
<view class="pricing-result">
|
||||
<view class="price-display">
|
||||
<text class="price-label">建议价格</text>
|
||||
<text class="price-value">¥{{suggestedPrice}}</text>
|
||||
</view>
|
||||
|
||||
<view class="price-details">
|
||||
<view class="detail-item">
|
||||
<text class="detail-label">商品成色</text>
|
||||
<text class="detail-value">{{conditionLevel}}</text>
|
||||
</view>
|
||||
<view class="detail-item">
|
||||
<text class="detail-label">市场参考</text>
|
||||
<text class="detail-value">{{marketRange}}</text>
|
||||
</view>
|
||||
<view class="detail-item">
|
||||
<text class="detail-label">AI评分</text>
|
||||
<text class="detail-value">{{aiScore}}分</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="ai-analysis">
|
||||
<text class="analysis-title">AI分析报告</text>
|
||||
<text class="analysis-content">{{analysisReport}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- AI生成的商品信息 -->
|
||||
<view class="product-info-group">
|
||||
<view class="section-header">
|
||||
<text class="section-title">AI智能识别</text>
|
||||
<text class="section-subtitle">基于图像识别自动生成商品信息</text>
|
||||
</view>
|
||||
|
||||
<view class="product-info">
|
||||
<view class="info-item">
|
||||
<text class="info-label">商品名称</text>
|
||||
<text class="info-value">{{productName}}</text>
|
||||
</view>
|
||||
|
||||
<view class="info-item">
|
||||
<text class="info-label">商品类别</text>
|
||||
<text class="info-value">{{productCategory}}</text>
|
||||
</view>
|
||||
|
||||
<view class="info-item">
|
||||
<text class="info-label">商品描述</text>
|
||||
<text class="info-description">{{productDescription}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<view class="action-buttons">
|
||||
<button class="save-btn" bindtap="onSaveProduct">保存商品信息</button>
|
||||
<button class="publish-btn" bindtap="onPublishProduct">立即发布</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载状态 -->
|
||||
<view class="loading-section" wx:if="{{isAnalyzing}}">
|
||||
<view class="loading-content">
|
||||
<image class="loading-icon" src="/images/边牧.png" mode="aspectFit"></image>
|
||||
<text class="loading-text">AI正在分析商品图片...</text>
|
||||
<text class="loading-subtext">请稍候,这可能需要几秒钟</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
@ -0,0 +1,400 @@
|
||||
/* pages/pricing/pricing.wxss */
|
||||
|
||||
.page-container {
|
||||
min-height: 100vh;
|
||||
background-color: #f5f5f5;
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
/* 通用样式 */
|
||||
.section-header {
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.section-subtitle {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* 商品上传模块 */
|
||||
.upload-section {
|
||||
background: white;
|
||||
border-radius: 20rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.upload-area {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.image-preview {
|
||||
width: 300rpx;
|
||||
height: 300rpx;
|
||||
border: 4rpx dashed #ddd;
|
||||
border-radius: 20rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 30rpx;
|
||||
background: #fafafa;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* 原价输入区域 */
|
||||
.original-price-section {
|
||||
width: 100%;
|
||||
margin-bottom: 30rpx;
|
||||
padding: 20rpx;
|
||||
background: #f8f9fa;
|
||||
border-radius: 15rpx;
|
||||
border: 2rpx solid #e0e0e0;
|
||||
}
|
||||
|
||||
.price-input-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.price-input-container .price-label {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.price-input-container .price-input-group {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: white;
|
||||
border: 2rpx solid #4285F4;
|
||||
border-radius: 10rpx;
|
||||
padding: 15rpx 20rpx;
|
||||
max-width: 250rpx;
|
||||
}
|
||||
|
||||
.price-input-container .price-symbol {
|
||||
font-size: 28rpx;
|
||||
color: #4285F4;
|
||||
font-weight: bold;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.price-input-container .price-input {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.image-preview:active {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
.preview-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.preview-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.preview-overlay {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
padding: 20rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.preview-text {
|
||||
color: white;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.upload-placeholder {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 40rpx;
|
||||
}
|
||||
|
||||
.camera-icon {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
margin-bottom: 20rpx;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.placeholder-text {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.placeholder-hint {
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.camera-btn, .ai-pricing-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20rpx 40rpx;
|
||||
border-radius: 50rpx;
|
||||
font-size: 26rpx;
|
||||
border: none;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.camera-btn {
|
||||
background: #34A853;
|
||||
}
|
||||
|
||||
.ai-pricing-btn {
|
||||
background: linear-gradient(135deg, #FF6B35, #4285F4);
|
||||
font-weight: bold;
|
||||
box-shadow: 0 4rpx 15rpx rgba(255, 107, 53, 0.3);
|
||||
}
|
||||
|
||||
.ai-pricing-btn[disabled] {
|
||||
background: #ccc;
|
||||
color: #999;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.btn-icon {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
/* AI定价结果模块 */
|
||||
.result-section {
|
||||
background: white;
|
||||
border-radius: 20rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.result-group {
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.pricing-result {
|
||||
border: 2rpx dashed #4285F4;
|
||||
border-radius: 15rpx;
|
||||
padding: 30rpx;
|
||||
background: #f8f9ff;
|
||||
}
|
||||
|
||||
.price-display {
|
||||
text-align: center;
|
||||
margin-bottom: 30rpx;
|
||||
padding-bottom: 30rpx;
|
||||
border-bottom: 1rpx solid #e0e0e0;
|
||||
}
|
||||
|
||||
.price-label {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.price-value {
|
||||
font-size: 48rpx;
|
||||
font-weight: bold;
|
||||
color: #FF6B35;
|
||||
}
|
||||
|
||||
.price-details {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.detail-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.detail-label {
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.detail-value {
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.ai-analysis {
|
||||
background: white;
|
||||
border-radius: 10rpx;
|
||||
padding: 20rpx;
|
||||
border: 1rpx solid #e0e0e0;
|
||||
}
|
||||
|
||||
.analysis-title {
|
||||
font-size: 24rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 15rpx;
|
||||
}
|
||||
|
||||
.analysis-content {
|
||||
font-size: 22rpx;
|
||||
color: #666;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* AI生成的商品信息模块 */
|
||||
.product-info-group {
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.product-info {
|
||||
background: #f8f9ff;
|
||||
border-radius: 15rpx;
|
||||
padding: 30rpx;
|
||||
border: 2rpx solid #4285F4;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
margin-bottom: 25rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.info-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
font-weight: bold;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
background: white;
|
||||
padding: 15rpx 20rpx;
|
||||
border-radius: 8rpx;
|
||||
border: 1rpx solid #e0e0e0;
|
||||
}
|
||||
|
||||
.info-description {
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
line-height: 1.6;
|
||||
background: white;
|
||||
padding: 20rpx;
|
||||
border-radius: 8rpx;
|
||||
border: 1rpx solid #e0e0e0;
|
||||
min-height: 120rpx;
|
||||
}
|
||||
|
||||
/* 操作按钮 */
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.save-btn, .publish-btn {
|
||||
flex: 1;
|
||||
padding: 25rpx;
|
||||
border-radius: 50rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.save-btn {
|
||||
background: #f8f9fa;
|
||||
color: #333;
|
||||
border: 2rpx solid #ddd;
|
||||
}
|
||||
|
||||
.publish-btn {
|
||||
background: linear-gradient(135deg, #4285F4, #34A853);
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* 加载状态 */
|
||||
.loading-section {
|
||||
background: white;
|
||||
border-radius: 20rpx;
|
||||
padding: 60rpx 30rpx;
|
||||
text-align: center;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.loading-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.loading-icon {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
margin-bottom: 30rpx;
|
||||
animation: rotate 2s linear infinite;
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.loading-subtext {
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
@keyframes rotate {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,263 @@
|
||||
// pages/profile/profile.js
|
||||
Page({
|
||||
|
||||
/**
|
||||
* 页面的初始数据
|
||||
*/
|
||||
data: {
|
||||
userInfo: {},
|
||||
userStats: {
|
||||
products: 0,
|
||||
wanted: 0,
|
||||
orders: 0,
|
||||
favorites: 0
|
||||
},
|
||||
notificationEnabled: true
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
this.loadUserInfo();
|
||||
this.loadUserStats();
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow() {
|
||||
this.loadUserInfo();
|
||||
this.loadUserStats();
|
||||
},
|
||||
|
||||
/**
|
||||
* 加载用户信息
|
||||
*/
|
||||
loadUserInfo() {
|
||||
const userInfo = wx.getStorageSync('userInfo') || {};
|
||||
this.setData({
|
||||
userInfo: userInfo
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 加载用户统计数据
|
||||
*/
|
||||
loadUserStats() {
|
||||
// 模拟从后端获取用户统计数据
|
||||
const stats = wx.getStorageSync('userStats') || {
|
||||
products: 12,
|
||||
wanted: 3,
|
||||
orders: 8,
|
||||
favorites: 25
|
||||
};
|
||||
|
||||
this.setData({
|
||||
userStats: stats
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 我的商品点击事件
|
||||
*/
|
||||
onMyProducts() {
|
||||
wx.showToast({
|
||||
title: '跳转到我的商品',
|
||||
icon: 'none'
|
||||
});
|
||||
// 这里可以跳转到我的商品页面
|
||||
},
|
||||
|
||||
/**
|
||||
* 我的求购点击事件
|
||||
*/
|
||||
onMyWanted() {
|
||||
wx.showToast({
|
||||
title: '跳转到我的求购',
|
||||
icon: 'none'
|
||||
});
|
||||
// 这里可以跳转到我的求购页面
|
||||
},
|
||||
|
||||
/**
|
||||
* 我的订单点击事件
|
||||
*/
|
||||
onMyOrders() {
|
||||
wx.showToast({
|
||||
title: '跳转到我的订单',
|
||||
icon: 'none'
|
||||
});
|
||||
// 这里可以跳转到我的订单页面
|
||||
},
|
||||
|
||||
/**
|
||||
* 我的收藏点击事件
|
||||
*/
|
||||
onMyFavorites() {
|
||||
wx.showToast({
|
||||
title: '跳转到我的收藏',
|
||||
icon: 'none'
|
||||
});
|
||||
// 这里可以跳转到我的收藏页面
|
||||
},
|
||||
|
||||
/**
|
||||
* 个人信息编辑
|
||||
*/
|
||||
onProfileEdit() {
|
||||
wx.showModal({
|
||||
title: '编辑个人信息',
|
||||
content: '此功能正在开发中',
|
||||
showCancel: false,
|
||||
confirmText: '知道了'
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 安全设置
|
||||
*/
|
||||
onSecurity() {
|
||||
wx.showModal({
|
||||
title: '安全设置',
|
||||
content: '此功能正在开发中',
|
||||
showCancel: false,
|
||||
confirmText: '知道了'
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 收货地址管理
|
||||
*/
|
||||
onAddress() {
|
||||
wx.showModal({
|
||||
title: '收货地址',
|
||||
content: '此功能正在开发中',
|
||||
showCancel: false,
|
||||
confirmText: '知道了'
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 意见反馈
|
||||
*/
|
||||
onFeedback() {
|
||||
wx.showModal({
|
||||
title: '意见反馈',
|
||||
content: '此功能正在开发中',
|
||||
showCancel: false,
|
||||
confirmText: '知道了'
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 消息通知开关
|
||||
*/
|
||||
onNotificationChange(e) {
|
||||
const enabled = e.detail.value;
|
||||
this.setData({
|
||||
notificationEnabled: enabled
|
||||
});
|
||||
|
||||
wx.showToast({
|
||||
title: enabled ? '通知已开启' : '通知已关闭',
|
||||
icon: 'success'
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 隐私设置
|
||||
*/
|
||||
onPrivacy() {
|
||||
wx.showModal({
|
||||
title: '隐私设置',
|
||||
content: '此功能正在开发中',
|
||||
showCancel: false,
|
||||
confirmText: '知道了'
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 关于我们
|
||||
*/
|
||||
onAbout() {
|
||||
wx.showModal({
|
||||
title: '关于SContact',
|
||||
content: '版本: 1.0.0\n开发者: SContact团队\n联系方式: support@scontact.com',
|
||||
showCancel: false,
|
||||
confirmText: '知道了'
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 退出登录
|
||||
*/
|
||||
onLogout() {
|
||||
wx.showModal({
|
||||
title: '确认退出',
|
||||
content: '确定要退出登录吗?',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
// 清除登录信息
|
||||
wx.removeStorageSync('userInfo');
|
||||
wx.removeStorageSync('token');
|
||||
wx.removeStorageSync('userStats');
|
||||
|
||||
// 显示退出成功提示
|
||||
wx.showToast({
|
||||
title: '退出成功',
|
||||
icon: 'success',
|
||||
duration: 1500
|
||||
});
|
||||
|
||||
// 延迟跳转到登录页面
|
||||
setTimeout(() => {
|
||||
wx.redirectTo({
|
||||
url: '/pages/index/index'
|
||||
});
|
||||
}, 1500);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 用户下拉刷新
|
||||
*/
|
||||
onPullDownRefresh() {
|
||||
console.log('下拉刷新个人中心');
|
||||
|
||||
// 重新加载用户信息
|
||||
this.loadUserInfo();
|
||||
this.loadUserStats();
|
||||
|
||||
// 模拟刷新延迟
|
||||
setTimeout(() => {
|
||||
wx.stopPullDownRefresh();
|
||||
wx.showToast({
|
||||
title: '刷新成功',
|
||||
icon: 'success'
|
||||
});
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面上拉触底事件的处理函数
|
||||
*/
|
||||
onReachBottom() {
|
||||
console.log('上拉加载更多');
|
||||
|
||||
// 可以在这里加载更多数据
|
||||
wx.showLoading({
|
||||
title: '加载中...'
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
wx.hideLoading();
|
||||
wx.showToast({
|
||||
title: '没有更多数据了',
|
||||
icon: 'none'
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
})
|
||||
@ -0,0 +1,8 @@
|
||||
{
|
||||
"navigationBarTitleText": "个人中心",
|
||||
"navigationBarBackgroundColor": "#667eea",
|
||||
"navigationBarTextStyle": "white",
|
||||
"backgroundColor": "#f5f5f5",
|
||||
"backgroundTextStyle": "dark",
|
||||
"enablePullDownRefresh": true
|
||||
}
|
||||
@ -0,0 +1,111 @@
|
||||
<!--pages/profile/profile.wxml-->
|
||||
<view class="page-container">
|
||||
<!-- 顶部用户信息区域 -->
|
||||
<view class="user-header">
|
||||
<view class="user-avatar-section">
|
||||
<image class="user-avatar" src="{{userInfo.avatar || '/images/default-avatar.png'}}" mode="aspectFit"></image>
|
||||
<view class="user-info">
|
||||
<text class="user-name">{{userInfo.nickName || '未设置昵称'}}</text>
|
||||
<text class="user-id">ID: {{userInfo.id || '未设置'}}</text>
|
||||
<text class="user-level">会员等级: {{userInfo.level || '普通会员'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="user-stats">
|
||||
<view class="stat-item" bindtap="onMyProducts">
|
||||
<text class="stat-number">{{userStats.products || 0}}</text>
|
||||
<text class="stat-label">我的商品</text>
|
||||
</view>
|
||||
<view class="stat-item" bindtap="onMyWanted">
|
||||
<text class="stat-number">{{userStats.wanted || 0}}</text>
|
||||
<text class="stat-label">我的求购</text>
|
||||
</view>
|
||||
<view class="stat-item" bindtap="onMyOrders">
|
||||
<text class="stat-number">{{userStats.orders || 0}}</text>
|
||||
<text class="stat-label">我的订单</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 功能菜单区域 -->
|
||||
<view class="menu-section">
|
||||
<view class="menu-group">
|
||||
<text class="group-title">交易管理</text>
|
||||
<view class="menu-list">
|
||||
<view class="menu-item" bindtap="onMyProducts">
|
||||
<image class="menu-icon" src="/images/product.png" mode="aspectFit"></image>
|
||||
<text class="menu-text">我的商品</text>
|
||||
<text class="menu-arrow">></text>
|
||||
</view>
|
||||
<view class="menu-item" bindtap="onMyWanted">
|
||||
<image class="menu-icon" src="/images/wanted.png" mode="aspectFit"></image>
|
||||
<text class="menu-text">我的求购</text>
|
||||
<text class="menu-arrow">></text>
|
||||
</view>
|
||||
<view class="menu-item" bindtap="onMyOrders">
|
||||
<image class="menu-icon" src="/images/order.png" mode="aspectFit"></image>
|
||||
<text class="menu-text">我的订单</text>
|
||||
<text class="menu-arrow">></text>
|
||||
</view>
|
||||
<view class="menu-item" bindtap="onMyFavorites">
|
||||
<image class="menu-icon" src="/images/favorite.png" mode="aspectFit"></image>
|
||||
<text class="menu-text">我的收藏</text>
|
||||
<text class="menu-arrow">></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="menu-group">
|
||||
<text class="group-title">账户设置</text>
|
||||
<view class="menu-list">
|
||||
<view class="menu-item" bindtap="onProfileEdit">
|
||||
<image class="menu-icon" src="/images/profile.png" mode="aspectFit"></image>
|
||||
<text class="menu-text">个人信息</text>
|
||||
<text class="menu-arrow">></text>
|
||||
</view>
|
||||
<view class="menu-item" bindtap="onSecurity">
|
||||
<image class="menu-icon" src="/images/security.png" mode="aspectFit"></image>
|
||||
<text class="menu-text">安全设置</text>
|
||||
<text class="menu-arrow">></text>
|
||||
</view>
|
||||
<view class="menu-item" bindtap="onAddress">
|
||||
<image class="menu-icon" src="/images/address.png" mode="aspectFit"></image>
|
||||
<text class="menu-text">收货地址</text>
|
||||
<text class="menu-arrow">></text>
|
||||
</view>
|
||||
<view class="menu-item" bindtap="onFeedback">
|
||||
<image class="menu-icon" src="/images/feedback.png" mode="aspectFit"></image>
|
||||
<text class="menu-text">意见反馈</text>
|
||||
<text class="menu-arrow">></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="menu-group">
|
||||
<text class="group-title">系统设置</text>
|
||||
<view class="menu-list">
|
||||
<view class="menu-item" bindtap="onNotification">
|
||||
<image class="menu-icon" src="/images/notification.png" mode="aspectFit"></image>
|
||||
<text class="menu-text">消息通知</text>
|
||||
<view class="menu-switch">
|
||||
<switch checked="{{notificationEnabled}}" bindchange="onNotificationChange" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="menu-item" bindtap="onPrivacy">
|
||||
<image class="menu-icon" src="/images/privacy.png" mode="aspectFit"></image>
|
||||
<text class="menu-text">隐私设置</text>
|
||||
<text class="menu-arrow">></text>
|
||||
</view>
|
||||
<view class="menu-item" bindtap="onAbout">
|
||||
<image class="menu-icon" src="/images/about.png" mode="aspectFit"></image>
|
||||
<text class="menu-text">关于我们</text>
|
||||
<text class="menu-arrow">></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部操作按钮 -->
|
||||
<view class="action-section">
|
||||
<button class="logout-btn" bindtap="onLogout">退出登录</button>
|
||||
</view>
|
||||
</view>
|
||||
@ -0,0 +1,173 @@
|
||||
/* pages/profile/profile.wxss */
|
||||
|
||||
.page-container {
|
||||
min-height: 100vh;
|
||||
background-color: #f5f5f5;
|
||||
padding-bottom: 100rpx;
|
||||
}
|
||||
|
||||
/* 顶部用户信息区域 */
|
||||
.user-header {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
padding: 40rpx 30rpx;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.user-avatar-section {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 50%;
|
||||
border: 4rpx solid rgba(255, 255, 255, 0.3);
|
||||
margin-right: 30rpx;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.user-id, .user-level {
|
||||
font-size: 24rpx;
|
||||
opacity: 0.9;
|
||||
display: block;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
|
||||
.user-stats {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
|
||||
.stat-number {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 24rpx;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
/* 功能菜单区域 */
|
||||
.menu-section {
|
||||
padding: 30rpx;
|
||||
}
|
||||
|
||||
.menu-group {
|
||||
background: white;
|
||||
border-radius: 20rpx;
|
||||
margin-bottom: 30rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.group-title {
|
||||
display: block;
|
||||
padding: 30rpx 30rpx 20rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.menu-list {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 30rpx;
|
||||
border-bottom: 1rpx solid #f8f8f8;
|
||||
transition: background-color 0.3s;
|
||||
}
|
||||
|
||||
.menu-item:active {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
.menu-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.menu-icon {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.menu-text {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.menu-arrow {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.menu-switch {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
/* 底部操作按钮 */
|
||||
.action-section {
|
||||
padding: 30rpx;
|
||||
}
|
||||
|
||||
.logout-btn {
|
||||
width: 100%;
|
||||
background: linear-gradient(135deg, #ff6b6b 0%, #ee5a52 100%);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 50rpx;
|
||||
padding: 30rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
box-shadow: 0 8rpx 25rpx rgba(255, 107, 107, 0.3);
|
||||
}
|
||||
|
||||
.logout-btn:active {
|
||||
transform: translateY(2rpx);
|
||||
box-shadow: 0 4rpx 15rpx rgba(255, 107, 107, 0.3);
|
||||
}
|
||||
|
||||
/* 响应式调整 */
|
||||
@media (max-width: 750rpx) {
|
||||
.user-header {
|
||||
padding: 30rpx 20rpx;
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
}
|
||||
|
||||
.menu-section {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
padding: 25rpx;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"usingComponents": {},
|
||||
"navigationBarTitleText": "发布商品",
|
||||
"navigationBarBackgroundColor": "#4285F4",
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
@ -0,0 +1,195 @@
|
||||
<!--pages/publish/publish.wxml-->
|
||||
<view class="publish-container">
|
||||
<!-- 页面标题 -->
|
||||
<view class="page-header">
|
||||
<text class="page-title">发布商品</text>
|
||||
<text class="page-subtitle">确认商品信息并发布到二手市场</text>
|
||||
</view>
|
||||
|
||||
<!-- 商品图片预览 -->
|
||||
<view class="section">
|
||||
<view class="section-header">
|
||||
<text class="section-title">商品图片</text>
|
||||
<button
|
||||
type="primary"
|
||||
size="mini"
|
||||
bindtap="onUploadImage"
|
||||
class="upload-btn"
|
||||
wx:if="{{!fromAIPricing}}"
|
||||
>
|
||||
上传图片
|
||||
</button>
|
||||
</view>
|
||||
<view class="image-preview">
|
||||
<image
|
||||
src="{{productImage}}"
|
||||
mode="aspectFill"
|
||||
class="product-image"
|
||||
wx:if="{{productImage}}"
|
||||
/>
|
||||
<view class="no-image" wx:else>
|
||||
<text class="no-image-text">暂无图片</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 商品基本信息 -->
|
||||
<view class="section">
|
||||
<view class="section-header">
|
||||
<text class="section-title">商品信息</text>
|
||||
</view>
|
||||
<view class="info-group">
|
||||
<view class="info-item">
|
||||
<text class="info-label">商品名称</text>
|
||||
<text class="info-value" wx:if="{{fromAIPricing}}">{{productName}}</text>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="请输入商品名称"
|
||||
value="{{productName}}"
|
||||
bindinput="onProductNameInput"
|
||||
class="info-input"
|
||||
placeholder-class="placeholder"
|
||||
wx:else
|
||||
/>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="info-label">商品类别</text>
|
||||
<text class="info-value" wx:if="{{fromAIPricing}}">{{productCategory}}</text>
|
||||
<picker
|
||||
range="{{categories}}"
|
||||
value="{{categoryIndex}}"
|
||||
bindchange="onCategoryChange"
|
||||
class="category-picker"
|
||||
wx:else
|
||||
>
|
||||
<view class="picker-display">
|
||||
<text class="picker-text">{{categories[categoryIndex] || '请选择商品类别'}}</text>
|
||||
<text class="picker-arrow">▼</text>
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="info-label">商品描述</text>
|
||||
<text class="info-value description-text" wx:if="{{fromAIPricing}}">{{productDescription}}</text>
|
||||
<textarea
|
||||
placeholder="请输入商品描述"
|
||||
value="{{productDescription}}"
|
||||
bindinput="onDescriptionInput"
|
||||
class="description-textarea"
|
||||
placeholder-class="placeholder"
|
||||
maxlength="200"
|
||||
auto-height
|
||||
wx:else
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 价格信息 -->
|
||||
<view class="section">
|
||||
<view class="section-header">
|
||||
<text class="section-title">价格信息</text>
|
||||
</view>
|
||||
<view class="price-group">
|
||||
<view class="price-item">
|
||||
<text class="price-label">原价</text>
|
||||
<text class="price-value original-price">¥{{originalPrice}}</text>
|
||||
</view>
|
||||
<view class="price-item">
|
||||
<text class="price-label">AI建议价格</text>
|
||||
<text class="price-value suggested-price">¥{{suggestedPrice}}</text>
|
||||
</view>
|
||||
<view class="price-item">
|
||||
<text class="price-label">价格范围</text>
|
||||
<text class="price-value range-price">{{priceRange}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 商品状况 -->
|
||||
<view class="section">
|
||||
<view class="section-header">
|
||||
<text class="section-title">商品状况</text>
|
||||
</view>
|
||||
<view class="condition-group">
|
||||
<view class="condition-item">
|
||||
<text class="condition-label">成色</text>
|
||||
<text class="condition-value">{{conditionLevel}}</text>
|
||||
</view>
|
||||
<view class="condition-item">
|
||||
<text class="condition-label">AI评分</text>
|
||||
<text class="condition-value score">{{aiScore}}分</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- AI分析报告 -->
|
||||
<view class="section" wx:if="{{analysisReport}}">
|
||||
<view class="section-header">
|
||||
<text class="section-title">AI分析报告</text>
|
||||
</view>
|
||||
<view class="report-container">
|
||||
<text class="report-text">{{analysisReport}}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 发布设置 -->
|
||||
<view class="section">
|
||||
<view class="section-header">
|
||||
<text class="section-title">发布设置</text>
|
||||
</view>
|
||||
<view class="publish-settings">
|
||||
<view class="setting-item">
|
||||
<text class="setting-label">商品售价</text>
|
||||
<view class="price-input-container">
|
||||
<text class="currency-symbol">¥</text>
|
||||
<input
|
||||
type="digit"
|
||||
placeholder="请输入售价"
|
||||
value="{{salePrice}}"
|
||||
bindinput="onSalePriceInput"
|
||||
class="price-input"
|
||||
placeholder-class="placeholder"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="setting-item">
|
||||
<text class="setting-label">联系方式</text>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="请输入手机号或微信号"
|
||||
value="{{contactInfo}}"
|
||||
bindinput="onContactInput"
|
||||
class="contact-input"
|
||||
placeholder-class="placeholder"
|
||||
/>
|
||||
</view>
|
||||
<view class="setting-item">
|
||||
<text class="setting-label">交易方式</text>
|
||||
<picker
|
||||
range="{{tradeMethods}}"
|
||||
value="{{tradeMethodIndex}}"
|
||||
bindchange="onTradeMethodChange"
|
||||
class="picker"
|
||||
>
|
||||
<view class="picker-display">
|
||||
<text class="picker-text">{{tradeMethods[tradeMethodIndex]}}</text>
|
||||
<text class="picker-arrow">▼</text>
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 发布按钮 -->
|
||||
<view class="publish-actions">
|
||||
<button
|
||||
class="publish-btn {{isPublishing ? 'disabled' : ''}}"
|
||||
bindtap="onPublish"
|
||||
disabled="{{isPublishing}}"
|
||||
>
|
||||
{{isPublishing ? '发布中...' : '确认发布'}}
|
||||
</button>
|
||||
<button class="back-btn" bindtap="onBack">返回修改</button>
|
||||
</view>
|
||||
</view>
|
||||
@ -0,0 +1,362 @@
|
||||
/* pages/publish/publish.wxss */
|
||||
|
||||
.publish-container {
|
||||
padding: 20rpx;
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* 页面标题 */
|
||||
.page-header {
|
||||
text-align: center;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.page-subtitle {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* 通用区块样式 */
|
||||
.section {
|
||||
background: white;
|
||||
border-radius: 16rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.section-header {
|
||||
margin-bottom: 20rpx;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
padding-bottom: 15rpx;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* 商品图片预览 */
|
||||
.image-preview {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 300rpx;
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 12rpx;
|
||||
border: 2rpx dashed #ddd;
|
||||
}
|
||||
|
||||
.product-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.no-image {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.no-image-text {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* 商品信息 */
|
||||
.info-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 20rpx 0;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
min-width: 120rpx;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.description-text {
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* 输入控件样式 */
|
||||
.info-input {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
border: none;
|
||||
outline: none;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.category-picker {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.picker-display {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10rpx 0;
|
||||
}
|
||||
|
||||
.picker-text {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.picker-arrow {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.description-textarea {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
flex: 1;
|
||||
min-height: 120rpx;
|
||||
border: none;
|
||||
outline: none;
|
||||
background: transparent;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
/* 价格信息 */
|
||||
.price-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 15rpx;
|
||||
}
|
||||
|
||||
.price-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.price-label {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.price-value {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.original-price {
|
||||
color: #999;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.suggested-price {
|
||||
color: #ff6b35;
|
||||
}
|
||||
|
||||
.range-price {
|
||||
color: #4285f4;
|
||||
}
|
||||
|
||||
/* 商品状况 */
|
||||
.condition-group {
|
||||
display: flex;
|
||||
gap: 40rpx;
|
||||
}
|
||||
|
||||
.condition-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.condition-label {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.condition-value {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.score {
|
||||
color: #ff6b35;
|
||||
}
|
||||
|
||||
/* AI分析报告 */
|
||||
.report-container {
|
||||
background: #f8f9ff;
|
||||
border: 1rpx solid #e0e7ff;
|
||||
border-radius: 12rpx;
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.report-text {
|
||||
font-size: 24rpx;
|
||||
color: #333;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* 发布设置 */
|
||||
.publish-settings {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 25rpx;
|
||||
}
|
||||
|
||||
.setting-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.setting-label {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
width: 140rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.price-input-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: #f8f9fa;
|
||||
border-radius: 8rpx;
|
||||
padding: 0 20rpx;
|
||||
height: 70rpx;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.currency-symbol {
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.price-input {
|
||||
flex: 1;
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.contact-input {
|
||||
flex: 1;
|
||||
background: #f8f9fa;
|
||||
border-radius: 8rpx;
|
||||
padding: 0 20rpx;
|
||||
height: 70rpx;
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.picker {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.picker-display {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background: #f8f9fa;
|
||||
border-radius: 8rpx;
|
||||
padding: 0 20rpx;
|
||||
height: 70rpx;
|
||||
}
|
||||
|
||||
.picker-text {
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.picker-arrow {
|
||||
font-size: 20rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
/* 发布按钮 */
|
||||
.publish-actions {
|
||||
margin-top: 40rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.publish-btn {
|
||||
background: linear-gradient(135deg, #FF6B35, #4285F4);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 50rpx;
|
||||
height: 80rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
box-shadow: 0 4rpx 20rpx rgba(255, 107, 53, 0.3);
|
||||
}
|
||||
|
||||
.publish-btn.disabled {
|
||||
background: #ccc;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.back-btn {
|
||||
background: white;
|
||||
color: #666;
|
||||
border: 1rpx solid #ddd;
|
||||
border-radius: 50rpx;
|
||||
height: 80rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
/* 响应式调整 */
|
||||
@media (max-width: 750rpx) {
|
||||
.publish-container {
|
||||
padding: 15rpx;
|
||||
}
|
||||
|
||||
.section {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.condition-group {
|
||||
flex-direction: column;
|
||||
gap: 20rpx;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,328 @@
|
||||
// pages/purchase/purchase.js
|
||||
Page({
|
||||
/**
|
||||
* 页面的初始数据
|
||||
*/
|
||||
data: {
|
||||
// 求购商品信息
|
||||
productName: '',
|
||||
categoryIndex: 0,
|
||||
categories: ['电子产品', '服装鞋帽', '家居用品', '图书文具', '运动户外', '美妆个护', '母婴玩具', '其他'],
|
||||
purchaseDescription: '',
|
||||
|
||||
// 求购要求
|
||||
expectedPrice: '',
|
||||
conditionIndex: 0,
|
||||
conditionLevels: ['全新', '95新', '9成新', '8成新', '7成新', '不限'],
|
||||
expectedBrand: '',
|
||||
expectedModel: '',
|
||||
|
||||
// 求购时间
|
||||
expectedDate: '',
|
||||
validityIndex: 0,
|
||||
validityPeriods: ['3天', '7天', '15天', '30天', '长期有效'],
|
||||
|
||||
// 联系方式
|
||||
contactName: '',
|
||||
contactPhone: '',
|
||||
contactWechat: '',
|
||||
tradeMethodIndex: 0,
|
||||
tradeMethods: ['面交', '快递', '均可'],
|
||||
|
||||
// 发布状态
|
||||
isPublishing: false
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad(options) {
|
||||
console.log('求购页面加载', options);
|
||||
// 可以在这里初始化一些数据,比如从缓存中读取用户信息
|
||||
},
|
||||
|
||||
/**
|
||||
* 商品名称输入
|
||||
*/
|
||||
onProductNameInput(e) {
|
||||
this.setData({
|
||||
productName: e.detail.value
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 商品类别选择
|
||||
*/
|
||||
onCategoryChange(e) {
|
||||
this.setData({
|
||||
categoryIndex: parseInt(e.detail.value)
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 求购描述输入
|
||||
*/
|
||||
onDescriptionInput(e) {
|
||||
this.setData({
|
||||
purchaseDescription: e.detail.value
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 期望价格输入
|
||||
*/
|
||||
onExpectedPriceInput(e) {
|
||||
this.setData({
|
||||
expectedPrice: e.detail.value
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 成色要求选择
|
||||
*/
|
||||
onConditionChange(e) {
|
||||
this.setData({
|
||||
conditionIndex: parseInt(e.detail.value)
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 期望品牌输入
|
||||
*/
|
||||
onBrandInput(e) {
|
||||
this.setData({
|
||||
expectedBrand: e.detail.value
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 期望型号输入
|
||||
*/
|
||||
onModelInput(e) {
|
||||
this.setData({
|
||||
expectedModel: e.detail.value
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 期望到货时间选择
|
||||
*/
|
||||
onDateChange(e) {
|
||||
this.setData({
|
||||
expectedDate: e.detail.value
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 有效期选择
|
||||
*/
|
||||
onValidityChange(e) {
|
||||
this.setData({
|
||||
validityIndex: parseInt(e.detail.value)
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 联系人姓名输入
|
||||
*/
|
||||
onContactNameInput(e) {
|
||||
this.setData({
|
||||
contactName: e.detail.value
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 手机号码输入
|
||||
*/
|
||||
onContactPhoneInput(e) {
|
||||
this.setData({
|
||||
contactPhone: e.detail.value
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 微信号输入
|
||||
*/
|
||||
onWechatInput(e) {
|
||||
this.setData({
|
||||
contactWechat: e.detail.value
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 交易方式选择
|
||||
*/
|
||||
onTradeMethodChange(e) {
|
||||
this.setData({
|
||||
tradeMethodIndex: parseInt(e.detail.value)
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 表单验证
|
||||
*/
|
||||
validateForm() {
|
||||
const { productName, contactName, contactPhone } = this.data;
|
||||
|
||||
if (!productName.trim()) {
|
||||
wx.showToast({
|
||||
title: '请输入商品名称',
|
||||
icon: 'none'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!contactName.trim()) {
|
||||
wx.showToast({
|
||||
title: '请输入联系人姓名',
|
||||
icon: 'none'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!contactPhone.trim()) {
|
||||
wx.showToast({
|
||||
title: '请输入手机号码',
|
||||
icon: 'none'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
// 手机号格式验证
|
||||
const phoneRegex = /^1[3-9]\d{9}$/;
|
||||
if (!phoneRegex.test(contactPhone)) {
|
||||
wx.showToast({
|
||||
title: '请输入正确的手机号码',
|
||||
icon: 'none'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* 发布求购
|
||||
*/
|
||||
onPublish() {
|
||||
if (this.data.isPublishing) return;
|
||||
|
||||
if (!this.validateForm()) return;
|
||||
|
||||
this.setData({
|
||||
isPublishing: true
|
||||
});
|
||||
|
||||
// 模拟发布过程
|
||||
wx.showLoading({
|
||||
title: '发布中...'
|
||||
});
|
||||
|
||||
// 构建求购数据
|
||||
const purchaseData = {
|
||||
productName: this.data.productName,
|
||||
category: this.data.categories[this.data.categoryIndex],
|
||||
description: this.data.purchaseDescription,
|
||||
expectedPrice: this.data.expectedPrice,
|
||||
condition: this.data.conditionLevels[this.data.conditionIndex],
|
||||
brand: this.data.expectedBrand,
|
||||
model: this.data.expectedModel,
|
||||
expectedDate: this.data.expectedDate,
|
||||
validity: this.data.validityPeriods[this.data.validityIndex],
|
||||
contactName: this.data.contactName,
|
||||
contactPhone: this.data.contactPhone,
|
||||
wechat: this.data.contactWechat,
|
||||
tradeMethod: this.data.tradeMethods[this.data.tradeMethodIndex],
|
||||
publishTime: new Date().toISOString(),
|
||||
status: 'active'
|
||||
};
|
||||
|
||||
console.log('发布求购数据:', purchaseData);
|
||||
|
||||
// 模拟网络请求
|
||||
setTimeout(() => {
|
||||
wx.hideLoading();
|
||||
|
||||
// 发布成功
|
||||
wx.showToast({
|
||||
title: '发布成功!',
|
||||
icon: 'success',
|
||||
duration: 2000
|
||||
});
|
||||
|
||||
this.setData({
|
||||
isPublishing: false
|
||||
});
|
||||
|
||||
// 发布成功后返回上一页或跳转到求购列表
|
||||
setTimeout(() => {
|
||||
wx.navigateBack();
|
||||
}, 1500);
|
||||
|
||||
}, 2000);
|
||||
},
|
||||
|
||||
/**
|
||||
* 取消发布
|
||||
*/
|
||||
onBack() {
|
||||
wx.showModal({
|
||||
title: '确认取消',
|
||||
content: '确定要取消发布求购吗?已填写的信息将不会保存。',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
wx.navigateBack();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面初次渲染完成
|
||||
*/
|
||||
onReady() {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow() {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面隐藏
|
||||
*/
|
||||
onHide() {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面卸载
|
||||
*/
|
||||
onUnload() {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面相关事件处理函数--监听用户下拉动作
|
||||
*/
|
||||
onPullDownRefresh() {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面上拉触底事件的处理函数
|
||||
*/
|
||||
onReachBottom() {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 用户点击右上角分享
|
||||
*/
|
||||
onShareAppMessage() {
|
||||
|
||||
}
|
||||
})
|
||||
@ -0,0 +1,8 @@
|
||||
{
|
||||
"usingComponents": {},
|
||||
"navigationBarTitleText": "发布求购",
|
||||
"navigationBarBackgroundColor": "#667eea",
|
||||
"navigationBarTextStyle": "white",
|
||||
"backgroundColor": "#f5f5f5",
|
||||
"backgroundTextStyle": "light"
|
||||
}
|
||||
@ -0,0 +1,219 @@
|
||||
<!-- 发布求购页面 -->
|
||||
<view class="purchase-container">
|
||||
<!-- 页面标题 -->
|
||||
<view class="page-header">
|
||||
<text class="page-title">发布求购</text>
|
||||
<text class="page-subtitle">发布您的求购需求,让卖家主动联系您</text>
|
||||
</view>
|
||||
|
||||
<!-- 求购商品信息 -->
|
||||
<view class="section">
|
||||
<view class="section-header">
|
||||
<text class="section-title">求购商品信息</text>
|
||||
</view>
|
||||
<view class="info-group">
|
||||
<view class="info-item">
|
||||
<text class="info-label">商品名称</text>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="请输入您想购买的商品名称"
|
||||
value="{{productName}}"
|
||||
bindinput="onProductNameInput"
|
||||
class="info-input"
|
||||
placeholder-class="placeholder"
|
||||
/>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="info-label">商品类别</text>
|
||||
<picker
|
||||
range="{{categories}}"
|
||||
value="{{categoryIndex}}"
|
||||
bindchange="onCategoryChange"
|
||||
class="category-picker"
|
||||
>
|
||||
<view class="picker-display">
|
||||
<text class="picker-text">{{categories[categoryIndex] || '请选择商品类别'}}</text>
|
||||
<text class="picker-arrow">▼</text>
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="info-label">求购描述</text>
|
||||
<textarea
|
||||
placeholder="请详细描述您的求购需求(品牌、型号、规格等)"
|
||||
value="{{purchaseDescription}}"
|
||||
bindinput="onDescriptionInput"
|
||||
class="description-textarea"
|
||||
placeholder-class="placeholder"
|
||||
maxlength="300"
|
||||
auto-height
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 求购要求 -->
|
||||
<view class="section">
|
||||
<view class="section-header">
|
||||
<text class="section-title">求购要求</text>
|
||||
</view>
|
||||
<view class="requirement-group">
|
||||
<view class="requirement-item">
|
||||
<text class="requirement-label">期望价格</text>
|
||||
<view class="price-input-container">
|
||||
<text class="currency-symbol">¥</text>
|
||||
<input
|
||||
type="digit"
|
||||
placeholder="请输入期望价格"
|
||||
value="{{expectedPrice}}"
|
||||
bindinput="onExpectedPriceInput"
|
||||
class="price-input"
|
||||
placeholder-class="placeholder"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="requirement-item">
|
||||
<text class="requirement-label">成色要求</text>
|
||||
<picker
|
||||
range="{{conditionLevels}}"
|
||||
value="{{conditionIndex}}"
|
||||
bindchange="onConditionChange"
|
||||
class="condition-picker"
|
||||
>
|
||||
<view class="picker-display">
|
||||
<text class="picker-text">{{conditionLevels[conditionIndex] || '请选择成色要求'}}</text>
|
||||
<text class="picker-arrow">▼</text>
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
<view class="requirement-item">
|
||||
<text class="requirement-label">期望品牌</text>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="请输入期望品牌(可选)"
|
||||
value="{{expectedBrand}}"
|
||||
bindinput="onBrandInput"
|
||||
class="brand-input"
|
||||
placeholder-class="placeholder"
|
||||
/>
|
||||
</view>
|
||||
<view class="requirement-item">
|
||||
<text class="requirement-label">期望型号</text>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="请输入期望型号(可选)"
|
||||
value="{{expectedModel}}"
|
||||
bindinput="onModelInput"
|
||||
class="model-input"
|
||||
placeholder-class="placeholder"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 求购时间 -->
|
||||
<view class="section">
|
||||
<view class="section-header">
|
||||
<text class="section-title">求购时间</text>
|
||||
</view>
|
||||
<view class="time-group">
|
||||
<view class="time-item">
|
||||
<text class="time-label">期望到货时间</text>
|
||||
<picker
|
||||
mode="date"
|
||||
value="{{expectedDate}}"
|
||||
bindchange="onDateChange"
|
||||
class="date-picker"
|
||||
>
|
||||
<view class="picker-display">
|
||||
<text class="picker-text">{{expectedDate || '请选择期望到货时间'}}</text>
|
||||
<text class="picker-arrow">▼</text>
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
<view class="time-item">
|
||||
<text class="time-label">求购有效期</text>
|
||||
<picker
|
||||
range="{{validityPeriods}}"
|
||||
value="{{validityIndex}}"
|
||||
bindchange="onValidityChange"
|
||||
class="validity-picker"
|
||||
>
|
||||
<view class="picker-display">
|
||||
<text class="picker-text">{{validityPeriods[validityIndex] || '请选择有效期'}}</text>
|
||||
<text class="picker-arrow">▼</text>
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 联系方式 -->
|
||||
<view class="section">
|
||||
<view class="section-header">
|
||||
<text class="section-title">联系方式</text>
|
||||
</view>
|
||||
<view class="contact-group">
|
||||
<view class="contact-item">
|
||||
<text class="contact-label">联系人</text>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="请输入您的姓名"
|
||||
value="{{contactName}}"
|
||||
bindinput="onContactNameInput"
|
||||
class="contact-input"
|
||||
placeholder-class="placeholder"
|
||||
/>
|
||||
</view>
|
||||
<view class="contact-item">
|
||||
<text class="contact-label">手机号码</text>
|
||||
<input
|
||||
type="number"
|
||||
placeholder="请输入手机号码"
|
||||
value="{{contactPhone}}"
|
||||
bindinput="onContactPhoneInput"
|
||||
class="phone-input"
|
||||
placeholder-class="placeholder"
|
||||
maxlength="11"
|
||||
/>
|
||||
</view>
|
||||
<view class="contact-item">
|
||||
<text class="contact-label">微信号</text>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="请输入微信号(可选)"
|
||||
value="{{contactWechat}}"
|
||||
bindinput="onWechatInput"
|
||||
class="wechat-input"
|
||||
placeholder-class="placeholder"
|
||||
/>
|
||||
</view>
|
||||
<view class="contact-item">
|
||||
<text class="contact-label">交易方式</text>
|
||||
<picker
|
||||
range="{{tradeMethods}}"
|
||||
value="{{tradeMethodIndex}}"
|
||||
bindchange="onTradeMethodChange"
|
||||
class="trade-picker"
|
||||
>
|
||||
<view class="picker-display">
|
||||
<text class="picker-text">{{tradeMethods[tradeMethodIndex] || '请选择交易方式'}}</text>
|
||||
<text class="picker-arrow">▼</text>
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 发布按钮 -->
|
||||
<view class="publish-actions">
|
||||
<button
|
||||
class="publish-btn {{isPublishing ? 'disabled' : ''}}"
|
||||
bindtap="onPublish"
|
||||
disabled="{{isPublishing}}"
|
||||
>
|
||||
{{isPublishing ? '发布中...' : '确认发布求购'}}
|
||||
</button>
|
||||
<button class="back-btn" bindtap="onBack">取消</button>
|
||||
</view>
|
||||
</view>
|
||||
@ -0,0 +1,320 @@
|
||||
/* 发布求购页面样式 */
|
||||
.purchase-container {
|
||||
padding: 20rpx;
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* 页面标题 */
|
||||
.page-header {
|
||||
text-align: center;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.page-subtitle {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* 通用区块样式 */
|
||||
.section {
|
||||
background: white;
|
||||
border-radius: 16rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.section-header {
|
||||
margin-bottom: 20rpx;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
padding-bottom: 15rpx;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* 求购信息组 */
|
||||
.info-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 20rpx 0;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
min-width: 120rpx;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
/* 输入控件样式 */
|
||||
.info-input {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
border: none;
|
||||
outline: none;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.category-picker {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.picker-display {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10rpx 0;
|
||||
}
|
||||
|
||||
.picker-text {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.picker-arrow {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.description-textarea {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
flex: 1;
|
||||
min-height: 120rpx;
|
||||
border: none;
|
||||
outline: none;
|
||||
background: transparent;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
/* 求购要求组 */
|
||||
.requirement-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.requirement-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 15rpx 0;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.requirement-label {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
min-width: 120rpx;
|
||||
}
|
||||
|
||||
/* 价格输入容器 */
|
||||
.price-input-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.currency-symbol {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.price-input {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
border: none;
|
||||
outline: none;
|
||||
background: transparent;
|
||||
text-align: right;
|
||||
width: 200rpx;
|
||||
}
|
||||
|
||||
.condition-picker {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.brand-input, .model-input {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
border: none;
|
||||
outline: none;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/* 时间组 */
|
||||
.time-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.time-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 15rpx 0;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.time-label {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
min-width: 120rpx;
|
||||
}
|
||||
|
||||
.date-picker, .validity-picker {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* 联系方式组 */
|
||||
.contact-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.contact-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 15rpx 0;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.contact-label {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
min-width: 120rpx;
|
||||
}
|
||||
|
||||
.contact-input, .phone-input, .wechat-input {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
border: none;
|
||||
outline: none;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.trade-picker {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* 发布按钮 */
|
||||
.publish-actions {
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
margin-top: 40rpx;
|
||||
}
|
||||
|
||||
.publish-btn {
|
||||
flex: 2;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 50rpx;
|
||||
padding: 25rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
box-shadow: 0 4rpx 20rpx rgba(102, 126, 234, 0.3);
|
||||
}
|
||||
|
||||
.publish-btn.disabled {
|
||||
background: #ccc;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.back-btn {
|
||||
flex: 1;
|
||||
background: #f8f9fa;
|
||||
color: #666;
|
||||
border: 1rpx solid #ddd;
|
||||
border-radius: 50rpx;
|
||||
padding: 25rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
/* 特殊样式:求购页面特色 */
|
||||
.purchase-container .section {
|
||||
border-left: 4rpx solid #667eea;
|
||||
}
|
||||
|
||||
.purchase-container .section-header {
|
||||
border-bottom-color: #e8ecff;
|
||||
}
|
||||
|
||||
.purchase-container .section-title {
|
||||
color: #667eea;
|
||||
}
|
||||
|
||||
/* 响应式调整 */
|
||||
@media (max-width: 375px) {
|
||||
.purchase-container {
|
||||
padding: 15rpx;
|
||||
}
|
||||
|
||||
.section {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.info-item, .requirement-item, .time-item, .contact-item {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 10rpx;
|
||||
}
|
||||
|
||||
.info-label, .requirement-label, .time-label, .contact-label {
|
||||
min-width: auto;
|
||||
}
|
||||
|
||||
.info-input, .price-input, .brand-input, .model-input,
|
||||
.contact-input, .phone-input, .wechat-input {
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.price-input-container {
|
||||
justify-content: flex-start;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,391 @@
|
||||
// register.js
|
||||
Page({
|
||||
data: {
|
||||
// 基本信息
|
||||
studentId: '',
|
||||
name: '',
|
||||
phone: '',
|
||||
password: '',
|
||||
confirmPassword: '',
|
||||
|
||||
// 学校信息
|
||||
school: '中国民航大学',
|
||||
department: '',
|
||||
major: '',
|
||||
grades: ['大一', '大二', '大三', '大四', '研究生', '博士生'],
|
||||
gradeIndex: 0,
|
||||
dormBuilding: '',
|
||||
dormRoom: '',
|
||||
|
||||
// 协议
|
||||
agreed: false,
|
||||
|
||||
// 按钮状态
|
||||
isRegisterDisabled: false
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
// 页面加载时初始化
|
||||
this.checkRegisterButton();
|
||||
},
|
||||
|
||||
// 学号输入处理
|
||||
onInputStudentId(e) {
|
||||
const studentId = e.detail.value.trim();
|
||||
this.setData({
|
||||
studentId: studentId
|
||||
});
|
||||
this.checkRegisterButton();
|
||||
},
|
||||
|
||||
// 姓名输入处理
|
||||
onInputName(e) {
|
||||
const name = e.detail.value.trim();
|
||||
this.setData({
|
||||
name: name
|
||||
});
|
||||
this.checkRegisterButton();
|
||||
},
|
||||
|
||||
// 手机号输入处理
|
||||
onInputPhone(e) {
|
||||
const phone = e.detail.value.trim();
|
||||
this.setData({
|
||||
phone: phone
|
||||
});
|
||||
this.checkRegisterButton();
|
||||
},
|
||||
|
||||
// 密码输入处理
|
||||
onInputPassword(e) {
|
||||
const password = e.detail.value.trim();
|
||||
this.setData({
|
||||
password: password
|
||||
});
|
||||
this.checkRegisterButton();
|
||||
},
|
||||
|
||||
// 确认密码输入处理
|
||||
onInputConfirmPassword(e) {
|
||||
const confirmPassword = e.detail.value.trim();
|
||||
this.setData({
|
||||
confirmPassword: confirmPassword
|
||||
});
|
||||
this.checkRegisterButton();
|
||||
},
|
||||
|
||||
// 学院输入处理
|
||||
onInputDepartment(e) {
|
||||
const department = e.detail.value.trim();
|
||||
this.setData({
|
||||
department: department
|
||||
});
|
||||
this.checkRegisterButton();
|
||||
},
|
||||
|
||||
// 专业输入处理
|
||||
onInputMajor(e) {
|
||||
const major = e.detail.value.trim();
|
||||
this.setData({
|
||||
major: major
|
||||
});
|
||||
this.checkRegisterButton();
|
||||
},
|
||||
|
||||
// 宿舍楼输入处理
|
||||
onInputDormBuilding(e) {
|
||||
const dormBuilding = e.detail.value.trim();
|
||||
this.setData({
|
||||
dormBuilding: dormBuilding
|
||||
});
|
||||
this.checkRegisterButton();
|
||||
},
|
||||
|
||||
// 宿舍号输入处理
|
||||
onInputDormRoom(e) {
|
||||
const dormRoom = e.detail.value.trim();
|
||||
this.setData({
|
||||
dormRoom: dormRoom
|
||||
});
|
||||
this.checkRegisterButton();
|
||||
},
|
||||
|
||||
// 年级选择处理
|
||||
onGradeChange(e) {
|
||||
const index = parseInt(e.detail.value);
|
||||
this.setData({
|
||||
gradeIndex: index
|
||||
});
|
||||
this.checkRegisterButton();
|
||||
},
|
||||
|
||||
// 协议勾选处理
|
||||
onAgreementChange(e) {
|
||||
// 微信小程序 checkbox 的 e.detail.value 是一个数组
|
||||
// 当勾选时,数组包含选中的值;未勾选时,数组为空
|
||||
const agreed = e.detail.value.length > 0;
|
||||
this.setData({
|
||||
agreed: agreed
|
||||
});
|
||||
this.checkRegisterButton();
|
||||
},
|
||||
|
||||
// 检查注册按钮状态
|
||||
checkRegisterButton() {
|
||||
const {
|
||||
studentId,
|
||||
name,
|
||||
phone,
|
||||
password,
|
||||
confirmPassword,
|
||||
department,
|
||||
major,
|
||||
gradeIndex,
|
||||
agreed
|
||||
} = this.data;
|
||||
|
||||
// 基本验证(只检查必填字段)
|
||||
const isBasicValid = studentId && name && phone && password && confirmPassword;
|
||||
|
||||
// 学校信息验证(只检查必填字段)
|
||||
const isSchoolValid = department && major && gradeIndex >= 0;
|
||||
|
||||
// 协议同意
|
||||
const isAgreed = agreed;
|
||||
|
||||
// 综合验证:只要必填字段和协议都满足,按钮就可用
|
||||
// 密码格式和手机号格式在点击注册时再验证
|
||||
const isRegisterDisabled = !(isBasicValid && isSchoolValid && isAgreed);
|
||||
|
||||
this.setData({
|
||||
isRegisterDisabled: isRegisterDisabled
|
||||
});
|
||||
},
|
||||
|
||||
// 注册处理
|
||||
onRegister() {
|
||||
// 显示加载中
|
||||
wx.showLoading({
|
||||
title: '注册中...',
|
||||
mask: true
|
||||
});
|
||||
|
||||
// 直接调用注册方法,跳过所有验证
|
||||
this.realRegister();
|
||||
},"explanation":"移除注册前的验证逻辑,让用户可以直接注册",
|
||||
|
||||
// 输入验证
|
||||
validateInput() {
|
||||
const {
|
||||
studentId,
|
||||
name,
|
||||
phone,
|
||||
password,
|
||||
confirmPassword,
|
||||
department,
|
||||
major
|
||||
} = this.data;
|
||||
|
||||
// 学号验证
|
||||
if (!studentId) {
|
||||
wx.showToast({
|
||||
title: '请输入学号',
|
||||
icon: 'none'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
// 姓名验证
|
||||
if (!name) {
|
||||
wx.showToast({
|
||||
title: '请输入姓名',
|
||||
icon: 'none'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
// 手机号验证
|
||||
if (!phone) {
|
||||
wx.showToast({
|
||||
title: '请输入手机号',
|
||||
icon: 'none'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!/^1[3-9]\d{9}$/.test(phone)) {
|
||||
wx.showToast({
|
||||
title: '请输入正确的手机号',
|
||||
icon: 'none'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
// 密码验证
|
||||
if (!password) {
|
||||
wx.showToast({
|
||||
title: '请输入密码',
|
||||
icon: 'none'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
if (password.length < 6) {
|
||||
wx.showToast({
|
||||
title: '密码长度不能少于6位',
|
||||
icon: 'none'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
if (password !== confirmPassword) {
|
||||
wx.showToast({
|
||||
title: '两次输入的密码不一致',
|
||||
icon: 'none'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
// 学校信息验证
|
||||
if (!department) {
|
||||
wx.showToast({
|
||||
title: '请输入学院名称',
|
||||
icon: 'none'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!major) {
|
||||
wx.showToast({
|
||||
title: '请输入专业名称',
|
||||
icon: 'none'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
// 协议验证
|
||||
if (!this.data.agreed) {
|
||||
wx.showToast({
|
||||
title: '请同意用户协议和隐私政策',
|
||||
icon: 'none'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
// 真实注册(保存到云数据库)
|
||||
realRegister() {
|
||||
const db = wx.cloud.database();
|
||||
|
||||
// 检查手机号或学号是否已存在
|
||||
db.collection('T_user').where({
|
||||
$or: [
|
||||
{ phone: this.data.phone },
|
||||
{ sno: this.data.studentId }
|
||||
]
|
||||
}).get({
|
||||
success: (res) => {
|
||||
if (res.data.length > 0) {
|
||||
// 手机号或学号已存在
|
||||
wx.hideLoading();
|
||||
wx.showToast({
|
||||
title: '手机号或学号已存在',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 插入新用户到数据库
|
||||
db.collection('T_user').add({
|
||||
data: {
|
||||
sno: this.data.studentId,
|
||||
sname: this.data.name,
|
||||
phone: this.data.phone,
|
||||
password: this.data.password,
|
||||
major: this.data.major,
|
||||
sushe: this.data.dormBuilding + ' ' + this.data.dormRoom,
|
||||
年级: this.data.grades[this.data.gradeIndex],
|
||||
avatar: 'https://via.placeholder.com/100x100/4285F4/ffffff?text=' + this.data.name.slice(0, 1),
|
||||
createTime: new Date()
|
||||
},
|
||||
success: (addRes) => {
|
||||
wx.hideLoading();
|
||||
|
||||
// 注册成功,保存用户信息到本地存储
|
||||
const userInfo = {
|
||||
_id: addRes._id,
|
||||
sno: this.data.studentId,
|
||||
sname: this.data.name,
|
||||
phone: this.data.phone,
|
||||
major: this.data.major,
|
||||
sushe: this.data.dormBuilding + ' ' + this.data.dormRoom,
|
||||
grade: this.data.grades[this.data.gradeIndex],
|
||||
avatar: 'https://via.placeholder.com/100x100/4285F4/ffffff?text=' + this.data.name.slice(0, 1)
|
||||
};
|
||||
|
||||
wx.setStorageSync('userInfo', userInfo);
|
||||
wx.setStorageSync('token', 'user_token_' + addRes._id);
|
||||
|
||||
wx.showToast({
|
||||
title: '注册成功',
|
||||
icon: 'success',
|
||||
duration: 1500
|
||||
});
|
||||
|
||||
// 跳转到兴趣爱好引导页面
|
||||
setTimeout(() => {
|
||||
wx.navigateTo({
|
||||
url: '/pages/interests/interests'
|
||||
});
|
||||
}, 1500);
|
||||
},
|
||||
fail: (err) => {
|
||||
wx.hideLoading();
|
||||
console.error('注册失败:', err);
|
||||
wx.showToast({
|
||||
title: '注册失败,请重试',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
fail: (err) => {
|
||||
wx.hideLoading();
|
||||
console.error('查询用户失败:', err);
|
||||
wx.showToast({
|
||||
title: '网络错误,请重试',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 查看用户协议
|
||||
onViewAgreement() {
|
||||
wx.showModal({
|
||||
title: '用户协议',
|
||||
content: '欢迎使用校园二手交易平台!请仔细阅读并同意我们的用户协议。\n\n1. 用户需保证所填信息的真实性\n2. 遵守平台交易规则\n3. 尊重他人隐私和权益\n4. 禁止发布违法违规内容',
|
||||
showCancel: false,
|
||||
confirmText: '我知道了'
|
||||
});
|
||||
},
|
||||
|
||||
// 查看隐私政策
|
||||
onViewPrivacy() {
|
||||
wx.showModal({
|
||||
title: '隐私政策',
|
||||
content: '我们非常重视您的隐私保护。\n\n1. 我们仅收集必要的个人信息\n2. 您的信息将用于个性化推荐\n3. 我们不会泄露您的个人信息\n4. 您可以随时管理您的隐私设置',
|
||||
showCancel: false,
|
||||
confirmText: '我知道了'
|
||||
});
|
||||
},
|
||||
|
||||
// 跳转到登录页面
|
||||
onGoToLogin() {
|
||||
wx.navigateBack({
|
||||
delta: 1
|
||||
});
|
||||
}
|
||||
})
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"usingComponents": {},
|
||||
"navigationBarTitleText": "用户注册"
|
||||
}
|
||||
@ -0,0 +1,220 @@
|
||||
/**register.wxss**/
|
||||
page {
|
||||
height: 100vh;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.page-container {
|
||||
height: 100vh;
|
||||
background: #ffffff;
|
||||
padding: 40rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.register-container {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 头部样式 */
|
||||
.header {
|
||||
text-align: center;
|
||||
margin-bottom: 60rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 48rpx;
|
||||
font-weight: bold;
|
||||
color: #333333;
|
||||
display: block;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 28rpx;
|
||||
color: #666666;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* 注册表单样式 */
|
||||
.register-form {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* 表单分区 */
|
||||
.form-section {
|
||||
margin-bottom: 60rpx;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333333;
|
||||
margin-bottom: 24rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.section-subtitle {
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
margin-bottom: 24rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* 表单组 */
|
||||
.form-group {
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
margin-bottom: 16rpx;
|
||||
display: block;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.input {
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
border: 2rpx solid #e0e0e0;
|
||||
border-radius: 12rpx;
|
||||
padding: 0 24rpx;
|
||||
font-size: 28rpx;
|
||||
background: #ffffff;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.input:focus {
|
||||
border-color: #4285F4;
|
||||
box-shadow: 0 0 0 4rpx rgba(66, 133, 244, 0.1);
|
||||
}
|
||||
|
||||
/* 固定学校样式 */
|
||||
.fixed-school {
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
border: 2rpx solid #e0e0e0;
|
||||
border-radius: 12rpx;
|
||||
padding: 0 24rpx;
|
||||
font-size: 28rpx;
|
||||
background: #f8f9fa;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #666666;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 选择器样式 */
|
||||
.picker {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.picker-value {
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
border: 2rpx solid #e0e0e0;
|
||||
border-radius: 12rpx;
|
||||
padding: 0 24rpx;
|
||||
font-size: 28rpx;
|
||||
background: #ffffff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.picker-value::after {
|
||||
content: '▼';
|
||||
margin-left: auto;
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
/* 兴趣爱好标签 */
|
||||
.interest-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 20rpx;
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
|
||||
.tag {
|
||||
padding: 16rpx 32rpx;
|
||||
border: 2rpx solid #e0e0e0;
|
||||
border-radius: 24rpx;
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
background: #f8f9fa;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.tag.selected {
|
||||
border-color: #4285F4;
|
||||
background: rgba(66, 133, 244, 0.1);
|
||||
color: #4285F4;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 协议样式 */
|
||||
.agreement {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
margin: 40rpx 0;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.agreement-text {
|
||||
color: #666666;
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
.agreement-link {
|
||||
color: #4285F4;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* 注册按钮 */
|
||||
.register-btn {
|
||||
width: 100%;
|
||||
height: 96rpx;
|
||||
background: linear-gradient(135deg, #4285F4, #3367D6);
|
||||
border: none;
|
||||
border-radius: 16rpx;
|
||||
color: #ffffff;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
margin-bottom: 32rpx;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.register-btn:active {
|
||||
transform: scale(0.98);
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.register-btn.disabled {
|
||||
background: #cccccc;
|
||||
color: #999999;
|
||||
transform: none;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
/* 登录链接 */
|
||||
.login-link {
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.link {
|
||||
color: #4285F4;
|
||||
font-weight: 500;
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
@ -0,0 +1,117 @@
|
||||
// test.js
|
||||
Page({
|
||||
data: {
|
||||
dbStatus: '',
|
||||
userCount: 0,
|
||||
userList: [],
|
||||
testResult: ''
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
this.checkDatabase();
|
||||
},
|
||||
|
||||
// 检查数据库状态
|
||||
checkDatabase() {
|
||||
wx.showLoading({
|
||||
title: '检查数据库中...',
|
||||
});
|
||||
|
||||
wx.cloud.callFunction({
|
||||
name: 'quickstartFunctions',
|
||||
data: {
|
||||
type: 'queryTUser'
|
||||
},
|
||||
success: (res) => {
|
||||
wx.hideLoading();
|
||||
if (res.result.success) {
|
||||
this.setData({
|
||||
dbStatus: '数据库连接正常',
|
||||
userCount: res.result.count,
|
||||
userList: res.result.data
|
||||
});
|
||||
} else {
|
||||
this.setData({
|
||||
dbStatus: '数据库查询失败: ' + res.result.error
|
||||
});
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
wx.hideLoading();
|
||||
this.setData({
|
||||
dbStatus: '云函数调用失败: ' + err.errMsg
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 添加测试用户
|
||||
addTestUser() {
|
||||
wx.showLoading({
|
||||
title: '添加测试用户...',
|
||||
});
|
||||
|
||||
wx.cloud.callFunction({
|
||||
name: 'quickstartFunctions',
|
||||
data: {
|
||||
type: 'addTestUser',
|
||||
userData: {
|
||||
sno: "230340151",
|
||||
sname: "测试用户",
|
||||
phone: "13800138000",
|
||||
password: "100997@mkg",
|
||||
major: "计算机科学",
|
||||
sushe: "1号楼 101",
|
||||
年级: "大三",
|
||||
avatar: "https://via.placeholder.com/100x100/4285F4/ffffff?text=T"
|
||||
}
|
||||
},
|
||||
success: (res) => {
|
||||
wx.hideLoading();
|
||||
if (res.result.success) {
|
||||
this.setData({
|
||||
testResult: '测试用户添加成功!现在可以尝试登录。'
|
||||
});
|
||||
this.checkDatabase(); // 刷新数据
|
||||
} else {
|
||||
this.setData({
|
||||
testResult: '添加失败: ' + res.result.error
|
||||
});
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
wx.hideLoading();
|
||||
this.setData({
|
||||
testResult: '云函数调用失败: ' + err.errMsg
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 测试登录功能
|
||||
testLogin() {
|
||||
// 直接调用登录页面的登录方法
|
||||
const pages = getCurrentPages();
|
||||
const indexPage = pages.find(page => page.route === 'pages/index/index');
|
||||
|
||||
if (indexPage) {
|
||||
indexPage.setData({
|
||||
studentId: '230340151',
|
||||
password: '100997@mkg'
|
||||
});
|
||||
indexPage.onLogin();
|
||||
} else {
|
||||
wx.showToast({
|
||||
title: '请先返回登录页面',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 跳转到登录页面
|
||||
goToLogin() {
|
||||
wx.navigateTo({
|
||||
url: '/pages/index/index'
|
||||
});
|
||||
}
|
||||
})
|
||||
@ -0,0 +1,39 @@
|
||||
<!-- test.wxml -->
|
||||
<view class="container">
|
||||
<view class="header">
|
||||
<text class="title">数据库测试页面</text>
|
||||
<text class="subtitle">用于检查云数据库状态和测试登录功能</text>
|
||||
</view>
|
||||
|
||||
<view class="section">
|
||||
<text class="section-title">数据库状态</text>
|
||||
<view class="status-box">
|
||||
<text class="status-text">{{dbStatus}}</text>
|
||||
<text class="user-count">用户数量: {{userCount}}</text>
|
||||
</view>
|
||||
<button class="btn" bindtap="checkDatabase">刷新状态</button>
|
||||
</view>
|
||||
|
||||
<view class="section" wx:if="{{userList.length > 0}}">
|
||||
<text class="section-title">用户列表</text>
|
||||
<view class="user-list">
|
||||
<view class="user-item" wx:for="{{userList}}" wx:key="_id">
|
||||
<text class="user-info">学号: {{item.sno}} | 姓名: {{item.sname}} | 手机: {{item.phone}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="section">
|
||||
<text class="section-title">测试操作</text>
|
||||
<button class="btn primary" bindtap="addTestUser">添加测试用户</button>
|
||||
<button class="btn success" bindtap="testLogin">测试登录</button>
|
||||
<button class="btn" bindtap="goToLogin">前往登录页面</button>
|
||||
</view>
|
||||
|
||||
<view class="section" wx:if="{{testResult}}">
|
||||
<text class="section-title">测试结果</text>
|
||||
<view class="result-box">
|
||||
<text class="result-text">{{testResult}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@ -0,0 +1,115 @@
|
||||
/* test.wxss */
|
||||
.container {
|
||||
padding: 20rpx;
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.header {
|
||||
text-align: center;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
display: block;
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
display: block;
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.section {
|
||||
background: white;
|
||||
border-radius: 10rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
box-shadow: 0 2rpx 10rpx rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.section-title {
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.status-box {
|
||||
background: #f8f9fa;
|
||||
border-radius: 8rpx;
|
||||
padding: 20rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.status-text {
|
||||
display: block;
|
||||
font-size: 24rpx;
|
||||
color: #333;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.user-count {
|
||||
display: block;
|
||||
font-size: 22rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.user-list {
|
||||
max-height: 300rpx;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.user-item {
|
||||
padding: 15rpx;
|
||||
border-bottom: 1rpx solid #eee;
|
||||
}
|
||||
|
||||
.user-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
font-size: 22rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 100%;
|
||||
margin-bottom: 20rpx;
|
||||
background: #007AFF;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 8rpx;
|
||||
padding: 20rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.btn.primary {
|
||||
background: #007AFF;
|
||||
}
|
||||
|
||||
.btn.success {
|
||||
background: #34C759;
|
||||
}
|
||||
|
||||
.btn:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.result-box {
|
||||
background: #f8f9fa;
|
||||
border-radius: 8rpx;
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.result-text {
|
||||
font-size: 24rpx;
|
||||
color: #333;
|
||||
line-height: 1.5;
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
{
|
||||
"desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
|
||||
"rules": [{
|
||||
"action": "allow",
|
||||
"page": "*"
|
||||
}]
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
// Coze API配置
|
||||
module.exports = {
|
||||
// Coze API配置
|
||||
token: 'YOUR_COZE_API_TOKEN_HERE', // 请替换为您的Coze API Token
|
||||
workflow_id: 'YOUR_WORKFLOW_ID_HERE', // 请替换为您的Workflow ID
|
||||
api_url: 'https://api.coze.cn/v1/workflows/runs',
|
||||
|
||||
// 微信云开发配置
|
||||
cloud_storage_path: 'coze-images/',
|
||||
|
||||
// 超时设置
|
||||
timeout: 30000,
|
||||
|
||||
// 调试模式
|
||||
debug: true
|
||||
};
|
||||
@ -0,0 +1,85 @@
|
||||
{
|
||||
"miniprogramRoot": "miniprogram/",
|
||||
"cloudfunctionRoot": "cloudfunctions/",
|
||||
"setting": {
|
||||
"urlCheck": true,
|
||||
"es6": true,
|
||||
"enhance": true,
|
||||
"postcss": true,
|
||||
"preloadBackgroundData": false,
|
||||
"minified": true,
|
||||
"newFeature": true,
|
||||
"coverView": true,
|
||||
"nodeModules": false,
|
||||
"autoAudits": false,
|
||||
"showShadowRootInWxmlPanel": true,
|
||||
"scopeDataCheck": false,
|
||||
"uglifyFileName": false,
|
||||
"checkInvalidKey": true,
|
||||
"checkSiteMap": true,
|
||||
"uploadWithSourceMap": true,
|
||||
"compileHotReLoad": false,
|
||||
"useMultiFrameRuntime": true,
|
||||
"useApiHook": true,
|
||||
"useApiHostProcess": true,
|
||||
"babelSetting": {
|
||||
"ignore": [],
|
||||
"disablePlugins": [],
|
||||
"outputPath": ""
|
||||
},
|
||||
"enableEngineNative": false,
|
||||
"useIsolateContext": true,
|
||||
"useCompilerModule": true,
|
||||
"userConfirmedUseCompilerModuleSwitch": false,
|
||||
"userConfirmedBundleSwitch": false,
|
||||
"packNpmManually": false,
|
||||
"packNpmRelationList": [],
|
||||
"minifyWXSS": true,
|
||||
"compileWorklet": false,
|
||||
"minifyWXML": true,
|
||||
"localPlugins": false,
|
||||
"disableUseStrict": false,
|
||||
"useCompilerPlugins": false,
|
||||
"condition": false,
|
||||
"swc": false,
|
||||
"disableSWC": true
|
||||
},
|
||||
"appid": "wx0f9e605dfd3db597",
|
||||
"projectname": "quickstart-wx-cloud",
|
||||
"libVersion": "2.20.1",
|
||||
"cloudfunctionTemplateRoot": "cloudfunctionTemplate/",
|
||||
"condition": {
|
||||
"search": {
|
||||
"list": []
|
||||
},
|
||||
"conversation": {
|
||||
"list": []
|
||||
},
|
||||
"plugin": {
|
||||
"list": []
|
||||
},
|
||||
"game": {
|
||||
"list": []
|
||||
},
|
||||
"miniprogram": {
|
||||
"list": [
|
||||
{
|
||||
"id": -1,
|
||||
"name": "db guide",
|
||||
"pathName": "pages/databaseGuide/databaseGuide"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"compileType": "miniprogram",
|
||||
"srcMiniprogramRoot": "miniprogram/",
|
||||
"packOptions": {
|
||||
"ignore": [],
|
||||
"include": []
|
||||
},
|
||||
"editorSetting": {
|
||||
"tabIndent": "insertSpaces",
|
||||
"tabSize": 2
|
||||
},
|
||||
"simulatorPluginLibVersion": {}
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
${installPath} cloud functions deploy --e ${envId} --n quickstartFunctions --r --project ${projectPath}
|
||||