gaoluyang
昨天 77861fcc5ee1c4f8e7c6412b373cb438c7313930
头部样式修改、适配不同机型
已修改10个文件
475 ■■■■■ 文件已修改
src/components/PageHeader.vue 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/cooperativeOffice/clientVisit/detail.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/equipmentManagement/ledger/detail.vue 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/equipmentManagement/ledger/index.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/equipmentManagement/repair/add.vue 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/index.vue 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/mine.vue 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/procurementManagement/invoiceEntry/index.vue 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/sales/invoicingRegistration/index.vue 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/sales/salesAccount/detail.vue 2 ●●● 补丁 | 查看 | 原始文档 | 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="点击选择业务员"
                />