管理员可以修改项目所属人

This commit is contained in:
sdaduanbilei 2025-12-02 11:39:24 +08:00
parent 8eb2c136b9
commit 522d847094
23 changed files with 460 additions and 36 deletions

View File

@ -13,7 +13,9 @@
"pages/user/index",
"pages/add/index",
"pages/community/add",
"pages/badge/index"
"pages/badge/index",
"pages/user/about",
"pages/community/info"
],
"window": {
"navigationBarTextStyle": "black",
@ -62,6 +64,14 @@
}
]
},
"permission": {
"scope.userFuzzyLocation": {
"desc": "您的位置信息将用于智能规划养护任务"
}
},
"requiredPrivateInfos": [
"getFuzzyLocation"
],
"componentFramework": "glass-easel",
"sitemapLocation": "sitemap.json",
"lazyCodeLoading": "requiredComponents",

View File

@ -25,7 +25,7 @@
</view>
</view>
<view class="flex flex-center flex-justify-between full-width mt-32">
<!-- <view class="flex flex-center flex-justify-between full-width mt-32">
<view class="flex flex-center">
<t-icon name="artboard"></t-icon>
<view class="ml-5">参与话题</view>
@ -33,7 +33,7 @@
</view>
<view class="flex flex-center flex-justify-start full-width mt-16" >
<t-tag shape="round" theme="primary">#植物园的秋天</t-tag>
</view>
</view> -->
</view>
<view class="full-width flex flex-center " style="margin-top: 96rpx;">

View File

@ -21,7 +21,15 @@ Page({
},
handleClick(){
goAdd(){
const tmp = wx.getStorageSync('user')
// todo
// if (tmp.phone.length === 0){
// wx.navigateTo({
// url: '../login/index',
// })
// return
// }
wx.navigateTo({
url: '../community/add',
})
@ -34,6 +42,15 @@ Page({
},
goInfo(e){
const id = e.currentTarget.dataset.id
wx.navigateTo({
url: '../community/info?id=' +id,
})
},
/**
* 生命周期函数--监听页面显示
*/

View File

@ -7,7 +7,7 @@
</t-tabs>
<view class="padding">
<view wx:for="{{list}}" class="padding row mb-32">
<view wx:for="{{list}}" class="padding row mb-32" data-id="{{item.id}}" bind:tap="goInfo">
<view class="flex flex-center flex-justify-start">
<image src="https://res.catter.cn/pub/2025/09/30/20250930143142508.png" class="avatar"></image>
<view class="ml-16">
@ -45,5 +45,5 @@
</view>
</view>
<t-fab icon="camera" bind:click="handleClick" aria-label="增加"></t-fab>
<t-fab icon="camera" bind:click="goAdd" aria-label="增加"></t-fab>
</view>

View File

@ -8,7 +8,7 @@
.grid {
display: grid;
grid-template-columns: 30% 30% 30%;
grid-template-columns: 32% 32% 32%;
grid-row-gap: 8px;
grid-column-gap: 8px;
}

99
pages/community/info.js Normal file
View File

@ -0,0 +1,99 @@
const { api } = require("../../utils/api")
// pages/community/info.js
Page({
/**
* 页面的初始数据
*/
data: {
id : '',
info:null,
content:'',
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
const id = options.id
this.data.id = id
this.fetchInfo()
},
fetchInfo(){
api('/post/detail','GET',{id: this.data.id}).then(res => {
if (res.code== 200){
const tmp = res.data
this.setData({info:tmp})
}
})
},
input(e){
const value = e.detail.value
console.log(value);
this.data.content = value
},
add(){
const data = {content: this.data.content, postId: this.data.id,parentId: this.data.id,rootId:this.data.id}
console.log(data);
api('/comment/add','POST',data,'json').then(res => {
if (res.code === 200){
this.fetchInfo()
}
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})

View File

@ -0,0 +1,3 @@
{
"usingComponents": {}
}

70
pages/community/info.wxml Normal file
View File

@ -0,0 +1,70 @@
<!--pages/community/info.wxml-->
<view>
<view style="padding-bottom: 200rpx;">
<view wx:if="{{info}}" class="padding row mb-32" data-id="{{item.id}}" bind:tap="goInfo">
<view class="flex flex-center flex-justify-start">
<image src="https://res.catter.cn/pub/2025/09/30/20250930143142508.png" class="avatar"></image>
<view class="ml-16">
<view class="bold">第五季</view>
<view class="font-12 grey">23 小时前</view>
</view>
</view>
<view class="mt-16">
<view>{{info.content}}</view>
</view>
<view class="mt-16">
<view wx:if="{{info.imgList.length == 1}}">
<view wx:for="{{info.imgList}}">
<image src="{{info.url}}" style="border-radius: 16rpx; height: 50vw; width: 100%;" mode="aspectFill"></image>
</view>
</view>
<view wx:else class="grid">
<view class="item" wx:for="{{info.imgList}}">
<view>
<image src="{{item.url}}" style="width: 100%;height: 30vw; border-radius: 16rpx;" mode="aspectFill" b></image>
</view>
</view>
</view>
</view>
<view class="mt-32 flex flex-center flex-justify-end">
<view class="flex flex-center" data-item="{{info}}" bind:tap="like">
<t-icon name="{{info.hasLiked === 1 ?'thumb-up-filled':'thumb-up'}}" style="color: {{info.hasLiked === 1 ?'red':''}};"></t-icon>
<view class="ml-16">{{info.likeCount}}</view>
</view>
<view class="flex flex-center ml-32">
<t-icon name="chat-bubble-smile"></t-icon>
<view class="ml-16">{{info.commentCount}}</view>
</view>
</view>
</view>
<view class="white-bg padding" style="border-bottom: #F6F6F6 1rpx solid;" wx:for="{{info.commentList}}">
<view class="flex flex-center flex-justify-start flex-aligin-start">
<t-avatar class="avatar-example" shape="round" wx:if="{{item.user.avatar}}" image="item.user.avatar" size="60rpx" />
<t-avatar class="avatar-example" shape="round" wx:else image="https://res.catter.cn/pub/2025/12/02/202512021046843.jpg" size="60rpx" />
<view class="full-width">
<view class="font-12 ml-16 flex flex-center flex-justify-between">
<view class="primary">
{{item.user.name}}
</view>
<view class="font-12 grey">
{{item.createdAt}}
</view>
</view>
<view class="mt-16 ml-16 font-12">
<view>{{item.content}}</view>
</view>
</view>
</view>
</view>
</view>
<view class="bottom">
<view class="flex flex-center flex-justify-between">
<t-input borderless placeholder="发表评论:" bind:change="input"></t-input>
<t-icon name="send" size="30" class="ml-32" bind:tap="add"></t-icon>
</view>
</view>
</view>

29
pages/community/info.wxss Normal file
View File

@ -0,0 +1,29 @@
/* pages/community/info.wxss */
.avatar {
height: 80rpx;
width: 80rpx;
border: white 2rpx solid;
border-radius: 60rpx;
}
.grid {
display: grid;
grid-template-columns: 32% 32% 32%;
grid-row-gap: 8px;
grid-column-gap: 8px;
}
.item {
background-color: #f1f1f1;
width: 100%;
}
.bottom {
position: fixed;
bottom: 0;
background-color: #F6F6F6;
left: 0;
right: 0;
padding:32rpx;
z-index: 2;
}

View File

@ -37,15 +37,15 @@
<image class="pic" mode="aspectFill" wx:else src="https://res.catter.cn/pub/2025/09/30/20250930143920286.png"></image>
<view style="margin-left:16rpx;" class="full-width">
<view class="flex flex-center flex-justify-between full-width">
<view class="font-16 bold">{{item.name}}</view>
<view class="font-16 bold">{{item.plant.name}}</view>
<t-tag wx:if="{{item.todayCare.status === 1}}" shape="round" theme="primary">立即完成</t-tag>
<t-tag wx:if="{{item.todayCare.status === 2}}" shape="round">已完成</t-tag>
<t-tag wx:if="{{item.todayCare.status === 3}}" shape="round" theme="primary">跳过</t-tag>
<t-tag wx:if="{{item.todayCare.status === 4}}" shape="round" theme="danger">已逾期{{item.todayCare.expireDays}}天</t-tag>
</view>
<view class="flex flex-center flex-justify-start mt-16 ">
<view class="mr-16 flex flex-center" wx:for="{{item.todayCares}}">
<t-icon name="{{item.icon}}" style="color: {{item.color}};"></t-icon>
<view>
<view class="font-12 grey">上次养护:{{item.plant.lastPeriod}}</view>
</view>
</view>
</view>

View File

@ -38,6 +38,22 @@ Page({
*/
onShow() {
this.fetchList()
this.fethcLocation()
},
fethcLocation(){
wx.getFuzzyLocation({
type: 'wgs84',
success (res) {
console.log(res);
const latitude = res.latitude
const longitude = res.longitude
console.log(latitude,longitude);
},
fail(err){
console.log(err);
}
})
},
fetchList() {
api('/plant/page', 'POST', {
@ -124,6 +140,13 @@ Page({
goAdd() {
const tmp = wx.getStorageSync('user')
if (tmp.phone.length === 0){
wx.navigateTo({
url: '../login/index',
})
return
}
wx.navigateTo({
url: '../add/index',
})

View File

@ -32,19 +32,19 @@
</view>
</view>
<view class="info font-12">
<view wx:if="{{item.todayCares}}" class="flex flex-center flex-justify-start">
<view wx:if="{{item.needCare}}" class="flex flex-center flex-justify-start">
<t-icon name="saturation" style="color: #4B84EE;"></t-icon>
<view class="ml-5 small">
今日需养护
</view>
</view>
<view wx:else>
<t-icon name="saturation" style="color: #4B84EE;"></t-icon>
<view class=" smallml-5">
<view wx:else class="flex flex-center flex-justify-start">
<t-icon name="saturation" style="color: #4FAB5F;"></t-icon>
<view class="small ml-5">
今日无需养护
</view>
</view>
<view class="mt-5 grey small">上次养护:{{item.lastPeriod ? itme.lastPeriod:'-' }} 天前</view>
<view class="mt-5 grey small">上次养护:{{item.lastPeriod ? item.lastPeriod:'-' }} </view>
</view>
</view>
</block>
@ -76,7 +76,7 @@
今日无需养护
</view>
</view>
<view class="mt-5 grey small">上次养护:{{item.lastPeriod ? itme.lastPeriod:'-' }} 天前</view>
<view class="mt-5 grey small">上次养护:{{item.lastPeriod ? item.lastPeriod:'-' }}</view>
</view>
</view>
</block>

View File

@ -29,10 +29,14 @@ Page({
this.setData({openData:tmp})
},
goPrivate(){
wx.openPrivacyContract()
},
read(){
if (this.data.checked === false){
wx.showModal({
content: '请先勾选我已经阅读并同意《植趣用户协议》和《植趣隐私政策》',
content: '请先勾选我已经阅读并同意《植趣用户协议》',
})
}
},
@ -60,7 +64,7 @@ Page({
})
},
change(e){
const tmp = this.data.checked === false
const tmp = this.data.checked === false
console.log(tmp);
this.setData({checked:tmp})
}

View File

@ -1,6 +1,6 @@
{
"navigationBarTitleText": "账号登录",
"usingComponents": {
"t-radio": "tdesign-miniprogram/radio/radio"
}
}

View File

@ -9,11 +9,11 @@
</view>
<view class="flex flex-center bottom" >
<t-radio bind:change="change" borderless checked="{{checked}}">
<view slot="label" class="font-12 grey">
我已经阅读并同意 <p class="primary">《植趣用户协议》</p> 和<p class="primary">《植趣隐私政策》</p>
<view class="flex flex-center " bind:tap="change">
<t-icon name="{{checked ? 'check-circle-filled':'check-circle'}}" class="{{checked ?'primary':'grey' }}" size="18"></t-icon>
<view slot="label" class="font-12 grey ml-5" >
我已经阅读并同意 <p class="primary" bind:tap="goPrivate">《植趣用户协议》</p>
</view>
</t-radio>
</view>
</view>
</view>

66
pages/user/about.js Normal file
View File

@ -0,0 +1,66 @@
// pages/user/about.js
Page({
/**
* 页面的初始数据
*/
data: {
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})

4
pages/user/about.json Normal file
View File

@ -0,0 +1,4 @@
{
"navigationBarTitleText": "植趣微信群",
"usingComponents": {}
}

8
pages/user/about.wxml Normal file
View File

@ -0,0 +1,8 @@
<!--pages/user/about.wxml-->
<view class="content padding">
<view class="flex flex-aligin-center flex-col padding row">
<image src="https://res.catter.cn/kaka/2024/11/02/1730546862685.JPG" style="height: 960rpx;" show-menu-by-longpress></image>
<view class="padding">长按二维码,加入群聊,</view>
<view class="padding">一起交流种植小技巧</view>
</view>
</view>

1
pages/user/about.wxss Normal file
View File

@ -0,0 +1 @@
/* pages/user/about.wxss */

View File

@ -1,5 +1,5 @@
const { api } = require("../../utils/api")
const config = require("../../config/config")
// pages/user/index.js
Page({
@ -16,7 +16,7 @@ Page({
*/
onLoad(options) {
const tmp = wx.getStorageSync('user')
if ( tmp){
if (tmp){
this.setData({user:tmp})
}
},
@ -37,11 +37,57 @@ Page({
fetchInfo(){
api('/personal/personal','GET').then(res => {
if (res.code === 200){
const tmps = res.data
this.setData({info:res.data})
}
})
},
onChooseAvatar(e) {
const avatarUrl = e.detail.avatarUrl
// 上传
const _this = this
wx.uploadFile({
filePath: avatarUrl,
name: 'file',
header: {
'Authorization': 'Bearer ' + wx.getStorageSync('token'),
},
url: config.baseUrl + '/oss/upload',
success: res => {
var data = JSON.parse(res.data)
if (data.code === 200) {
const tmps = _this.data.user
tmps.avatar = data.data.file
_this.setData({
user:tmps
})
_this.update()
}
}
})
},
update(){
api('/user/update','POST',this.data.user,"json").then(res => {
if (res.code === 200){
}
})
},
goAbout(){
wx.navigateTo({
url: '../user/about',
})
},
goPrivate(){
wx.openPrivacyContract()
},
/**
* 生命周期函数--监听页面隐藏
*/

View File

@ -2,10 +2,14 @@
<view>
<!-- top -->
<view class="bg">
<view wx:if="{{info}}">
<view style="margin-top: 128rpx;" class="flex flex-center flex-justify-start" wx:if="{{user}}">
<image src="https://res.catter.cn/pub/2025/09/30/20250930143142508.png" class="avatar"></image>
<view class="white ml-32">
<view wx:if="{{info}}" >
<view class="flex flex-center flex-justify-start" style="margin-top:128rpx;">
<view style="width: 140rpx;height:140rpx;" class="flex flex-center flex-justify-start full-width ">
<button class="avatar-wrapper" open-type="chooseAvatar" bind:chooseavatar="onChooseAvatar" style="background-color: red;">
<image class="avatar-example" src="{{user.avatar ? user.avatar.url : 'https://res.catter.cn/pub/2025/09/30/20250930143142508.png'}}" />
</button>
</view>
<view class="white ml-16">
<view class="font-16">
{{user.name}}
</view>
@ -14,7 +18,7 @@
</view>
</view>
</view>
<view class="white flex flex-center flex-justify-start mt-32">我的徽章 已解锁 23 个</view>
<view class="white flex flex-center flex-justify-start mt-16">我的徽章 已解锁 23 个</view>
<view class="mt-32">
<view class="">🎖️🎖️🎖️🎖️🎖️🎖️🎖️</view>
</view>
@ -76,10 +80,10 @@
<view style="padding: 0 32rpx">
<view class="row " style="padding-top: 8rpx; padding-bottom: 8rpx;">
<t-cell title="提醒设置(浇水/施肥时间)" hover arrow />
<t-cell title="关于我们" hover arrow />
<t-cell title="用户协议 / 隐私政策" hover arrow />
<t-cell title="邀请好友" hover arrow bordered="{{false}}" description="成功邀请可以获得稀有种子" />
<t-cell title="提醒设置" hover arrow />
<t-cell title="加入微信群" hover arrow bind:tap="goAbout" />
<t-cell title="用户协议" hover arrow bind:tap="goPrivate" />
<t-cell title="邀请好友" hover arrow bordered="{{false}}" description="成功邀请可以获得稀有种子" />
</view>
</view>

View File

@ -2,6 +2,7 @@
.bg {
background-color: #4FAB5F;
padding: 32rpx;
}
.avatar {
@ -11,6 +12,33 @@
border-radius: 60rpx;
}
button::after {
border: none;
}
.avatar-wrapper {
padding: 0;
background-color: rebeccapurple !important;
width: 280rpx;
}
.avatar-example {
width: 120rpx;
height: 120rpx;
border-radius: 100%;
border: white solid 1px;
object-fit: contain;
margin-top: 32rpx;
}
.avatar-wrapper {
padding: 0;
background-color: transparent !important;
width: 280rpx;
}
.camera{
background-color: #4fab5e3d;
width: 100rpx;

View File

@ -20,5 +20,17 @@
"bigPackageSizeSupport": false
},
"libVersion": "3.10.1",
"condition": {}
"condition": {
"miniprogram": {
"list": [
{
"name": "pages/community/info",
"pathName": "pages/community/info",
"query": "id=d7082150-c68d-11f0-b4a9-bc2411e64a23",
"scene": null,
"launchMode": "default"
}
]
}
}
}