src/router/routes.static.ts
@@ -1379,7 +1379,7 @@ { name: 'addCruiseCheckInRule', path: '/operations/cruiseCheckInManagement/cruiseCheckInRule/add', title: '新增打卡规则', title: '新增巡游打卡规则', requiresAuth: true, icon: 'icon-park-outline:list-view', menuType: 'page', src/views/operations/attendance/address/components/AddressFormModal.vue
@@ -8,6 +8,7 @@ const props = defineProps<{ show: boolean mode?: 'add' | 'edit' title?: string type?: number }>() @@ -316,7 +317,7 @@ <template> <n-modal v-model:show="show" :mask-closable="false" preset="card" :title="mode === 'edit' ? '编辑打卡地址' : '新增打卡地址'" v-model:show="show" :mask-closable="false" preset="card" :title="mode === 'edit' ? `编辑${title}` : `新增${title}`" class="w-600px" :auto-focus="false" :segmented="{ content: true, action: true, src/views/operations/attendance/address/index.vue
@@ -312,7 +312,7 @@ /> </div> <AddressFormModal ref="modalRef" v-model:show="showFormModal" :mode="formMode" @confirm="handleConfirmForm" /> <AddressFormModal ref="modalRef" v-model:show="showFormModal" title="打卡地" :mode="formMode" @confirm="handleConfirmForm" /> </n-card> </div> </template> src/views/operations/cruiseCheckIn/index.vue
@@ -1,8 +1,8 @@ <script setup lang="tsx"> import type { DataTableColumns } from 'naive-ui' import { useBoolean } from '@/hooks' import { NButton, NTag } from 'naive-ui' import { addCheckLocation, deleteCheckLocation, editCheckLocation, getCheckLocationList } from '@/service/api/attendance' import { NButton, NSwitch, NTag } from 'naive-ui' import { addCheckLocation, deleteCheckLocation, editCheckLocation, getCheckLocationList, updateCheckLocationStatus } from '@/service/api/attendance' import SearchPanel from '@/components/custom/SearchPanel.vue' import AddressFormModal from '@/views/operations/attendance/address/components/AddressFormModal.vue' import dayjs from 'dayjs' @@ -31,6 +31,28 @@ function handleSearch() { pageParams.value.pageNum = 1 getList() } async function handleSwitchChange(row: any) { dialog.warning({ title: `是否确认${row.status === 1 ? '禁用' : '启用'}打卡地?`, content: '', positiveText: '确认', negativeText: '取消', maskClosable: false, autoFocus: false, onPositiveClick: async () => { updateCheckLocationStatus({ id: row.id, status: row.status === 1 ? 0 : 1 }).then((res) => { if (res.code === 200) { window.$message.success('操作成功') getList() } }) }, onNegativeClick: () => { getList() }, }) } const tableScrollX = computed(() => Math.min(1600, 70 + 180 + 360 + 120 + 200)) @@ -89,7 +111,7 @@ { title: '操作', key: 'actions', width: 70, width: 140, align: 'left', render: (row) => { return ( @@ -108,6 +130,18 @@ > 删除 </span> <NSwitch v-permission="70214" value={row.status} checked-value={1} unchecked-value={0} onUpdateValue={() => handleSwitchChange(row)} > {{ checked: () => '启用', unchecked: () => '禁用', }} </NSwitch> </div> ) }, @@ -253,7 +287,7 @@ /> </div> <AddressFormModal ref="modalRef" v-model:show="showFormModal" :mode="formMode" :type="2" @confirm="handleConfirmForm" /> <AddressFormModal ref="modalRef" v-model:show="showFormModal" title="巡游打卡地" :mode="formMode" :type="2" @confirm="handleConfirmForm" /> </n-card> </div> </template> src/views/operations/cruiseCheckInDetails/detail.vue
@@ -154,10 +154,23 @@ <div class="col-span-1 md:col-span-3 flex items-start"> <span class="label">现场照片:</span> <div v-if="detailInfo?.scenePhoto" class="flex gap-16px flex-wrap"> <img <!-- <img v-for="(item, idx) in JSON.parse(detailInfo.scenePhoto)" :key="idx" :src="item.url" class="w-182px h-120px" @error="(e: any) => { e.target.src = 'https://huishou-1323682843.cos.ap-nanjing.myqcloud.com/images/9bed493b-a6aa-4ef6-ac10-7f67f5c6adc5.png' }" > > --> <n-image-group> <div class="flex flex-wrap gap-2"> <n-image v-for="item in JSON.parse(detailInfo.scenePhoto)" :key="item.id || item.url" :src="item.url" width="182" height="120" class="rounded-lg" fallback-src="https://huishou-1323682843.cos.ap-nanjing.myqcloud.com/images/9bed493b-a6aa-4ef6-ac10-7f67f5c6adc5.png" /> </div> </n-image-group> </div> <span v-else class="value">-</span> </div> src/views/operations/cruiseCheckInRule/add.vue
@@ -47,6 +47,7 @@ } const checkInPoints = ref<CheckInPoint[]>([]) const editingPointId = ref<number | null>(null) const draggedPointId = ref<number | null>(null) const executorOptions = ref<Array<{ label: string, value: number }>>([]) @@ -74,18 +75,17 @@ title: '打卡地', key: 'name', ellipsis: true, width: 300, }, { title: '打卡范围', key: 'range', width: 160, ellipsis: true, }, { title: '打卡限时', key: 'timeLimit', width: 180, ellipsis: true, }, { title: '操作', @@ -165,6 +165,7 @@ } function handleAddPoint() { editingPointId.value = null showSelectModal.value = true } @@ -174,23 +175,33 @@ message.warning('打卡点数据异常,请重试') return } const existed = checkInPoints.value.some(item => item.pointId === pointId) const currentEditId = Number(pointData?.id ?? 0) || null const existed = checkInPoints.value.some(item => item.pointId === pointId && item.id !== currentEditId) if (existed) { message.warning('该打卡点已添加') return } checkInPoints.value.push({ const nextPoint: CheckInPoint = { id: Number(pointData?.id ?? Date.now()), pointId, name: pointData?.name || '-', range: pointData?.range || '-', timeLimit: pointData?.timeLimit || '-', }) } const editIndex = checkInPoints.value.findIndex(item => item.id === nextPoint.id) if (editIndex > -1) checkInPoints.value.splice(editIndex, 1, nextPoint) else checkInPoints.value.push(nextPoint) editingPointId.value = null } function handleEditPoint(point: CheckInPoint) { message.info(`点击了编辑点位:${point.name}`) editingPointId.value = point.id showSelectModal.value = true } function handleRemovePoint(point: CheckInPoint) { @@ -302,7 +313,7 @@ <n-form-item label="任务起止日期" path="taskDateRange" class="mb-0"> <n-date-picker v-model:value="basicFormModel.taskDateRange" type="daterange" clearable class="flex-1" placeholder="请选择起止日期" format="yyyy/MM/dd" :actions="[]" :close-on-select="true" start-placeholder="开始时间" end-placeholder="结束时间" format="yyyy/MM/dd" :actions="[]" :close-on-select="true" /> </n-form-item> @@ -334,7 +345,7 @@ 打卡点位 </div> <div class="flex gap-2"> <n-button @click="handleResetPoints"> <n-button class="w-58px" @click="handleResetPoints"> 重置 </n-button> <n-button secondary type="primary" @click="handleAddPoint"> @@ -369,7 +380,11 @@ </NButton> </NSpace> </div> <SelectPointModal v-model:show="showSelectModal" @confirm="handleConfirmSelect" /> <SelectPointModal v-model:show="showSelectModal" :edit-point="checkInPoints.find(item => item.id === editingPointId) || null" @confirm="handleConfirmSelect" /> </div> </template> src/views/operations/cruiseCheckInRule/components/DetailModal.vue
@@ -42,7 +42,7 @@ function formatDateRange(startTime?: string, endTime?: string) { const start = startTime ? dayjs(startTime).format('YYYY/MM/DD') : '-' const end = endTime ? dayjs(endTime).format('YYYY/MM/DD') : '-' return `${start} ~ ${end}` return `${start}~${end}` } function formatCycleMode(cyclicMode?: number) { @@ -70,7 +70,7 @@ detailInfo.value = { baseInfo: { ruleName: data.name || '-', associatedPerson: data.createBy || '-', associatedPerson: data.operationsUserName || '-', dateRange: formatDateRange(data.startTime, data.endTime), cycleMode: formatCycleMode(data.cyclicMode), }, @@ -116,32 +116,32 @@ <div class="head mb-16px"> 基础信息 </div> <div class="grid grid-cols-2 gap-y-16px gap-x-24px px-12px"> <div class="flex"> <span class="label-color flex-shrink-0 whitespace-nowrap">打卡规则名称:</span> <span class="value-color break-all">{{ detailInfo.baseInfo.ruleName }}</span> <div class="grid grid-cols-2 gap-y-16px gap-x-24px"> <div class="flex flex-col"> <span class="label-color flex-shrink-0 whitespace-nowrap">打卡规则名称</span> <span class="value-color break-all mt-4px">{{ detailInfo.baseInfo.ruleName }}</span> </div> <div class="flex"> <span class="label-color flex-shrink-0 whitespace-nowrap">关联人员:</span> <span class="value-color break-all">{{ detailInfo.baseInfo.associatedPerson }}</span> <div class="flex flex-col"> <span class="label-color flex-shrink-0 whitespace-nowrap">关联人员</span> <span class="value-color break-all mt-4px">{{ detailInfo.baseInfo.associatedPerson }}</span> </div> <div class="flex"> <span class="label-color flex-shrink-0 whitespace-nowrap">任务起止日期:</span> <span class="value-color break-all">{{ detailInfo.baseInfo.dateRange }}</span> <div class="flex flex-col"> <span class="label-color flex-shrink-0 whitespace-nowrap">任务起止日期</span> <span class="value-color break-all mt-4px">{{ detailInfo.baseInfo.dateRange }}</span> </div> <div class="flex"> <span class="label-color flex-shrink-0 whitespace-nowrap">循环方式:</span> <span class="value-color break-all">{{ detailInfo.baseInfo.cycleMode }}</span> <div class="flex flex-col"> <span class="label-color flex-shrink-0 whitespace-nowrap">循环方式</span> <span class="value-color break-all mt-4px">{{ detailInfo.baseInfo.cycleMode }}</span> </div> </div> </div> <!-- 打卡点位信息 --> <div> <div class="head mb-24px"> <div class="head mb-16px"> 打卡点位信息 </div> <div class="px-12px"> <div> <NDataTable :columns="columns" :data="detailInfo.pointInfoList" src/views/operations/cruiseCheckInRule/components/SelectPointModal.vue
@@ -5,6 +5,13 @@ const props = defineProps<{ show: boolean editPoint?: { id: string pointId: number timeLimit: string name?: string range?: string } | null }>() const emit = defineEmits<{ @@ -118,6 +125,34 @@ } }) watch(show, async (visible) => { if (!visible) return // 每次打开都刷新选项,避免编辑时 value 已有但 options 尚未加载导致不回显 await getPointOptions() // 编辑场景:打开弹窗时回填点位和时间段 if (props.editPoint) { const editPointId = props.editPoint.pointId || null pointId.value = editPointId // 当前点位不在下拉选项中时,补一个临时选项用于回显名称 if (editPointId && !pointOptions.value.some(item => item.value === editPointId)) { pointOptions.value.unshift({ label: props.editPoint.name || `点位${editPointId}`, value: editPointId, range: String(props.editPoint.range || '-'), }) } const timeRangeMatch = String(props.editPoint.timeLimit || '').match(/^(\d{2}:\d{2})\s*~\s*(\d{2}:\d{2})$/) startTime.value = timeRangeMatch?.[1] ?? null endTime.value = timeRangeMatch?.[2] ?? null return } // 新增场景:每次打开重置表单 pointId.value = null startTime.value = null endTime.value = null }) function handleConfirm() { if (!pointId.value) { window.$message.warning('请选择打卡点') @@ -140,7 +175,7 @@ } emit('confirm', { id: Date.now(), // Generate a temp ID for the row id: props.editPoint?.id, pointId: pointId.value, name: selectedPoint?.label, range: selectedPoint?.range, src/views/operations/personnel/personnelManagement/index.vue
@@ -363,7 +363,7 @@ { title: '操作', key: 'actions', width: 250, width: 230, fixed: 'right', align: 'left', render: row => ( src/views/system/config/index.vue
@@ -9,18 +9,20 @@ minOrderDistance: any adsorptionDistance: any arriveTime: any xczSyDistance: number xczSyTime: number xczCaCount: number xczHmSpeedPerHour: number xczHmDuration: number headShowCount: number xczSyDistance: string xczSyTime: string xczCaCount: string xczHmSpeedPerHour: string xczHmDuration: string headShowCount: string nearPointDistance: any operateFree: boolean temperatureUnit: string } const formRef = ref<FormInst | null>(null) const strategyFormRef = ref<FormInst | null>(null) const orderStrategyFormRef = ref<FormInst | null>(null) const formModel = ref<FormModel>({ customerServicePhone: '', @@ -28,12 +30,12 @@ minOrderDistance: '', adsorptionDistance: '', arriveTime: '', xczSyDistance: 0, xczSyTime: 0, xczCaCount: 0, xczHmSpeedPerHour: 0, xczHmDuration: 0, headShowCount: 0, xczSyDistance: '', xczSyTime: '', xczCaCount: '', xczHmSpeedPerHour: '', xczHmDuration: '', headShowCount: '', nearPointDistance: '', operateFree: true, temperatureUnit: '℃', @@ -41,6 +43,18 @@ const onlyAllowNumberAndDash = (value: string) => !value || /^[\d-]+$/.test(value) const isWeatherUnitOpen = ref(false) function handleHeadShowCountChange(value: string) { // 仅保留数字,并在输入阶段直接截断为最多3位,确保不超过999 const normalizedValue = value.replace(/\D/g, '').slice(0, 3) formModel.value.headShowCount = normalizedValue } function handleNearPointDistanceChange(value: string) { // 仅保留数字,并在输入阶段直接截断为最多5位,确保不超过99999 const normalizedValue = value.replace(/\D/g, '').slice(0, 5) formModel.value.nearPointDistance = normalizedValue } const rules: FormRules = { customerServicePhone: [ @@ -60,28 +74,26 @@ { required: true, min: 1, message: '请输入正整数', trigger: 'blur' }, ], xczSyDistance: [ { required: true, type: 'number', min: 0, message: '请输入正整数', trigger: 'blur' }, { required: true, message: '请输入正整数', trigger: 'blur' }, ], xczSyTime: [ { required: true, type: 'number', min: 0, message: '请输入正整数', trigger: 'blur' }, { required: true, message: '请输入正整数', trigger: 'blur' }, ], xczCaCount: [ { required: true, type: 'number', min: 0, message: '请输入正整数', trigger: 'blur' }, { required: true, message: '请输入正整数', trigger: 'blur' }, ], xczHmSpeedPerHour: [ { required: true, type: 'number', min: 0, message: '请输入正整数', trigger: 'blur' }, { required: true, message: '请输入正整数', trigger: 'blur' }, ], xczHmDuration: [ { required: true, type: 'number', min: 0, message: '请输入正整数', trigger: 'blur' }, { required: true, message: '请输入正整数', trigger: 'blur' }, ], headShowCount: [ { required: true, type: 'number', min: 0, message: '请输入正整数', trigger: 'blur' }, { type: 'number', max: 999, message: '最大999', trigger: 'blur' }, { required: true, message: '请输入正整数', trigger: 'blur' }, ], // nearPointDistance: [ // { required: true, type: 'number', min: 0, message: '请输入正整数', trigger: 'blur' }, // { type: 'number', max: 99999, message: '最大99999m', trigger: 'blur' }, // ], nearPointDistance: [ { required: true, message: '请输入正整数', trigger: 'blur' }, ], temperatureUnit: [ { required: true, message: '请选择', trigger: 'change' }, ], @@ -91,7 +103,21 @@ async function handleSave() { try { await formRef.value?.validate() // 三块表单统一校验,任意一块不通过都不允许保存 await Promise.all([ formRef.value?.validate(), strategyFormRef.value?.validate(), orderStrategyFormRef.value?.validate(), ]) // 这两个字段未单独挂载 path,补充保存前兜底校验 if (!String(formModel.value.xczSyTime ?? '').trim()) { window.$message?.warning('请输入正整数') return } if (!String(formModel.value.xczHmDuration ?? '').trim()) { window.$message?.warning('请输入正整数') return } const base = originalSetting.value || {} const payload: any = { ...base, @@ -131,19 +157,19 @@ const d = res.data originalSetting.value = d formModel.value.customerServicePhone = d.customerServicePhone ?? '' formModel.value.orderDistance = Number(d.orderDistance ?? 0) formModel.value.minOrderDistance = Number(d.minOrderDistance ?? 0) formModel.value.adsorptionDistance = Number(d.adsorptionDistance ?? 0) formModel.value.arriveTime = Number(d.arriveTime ?? 0) formModel.value.headShowCount = Math.min(999, Number(d.headShowCount ?? 0)) formModel.value.nearPointDistance = Math.min(99999, Number(d.nearPointDistance ?? 0)) formModel.value.orderDistance = d.orderDistance ? d.orderDistance.toString() : '' formModel.value.minOrderDistance = d.minOrderDistance ? d.minOrderDistance.toString() : '' formModel.value.adsorptionDistance = d.adsorptionDistance ? d.adsorptionDistance.toString() : '' formModel.value.arriveTime = d.arriveTime ? d.arriveTime.toString() : '' formModel.value.headShowCount = d.headShowCount ? d.headShowCount.toString() : '' formModel.value.nearPointDistance = d.nearPointDistance ? d.nearPointDistance.toString() : '' formModel.value.operateFree = d.operateFree formModel.value.temperatureUnit = d.temperatureUnit || '℃' formModel.value.xczSyDistance = Number(d.xczSyDistance ?? 0) formModel.value.xczSyTime = Number(d.xczSyTime ?? 0) formModel.value.xczCaCount = Number(d.xczCaCount ?? 0) formModel.value.xczHmSpeedPerHour = Number(d.xczHmSpeedPerHour ?? 0) formModel.value.xczHmDuration = Number(d.xczHmDuration ?? 0) formModel.value.xczSyDistance = d.xczSyDistance ? d.xczSyDistance.toString() : '' formModel.value.xczSyTime = d.xczSyTime ? d.xczSyTime.toString() : '' formModel.value.xczCaCount = d.xczCaCount ? d.xczCaCount.toString() : '' formModel.value.xczHmSpeedPerHour = d.xczHmSpeedPerHour ? d.xczHmSpeedPerHour.toString() : '' formModel.value.xczHmDuration = d.xczHmDuration ? d.xczHmDuration.toString() : '' } else { window.$message?.warning('获取系统配置失败') @@ -171,7 +197,7 @@ ref="formRef" :model="formModel" :rules="rules" label-placement="left" require-mark-placement="left" > <div class="form-row"> <div class="form-row gap-x-40px!"> <n-form-item label="客服电话" path="customerServicePhone" required class="row-item"> <n-input v-model:value="formModel.customerServicePhone" placeholder="请输入" style="width: 339px;" @@ -179,9 +205,10 @@ /> </n-form-item> <n-form-item label="常见问题首页展示数" path="headShowCount" required class="row-item"> <n-input-number v-model:value="formModel.headShowCount" placeholder="请输入" :min="0" :max="999" :show-button="false" style="width: 339px;" <n-input :value="formModel.headShowCount" placeholder="请输入" :allow-input="onlyAllowNumberAndDash" style="width: 339px;" @update:value="handleHeadShowCountChange" /> </n-form-item> <n-form-item label="是否开启运营期免收费" path="operateFree" required class="row-item"> @@ -189,13 +216,14 @@ </n-form-item> </div> <div class="form-row"> <div class="form-row gap-x-20px!"> <n-form-item label="小程序附近热门站点推荐距离" path="nearPointDistance" required class="row-item"> <div class="inline-input"> <n-input-group style="width: 222px;"> <n-input v-model:value="formModel.nearPointDistance" placeholder="请输入" :value="formModel.nearPointDistance" placeholder="请输入" :allow-input="onlyAllowNumberAndDash" @update:value="handleNearPointDistanceChange" /> <n-input-group-label>m</n-input-group-label> </n-input-group> @@ -207,7 +235,7 @@ v-model:value="formModel.temperatureUnit" :options="[{ label: '℃', value: '℃' }, { label: '℉', value: '℉' }]" placeholder="请选择" style="width: 280px;" style="width: 362px;" @update:show="isWeatherUnitOpen = $event" > <template #arrow> @@ -229,28 +257,23 @@ 行程中修改目的地策略 </div> <n-form ref="strategyFormRef" :model="formModel" :rules="rules" label-placement="left" require-mark-placement="left" > <div class="form-row single-line-row"> <n-form-item label="当前剩余里程<" path="xczSyDistance" required> <div class="inline-input"> <n-input-number v-model:value="formModel.xczSyDistance" placeholder="请输入" :min="0" :precision="0" :show-button="false" <n-input v-model:value="formModel.xczSyDistance" placeholder="请输入" style="width: 115px;" :allow-input="onlyAllowNumberAndDash" /> <span>米,或剩余时长<</span> <n-input-number v-model:value="formModel.xczSyTime" placeholder="请输入" :min="0" :precision="0" :show-button="false" <n-input v-model:value="formModel.xczSyTime" placeholder="请输入" style="width: 115px;" :allow-input="onlyAllowNumberAndDash" /> <span>分钟,禁止修改</span> </div> @@ -260,13 +283,10 @@ <div class="form-row single-line-row"> <n-form-item label="单次行程最多允许修改" path="xczCaCount" required> <div class="inline-input"> <n-input-number v-model:value="formModel.xczCaCount" placeholder="请输入" :min="0" :precision="0" :show-button="false" <n-input v-model:value="formModel.xczCaCount" placeholder="请输入" style="width: 115px;" :allow-input="onlyAllowNumberAndDash" /> <span>次目的地,防恶意高频调用</span> </div> @@ -274,25 +294,19 @@ </div> <div class="form-row single-line-row"> <n-form-item label="特殊豁免:" required label-placement="top"> <n-form-item label="特殊豁免:" required path="xczHmSpeedPerHour" label-placement="top"> <div class="inline-input break-line block!"> <span>若系统检测到车辆在当前坐标时速<</span> <n-input-number v-model:value="formModel.xczHmSpeedPerHour" placeholder="请输入" :min="0" :precision="0" :show-button="false" <n-input v-model:value="formModel.xczHmSpeedPerHour" placeholder="请输入" style="width: 115px; display: inline-block;margin: 0 8px;" :allow-input="onlyAllowNumberAndDash" /> <span>km/h 且持续时长></span> <n-input-number v-model:value="formModel.xczHmDuration" placeholder="请输入" :min="0" :precision="0" :show-button="false" <n-input v-model:value="formModel.xczHmDuration" placeholder="请输入" style="width: 115px; display: inline-block;margin: 0 8px;" :allow-input="onlyAllowNumberAndDash" /> <span>分钟<span class="inline-note">(判定为极度拥堵或异常滞留)</span>,此时解除限制,允许用户修改目的地新增途经点以寻找更近的下车位置</span> </div> @@ -306,13 +320,14 @@ 下单及点位吸附策略 </div> <n-form ref="orderStrategyFormRef" :model="formModel" :rules="rules" label-placement="left" require-mark-placement="left" > <div class="form-row single-line-row"> <n-form-item label="距点位" path="orderDistance" required> <div class="inline-input"> <n-input-group class="w-326px"> <n-input-group class="w-352px"> <n-input v-model:value="formModel.orderDistance" placeholder="请输入" :allow-input="onlyAllowNumberAndDash" /> @@ -326,11 +341,11 @@ <div class="form-row single-line-row"> <n-form-item label="起终点之间" path="minOrderDistance" required> <div class="inline-input"> <n-input-group> <n-input-group class="w-326px"> <n-input v-model:value="formModel.minOrderDistance" placeholder="请输入" :allow-input="onlyAllowNumberAndDash" /> <n-input-group-label>分钟</n-input-group-label> <n-input-group-label>m</n-input-group-label> </n-input-group> <span class="inline-note">内不可下单</span> </div> @@ -340,7 +355,7 @@ <div class="form-row single-line-row"> <n-form-item label="距点位" path="adsorptionDistance" required> <div class="inline-input"> <n-input-group class="w-326px"> <n-input-group class="w-352px"> <n-input v-model:value="formModel.adsorptionDistance" placeholder="请输入" :allow-input="onlyAllowNumberAndDash" /> @@ -354,13 +369,13 @@ <div class="form-row single-line-row"> <n-form-item label="到达目的地后" path="arriveTime" required> <div class="inline-input"> <n-input-group class="w-326px"> <n-input-group class="w-313px"> <n-input v-model:value="formModel.arriveTime" placeholder="请输入" :allow-input="onlyAllowNumberAndDash" /> <n-input-group-label>m</n-input-group-label> <n-input-group-label>分钟</n-input-group-label> </n-input-group> <span class="inline-note">内结束行程</span> <span class="inline-note">自动结束行程</span> </div> </n-form-item> </div> src/views/transaction/pricingManagement/components/TableModal.vue
@@ -237,7 +237,7 @@ } } // 获取车辆型号列表(预留接口) // 获取车辆型号列表 async function getVehicleModelList() { try { const { data } = await queryVehicleModelNoPageList() // TODO: 对接获取车辆型号接口 src/views/transaction/pricingManagement/detail.vue
@@ -503,7 +503,7 @@ 车型: </div> <div class="value"> {{ detail?.vehicleModel || '-' }} {{ detail?.vehicleModelName || '-' }} </div> </div> </n-grid-item> src/views/userContent/active/activityManagement/add.vue
@@ -132,7 +132,7 @@ message.success(`成功导入了 ${newUsers.length} 名用户`) } const activeTab = ref(4) const activeTab = ref(1) const isEditMode = computed(() => route.query.mode === 'edit' && !!route.query.id) interface UsagePeriodItem { @@ -995,6 +995,12 @@ userGroupList.value.splice(index, 1) } function closeTimePicker() { if (document.activeElement) { (document.activeElement as HTMLElement).blur() } } onMounted(() => { getDetail() }) @@ -1032,7 +1038,7 @@ <div class="flex items-center gap-12px"> <NDatePicker v-model:value="formModel.timeRange" format="yyyy/MM/dd" type="daterange" clearable start-placeholder="请选择日期" end-placeholder="请选择日期" close-on-select :actions="null" start-placeholder="开始时间" end-placeholder="结束时间" close-on-select :actions="null" style="width: 400px;" /> </div> @@ -1085,7 +1091,7 @@ class="mb-12px p-24px pb-12px border border-[#EEE9E9] last:mb-0 rounded-6px" > <NForm :model="strategy" :rules="strategyRules" label-placement="left" require-mark-placement="left"> <div class="flex items-center justify-between mb-16px"> <div class="flex items-center justify-between mb-8px"> <!-- 策略名称 --> <NFormItem label="策略名称" path="name"> <NInput @@ -1104,13 +1110,12 @@ </NButton> </div> </NFormItem> <div class="mt-4px min-h-[262px]"> <div class="mt-4px"> <NDataTable :columns="createCouponColumns(strategyIndex, 'normal')" :data="strategy.couponList" :bordered="false" style="min-height: 263px" flex-height :style="strategy.couponList.length === 0 ? { minHeight: '263px' } : {}" :pagination="false" > <template #empty> @@ -1160,8 +1165,7 @@ :columns="createCouponColumns(strategyIndex, 'afterUse')" :data="strategy.distributionRulesAfterUse.couponList" :bordered="false" style="min-height: 263px" flex-height :style="strategy.distributionRulesAfterUse.couponList.length === 0 ? { minHeight: '263px' } : {}" :pagination="false" > <template #empty> @@ -1244,12 +1248,20 @@ > <NTimePicker v-model:formatted-value="timeLimit.startTime" format="HH:mm" value-format="HH:mm" placeholder="请选择开始时间" style="width: 240px" placeholder="请选择开始时间" style="width: 240px" :actions="['now']" @update:value=" () => { closeTimePicker(); } " /> <span class="text-[#171f26cc]">至</span> <NTimePicker v-model:formatted-value="timeLimit.endTime" format="HH:mm" value-format="HH:mm" placeholder="请选择结束时间" style="width: 240px" placeholder="请选择结束时间" style="width: 240px" :actions="['now']" @update:value=" () => { closeTimePicker(); } " /> <img v-if="index > 0" :src="deleteIcon" alt="删除" style="width: 16px;height: 16px;cursor: pointer;" @click="handleRemoveTimeLimit(strategyIndex, index)"> </div> @@ -1347,8 +1359,7 @@ :columns="createUserColumns(groupIndex)" :data="group.userList" :bordered="false" flex-height style="min-height: 263px" :style="group.userList.length === 0 ? { minHeight: '263px' } : {}" :pagination="false" > <template #empty>