绿满眶商城微信小程序-uniapp
xiangpei
2025-06-03 877c92743693f645bbf86cfbfe8d28c7f1196575
视频主页-个人信息修改
5个文件已修改
1个文件已添加
340 ■■■■■ 已修改文件
api/user.js 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages.json 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/tabbar/video/video.vue 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/video/home-page-edit.vue 278 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/video/home-page.vue 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/video/video-play.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api/user.js
@@ -49,3 +49,17 @@
  });
}
/**
 * 保存视频主页信息编辑
 *
 * @param params
 */
 export function saveVideoHomeInfo(data) {
  return http.request({
    url: "/lmk/video/home-page-info-edit",
    method: Method.POST,
    needToken: true,
    data: data
  });
}
pages.json
@@ -813,6 +813,13 @@
                    {
                        "navigationBarTitleText" : ""
                    }
                },
                {
                    "path" : "home-page-edit",
                    "style" :
                    {
                        "navigationBarTitleText" : "主页信息修改"
                    }
                }
            ]
        },
pages/tabbar/video/video.vue
@@ -20,7 +20,7 @@
        </view>
        <view class="video-actions">
          <u-button type="error" size="mini" @click="reUpload">重新上传</u-button>
          <u-button type="primary" size="mini" @click="chooseCover" v-if="videoInfo.url">选择封面</u-button>
          <u-button type="primary" size="mini" @click="chooseCover" v-if="videoInfo.url">{{formData.cover ? '更换封面' : '请选择封面'}}</u-button>
        </view>
      </view>
    </view>
@@ -57,7 +57,7 @@
                :key="index"
                :text="tag.tagName"
                :index="index"
                type="error"
                type="success"
                @close="removeTag(index)"
              />
            </view>
@@ -74,7 +74,7 @@
                :key="index"
                :text="tag.tagName"
                  :index="index"
                type="primary"
                type="success"
                :closeable="false"
                @click="selectTopic(index)"
              />
@@ -178,7 +178,8 @@
import UInput from '@/uview-components/uview-ui/components/u-input/u-input.vue';
import USearch from '@/uview-components/uview-ui/components/u-search/u-search.vue';
import UPopup from '@/uview-components/uview-ui/components/u-popup/u-popup.vue';
import MyTag from "@/components/my-tag.vue"
import MyTag from '@/components/my-tag.vue'
import { getSTSToken, getFilePreviewUrl } from "@/api/common.js";
import { publish } from "@/api/video.js";
import { getRecommendTag3 } from "@/api/video-tag.js";
@@ -239,7 +240,7 @@
  },
  computed: {
    canPublish() {
      return this.formData.videoFileKey && this.formData.title;
      return this.formData.videoFileKey && this.formData.title && this.formData.cover;
    },
    filteredGoods() {
      if (!this.goodsSearch) return this.goodsList;
@@ -272,7 +273,6 @@
      },
      // 初始化腾讯云cos客户端
      initCOS() {
          console.log("执行了");
          // 调用后端获取sts临时访问凭证
          getSTSToken().then(res => {
              const COS = require('@/lib/cos-wx-sdk-v5.js'); // 开发时使用
pages/video/home-page-edit.vue
New file
@@ -0,0 +1,278 @@
<template>
  <view class="edit-profile-container">
    <!-- 头部标题 -->
    <view class="header">
      <text class="title">编辑资料</text>
    </view>
    <!-- 表单区域 -->
    <view class="form-container">
      <!-- 头像上传 -->
      <view class="form-item">
        <text class="label">头像</text>
        <view class="avatar-upload" @click="chooseAvatar">
          <image class="avatar" :src="formData.avatar" mode="aspectFill"></image>
          <view class="upload-tip">点击修改</view>
        </view>
      </view>
      <!-- 昵称 -->
      <view class="form-item">
        <text class="label">昵称</text>
        <input
          class="input"
          type="nickname"
          v-model="formData.nickName"
          placeholder="请输入昵称"
          @blur="validateNickname"
        />
      </view>
      <!-- 签名 -->
      <view class="form-item">
        <text class="label">签名</text>
        <textarea
          class="textarea"
          v-model="formData.motto"
          placeholder="介绍一下自己吧~"
          maxlength="50"
          auto-height
        />
        <text class="word-count">{{ formData.motto.length }}/50</text>
      </view>
    </view>
    <!-- 保存按钮 -->
    <view class="btn-container">
      <button
        class="save-btn"
        :disabled="isSaving"
        @click="saveInfo"
      >
        {{ isSaving ? '保存中...' : '保存修改' }}
      </button>
    </view>
  </view>
</template>
<script>
import { getSTSToken, getFilePreviewUrl } from "@/api/common.js";
import { saveVideoHomeInfo } from "@/api/user.js";
import { getFileKey } from "@/utils/file.js";
export default {
  data() {
    return {
      formData: {
        avatar: '',
        nickName: '',
        motto: '',
        authorId: ''
      },
      isSaving: false,
      bucket: '',
      region: '',
      cosClient: null
    }
  },
  onShow() {
    this.initCOS();
  },
  onLoad(option) {
    this.formData.authorId = option.authorId;
    this.formData.avatar = option.avatar;
    this.formData.nickName = option.nickName;
    this.formData.motto = option.motto ? option.motto : '';
  },
  methods: {
    initCOS() {
      // 调用后端获取sts临时访问凭证
      getSTSToken().then(res => {
          const COS = require('@/lib/cos-wx-sdk-v5.js'); // 开发时使用
          // const COS = require('./lib/cos-wx-sdk-v5.min.js'); // 上线时使用压缩包
          // console.log(COS.version);  sdk 版本需要不低于 1.7.2
          this.cosClient = new COS({
              SecretId: res.data.data.tmpSecretId, // sts 服务下发的临时 secretId
              SecretKey: res.data.data.tmpSecretKey, // sts 服务下发的临时 secretKey
              SecurityToken: res.data.data.sessionToken, // sts 服务下发的临时 SessionToken
              StartTime: res.data.data.stsStartTime, // 建议传入服务端时间,可避免客户端时间不准导致的签名错误
              ExpiredTime: res.data.data.stsEndTime, // 临时密钥过期时间
              SimpleUploadMethod: 'putObject', // 强烈建议,高级上传、批量上传内部对小文件做简单上传时使用 putObject,sdk 版本至少需要v1.3.0
           });
           this.bucket = res.data.data.bucket
           this.region = res.data.data.region
      })
    },
    // 选择头像
    chooseAvatar() {
      uni.chooseImage({
        count: 1,
        sizeType: ['compressed'],
        sourceType: ['album', 'camera'],
        success: (res) => {
          const tempPath = res.tempFilePaths[0];
          // 获取文件名
          let fileName = tempPath.substring(tempPath.lastIndexOf('/') + 1);
          // 处理安卓可能的URI编码
          if(fileName.indexOf('%') > -1) {
              fileName = decodeURIComponent(fileName);
          }
          const fileKey = getFileKey(fileName);
          this.cosClient.uploadFile({
               Bucket: this.bucket,
               Region: this.region,
               Key: fileKey,
               FilePath: tempPath,
               SliceSize: 1024 * 1024 * 5,     /* 触发分块上传的阈值,5M */
           }, (err, data) => {
               if (err) {
                 console.log('上传失败', err);
                 this.formData.avatar = ''
                 uni.showToast({
                   title: '图片上传失败',
                   icon: 'none'
                 });
               } else {
                 getFilePreviewUrl(fileKey).then(res => {
                     this.formData.avatar = res.data.data
                 })
               }
           });
        },
        fail: (err) => {
          console.error('选择图片失败:', err);
          uni.showToast({
            title: '选择图片失败',
            icon: 'none'
          });
        }
      });
    },
    // 验证昵称
    validateNickname() {
      if (!this.formData.nickName.trim()) {
        uni.showToast({ title: '昵称不能为空', icon: 'none' });
        return false;
      }
      if (this.formData.nickName.length > 12) {
        uni.showToast({ title: '昵称不能超过12个字符', icon: 'none' });
        return false;
      }
      return true;
    },
    // 保存个人信息
    async saveInfo() {
      this.isSaving = true;
      if(this.validateNickname()) {
          saveVideoHomeInfo(this.formData).then(res => {
              uni.showToast({
                title: '保存成功',
                icon: 'success'
              });
              // 返回上级页面
              uni.navigateBack({
                  delta: 1
              });
          })
      }
    }
  }
}
</script>
<style lang="scss" scoped>
.edit-profile-container {
  padding: 20rpx 30rpx;
  min-height: 100vh;
  background-color: #f7f7f7;
}
.header {
  padding: 30rpx 0;
  .title {
    font-size: 36rpx;
    font-weight: bold;
    color: #333;
  }
}
.form-container {
  background-color: #fff;
  border-radius: 16rpx;
  padding: 0 30rpx;
  margin-bottom: 40rpx;
}
.form-item {
  padding: 30rpx 0;
  border-bottom: 1rpx solid #f2f2f2;
  display: flex;
  flex-direction: column;
  &:last-child {
    border-bottom: none;
  }
  .label {
    font-size: 30rpx;
    color: #333;
    margin-bottom: 20rpx;
  }
}
.avatar-upload {
  display: flex;
  align-items: center;
  .avatar {
    width: 120rpx;
    height: 120rpx;
    border-radius: 50%;
    margin-right: 30rpx;
  }
  .upload-tip {
    color: #999;
    font-size: 26rpx;
  }
}
.input {
  height: 80rpx;
  font-size: 28rpx;
  color: #333;
}
.textarea {
  width: 100%;
  min-height: 120rpx;
  font-size: 28rpx;
  color: #333;
  padding: 10rpx 0;
}
.word-count {
  align-self: flex-end;
  font-size: 24rpx;
  color: #999;
  margin-top: 10rpx;
}
.btn-container {
  padding: 0 30rpx;
  .save-btn {
    background-color: #07c160;
    color: #fff;
    border-radius: 50rpx;
    font-size: 32rpx;
    &[disabled] {
      background-color: #cccccc;
      color: #fff;
      opacity: 0.7;
    }
  }
}
</style>
pages/video/home-page.vue
@@ -4,9 +4,6 @@
    <view class="user-header">
      <view class="user-avatar-container">
        <image class="user-avatar" :src="userInfo.avatar" mode="aspectFill"></image>
        <view class="edit-icon" @click="editProfile" v-if="isSelf">
          <uni-icons type="compose" size="20" color="#666"></uni-icons>
        </view>
      </view>
      <view class="user-info">
        <view class="user-name">{{userInfo.nickName}}</view>
@@ -38,6 +35,10 @@
          {{userInfo.hasSub ? '取消关注' : '关注'}}
        </button>
      </view>
      <view class="edit-icon" @click="editInfo" v-if="userInfo.self">
        <uni-icons type="compose" size="20" color="#666"></uni-icons>编辑主页信息
      </view>
    </view>
    
        <!-- 作品/喜欢切换 -->
@@ -148,6 +149,9 @@
      nomoreVideo: false,
      nomoreCollectVideo: false
    }
  },
  onShow() {
     this.getAuthorInfo();
  },
  onLoad(option) {
    this.authorId = option.authorId;
@@ -294,9 +298,9 @@
      });
    },
    // 编辑个人资料
    editProfile() {
    editInfo() {
      uni.navigateTo({
        url: '/pages/user/edit'
        url: `/pages/video/home-page-edit?authorId=${this.authorId}&avatar=${this.userInfo.avatar}&motto=${this.userInfo.motto || ''}&nickName=${this.userInfo.nickName}`
      });
    },
    
@@ -351,16 +355,13 @@
.edit-icon {
  position: absolute;
  right: 0;
  bottom: 0;
  right: 30rpx;
  top: 30rpx;
  background-color: #fff;
  border-radius: 50%;
  width: 40rpx;
  height: 40rpx;
  display: flex;
  justify-content: center;
  align-items: center;
  box-shadow: 0 0 10rpx rgba(0, 0, 0, 0.1);
}
.user-info {
@@ -539,11 +540,6 @@
    background-color: #f5f5f5;
    color: #666;
  }
}
/* 如果是自己的主页,隐藏关注按钮 */
.user-header {
  position: relative;
}
.video-container {
pages/video/video-play.vue
@@ -246,6 +246,9 @@
  onHide() {
      this.startHidenTime = Date.now()
  },
  onUnload() {
      uni.removeStorageSync("playInfo");
  },
  onLoad(option) {
      const playInfo = uni.getStorageSync("playInfo", playInfo);
      if(playInfo) {