This commit is contained in:
qiuyuan 2025-12-29 13:54:05 +08:00
parent 2736f63505
commit 98435311b2
4 changed files with 1052 additions and 1174 deletions

View File

@ -1,165 +0,0 @@
<template>
<view class="container">
<canvas canvas-id="myCanvas" style="width: 300px; height: 300px;"></canvas>
<button @tap="uploadImage">上传印章图片</button>
<button @tap="processImage" v-if="imagePath">处理图片</button>
<image :src="processedImage" v-if="processedImage" mode="widthFix"></image>
</view>
</template>
<script>
import { BASE_URL,IMAGE_BASE_URL } from '@/utils/config';
export default {
data() {
return {
imagePath: '',
processedImage: ''
}
},
methods: {
//
uploadImage() {
const that = this;
uni.chooseImage({
count: 1,
sourceType: ['album', 'camera'],
success: function (res) {
that.imagePath = res.tempFilePaths[0];
that.drawImageToCanvas();
}
});
},
// Canvas
drawImageToCanvas() {
const that = this;
const ctx = uni.createCanvasContext('myCanvas', this);
// Canvas
ctx.clearRect(0, 0, 300, 300);
//
uni.getImageInfo({
src: that.imagePath,
success: function (res) {
ctx.drawImage(res.path, 0, 0, 300, 300);
ctx.draw(false, () => {
console.log('图片绘制完成');
});
}
});
},
//
processImage() {
const that = this;
const ctx = uni.createCanvasContext('myCanvas', this);
// Canvas
uni.canvasGetImageData({
canvasId: 'myCanvas',
x: 0,
y: 0,
width: 300,
height: 300,
success: function(res) {
const data = res.data;
//
for (let i = 0; i < data.length; i += 4) {
const r = data[i];
const g = data[i + 1];
const b = data[i + 2];
//
if (r > 200 && g > 200 && b > 200) {
data[i + 3] = 0; // Alpha0
}
}
// Canvas
uni.canvasPutImageData({
canvasId: 'myCanvas',
x: 0,
y: 0,
width: 300,
height: 300,
data: data,
success: function() {
// Canvas
that.canvasToImage();
}
});
}
});
},
// Canvas
canvasToImage() {
const that = this;
uni.canvasToTempFilePath({
canvasId: 'myCanvas',
success: function(res) {
that.processedImage = res.tempFilePath;
const fileList = [{
url: res.tempFilePath,
status: 'uploading'
}];
console.log("==fileList",fileList)
// 4.
that.uploadFile(fileList[0]);
//
console.log('处理后的图片路径:', res.tempFilePath);
},
fail: function(err) {
console.error('Canvas转换失败', err);
}
});
},
async uploadFile(file) {
try {
await new Promise((resolve, reject) => {
uni.uploadFile({
url: `${IMAGE_BASE_URL}/api/v1/upload`,
filePath: file.url,
name: 'file',
header: {
'Authorization': `Bearer ${uni.getStorageSync('token')}`,
'Content-Type': 'multipart/form-data'
},
success: (uploadRes) => {
try {
const data = JSON.parse(uploadRes.data);
if (data.success) {
resolve(data.data);
} else {
reject(data.message || '上传失败');
}
} catch (e) {
reject('解析响应失败');
}
},
fail: (err) => reject(err)
});
});
} catch (err) {
console.error('上传失败:', err);
const index = this.fileList.findIndex(f => f.url === file.url);
if (index !== -1) {
this.$set(this.fileList, index, {
...file,
status: 'failed',
error: err.message || err
});
}
uni.showToast({
title: `上传失败: ${err.message || err}`,
icon: 'none'
});
throw err;
}
},
}
}
</script>

View File

@ -90,7 +90,7 @@
</view> </view>
<view class="service-grid"> <view class="service-grid">
<view class="service-card card-1" @click="goDetail('neighborList')" hover-class="card-hover"> <!-- <view class="service-card card-1" @click="goDetail('neighborList')" hover-class="card-hover">
<view class="card-content"> <view class="card-content">
<text class="card-title">邻里互助</text> <text class="card-title">邻里互助</text>
<text class="card-desc">近邻互帮互助</text> <text class="card-desc">近邻互帮互助</text>
@ -107,6 +107,15 @@
<view class="card-bg"></view> <view class="card-bg"></view>
</view> </view>
<image class="card-icon" src="/static/imgs/index/weixiu.png" style="width: 80rpx;height: 80rpx;bottom: 32rpx;"></image> <image class="card-icon" src="/static/imgs/index/weixiu.png" style="width: 80rpx;height: 80rpx;bottom: 32rpx;"></image>
</view> -->
<view class="service-card card-1" @click="goDetail('meetingList')" hover-class="card-hover">
<view class="card-content">
<text class="card-title">会客厅预约</text>
<text class="card-desc">社区服务功能</text>
<view class="card-bg"></view>
</view>
<image class="card-icon" src="/static/imgs/index/bangzhu.png"
style="width: 68rpx;height: 68rpx; bottom: 48rpx;"></image>
</view> </view>
</view> </view>
</view> </view>
@ -160,6 +169,8 @@ export default {
goDetail(page) { goDetail(page) {
if(page==='neighbor'){ if(page==='neighbor'){
navigateTo({url: `/pages/${page}/index`}) navigateTo({url: `/pages/${page}/index`})
}else if( page == 'serviceTickets'){
uni.showToast({ title: '此功能暂未开放', icon: 'error' });
}else{ }else{
uni.navigateTo({ uni.navigateTo({
url: `/pages/${page}/index` url: `/pages/${page}/index`

View File

@ -47,8 +47,7 @@
手机号快捷登录 手机号快捷登录
</button> </button>
<button class="auth-button" <button class="auth-button" @click="showEditModal=false">
@click="showEditModal=false">
取消登录授权 取消登录授权
</button> </button>
@ -61,8 +60,10 @@
<view class="auth-agreement"> <view class="auth-agreement">
<checkbox-group @change="handleAgreementChange"> <checkbox-group @change="handleAgreementChange">
<label> <label>
<checkbox :checked="agreementChecked" color="#2979ff" style="transform:scale(0.7)"/> <checkbox :checked="agreementChecked" color="#2979ff" style="transform:scale(0.7)" />
我已阅读并同意<text class="agreement-link" @click.stop="goToAgreement('userAgreement')">用户协议</text><text class="agreement-link" @click.stop="goToAgreement('agreement')">隐私政策</text> 我已阅读并同意<text class="agreement-link"
@click.stop="goToAgreement('userAgreement')">用户协议</text><text
class="agreement-link" @click.stop="goToAgreement('agreement')">隐私政策</text>
</label> </label>
</checkbox-group> </checkbox-group>
</view> </view>
@ -73,17 +74,15 @@
<text class="form-label">头像</text> <text class="form-label">头像</text>
<view class="avatar-upload-container" @click="onAvatarClick"> <view class="avatar-upload-container" @click="onAvatarClick">
<view class="avatar-preview"> <view class="avatar-preview">
<image <image v-if="avatarList.length > 0" :src="avatarList[0].url" mode="aspectFill"
v-if="avatarList.length > 0"
:src="avatarList[0].url"
mode="aspectFill"
class="avatar-img"> class="avatar-img">
</image> </image>
<view v-else class="avatar-placeholder"> <view v-else class="avatar-placeholder">
<u-icon name="plus" color="#c0c4cc" size="28"></u-icon> <u-icon name="plus" color="#c0c4cc" size="28"></u-icon>
<text class="placeholder-text">点击上传</text> <text class="placeholder-text">点击上传</text>
</view> </view>
<view v-if="avatarList.length > 0" class="avatar-delete" @click.stop="handleAvatarDelete"> <view v-if="avatarList.length > 0" class="avatar-delete"
@click.stop="handleAvatarDelete">
<u-icon name="close" color="#fff" size="26"></u-icon> <u-icon name="close" color="#fff" size="26"></u-icon>
</view> </view>
</view> </view>
@ -104,20 +103,14 @@
</view> </view>
</view> </view>
</u-modal> </u-modal>
<u-modal <u-modal :show="showPhoneDialog" title="联系社区" confirm-text="拨打" cancel-text="取消" @confirm="callCommunityPhone"
:show="showPhoneDialog" @cancel="showPhoneDialog = false" :closeOnClickOverlay="true">
title="联系社区"
confirm-text="拨打"
cancel-text="取消"
@confirm="callCommunityPhone"
@cancel="showPhoneDialog = false"
:closeOnClickOverlay="true">
<view class="phone-dialog-content"> <view class="phone-dialog-content">
<text>社区电话</text> <text>社区电话</text>
<text class="phone-number">{{communityPhone}}</text> <text class="phone-number">{{communityPhone}}</text>
</view> </view>
</u-modal> </u-modal>
<Copyright/> <Copyright />
<Footer></Footer> <Footer></Footer>
</view> </view>
</template> </template>
@ -135,7 +128,8 @@
} from '@/utils/config'; } from '@/utils/config';
export default { export default {
components: { components: {
Footer,Copyright Footer,
Copyright
}, },
data() { data() {
return { return {
@ -156,30 +150,32 @@
uploading: false, uploading: false,
displayAvatar: '/static/imgs/index/nav.png', displayAvatar: '/static/imgs/index/nav.png',
agreementChecked: false, agreementChecked: false,
choseList: [{ choseList: [
key: 1, // {
url: "/static/imgs/service/service_list.png", // key: 1,
name: '全部工单', // url: "/static/imgs/service/service_list.png",
pageUrl: 'myTickets' // name: '',
}, // pageUrl: 'myTickets'
{ // },
key: 2,
url: "/static/imgs/service/service_help.png",
name: '邻里互助',
pageUrl: 'mySeekHelp'
},
{
key: 3,
url: "/static/imgs/service/service_service.png",
name: '周边服务',
pageUrl: 'neighbor'
},
{ {
key: 4, key: 4,
url: "/static/imgs/service/service_friend.png", url: "/static/imgs/service/service_friend.png",
name: '会客厅预约', name: '会客厅预约',
pageUrl: 'meetingList' pageUrl: 'meetingList'
}, },
// {
// key: 2,
// url: "/static/imgs/service/service_help.png",
// name: '',
// pageUrl: 'mySeekHelp'
// },
{
key: 3,
url: "/static/imgs/service/service_service.png",
name: '周边服务',
pageUrl: 'neighbor'
},
{ {
key: 5, key: 5,
url: "/static/imgs/service/service_notice.png", url: "/static/imgs/service/service_notice.png",
@ -248,7 +244,9 @@
const file = { const file = {
url: tempFilePaths[0] url: tempFilePaths[0]
}; };
this.handleAvatarUpload({ file }); this.handleAvatarUpload({
file
});
} }
}, },
fail: (err) => { fail: (err) => {
@ -732,24 +730,29 @@
box-sizing: border-box; box-sizing: border-box;
padding-bottom: calc(100rpx + 50rpx); padding-bottom: calc(100rpx + 50rpx);
} }
.user-info-card { .user-info-card {
background: #fff; background: #fff;
border-radius: 16rpx; border-radius: 16rpx;
padding: 40rpx 30rpx; padding: 40rpx 30rpx;
margin-bottom: 24rpx; margin-bottom: 24rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.04); box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.04);
.user-info { .user-info {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
} }
} }
.avatar-section { .avatar-section {
margin-bottom: 20rpx; margin-bottom: 20rpx;
.avatar-wrapper { .avatar-wrapper {
position: relative; position: relative;
width: 140rpx; width: 140rpx;
height: 140rpx; height: 140rpx;
.avatar { .avatar {
width: 100%; width: 100%;
height: 100%; height: 100%;
@ -757,6 +760,7 @@
border: 4rpx solid #fff; border: 4rpx solid #fff;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1); box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);
} }
.edit-icon { .edit-icon {
position: absolute; position: absolute;
right: 0; right: 0;
@ -770,6 +774,7 @@
justify-content: center; justify-content: center;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1); box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
} }
.u-loading-icon { .u-loading-icon {
position: absolute; position: absolute;
top: 0; top: 0;
@ -785,66 +790,79 @@
} }
} }
} }
.name-section { .name-section {
width: 100%; width: 100%;
align-items: center; align-items: center;
text-align: center; text-align: center;
margin-bottom: 30rpx; margin-bottom: 30rpx;
.name { .name {
font-size: 36rpx; font-size: 36rpx;
font-weight: 600; font-weight: 600;
color: #333; color: #333;
} }
.phone { .phone {
color: #999; color: #999;
font-size: 24rpx; font-size: 24rpx;
} }
} }
.description-card { .description-card {
background: #f8f9fa; background: #f8f9fa;
border-radius: 12rpx; border-radius: 12rpx;
padding: 24rpx; padding: 24rpx;
width: 100%; width: 100%;
text-align: center; text-align: center;
.title { .title {
font-size: 28rpx; font-size: 28rpx;
color: #666; color: #666;
margin-bottom: 12rpx; margin-bottom: 12rpx;
display: block; display: block;
} }
.content { .content {
font-size: 26rpx; font-size: 26rpx;
color: #999; color: #999;
line-height: 1.5; line-height: 1.5;
} }
} }
.function-card { .function-card {
background: #fff; background: #fff;
border-radius: 16rpx; border-radius: 16rpx;
padding: 0 30rpx; padding: 0 30rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.04); box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.04);
.button-item { .button-item {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
padding: 28rpx 0; padding: 28rpx 0;
border-bottom: 1rpx solid #f2f3f5; border-bottom: 1rpx solid #f2f3f5;
&:active { &:active {
background-color: #f8f8f8; background-color: #f8f8f8;
} }
&:last-child { &:last-child {
border-bottom: none; border-bottom: none;
} }
.button-content { .button-content {
display: flex; display: flex;
align-items: center; align-items: center;
flex: 1; flex: 1;
} }
.icon { .icon {
width: 48rpx; width: 48rpx;
height: 48rpx; height: 48rpx;
margin-right: 24rpx; margin-right: 24rpx;
} }
.label { .label {
font-size: 30rpx; font-size: 30rpx;
color: #333; color: #333;
@ -852,17 +870,21 @@
} }
} }
} }
.modal-content { .modal-content {
padding: 0 30rpx; padding: 0 30rpx;
width: 90%; width: 90%;
margin: 0 auto; margin: 0 auto;
max-height: 70vh; max-height: 70vh;
overflow-y: auto; overflow-y: auto;
/* 编辑表单区域 */ /* 编辑表单区域 */
.edit-section { .edit-section {
padding: 20rpx 0; padding: 20rpx 0;
.form-item { .form-item {
margin-bottom: 40rpx; margin-bottom: 40rpx;
.form-label { .form-label {
display: block; display: block;
font-size: 28rpx; font-size: 28rpx;
@ -870,12 +892,14 @@
margin-bottom: 16rpx; margin-bottom: 16rpx;
font-weight: 500; font-weight: 500;
} }
.upload-tip { .upload-tip {
font-size: 24rpx; font-size: 24rpx;
color: #999; color: #999;
margin-top: 10rpx; margin-top: 10rpx;
text-align: center; text-align: center;
} }
.word-count { .word-count {
text-align: right; text-align: right;
font-size: 24rpx; font-size: 24rpx;
@ -884,12 +908,14 @@
} }
} }
} }
/* 授权登录区域 - 修改相关文案和图标 */ /* 授权登录区域 - 修改相关文案和图标 */
.auth-section { .auth-section {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
padding: 40rpx 0; padding: 40rpx 0;
.auth-title { .auth-title {
font-size: 32rpx; font-size: 32rpx;
color: #333; color: #333;
@ -897,6 +923,7 @@
text-align: center; text-align: center;
font-weight: 500; font-weight: 500;
} }
.auth-button { .auth-button {
display: flex; display: flex;
align-items: center; align-items: center;
@ -925,21 +952,26 @@
} }
.phone-button { .phone-button {
background: #07C160; /* 微信绿色,保持原有成功色 */ background: #07C160;
/* 微信绿色,保持原有成功色 */
} }
.auth-agreement { .auth-agreement {
margin-top: 20rpx; margin-top: 20rpx;
font-size: 24rpx; font-size: 24rpx;
color: #666; color: #666;
.agreement-link { .agreement-link {
color: #2979ff; color: #2979ff;
} }
} }
} }
.phone-dialog-content { .phone-dialog-content {
padding: 40rpx; padding: 40rpx;
text-align: center; text-align: center;
font-size: 32rpx; font-size: 32rpx;
.phone-number { .phone-number {
font-weight: bold; font-weight: bold;
color: #2979ff; color: #2979ff;