Compare commits
3 Commits
817a215c74
...
6613402217
Author | SHA1 | Date |
---|---|---|
|
6613402217 | 4 weeks ago |
|
63b5057868 | 4 weeks ago |
|
361d4518a9 | 4 weeks ago |
@ -0,0 +1 @@
|
||||
{"containers":[],"config":{}}
|
@ -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,15 @@
|
||||
{
|
||||
"name": "completeorder",
|
||||
"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.6.3"
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "createorder",
|
||||
"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.6.3"
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
// 云函数getGoodsDetail
|
||||
const cloud = require('wx-server-sdk')
|
||||
|
||||
// 初始化cloud
|
||||
cloud.init({
|
||||
env: cloud.DYNAMIC_CURRENT_ENV
|
||||
})
|
||||
const db = cloud.database()
|
||||
|
||||
exports.main = async (event, context) => {
|
||||
const { goodsId } = event
|
||||
|
||||
if (!goodsId) {
|
||||
return {
|
||||
success: false,
|
||||
message: '参数错误'
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// 获取商品详情
|
||||
const goodsResult = await db.collection('secondhand_goods').doc(goodsId).get()
|
||||
|
||||
if (!goodsResult.data) {
|
||||
return {
|
||||
success: false,
|
||||
message: '商品不存在'
|
||||
}
|
||||
}
|
||||
|
||||
// 获取卖家信息
|
||||
const sellerResult = await db.collection('users').where({
|
||||
openid: goodsResult.data.openid
|
||||
}).field({
|
||||
nickName: true,
|
||||
avatarUrl: true
|
||||
}).get()
|
||||
|
||||
const seller = sellerResult.data.length > 0 ? sellerResult.data[0] : {}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: {
|
||||
...goodsResult.data,
|
||||
seller
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
message: '获取商品详情失败',
|
||||
error: error.message
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "getgoodsdetail",
|
||||
"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.6.3"
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "getmyorders",
|
||||
"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.6.3"
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
// 云函数getSecondhandGoods
|
||||
const cloud = require('wx-server-sdk')
|
||||
|
||||
// 初始化cloud
|
||||
cloud.init({
|
||||
env: cloud.DYNAMIC_CURRENT_ENV
|
||||
})
|
||||
const db = cloud.database()
|
||||
const _ = db.command
|
||||
|
||||
exports.main = async (event, context) => {
|
||||
// 从请求中获取参数
|
||||
const {
|
||||
category = 'all',
|
||||
keyword = '',
|
||||
pageNum = 1,
|
||||
pageSize = 10,
|
||||
sortBy = 'createTime'
|
||||
} = event
|
||||
|
||||
// 构建查询条件
|
||||
let query = {}
|
||||
|
||||
// 根据分类筛选
|
||||
if (category !== 'all') {
|
||||
query.category = category
|
||||
}
|
||||
|
||||
// 根据关键词搜索标题
|
||||
if (keyword) {
|
||||
query.title = db.RegExp({
|
||||
regexp: keyword,
|
||||
options: 'i',
|
||||
})
|
||||
}
|
||||
|
||||
// 只查询未售出的商品
|
||||
query.status = 'available'
|
||||
|
||||
// 计算总数
|
||||
const countResult = await db.collection('secondhand_goods')
|
||||
.where(query)
|
||||
.count()
|
||||
const total = countResult.total
|
||||
|
||||
// 构建排序条件
|
||||
let orderBy = {}
|
||||
switch(sortBy) {
|
||||
case 'price':
|
||||
orderBy = { price: 1 }
|
||||
break
|
||||
case 'price-desc':
|
||||
orderBy = { price: -1 }
|
||||
break
|
||||
case 'createTime':
|
||||
default:
|
||||
orderBy = { createTime: -1 }
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
const goods = await db.collection('secondhand_goods')
|
||||
.where(query)
|
||||
.orderBy(Object.keys(orderBy)[0], Object.values(orderBy)[0] > 0 ? 'asc' : 'desc')
|
||||
.skip((pageNum - 1) * pageSize)
|
||||
.limit(pageSize)
|
||||
.get()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: goods.data,
|
||||
total,
|
||||
pageNum,
|
||||
pageSize,
|
||||
hasMore: total > pageNum * pageSize
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "getsecondhandgoods",
|
||||
"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.6.3"
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
// 云函数getUserInfo
|
||||
const cloud = require('wx-server-sdk')
|
||||
|
||||
// 初始化cloud
|
||||
cloud.init({
|
||||
env: 'cloud1-5gqeisa06659849a'
|
||||
})
|
||||
const db = cloud.database()
|
||||
|
||||
exports.main = async (event, context) => {
|
||||
const wxContext = cloud.getWXContext()
|
||||
const openid = wxContext.OPENID
|
||||
|
||||
try {
|
||||
// 获取用户信息
|
||||
const userInfo = await db.collection('users').where({
|
||||
openid: openid
|
||||
}).get()
|
||||
|
||||
if (userInfo.data.length === 0) {
|
||||
return {
|
||||
success: false,
|
||||
message: '用户不存在'
|
||||
}
|
||||
}
|
||||
|
||||
// 获取订单计数
|
||||
const waitingOrders = await db.collection('orders').where({
|
||||
buyerOpenid: openid,
|
||||
status: 'waiting'
|
||||
}).count()
|
||||
|
||||
const processingOrders = await db.collection('orders').where({
|
||||
buyerOpenid: openid,
|
||||
status: 'processing'
|
||||
}).count()
|
||||
|
||||
const completedOrders = await db.collection('orders').where({
|
||||
buyerOpenid: openid,
|
||||
status: 'completed'
|
||||
}).count()
|
||||
|
||||
const refundOrders = await db.collection('orders').where({
|
||||
buyerOpenid: openid,
|
||||
status: 'refund'
|
||||
}).count()
|
||||
|
||||
return {
|
||||
success: true,
|
||||
userInfo: userInfo.data[0],
|
||||
orderCount: {
|
||||
waiting: waitingOrders.total,
|
||||
processing: processingOrders.total,
|
||||
completed: completedOrders.total,
|
||||
refund: refundOrders.total
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取用户信息失败', error)
|
||||
return {
|
||||
success: false,
|
||||
message: '获取用户信息失败',
|
||||
error: error.message
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "getuserinfo",
|
||||
"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.6.3"
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "initdatabase",
|
||||
"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.6.3"
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "login",
|
||||
"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.6.3"
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
// 云函数publishSecondhandGoods
|
||||
const cloud = require('wx-server-sdk')
|
||||
|
||||
// 初始化cloud
|
||||
cloud.init({
|
||||
env: cloud.DYNAMIC_CURRENT_ENV
|
||||
})
|
||||
const db = cloud.database()
|
||||
|
||||
exports.main = async (event, context) => {
|
||||
const wxContext = cloud.getWXContext()
|
||||
const openid = wxContext.OPENID
|
||||
|
||||
// 获取请求参数
|
||||
const {
|
||||
title,
|
||||
description,
|
||||
price,
|
||||
condition,
|
||||
category,
|
||||
images = []
|
||||
} = event
|
||||
|
||||
// 验证必填字段
|
||||
if (!title || !price || !category) {
|
||||
return {
|
||||
success: false,
|
||||
message: '请填写所有必填字段'
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// 添加新商品
|
||||
const result = await db.collection('secondhand_goods').add({
|
||||
data: {
|
||||
openid,
|
||||
title,
|
||||
description,
|
||||
price: parseFloat(price),
|
||||
condition,
|
||||
category,
|
||||
images,
|
||||
status: 'available', // 状态:可购买
|
||||
createTime: db.serverDate(),
|
||||
updateTime: db.serverDate(),
|
||||
publishTime: new Date().toISOString()
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
success: true,
|
||||
goodsId: result._id,
|
||||
message: '商品发布成功'
|
||||
}
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
message: '商品发布失败',
|
||||
error: error.message
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "publishsecondhandgoods",
|
||||
"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.6.3"
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "updateuserinfo",
|
||||
"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.6.3"
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
// 云函数 userLogin/index.js
|
||||
const cloud = require('wx-server-sdk');
|
||||
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV });
|
||||
|
||||
exports.main = async (event, context) => {
|
||||
const wxContext = cloud.getWXContext();
|
||||
|
||||
// 拿到用户 openid 和 unionid
|
||||
const openid = wxContext.OPENID;
|
||||
const userInfo = event.userInfo;
|
||||
|
||||
// 查询数据库中是否存在该用户
|
||||
const db = cloud.database();
|
||||
const users = db.collection('users');
|
||||
|
||||
const existingUser = await users.where({ _openid: openid }).get();
|
||||
|
||||
if (existingUser.data.length > 0) {
|
||||
// 用户已存在,更新信息
|
||||
await users.doc(existingUser.data[0]._id).update({
|
||||
data: {
|
||||
nickName: userInfo.nickName,
|
||||
avatarUrl: userInfo.avatarUrl,
|
||||
updateTime: new Date()
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
isNewUser: false,
|
||||
userInfo: userInfo,
|
||||
openid: openid
|
||||
};
|
||||
} else {
|
||||
// 用户不存在,新建用户
|
||||
await users.add({
|
||||
data: {
|
||||
_openid: openid,
|
||||
nickName: userInfo.nickName,
|
||||
avatarUrl: userInfo.avatarUrl,
|
||||
createTime: new Date(),
|
||||
balance: 0,
|
||||
credit: 100,
|
||||
coupons: 0
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
isNewUser: true,
|
||||
userInfo: userInfo,
|
||||
openid: openid
|
||||
};
|
||||
}
|
||||
};
|
@ -0,0 +1,10 @@
|
||||
/**app.wxss**/
|
||||
.container {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 200rpx 0;
|
||||
box-sizing: border-box;
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"component": true,
|
||||
"styleIsolation": "apply-shared",
|
||||
"usingComponents": {}
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
.weui-navigation-bar {
|
||||
--weui-FG-0:rgba(0,0,0,.9);
|
||||
--height: 44px;
|
||||
--left: 16px;
|
||||
}
|
||||
.weui-navigation-bar .android {
|
||||
--height: 48px;
|
||||
}
|
||||
|
||||
.weui-navigation-bar {
|
||||
overflow: hidden;
|
||||
color: var(--weui-FG-0);
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.weui-navigation-bar__inner {
|
||||
position: relative;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: calc(var(--height) + env(safe-area-inset-top));
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding-top: env(safe-area-inset-top);
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.weui-navigation-bar__left {
|
||||
position: relative;
|
||||
padding-left: var(--left);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.weui-navigation-bar__btn_goback_wrapper {
|
||||
padding: 11px 18px 11px 16px;
|
||||
margin: -11px -18px -11px -16px;
|
||||
}
|
||||
|
||||
.weui-navigation-bar__btn_goback_wrapper.weui-active {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.weui-navigation-bar__btn_goback {
|
||||
font-size: 12px;
|
||||
width: 12px;
|
||||
height: 24px;
|
||||
-webkit-mask: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='24' viewBox='0 0 12 24'%3E %3Cpath fill-opacity='.9' fill-rule='evenodd' d='M10 19.438L8.955 20.5l-7.666-7.79a1.02 1.02 0 0 1 0-1.42L8.955 3.5 10 4.563 2.682 12 10 19.438z'/%3E%3C/svg%3E") no-repeat 50% 50%;
|
||||
mask: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='24' viewBox='0 0 12 24'%3E %3Cpath fill-opacity='.9' fill-rule='evenodd' d='M10 19.438L8.955 20.5l-7.666-7.79a1.02 1.02 0 0 1 0-1.42L8.955 3.5 10 4.563 2.682 12 10 19.438z'/%3E%3C/svg%3E") no-repeat 50% 50%;
|
||||
-webkit-mask-size: cover;
|
||||
mask-size: cover;
|
||||
background-color: var(--weui-FG-0);
|
||||
}
|
||||
|
||||
.weui-navigation-bar__center {
|
||||
font-size: 17px;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: bold;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.weui-navigation-bar__loading {
|
||||
margin-right: 4px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.weui-loading {
|
||||
font-size: 16px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: block;
|
||||
background: transparent url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg width='80px' height='80px' viewBox='0 0 80 80' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Ctitle%3Eloading%3C/title%3E%3Cdefs%3E%3ClinearGradient x1='94.0869141%25' y1='0%25' x2='94.0869141%25' y2='90.559082%25' id='linearGradient-1'%3E%3Cstop stop-color='%23606060' stop-opacity='0' offset='0%25'%3E%3C/stop%3E%3Cstop stop-color='%23606060' stop-opacity='0.3' offset='100%25'%3E%3C/stop%3E%3C/linearGradient%3E%3ClinearGradient x1='100%25' y1='8.67370605%25' x2='100%25' y2='90.6286621%25' id='linearGradient-2'%3E%3Cstop stop-color='%23606060' offset='0%25'%3E%3C/stop%3E%3Cstop stop-color='%23606060' stop-opacity='0.3' offset='100%25'%3E%3C/stop%3E%3C/linearGradient%3E%3C/defs%3E%3Cg stroke='none' stroke-width='1' fill='none' fill-rule='evenodd' opacity='0.9'%3E%3Cg%3E%3Cpath d='M40,0 C62.09139,0 80,17.90861 80,40 C80,62.09139 62.09139,80 40,80 L40,73 C58.2253967,73 73,58.2253967 73,40 C73,21.7746033 58.2253967,7 40,7 L40,0 Z' fill='url(%23linearGradient-1)'%3E%3C/path%3E%3Cpath d='M40,0 L40,7 C21.7746033,7 7,21.7746033 7,40 C7,58.2253967 21.7746033,73 40,73 L40,80 C17.90861,80 0,62.09139 0,40 C0,17.90861 17.90861,0 40,0 Z' fill='url(%23linearGradient-2)'%3E%3C/path%3E%3Ccircle id='Oval' fill='%23606060' cx='40.5' cy='3.5' r='3.5'%3E%3C/circle%3E%3C/g%3E%3C/g%3E%3C/svg%3E%0A") no-repeat;
|
||||
background-size: 100%;
|
||||
margin-left: 0;
|
||||
animation: loading linear infinite 1s;
|
||||
}
|
||||
|
||||
@keyframes loading {
|
||||
from {
|
||||
transform: rotate(0);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
<view class="weui-navigation-bar {{extClass}}">
|
||||
<view class="weui-navigation-bar__inner {{ios ? 'ios' : 'android'}}" style="color: {{color}}; background: {{background}}; {{displayStyle}}; {{innerPaddingRight}}; {{safeAreaTop}};">
|
||||
|
||||
<!-- 左侧按钮 -->
|
||||
<view class='weui-navigation-bar__left' style="{{leftWidth}};">
|
||||
<block wx:if="{{back || homeButton}}">
|
||||
<!-- 返回上一页 -->
|
||||
<block wx:if="{{back}}">
|
||||
<view class="weui-navigation-bar__buttons weui-navigation-bar__buttons_goback">
|
||||
<view
|
||||
bindtap="back"
|
||||
class="weui-navigation-bar__btn_goback_wrapper"
|
||||
hover-class="weui-active"
|
||||
hover-stay-time="100"
|
||||
aria-role="button"
|
||||
aria-label="返回"
|
||||
>
|
||||
<view class="weui-navigation-bar__button weui-navigation-bar__btn_goback"></view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<!-- 返回首页 -->
|
||||
<block wx:if="{{homeButton}}">
|
||||
<view class="weui-navigation-bar__buttons weui-navigation-bar__buttons_home">
|
||||
<view
|
||||
bindtap="home"
|
||||
class="weui-navigation-bar__btn_home_wrapper"
|
||||
hover-class="weui-active"
|
||||
aria-role="button"
|
||||
aria-label="首页"
|
||||
>
|
||||
<view class="weui-navigation-bar__button weui-navigation-bar__btn_home"></view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</block>
|
||||
<block wx:else>
|
||||
<slot name="left"></slot>
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!-- 标题 -->
|
||||
<view class='weui-navigation-bar__center'>
|
||||
<view wx:if="{{loading}}" class="weui-navigation-bar__loading" aria-role="alert">
|
||||
<view
|
||||
class="weui-loading"
|
||||
aria-role="img"
|
||||
aria-label="加载中"
|
||||
></view>
|
||||
</view>
|
||||
<block wx:if="{{title}}">
|
||||
<text>{{title}}</text>
|
||||
</block>
|
||||
<block wx:else>
|
||||
<slot name="center"></slot>
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!-- 右侧留空 -->
|
||||
<view class='weui-navigation-bar__right'>
|
||||
<slot name="right"></slot>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
After Width: | Height: | Size: 703 B |
After Width: | Height: | Size: 81 KiB |
After Width: | Height: | Size: 311 B |
After Width: | Height: | Size: 227 KiB |
After Width: | Height: | Size: 346 KiB |
After Width: | Height: | Size: 449 B |
After Width: | Height: | Size: 665 B |
After Width: | Height: | Size: 374 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 699 B |
After Width: | Height: | Size: 380 B |
After Width: | Height: | Size: 42 KiB |
After Width: | Height: | Size: 42 KiB |
After Width: | Height: | Size: 625 B |
After Width: | Height: | Size: 926 B |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 734 B |
After Width: | Height: | Size: 782 B |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 714 B |
After Width: | Height: | Size: 163 KiB |
After Width: | Height: | Size: 351 KiB |
After Width: | Height: | Size: 678 B |
@ -0,0 +1,23 @@
|
||||
<view class="container">
|
||||
<!-- 顶部分类名称 -->
|
||||
<view class="header">
|
||||
<text class="category-title">{{categoryName}}</text>
|
||||
</view>
|
||||
|
||||
<!-- 商品列表 -->
|
||||
<view class="products-list">
|
||||
<view class="product-item" wx:for="{{products}}" wx:key="id" bindtap="goToDetail" data-product="{{item}}">
|
||||
<image class="product-image" src="{{item.image}}" mode="aspectFill"></image>
|
||||
<view class="product-info">
|
||||
<text class="product-title">{{item.title}}</text>
|
||||
<text class="product-price">¥{{item.price}}</text>
|
||||
<button class="detail-btn" catchtap="goToDetail" data-product="{{item}}">查看详情</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<view class="empty-state" wx:if="{{products.length === 0}}">
|
||||
<text class="empty-text">暂无商品</text>
|
||||
</view>
|
||||
</view>
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"navigationBarTitleText": "商品详情",
|
||||
"navigationBarBackgroundColor": "#667eea",
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
/* detail.wxss */
|
||||
.container {
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* 商品主图 */
|
||||
.product-image-section {
|
||||
width: 100%;
|
||||
height: 500rpx;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.product-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
/* 商品信息 */
|
||||
.product-info-section {
|
||||
background: white;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.product-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.product-price {
|
||||
font-size: 48rpx;
|
||||
color: #e74c3c;
|
||||
font-weight: bold;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.product-description {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* 联系卖家 */
|
||||
.contact-section {
|
||||
background: white;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.contact-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.contact-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10rpx;
|
||||
}
|
||||
|
||||
.contact-text {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.contact-note {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* 操作按钮 */
|
||||
.action-section {
|
||||
padding: 30rpx;
|
||||
}
|
||||
|
||||
.back-btn {
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 12rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.back-btn:active {
|
||||
opacity: 0.8;
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/**index.less**/
|
||||
page {
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.scrollarea {
|
||||
flex: 1;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.userinfo {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
color: #aaa;
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.userinfo-avatar {
|
||||
overflow: hidden;
|
||||
width: 128rpx;
|
||||
height: 128rpx;
|
||||
margin: 20rpx;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.usermotto {
|
||||
margin-top: 200px;
|
||||
}
|
||||
.avatar-wrapper {
|
||||
padding: 0;
|
||||
width: 56px !important;
|
||||
border-radius: 8px;
|
||||
margin-top: 40px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
display: block;
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
}
|
||||
|
||||
.nickname-wrapper {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
padding: 16px;
|
||||
box-sizing: border-box;
|
||||
border-top: .5px solid rgba(0, 0, 0, 0.1);
|
||||
border-bottom: .5px solid rgba(0, 0, 0, 0.1);
|
||||
color: black;
|
||||
}
|
||||
|
||||
.nickname-label {
|
||||
width: 105px;
|
||||
}
|
||||
|
||||
.nickname-input {
|
||||
flex: 1;
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"usingComponents": {
|
||||
"navigation-bar": "/components/navigation-bar/navigation-bar"
|
||||
}
|
||||
}
|
@ -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,21 @@
|
||||
// logs.ts
|
||||
// const util = require('../../utils/util.js')
|
||||
import { formatTime } from '../../utils/util'
|
||||
|
||||
Component({
|
||||
data: {
|
||||
logs: [],
|
||||
},
|
||||
lifetimes: {
|
||||
attached() {
|
||||
this.setData({
|
||||
logs: (wx.getStorageSync('logs') || []).map((log: string) => {
|
||||
return {
|
||||
date: formatTime(new Date(log)),
|
||||
timeStamp: log
|
||||
}
|
||||
}),
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
@ -0,0 +1,7 @@
|
||||
<!--logs.wxml-->
|
||||
<navigation-bar title="查看启动日志" back="{{true}}" color="black" background="#FFF"></navigation-bar>
|
||||
<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,124 @@
|
||||
<view class="profile-container">
|
||||
<!-- 用户信息区域 -->
|
||||
<view class="user-info">
|
||||
<view class="user-info-bg"></view>
|
||||
<view class="user-info-content" style="height: 250rpx; display: flex; box-sizing: border-box; left: 0rpx; top: 0rpx">
|
||||
<image class="avatar" src="{{userInfo.avatarUrl || '/images/default_avatar.png'}}"></image>
|
||||
<view class="user-details" wx:if="{{hasUserInfo}}">
|
||||
<text class="nickname">{{userInfo.nickName}}</text>
|
||||
<text class="school">{{userInfo.school}} {{userInfo.studentId}}</text>
|
||||
</view>
|
||||
<!-- 新版获取用户信息按钮 -->
|
||||
<button class="login-btn" wx:if="{{!hasUserInfo}}" bindtap="getUserProfile">授权登录</button>
|
||||
|
||||
</view>
|
||||
<!-- 编辑昵称头像弹窗 -->
|
||||
<!-- 2025-8-1任柯敏添加 -->
|
||||
<view wx:if="{{showEditDialog}}" class="edit-dialog-mask">
|
||||
<view class="edit-dialog">
|
||||
<!-- <text class="dialog-title">完善个人信息</text> -->
|
||||
<image class="edit-avatar" src="{{editUserInfo.avatarUrl}}"></image>
|
||||
<button open-type="chooseAvatar" bindchooseavatar="chooseAvatar">点击更换头像</button>
|
||||
|
||||
<input class="edit-nickname-input" placeholder="请输入昵称" value="{{editUserInfo.nickName}}" bindinput="onNickNameInput" />
|
||||
|
||||
<input class="edit-nickname-input" placeholder="请输入学校名称" value="{{editUserInfo.school}}" bindinput="onschoolInput" />
|
||||
<input class="edit-nickname-input" placeholder="请输入学号" value="{{editUserInfo.studentId}}" bindinput="onstudentIdInput" />
|
||||
<view class="dialog-btns">
|
||||
<button bindtap="cancelEdit">取消</button>
|
||||
<button bindtap="confirmEdit">确认</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
<!-- 我的钱包 -->
|
||||
<view class="wallet-card">
|
||||
<view class="wallet-item">
|
||||
<text class="wallet-value">{{wallet.balance}}</text>
|
||||
<text class="wallet-label">余额</text>
|
||||
</view>
|
||||
<view class="wallet-divider"></view>
|
||||
<view class="wallet-item">
|
||||
<text class="wallet-value">{{wallet.points}}</text>
|
||||
<text class="wallet-label">积分</text>
|
||||
</view>
|
||||
<view class="wallet-divider"></view>
|
||||
<view class="wallet-item">
|
||||
<text class="wallet-value">{{wallet.coupons}}</text>
|
||||
<text class="wallet-label">优惠券</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 订单区域 -->
|
||||
<view class="section-card">
|
||||
<view class="section-header">
|
||||
<text class="section-title">我的订单</text>
|
||||
<navigator url="/pages/profile/orders" class="section-more">
|
||||
<text>全部订单</text>
|
||||
<image class="arrow-icon" src="/images/arrow.png"></image>
|
||||
</navigator>
|
||||
</view>
|
||||
<view class="order-types">
|
||||
<navigator url="/pages/profile/orders?status=waiting" class="order-type-item">
|
||||
<image class="order-type-icon" src="/images/waiting.png"></image>
|
||||
<text>待付款</text>
|
||||
<text class="badge" wx:if="{{orderCount.waiting > 0}}">{{orderCount.waiting}}</text>
|
||||
</navigator>
|
||||
<navigator url="/pages/profile/orders?status=processing" class="order-type-item">
|
||||
<image class="order-type-icon" src="/images/processing.png"></image>
|
||||
<text>进行中</text>
|
||||
<text class="badge" wx:if="{{orderCount.processing > 0}}">{{orderCount.processing}}</text>
|
||||
</navigator>
|
||||
<navigator url="/pages/profile/orders?status=completed" class="order-type-item">
|
||||
<image class="order-type-icon" src="/images/completed.png"></image>
|
||||
<text>已完成</text>
|
||||
<text class="badge" wx:if="{{orderCount.completed > 0}}">{{orderCount.completed}}</text>
|
||||
</navigator>
|
||||
<navigator url="/pages/profile/orders?status=refund" class="order-type-item">
|
||||
<image class="order-type-icon" src="/images/refund.png"></image>
|
||||
<text>退款/售后</text>
|
||||
<text class="badge" wx:if="{{orderCount.refund > 0}}">{{orderCount.refund}}</text>
|
||||
</navigator>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 我的服务 -->
|
||||
<view class="section-card">
|
||||
<view class="section-header">
|
||||
<text class="section-title">我的服务</text>
|
||||
</view>
|
||||
<view class="service-list">
|
||||
<view class="service-item" bindtap="navigateTo" data-url="/pages/profile/my_posts">
|
||||
<image class="service-icon" src="/images/my_posts.png"></image>
|
||||
<text>我的发布</text>
|
||||
</view>
|
||||
<view class="service-item" bindtap="navigateTo" data-url="/pages/profile/favorites">
|
||||
<image class="service-icon" src="/images/favorites.png"></image>
|
||||
<text>我的收藏</text>
|
||||
</view>
|
||||
<view class="service-item" bindtap="navigateTo" data-url="/pages/profile/address">
|
||||
<image class="service-icon" src="/images/address.png"></image>
|
||||
<text>收货地址</text>
|
||||
</view>
|
||||
<view class="service-item" bindtap="navigateTo" data-url="/pages/profile/feedback">
|
||||
<image class="service-icon" src="/images/feedback.png"></image>
|
||||
<text>意见反馈</text>
|
||||
</view>
|
||||
<view class="service-item" bindtap="navigateTo" data-url="/pages/profile/settings">
|
||||
<image class="service-icon" src="/images/settings.png"></image>
|
||||
<text>设置</text>
|
||||
</view>
|
||||
<view class="service-item" bindtap="navigateTo" data-url="/pages/profile/settings">
|
||||
<image class="service-icon" src="/images/settings.png"></image>
|
||||
<text>联系客服</text>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 客服按钮 -->
|
||||
<!-- <button class="customer-service" open-type="contact">联系客服</button> -->
|
||||
<button class="logout-btn" wx:if="{{hasUserInfo}}" bindtap="logout">退出登录</button>
|
||||
</view>
|
@ -0,0 +1,316 @@
|
||||
.profile-container {
|
||||
min-height: 100vh;
|
||||
background-color: #f7f7f7;
|
||||
padding-bottom: 40rpx;
|
||||
}
|
||||
|
||||
/* 用户信息区域 */
|
||||
.user-info {
|
||||
position: relative;
|
||||
height: 300rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.user-info-bg {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #3A86FF;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.user-info-content {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 40rpx 30rpx;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 50%;
|
||||
border: 4rpx solid #ffffff;
|
||||
margin-right: 30rpx;
|
||||
}
|
||||
|
||||
.user-details {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.nickname {
|
||||
color: #ffffff;
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.school {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.login-btn {
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
color: #ffffff;
|
||||
font-size: 28rpx;
|
||||
padding: 12rpx 40rpx;
|
||||
border-radius: 32rpx;
|
||||
border: 1rpx solid rgba(255, 255, 255, 0.5);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.login-btn::after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* 钱包卡片 */
|
||||
.wallet-card {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
margin: -50rpx 30rpx 30rpx;
|
||||
padding: 30rpx 0;
|
||||
background-color: #ffffff;
|
||||
border-radius: 12rpx;
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.wallet-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.wallet-value {
|
||||
font-size: 36rpx;
|
||||
color: #333333;
|
||||
font-weight: bold;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.wallet-label {
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.wallet-divider {
|
||||
width: 1rpx;
|
||||
height: 50rpx;
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
|
||||
/* 功能区块 */
|
||||
.section-card {
|
||||
margin: 0 30rpx 30rpx;
|
||||
padding: 30rpx;
|
||||
background-color: #ffffff;
|
||||
border-radius: 12rpx;
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
color: #333333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.section-more {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.arrow-icon {
|
||||
width: 24rpx;
|
||||
height: 24rpx;
|
||||
margin-left: 6rpx;
|
||||
}
|
||||
|
||||
/* 订单类型 */
|
||||
.order-types {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.order-type-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.order-type-icon {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.order-type-item text {
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.badge {
|
||||
position: absolute;
|
||||
top: -10rpx;
|
||||
right: -10rpx;
|
||||
background-color: #FF5252;
|
||||
color: #ffffff;
|
||||
font-size: 20rpx;
|
||||
border-radius: 20rpx;
|
||||
padding: 2rpx 10rpx;
|
||||
min-width: 32rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 服务列表 */
|
||||
.service-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.service-item {
|
||||
width: 33.33%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.service-icon {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.service-item text {
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
/* 客服按钮 */
|
||||
.customer-service {
|
||||
width: 90%;
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
font-size: 30rpx;
|
||||
color: #666666;
|
||||
background-color: #ffffff;
|
||||
border-radius: 44rpx;
|
||||
margin-top: 30rpx;
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
/* 新增选择昵称和头像功能 */
|
||||
/* 遮罩层 */
|
||||
.edit-dialog-mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.5); /* 半透明黑色遮罩 */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
/* 弹窗主体 */
|
||||
.edit-dialog {
|
||||
width: 85%;
|
||||
max-width: 400rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 20rpx;
|
||||
padding: 30rpx 30rpx 40rpx 30rpx;
|
||||
box-shadow: 0 8rpx 20rpx rgba(0, 0, 0, 0.15);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 标题 */
|
||||
.dialog-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 25rpx;
|
||||
}
|
||||
|
||||
/* 头像图片 */
|
||||
.edit-avatar {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 60rpx;
|
||||
margin: 0 auto 20rpx auto;
|
||||
object-fit: cover;
|
||||
border: 2rpx solid #1AAD19; /* 微信绿边框 */
|
||||
}
|
||||
|
||||
/* 更换头像按钮 */
|
||||
button[open-type="chooseAvatar"] {
|
||||
display: inline-block;
|
||||
background-color: #1AAD19;
|
||||
color: #fff;
|
||||
font-size: 28rpx;
|
||||
padding: 10rpx 25rpx;
|
||||
border-radius: 40rpx;
|
||||
margin-bottom: 25rpx;
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* 昵称输入框 */
|
||||
.edit-nickname-input {
|
||||
width: 100%;
|
||||
height: 50rpx;
|
||||
line-height: 50rpx;
|
||||
font-size: 28rpx;
|
||||
padding: 0 15rpx;
|
||||
border: 1rpx solid #ddd;
|
||||
border-radius: 10rpx;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 30rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* 底部按钮容器 */
|
||||
.dialog-btns {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
/* 取消按钮 */
|
||||
.dialog-btns button:first-child {
|
||||
flex: 1;
|
||||
background-color: #f5f5f5;
|
||||
color: #666;
|
||||
font-size: 28rpx;
|
||||
padding: 12rpx 0;
|
||||
border-radius: 12rpx;
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* 确认按钮 */
|
||||
.dialog-btns button:last-child {
|
||||
flex: 1;
|
||||
background-color: #1AAD19;
|
||||
color: white;
|
||||
font-size: 28rpx;
|
||||
padding: 12rpx 0;
|
||||
border-radius: 12rpx;
|
||||
border: none;
|
||||
}
|
@ -0,0 +1,201 @@
|
||||
// pages/profile/orders.js
|
||||
Page({
|
||||
data: {
|
||||
currentTab: 'all',
|
||||
orders: [],
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
hasMoreOrders: true,
|
||||
isLoading: false
|
||||
},
|
||||
|
||||
onLoad: function (options) {
|
||||
// 如果有状态参数,则切换到对应状态选项卡
|
||||
if (options.status) {
|
||||
this.setData({
|
||||
currentTab: options.status
|
||||
});
|
||||
}
|
||||
|
||||
// 加载订单列表
|
||||
this.loadOrders(true);
|
||||
},
|
||||
|
||||
// 切换选项卡
|
||||
switchTab: function (e) {
|
||||
const tab = e.currentTarget.dataset.tab;
|
||||
this.setData({
|
||||
currentTab: tab,
|
||||
orders: [],
|
||||
page: 1,
|
||||
hasMoreOrders: true
|
||||
});
|
||||
this.loadOrders(true);
|
||||
},
|
||||
|
||||
// 加载订单列表
|
||||
loadOrders: function (refresh = false) {
|
||||
if (this.data.isLoading || (!refresh && !this.data.hasMoreOrders)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setData({ isLoading: true });
|
||||
|
||||
if (refresh) {
|
||||
wx.showLoading({
|
||||
title: '加载中...',
|
||||
});
|
||||
}
|
||||
|
||||
// 模拟请求数据
|
||||
setTimeout(() => {
|
||||
// 模拟订单数据 - 只保留二手超市相关订单
|
||||
const mockOrders = [
|
||||
{
|
||||
id: 1,
|
||||
orderType: '二手商品',
|
||||
status: 'processing',
|
||||
statusText: '已付款',
|
||||
title: 'iPad Pro 2021 二手95新',
|
||||
price: 4500,
|
||||
image: '/images/ipad.jpg',
|
||||
createTime: '2023-05-19 10:15'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
orderType: '二手商品',
|
||||
status: 'completed',
|
||||
statusText: '已完成',
|
||||
title: '微积分教材 同济第七版',
|
||||
price: 20,
|
||||
image: '/images/book.jpg',
|
||||
createTime: '2023-05-17 16:20'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
orderType: '二手商品',
|
||||
status: 'refund',
|
||||
statusText: '退款中',
|
||||
title: '自行车 捷安特 ATX',
|
||||
price: 800,
|
||||
image: '/images/bike.jpg',
|
||||
createTime: '2023-05-16 09:30'
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
orderType: '二手商品',
|
||||
status: 'waiting',
|
||||
statusText: '待付款',
|
||||
title: 'AirPods Pro 二代',
|
||||
price: 1200,
|
||||
image: '/images/airpods.jpg',
|
||||
createTime: '2023-05-15 14:20'
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
orderType: '二手商品',
|
||||
status: 'completed',
|
||||
statusText: '已完成',
|
||||
title: '学习桌 可调节高度',
|
||||
price: 150,
|
||||
image: '/images/table.jpg',
|
||||
createTime: '2023-05-14 11:45'
|
||||
}
|
||||
];
|
||||
|
||||
// 根据当前选项卡筛选订单
|
||||
let filteredOrders = this.data.currentTab === 'all' ?
|
||||
mockOrders :
|
||||
mockOrders.filter(item => item.status === this.data.currentTab);
|
||||
|
||||
// 模拟分页
|
||||
const start = (this.data.page - 1) * this.data.pageSize;
|
||||
const end = start + this.data.pageSize;
|
||||
const pageOrders = filteredOrders.slice(start, end);
|
||||
|
||||
// 更新数据
|
||||
if (refresh) {
|
||||
this.setData({
|
||||
orders: pageOrders,
|
||||
hasMoreOrders: pageOrders.length === this.data.pageSize,
|
||||
page: this.data.page + 1,
|
||||
isLoading: false
|
||||
});
|
||||
wx.hideLoading();
|
||||
wx.stopPullDownRefresh();
|
||||
} else {
|
||||
this.setData({
|
||||
orders: [...this.data.orders, ...pageOrders],
|
||||
hasMoreOrders: pageOrders.length === this.data.pageSize,
|
||||
page: this.data.page + 1,
|
||||
isLoading: false
|
||||
});
|
||||
}
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
|
||||
// 加载更多
|
||||
loadMore: function () {
|
||||
if (!this.data.isLoading && this.data.hasMoreOrders) {
|
||||
this.loadOrders();
|
||||
}
|
||||
},
|
||||
//雷雨田2025.8.30添加
|
||||
confirmOrder() {
|
||||
if (!this.data.address) {
|
||||
wx.showToast({ title: '请选择地址', icon: 'none' })
|
||||
return
|
||||
}
|
||||
wx.showToast({ title: '下单成功', icon: 'success' })
|
||||
},
|
||||
|
||||
// 下拉刷新
|
||||
onPullDownRefresh: function () {
|
||||
this.setData({
|
||||
page: 1,
|
||||
hasMoreOrders: true
|
||||
});
|
||||
this.loadOrders(true);
|
||||
},
|
||||
|
||||
// 查看订单详情
|
||||
viewOrderDetail: function (e) {
|
||||
const orderId = e.currentTarget.dataset.id;
|
||||
wx.navigateTo({
|
||||
url: `/pages/profile/order_detail?id=${orderId}`
|
||||
});
|
||||
},
|
||||
|
||||
// 取消订单
|
||||
cancelOrder: function (e) {
|
||||
const orderId = e.currentTarget.dataset.id;
|
||||
wx.showModal({
|
||||
title: '确认取消',
|
||||
content: '确定要取消此订单吗?',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
// 模拟取消订单
|
||||
wx.showLoading({
|
||||
title: '处理中...',
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
wx.hideLoading();
|
||||
|
||||
// 更新本地订单状态或重新加载订单列表
|
||||
const orders = this.data.orders.filter(item => item.id !== orderId);
|
||||
this.setData({
|
||||
orders: orders
|
||||
});
|
||||
|
||||
wx.showToast({
|
||||
title: '订单已取消',
|
||||
icon: 'success'
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
@ -0,0 +1,62 @@
|
||||
<view class="orders-container">
|
||||
<!-- 订单状态选项卡 -->
|
||||
<view class="tabs">
|
||||
<view class="tab-item {{currentTab === 'all' ? 'active' : ''}}" data-tab="all" bindtap="switchTab">
|
||||
全部
|
||||
</view>
|
||||
<view class="tab-item {{currentTab === 'waiting' ? 'active' : ''}}" data-tab="waiting" bindtap="switchTab">
|
||||
待付款
|
||||
</view>
|
||||
<view class="tab-item {{currentTab === 'processing' ? 'active' : ''}}" data-tab="processing" bindtap="switchTab">
|
||||
进行中
|
||||
</view>
|
||||
<view class="tab-item {{currentTab === 'completed' ? 'active' : ''}}" data-tab="completed" bindtap="switchTab">
|
||||
已完成
|
||||
</view>
|
||||
<view class="tab-item {{currentTab === 'refund' ? 'active' : ''}}" data-tab="refund" bindtap="switchTab">
|
||||
退款/售后
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 订单列表 -->
|
||||
<scroll-view scroll-y class="order-list" bindscrolltolower="loadMore">
|
||||
<view class="empty-tip" wx:if="{{orders.length === 0}}">
|
||||
<image class="empty-icon" src="/images/empty.png"></image>
|
||||
<text>暂无订单</text>
|
||||
</view>
|
||||
<view class="order-item" wx:for="{{orders}}" wx:key="id" bindtap="viewOrderDetail" data-id="{{item.id}}">
|
||||
<!-- 订单头部信息 -->
|
||||
<view class="order-header">
|
||||
<view class="order-type">{{item.orderType}}</view>
|
||||
<view class="order-status {{item.status}}">{{item.statusText}}</view>
|
||||
</view>
|
||||
|
||||
<!-- 订单主体内容 -->
|
||||
<view class="order-content">
|
||||
<image class="order-image" src="{{item.image}}" mode="aspectFill"></image>
|
||||
<view class="order-info">
|
||||
<view class="order-title">{{item.title}}</view>
|
||||
<view class="order-price">¥{{item.price}}</view>
|
||||
<view class="order-time">{{item.createTime}}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 订单操作按钮 -->
|
||||
<view class="order-footer">
|
||||
<button class="order-btn cancel" wx:if="{{item.status === 'waiting'}}" catchtap="cancelOrder" data-id="{{item.id}}">取消订单</button>
|
||||
<button class="order-btn primary" wx:if="{{item.status === 'waiting'}}">付款</button>
|
||||
<button class="order-btn primary" wx:if="{{item.status === 'processing'}}">确认收货</button>
|
||||
<button class="order-btn" wx:if="{{item.status === 'completed'}}">再次购买</button>
|
||||
<button class="order-btn" wx:if="{{item.status === 'completed'}}">评价</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载更多 -->
|
||||
<view class="loading-more" wx:if="{{hasMoreOrders && orders.length > 0}}">
|
||||
<text>加载中...</text>
|
||||
</view>
|
||||
<view class="no-more" wx:if="{{!hasMoreOrders && orders.length > 0}}">
|
||||
<text>没有更多订单了</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
@ -0,0 +1,187 @@
|
||||
.orders-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
background-color: #f7f7f7;
|
||||
}
|
||||
|
||||
/* 选项卡样式 */
|
||||
.tabs {
|
||||
display: flex;
|
||||
background-color: #ffffff;
|
||||
border-bottom: 1rpx solid #eeeeee;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.tab-item {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
padding: 24rpx 0;
|
||||
font-size: 28rpx;
|
||||
color: #666666;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.tab-item.active {
|
||||
color: #3A86FF;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.tab-item.active::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 40rpx;
|
||||
height: 4rpx;
|
||||
background-color: #3A86FF;
|
||||
border-radius: 2rpx;
|
||||
}
|
||||
|
||||
/* 订单列表样式 */
|
||||
.order-list {
|
||||
flex: 1;
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.empty-tip {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 100rpx 0;
|
||||
}
|
||||
|
||||
.empty-icon {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.empty-tip text {
|
||||
font-size: 28rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.order-item {
|
||||
background-color: #ffffff;
|
||||
border-radius: 12rpx;
|
||||
margin-bottom: 20rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.order-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 20rpx;
|
||||
border-bottom: 1rpx solid #f2f2f2;
|
||||
}
|
||||
|
||||
.order-type {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.order-status {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.order-status.waiting {
|
||||
color: #FF9800;
|
||||
}
|
||||
|
||||
.order-status.processing {
|
||||
color: #3A86FF;
|
||||
}
|
||||
|
||||
.order-status.completed {
|
||||
color: #4CAF50;
|
||||
}
|
||||
|
||||
.order-status.refund {
|
||||
color: #9E9E9E;
|
||||
}
|
||||
|
||||
.order-content {
|
||||
display: flex;
|
||||
padding: 20rpx;
|
||||
border-bottom: 1rpx solid #f2f2f2;
|
||||
}
|
||||
|
||||
.order-image {
|
||||
width: 160rpx;
|
||||
height: 160rpx;
|
||||
border-radius: 8rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.order-info {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.order-title {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.order-price {
|
||||
font-size: 32rpx;
|
||||
color: #FF5252;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.order-time {
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.order-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.order-btn {
|
||||
margin-left: 20rpx;
|
||||
padding: 0 30rpx;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
font-size: 26rpx;
|
||||
color: #666666;
|
||||
background-color: #f7f7f7;
|
||||
border-radius: 30rpx;
|
||||
min-width: 120rpx;
|
||||
}
|
||||
|
||||
.order-btn.primary {
|
||||
background-color: #3A86FF;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.order-btn.cancel {
|
||||
background-color: #ffffff;
|
||||
color: #999999;
|
||||
border: 1rpx solid #eeeeee;
|
||||
}
|
||||
|
||||
.order-btn::after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.loading-more, .no-more {
|
||||
text-align: center;
|
||||
padding: 20rpx 0;
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
// profile.js
|
||||
Page({
|
||||
data: {
|
||||
userInfo: {
|
||||
name: '用户XXX',
|
||||
avatar: '/images/icons/avatar.png',
|
||||
desc: '中南民族大学学生'
|
||||
}
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
console.log('个人中心页面加载完成')
|
||||
},
|
||||
|
||||
// 显示功能提示
|
||||
showFeatureTip(e) {
|
||||
const feature = e.currentTarget.dataset.feature
|
||||
wx.showToast({
|
||||
title: `${feature}功能暂未开放`,
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
})
|
||||
}
|
||||
})
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"navigationBarTitleText": "个人中心",
|
||||
"navigationBarBackgroundColor": "#667eea",
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
<view class="container">
|
||||
<!-- 用户信息 -->
|
||||
<view class="user-section">
|
||||
<view class="user-info">
|
||||
<image class="user-avatar" src="/images/icons/avatar.png" mode="aspectFill"></image>
|
||||
<view class="user-details">
|
||||
<text class="user-name">用户XXX</text>
|
||||
<text class="user-desc">中南民族大学学生</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 功能入口 -->
|
||||
<view class="features-section">
|
||||
<view class="feature-item" bindtap="showFeatureTip" data-feature="收藏">
|
||||
<view class="feature-icon">❤️</view>
|
||||
<text class="feature-name">我的收藏</text>
|
||||
<view class="feature-arrow">></view>
|
||||
</view>
|
||||
|
||||
<view class="feature-item" bindtap="showFeatureTip" data-feature="发布">
|
||||
<view class="feature-icon">📝</view>
|
||||
<text class="feature-name">我的发布</text>
|
||||
<view class="feature-arrow">></view>
|
||||
</view>
|
||||
|
||||
<view class="feature-item" bindtap="showFeatureTip" data-feature="订单">
|
||||
<view class="feature-icon">📋</view>
|
||||
<text class="feature-name">我的订单</text>
|
||||
<view class="feature-arrow">></view>
|
||||
</view>
|
||||
|
||||
<view class="feature-item" bindtap="showFeatureTip" data-feature="设置">
|
||||
<view class="feature-icon">⚙️</view>
|
||||
<text class="feature-name">设置</text>
|
||||
<view class="feature-arrow">></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 版本信息 -->
|
||||
<view class="version-section">
|
||||
<text class="version-text">版本 1.0.0</text>
|
||||
</view>
|
||||
</view>
|
@ -0,0 +1,97 @@
|
||||
/* profile.wxss */
|
||||
.container {
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* 用户信息 */
|
||||
.user-section {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
padding: 40rpx 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 60rpx;
|
||||
margin-right: 30rpx;
|
||||
border: 4rpx solid rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.user-details {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: 36rpx;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.user-desc {
|
||||
font-size: 28rpx;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* 功能入口 */
|
||||
.features-section {
|
||||
background: white;
|
||||
border-radius: 16rpx;
|
||||
margin: 0 20rpx 20rpx 20rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.feature-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 30rpx;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
|
||||
.feature-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.feature-item:active {
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
.feature-icon {
|
||||
font-size: 40rpx;
|
||||
margin-right: 20rpx;
|
||||
width: 40rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.feature-name {
|
||||
flex: 1;
|
||||
font-size: 32rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.feature-arrow {
|
||||
font-size: 32rpx;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
/* 版本信息 */
|
||||
.version-section {
|
||||
text-align: center;
|
||||
padding: 40rpx 0;
|
||||
}
|
||||
|
||||
.version-text {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
<view class="detail-container">
|
||||
<!-- 商品图片轮播 -->
|
||||
<swiper class="goods-swiper" indicator-dots="{{true}}" autoplay="{{true}}" interval="{{3000}}" duration="{{500}}">
|
||||
<swiper-item wx:for="{{goods.images}}" wx:key="index">
|
||||
<image src="{{item}}" class="slide-image" mode="aspectFill" bindtap="previewImage" data-index="{{index}}"/>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
|
||||
<!-- 商品基本信息 -->
|
||||
<view class="goods-info">
|
||||
<view class="goods-price">¥{{goods.price}}</view>
|
||||
<view class="goods-title">{{goods.title}}</view>
|
||||
<view class="goods-meta">
|
||||
<text class="goods-condition">{{goods.condition}}</text>
|
||||
<text class="goods-time">发布于 {{goods.publishTime}}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 商品详情 -->
|
||||
<view class="goods-details">
|
||||
<view class="section-title">商品详情</view>
|
||||
<view class="goods-desc">{{goods.description}}</view>
|
||||
</view>
|
||||
|
||||
<!-- 卖家信息 -->
|
||||
<view class="seller-info">
|
||||
<view class="section-title">卖家信息</view>
|
||||
<view class="seller-profile">
|
||||
<image class="seller-avatar" src="{{goods.seller.avatar}}"></image>
|
||||
<view class="seller-detail">
|
||||
<text class="seller-name">{{goods.seller.name}}</text>
|
||||
<text class="seller-meta">校园认证 · {{goods.seller.verifyType}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部操作栏 -->
|
||||
<view class="bottom-bar">
|
||||
<view class="contact-container">
|
||||
<button class="contact-btn" open-type="share">
|
||||
<image class="btn-icon" src="/images/share.png"></image>
|
||||
<text>分享</text>
|
||||
</button>
|
||||
<button class="contact-btn" bindtap="contactSeller">
|
||||
<image class="btn-icon" src="/images/contact.png"></image>
|
||||
<text>联系卖家</text>
|
||||
</button>
|
||||
</view>
|
||||
<button class="buy-btn" bindtap="buyNow">立即购买</button>
|
||||
</view>
|
||||
</view>
|
@ -0,0 +1,163 @@
|
||||
.detail-container {
|
||||
min-height: 100vh;
|
||||
background-color: #f7f7f7;
|
||||
padding-bottom: 120rpx;
|
||||
}
|
||||
|
||||
/* 轮播图样式 */
|
||||
.goods-swiper {
|
||||
width: 100%;
|
||||
height: 750rpx;
|
||||
}
|
||||
|
||||
.slide-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* 商品信息样式 */
|
||||
.goods-info {
|
||||
background-color: #ffffff;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.goods-price {
|
||||
font-size: 44rpx;
|
||||
color: #FF5252;
|
||||
font-weight: bold;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.goods-title {
|
||||
font-size: 32rpx;
|
||||
color: #333333;
|
||||
font-weight: bold;
|
||||
margin-bottom: 16rpx;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.goods-meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
/* 商品详情样式 */
|
||||
.goods-details, .seller-info {
|
||||
background-color: #ffffff;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 30rpx;
|
||||
color: #333333;
|
||||
font-weight: bold;
|
||||
margin-bottom: 20rpx;
|
||||
position: relative;
|
||||
padding-left: 20rpx;
|
||||
}
|
||||
|
||||
.section-title::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 6rpx;
|
||||
width: 6rpx;
|
||||
height: 30rpx;
|
||||
background-color: #3A86FF;
|
||||
border-radius: 3rpx;
|
||||
}
|
||||
|
||||
.goods-desc {
|
||||
font-size: 28rpx;
|
||||
color: #666666;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* 卖家信息样式 */
|
||||
.seller-profile {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.seller-avatar {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 50%;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.seller-detail {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.seller-name {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
|
||||
.seller-meta {
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
/* 底部操作栏 */
|
||||
.bottom-bar {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 100rpx;
|
||||
display: flex;
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.contact-container {
|
||||
display: flex;
|
||||
width: 45%; /* 分享和联系卖家占45%宽度 */
|
||||
}
|
||||
|
||||
.contact-btn {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 26rpx;
|
||||
color: #666666;
|
||||
background-color: #ffffff;
|
||||
border-radius: 0;
|
||||
padding: 0;
|
||||
line-height: normal;
|
||||
height: 100rpx;
|
||||
}
|
||||
|
||||
.contact-btn::after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.btn-icon {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.buy-btn {
|
||||
width: 55%; /* 立即购买占55%宽度 */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
color: #ffffff;
|
||||
background-color: #FF5252;
|
||||
height: 100rpx;
|
||||
}
|
@ -0,0 +1,179 @@
|
||||
Page({
|
||||
data: {
|
||||
currentCategory: 'all',
|
||||
goodsList: [],
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
hasMoreGoods: true,
|
||||
isLoading: false
|
||||
},
|
||||
|
||||
onLoad: function (options) {
|
||||
console.log('二手超市页面加载');
|
||||
this.loadGoodsList(true);
|
||||
},
|
||||
|
||||
onPullDownRefresh: function () {
|
||||
console.log('下拉刷新');
|
||||
this.setData({
|
||||
pageNum: 1,
|
||||
hasMoreGoods: true
|
||||
});
|
||||
this.loadGoodsList(true);
|
||||
},
|
||||
|
||||
switchCategory: function (e) {
|
||||
const category = e.currentTarget.dataset.category;
|
||||
console.log('切换分类:', category);
|
||||
this.setData({
|
||||
currentCategory: category,
|
||||
pageNum: 1,
|
||||
goodsList: [],
|
||||
hasMoreGoods: true
|
||||
});
|
||||
this.loadGoodsList(true);
|
||||
},
|
||||
|
||||
searchGoods: function (e) {
|
||||
const keyword = e.detail.value;
|
||||
if (!keyword.trim()) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('搜索商品:', keyword);
|
||||
this.setData({
|
||||
pageNum: 1,
|
||||
goodsList: [],
|
||||
hasMoreGoods: true
|
||||
});
|
||||
|
||||
this.loadGoodsList(true, keyword);
|
||||
},
|
||||
|
||||
loadGoodsList: function (refresh, keyword) {
|
||||
refresh = refresh || false;
|
||||
keyword = keyword || '';
|
||||
|
||||
console.log('加载商品列表, 刷新:', refresh, '关键词:', keyword);
|
||||
|
||||
// 模拟商品数据
|
||||
const mockGoods = [
|
||||
{
|
||||
id: 1,
|
||||
title: 'iPad Pro 2021 二手95新',
|
||||
price: 4500,
|
||||
condition: '95新',
|
||||
images: ['/images/ipad.jpg'],
|
||||
publishTime: '3小时前',
|
||||
category: 'electronics'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: '微积分教材 同济第七版',
|
||||
price: 20,
|
||||
condition: '8成新',
|
||||
images: ['/images/book.jpg'],
|
||||
publishTime: '1天前',
|
||||
category: 'books'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: '耐克运动鞋 Air Max 270',
|
||||
price: 350,
|
||||
condition: '9成新',
|
||||
images: ['/images/shoes.jpg'],
|
||||
publishTime: '2天前',
|
||||
category: 'clothes'
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: '宿舍小桌子 可折叠',
|
||||
price: 50,
|
||||
condition: '全新',
|
||||
images: ['/images/table.jpg'],
|
||||
publishTime: '3天前',
|
||||
category: 'daily'
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
title: '自行车 捷安特 ATX',
|
||||
price: 800,
|
||||
condition: '8成新',
|
||||
images: ['/images/bike.jpg'],
|
||||
publishTime: '5天前',
|
||||
category: 'others'
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
title: 'AirPods Pro 无线耳机',
|
||||
price: 850,
|
||||
condition: '9成新',
|
||||
images: ['/images/airpods.jpg'],
|
||||
publishTime: '1周前',
|
||||
category: 'electronics'
|
||||
}
|
||||
];
|
||||
|
||||
// 根据分类和关键词筛选商品
|
||||
var filteredGoods = mockGoods;
|
||||
var self = this;
|
||||
|
||||
if (this.data.currentCategory !== 'all') {
|
||||
filteredGoods = mockGoods.filter(function(item) {
|
||||
return item.category === self.data.currentCategory;
|
||||
});
|
||||
}
|
||||
|
||||
if (keyword) {
|
||||
filteredGoods = filteredGoods.filter(function(item) {
|
||||
return item.title.toLowerCase().indexOf(keyword.toLowerCase()) !== -1;
|
||||
});
|
||||
}
|
||||
|
||||
// 模拟分页
|
||||
var start = (this.data.pageNum - 1) * this.data.pageSize;
|
||||
var end = start + this.data.pageSize;
|
||||
var pageGoods = filteredGoods.slice(start, end);
|
||||
|
||||
// 更新数据
|
||||
if (refresh) {
|
||||
this.setData({
|
||||
goodsList: pageGoods,
|
||||
hasMoreGoods: pageGoods.length === this.data.pageSize,
|
||||
pageNum: this.data.pageNum + 1
|
||||
});
|
||||
wx.stopPullDownRefresh();
|
||||
} else {
|
||||
this.setData({
|
||||
goodsList: this.data.goodsList.concat(pageGoods),
|
||||
hasMoreGoods: pageGoods.length === this.data.pageSize,
|
||||
pageNum: this.data.pageNum + 1
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
loadMore: function () {
|
||||
console.log('加载更多商品');
|
||||
if (this.data.hasMoreGoods) {
|
||||
this.loadGoodsList();
|
||||
}
|
||||
},
|
||||
|
||||
navigateToDetail: function (e) {
|
||||
var goodsId = e.currentTarget.dataset.id;
|
||||
wx.navigateTo({
|
||||
url: '/pages/secondhand/detail?id=' + goodsId
|
||||
});
|
||||
},
|
||||
|
||||
navigateToPublish: function () {
|
||||
wx.navigateTo({
|
||||
url: '/pages/secondhand/publish'
|
||||
});
|
||||
},
|
||||
|
||||
// 处理图片加载错误
|
||||
handleImageError: function() {
|
||||
console.log('图片加载错误处理已注册');
|
||||
}
|
||||
})
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"enablePullDownRefresh": true,
|
||||
"backgroundTextStyle": "dark",
|
||||
"usingComponents": {}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
<view class="secondhand-container">
|
||||
<!-- 顶部搜索栏 -->
|
||||
<view class="search-container">
|
||||
<view class="search-box">
|
||||
<!-- 雷雨田2025.8.30添加 -->
|
||||
<image class="search-icon" src="/images/new_search.png" style="width: 62rpx; display: block; box-sizing: border-box; height: 60rpx"></image>
|
||||
<input class="search-input" placeholder="搜索二手商品" confirm-type="search" bindconfirm="searchGoods" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 分类导航 -->
|
||||
<scroll-view scroll-x class="category-scroll">
|
||||
<view class="category-list">
|
||||
<view class="category-item {{currentCategory === 'all' ? 'active' : ''}}" bindtap="switchCategory" data-category="all">
|
||||
全部
|
||||
</view>
|
||||
<view class="category-item {{currentCategory === 'electronics' ? 'active' : ''}}" bindtap="switchCategory" data-category="electronics">
|
||||
电子产品
|
||||
</view>
|
||||
<view class="category-item {{currentCategory === 'books' ? 'active' : ''}}" bindtap="switchCategory" data-category="books">
|
||||
书籍教材
|
||||
</view>
|
||||
<view class="category-item {{currentCategory === 'daily' ? 'active' : ''}}" bindtap="switchCategory" data-category="daily">
|
||||
日用品
|
||||
</view>
|
||||
<view class="category-item {{currentCategory === 'clothes' ? 'active' : ''}}" bindtap="switchCategory" data-category="clothes">
|
||||
衣物服饰
|
||||
</view>
|
||||
<view class="category-item {{currentCategory === 'others' ? 'active' : ''}}" bindtap="switchCategory" data-category="others">
|
||||
其他
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 商品列表 -->
|
||||
<scroll-view scroll-y class="goods-container" bindscrolltolower="loadMore">
|
||||
<view class="goods-list">
|
||||
<view class="goods-item" wx:for="{{goodsList}}" wx:key="id" bindtap="navigateToDetail" data-id="{{item.id}}">
|
||||
<image class="goods-image" src="{{item.images[0]}}" mode="aspectFill"></image>
|
||||
<view class="goods-info">
|
||||
<view class="goods-title">{{item.title}}</view>
|
||||
<view class="goods-price">¥{{item.price}}</view>
|
||||
<view class="goods-meta">
|
||||
<text class="goods-time">{{item.publishTime}}</text>
|
||||
<text class="goods-condition">{{item.condition}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载更多 -->
|
||||
<view class="loading-more" wx:if="{{hasMoreGoods}}">
|
||||
<text>加载中...</text>
|
||||
</view>
|
||||
<view class="no-more" wx:if="{{!hasMoreGoods && goodsList.length > 0}}">
|
||||
<text>没有更多商品了</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 发布按钮 -->
|
||||
<view class="publish-btn" bindtap="navigateToPublish" style="height: 118rpx; display: flex; box-sizing: border-box; left: 604rpx; top: 1047rpx; width: 118rpx; position: fixed">+</view>
|
||||
</view>
|
@ -0,0 +1,149 @@
|
||||
.secondhand-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
background-color: #f7f7f7;
|
||||
}
|
||||
|
||||
/* 搜索栏样式 */
|
||||
.search-container {
|
||||
padding: 20rpx 30rpx;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #f2f2f2;
|
||||
border-radius: 32rpx;
|
||||
padding: 10rpx 20rpx;
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
flex: 1;
|
||||
height: 60rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
/* 分类导航样式 */
|
||||
.category-scroll {
|
||||
background-color: #ffffff;
|
||||
white-space: nowrap;
|
||||
padding: 0 0 16rpx;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.category-list {
|
||||
display: inline-flex;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.category-item {
|
||||
display: inline-block;
|
||||
padding: 12rpx 24rpx;
|
||||
margin: 0 10rpx;
|
||||
font-size: 28rpx;
|
||||
color: #666666;
|
||||
border-radius: 24rpx;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.category-item.active {
|
||||
background-color: #3A86FF;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
/* 商品列表样式 */
|
||||
.goods-container {
|
||||
flex: 1;
|
||||
padding: 20rpx 30rpx;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.goods-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.goods-item {
|
||||
width: 47%;
|
||||
background-color: #ffffff;
|
||||
border-radius: 12rpx;
|
||||
overflow: hidden;
|
||||
margin-bottom: 20rpx;
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.goods-image {
|
||||
width: 100%;
|
||||
height: 320rpx;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.goods-info {
|
||||
padding: 16rpx;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.goods-title {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
margin-bottom: 10rpx;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
height: 76rpx;
|
||||
}
|
||||
|
||||
.goods-price {
|
||||
font-size: 32rpx;
|
||||
color: #FF5252;
|
||||
font-weight: bold;
|
||||
margin-bottom: 8rpx;
|
||||
width: 100%;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.goods-meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 22rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.loading-more, .no-more {
|
||||
text-align: center;
|
||||
padding: 20rpx 0;
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
/* 发布按钮样式 */
|
||||
.publish-btn {
|
||||
position: fixed;
|
||||
right: 40rpx;
|
||||
bottom: 120rpx;
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
background-color: #3A86FF;
|
||||
color: #ffffff;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 60rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(58, 134, 255, 0.3);
|
||||
}
|
@ -0,0 +1,214 @@
|
||||
// pages/secondhand/publish.js
|
||||
Page({
|
||||
data: {
|
||||
images: [],
|
||||
category: '',
|
||||
title: '',
|
||||
price: '',
|
||||
condition: '',
|
||||
description: '',
|
||||
tradeMethod: '',
|
||||
contact: ''
|
||||
},
|
||||
|
||||
onLoad: function (options) {
|
||||
// 初始化页面
|
||||
},
|
||||
|
||||
// 选择图片
|
||||
chooseImage: function () {
|
||||
const that = this;
|
||||
wx.chooseImage({
|
||||
count: 6 - that.data.images.length,
|
||||
sizeType: ['compressed'],
|
||||
sourceType: ['album', 'camera'],
|
||||
success: function (res) {
|
||||
// 更新图片数组
|
||||
that.setData({
|
||||
images: [...that.data.images, ...res.tempFilePaths]
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 预览图片
|
||||
previewImage: function (e) {
|
||||
const index = e.currentTarget.dataset.index;
|
||||
wx.previewImage({
|
||||
current: this.data.images[index],
|
||||
urls: this.data.images
|
||||
});
|
||||
},
|
||||
|
||||
// 删除图片
|
||||
deleteImage: function (e) {
|
||||
const index = e.currentTarget.dataset.index;
|
||||
const images = this.data.images;
|
||||
images.splice(index, 1);
|
||||
this.setData({
|
||||
images: images
|
||||
});
|
||||
},
|
||||
|
||||
// 选择分类
|
||||
selectCategory: function (e) {
|
||||
this.setData({
|
||||
category: e.currentTarget.dataset.category
|
||||
});
|
||||
},
|
||||
|
||||
// 输入标题
|
||||
inputTitle: function (e) {
|
||||
this.setData({
|
||||
title: e.detail.value
|
||||
});
|
||||
},
|
||||
|
||||
// 输入价格
|
||||
inputPrice: function (e) {
|
||||
this.setData({
|
||||
price: e.detail.value
|
||||
});
|
||||
},
|
||||
|
||||
// 选择新旧程度
|
||||
selectCondition: function (e) {
|
||||
this.setData({
|
||||
condition: e.currentTarget.dataset.condition
|
||||
});
|
||||
},
|
||||
|
||||
// 输入描述
|
||||
inputDescription: function (e) {
|
||||
this.setData({
|
||||
description: e.detail.value
|
||||
});
|
||||
},
|
||||
|
||||
// 选择交易方式
|
||||
selectTradeMethod: function (e) {
|
||||
this.setData({
|
||||
tradeMethod: e.currentTarget.dataset.method
|
||||
});
|
||||
},
|
||||
|
||||
// 输入联系方式
|
||||
inputContact: function (e) {
|
||||
this.setData({
|
||||
contact: e.detail.value
|
||||
});
|
||||
},
|
||||
//雷雨田2025.8.30添加
|
||||
handleSubmit() {
|
||||
if (!this.data.title) {
|
||||
wx.showToast({ title: '标题不能为空', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (!this.data.desc) {
|
||||
wx.showToast({ title: '描述不能为空', icon: 'none' })
|
||||
return
|
||||
}
|
||||
// 校验通过 -> 调用 showSuccess
|
||||
wx.showToast({ title: '发布成功', icon: 'success' })
|
||||
},
|
||||
|
||||
// 校验表单
|
||||
validateForm: function () {
|
||||
if (this.data.images.length === 0) {
|
||||
wx.showToast({
|
||||
title: '请至少上传一张商品图片',
|
||||
icon: 'none'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!this.data.category) {
|
||||
wx.showToast({
|
||||
title: '请选择商品分类',
|
||||
icon: 'none'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!this.data.title) {
|
||||
wx.showToast({
|
||||
title: '请输入商品名称',
|
||||
icon: 'none'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!this.data.price) {
|
||||
wx.showToast({
|
||||
title: '请输入商品价格',
|
||||
icon: 'none'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!this.data.condition) {
|
||||
wx.showToast({
|
||||
title: '请选择商品新旧程度',
|
||||
icon: 'none'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!this.data.description) {
|
||||
wx.showToast({
|
||||
title: '请输入商品描述',
|
||||
icon: 'none'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!this.data.tradeMethod) {
|
||||
wx.showToast({
|
||||
title: '请选择交易方式',
|
||||
icon: 'none'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!this.data.contact) {
|
||||
wx.showToast({
|
||||
title: '请输入联系方式',
|
||||
icon: 'none'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
// 提交发布
|
||||
submitPublish: function () {
|
||||
if (!this.validateForm()) return;
|
||||
|
||||
// 这里应该调用发布商品的接口
|
||||
wx.showLoading({
|
||||
title: '发布中...'
|
||||
});
|
||||
|
||||
// 模拟上传过程
|
||||
setTimeout(() => {
|
||||
wx.hideLoading();
|
||||
wx.showToast({
|
||||
title: '发布成功',
|
||||
icon: 'success',
|
||||
duration: 2000,
|
||||
success: () => {
|
||||
// 延迟返回,让用户看到成功提示
|
||||
setTimeout(() => {
|
||||
wx.navigateBack();
|
||||
}, 1500);
|
||||
}
|
||||
});
|
||||
}, 2000);
|
||||
},
|
||||
|
||||
// 取消发布
|
||||
cancelPublish: function () {
|
||||
wx.showModal({
|
||||
title: '确认取消',
|
||||
content: '确定要放弃发布吗?已填写的内容将不会保存。',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
wx.navigateBack();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
@ -0,0 +1,178 @@
|
||||
.publish-container {
|
||||
padding: 30rpx;
|
||||
background-color: #f7f7f7;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.form-item {
|
||||
margin-bottom: 30rpx;
|
||||
background-color: #ffffff;
|
||||
border-radius: 12rpx;
|
||||
padding: 20rpx;
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
margin-bottom: 15rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* 图片上传区域 */
|
||||
.image-uploader {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.image-item, .upload-btn {
|
||||
width: 180rpx;
|
||||
height: 180rpx;
|
||||
margin-right: 20rpx;
|
||||
margin-bottom: 20rpx;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.uploaded-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.delete-btn {
|
||||
position: absolute;
|
||||
top: -20rpx;
|
||||
right: -20rpx;
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
border-radius: 50%;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.upload-btn {
|
||||
border: 1rpx dashed #cccccc;
|
||||
border-radius: 8rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.upload-icon {
|
||||
font-size: 60rpx;
|
||||
color: #cccccc;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.upload-text {
|
||||
margin-top: 10rpx;
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
/* 分类选择器 */
|
||||
.category-selector, .condition-selector, .trade-selector {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.category-item, .condition-item, .trade-item {
|
||||
padding: 10rpx 20rpx;
|
||||
margin: 0 20rpx 20rpx 0;
|
||||
border-radius: 8rpx;
|
||||
font-size: 28rpx;
|
||||
background-color: #f2f2f2;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.category-item.active, .condition-item.active, .trade-item.active {
|
||||
background-color: #3A86FF;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
/* 输入框样式 */
|
||||
.form-input {
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
border: 1rpx solid #eeeeee;
|
||||
border-radius: 8rpx;
|
||||
padding: 0 20rpx;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.char-count {
|
||||
position: absolute;
|
||||
right: 20rpx;
|
||||
bottom: 20rpx;
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.price-input-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border: 1rpx solid #eeeeee;
|
||||
border-radius: 8rpx;
|
||||
padding: 0 20rpx;
|
||||
height: 80rpx;
|
||||
}
|
||||
|
||||
.price-prefix {
|
||||
font-size: 32rpx;
|
||||
color: #FF5252;
|
||||
margin-right: 10rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.price-input {
|
||||
flex: 1;
|
||||
height: 80rpx;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.form-textarea {
|
||||
width: 100%;
|
||||
height: 200rpx;
|
||||
border: 1rpx solid #eeeeee;
|
||||
border-radius: 8rpx;
|
||||
padding: 20rpx;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 按钮区域 */
|
||||
.btn-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 60rpx;
|
||||
}
|
||||
|
||||
.cancel-btn, .publish-btn {
|
||||
width: 45%;
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
text-align: center;
|
||||
border-radius: 44rpx;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.cancel-btn {
|
||||
background-color: #f2f2f2;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.publish-btn {
|
||||
background-color: #3A86FF;
|
||||
color: #ffffff;
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
/// <reference path="./types/index.d.ts" />
|
||||
|
||||
interface IAppOption {
|
||||
globalData: {
|
||||
userInfo: WechatMiniprogram.UserInfo | null;
|
||||
openid: string;
|
||||
isLoggedIn: boolean;
|
||||
hasUserInfo: boolean;
|
||||
canIUseGetUserProfile: boolean;
|
||||
};
|
||||
userInfoReadyCallback?: WechatMiniprogram.GetUserInfoSuccessCallback;
|
||||
silentLogin: () => void;
|
||||
getUserProfile: (callback: (userInfo: WechatMiniprogram.UserInfo) => void) => void;
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
// 微信小程序类型定义
|
||||
type IAnyObject = Record<string, any>
|
@ -0,0 +1,19 @@
|
||||
export const formatTime = (date: Date) => {
|
||||
const year = date.getFullYear()
|
||||
const month = date.getMonth() + 1
|
||||
const day = date.getDate()
|
||||
const hour = date.getHours()
|
||||
const minute = date.getMinutes()
|
||||
const second = date.getSeconds()
|
||||
|
||||
return (
|
||||
[year, month, day].map(formatNumber).join('/') +
|
||||
' ' +
|
||||
[hour, minute, second].map(formatNumber).join(':')
|
||||
)
|
||||
}
|
||||
|
||||
const formatNumber = (n: number) => {
|
||||
const s = n.toString()
|
||||
return s[1] ? s : '0' + s
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "miniprogram-ts-less-quickstart",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"scripts": {
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "",
|
||||
"dependencies": {}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"strictNullChecks": true,
|
||||
"noImplicitAny": true,
|
||||
"module": "CommonJS",
|
||||
"target": "ES2020",
|
||||
"allowJs": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"esModuleInterop": true,
|
||||
"experimentalDecorators": true,
|
||||
"noImplicitThis": true,
|
||||
"noImplicitReturns": true,
|
||||
"alwaysStrict": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"strict": true,
|
||||
"strictPropertyInitialization": true,
|
||||
"lib": ["ES2020"],
|
||||
"typeRoots": [
|
||||
"./typings"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"./**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
/// <reference path="./types/index.d.ts" />
|
||||
|
||||
interface IAppOption {
|
||||
globalData: {
|
||||
userInfo?: WechatMiniprogram.UserInfo,
|
||||
}
|
||||
userInfoReadyCallback?: WechatMiniprogram.GetUserInfoSuccessCallback,
|
||||
}
|
@ -0,0 +1 @@
|
||||
/// <reference path="./wx/index.d.ts" />
|
@ -0,0 +1,68 @@
|
||||
/*! *****************************************************************************
|
||||
Copyright (c) 2021 Tencent, Inc. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
***************************************************************************** */
|
||||
|
||||
declare namespace WechatMiniprogram.Behavior {
|
||||
type BehaviorIdentifier = string
|
||||
type Instance<
|
||||
TData extends DataOption,
|
||||
TProperty extends PropertyOption,
|
||||
TMethod extends MethodOption,
|
||||
TCustomInstanceProperty extends IAnyObject = Record<string, never>
|
||||
> = Component.Instance<TData, TProperty, TMethod, TCustomInstanceProperty>
|
||||
type TrivialInstance = Instance<IAnyObject, IAnyObject, IAnyObject>
|
||||
type TrivialOption = Options<IAnyObject, IAnyObject, IAnyObject>
|
||||
type Options<
|
||||
TData extends DataOption,
|
||||
TProperty extends PropertyOption,
|
||||
TMethod extends MethodOption,
|
||||
TCustomInstanceProperty extends IAnyObject = Record<string, never>
|
||||
> = Partial<Data<TData>> &
|
||||
Partial<Property<TProperty>> &
|
||||
Partial<Method<TMethod>> &
|
||||
Partial<OtherOption> &
|
||||
Partial<Lifetimes> &
|
||||
ThisType<Instance<TData, TProperty, TMethod, TCustomInstanceProperty>>
|
||||
interface Constructor {
|
||||
<
|
||||
TData extends DataOption,
|
||||
TProperty extends PropertyOption,
|
||||
TMethod extends MethodOption,
|
||||
TCustomInstanceProperty extends IAnyObject = Record<string, never>
|
||||
>(
|
||||
options: Options<TData, TProperty, TMethod, TCustomInstanceProperty>
|
||||
): BehaviorIdentifier
|
||||
}
|
||||
|
||||
type DataOption = Component.DataOption
|
||||
type PropertyOption = Component.PropertyOption
|
||||
type MethodOption = Component.MethodOption
|
||||
type Data<D extends DataOption> = Component.Data<D>
|
||||
type Property<P extends PropertyOption> = Component.Property<P>
|
||||
type Method<M extends MethodOption> = Component.Method<M>
|
||||
|
||||
type DefinitionFilter = Component.DefinitionFilter
|
||||
type Lifetimes = Component.Lifetimes
|
||||
|
||||
type OtherOption = Omit<Component.OtherOption, 'options'>
|
||||
}
|
||||
/** 注册一个 `behavior`,接受一个 `Object` 类型的参数。*/
|
||||
declare let Behavior: WechatMiniprogram.Behavior.Constructor
|