src/components/PageHeader.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/pages/cooperativeOffice/clientVisit/detail.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/pages/equipmentManagement/ledger/detail.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/pages/equipmentManagement/ledger/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/pages/equipmentManagement/repair/add.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/pages/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/pages/mine.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/pages/procurementManagement/invoiceEntry/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/pages/sales/invoicingRegistration/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/pages/sales/salesAccount/detail.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/components/PageHeader.vue
@@ -1,20 +1,17 @@ <template> <view class="page-header"> <view class="header-left"> <up-icon name="arrow-left" size="20" color="#333" @click="handleBack" ></up-icon> </view> <view class="header-center"> <text class="page-title">{{ title }}</text> </view> <view class="header-right" v-if="$slots.right"> <slot name="right"></slot> </view> </view> <up-navbar :title="title" :show-back="showBack" @leftClick="handleBack" :color="color" :border="true" :fixed="true" :placeholder="true" > <template v-if="$slots.right" #right> <slot name="right"></slot> </template> </up-navbar> </template> <script setup> @@ -22,21 +19,41 @@ // 定义组件属性 const props = defineProps({ // 页面标题 title: { type: String, default: '' }, // 是否显示返回按钮 showBack: { type: Boolean, default: true }, // 自定义返回事件 customBack: { type: Function, default: null } // 页面标题 title: { type: String, default: '' }, // 是否显示返回按钮 showBack: { type: Boolean, default: true }, // 自定义返回事件 customBack: { type: Function, default: null }, // 背景色 background: { type: String, default: '#ffffff' }, // 文字颜色 color: { type: String, default: '#333333' }, // 是否显示底部分割线 borderBottom: { type: Boolean, default: true }, // 是否固定在顶部 isFixed: { type: Boolean, default: true } }); // 定义事件 @@ -44,60 +61,28 @@ // 处理返回事件 const handleBack = () => { if (props.customBack) { props.customBack(); } else { emit('back'); // uni.navigateBack(); } if (props.customBack) { props.customBack(); } else { emit('back'); // uni.navigateBack(); } }; </script> <style scoped lang="scss"> .page-header { background: #ffffff; padding: 16px 20px; display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid #f0f0f0; position: sticky; /* 兼容 iOS 刘海/灵动岛安全区 */ padding-top: calc(env(safe-area-inset-top)); top: 0; z-index: 100; position: relative; } /* up-navbar 组件已经内置了安全区域适配,不需要额外的样式调整 */ .header-left { display: flex; align-items: center; gap: 8px; min-width: 30px; /* 确保点击区域足够大 */ } .header-center { flex: 1; display: flex; justify-content: center; align-items: center; position: absolute; left: 0; right: 0; pointer-events: none; } .page-title { font-size: 18px; font-weight: 600; color: #333; pointer-events: auto; } .header-right { display: flex; align-items: center; min-width: 44px; /* 确保右侧区域有足够空间 */ justify-content: flex-end; /* 暗色模式适配 */ @media (prefers-color-scheme: dark) { :deep(.up-navbar) { background: #1e1f24 !important; .up-navbar__title { color: #e9edf3 !important; } .up-navbar__back { color: #e9edf3 !important; } } } </style> src/pages/cooperativeOffice/clientVisit/detail.vue
@@ -53,7 +53,7 @@ placeholder="请输入拜访地点" > <template #suffix> <u-icon name="map" @click.stop="getCurrentLocation" class="location-icon" /> <u-icon name="map" @click="getCurrentLocation" class="location-icon" /> </template> </u-input> </u-form-item> src/pages/equipmentManagement/ledger/detail.vue
@@ -1,10 +1,10 @@ <template> <view class="equipment-detail"> <view class="account-detail"> <!-- 使用通用页面头部组件 --> <PageHeader title="设备台账详情" @back="goBack" /> <!-- 表单内容 --> <u-form @submit="sendForm" ref="formRef" :rules="formRules" label-width="110"> <u-form @submit="sendForm" ref="formRef" :model="form" :rules="formRules" label-width="110"> <!-- 基本信息 --> <u-cell-group title="基本信息"> <u-form-item label="设备名称" prop="deviceName" required border-bottom> @@ -22,13 +22,13 @@ clearable /> </u-form-item> <u-form-item label="设备品牌" prop="deviceBrand" required border-bottom> <!-- <u-form-item label="设备品牌" prop="deviceBrand" required border-bottom> <u-input v-model="form.deviceBrand" placeholder="请输入设备品牌" clearable /> </u-form-item> </u-form-item> --> <u-form-item label="供应商" prop="supplierName" required border-bottom> <u-input v-model="form.supplierName" @@ -36,13 +36,13 @@ clearable /> </u-form-item> <u-form-item label="存放位置" prop="storageLocation" required border-bottom> <!-- <u-form-item label="存放位置" prop="storageLocation" required border-bottom> <u-input v-model="form.storageLocation" placeholder="请输入存放位置" clearable /> </u-form-item> </u-form-item> --> <u-form-item label="单位" prop="unit" required border-bottom> <u-input v-model="form.unit" @@ -50,13 +50,13 @@ clearable /> </u-form-item> <u-form-item label="启用折旧" prop="enableDepreciation" required border-bottom> <!-- <u-form-item label="启用折旧" prop="enableDepreciation" required border-bottom> <u-switch v-model="form.enableDepreciation" :active-value="true" :inactive-value="false" /> </u-form-item> </u-form-item> --> <u-form-item label="数量" prop="number" required border-bottom> <u-input v-model="form.number" @@ -186,9 +186,46 @@ supplierName: [{ required: true, trigger: "blur", message: "请输入" }], storageLocation: [{ required: true, trigger: "blur", message: "请输入" }], unit: [{ required: true, trigger: "blur", message: "请输入" }], number: [{ required: true, trigger: "blur", message: "请输入" }], taxIncludingPriceUnit: [{ required: true, trigger: "blur", message: "请输入" }], taxRate: [{ required: true, trigger: "change", message: "请输入" }], // 数字类型字段需要特殊处理,确保有数值时不会触发必填校验 number: [{ required: true, trigger: "blur", message: "请输入", validator: (rule, value, callback) => { // 对于数字类型,检查是否为有效数字(包括0) if (value !== undefined && value !== null && value !== '' && !isNaN(value)) { callback(); } else { callback(new Error('请输入数量')); } } }], taxIncludingPriceUnit: [{ required: true, trigger: "blur", message: "请输入", validator: (rule, value, callback) => { // 对于数字类型,检查是否为有效数字(包括0) if (value !== undefined && value !== null && value !== '' && !isNaN(value)) { callback(); } else { callback(new Error('请输入含税单价')); } } }], taxRate: [{ required: true, trigger: "change", message: "请选择", validator: (rule, value, callback) => { // 检查税率是否为有效数字 if (value !== undefined && value !== null && value !== '' && !isNaN(value)) { callback(); } else { callback(new Error('请选择税率')); } } }], createTime: [{ required: true, trigger: "change", message: "请选择" }], }; @@ -218,6 +255,8 @@ } try { const { code, data } = await getLedgerById(id); console.log(data); if (code == 200) { form.value.deviceName = data.deviceName; form.value.deviceModel = data.deviceModel; @@ -232,6 +271,11 @@ form.value.taxRate = data.taxRate; form.value.unTaxIncludingPriceTotal = data.unTaxIncludingPriceTotal; form.value.createTime = data.createTime; // 数据加载完成后,重置表单验证状态 setTimeout(() => { clearValidate(); }, 100); } } catch (e) { showToast('获取详情失败'); @@ -240,11 +284,12 @@ // 数学计算 const mathNum = () => { if (!form.value.taxIncludingPriceUnit) { // 只有在新增模式或者字段确实为空时才显示提示 if (operationType.value !== 'edit' || (form.value.taxIncludingPriceUnit === undefined || form.value.taxIncludingPriceUnit === '')) { showToast("请输入单价"); return; } if (!form.value.number) { if (operationType.value !== 'edit' || (form.value.number === undefined || form.value.number === '')) { showToast("请输入数量"); return; } @@ -265,47 +310,65 @@ formRef.value?.clearValidate(); }; // 重置表单数据和校验状态 const resetForm = () => { form.value = { deviceName: undefined, deviceModel: undefined, deviceBrand: undefined, supplierName: undefined, storageLocation: undefined, unit: undefined, enableDepreciation: false, number: undefined, taxIncludingPriceUnit: undefined, taxIncludingPriceTotal: undefined, taxRate: undefined, unTaxIncludingPriceTotal: undefined, createTime: dayjs().format("YYYY-MM-DD"), }; }; const resetFormAndValidate = () => { resetForm(); clearValidate(); }; // 提交表单 const sendForm = async () => { try { // 手动验证表单 await formRef.value?.validate(); // 检查必填字段 let isValid = true; let errorMessage = ''; // 检查文本类型必填字段 if (!form.value.deviceName || form.value.deviceName.trim() === '') { isValid = false; errorMessage = '请输入设备名称'; } else if (!form.value.deviceModel || form.value.deviceModel.trim() === '') { isValid = false; errorMessage = '请输入规格型号'; } else if (!form.value.deviceBrand || form.value.deviceBrand.trim() === '') { isValid = false; errorMessage = '请输入设备品牌'; } else if (!form.value.supplierName || form.value.supplierName.trim() === '') { isValid = false; errorMessage = '请输入供应商'; } else if (!form.value.storageLocation || form.value.storageLocation.trim() === '') { isValid = false; errorMessage = '请输入存放位置'; } else if (!form.value.unit || form.value.unit.trim() === '') { isValid = false; errorMessage = '请输入单位'; } // 检查数字类型必填字段 else if (form.value.number === undefined || form.value.number === null || form.value.number === '' || isNaN(form.value.number)) { isValid = false; errorMessage = '请输入数量'; } else if (form.value.taxIncludingPriceUnit === undefined || form.value.taxIncludingPriceUnit === null || form.value.taxIncludingPriceUnit === '' || isNaN(form.value.taxIncludingPriceUnit)) { isValid = false; errorMessage = '请输入含税单价'; } else if (form.value.taxRate === undefined || form.value.taxRate === null || form.value.taxRate === '' || isNaN(form.value.taxRate)) { isValid = false; errorMessage = '请选择税率'; } else if (!form.value.createTime || form.value.createTime.trim() === '') { isValid = false; errorMessage = '请选择录入日期'; } // 如果验证失败,显示错误提示 if (!isValid) { showToast(errorMessage); return; } // 验证通过,显示提交中提示 showToast('正在提交表单...'); loading.value = true; const id = getPageId(); // 准备提交数据,createTime 加上当前时分秒 const submitData = { ...form.value }; if (submitData.createTime && !submitData.createTime.includes(':')) { // 如果 createTime 只包含日期,添加当前时分秒 submitData.createTime = submitData.createTime + ' ' + dayjs().format('HH:mm:ss'); } const { code } = id const { code, res } = id ? await editLedger({ id: id, ...submitData }) : await addLedger(submitData); @@ -316,47 +379,52 @@ }, 1500); } else { loading.value = false; console.log(res); } } catch (e) { loading.value = false; showToast('表单验证失败'); showToast('提交失败'); } }; // 返回上一页 const goBack = () => { // 使用后清除storage中的ID,避免数据残留 uni.removeStorageSync('ledgerId'); uni.navigateBack(); }; // 获取页面参数 const getPageParams = () => { const pages = getCurrentPages(); const currentPage = pages[pages.length - 1]; const options = currentPage.options; if (options.id) { // 编辑模式,获取详情 loadForm(options.id); } else { // 新增模式 try { // 优先从storage中获取ID const ledgerId = uni.getStorageSync('ledgerId'); if (ledgerId) { // 编辑模式,获取详情 loadForm(ledgerId); } else { // 新增模式 operationType.value = 'add'; } } catch (e) { operationType.value = 'add'; } }; // 获取页面ID const getPageId = () => { const pages = getCurrentPages(); const currentPage = pages[pages.length - 1]; const options = currentPage.options; return options.id; }; // 确认税率选择 const onTaxRateConfirm = (e) => { form.value.taxRate = e.value; mathNum(); // 重新计算 try { // 优先从storage中获取ID const ledgerId = uni.getStorageSync('ledgerId'); if (ledgerId) { return ledgerId; } } catch (e) { console.error('获取页面ID出错:', e); } return null; }; // 选择税率 src/pages/equipmentManagement/ledger/index.vue
@@ -150,7 +150,7 @@ } getLedgerPage(params) .then((res) => { ledgerList.value = res.records || res.data?.records || [] ledgerList.value = res.data.records }) .catch(() => { showToast('获取数据失败') @@ -167,8 +167,9 @@ // 编辑 - 跳转到详情页面 const edit = (id) => { if (!id) return uni.setStorageSync('ledgerId', id) uni.navigateTo({ url: `/pages/equipmentManagement/ledger/detail?id=${id}` url: '/pages/equipmentManagement/ledger/detail' }) } src/pages/equipmentManagement/repair/add.vue
@@ -4,7 +4,7 @@ <PageHeader :title="operationType === 'edit' ? '编辑报修' : '新增报修'" @back="goBack" /> <!-- 表单内容 --> <u-form @submit="sendForm" ref="formRef" :rules="formRules" label-width="110" input-align="right" error-message-align="right"> <u-form @submit="sendForm" ref="formRef" :rules="formRules" :model="form" label-width="110"> <!-- 基本信息 --> <u-cell-group title="基本信息"> <u-form-item label="设备名称" prop="deviceLedgerId" required border-bottom> @@ -204,11 +204,6 @@ deviceNameText.value = ''; }; const resetFormAndValidate = () => { resetForm(); clearValidate(); }; // 扫描二维码功能 const startScan = () => { if (isScanning.value) { @@ -313,18 +308,37 @@ const sendForm = async () => { try { // 手动验证表单 await formRef.value?.validate(); let isValid = true; let errorMessage = ''; if (!form.value.deviceLedgerId) { isValid = false; errorMessage = '请选择设备名称'; } else if (!form.value.repairTime || form.value.repairTime.trim() === '') { isValid = false; errorMessage = '请选择报修日期'; } else if (!form.value.repairName || form.value.repairName.trim() === '') { isValid = false; errorMessage = '请输入报修人'; } else if (!form.value.remark || form.value.remark.trim() === '') { isValid = false; errorMessage = '请输入故障现象'; } if (!isValid) { showToast(errorMessage); return; } loading.value = true; const id = getPageId(); // 准备提交数据 const submitData = { ...form.value }; const { code } = id ? await editRepair({ id: id, ...submitData }) : await addRepair(submitData); if (code == 200) { showToast(`${id ? "编辑" : "新增"}报修成功`); setTimeout(() => { src/pages/index.vue
@@ -433,8 +433,22 @@ background: linear-gradient(135deg, #f8f9fa 0%, #e3f2fd 100%); min-height: 100vh; padding: 1.25rem; padding-top: env(safe-area-inset-top); /* 为所有设备设置基础padding-top */ padding-top: 40px; position: relative; /* iOS设备使用env()函数处理安全区域 */ padding-top: env(safe-area-inset-top); /* 为安卓设备设置更大的顶部内边距 */ /* #ifdef APP-PLUS && !MP && !H5 */ padding-top: 45px; /* #endif */ /* H5和小程序平台的通用样式 */ /* #ifdef H5 || MP */ padding-top: 30px; /* #endif */ &::before { content: ''; @@ -462,11 +476,13 @@ } } /* 本页不再定义 .safe-area-top,已移至全局样式 */ .header-section { margin-bottom: 1rem; animation: fadeInDown 0.6s ease-out; /* 为安卓设备额外调整头部位置 */ /* #ifdef APP-PLUS && !MP && !H5 */ margin-top: 10px; /* #endif */ } .currentFactory { src/pages/mine.vue
@@ -150,9 +150,23 @@ .mine-page { min-height: 100vh; padding: 1.25rem; padding-top: env(safe-area-inset-top); /* 为所有设备设置基础padding-top */ padding-top: 40px; position: relative; background: linear-gradient( 225deg, #E7F1FF 0%, rgba(255,255,255,0) 74%, rgba(255,255,255,0) 100%); /* iOS设备使用env()函数处理安全区域 */ padding-top: env(safe-area-inset-top); /* 为安卓设备设置更大的顶部内边距 */ /* #ifdef APP-PLUS && !MP && !H5 */ padding-top: 45px; /* #endif */ /* H5和小程序平台的通用样式 */ /* #ifdef H5 || MP */ padding-top: 30px; /* #endif */ } /* 顶部个人信息卡 */ @@ -162,6 +176,11 @@ align-items: center; color: #333; margin: 1.25rem 0; /* 为安卓设备额外调整卡片位置 */ /* #ifdef APP-PLUS && !MP && !H5 */ margin-top: 15px; /* #endif */ .left { display: flex; src/pages/procurementManagement/invoiceEntry/index.vue
@@ -171,26 +171,6 @@ position: relative; } .page-header { background: #ffffff; padding: 16px 20px; display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid #f0f0f0; position: sticky; /* 兼容 iOS 刘海/灵动岛安全区 */ padding-top: env(safe-area-inset-top); top: 0; z-index: 100; } .header-left { display: flex; align-items: center; gap: 8px; } .nav-icon { width: 24px; height: 24px; src/pages/sales/invoicingRegistration/index.vue
@@ -178,26 +178,6 @@ position: relative; } .page-header { background: #ffffff; padding: 16px 20px; display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid #f0f0f0; position: sticky; /* 兼容 iOS 刘海/灵动岛安全区 */ padding-top: env(safe-area-inset-top); top: 0; z-index: 100; } .header-left { display: flex; align-items: center; gap: 8px; } .nav-icon { width: 24px; height: 24px; src/pages/sales/salesAccount/detail.vue
@@ -17,7 +17,7 @@ > <up-input v-model="form.salesman" readonly="" readonly @click="showPicker = true" placeholder="点击选择业务员" />