From f2632fd89894182c288348b14afafe1a26440142 Mon Sep 17 00:00:00 2001 From: yangzhe Date: Mon, 10 Nov 2025 16:45:03 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E7=94=A8=E6=88=B7=E8=AE=BE=E7=BD=AE):=20?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=94=A8=E6=88=B7=E8=AE=BE=E7=BD=AE=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E5=8F=8A=E7=9B=B8=E5=85=B3=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增用户设置页面,包含头像、姓名、性别和归属地编辑功能 - 实现头像上传功能,使用uni-file-picker组件 - 实现保存和退出登录功能 - 优化登录跳转逻辑,统一携带用户类型参数 - 清理Vuex中不再使用的字段,简化状态管理 - 新增中国省份数据文件用于归属地选择 - 重构图片上传API,改用uni.uploadFile实现 --- common/http.api.js | 58 +- common/http.interceptor.js | 2 +- components/ChatHistory.vue | 8 +- components/PerfectInfo.vue | 2 +- pages.json | 4 +- .../home/{userInfo => userSetting}/index.vue | 318 ++++---- static/common/js/china-provinces.js | 47 ++ static/common/js/router.js | 2 +- store/index.js | 19 +- types/global.d.ts | 32 +- uni_modules/uni-file-picker/changelog.md | 89 +++ .../uni-file-picker/choose-and-upload-file.js | 287 ++++++++ .../uni-file-picker/uni-file-picker.vue | 680 ++++++++++++++++++ .../uni-file-picker/upload-file.vue | 323 +++++++++ .../uni-file-picker/upload-image.vue | 285 ++++++++ .../components/uni-file-picker/utils.js | 110 +++ uni_modules/uni-file-picker/package.json | 105 +++ uni_modules/uni-file-picker/readme.md | 11 + 18 files changed, 2210 insertions(+), 172 deletions(-) rename pages/home/{userInfo => userSetting}/index.vue (53%) create mode 100644 static/common/js/china-provinces.js create mode 100644 uni_modules/uni-file-picker/changelog.md create mode 100644 uni_modules/uni-file-picker/components/uni-file-picker/choose-and-upload-file.js create mode 100644 uni_modules/uni-file-picker/components/uni-file-picker/uni-file-picker.vue create mode 100644 uni_modules/uni-file-picker/components/uni-file-picker/upload-file.vue create mode 100644 uni_modules/uni-file-picker/components/uni-file-picker/upload-image.vue create mode 100644 uni_modules/uni-file-picker/components/uni-file-picker/utils.js create mode 100644 uni_modules/uni-file-picker/package.json create mode 100644 uni_modules/uni-file-picker/readme.md diff --git a/common/http.api.js b/common/http.api.js index 61aa2a5..2222644 100644 --- a/common/http.api.js +++ b/common/http.api.js @@ -3,8 +3,34 @@ const install = (Vue, vm) => { /** * 单图片上传 */ - let UploadSingleImage = (params = {}) => - vm.$u.post("api/UploadFiles/SingleImageUpload", params); + // 使用 uni.uploadFile 以 file 类型上传(multipart/form-data),避免 H5 plus 依赖 + // params: { filePath: string, name?: string, formData?: object } + let UploadSingleImage = (params = {}) => { + const { filePath, name = "file", formData = {} } = params; + return new Promise((resolve, reject) => { + if (!filePath) return reject(new Error("filePath 不能为空")); + uni.uploadFile({ + url: vm.$u.http.config.baseUrl + "/api/UploadFiles/SingleImageUpload", + filePath, + name, + formData, + header: { + Authorization: "Bearer " + vm.vuex_token, + }, + success: (res) => { + // uni.uploadFile 的 res.data 可能是字符串,需要手动解析 + let data = res.data; + try { + data = typeof res.data === "string" ? JSON.parse(res.data) : res.data; + } catch (e) { + // 保持原始数据 + } + resolve(data); + }, + fail: (err) => reject(err), + }); + }); + }; // ******** // 获取教师信息 @@ -58,19 +84,19 @@ const install = (Vue, vm) => { let GetSchoolList = (params = {}) => vm.$u.get("app/AlumnRange/AlumnRangeSchool", params); //获取最新的用户信息(更新用户数据) - let getUser = (params = {}) => - vm.$u.get("app/User/GetUser", { userId: vm.vuex_user.id }).then((res) => { - vm.$u.get("/app/User/GetUserSchool").then((ress) => { - // res.isAttestationGLY = ress.isAttestationGLY - // res.isAttestationJZG = ress.isAttestationJZG - // res.isAttestationQY = ress.isAttestationQY - // res.isAttestationXY = res.isAttestationXY - // res.isAttestationZXS = ress.isAttestationZXS - res.schoolId = ress.items.schoolId; - vm.$u.vuex("vuex_user", { ...res.user, ...res.userExtension }); - vm.$u.vuex("vuex_user_hobby", res.lableList); - }); - }); + // let getUser = (params = {}) => + // vm.$u.get("app/User/GetUser", { userId: vm.vuex_user.id }).then((res) => { + // vm.$u.get("/app/User/GetUserSchool").then((ress) => { + // // res.isAttestationGLY = ress.isAttestationGLY + // // res.isAttestationJZG = ress.isAttestationJZG + // // res.isAttestationQY = ress.isAttestationQY + // // res.isAttestationXY = res.isAttestationXY + // // res.isAttestationZXS = ress.isAttestationZXS + // res.schoolId = ress.items.schoolId; + // vm.$u.vuex("vuex_user", { ...res.user, ...res.userExtension }); + // vm.$u.vuex("vuex_user_hobby", res.lableList); + // }); + // }); //获取用户消息列表 let getcharList = (params = {}) => vm.$u.get("app/Chat/GetUserMessageList", params); @@ -195,7 +221,7 @@ const install = (Vue, vm) => { getUserInfo, GetHelpList, GetSchoolList, - getUser, + // getUser, getcharList, getFollowList, getSysList, diff --git a/common/http.interceptor.js b/common/http.interceptor.js index 8cf6961..8a30b11 100644 --- a/common/http.interceptor.js +++ b/common/http.interceptor.js @@ -88,7 +88,7 @@ function handleAuthError(vm) { // 延迟跳转到登录页 uni.reLaunch({ - url: "/pages/login/login/index", + url: "/pages/login/login/index?type=" + vm.vuex_userType || 0, }); } diff --git a/components/ChatHistory.vue b/components/ChatHistory.vue index 2934566..4093db4 100644 --- a/components/ChatHistory.vue +++ b/components/ChatHistory.vue @@ -58,7 +58,7 @@ > {{ userName || "晓德塔," }} - + @@ -120,6 +120,12 @@ export default { }, }, methods: { + // 处理设置点击事件 + handleSettingsClick() { + uni.navigateTo({ + url: "/pages/home/userSetting/index", + }); + }, // 滚动到激活的聊天项 scrollToActiveItem() { // 查找激活的聊天项 diff --git a/components/PerfectInfo.vue b/components/PerfectInfo.vue index 1d6afe3..ed6312c 100644 --- a/components/PerfectInfo.vue +++ b/components/PerfectInfo.vue @@ -60,7 +60,7 @@ export default { toPerfectInfo() { this.showPopup = false; this.$emit("update:show", false); - this.$router.push("/pages/home/userInfo/index"); + this.$router.push("/pages/home/userSetting/index"); }, }, }; diff --git a/pages.json b/pages.json index 747f1ab..607db66 100644 --- a/pages.json +++ b/pages.json @@ -98,9 +98,9 @@ } }, { - "path": "pages/home/userInfo/index", + "path": "pages/home/userSetting/index", "style": { - "navigationBarTitleText": "个人信息", + "navigationBarTitleText": "设置", "enablePullDownRefresh": false, "navigationStyle": "custom" } diff --git a/pages/home/userInfo/index.vue b/pages/home/userSetting/index.vue similarity index 53% rename from pages/home/userInfo/index.vue rename to pages/home/userSetting/index.vue index 2767430..d893d5e 100644 --- a/pages/home/userInfo/index.vue +++ b/pages/home/userSetting/index.vue @@ -1,5 +1,5 @@ diff --git a/uni_modules/uni-file-picker/components/uni-file-picker/upload-file.vue b/uni_modules/uni-file-picker/components/uni-file-picker/upload-file.vue new file mode 100644 index 0000000..0d26379 --- /dev/null +++ b/uni_modules/uni-file-picker/components/uni-file-picker/upload-file.vue @@ -0,0 +1,323 @@ + + + + + \ No newline at end of file diff --git a/uni_modules/uni-file-picker/components/uni-file-picker/upload-image.vue b/uni_modules/uni-file-picker/components/uni-file-picker/upload-image.vue new file mode 100644 index 0000000..0ce5eb7 --- /dev/null +++ b/uni_modules/uni-file-picker/components/uni-file-picker/upload-image.vue @@ -0,0 +1,285 @@ + + + + + diff --git a/uni_modules/uni-file-picker/components/uni-file-picker/utils.js b/uni_modules/uni-file-picker/components/uni-file-picker/utils.js new file mode 100644 index 0000000..1bc9259 --- /dev/null +++ b/uni_modules/uni-file-picker/components/uni-file-picker/utils.js @@ -0,0 +1,110 @@ +/** + * 获取文件名和后缀 + * @param {String} name + */ +export const get_file_ext = (name) => { + const last_len = name.lastIndexOf('.') + const len = name.length + return { + name: name.substring(0, last_len), + ext: name.substring(last_len + 1, len) + } +} + +/** + * 获取扩展名 + * @param {Array} fileExtname + */ +export const get_extname = (fileExtname) => { + if (!Array.isArray(fileExtname)) { + let extname = fileExtname.replace(/(\[|\])/g, '') + return extname.split(',') + } else { + return fileExtname + } + return [] +} + +/** + * 获取文件和检测是否可选 + */ +export const get_files_and_is_max = (res, _extname) => { + let filePaths = [] + let files = [] + if(!_extname || _extname.length === 0){ + return { + filePaths, + files + } + } + res.tempFiles.forEach(v => { + let fileFullName = get_file_ext(v.name) + const extname = fileFullName.ext.toLowerCase() + if (_extname.indexOf(extname) !== -1) { + files.push(v) + filePaths.push(v.path) + } + }) + if (files.length !== res.tempFiles.length) { + uni.showToast({ + title: `当前选择了${res.tempFiles.length}个文件 ,${res.tempFiles.length - files.length} 个文件格式不正确`, + icon: 'none', + duration: 5000 + }) + } + + return { + filePaths, + files + } +} + + +/** + * 获取图片信息 + * @param {Object} filepath + */ +export const get_file_info = (filepath) => { + return new Promise((resolve, reject) => { + uni.getImageInfo({ + src: filepath, + success(res) { + resolve(res) + }, + fail(err) { + reject(err) + } + }) + }) +} +/** + * 获取封装数据 + */ +export const get_file_data = async (files, type = 'image') => { + // 最终需要上传数据库的数据 + let fileFullName = get_file_ext(files.name) + const extname = fileFullName.ext.toLowerCase() + let filedata = { + name: files.name, + uuid: files.uuid, + extname: extname || '', + cloudPath: files.cloudPath, + fileType: files.fileType, + thumbTempFilePath: files.thumbTempFilePath, + url: files.path || files.path, + size: files.size, //单位是字节 + image: {}, + path: files.path, + video: {} + } + if (type === 'image') { + const imageinfo = await get_file_info(files.path) + delete filedata.video + filedata.image.width = imageinfo.width + filedata.image.height = imageinfo.height + filedata.image.location = imageinfo.path + } else { + delete filedata.image + } + return filedata +} diff --git a/uni_modules/uni-file-picker/package.json b/uni_modules/uni-file-picker/package.json new file mode 100644 index 0000000..9e2e080 --- /dev/null +++ b/uni_modules/uni-file-picker/package.json @@ -0,0 +1,105 @@ +{ + "id": "uni-file-picker", + "displayName": "uni-file-picker 文件选择上传", + "version": "1.1.2", + "description": "文件选择上传组件,可以选择图片、视频等任意文件并上传到当前绑定的服务空间", + "keywords": [ + "uni-ui", + "uniui", + "图片上传", + "文件上传" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "", + "uni-app": "^4.33", + "uni-app-x": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, + "dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", + "type": "component-vue", + "darkmode": "x", + "i18n": "x", + "widescreen": "x" + }, + "uni_modules": { + "dependencies": [ + "uni-scss" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "√", + "aliyun": "√", + "alipay": "√" + }, + "client": { + "uni-app": { + "vue": { + "vue2": "√", + "vue3": "√" + }, + "web": { + "safari": "√", + "chrome": "√" + }, + "app": { + "vue": "√", + "nvue": "-", + "android": "√", + "ios": "√", + "harmony": "√" + }, + "mp": { + "weixin": "√", + "alipay": "√", + "toutiao": "√", + "baidu": "√", + "kuaishou": "√", + "jd": "-", + "harmony": "-", + "qq": "√", + "lark": "-" + }, + "quickapp": { + "huawei": "√", + "union": "√" + } + }, + "uni-app-x": { + "web": { + "safari": "-", + "chrome": "-" + }, + "app": { + "android": "-", + "ios": "-", + "harmony": "-" + }, + "mp": { + "weixin": "-" + } + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uni-file-picker/readme.md b/uni_modules/uni-file-picker/readme.md new file mode 100644 index 0000000..c8399a5 --- /dev/null +++ b/uni_modules/uni-file-picker/readme.md @@ -0,0 +1,11 @@ + +## FilePicker 文件选择上传 + +> **组件名:uni-file-picker** +> 代码块: `uFilePicker` + + +文件选择上传组件,可以选择图片、视频等任意文件并上传到当前绑定的服务空间 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-file-picker) +#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 \ No newline at end of file