feat(forms): 完善多页面表单输入校验,限制非法字符输入
| | |
| | | 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' |
| | | |
| | |
| | | { |
| | | 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} />, |
| | | }, |
| | | ]) |
| | | |
| | |
| | | import dayjs from 'dayjs' |
| | | import { exportCruiseCheckInRecord, fetchCruiseCheckInRecordList } from '@/service/api/maintenance' |
| | | import { downloadFile } from '@/utils/common' |
| | | import { onlyAllowNumber } from '@/utils' |
| | | |
| | | const router = useRouter() |
| | | |
| | |
| | | { |
| | | 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: '打卡日期', |
| | |
| | | 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' |
| | |
| | | { |
| | | 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} />, |
| | | }, |
| | | ]) |
| | | |
| | |
| | | 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' |
| | |
| | | { |
| | | 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: '角色', |
| | |
| | | { |
| | | 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: '创建时间', |
| | |
| | | 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 |
| | |
| | | { |
| | | 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: '安全员姓名', |
| | |
| | | { |
| | | 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: '创建时间', |
| | |
| | | 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, |
| | |
| | | { |
| | | 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} />, |
| | | }, |
| | | ]) |
| | | |
| | |
| | | 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() |
| | |
| | | { |
| | | 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: '车牌号', |
| | |
| | | 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() |
| | |
| | | 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> |
| | |
| | | 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, |
| | |
| | | { |
| | | 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: '起点', |
| | |
| | | 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() |
| | |
| | | { |
| | | 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: '状态', |
| | |
| | | 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' |
| | | |
| | |
| | | { |
| | | 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: '评价等级', |
| | |
| | | { |
| | | label: '关联订单号', |
| | | path: 'orderNumber', |
| | | render: () => <n-input v-model:value={model.value.orderNumber} />, |
| | | render: () => <n-input v-model:value={model.value.orderNumber} allow-input={onlyAllowNumberAndLetter} />, |
| | | }, |
| | | ]) |
| | | |
| | |
| | | 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' |
| | |
| | | ] |
| | | |
| | | 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'), |
| | |
| | | { |
| | | 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} />, |
| | | }, |
| | | ]) |
| | | |
| | |
| | | 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({ |
| | |
| | | .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[]) { |
| | |
| | | { |
| | | 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: '用户', |
| | |
| | | { |
| | | 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: '车辆', |
| | |
| | | value={searchModel.value.orderMoney} |
| | | placeholder="请输入" |
| | | clearable |
| | | allow-input={onlyAllowDecimal} |
| | | onUpdateValue={value => handleAmountInput('orderMoney', value)} |
| | | /> |
| | | ), |
| | |
| | | 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({ |
| | |
| | | value={searchModel.value.num} |
| | | placeholder="请输入" |
| | | clearable |
| | | allow-input={onlyAllowNumber} |
| | | onUpdateValue={handleReceiveNumInput} |
| | | /> |
| | | ), |
| | |
| | | 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: '协议标题', |
| | |
| | | { |
| | | 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: '授权时间', |
| | |
| | | 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' |
| | |
| | | { |
| | | 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: '创建时间', |
| | |
| | | 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() |
| | |
| | | { |
| | | 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: '车辆', |
| | |
| | | import Pagination from '@/components/common/Pagination.vue' |
| | | import dayjs from 'dayjs' |
| | | import { useRouter } from 'vue-router' |
| | | import { onlyAllowNumber, onlyAllowNumberAndLetter } from '@/utils' |
| | | |
| | | // 路由实例,用于从列表跳转到白名单详情页。 |
| | | const router = useRouter() |
| | |
| | | placeholder="请输入最小值" |
| | | clearable |
| | | class="flex-1" |
| | | allow-input={onlyAllowNumber} |
| | | onUpdateValue={value => handlePositiveIntegerInput(value, minKey)} |
| | | /> |
| | | <span>~</span> |
| | |
| | | placeholder="请输入最大值" |
| | | clearable |
| | | class="flex-1" |
| | | allow-input={onlyAllowNumber} |
| | | onUpdateValue={value => handlePositiveIntegerInput(value, maxKey)} |
| | | /> |
| | | </div> |
| | |
| | | { |
| | | 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: '来源', |