zjk
2026-06-20 21d969d8dc09db6ef551b0506a13b32547f1bffa
feat(forms): 完善多页面表单输入校验,限制非法字符输入
18个文件已修改
122 ■■■■■ 已修改文件
src/views/operations/attendance/statistics/index.vue 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/operations/cruiseCheckInDetails/index.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/operations/cruiseCheckInRule/index.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/operations/personnel/personnelManagement/index.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/operations/personnel/safetyOfficerInfo/index.vue 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/accountPermission/permissionGroup/form.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/testDemo/testPlanList/detail.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/testDemo/testPlanList/index.vue 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/testDemo/testPlanManagement/detail.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/transaction/directServiceManagement/index.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/transaction/order/evaluationRecord/index.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/transaction/order/orderManagement/index.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/userContent/active/activityManagement/components/ActivityOrderList.vue 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/userContent/active/activityManagement/components/ReceiveRecord.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/userContent/contentCenter/agreementAuthorizationRecord.vue 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/userContent/whitelistManagement/invitationCode/index.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/userContent/whitelistManagement/whitelist/detail.vue 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/userContent/whitelistManagement/whitelist/index.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/operations/attendance/statistics/index.vue
@@ -7,7 +7,7 @@
import { exportClockInStatistics, getClockInStatisticsList } from '@/service/api/attendance'
import { fetchRoleList } from '@/service/api/fleet'
import { NButton, NTag } from 'naive-ui'
import { downloadFile } from '@/utils'
import { downloadFile, onlyAllowNumber } from '@/utils'
import SearchPanel from '@/components/custom/SearchPanel.vue'
import dayjs from 'dayjs'
@@ -144,22 +144,22 @@
  {
    label: '应打卡天数',
    path: 'shouldClockInDays',
    render: () => <n-input v-model:value={searchModel.value.shouldClockInDays} placeholder="请输入" clearable />,
    render: () => <n-input v-model:value={searchModel.value.shouldClockInDays} placeholder="请输入" clearable allow-input={onlyAllowNumber} />,
  },
  {
    label: '正常',
    path: 'clockInDays',
    render: () => <n-input v-model:value={searchModel.value.clockInDays} placeholder="请输入" clearable />,
    render: () => <n-input v-model:value={searchModel.value.clockInDays} placeholder="请输入" clearable allow-input={onlyAllowNumber} />,
  },
  {
    label: '缺卡',
    path: 'notClockInDays',
    render: () => <n-input v-model:value={searchModel.value.notClockInDays} placeholder="请输入" clearable />,
    render: () => <n-input v-model:value={searchModel.value.notClockInDays} placeholder="请输入" clearable allow-input={onlyAllowNumber} />,
  },
  {
    label: '迟到',
    path: 'lateEarly',
    render: () => <n-input v-model:value={searchModel.value.lateEarly} placeholder="请输入" clearable />,
    render: () => <n-input v-model:value={searchModel.value.lateEarly} placeholder="请输入" clearable allow-input={onlyAllowNumber} />,
  },
])
src/views/operations/cruiseCheckInDetails/index.vue
@@ -9,6 +9,7 @@
import dayjs from 'dayjs'
import { exportCruiseCheckInRecord, fetchCruiseCheckInRecordList } from '@/service/api/maintenance'
import { downloadFile } from '@/utils/common'
import { onlyAllowNumber } from '@/utils'
const router = useRouter()
@@ -234,7 +235,7 @@
  {
    label: '手机号',
    path: 'phoneNumber',
    render: () => <n-input v-model:value={model.value.phoneNumber} placeholder="请输入" clearable />,
    render: () => <n-input v-model:value={model.value.phoneNumber} placeholder="请输入" clearable allow-input={onlyAllowNumber} />,
  },
  {
    label: '打卡日期',
src/views/operations/cruiseCheckInRule/index.vue
@@ -4,6 +4,7 @@
import type { DataTableColumns } from 'naive-ui'
import { useBoolean } from '@/hooks'
import { NButton } from 'naive-ui'
import { onlyAllowNumber } from '@/utils'
import SearchPanel from '@/components/custom/SearchPanel.vue'
import OperationLogModal from '@/components/custom/OperationLogModal.vue'
import DetailModal from './components/DetailModal.vue'
@@ -137,17 +138,17 @@
  {
    label: '手机号',
    path: 'phoneNumber',
    render: () => <n-input v-model:value={model.value.phoneNumber} placeholder="请输入" clearable />,
    render: () => <n-input v-model:value={model.value.phoneNumber} placeholder="请输入" clearable allow-input={onlyAllowNumber} />,
  },
  {
    label: '关联点位',
    path: 'pointNum',
    render: () => <n-input v-model:value={model.value.pointNum} placeholder="请输入" clearable />,
    render: () => <n-input v-model:value={model.value.pointNum} placeholder="请输入" clearable allow-input={onlyAllowNumber} />,
  },
  {
    label: '执行人数',
    path: 'userNumber',
    render: () => <n-input v-model:value={model.value.userNumber} placeholder="请输入" clearable />,
    render: () => <n-input v-model:value={model.value.userNumber} placeholder="请输入" clearable allow-input={onlyAllowNumber} />,
  },
])
src/views/operations/personnel/personnelManagement/index.vue
@@ -7,7 +7,7 @@
import { NButton, NDropdown, NSwitch, NTag, NTooltip } from 'naive-ui'
import { addOperationsUser, deleteOperationsUser, editOperationsUser, exportOperationsUser, exportOperationsUserTemplate, getOperationsUserList, importOperationsUser, updateOperationsUserStatus } from '@/service/api/attendance'
import { fetchRoleList } from '@/service/api/fleet'
import { downloadFile } from '@/utils'
import { downloadFile, onlyAllowNumber, onlyAllowNumberAndLetter } from '@/utils'
import SearchPanel from '@/components/custom/SearchPanel.vue'
import OperationLogModal from '@/components/custom/OperationLogModal.vue'
import PersonnelFormModal from './components/PersonnelFormModal.vue'
@@ -223,7 +223,7 @@
  {
    label: '联系电话',
    path: 'phoneNumber',
    render: () => <n-input v-model:value={searchModel.value.phoneNumber} placeholder="请输入" clearable />,
    render: () => <n-input v-model:value={searchModel.value.phoneNumber} placeholder="请输入" clearable allow-input={onlyAllowNumber} />,
  },
  {
    label: '角色',
@@ -292,7 +292,7 @@
  {
    label: '编号',
    path: 'uniqueNumber',
    render: () => <n-input v-model:value={searchModel.value.uniqueNumber} placeholder="请输入" clearable />,
    render: () => <n-input v-model:value={searchModel.value.uniqueNumber} placeholder="请输入" clearable allow-input={onlyAllowNumberAndLetter} />,
  },
  {
    label: '创建时间',
src/views/operations/personnel/safetyOfficerInfo/index.vue
@@ -10,7 +10,7 @@
import Pagination from '@/components/common/Pagination.vue'
import OperationLogModal from '@/components/custom/OperationLogModal.vue'
import { exportSafetyOfficer, exportSafetyOfficerTemplate, getSafetyOfficerList, importSafetyOfficer, updateSafetyOfficerStatus } from '@/service/api/attendance'
import { downloadFile } from '@/utils'
import { downloadFile, onlyAllowNumber, onlyAllowNumberAndLetter } from '@/utils'
interface SafetyOfficerItem {
  id: number
@@ -266,7 +266,7 @@
  {
    label: 'ID',
    path: 'id',
    render: () => <n-input v-model:value={searchModel.value.id} placeholder="请输入" clearable />,
    render: () => <n-input v-model:value={searchModel.value.id} placeholder="请输入" clearable allow-input={onlyAllowNumber} />,
  },
  {
    label: '安全员姓名',
@@ -276,17 +276,17 @@
  {
    label: '身份证号',
    path: 'idCardNo',
    render: () => <n-input v-model:value={searchModel.value.idCardNo} placeholder="请输入" clearable />,
    render: () => <n-input v-model:value={searchModel.value.idCardNo} placeholder="请输入" clearable allow-input={onlyAllowNumberAndLetter} />,
  },
  {
    label: '联系电话',
    path: 'phoneNumber',
    render: () => <n-input v-model:value={searchModel.value.phoneNumber} placeholder="请输入" clearable />,
    render: () => <n-input v-model:value={searchModel.value.phoneNumber} placeholder="请输入" clearable allow-input={onlyAllowNumber} />,
  },
  {
    label: '机动车驾驶证号',
    path: 'drivingLicenseNo',
    render: () => <n-input v-model:value={searchModel.value.drivingLicenseNo} placeholder="请输入" clearable />,
    render: () => <n-input v-model:value={searchModel.value.drivingLicenseNo} placeholder="请输入" clearable allow-input={onlyAllowNumberAndLetter} />,
  },
  {
    label: '创建时间',
src/views/system/accountPermission/permissionGroup/form.vue
@@ -4,6 +4,7 @@
import SearchPanel from '@/components/custom/SearchPanel.vue'
import Pagination from '@/components/common/Pagination.vue'
import { useTabStore } from '@/store'
import { onlyAllowNumber } from '@/utils'
import {
  createPermissionGroup,
  fetchGroupUserPageList,
@@ -153,7 +154,7 @@
  {
    label: t('permissionGroup.userSearch.userPhone'),
    path: 'phoneNumber',
    render: () => <n-input v-model:value={userSearchModel.phoneNumber} placeholder={t('permissionGroup.placeholder.groupName')} clearable />,
    render: () => <n-input v-model:value={userSearchModel.phoneNumber} placeholder={t('permissionGroup.placeholder.groupName')} clearable allow-input={onlyAllowNumber} />,
  },
])
src/views/testDemo/testPlanList/detail.vue
@@ -12,6 +12,7 @@
import dragIcon from '@/assets/point/union.png'
import { deleteCruiseOrder, editCruisePlan, exportCruiseOrderExcel, fetchCruiseOrderPageList, fetchCruisePlanDetail } from '@/service/api/copyText'
import { downloadFile } from '@/utils/common'
import { onlyAllowNumberAndLetter } from '@/utils'
const router = useRouter()
const route = useRoute()
@@ -402,7 +403,7 @@
  {
    label: '订单号',
    path: 'id',
    render: () => <n-input v-model:value={recordSearch.value.id} placeholder="请输入" clearable />,
    render: () => <n-input v-model:value={recordSearch.value.id} placeholder="请输入" clearable allow-input={onlyAllowNumberAndLetter} />,
  },
  {
    label: '车牌号',
src/views/testDemo/testPlanList/index.vue
@@ -9,6 +9,7 @@
import SearchPanel from '@/components/custom/SearchPanel.vue'
import { useBoolean } from '@/hooks'
import { deleteTestPlanById, fetchTestPlanPageList } from '@/service/api/copyText'
import { onlyAllowNumber } from '@/utils'
const router = useRouter()
const dialog = useDialog()
@@ -209,21 +210,19 @@
function renderRange(minKey: keyof typeof initialModel, maxKey: keyof typeof initialModel) {
  return (
    <div class="flex items-center gap-8px">
      <n-input-number
      <n-input
        v-model:value={model.value[minKey]}
        placeholder="请输入最小值"
        clearable
        precision={0}
        show-button={false}
        class="flex-1"
        allow-input={onlyAllowNumber}
      />
      <span>~</span>
      <n-input-number
      <n-input
        v-model:value={model.value[maxKey]}
        placeholder="请输入最大值"
        clearable
        precision={0}
        show-button={false}
        allow-input={onlyAllowNumber}
        class="flex-1"
      />
    </div>
src/views/testDemo/testPlanManagement/detail.vue
@@ -7,6 +7,7 @@
import Pagination from '@/components/common/Pagination.vue'
import SearchPanel from '@/components/custom/SearchPanel.vue'
import { downloadFile } from '@/utils/common'
import { onlyAllowNumberAndLetter } from '@/utils'
import {
  cancelTestPlanOrder,
  closeTestPlanOrder,
@@ -176,7 +177,7 @@
  {
    label: '订单号',
    path: 'orderNo',
    render: () => <n-input v-model:value={searchModel.value.orderNo} placeholder="请输入" clearable />,
    render: () => <n-input v-model:value={searchModel.value.orderNo} placeholder="请输入" clearable allow-input={onlyAllowNumberAndLetter} />,
  },
  {
    label: '起点',
src/views/transaction/directServiceManagement/index.vue
@@ -11,6 +11,7 @@
import { useRouter } from 'vue-router'
import Pagination from '@/components/common/Pagination.vue'
import OperationLogModal from '@/components/custom/OperationLogModal.vue'
import { onlyAllowNumber } from '@/utils'
const { bool: loading, setTrue: startLoading, setFalse: endLoading } = useBoolean(false)
const message = useMessage()
@@ -130,12 +131,12 @@
  {
    label: '绑定车辆数',
    path: 'vehicleCount',
    render: () => <n-input v-model:value={model.value.vehicleCount} placeholder="请输入" clearable />,
    render: () => <n-input v-model:value={model.value.vehicleCount} placeholder="请输入" clearable allow-input={onlyAllowNumber} />,
  },
  {
    label: '绑定用户数',
    path: 'whitelistCount',
    render: () => <n-input v-model:value={model.value.whitelistCount} placeholder="请输入" clearable />,
    render: () => <n-input v-model:value={model.value.whitelistCount} placeholder="请输入" clearable allow-input={onlyAllowNumber} />,
  },
  {
    label: '状态',
src/views/transaction/order/evaluationRecord/index.vue
@@ -4,6 +4,7 @@
import { useBoolean } from '@/hooks'
import { getOrderEvaluateList } from '@/service/api/transaction'
import { NButton } from 'naive-ui'
import { onlyAllowNumber, onlyAllowNumberAndLetter } from '@/utils'
import SearchPanel from '@/components/custom/SearchPanel.vue'
import dayjs from 'dayjs'
@@ -126,7 +127,7 @@
  {
    label: '用户电话',
    path: 'phoneNumber',
    render: () => <n-input v-model:value={model.value.phoneNumber} />,
    render: () => <n-input v-model:value={model.value.phoneNumber} allow-input={onlyAllowNumber} />,
  },
  {
    label: '评价等级',
@@ -177,7 +178,7 @@
  {
    label: '关联订单号',
    path: 'orderNumber',
    render: () => <n-input v-model:value={model.value.orderNumber} />,
    render: () => <n-input v-model:value={model.value.orderNumber} allow-input={onlyAllowNumberAndLetter} />,
  },
])
src/views/transaction/order/orderManagement/index.vue
@@ -10,7 +10,7 @@
import SearchPanel from '@/components/custom/SearchPanel.vue'
import OperationLogModal from '@/components/custom/OperationLogModal.vue'
import dayjs from 'dayjs'
import { downloadFile } from '@/utils'
import { downloadFile, onlyAllowNumberAndLetter } from '@/utils'
import TableModal from './components/TableModal.vue'
// import ReassignModal from './components/ReassignModal.vue'
import CloseOrderModal from './components/CloseOrderModal.vue'
@@ -452,12 +452,13 @@
]
const pcaOptions = ref<any[]>([])
const onlyAllowDecimal = (value: string) => !value || /^\d*(?:\.\d{0,2})?$/.test(value)
// 搜索项
const filterItems = computed(() => [
  {
    label: t('transaction.orderNo'),
    path: 'orderNumber',
    render: () => <n-input v-model:value={model.value.orderNumber} />,
    render: () => <n-input v-model:value={model.value.orderNumber} allow-input={onlyAllowNumberAndLetter} />,
  },
  {
    label: t('transaction.userName'),
@@ -635,7 +636,7 @@
  {
    label: t('transaction.orderAmount'),
    path: 'orderMoney',
    render: () => <n-input v-model:value={model.value.orderMoney} />,
    render: () => <n-input v-model:value={model.value.orderMoney} allow-input={onlyAllowDecimal} />,
  },
])
src/views/userContent/active/activityManagement/components/ActivityOrderList.vue
@@ -17,7 +17,7 @@
import SearchPanel from '@/components/custom/SearchPanel.vue'
import Pagination from '@/components/common/Pagination.vue'
import { getRegionCascaderNoArea } from '@/service/api/operations'
import { downloadFile } from '@/utils'
import { downloadFile, onlyAllowNumber, onlyAllowNumberAndLetter } from '@/utils'
import dayjs from 'dayjs'
const props = defineProps({
@@ -138,6 +138,13 @@
    .replace('$#$', '.')
    .replace(/^(\d+)\.(\d{0,2}).*$/, '$1.$2')
  searchModel.value[field] = normalizedValue
}
function onlyAllowDecimal(value: string) {
  if (!value)
    return true
  return /^\d*(?:\.\d{0,2})?$/.test(value)
}
function handleCheck(keys: string[]) {
@@ -261,7 +268,7 @@
  {
    label: '订单号',
    path: 'orderNumber',
    render: () => <NInput v-model:value={searchModel.value.orderNumber} placeholder="请输入" clearable />,
    render: () => <NInput v-model:value={searchModel.value.orderNumber} placeholder="请输入" clearable allow-input={onlyAllowNumberAndLetter} />,
  },
  {
    label: '用户',
@@ -271,7 +278,7 @@
  {
    label: '下单用户手机',
    path: 'phoneNumber',
    render: () => <NInput v-model:value={searchModel.value.phoneNumber} placeholder="请输入" clearable />,
    render: () => <NInput v-model:value={searchModel.value.phoneNumber} placeholder="请输入" clearable allow-input={onlyAllowNumber} />,
  },
  {
    label: '车辆',
@@ -444,6 +451,7 @@
        value={searchModel.value.orderMoney}
        placeholder="请输入"
        clearable
        allow-input={onlyAllowDecimal}
        onUpdateValue={value => handleAmountInput('orderMoney', value)}
      />
    ),
src/views/userContent/active/activityManagement/components/ReceiveRecord.vue
@@ -19,6 +19,7 @@
import { fetchCouponActivityReceiptRecord } from '@/service/api/coupon'
import SearchPanel from '@/components/custom/SearchPanel.vue'
import Pagination from '@/components/common/Pagination.vue'
import { onlyAllowNumber } from '@/utils'
import dayjs from 'dayjs'
const props = defineProps({
@@ -194,6 +195,7 @@
        value={searchModel.value.num}
        placeholder="请输入"
        clearable
        allow-input={onlyAllowNumber}
        onUpdateValue={handleReceiveNumInput}
      />
    ),
src/views/userContent/contentCenter/agreementAuthorizationRecord.vue
@@ -32,6 +32,20 @@
const count = ref(0)
const listData = ref<any[]>([])
function onlyAllowVersion(value: string) {
  if (!value)
    return true
  return /^[a-z0-9.]+$/i.test(value)
}
function onlyAllowIp(value: string) {
  if (!value)
    return true
  return /^\d+(?:\.\d*){0,3}$/.test(value) || /^\d*(?:\.\d*){0,3}$/.test(value)
}
const filterItems = computed(() => [
  {
    label: '协议标题',
@@ -51,12 +65,12 @@
  {
    label: '协议版本号',
    path: 'version',
    render: () => <NInput v-model:value={model.value.version} placeholder="请输入" />,
    render: () => <NInput v-model:value={model.value.version} placeholder="请输入" allow-input={onlyAllowVersion} />,
  },
  {
    label: '授权IP',
    path: 'authorizationIp',
    render: () => <NInput v-model:value={model.value.authorizationIp} placeholder="请输入" />,
    render: () => <NInput v-model:value={model.value.authorizationIp} placeholder="请输入" allow-input={onlyAllowIp} />,
  },
  {
    label: '授权时间',
src/views/userContent/whitelistManagement/invitationCode/index.vue
@@ -3,7 +3,7 @@
import type { DataTableColumns } from 'naive-ui'
import { NButton, useDialog, useMessage } from 'naive-ui'
import { useBoolean } from '@/hooks'
import { downloadFile } from '@/utils'
import { downloadFile, onlyAllowNumberAndLetter } from '@/utils'
import SearchPanel from '@/components/custom/SearchPanel.vue'
import OperationLogModal from '@/components/custom/OperationLogModal.vue'
import { deleteInvitationCodes, exportInvitationExcel, getInvitationPageList, getInvitationTemplate, importInvitationExcel } from '@/service'
@@ -42,12 +42,12 @@
  {
    label: '邀请码',
    path: 'invitationCode',
    render: () => <n-input v-model:value={model.value.invitationCode} placeholder="请输入" clearable />,
    render: () => <n-input v-model:value={model.value.invitationCode} placeholder="请输入" clearable allow-input={onlyAllowNumberAndLetter} />,
  },
  {
    label: '绑定账号',
    path: 'bindAccount',
    render: () => <n-input v-model:value={model.value.bindAccount} placeholder="请输入" clearable />,
    render: () => <n-input v-model:value={model.value.bindAccount} placeholder="请输入" clearable allow-input={onlyAllowNumberAndLetter} />,
  },
  {
    label: '创建时间',
src/views/userContent/whitelistManagement/whitelist/detail.vue
@@ -26,7 +26,7 @@
import { getRegionCascaderNoArea } from '@/service/api/operations'
import { deleteWhitelistActivityByIds, fetchWhitelistActivityPageList, fetchWhitelistDetail } from '@/service/api/whitelist'
import dayjs from 'dayjs'
import { downloadFile } from '@/utils'
import { downloadFile, onlyAllowNumberAndLetter } from '@/utils'
// 基础定义
const route = useRoute()
@@ -321,7 +321,7 @@
  {
    label: '订单号',
    path: 'orderNumber',
    render: () => <NInput v-model:value={orderSearchModel.value.orderNumber} placeholder="请输入订单编号" clearable />,
    render: () => <NInput v-model:value={orderSearchModel.value.orderNumber} placeholder="请输入订单编号" clearable allow-input={onlyAllowNumberAndLetter} />,
  },
  {
    label: '车辆',
src/views/userContent/whitelistManagement/whitelist/index.vue
@@ -20,6 +20,7 @@
import Pagination from '@/components/common/Pagination.vue'
import dayjs from 'dayjs'
import { useRouter } from 'vue-router'
import { onlyAllowNumber, onlyAllowNumberAndLetter } from '@/utils'
// 路由实例,用于从列表跳转到白名单详情页。
const router = useRouter()
@@ -106,6 +107,7 @@
        placeholder="请输入最小值"
        clearable
        class="flex-1"
        allow-input={onlyAllowNumber}
        onUpdateValue={value => handlePositiveIntegerInput(value, minKey)}
      />
      <span>~</span>
@@ -114,6 +116,7 @@
        placeholder="请输入最大值"
        clearable
        class="flex-1"
        allow-input={onlyAllowNumber}
        onUpdateValue={value => handlePositiveIntegerInput(value, maxKey)}
      />
    </div>
@@ -138,7 +141,7 @@
  {
    label: '白名单账号',
    path: 'account',
    render: () => <n-input v-model:value={model.value.account} placeholder="请输入" />,
    render: () => <n-input v-model:value={model.value.account} placeholder="请输入" allow-input={onlyAllowNumberAndLetter} />,
  },
  {
    label: '来源',