From cdba9f6569c389c172c698dfa832d240b0d5337c Mon Sep 17 00:00:00 2001 From: tianyongbao Date: Thu, 25 Jun 2026 21:40:42 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=83=A8=E5=88=86=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=EF=BC=8C=E6=96=B0=E5=A2=9E=E9=99=84=E4=BB=B6=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=8C=E4=BC=98=E5=8C=96=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=EF=BC=8C=E4=BF=AE=E5=A4=8Dbug=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/health/activity.js | 10 + src/api/health/doctorRecord.js | 10 + src/api/health/medicineBasic.js | 10 + src/pages.json | 12 ++ src/pages/health/activity/addEdit.vue | 162 ++++++++++++++- src/pages/health/activity/list.vue | 52 +++++ src/pages/health/doctorRecord/addEdit.vue | 182 +++++++++++++++- src/pages/health/doctorRecord/costAddEdit.vue | 4 + src/pages/health/doctorRecord/list.vue | 55 +++++ src/pages/health/medicineBasic/addEdit.vue | 194 +++++++++++++++++- src/pages/health/medicineBasic/list.vue | 56 ++++- src/pages/login.vue | 104 +++++++++- 12 files changed, 833 insertions(+), 18 deletions(-) diff --git a/src/api/health/activity.js b/src/api/health/activity.js index 00ea5cf..1839f10 100644 --- a/src/api/health/activity.js +++ b/src/api/health/activity.js @@ -1,4 +1,14 @@ import request from '@/utils/request' +import upload from '@/utils/upload' + +// 通用文件上传(RuoYi-Cloud 文件接口) +export function uploadFile(data) { + return upload({ + url: '/file/upload', + name: data.name || 'file', + filePath: data.filePath + }) +} // 查询活动记录列表 export function listActivity(query) { diff --git a/src/api/health/doctorRecord.js b/src/api/health/doctorRecord.js index 055d389..618da5a 100644 --- a/src/api/health/doctorRecord.js +++ b/src/api/health/doctorRecord.js @@ -1,4 +1,14 @@ import request from '@/utils/request' +import upload from '@/utils/upload' + +// 通用文件上传(RuoYi-Cloud 文件接口) +export function uploadFile(data) { + return upload({ + url: '/file/upload', + name: data.name || 'file', + filePath: data.filePath + }) +} // 查询就医记录列表 export function listDoctorRecord(query) { diff --git a/src/api/health/medicineBasic.js b/src/api/health/medicineBasic.js index 0e13201..b8a9da2 100644 --- a/src/api/health/medicineBasic.js +++ b/src/api/health/medicineBasic.js @@ -1,4 +1,14 @@ import request from '@/utils/request' +import upload from '@/utils/upload' + +// 通用文件上传(RuoYi-Cloud 文件接口) +export function uploadFile(data) { + return upload({ + url: '/file/upload', + name: data.name || 'file', + filePath: data.filePath + }) +} // 查询药品基础信息列表 export function listMedicineBasic(query) { diff --git a/src/pages.json b/src/pages.json index 62209f1..f8af2d7 100644 --- a/src/pages.json +++ b/src/pages.json @@ -36,6 +36,18 @@ "navigationBarTitleText": "浏览文本" } }, + { + "path": "pages/common/agreement/index", + "style": { + "navigationBarTitleText": "用户服务协议" + } + }, + { + "path": "pages/common/privacy/index", + "style": { + "navigationBarTitleText": "隐私协议" + } + }, { "path": "pages/health/homepage/index", "style": { diff --git a/src/pages/health/activity/addEdit.vue b/src/pages/health/activity/addEdit.vue index 60232fb..36f4f8a 100644 --- a/src/pages/health/activity/addEdit.vue +++ b/src/pages/health/activity/addEdit.vue @@ -74,6 +74,23 @@ + + + + + + + + + + + + 上传图片 + + + 最多上传9张图片,支持 jpg/png/jpeg 等格式 + + @@ -105,8 +122,9 @@ - diff --git a/src/pages/health/activity/list.vue b/src/pages/health/activity/list.vue index cfe1b84..a59d52a 100644 --- a/src/pages/health/activity/list.vue +++ b/src/pages/health/activity/list.vue @@ -84,6 +84,19 @@ 备注 {{ item.remark }} + + 附件 + + + + @@ -180,6 +193,7 @@ import { getDicts } from '@/api/system/dict/data.js' import { timeHandler } from '@/utils/common.ts' import {onLoad,onShow} from "@dcloudio/uni-app"; import dayjs from 'dayjs' +import config from '@/config' // 计算属性与监听属性是在vue中而非uniap中 需要注意!!! import {reactive ,toRefs,ref,computed }from "vue"; const pageNum = ref(1) @@ -409,6 +423,23 @@ function getList() { } }); } + +function parseAttachment(attachment) { + if (!attachment) return [] + // 附件是后端静态资源直链,需要用域名拼接,不能带网关前缀 prod-api + const origin = config.baseUrl.replace(/^(https?:\/\/[^/]+).*$/, '$1') + return attachment.split(',').filter(url => url).map(url => { + if (url.startsWith('http')) return url + return origin + url + }) +} + +function previewAttachment(urls, index) { + uni.previewImage({ + urls: urls, + current: urls[index] + }) +} @@ -489,6 +520,27 @@ function getList() { border: 1rpx solid rgba(19, 194, 194, 0.3); } +.attachment-list { + display: flex; + flex-wrap: wrap; + gap: 12rpx; + margin-top: 4rpx; + width: 100%; + + .attachment-thumb { + width: 120rpx; + height: 120rpx; + border-radius: 8rpx; + background: #f5f7fa; + box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.08); + transition: transform 0.2s ease; + + &:active { + transform: scale(0.95); + } + } +} + // ==================== 费用汇总面板 ==================== .summary-mask { position: fixed; diff --git a/src/pages/health/doctorRecord/addEdit.vue b/src/pages/health/doctorRecord/addEdit.vue index ff24b0c..66b80b6 100644 --- a/src/pages/health/doctorRecord/addEdit.vue +++ b/src/pages/health/doctorRecord/addEdit.vue @@ -70,6 +70,23 @@ + + + + + + + + + + + + 上传图片 + + + 最多上传9张图片,支持 jpg/png/jpeg 等格式 + + @@ -95,7 +112,8 @@ @@ -479,4 +655,4 @@ page { border: 2rpx solid #f56c6c !important; background: #fef0f0 !important; } - \ No newline at end of file + diff --git a/src/pages/health/doctorRecord/costAddEdit.vue b/src/pages/health/doctorRecord/costAddEdit.vue index 1070989..34679fe 100644 --- a/src/pages/health/doctorRecord/costAddEdit.vue +++ b/src/pages/health/doctorRecord/costAddEdit.vue @@ -287,6 +287,10 @@ function getData() { form.value.typeName = dictStr(form.value.type, costTypeList.value) form.value.unitName = dictStr(form.value.unit, packageUnitList.value) form.value.checkTypeName = dictStr(form.value.checkType, checkTypeList.value) || dictStr(form.value.checkType, nursingTypeList.value) + // 后端返回的单价/数量/总价为数字类型,校验器按 string 校验会误判为空,这里统一转为字符串 + form.value.price = form.value.price != null ? String(form.value.price) : form.value.price + form.value.count = form.value.count != null ? String(form.value.count) : form.value.count + form.value.totalCost = form.value.totalCost != null ? String(form.value.totalCost) : form.value.totalCost applyTypeState(form.value.type) if (flag.value != null) { form.value.id = null diff --git a/src/pages/health/doctorRecord/list.vue b/src/pages/health/doctorRecord/list.vue index c9e6ded..2fbf840 100644 --- a/src/pages/health/doctorRecord/list.vue +++ b/src/pages/health/doctorRecord/list.vue @@ -168,6 +168,19 @@ 备注 {{ item.remark }} + + 附件 + + + + @@ -213,6 +226,7 @@ import { getDicts } from '@/api/system/dict/data.js' import { timeHandler } from '@/utils/common.ts' import {onLoad,onShow} from "@dcloudio/uni-app"; import dayjs from 'dayjs' +import config from '@/config' // 计算属性与监听属性是在vue中而非uniap中 需要注意!!! import {reactive ,toRefs,ref,computed }from "vue"; const pageNum = ref(1) @@ -467,6 +481,25 @@ function settingCancel() { } }); } + +// 解析附件字段为URL数组 +function parseAttachment(attachment) { + if (!attachment) return [] + // 附件是后端静态资源直链,需要用域名拼接,不能带网关前缀 prod-api + const origin = config.baseUrl.replace(/^(https?:\/\/[^/]+).*$/, '$1') + return attachment.split(',').filter(url => url).map(url => { + if (url.startsWith('http')) return url + return origin + url + }) +} + +// 预览附件图片 +function previewAttachment(urls, index) { + uni.previewImage({ + urls: urls, + current: urls[index] + }) +} diff --git a/src/pages/health/medicineBasic/addEdit.vue b/src/pages/health/medicineBasic/addEdit.vue index b80152d..7f81b5a 100644 --- a/src/pages/health/medicineBasic/addEdit.vue +++ b/src/pages/health/medicineBasic/addEdit.vue @@ -129,6 +129,23 @@ + + + + + + + + + + + + 上传图片 + + + 最多上传9张图片,支持 jpg/png/jpeg 等格式 + + @@ -158,7 +175,8 @@ diff --git a/src/pages/health/medicineBasic/list.vue b/src/pages/health/medicineBasic/list.vue index 8fa3e37..cee1521 100644 --- a/src/pages/health/medicineBasic/list.vue +++ b/src/pages/health/medicineBasic/list.vue @@ -130,6 +130,19 @@ 录入时间 {{ item.createTime || '--' }} + + 附件 + + + + @@ -166,6 +179,7 @@ import { getDicts } from '@/api/system/dict/data.js' import { timeHandler } from '@/utils/common.ts' import {onLoad,onShow} from "@dcloudio/uni-app"; import auth from "@/plugins/auth"; // 建议使用auth进行鉴权操作 +import config from '@/config' import dayjs from 'dayjs' // 计算属性与监听属性是在vue中而非uniap中 需要注意!!! import {reactive ,toRefs,ref,computed }from "vue"; @@ -358,7 +372,25 @@ function settingCancel() { } }); } - + +// 解析附件字段为URL数组 +function parseAttachment(attachment) { + if (!attachment) return [] + // 附件是后端静态资源直链,需要用域名拼接,不能带网关前缀 prod-api + const origin = config.baseUrl.replace(/^(https?:\/\/[^/]+).*$/, '$1') + return attachment.split(',').filter(url => url).map(url => { + if (url.startsWith('http')) return url + return origin + url + }) +} + +// 预览附件图片 +function previewAttachment(urls, index) { + uni.previewImage({ + urls: urls, + current: urls[index] + }) +} \ No newline at end of file diff --git a/src/pages/login.vue b/src/pages/login.vue index 3828f3c..a1bf15c 100644 --- a/src/pages/login.vue +++ b/src/pages/login.vue @@ -38,16 +38,26 @@ /> - + - - - + + + + + + + 记住密码 + + + + + + + 已阅读并同意 + 《用户协议》 + + 《隐私协议》 - 已阅读并同意 - 《用户协议》 - - 《隐私协议》 @@ -77,12 +87,23 @@ import { getWxCode } from '@/utils/geek'; import { wxLogin } from '@/api/oauth'; import { setToken } from '@/utils/auth'; import { encrypt, decrypt } from '@/utils/jsencrypt' + +// ========== 平台判断(条件编译)========== +// H5 端为 true,其他端为 false。条件编译保证仅 H5 打包对应逻辑 +let isH5 = false +// #ifdef H5 +isH5 = true +// #endif + +const REMEMBER_KEY = 'remember_login_info' + const userStore = useUserStore() const codeUrl = ref(""); const captchaEnabled = ref(true); // 是否开启验证码 const useWxLogin = ref(false); // 是否使用微信登录 const globalConfig = ref(config); -const agree = ref(false); // 同意协议 +const agree = ref(isH5 ? true : false); // H5 端默认勾选同意协议 +const rememberPwd = ref(false); // 记住密码 const loginForm = ref({ username: "", password: "", @@ -103,8 +124,49 @@ if (useWxLogin.value) { } // 页面加载时检查是否记住了密码 onMounted(() => { + loadRememberedLogin() }); +// 读取本地记住的登录信息(仅 H5) +function loadRememberedLogin() { + if (!isH5) return + try { + const raw = uni.getStorageSync(REMEMBER_KEY) + if (!raw) return + const info = JSON.parse(raw) + if (info && info.username) { + loginForm.value.username = info.username + // 密码以 base64 存储,解码后回填 + if (info.password) { + try { + loginForm.value.password = decodeURIComponent(escape(atob(info.password))) + } catch (e) { + loginForm.value.password = '' + } + } + rememberPwd.value = true + } + } catch (e) { + console.error('读取记住的登录信息失败', e) + uni.removeStorageSync(REMEMBER_KEY) + } +} + +// 保存或清除记住的登录信息(仅 H5) +function saveRememberedLogin() { + if (!isH5) return + if (rememberPwd.value && loginForm.value.username) { + const info = { + username: loginForm.value.username, + // 密码使用 base64 简单编码,避免明文存储 + password: btoa(unescape(encodeURIComponent(loginForm.value.password || ''))) + } + uni.setStorageSync(REMEMBER_KEY, JSON.stringify(info)) + } else { + uni.removeStorageSync(REMEMBER_KEY) + } +} + // 获取图形验证码 function getCode() { getCodeImg().then(res => { @@ -137,6 +199,8 @@ async function handleLogin() { async function pwdLogin() { userStore.login(loginForm.value).then(() => { modal.closeLoading() + // 登录成功后保存或清除记住的密码 + saveRememberedLogin() loginSuccess() }).catch(() => { if (captchaEnabled.value) { @@ -158,6 +222,11 @@ function agreeChange(){ agree.value = !agree.value; } +// 切换记住密码状态 +function rememberChange(){ + rememberPwd.value = !rememberPwd.value; +} + // 隐私协议 function handlePrivacy() { uni.navigateTo({ @@ -266,12 +335,29 @@ page { margin-top: 24rpx; padding: 0 4rpx; + .agreement-line { + display: flex; + align-items: flex-start; + flex-wrap: wrap; + line-height: 1.6; + } + .agreement-row { display: flex; align-items: center; flex-wrap: wrap; line-height: 1.6; + &.remember-part { + margin-right: 32rpx; + flex-shrink: 0; + } + + &.agree-part { + flex: 1; + min-width: 0; + } + .checkbox-small { width: 28rpx; height: 28rpx;