Files
intc-vue-h5/src/pages/health/chronicDisease/addEdit.vue
bot5 bc39cb60d3 feat(health): 新增慢性疾病档案小程序模块
- 新增慢性疾病档案API接口
- 新增慢性疾病档案列表页
- 新增慢性疾病档案新增/编辑页
- 支持成员选择、疾病状态管理
- 参考现有模块样式开发
2026-03-17 23:51:42 +08:00

387 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="container" style="paddingBottom:1rpx;">
<view class="section">
<view class="section-title">{{ title }}</view>
<view class="form-view">
<u--form labelPosition="left" :model="form" :rules="rules" ref="uForm" label-width="160rpx"
:labelStyle="{ color: '#333333', fontSize: '30rpx', marginRight: '24rpx' }">
<u-form-item label="成员" prop="memberName" required @click="handleMember">
<view class="input-with-arrow">
<u--input v-model="form.memberName" disabled disabledColor="#ffffff" placeholder="请选择成员"
inputAlign="left" :customStyle="getInputStyle('memberName')"></u--input>
<text class="arrow-icon"></text>
</view>
</u-form-item>
<u-form-item label="疾病名称" prop="diseaseName" required>
<u--input v-model="form.diseaseName" placeholder="请输入疾病名称"
inputAlign="left" :customStyle="getInputStyle('diseaseName')"></u--input>
</u-form-item>
<u-form-item label="疾病编码" prop="diseaseCode">
<u--input v-model="form.diseaseCode" placeholder="ICD-10编码可选"
inputAlign="left" :customStyle="getInputStyle('diseaseCode')"></u--input>
</u-form-item>
<u-form-item label="确诊日期" prop="diagnosisDate" @click="selectDate">
<view class="input-with-arrow">
<u--input v-model="form.diagnosisDate" disabled disabledColor="#ffffff" placeholder="请选择确诊日期"
inputAlign="left" :customStyle="getInputStyle('diagnosisDate')"></u--input>
<text class="arrow-icon"></text>
</view>
</u-form-item>
<u-form-item label="疾病状态" prop="diseaseStatusName" required @click="handleStatus">
<view class="input-with-arrow">
<u--input v-model="form.diseaseStatusName" disabled disabledColor="#ffffff" placeholder="请选择疾病状态"
inputAlign="left" :customStyle="getInputStyle('diseaseStatusName')"></u--input>
<text class="arrow-icon"></text>
</view>
</u-form-item>
<u-form-item label="主治医生" prop="mainDoctor">
<u--input v-model="form.mainDoctor" placeholder="请输入主治医生"
inputAlign="left" :customStyle="getInputStyle('mainDoctor')"></u--input>
</u-form-item>
<u-form-item label="就诊医院" prop="hospital">
<u--input v-model="form.hospital" placeholder="请输入就诊医院"
inputAlign="left" :customStyle="getInputStyle('hospital')"></u--input>
</u-form-item>
<u-form-item label="科室" prop="department">
<u--input v-model="form.department" placeholder="请输入科室"
inputAlign="left" :customStyle="getInputStyle('department')"></u--input>
</u-form-item>
<u-form-item label="是否启用" prop="isActive">
<u-switch v-model="isActiveSwitch" activeColor="#667eea" @change="handleActiveChange"></u-switch>
</u-form-item>
<u-form-item label="备注说明" prop="notes" labelPosition="top">
<u--textarea v-model="form.notes" height="60rpx" placeholder="请输入备注说明" inputAlign="left"
style="border: 2rpx solid #dcdfe6 !important; height: 160rpx;"
:customStyle="getTextareaStyle('notes')"></u--textarea>
</u-form-item>
<u-form-item label="备注" prop="remark" labelPosition="top">
<u--textarea v-model="form.remark" height="40rpx" placeholder="请输入备注" inputAlign="left"
style="border: 2rpx solid #dcdfe6 !important; height: 160rpx;"
:customStyle="getTextareaStyle('remark')"></u--textarea>
</u-form-item>
</u--form>
<view class="form-btn">
<u-button type="primary" text="提交" @click="submit"></u-button>
</view>
</view>
</view>
<u-toast ref="uToast"></u-toast>
<u-picker itemHeight="88" :show="showMember" :columns="memberList" keyName="name"
@cancel="handleMemberCancel" @confirm="handleMemberConfirm"></u-picker>
<u-picker itemHeight="88" :show="showStatus" :columns="statusList" keyName="label"
@cancel="handleStatusCancel" @confirm="handleStatusConfirm"></u-picker>
<u-datetime-picker
:show="datePickShow"
mode="date"
ref="diagnosisDateRef"
@cancel="datePickShow=false"
@confirm="datePickConfirm"
itemHeight="88"
:maxDate="maxDate"
></u-datetime-picker>
</view>
</template>
<script setup>
import { getChronicDisease, addChronicDisease, updateChronicDisease } from '@/api/health/chronicDisease'
import { listPerson } from '@/api/health/person'
import { onLoad, onReady } from "@dcloudio/uni-app"
import dayjs from 'dayjs'
import { reactive, toRefs, ref, computed, getCurrentInstance } from "vue"
const { proxy } = getCurrentInstance()
const datePickShow = ref(false)
const showMember = ref(false)
const showStatus = ref(false)
const title = ref("慢性疾病档案")
const memberList = ref([])
const maxDate = ref(Date.now())
const statusList = ref([
[
{ value: 1, label: '稳定' },
{ value: 2, label: '需关注' },
{ value: 3, label: '急性期' }
]
])
const data = reactive({
form: {
id: null,
memberId: null,
memberName: null,
diseaseName: null,
diseaseCode: null,
diagnosisDate: null,
diseaseStatus: 1,
diseaseStatusName: '稳定',
mainDoctor: null,
hospital: null,
department: null,
isActive: 1,
notes: null,
remark: null
},
queryPersonParams: {
pageNum: 1,
pageSize: 1000
},
rules: {
memberName: [{ required: true, message: '成员不能为空', trigger: ['change', 'blur'] }],
diseaseName: [{ required: true, message: '疾病名称不能为空', trigger: ['change', 'blur'] }],
diseaseStatusName: [{ required: true, message: '疾病状态不能为空', trigger: ['change', 'blur'] }]
}
})
const { form, queryPersonParams, rules } = toRefs(data)
// 错误字段
const errorFields = ref([])
// 输入框基础样式
const inputBaseStyle = {
background: '#ffffff',
border: '2rpx solid #dcdfe6',
borderRadius: '8rpx',
padding: '0 24rpx',
height: '68rpx',
width: '100%',
boxSizing: 'border-box'
}
// 输入框错误样式
const inputErrorStyle = {
background: '#fef0f0',
border: '2rpx solid #f56c6c',
borderRadius: '8rpx',
padding: '0 24rpx',
height: '68rpx',
width: '100%',
boxSizing: 'border-box'
}
// 根据字段名获取输入框样式
const getInputStyle = (field) => {
return errorFields.value.includes(field) ? inputErrorStyle : inputBaseStyle
}
// 文本域基础样式
const textareaBaseStyle = {
background: '#ffffff',
border: '2rpx solid #dcdfe6',
}
// 文本域错误样式
const textareaErrorStyle = {
background: '#fef0f0',
border: '2rpx solid #f56c6c'
}
// 根据字段名获取文本域样式
const getTextareaStyle = (field) => {
return errorFields.value.includes(field) ? textareaErrorStyle : textareaBaseStyle
}
// 是否启用开关
const isActiveSwitch = computed({
get: () => form.value.isActive === 1,
set: (val) => { form.value.isActive = val ? 1 : 0 }
})
onLoad((option) => {
form.value.id = option.id
if (form.value.id != null) {
title.value = "慢性疾病档案-修改"
} else {
title.value = "慢性疾病档案-新增"
}
getData()
})
function getData() {
listPerson(queryPersonParams.value).then((response) => {
memberList.value = [response.rows]
if (form.value.id != null) {
getChronicDisease(form.value.id).then(res => {
form.value = res.data
// 设置状态名称
const statusItem = statusList.value[0].find(s => s.value === form.value.diseaseStatus)
if (statusItem) {
form.value.diseaseStatusName = statusItem.label
}
})
} else {
// 默认选择第一个成员
if (response.rows.length > 0) {
form.value.memberName = response.rows[0].name
form.value.memberId = response.rows[0].id
}
}
})
}
function handleMember() {
if (memberList.value[0].length === 0) {
proxy.$refs['uToast'].show({
message: '成员为空', type: 'warning'
})
} else {
showMember.value = true
}
}
function handleMemberConfirm(e) {
form.value.memberName = e.value[0].name
form.value.memberId = e.value[0].id
showMember.value = false
}
function handleMemberCancel() {
showMember.value = false
}
function handleStatus() {
showStatus.value = true
}
function handleStatusConfirm(e) {
form.value.diseaseStatusName = e.value[0].label
form.value.diseaseStatus = e.value[0].value
showStatus.value = false
}
function handleStatusCancel() {
showStatus.value = false
}
function selectDate() {
datePickShow.value = true
proxy.$refs['diagnosisDateRef'].innerValue = new Date().getTime()
}
function datePickConfirm(e) {
form.value.diagnosisDate = dayjs(e.value).format("YYYY-MM-DD")
datePickShow.value = false
}
function handleActiveChange(val) {
form.value.isActive = val ? 1 : 0
}
function submit() {
proxy.$refs['uForm'].validate().then(() => {
if (form.value.id != null) {
updateChronicDisease(form.value).then(res => {
proxy.$refs['uToast'].show({
message: '修改成功', complete() {
uni.navigateTo({ url: `/pages/health/chronicDisease/list` })
}
})
})
} else {
addChronicDisease(form.value).then(res => {
proxy.$refs['uToast'].show({
message: '新增成功', complete() {
uni.navigateTo({ url: `/pages/health/chronicDisease/list` })
}
})
})
}
}).catch(errors => {
if (errors && errors.length > 0) {
errorFields.value = errors.map(err => err.field)
}
proxy.$modal.msgError('请填写完整信息')
})
}
</script>
<style lang="scss" scoped>
page {
height: 100%;
overflow: auto;
}
.section {
margin: 24rpx;
padding: 0;
background-color: #fff;
border-radius: 16rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
overflow: hidden;
.section-title {
padding: 16rpx 24rpx;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: #ffffff;
line-height: 1.2;
font-size: 28rpx;
font-weight: 600;
display: flex;
align-items: center;
&::before {
content: '';
width: 6rpx;
height: 28rpx;
background: #ffffff;
border-radius: 3rpx;
margin-right: 12rpx;
}
}
.form-view {
padding: 24rpx;
.form-btn {
padding-top: 16rpx;
}
.input-with-arrow {
position: relative;
width: 100%;
.arrow-icon {
position: absolute;
right: 20rpx;
top: 50%;
transform: translateY(-50%);
color: #c0c4cc;
font-size: 20rpx;
pointer-events: none;
z-index: 10;
}
}
}
}
</style>
<style lang="scss">
.form-btn .u-button {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
border: none !important;
border-radius: 24rpx !important;
height: 80rpx !important;
box-shadow: 0 4rpx 16rpx rgba(102, 126, 234, 0.4) !important;
}
.form-btn .u-button__text {
font-size: 30rpx !important;
font-weight: 500 !important;
letter-spacing: 2rpx !important;
}
.u-form-item--error .u--input,
.u-form-item--error .u-input,
.u-form-item--error .u-input__content,
.u-form-item--error .u-input__content__field-wrapper {
border: 2rpx solid #f56c6c !important;
background: #fef0f0 !important;
}
.u-form-item--error .u--textarea,
.u-form-item--error .u-textarea {
border: 2rpx solid #f56c6c !important;
background: #fef0f0 !important;
}
</style>