commit 1d7e076242e0f53f1dfee1790ff6cf7ab7a86908
Author: zhouyanli <593579392@qq.com>
Date: Fri Jul 24 09:14:45 2026 +0800
首次提交项目代码
diff --git a/huakai-app/.gitignore b/huakai-app/.gitignore
new file mode 100644
index 0000000..2370852
--- /dev/null
+++ b/huakai-app/.gitignore
@@ -0,0 +1,4 @@
+node_modules/
+unpackage/
+.hbuilderx/
+.DS_Store
diff --git a/huakai-app/App.vue b/huakai-app/App.vue
new file mode 100644
index 0000000..13d0db7
--- /dev/null
+++ b/huakai-app/App.vue
@@ -0,0 +1,73 @@
+
+
+
+
+
diff --git a/huakai-app/components/time-popup/time-popup.vue b/huakai-app/components/time-popup/time-popup.vue
new file mode 100644
index 0000000..2b49cfd
--- /dev/null
+++ b/huakai-app/components/time-popup/time-popup.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/huakai-app/index.html b/huakai-app/index.html
new file mode 100644
index 0000000..b5d330d
--- /dev/null
+++ b/huakai-app/index.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/huakai-app/main.js b/huakai-app/main.js
new file mode 100644
index 0000000..d950181
--- /dev/null
+++ b/huakai-app/main.js
@@ -0,0 +1,24 @@
+import App from './App'
+import uviewPlus from '@/uni_modules/uview-plus'
+
+// #ifndef VUE3
+import Vue from 'vue'
+import './uni.promisify.adaptor'
+Vue.config.productionTip = false
+App.mpType = 'app'
+const app = new Vue({
+ ...App
+})
+app.$mount()
+// #endif
+
+// #ifdef VUE3
+import { createSSRApp } from 'vue'
+export function createApp() {
+ const app = createSSRApp(App)
+ app.use(uviewPlus)
+ return {
+ app
+ }
+}
+// #endif
\ No newline at end of file
diff --git a/huakai-app/manifest.json b/huakai-app/manifest.json
new file mode 100644
index 0000000..78f1196
--- /dev/null
+++ b/huakai-app/manifest.json
@@ -0,0 +1,132 @@
+{
+ "name" : "花开物业",
+ "appid" : "__UNI__29C3D60",
+ "description" : "物业用户端app",
+ "versionName" : "1.0.1",
+ "versionCode" : "103",
+ "transformPx" : false,
+ /* 5+App特有相关 */
+ "app-plus" : {
+ "usingComponents" : true,
+ "nvueStyleCompiler" : "uni-app",
+ "compilerVersion" : 3,
+ "splashscreen" : {
+ "alwaysShowBeforeRender" : true,
+ "waiting" : true,
+ "autoclose" : true,
+ "delay" : 0
+ },
+ /* 模块配置 */
+ "modules" : {
+ "Geolocation" : {},
+ "Maps" : {},
+ "Camera" : {},
+ "Contacts" : {},
+ "Gallery" : {},
+ "Push" : {}
+ },
+ /* 应用发布信息 */
+ "distribute" : {
+ /* android打包配置 */
+ "android" : {
+ "permissions" : [
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ ""
+ ]
+ },
+ /* ios打包配置 */
+ "ios" : {
+ "dSYMs" : false,
+ "privacyDescription" : {
+ "NSPhotoLibraryUsageDescription" : "需要访问您的相册,用于选择图片上传",
+ "NSPhotoLibraryAddUsageDescription" : "保存二维码图片到相册"
+ }
+ },
+ /* SDK配置 */
+ "sdkConfigs" : {
+ "geolocation" : {
+ "system" : {
+ "__platform__" : [ "ios", "android" ]
+ }
+ },
+ "maps" : {
+ "amap" : {
+ "name" : "玉米汁穿过三峡人家",
+ "appkey_ios" : "39a4c28a01c3ec15684b21d4093aad3d",
+ "appkey_android" : "044055aed47cb305e86419fd82e4c5f3"
+ }
+ },
+ "push" : {
+ "unipush" : {
+ "version" : "2",
+ "offline" : true,
+ "icons" : {
+ "small" : {
+ "mdpi" : "D:/图片文档/logo-app.png"
+ }
+ }
+ }
+ },
+ "share" : {
+ "weixin" : {
+ "appid" : "",
+ "UniversalLinks" : ""
+ }
+ }
+ }
+ }
+ },
+ /* 快应用特有相关 */
+ "quickapp" : {},
+ /* 小程序特有相关 */
+ "mp-weixin" : {
+ "appid" : "wx40625124315d2de1",
+ "setting" : {
+ "urlCheck" : false
+ },
+ "requiredPrivateInfos" : [ "chooseLocation", "getLocation" ],
+ "permission" : {
+ "scope.camera" : {
+ "desc" : "用于扫码"
+ },
+ "scope.userLocation" : {
+ "desc" : "你的位置信息将用于定位选择"
+ }
+ },
+ "usingComponents" : true
+ },
+ "mp-alipay" : {
+ "usingComponents" : true
+ },
+ "mp-baidu" : {
+ "usingComponents" : true
+ },
+ "mp-toutiao" : {
+ "usingComponents" : true
+ },
+ "uniStatistics" : {
+ "enable" : false
+ },
+ "vueVersion" : "3",
+ "app-harmony" : {
+ "distribute" : {
+ "bundleName" : "com.chengkong.property.owner"
+ }
+ }
+}
diff --git a/huakai-app/package-lock.json b/huakai-app/package-lock.json
new file mode 100644
index 0000000..1913237
--- /dev/null
+++ b/huakai-app/package-lock.json
@@ -0,0 +1,74 @@
+{
+ "name": "property-uniapp-project",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "dependencies": {
+ "clipboard": "^2.0.11",
+ "dayjs": "^1.11.20",
+ "moment": "^2.30.1",
+ "uqrcodejs": "^4.0.7"
+ }
+ },
+ "node_modules/clipboard": {
+ "version": "2.0.11",
+ "resolved": "https://registry.npmmirror.com/clipboard/-/clipboard-2.0.11.tgz",
+ "integrity": "sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==",
+ "license": "MIT",
+ "dependencies": {
+ "good-listener": "^1.2.2",
+ "select": "^1.1.2",
+ "tiny-emitter": "^2.0.0"
+ }
+ },
+ "node_modules/dayjs": {
+ "version": "1.11.20",
+ "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.20.tgz",
+ "integrity": "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==",
+ "license": "MIT"
+ },
+ "node_modules/delegate": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmmirror.com/delegate/-/delegate-3.2.0.tgz",
+ "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==",
+ "license": "MIT"
+ },
+ "node_modules/good-listener": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmmirror.com/good-listener/-/good-listener-1.2.2.tgz",
+ "integrity": "sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==",
+ "license": "MIT",
+ "dependencies": {
+ "delegate": "^3.1.2"
+ }
+ },
+ "node_modules/moment": {
+ "version": "2.30.1",
+ "resolved": "https://registry.npmmirror.com/moment/-/moment-2.30.1.tgz",
+ "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/select": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmmirror.com/select/-/select-1.1.2.tgz",
+ "integrity": "sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA==",
+ "license": "MIT"
+ },
+ "node_modules/tiny-emitter": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
+ "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==",
+ "license": "MIT"
+ },
+ "node_modules/uqrcodejs": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmmirror.com/uqrcodejs/-/uqrcodejs-4.0.7.tgz",
+ "integrity": "sha512-84+aZmD2godCVI+93lxE3YUAPNY8zAJvNA7xRS7R7U+q57KzMDepBSfNCwoRUhWOfR6eHFoAOcHRPwsP6ka1cA==",
+ "license": "Apache-2.0"
+ }
+ }
+}
diff --git a/huakai-app/package.json b/huakai-app/package.json
new file mode 100644
index 0000000..771f35d
--- /dev/null
+++ b/huakai-app/package.json
@@ -0,0 +1,8 @@
+{
+ "dependencies": {
+ "clipboard": "^2.0.11",
+ "dayjs": "^1.11.20",
+ "moment": "^2.30.1",
+ "uqrcodejs": "^4.0.7"
+ }
+}
diff --git a/huakai-app/pageSubPack/api/api.js b/huakai-app/pageSubPack/api/api.js
new file mode 100644
index 0000000..9a9f54f
--- /dev/null
+++ b/huakai-app/pageSubPack/api/api.js
@@ -0,0 +1,141 @@
+import request,{get,post,upload} from "./request.js"
+
+
+// =======账号密码登录========
+export const getLoginPassword = (data) =>{
+ return post('/api/resident/auth/loginByPassword',data)
+}
+// 注册新用户获取验证码
+export const getSendCode = (data) =>{
+ return post('/api/resident/auth/sendSmsCode',data)
+}
+// 注册新用户
+export const getRegisterUser = (data) =>{
+ return post('/api/resident/auth/register',data)
+}
+// 短信验证码登录
+export const getLoginBySms = (data) =>{
+ return post('/api/resident/auth/loginBySms',data)
+}
+// 忘记密码接口
+export const getResetPassword = (data) =>{
+ return post('/api/resident/auth/resetPassword',data)
+}
+// =========首页=======
+// 获取bannar图
+export const getBannarList = (data) =>{
+ return get('/resident/banner',data)
+}
+// 首页最新公告
+export const getNoticeLatest = () =>{
+ return get('/api/resident/notice/latest')
+}
+
+// 查询已认证的小区
+export const getVillageList = (data) =>{
+ return get('/api/resident/village/myList', data)
+}
+// 获取当前小区
+export const getCurrentVillage = () =>{
+ return get('/api/resident/village/current')
+}
+// 切换小区
+export const getVillageSwitch = (data)=>{
+ return post('/api/resident/village/switch',data)
+}
+// 首页最新活动列表
+export const getActivitylatest = () =>{
+ return get('/api/resident/activity/latest')
+}
+
+// ========公告列表======
+// 获取公告列表
+export const getNoticeList = (data) =>{
+ return get('/api/resident/notice/list',data)
+}
+// 获取公告详情
+export const getNoticeDetails = (noticeId) =>{
+ return get(`/api/resident/notice/${noticeId}`)
+}
+// =========键开门===============
+// 查询门禁列表
+export const getAccessDevices = (data) =>{
+ return get("/api/resident/access/devices",data)
+}
+// 确认开门
+export const getAccessOpen = (data) =>{
+ return post("/api/resident/access/open",data)
+}
+// ==========活动列表===========
+// 获取活动列表
+export const getActivityList = (data) =>{
+ return get("/api/resident/activity/list",data)
+}
+// 获取活动列表详情
+export const getActivityDetails = (id) =>{
+ return get(`/api/resident/activity/${id}`)
+}
+// 确认报名
+export const confirmResident = (id) =>{
+ return post(`/api/resident/activity/${id}/apply`)
+}
+// 取消报名
+export const cancelActivity = (id) =>{
+ return post(`/api/resident/activity/${id}/cancel`)
+}
+// =========我的活动========
+export const getMyActivityList = (data) =>{
+ return get("/api/resident/activity/my",data)
+}
+// ===========活动实况============
+// 活动实况列表
+export const getActivityLive = (id) =>{
+ return get(`/api/resident/activity/${id}/live`)
+}
+// 添加实况
+export const addActivityLive = (id, data) =>{
+ return post(`/api/resident/activity/${id}/live`, data)
+}
+// 签到
+export const signinActivityLive = (id, data) =>{
+ return post(`/api/resident/activity/${id}/signin`, data)
+}
+// ==============在线报修========
+// 添加报修工单
+export const addQueryRepair = (data) =>{
+ return post("/repairOrder/addRepair",data)
+}
+// 获取公共维修项目列表
+export const getRepairProjectList = (data) =>{
+ return get("/repairOrder/list",data)
+}
+// 获取报修列表
+export const getQueryRepair = (data) =>{
+ return get("/repairOrder/queryRepair",data)
+}
+// 获取房屋列表
+export const getHouseList = (data) =>{
+ return get('/api/resident/my/house/list',data)
+}
+// 报修详情
+export const getRepairDetail = (data) =>{
+ return get('/repairOrder/queryRepairDetail',data)
+}
+// =========访客邀请===========
+// 获取访客列表
+export const getVisitorList = (data) =>{
+ return get('/api/visitor/list',data)
+}
+// 获取详情信息
+export const getVisitorDetail = (id) =>{
+ return get(`/api/visitor/${id}`)
+}
+// 新增访客
+export const addVisitorData = (data) =>{
+ return post("/api/visitor", data)
+}
+
+// 上传单张图片
+export const uploadFile = (filePath) => {
+ return upload(filePath,'/api/resident/file/uploadImage');
+}
\ No newline at end of file
diff --git a/huakai-app/pageSubPack/api/apiSub.js b/huakai-app/pageSubPack/api/apiSub.js
new file mode 100644
index 0000000..382909a
--- /dev/null
+++ b/huakai-app/pageSubPack/api/apiSub.js
@@ -0,0 +1,225 @@
+import request, {
+ get,
+ post,
+ deleteMethod,
+ putMethod
+} from "./request.js"
+
+// 字典
+export const getSystemDictData = (data) => {
+ return get('/system/dict/data/list', data)
+}
+
+// =======公告列表========
+export const getResidentNoticeList = (data) => {
+ return get('/api/resident/notice/list', data)
+}
+// 我的房屋列表
+export const getMyHouseList = (data) => {
+ return get('/api/resident/my/house/list', data)
+}
+// 提交房屋注册认证申请
+export const myHouseApply = (data) => {
+ return post('/api/resident/my/house/apply', data)
+}
+// 查询小区列表
+export const getVillageList = (data) => {
+ return get('/api/resident/village/list', data)
+} // 查询楼栋列表
+export const getHouseBuildings = (data) => {
+ return get('/api/resident/house/buildings', data)
+}
+// 查询单元列表
+export const getHouseUnits = (data) => {
+ return get('/api/resident/house/units', data)
+}
+// 查询楼层列表
+export const getHouseFloors = (data) => {
+ return get('/api/resident/house/floors', data)
+}
+// 查询户号列表
+export const getHouseHouses = (data) => {
+ return get('/api/resident/house/houses', data)
+}
+// 房屋绑定手机获取验证码
+export const getHouseAuthSendSmsCode = (data) => {
+ return post('/api/resident/auth/sendSmsCode', data)
+}
+// 房屋详情
+export const getMyHouseDetail = (data) => {
+ return get(`/api/resident/my/house/${data.id}`, data)
+}
+// 删除房屋
+export const deleteMyHouse = (data) => {
+ return deleteMethod(`/api/resident/my/house/${data.id}`, data)
+}
+// 设置默认房屋
+export const setMyHouseDefault = (data) => {
+ return post(`/api/resident/my/house/default`, data)
+}
+// 获取当前用户登录信息
+export const getUserProfile = (data) => {
+ return get(`/api/resident/user/profile`, data)
+}
+// 发送新手机号验证码
+export const getAuthSendSmsCode = (data) => {
+ return post(`/api/resident/auth/sendSmsCode`, data)
+}
+// 更改手机号
+export const getUserChangePhone = (data) => {
+ return post(`/api/resident/user/changePhone`, data)
+}
+// 获取消息通知开关
+export const getUserNotify = (data) => {
+ return get(`/api/resident/user/notify`, data)
+}
+// 更新消息通知开关
+export const changeUserNotify = (data) => {
+ return post(`/api/resident/user/notify`, data)
+} // 修改密码(需登录)
+export const authChangePassword = (data) => {
+ return post(`/api/resident/auth/changePassword`, data)
+} // 退出登录
+export const authLogout = (data) => {
+ return post(`/api/resident/auth/logout`, data)
+}
+// 编辑房屋
+export const upDateMyHouse = (data) => {
+ return putMethod(`/api/resident/my/house/${data.id}`, data)
+
+}
+
+// =========问卷调查=========
+// 问卷列表
+export const getQuestionnaireList = (data) => {
+ return get('/api/resident/questionnaire/list',data)
+}
+// 问卷详情
+export const getQuestionnaireDetail = (data) => {
+ return get('/api/resident/questionnaire/myAnswers',data)
+}
+// 提交问卷
+export const submitQuestionnair = (id,data) => {
+ return post(`/api/resident/questionnaire/${id}/submit`, data)
+}
+// =====投诉意见=======
+// 获取投诉类型
+export const getComplainType = () => {
+ return get('/complain/getComplainType')
+}
+// 获取投诉列表
+export const getComplainList = (data) => {
+ return get('/complain/getComplainList',data)
+}
+// 提交投诉建议
+export const addComplain = (data) => {
+ return post('/complain/add',data)
+}
+// 投诉详情
+export const getComplainDetail = (data) => {
+ return get('/complain/detail',data)
+}
+// 联系物业
+export const getManagePhoneData = (data) => {
+ return get('/api/manage/banner/getManagePhone',data)
+}
+
+// 修改身份证照片
+export const uploadFileUploadImage = (data) => {
+ return post(`/api/resident/file/uploadImage`, data)
+}
+
+// 水电表
+export const getTopUpSelectByResident = (data) => {
+ console.log(data);
+ return get(`/api/topUp/selectByResident/${data.residentUserId}`, data)
+}
+// 绑定设备
+export const getTopUpBindDevice = (data) => {
+ return post(`/api/topUp/bindDevice/${data.deviceCode}/${data.residentUserId}/${data.openid}/${data.deviceType}`,
+ data)
+}
+// 充值调用
+// /${data.rechargeAmount}/${data.type}/${data.deviceCode}
+export const getTopUp = (data) => {
+ return post(`/api/topUp`, data)
+}
+export const getopenIdByCode = (data) => {
+ return get(`/api/topUp/getOpenIdByCode?code=${data.code}`, data)
+}
+
+// 微信支付调用
+export const getToWxPay = (data) => {
+ return post(`/api/topUp/wxPay/${data.orderId}/${data.openid}`, data)
+}
+// 缴费记录查询
+export const getTopupRecordWithStat = (data) => {
+ return get(
+ `/api/topUp/topupRecordWithStat?residentUserId=${data.residentUserId}&pageNum=${data.pageNum}&pageSize=${data.pageSize}`,
+ data)
+}
+export const postInsertOpenId = (data) => {
+ return post(`/api/resident/auth/insertOpenId`, data)
+}
+export const postSubscribeAuth = (data) => {
+ return post(`/api/wx/subscribeAuth/auth`, data)
+}
+
+// 添加车辆
+export const postCar = (data) => {
+ return post(`/api/resident/car`, data)
+}
+// 修改车辆
+export const putCar = (data) => {
+ return putMethod(`/api/resident/car`, data)
+}
+
+// 获取车辆列表
+export const getMyCarList = (data) => {
+ return get(`/api/resident/car/myList`, data)
+}
+// 获取车位列表
+export const getCarList = (data) => {
+ return get(`/api/resident/car/list`, data)
+}
+// 获取车辆详细信息
+export const getCarDetail = (data) => {
+ return get(`/api/resident/car/${data.id}`, data)
+}
+// 删除车辆信息
+export const deleteCar = (data) => {
+ return deleteMethod(`/api/resident/car/${data.carId}`, data)
+}
+// 获取用户车位绑定列表
+export const getUserParkingSpaceList = (data) => {
+ return get(`/api/resident/car/parking/list`, data)
+}
+
+// 获取区域列表
+export const getResidentCarAreaManageAreaListByVillageId = (data) => {
+ return get(`/ResidentCarAreaManage/areaListByVillageId`, data)
+}
+// 根据区域id获得车位列表
+export const getResidentCarAreaManageParkingListByAreaId = (data) => {
+ return get(`/ResidentCarAreaManage/parkingListByAreaId`, data)
+}
+// 绑定车位
+export const postCarBind = (data) => {
+ return post(`/api/resident/car/bind`, data)
+}
+// 获取用户下车位绑定信息
+// export const getCarList = (data) => {
+// return get(`/api/resident/car/list`, data)
+// }
+// 删除车位
+export const deleteParking = (data) => {
+ return deleteMethod(`/ResidentCarAreaManage/parking/${data.parkingId}`, data)
+}
+// 车位详情
+export const getParkingDetail = (data) => {
+ return get(`/api/resident/car/parking/detail/${data.id}`, data)
+}
+// 解绑车辆
+export const rebindCar = (data) => {
+ return post(`/ResidentCarAreaManage/rebind`, data)
+}
diff --git a/huakai-app/pageSubPack/api/auth.js b/huakai-app/pageSubPack/api/auth.js
new file mode 100644
index 0000000..e790384
--- /dev/null
+++ b/huakai-app/pageSubPack/api/auth.js
@@ -0,0 +1,85 @@
+/**
+ * 登录状态管理工具
+ * 仅在用户点击需要身份认证的功能时才要求登录
+ */
+
+/**
+ * 检查用户是否已登录
+ * @returns {boolean} true 已登录,false 未登录
+ */
+export function isLoggedIn() {
+ const token = uni.getStorageSync('token');
+ return !!token;
+}
+
+/**
+ * 要求登录 — 未登录时跳转登录页,已登录直接执行回调
+ * 登录页提供返回/取消按钮,用户可拒绝登录
+ *
+ * @param {Object} options
+ * @param {Function} [options.onLoggedIn] - 已登录或登录成功后执行的回调
+ * @param {string} [options.title] - 展示给用户的提示标题(为什么需要登录)
+ * @param {Function} [options.onCancel] - 用户取消登录后的回调
+ */
+export function requireAuth({ onLoggedIn, title, onCancel } = {}) {
+ if (isLoggedIn()) {
+ if (onLoggedIn) onLoggedIn();
+ return;
+ }
+
+ // 弹窗询问用户是否去登录,用户可拒绝("暂不")
+ const tipTitle = title ? `"${title}"需要登录` : '该功能需要登录';
+ uni.showModal({
+ title: '提示',
+ content: `${tipTitle},是否去登录?`,
+ confirmText: '去登录',
+ cancelText: '暂不',
+ success: (modalRes) => {
+ if (modalRes.confirm) {
+ // 用户点击"去登录"
+ uni.setStorageSync('pendingAuthCallback', {
+ time: Date.now(),
+ title: title || ''
+ });
+
+ uni.navigateTo({
+ url: '/pageSubPack/loginSub/pwd-login',
+ events: {
+ loginSuccess: () => {
+ if (onLoggedIn) onLoggedIn();
+ uni.removeStorageSync('pendingAuthCallback');
+ }
+ }
+ });
+ } else {
+ // 用户点击"暂不",留在当前页
+ if (onCancel) onCancel();
+ }
+ }
+ });
+}
+
+/**
+ * 清除登录状态
+ */
+export function clearLoginState() {
+ uni.removeStorageSync('token');
+ uni.removeStorageSync('userId');
+ uni.removeStorageSync('currentVillageId');
+ uni.removeStorageSync('pendingAuthCallback');
+}
+
+/**
+ * 保存登录成功后的 token 和用户信息
+ * @param {Object} data - 登录接口返回的 data
+ */
+export function saveLoginData(data) {
+ if (data.token) {
+ uni.setStorageSync('token', data.token);
+ }
+ if (data.userId) {
+ uni.setStorageSync('userId', data.userId);
+ }
+ const currentVillageId = data.currentVillageId || 0;
+ uni.setStorageSync('currentVillageId', currentVillageId);
+}
diff --git a/huakai-app/pageSubPack/api/request.js b/huakai-app/pageSubPack/api/request.js
new file mode 100644
index 0000000..0d29659
--- /dev/null
+++ b/huakai-app/pageSubPack/api/request.js
@@ -0,0 +1,113 @@
+let baseUrl = '';
+if (process.env.NODE_ENV === 'development') {
+ // baseUrl = 'https://wuyeapi.ckdzkj.com'; // 开发环境
+ baseUrl = "https://wuyeapi.bugtc.com"
+} else {
+ baseUrl = 'https://wuyeapi.bugtc.com'; // 生产环境
+}
+
+/**
+ * 显示接口错误提示(自动处理长消息截断问题)
+ * @param {string|Object} msg - 错误消息或含 msg 字段的错误对象
+ */
+export function showApiError(msg) {
+ const message = typeof msg === 'string' ? msg : (msg.msg || msg.message || '请求失败');
+ uni.showToast({ title: message || '请求失败', icon: 'error', duration: 2000 });
+}
+
+export default function request(url, data = {}, method = "GET") {
+ return new Promise((resolve, reject) => {
+ uni.showLoading({
+ title: '请求中...',
+ mask: true
+ });
+
+ uni.request({
+ url: baseUrl + url,
+ data: data,
+ method: method,
+ header: {
+ "Authorization": "Bearer " + (uni.getStorageSync("token") || ''),
+ "clientid": "resident",
+ 'content-type': 'application/json'
+ },
+ success: (res) => {
+ uni.hideLoading();
+
+ // HTTP 失败
+ if (res.statusCode !== 200) {
+ reject({ msg: `请求异常 ${res.statusCode}`, code: res.statusCode });
+ return;
+ }
+
+ const resData = res.data || {};
+
+ // token 过期 — 清除登录态,提示用户,但不强制跳转(用户可继续浏览非敏感页面)
+ if (resData.code === 401) {
+ uni.showToast({ title: '登录已过期,请重新登录', icon: 'none', duration: 2000 });
+ uni.removeStorageSync('token');
+ uni.removeStorageSync('userId');
+ // 使用 navigateTo 而非 reLaunch,用户可通过返回按钮退出登录页
+ setTimeout(() => {
+ uni.navigateTo({
+ url: '/pageSubPack/loginSub/pwd-login',
+ fail: () => {
+ // 如果 navigateTo 失败(如页面栈满),则用 reLaunch
+ uni.reLaunch({ url: '/pageSubPack/loginSub/pwd-login' });
+ }
+ });
+ }, 1500);
+ reject({ msg: '登录过期', code: 401 });
+ return;
+ }
+
+ // 成功
+ if (resData.code === 200) {
+ resolve(resData);
+ }
+ // 业务失败(code === 500 统一 showToast 展示完整 msg)
+ else {
+ if (resData.code === 500 && resData.msg) {
+ uni.showToast({ title: resData.msg, icon: 'error', duration: 2500 });
+ }
+ reject({ msg: resData.msg || '请求失败', code: resData.code, data: resData });
+ }
+ },
+ fail: (err) => {
+ uni.hideLoading();
+ reject({ msg: '网络异常', code: -1, raw: err });
+ }
+ });
+ });
+}
+
+export const get = (url, data = {}) => request(url, data, 'GET');
+export const post = (url, data) => request(url, data, 'POST');
+export const deleteMethod = (url, data) => request(url, data, 'DELETE');
+export const putMethod = (url, data) => request(url, data, 'PUT');
+
+// 上传
+export const upload = (filePath, url) => {
+ return new Promise((resolve, reject) => {
+ uni.uploadFile({
+ url: baseUrl + url,
+ filePath: filePath,
+ name: 'file',
+ header: {
+ "Authorization": "Bearer " + (uni.getStorageSync("token") || ''),
+ "clientid": "resident"
+ },
+ success: (res) => {
+ try {
+ const data = JSON.parse(res.data);
+ resolve(data.data || ''); // 直接返回图片地址
+ } catch (e) {
+ resolve('');
+ }
+ },
+ fail: (err) => {
+ reject(err);
+ }
+ });
+ });
+};
diff --git a/huakai-app/pageSubPack/api/useImageUpload.js b/huakai-app/pageSubPack/api/useImageUpload.js
new file mode 100644
index 0000000..497d1ff
--- /dev/null
+++ b/huakai-app/pageSubPack/api/useImageUpload.js
@@ -0,0 +1,190 @@
+// 服务器地址(与 request.js 保持一致)
+const baseUrl = 'http://192.168.0.239:8080';
+
+/**
+ * 图片上传 Hook
+ * 支持 uniapp 和微信小程序
+ * 解决编辑回显后重新上传的问题
+ */
+
+import { reactive } from 'vue'
+
+/**
+ * @param {Object} options 配置
+ * @param {string} options.uploadUrl - 上传接口地址
+ * @param {string} options.fileKey - 上传文件的字段名,默认 'file'
+ * @returns {Object}
+ */
+export function useImageUpload(options = {}) {
+ const {
+ uploadUrl = '/api/resident/file/uploadImage',
+ fileKey = 'file'
+ } = options
+
+ // 使用 reactive 对象存储所有状态
+ const state = reactive({
+ // 当前显示的图片(前端展示用,支持 base64/blob URL/网络URL)
+ previewUrl: '',
+ // 服务器返回的 URL(提交时使用)
+ serverUrl: '',
+ // 临时的文件路径(重新上传时用)
+ tempFilePath: null,
+ // 上传状态
+ uploading: false
+ })
+
+ /**
+ * 设置回显图片(编辑时从后端获取)
+ * @param {string} url - 后端返回的图片URL
+ */
+ const setPreviewUrl = (url) => {
+ if (url) {
+ // 确保 url 是字符串
+ const urlStr = typeof url === 'string' ? url : (url?.url || String(url))
+ state.previewUrl = urlStr
+ state.serverUrl = urlStr
+ state.tempFilePath = null // 重置临时文件,表示没有重新上传
+ }
+ }
+
+ /**
+ * 选择图片并预览(不上传)
+ * @returns {Promise} 返回临时文件路径
+ */
+ const chooseImage = () => {
+ return new Promise((resolve, reject) => {
+ uni.chooseImage({
+ count: 1,
+ sizeType: ['compressed'],
+ sourceType: ['camera', 'album'],
+ success: (res) => {
+ const path = res.tempFilePaths?.[0]
+ if (!path) {
+ reject(new Error('选择图片失败'))
+ return
+ }
+ // 确保 path 是字符串
+ const pathStr = typeof path === 'string' ? path : String(path)
+ // 设置预览
+ state.previewUrl = pathStr
+ // 记录临时文件路径
+ state.tempFilePath = pathStr
+ // 置空服务器URL,等实际上传后再获取
+ state.serverUrl = ''
+ resolve(pathStr)
+ },
+ fail: (err) => {
+ reject(err)
+ }
+ })
+ })
+ }
+
+ /**
+ * 上传图片到服务器
+ * @returns {Promise