feat: 班次管理接口对接、订单列表样式调整、交易策略样式调整
| | |
| | | <!-- 操作区 --> |
| | | <n-gi suffix> |
| | | <div class="search-panel__actions"> |
| | | <slot name="action" /> |
| | | <!-- 展开 / 收起 --> |
| | | <n-button v-if="showToggle" text size="small" @click="toggle"> |
| | | <template #icon> |
| | |
| | | </template> |
| | | {{ collapsed ? t('common.expand') : t('common.collapse') }} |
| | | </n-button> |
| | | <slot name="action" /> |
| | | </div> |
| | | </n-gi> |
| | | </n-grid> |
| | |
| | | componentPath: '/transaction/transactionStrategy/index.vue', |
| | | id: 605, |
| | | pid: 6, |
| | | fullScreen: true, |
| | | }, |
| | | { |
| | | name: 'navigationAndRoutePlanning', |
| | |
| | | |
| | | // 删除班次 |
| | | export function deleteShift(id: any) { |
| | | return request.Delete<Service.ResponseResult<any>>('/maintenance/xp-shift/api/v1/shift/deleteById', { id }) |
| | | return request.Delete<Service.ResponseResult<any>>('/maintenance/xp-shift/api/v1/shift/deleteById?id=' + id) |
| | | } |
| | |
| | | |
| | | // 导出订单Excel |
| | | export function exportOrderExcel(params: any) { |
| | | return request.Post<Service.ResponseResult<any>>('/order/api/v1/order/exportExcel', params) |
| | | // return request.Post<Service.ResponseResult<any>>('/order/api/v1/order/exportExcel', params, { responseType: 'blob' }) |
| | | const method = request.Post<Service.ResponseResult<any>>('/order/api/v1/order/exportExcel', params, { responseType: 'blob' }) |
| | | method.meta = { ...method.meta, isBlob: true } |
| | | return method |
| | | } |
| | | |
| | | // 改派订单 |
| | |
| | | } |
| | | |
| | | // 删除订单 |
| | | export function deleteOrder(params: any) { |
| | | return request.Delete<Service.ResponseResult<any>>('/order/api/v1/order/deleteById', params) |
| | | export function deleteOrder(id: any) { |
| | | return request.Delete<Service.ResponseResult<any>>('/order/api/v1/order/deleteById?id=' + id) |
| | | } |
| | | |
| | | // 获取车队不分页列表 |
| | | export function getFleetList() { |
| | | return request.Post<Service.ResponseResult<any>>('/vehicleConvoy/api/v1/fleet/list') |
| | | } |
| | | |
| | | /** 订单评价 */ |
| | |
| | | { |
| | | title: '打卡地', |
| | | key: 'locationAddress', |
| | | resizable: true |
| | | resizable: true, |
| | | minWidth: 200 |
| | | }, |
| | | { |
| | | title: '状态', |
| | |
| | | width: 150, |
| | | render: (row) => { |
| | | return ( |
| | | <NSpace justify="center"> |
| | | <NSpace> |
| | | <NButton |
| | | text |
| | | type='primary' |
| | |
| | | endLoading() |
| | | }) |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getList() |
| | | }) |
| | |
| | | pageParams.value.pageSize = size |
| | | getList() |
| | | } |
| | | |
| | | </script> |
| | | |
| | | <template> |
| | |
| | | import type { FormInst, FormRules } from 'naive-ui' |
| | | |
| | | interface FormModel { |
| | | name: string |
| | | color: string |
| | | shiftName: string |
| | | shiftColor: string |
| | | startTime: string | null |
| | | endTime: string | null |
| | | hasRest: boolean |
| | | isRest: boolean |
| | | restStartTime: string | null |
| | | restEndTime: string | null |
| | | } |
| | |
| | | |
| | | const formRef = ref<FormInst | null>(null) |
| | | const formModel = ref<FormModel>({ |
| | | name: '', |
| | | color: '#DE868F', |
| | | shiftName: '', |
| | | shiftColor: '#DE868F', |
| | | startTime: null, |
| | | endTime: null, |
| | | hasRest: false, |
| | | isRest: false, |
| | | restStartTime: null, |
| | | restEndTime: null |
| | | }) |
| | |
| | | ] |
| | | |
| | | const rules: FormRules = { |
| | | name: [ |
| | | shiftName: [ |
| | | { required: true, message: '请输入班次名称', trigger: 'blur' } |
| | | ], |
| | | color: [ |
| | | shiftColor: [ |
| | | { required: true, message: '请选择班次颜色', trigger: 'change' } |
| | | ], |
| | | startTime: [ |
| | |
| | | { required: true, message: '请选择结束时间', trigger: 'change' } |
| | | ], |
| | | restStartTime: [ |
| | | { |
| | | required: true, |
| | | { |
| | | required: true, |
| | | validator: (_rule: any, value: any) => { |
| | | if (formModel.value.hasRest && !value) { |
| | | if (formModel.value.isRest && !value) { |
| | | return new Error('请选择开始休息时间') |
| | | } |
| | | return true |
| | |
| | | } |
| | | ], |
| | | restEndTime: [ |
| | | { |
| | | required: true, |
| | | { |
| | | required: true, |
| | | validator: (_rule: any, value: any) => { |
| | | if (formModel.value.hasRest && !value) { |
| | | if (formModel.value.isRest && !value) { |
| | | return new Error('请选择结束休息时间') |
| | | } |
| | | return true |
| | |
| | | |
| | | const resetForm = () => { |
| | | formModel.value = { |
| | | name: '', |
| | | color: '#DE868F', |
| | | shiftName: '', |
| | | shiftColor: '#DE868F', |
| | | startTime: null, |
| | | endTime: null, |
| | | hasRest: false, |
| | | isRest: false, |
| | | restStartTime: null, |
| | | restEndTime: null |
| | | } |
| | | } |
| | | |
| | | const openEdit = (data: any) => { |
| | | formModel.value = { ...data } |
| | | } |
| | | |
| | | defineExpose({ |
| | | openEdit, |
| | | }) |
| | | </script> |
| | | |
| | | <template> |
| | | <n-modal |
| | | v-model:show="show" |
| | | :mask-closable="false" |
| | | preset="card" |
| | | :title="mode === 'edit' ? '编辑班次' : '新增班次'" |
| | | <n-modal |
| | | v-model:show="show" |
| | | :mask-closable="false" |
| | | preset="card" |
| | | :title="mode === 'edit' ? '编辑班次' : '新增班次'" |
| | | class="w-600px" |
| | | :segmented="{ |
| | | content: true, |
| | |
| | | require-mark-placement="left" |
| | | show-require-mark |
| | | > |
| | | <n-form-item label="班次" path="name"> |
| | | <n-input v-model:value="formModel.name" placeholder="请输入" clearable /> |
| | | <n-form-item label="班次" path="shiftName"> |
| | | <n-input v-model:value="formModel.shiftName" placeholder="请输入" clearable /> |
| | | </n-form-item> |
| | | |
| | | <n-form-item label="班次色号" path="color"> |
| | |
| | | v-for="color in colorOptions" |
| | | :key="color.value" |
| | | class="w-12 h-12 rounded cursor-pointer relative" |
| | | :style="{ backgroundColor: color.value, border: formModel.color === color.value ? '2px solid #0068FF' : '1px solid #e5e7eb' }" |
| | | @click="formModel.color = color.value" |
| | | :style="{ backgroundColor: color.value, border: formModel.shiftColor === color.value ? '2px solid #0068FF' : '1px solid #e5e7eb' }" |
| | | @click="formModel.shiftColor = color.value" |
| | | > |
| | | <div |
| | | v-if="formModel.color === color.value" |
| | | v-if="formModel.shiftColor === color.value" |
| | | class="absolute top-0 right-0 w-4 h-4 bg-blue-500 rounded-bl flex items-center justify-center" |
| | | > |
| | | <span class="text-white text-xs">✓</span> |
| | |
| | | <n-time-picker v-model:formatted-value="formModel.endTime" format="HH:mm" value-format="HH:mm" placeholder="--:--" clearable style="width: 100%" /> |
| | | </n-form-item> |
| | | |
| | | <n-form-item label="是否中途休息" path="hasRest"> |
| | | <n-switch v-model:value="formModel.hasRest" /> |
| | | <n-form-item label="是否中途休息" path="isRest"> |
| | | <n-switch v-model:value="formModel.isRest" /> |
| | | </n-form-item> |
| | | |
| | | <template v-if="formModel.hasRest"> |
| | | <template v-if="formModel.isRest"> |
| | | <n-form-item label="开始休息时间" path="restStartTime"> |
| | | <n-time-picker v-model:formatted-value="formModel.restStartTime" format="HH:mm" value-format="HH:mm" placeholder="--:--" clearable style="width: 100%" /> |
| | | </n-form-item> |
| | |
| | | <script setup lang="tsx"> |
| | | import { ref, computed, h } from 'vue' |
| | | import { useBoolean } from '@/hooks' |
| | | import type { DataTableColumns } from 'naive-ui' |
| | | import { NButton, NTag } from 'naive-ui' |
| | | import { getShiftList, addShift, editShift, deleteShift } from '@/service/api/attendance' |
| | | import { NButton, NSpace, NPopconfirm } from 'naive-ui' |
| | | import ShiftFormModal from './components/ShiftFormModal.vue' |
| | | |
| | | interface Shift { |
| | | id: number |
| | | name: string |
| | | workTime: string |
| | | restTime: string |
| | | createTime: string |
| | | } |
| | | const { bool: loading, setTrue: startLoading, setFalse: endLoading } = useBoolean(false) |
| | | |
| | | const shiftName = ref<string | null>(null) |
| | | |
| | |
| | | { label: '角色1', value: '角色1' } |
| | | ] |
| | | |
| | | const shiftList = ref<Shift[]>([ |
| | | { id: 1, name: '早班', workTime: '9:00-12:00', restTime: '', createTime: '2025-05-07 14:53' }, |
| | | { id: 2, name: '中班', workTime: '13:00-17:00', restTime: '', createTime: '2025-05-07 14:53' }, |
| | | { id: 3, name: '晚班', workTime: '18:00-22:00', restTime: '', createTime: '2025-05-07 14:53' }, |
| | | { id: 4, name: '全天', workTime: '9:00-22:00', restTime: '(12:00-13:00休息)', createTime: '2025-05-07 14:53' }, |
| | | { id: 5, name: '全天', workTime: '9:00-12:00', restTime: '', createTime: '2025-05-07 14:53' }, |
| | | { id: 6, name: '全天', workTime: '13:00-17:00', restTime: '', createTime: '2025-05-07 14:53' }, |
| | | { id: 7, name: '全天', workTime: '9:00-22:00', restTime: '(12:00-13:00休息)', createTime: '2025-05-07 14:53' }, |
| | | { id: 8, name: '全天', workTime: '-', restTime: '', createTime: '2025-05-07 14:53' }, |
| | | { id: 9, name: '全天', workTime: '-', restTime: '', createTime: '2025-05-07 14:53' }, |
| | | { id: 10, name: '全天', workTime: '-', restTime: '', createTime: '2025-05-07 14:53' } |
| | | ]) |
| | | |
| | | const currentPage = ref(1) |
| | | const pageSize = ref(10) |
| | | const total = ref(1000) |
| | | const shiftList = ref<any[]>([]) |
| | | const modalRef = ref() |
| | | const total = ref(0) |
| | | const pageParams = ref({ |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | }) |
| | | |
| | | const showFormModal = ref(false) |
| | | const formMode = ref<'add' | 'edit'>('add') |
| | |
| | | showFormModal.value = true |
| | | } |
| | | |
| | | const handleEdit = (row: Shift) => { |
| | | const handleEdit = (row: any) => { |
| | | formMode.value = 'edit' |
| | | showFormModal.value = true |
| | | console.log('编辑', row) |
| | | modalRef.value.openEdit(row) |
| | | } |
| | | |
| | | const handleConfirmForm = (data: any) => { |
| | | console.log('保存数据', data) |
| | | if (data.id) { |
| | | editShift(data).then((res) => { |
| | | if (res.code === 200) { |
| | | window.$message.success('编辑成功') |
| | | } |
| | | }).finally(() => { |
| | | getList() |
| | | }) |
| | | } else { |
| | | addShift(data).then((res) => { |
| | | if (res.code === 200) { |
| | | window.$message.success('新增成功') |
| | | } |
| | | }).finally(() => { |
| | | getList() |
| | | }) |
| | | } |
| | | } |
| | | |
| | | const handleDelete = (row: Shift) => { |
| | | console.log('删除', row) |
| | | const handleDelete = (id: any) => { |
| | | deleteShift(id).then((res) => { |
| | | if (res.code === 200) { |
| | | window.$message.success('删除成功') |
| | | } |
| | | }).finally(() => { |
| | | getList() |
| | | }) |
| | | } |
| | | |
| | | const getShiftTagType = (name: string) => { |
| | | if (name === '早班') return { bg: '#DCF5DD', color: '#0BB52D' } |
| | | if (name === '中班') return { bg: '#FFF8E6', color: '#FF9000' } |
| | | if (name === '晚班') return { bg: '#F6F0FF', color: '#764DFF' } |
| | | if (name === '全天') return { bg: '#E6F4FF', color: '#0068FF' } |
| | | return { bg: '#E6F4FF', color: '#0068FF' } |
| | | } |
| | | |
| | | const columns = computed<DataTableColumns<Shift>>(() => [ |
| | | { title: '序号', key: 'id', width: 80, align: 'center' }, |
| | | const columns = computed<DataTableColumns<any>>(() => [ |
| | | { title: '序号', key: 'serialNumber', width: 158, resizable: true, }, |
| | | { |
| | | title: '状态', |
| | | key: 'name', |
| | | width: 120, |
| | | key: 'shiftName', |
| | | width: 256, |
| | | resizable: true, |
| | | render: (row) => { |
| | | const style = getShiftTagType(row.name) |
| | | return h('span', { |
| | | style: { |
| | | display: 'inline-block', |
| | | padding: '2px 12px', |
| | | borderRadius: '4px', |
| | | fontSize: '12px', |
| | | backgroundColor: style.bg, |
| | | color: style.color |
| | | backgroundColor: row.shiftColor + '25', |
| | | color: row.shiftColor |
| | | } |
| | | }, row.name) |
| | | }, row.shiftName) |
| | | } |
| | | }, |
| | | { |
| | | title: '工作时间', |
| | | key: 'workTime', |
| | | minWidth: 200, |
| | | resizable: true, |
| | | render: (row) => ( |
| | | <span> |
| | | {row.workTime} |
| | | {row.restTime && <span style={{ color: '#0068FF', marginLeft: '4px' }}>{row.restTime}</span>} |
| | | {row.startTime}-{row.endTime} |
| | | {row.isRest && <span style={{ color: '#0068FF', marginLeft: '4px' }}>({row.restStartTime}-{row.restEndTime}休息)</span>} |
| | | </span> |
| | | ) |
| | | }, |
| | | { title: '添加时间', key: 'createTime', width: 180 }, |
| | | { title: '添加时间', key: 'createTime', width: 290, resizable: true, }, |
| | | { |
| | | title: '操作', |
| | | key: 'actions', |
| | | width: 150, |
| | | align: 'center', |
| | | width: 134, |
| | | fixed: 'right', |
| | | render: (row) => ( |
| | | <div class="flex gap-3 justify-center"> |
| | | <NButton text type="primary" onClick={() => handleEdit(row)}> |
| | | 编辑 |
| | | </NButton> |
| | | <NButton text type="primary" onClick={() => handleDelete(row)}> |
| | | 删除 |
| | | </NButton> |
| | | </div> |
| | | <NSpace> |
| | | <NButton |
| | | text |
| | | type='primary' |
| | | onClick={() => handleEdit(row)} |
| | | > |
| | | 编辑 |
| | | </NButton> |
| | | <NPopconfirm onPositiveClick={() => handleDelete(row.id!)}> |
| | | {{ |
| | | default: () => '确认删除', |
| | | trigger: () => <NButton text type="error">删除</NButton>, |
| | | }} |
| | | </NPopconfirm> |
| | | </NSpace> |
| | | ) |
| | | } |
| | | ]) |
| | | |
| | | async function getList() { |
| | | startLoading() |
| | | const params = { |
| | | ...pageParams.value |
| | | } |
| | | getShiftList(params).then((res) => { |
| | | shiftList.value = res.data.records || [] |
| | | shiftList.value.forEach((item: any, index: number) => { |
| | | item.serialNumber = index + 1 |
| | | }) |
| | | total.value = res.data.total || res.data.records?.length |
| | | }).finally(() => { |
| | | endLoading() |
| | | }) |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getList() |
| | | }) |
| | | |
| | | function changePage(page: number, size: number) { |
| | | pageParams.value.pageNum = page |
| | | pageParams.value.pageSize = size |
| | | getList() |
| | | } |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="h-full flex flex-col"> |
| | | <n-card style="border-radius: 6px" content-style="padding: 12px"> |
| | | <div class="flex items-center justify-between"> |
| | | <div class="flex items-center gap-2"> |
| | | <div class="text-sm">角色</div> |
| | | <n-select v-model:value="shiftName" :options="roleOptions" placeholder="请选择" clearable style="width: 269px" /> |
| | | <div class="roboTaxi"> |
| | | <NSpace vertical class="flex-1"> |
| | | <!-- <n-card style="border-radius: 6px" content-style="padding: 12px"> |
| | | <div class="flex items-center justify-between"> |
| | | <div class="flex items-center gap-2"> |
| | | <div class="text-sm">角色</div> |
| | | <n-select v-model:value="shiftName" :options="roleOptions" placeholder="请选择" clearable |
| | | style="width: 269px" /> |
| | | </div> |
| | | <div class="flex gap-2"> |
| | | <n-button style="width: 84px; height: 32px" @click="handleReset">重置</n-button> |
| | | <n-button type="primary" style="width: 84px; height: 32px" @click="handleSearch">查询</n-button> |
| | | </div> |
| | | </div> |
| | | <div class="flex gap-2"> |
| | | <n-button style="width: 84px; height: 32px" @click="handleReset">重置</n-button> |
| | | <n-button type="primary" style="width: 84px; height: 32px" @click="handleSearch">查询</n-button> |
| | | </div> |
| | | </div> |
| | | </n-card> |
| | | </n-card> --> |
| | | |
| | | <n-card style="border-radius: 6px; margin-top: 12px" content-style="padding: 12px"> |
| | | <div class="mb-4 flex justify-end"> |
| | | <n-button |
| | | style="height: 32px; background-color: #E6F4FF; color: #0068FF; border: 1px solid #7ABDFF" |
| | | @click="handleAdd"> |
| | | 新增班次 |
| | | </n-button> |
| | | </div> |
| | | <n-card class="flex-1"> |
| | | <template #header> |
| | | <n-flex justify="flex-end"> |
| | | <NButton type="primary" secondary @click="handleAdd"> |
| | | 新增班次 |
| | | </NButton> |
| | | </n-flex> |
| | | </template> |
| | | <NSpace vertical :size="12"> |
| | | <n-data-table :columns="columns" :data="shiftList" :loading="loading" :bordered="false" :header-height="18" |
| | | :row-height="18" /> |
| | | <Pagination :count="total" @change="changePage" /> |
| | | </NSpace> |
| | | </n-card> |
| | | </NSpace> |
| | | |
| | | <n-data-table |
| | | :columns="columns" |
| | | :data="shiftList" |
| | | :pagination="{ |
| | | page: currentPage, |
| | | pageSize: pageSize, |
| | | itemCount: total, |
| | | showSizePicker: true, |
| | | pageSizes: [10, 20, 50, 100], |
| | | prefix: ({ itemCount }) => `第 ${(currentPage - 1) * pageSize + 1}-${Math.min(currentPage * pageSize, itemCount || 0)} 条 / 总共 ${itemCount || 0} 条` |
| | | }" |
| | | :scroll-x="1000" |
| | | /> |
| | | </n-card> |
| | | |
| | | <ShiftFormModal v-model:show="showFormModal" :mode="formMode" @confirm="handleConfirmForm" /> |
| | | <ShiftFormModal v-model:show="showFormModal" ref="modalRef" :mode="formMode" @confirm="handleConfirmForm" /> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | <script setup lang="tsx"> |
| | | import type { DataTableColumns, FormInst } from 'naive-ui' |
| | | import type { DataTableColumns, FormInst, DataTableRowKey } from 'naive-ui' |
| | | import { useBoolean } from '@/hooks' |
| | | import { getOrderList, cancelAndCloseOrder, exportOrderExcel, deleteOrder } from '@/service/api/transaction' |
| | | import { getOrderList, cancelAndCloseOrder, exportOrderExcel, deleteOrder, getFleetList } from '@/service/api/transaction' |
| | | import { getRegionCascader } from '@/service/api/operations' |
| | | import { NButton, NSpace, NTag, useMessage } from 'naive-ui' |
| | | import SearchPanel from '@/components/custom/SearchPanel.vue' |
| | | import PcaCascader from '@/components/custom/PcaCascader.vue' |
| | | import dayjs from 'dayjs' |
| | | import { downloadFile } from '@/utils' |
| | | import TableModal from './components/TableModal.vue' |
| | | import Modal from './components/Modal.vue' |
| | | |
| | |
| | | const modalRef1 = ref() |
| | | const formRef = ref<FormInst | null>() |
| | | |
| | | const checkedRowKeysRef = ref<DataTableRowKey[]>([]) |
| | | |
| | | const columns = computed<DataTableColumns<any>>(() => [ |
| | | { |
| | | type: 'selection', |
| | | width: 40, |
| | | fixed: 'left' |
| | | }, |
| | | { |
| | | title: t('transaction.orderNo'), |
| | | align: 'center', |
| | | key: 'orderNumber', |
| | | ellipsis: true, |
| | | resizable: true |
| | | width: 150, |
| | | resizable: true, |
| | | fixed: 'left' |
| | | }, |
| | | { |
| | | title: t('transaction.orderTime'), |
| | | align: 'center', |
| | | key: 'createTime', |
| | | ellipsis: true, |
| | | width: 160, |
| | | resizable: true |
| | | }, |
| | | { |
| | | title: t('transaction.orderSource'), |
| | | align: 'center', |
| | | key: 'orderSource', |
| | | ellipsis: true, |
| | | width: 100, |
| | | resizable: true, |
| | | render(row) { |
| | | return row.orderSource === 1 ? '小鹏小程序' : '-' |
| | | } |
| | | }, |
| | | { |
| | | title: t('transaction.pickupTime'), |
| | | align: 'center', |
| | | key: 'rideTime', |
| | | ellipsis: true, |
| | | width: 160, |
| | | resizable: true |
| | | }, |
| | | { |
| | | title: t('transaction.userNickname'), |
| | | align: 'center', |
| | | key: 'nickName', |
| | | ellipsis: true, |
| | | width: 120, |
| | | resizable: true |
| | | }, |
| | | { |
| | | title: t('transaction.userPhone'), |
| | | align: 'center', |
| | | key: 'phoneNumber', |
| | | ellipsis: true, |
| | | width: 120, |
| | | resizable: true |
| | | }, |
| | | { |
| | | title: t('transaction.pickupLocation'), |
| | | align: 'center', |
| | | key: 'startAddress', |
| | | ellipsis: true, |
| | | resizable: true |
| | | width: 160, |
| | | resizable: true, |
| | | ellipsis: { |
| | | tooltip: true |
| | | } |
| | | }, |
| | | { |
| | | title: t('transaction.dropoffLocation'), |
| | | align: 'center', |
| | | key: 'endAddress', |
| | | ellipsis: true, |
| | | resizable: true |
| | | width: 160, |
| | | resizable: true, |
| | | ellipsis: { |
| | | tooltip: true |
| | | } |
| | | }, |
| | | { |
| | | title: t('transaction.selectedVehicleType'), |
| | | align: 'center', |
| | | key: 'vehicleModel', |
| | | ellipsis: true, |
| | | width: 120, |
| | | resizable: true |
| | | }, |
| | | { |
| | | title: t('transaction.acceptedVehicleType'), |
| | | align: 'center', |
| | | key: 'plateNumber', |
| | | ellipsis: true, |
| | | width: 120, |
| | | resizable: true |
| | | }, |
| | | { |
| | | title: t('transaction.affiliatedFleet'), |
| | | align: 'center', |
| | | key: 'fleetName', |
| | | ellipsis: true, |
| | | width: 120, |
| | | resizable: true |
| | | }, |
| | | { |
| | | title: t('transaction.orderAmount'), |
| | | align: 'center', |
| | | key: 'orderMoney', |
| | | ellipsis: true, |
| | | width: 120, |
| | | resizable: true |
| | | }, |
| | | { |
| | | title: t('transaction.status'), |
| | | align: 'center', |
| | | key: 'status', |
| | | ellipsis: true, |
| | | width: 120, |
| | | resizable: true, |
| | | render(row) { |
| | | return h( |
| | | NTag, |
| | | { |
| | | type: row.status === 1 || row.status === 4 ? 'primary' : row.status === 2 || row.status === 5 ? 'success' : row.status === 3 || row.status === 6 ? 'warning' : 'default', |
| | | type: statusOptions.find(item => item.value === row.status)?.type || 'default', |
| | | style: row.status === 7 ? { |
| | | color: '#764DFF', |
| | | backgroundColor: '#F6F0FF', |
| | | } : {}, |
| | | bordered: false |
| | | }, |
| | | { |
| | |
| | | }, |
| | | { |
| | | title: '操作', |
| | | align: 'center', |
| | | key: 'actions', |
| | | width: 200, |
| | | fixed: 'right', |
| | | render: (row) => { |
| | | console.log(row.status === 1) |
| | | return ( |
| | | <NSpace justify="center"> |
| | | <NSpace> |
| | | {(row.status === 1 || row.status === 2 || row.status === 3 || row.status === 4) && <NButton |
| | | text |
| | | type="primary" |
| | |
| | | negativeText: '取消', |
| | | draggable: true, |
| | | onPositiveClick: () => { |
| | | deleteOrder({ id: row.id! }).then(res => { |
| | | if (res.code === 200) { |
| | | message.success('删除订单成功') |
| | | getList() |
| | | } |
| | | }) |
| | | deleteOrder(row.id!).then(res => { |
| | | if (res.code === 200) { |
| | | message.success('删除订单成功') |
| | | getList() |
| | | } |
| | | }) |
| | | }, |
| | | onNegativeClick: () => { |
| | | // message.error('取消') |
| | | } |
| | | }) |
| | | }} |
| | | > |
| | |
| | | }, |
| | | ]) |
| | | // 车队 |
| | | const options = [ |
| | | { |
| | | label: '车队1', |
| | | value: 1, |
| | | }, |
| | | { |
| | | label: '车队2', |
| | | value: 2, |
| | | }, |
| | | ] |
| | | const options = ref<any[]>([]) |
| | | // 渠道 |
| | | const chanleOptions = [ |
| | | { |
| | |
| | | { |
| | | label: '待接单', |
| | | value: 1, |
| | | type: 'primary', |
| | | }, |
| | | { |
| | | label: '待出发', |
| | | value: 2, |
| | | type: 'success', |
| | | }, |
| | | { |
| | | label: '待到达预约地点', |
| | | value: 3, |
| | | type: 'warning', |
| | | }, |
| | | { |
| | | label: '待乘客上车', |
| | | value: 4, |
| | | type: 'primary', |
| | | }, |
| | | { |
| | | label: '服务中', |
| | | value: 5, |
| | | type: 'success', |
| | | }, |
| | | { |
| | | label: '待支付', |
| | | value: 6, |
| | | type: 'warning', |
| | | }, |
| | | { |
| | | label: '待评价', |
| | | value: 7, |
| | | type: 'default', |
| | | }, |
| | | { |
| | | label: '已完成', |
| | | value: 8, |
| | | type: 'default', |
| | | }, |
| | | { |
| | | label: '已取消', |
| | | value: 0, |
| | | type: 'default', |
| | | }, |
| | | ] |
| | | const pcaOptions = ref<any[]>([]) |
| | | // 搜索项 |
| | | const filterItems = computed(() => [ |
| | | { |
| | |
| | | { |
| | | label: t('transaction.fleetName'), |
| | | path: 'fleetId', |
| | | render: () => <n-select v-model:value={model.value.fleetId} options={options} />, |
| | | render: () => <n-select v-model:value={model.value.fleetId} options={options.value} />, |
| | | }, |
| | | { |
| | | label: t('transaction.channel'), |
| | |
| | | },{ |
| | | label: t('transaction.city'), |
| | | path: 'cityCode', |
| | | render: () => <PcaCascader v-model:value={model.value.cityCode} />, |
| | | render: () => <n-cascader v-model:value={model.value.cityCode} options={pcaOptions.value} value-field="code" label-field="name" check-strategy="all" clearable />, |
| | | }, |
| | | { |
| | | label: t('transaction.status'), |
| | |
| | | }) |
| | | } |
| | | |
| | | const handleExport = () => { |
| | | const handleExport =async () => { |
| | | const params = { |
| | | ...pageParams.value, |
| | | status: model.value.status, |
| | |
| | | startTime: model.value.orderTime ? dayjs(model.value.orderTime?.[0]).format('YYYY-MM-DD HH:mm:ss') : null, |
| | | endTime: model.value.orderTime ? dayjs(model.value.orderTime?.[1]).format('YYYY-MM-DD HH:mm:ss') : null, |
| | | } |
| | | exportOrderExcel(params).then(res => { |
| | | if (res.code === 200) { |
| | | message.success('导出订单成功') |
| | | const response = await exportOrderExcel(params) |
| | | if (response instanceof Blob) { |
| | | downloadFile(response, `订单列表_${new Date().getTime()}.xlsx`) |
| | | message.success('导出成功') |
| | | } |
| | | } |
| | | |
| | | function formatCascaderData(list: any[]) { |
| | | return list.map(item => { |
| | | const newItem = { ...item } |
| | | if (newItem.children && newItem.children.length > 0) { |
| | | newItem.children = formatCascaderData(newItem.children) |
| | | } else { |
| | | delete newItem.children |
| | | } |
| | | return newItem |
| | | }) |
| | | } |
| | | |
| | | async function fetchCascaderData() { |
| | | const res = await getRegionCascader() |
| | | if (res.code === 200 && res.data) { |
| | | pcaOptions.value = formatCascaderData(res.data) |
| | | } |
| | | } |
| | | |
| | | async function fetchFleetList() { |
| | | const res = await getFleetList() |
| | | if (res.code === 200 && res.data) { |
| | | options.value = res.data.map((item: any) => ({ |
| | | label: item.fleetName, |
| | | value: item.id, |
| | | })) |
| | | } |
| | | } |
| | | |
| | | function rowKey(row: any) { |
| | | return row.id |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getList() |
| | | fetchCascaderData() |
| | | fetchFleetList() |
| | | }) |
| | | |
| | | function handleCheck(rowKeys: DataTableRowKey[]) { |
| | | checkedRowKeysRef.value = rowKeys |
| | | } |
| | | |
| | | function changePage(page: number, size: number) { |
| | | pageParams.value.pageNum = page |
| | |
| | | </script> |
| | | |
| | | <template> |
| | | <n-flex class="roboTaxi"> |
| | | <NSpace vertical class="flex-1"> |
| | | <n-flex class="roboTaxi w-full"> |
| | | <NSpace vertical class="flex-1 w-full"> |
| | | <div class="roboTaxi-form-card"> |
| | | <n-form ref="formRef" :model="model" label-placement="left" inline :show-feedback="false"> |
| | | <SearchPanel> |
| | | <SearchPanel showToggle> |
| | | <n-gi v-for="item in filterItems" :key="item.path"> |
| | | <n-form-item :label="item.label" :path="item.path"> |
| | | <component :is="item.render" /> |
| | |
| | | </n-form> |
| | | </div> |
| | | |
| | | <n-card class="flex-1"> |
| | | <n-card class="flex-1" > |
| | | <template #header> |
| | | <n-flex justify="flex-start"> |
| | | <NButton strong @click="handleExport"> |
| | |
| | | </n-flex> |
| | | </template> |
| | | <NSpace vertical> |
| | | <n-data-table :columns="columns" :data="listData" :loading="loading" :bordered="false" :header-height="18" |
| | | :row-height="18" /> |
| | | <n-data-table :row-key="rowKey" :scroll-x="1950" :columns="columns" :data="listData" :loading="loading" :bordered="false" |
| | | :header-height="18" :row-height="18" @update:checked-row-keys="handleCheck" /> |
| | | <Pagination :count="count" @change="changePage" /> |
| | | </NSpace> |
| | | </n-card> |
| | |
| | | import { useBoolean } from '@/hooks' |
| | | import type { DataTableColumns } from 'naive-ui' |
| | | import { NButton, NSpace } from 'naive-ui' |
| | | import { useTabStore } from '@/store' |
| | | import { editTradingStrategy, getTradingStrategyDetail } from '@/service/api/transaction' |
| | | |
| | | const { bool: loading, setTrue: startLoading, setFalse: endLoading } = useBoolean(false) |
| | | const message = useMessage() |
| | | const router = useRouter() |
| | | const route = useRoute() |
| | | const tabStore = useTabStore() |
| | | |
| | | |
| | | const initialModel:any = { |
| | | cancleCount: null, // 取消订单次数 |
| | |
| | | |
| | | const columns = computed<DataTableColumns<any>>(() =>[ |
| | | { |
| | | title: '纬度', |
| | | align: 'center', |
| | | title() { |
| | | return h( |
| | | 'div', |
| | | { |
| | | style: { |
| | | fontWeight: 'bold', |
| | | } |
| | | }, |
| | | { default: () => '纬度' } |
| | | ) |
| | | }, |
| | | key: 'name', |
| | | resizable: true, |
| | | width: 244, |
| | | }, |
| | | { |
| | | title: '权重', |
| | | align: 'center', |
| | | title() { |
| | | return h( |
| | | 'div', |
| | | { |
| | | style: { |
| | | fontWeight: 'bold', |
| | | } |
| | | }, |
| | | { default: () => '权重' } |
| | | ) |
| | | }, |
| | | width: 180, |
| | | key: 'value', |
| | | render: (row) => { |
| | | return ( |
| | | <n-input-number v-model:value={row.value} min="0" max="10" precision={0} show-button={false} placeholder="请输入1-10" /> |
| | | <n-input-number v-model:value={row.value} width={148} min="0" max="10" precision={0} show-button={false} placeholder="请输入1-10" /> |
| | | ) |
| | | }, |
| | | }, |
| | |
| | | |
| | | const columns1 = computed<DataTableColumns<any>>(() =>[ |
| | | { |
| | | title: '纬度', |
| | | align: 'center', |
| | | title() { |
| | | return h( |
| | | 'div', |
| | | { |
| | | style: { |
| | | fontWeight: 'bold', |
| | | } |
| | | }, |
| | | { default: () => '纬度' } |
| | | ) |
| | | }, |
| | | width: 244, |
| | | resizable: true, |
| | | key: 'name' |
| | | }, |
| | | { |
| | | title: '权重', |
| | | align: 'center', |
| | | title() { |
| | | return h( |
| | | 'div', |
| | | { |
| | | style: { |
| | | fontWeight: 'bold', |
| | | } |
| | | }, |
| | | { default: () => '权重' } |
| | | ) |
| | | }, |
| | | width: 180, |
| | | key: 'value', |
| | | render: (row) => { |
| | | return ( |
| | | <n-input-number v-model:value={row.value} min="0" max="10" precision={0} show-button={false} placeholder="请输入1-10" /> |
| | | <n-input-number v-model:value={row.value} width={148} min="0" max="10" precision={0} show-button={false} placeholder="请输入1-10" /> |
| | | ) |
| | | }, |
| | | }, |
| | |
| | | value: null, |
| | | }, |
| | | ]) |
| | | |
| | | function handleCancel() { |
| | | tabStore.closeTab(route.fullPath) |
| | | router.back() |
| | | } |
| | | |
| | | async function handleSubmit() { |
| | | startLoading() |
| | |
| | | </script> |
| | | |
| | | <template> |
| | | <n-flex class="w-full h-full"> |
| | | <n-card> |
| | | <n-form ref="formRef" :model="model" label-placement="left" inline :show-feedback="false" |
| | | require-mark-placement="left"> |
| | | <div class="w-full h-full relative content"> |
| | | <div class="p-12px"> |
| | | <div class="box py-16px! title mb-12px">交易策略配置</div> |
| | | <n-form ref="formRef" :model="model" label-placement="left" :show-feedback="false" require-mark-placement="left"> |
| | | <n-spin :show="loading"> |
| | | <NSpace vertical :size="16"> |
| | | <!-- 发单策略 --> |
| | | <NSpace vertical :size="16"> |
| | | <div class="text-base font-bold">发单策略</div> |
| | | <div class="pl-4"> |
| | | <n-form-item label="用户取消订单" path="cancleCount" required> |
| | | <n-tooltip placement="top-start" trigger="hover"> |
| | | <template #trigger> |
| | | <icon-park-outline-help /> |
| | | </template> |
| | | 自然日(00:00~24:00)内用户取消订单数超过X单后,不播单 |
| | | </n-tooltip> |
| | | </n-form-item> |
| | | </div> |
| | | <div class="pl-20"> |
| | | <n-form-item label="用户每日取消订单数" path="cancleCount" required> |
| | | <n-input-number v-model:value="model.cancleCount" min="0" :precision="0" :show-button="false" /> |
| | | </n-form-item> |
| | | </div> |
| | | <!-- 发单策略 --> |
| | | <div class="box mb-12px"> |
| | | <div class="head">发单策略</div> |
| | | <n-form-item label="用户每日取消订单数" path="cancleCount" required> |
| | | <n-input-number v-model:value="model.cancleCount" min="0" class="w-272px mr-8px" :precision="0" |
| | | :show-button="false" /> |
| | | <n-tooltip placement="top-start" trigger="hover"> |
| | | <template #trigger> |
| | | <icon-park-outline-help color="#0256ff" /> |
| | | </template> |
| | | 自然日(00:00~24:00)内用户取消订单数超过X单后,不播单 |
| | | </n-tooltip> |
| | | </n-form-item> |
| | | </div> |
| | | <!-- 发单拦截策略(1.0做, mvp版本不做) --> |
| | | <div class="box mb-12px" v-if="false"> |
| | | <div class="head">发单拦截策略</div> |
| | | <div class="mb-12px text-14px"> |
| | | 小额豁免配置 |
| | | </div> |
| | | <NSpace :size="[24, 16]" style="color: rgba(23, 31, 38, 0.8);"> |
| | | <n-form-item label="金额上限" path="smallAmountExemption" label-style="color: rgba(23, 31, 38, 0.8);"> |
| | | <n-input-number v-model:value="model.smallAmountExemption" class="w-200px mr-8px" min="0" :precision="0" |
| | | :show-button="false" />元内可豁免 |
| | | </n-form-item> |
| | | <n-form-item label="豁免城市" path="cityList" label-style="color: rgba(23, 31, 38, 0.8);"> |
| | | <PcaCascader v-model:value="model.cityList" class="w-200px" /> |
| | | </n-form-item> |
| | | <n-form-item label="豁免时效" path="exemptionTime" label-style="color: rgba(23, 31, 38, 0.8);"> |
| | | <n-date-picker v-model:value="model.exemptionTime" type="daterange" clearable class="mr-2 w-[320px]" /> |
| | | <n-checkbox v-model:checked="model.isLongValid"> |
| | | 长期有效 |
| | | </n-checkbox> |
| | | </n-form-item> |
| | | <n-form-item label="豁免角色" path="exemptionRole" label-style="color: rgba(23, 31, 38, 0.8);"> |
| | | <n-select v-model:value="model.exemptionRole" :options="options" multiple class="w-[200px]" /> |
| | | </n-form-item> |
| | | </NSpace> |
| | | <!-- 发单拦截策略(1.0做, mvp版本不做) --> |
| | | <NSpace vertical :size="16" v-if="false"> |
| | | <div class="text-base font-bold">发单拦截策略</div> |
| | | <div class="pl-4"> |
| | | <n-form-item label="小额豁免配置" path="smallAmountExemption" /> |
| | | </div> |
| | | <NSpace vertical class="pl-20" :size="16"> |
| | | <n-form-item label="金额上限" path="smallAmountExemption" required> |
| | | <n-input-number v-model:value="model.smallAmountExemption" min="0" :precision="0" :show-button="false" |
| | | class="mr-2" />元内可豁免 |
| | | </n-form-item> |
| | | <n-form-item label="豁免城市" path="cityList" required> |
| | | <PcaCascader v-model:value="model.cityList" class="w-[240px]" /> |
| | | </n-form-item> |
| | | <n-form-item label="豁免时效" path="exemptionTime" required> |
| | | <n-date-picker v-model:value="model.exemptionTime" type="daterange" clearable |
| | | class="mr-2 w-[240px]" /> |
| | | <n-checkbox v-model:checked="model.isLongValid"> |
| | | 长期有效 |
| | | </n-checkbox> |
| | | </n-form-item> |
| | | <n-form-item label="豁免角色" path="exemptionRole" required> |
| | | <n-select v-model:value="model.exemptionRole" :options="options" multiple class="w-[240px]" /> |
| | | </n-form-item> |
| | | </NSpace> |
| | | <div class="pl-4"> |
| | | <n-form-item label="分级预付配置" path="condition_1" /> |
| | | </div> |
| | | <NSpace vertical class="pl-20" :size="16"> |
| | | <n-form-item label="小额免密授权" path="condition_1"> |
| | | 订单 > |
| | | <n-input-number v-model:value="model.condition_1" min="0" :show-button="false" class="mx-2" /> |
| | | 元,需免密授权 |
| | | </n-form-item> |
| | | <n-form-item label="预付" path="condition_1" required> |
| | | 订单> |
| | | <n-input-number v-model:value="model.condition_1" min="0" :show-button="false" class="mx-2" /> |
| | | 元,需预付 |
| | | </n-form-item> |
| | | </NSpace> |
| | | <div class="mb-12px text-14px mt-24px"> |
| | | 分级预付配置 |
| | | </div> |
| | | <NSpace :size="[24, 16]" style="color: rgba(23, 31, 38, 0.8);"> |
| | | <n-form-item label="小额免密授权" path="condition_1" label-style="color: rgba(23, 31, 38, 0.8);"> |
| | | 订单 > |
| | | <n-input-number v-model:value="model.condition_1" min="0" :show-button="false" class="mx-2 w-200px" /> |
| | | 元,需免密授权 |
| | | </n-form-item> |
| | | <n-form-item label="预付订单 >" path="condition_1" required label-style="color: rgba(23, 31, 38, 0.8);"> |
| | | <n-input-number v-model:value="model.condition_1" min="0" :show-button="false" class="mx-2 w-200px" /> |
| | | 元,需预付 |
| | | </n-form-item> |
| | | </NSpace> |
| | | <!-- 播单策略 --> |
| | | <NSpace vertical :size="16"> |
| | | <div class="text-base font-bold">播单策略</div> |
| | | <NSpace vertical class="pl-20" :size="16"> |
| | | <n-form-item label="第一轮推单" path="onePushDistance" required> |
| | | 推单距离为 |
| | | <n-input-number v-model:value="model.onePushDistance" min="0" :show-button="false" class="mx-2" /> |
| | | 公里,推单时间为 |
| | | <n-input-number v-model:value="model.onePushTime" min="0" :show-button="false" class="mx-2" /> |
| | | 秒 |
| | | </n-form-item> |
| | | <n-form-item label="第二轮推单" path="twoPushDistance" required> |
| | | 推单距离为 |
| | | <n-input-number v-model:value="model.twoPushDistance" min="0" :show-button="false" class="mx-2" /> |
| | | 公里,推单时间为 |
| | | <n-input-number v-model:value="model.twoPushTime" min="0" :show-button="false" class="mx-2" /> |
| | | 秒 |
| | | </n-form-item> |
| | | <n-form-item label="第三轮推单" path="threePushTime" required> |
| | | 推单距离为 |
| | | <n-input-number v-model:value="model.threePushDistance" min="0" :show-button="false" class="mx-2" /> |
| | | 公里,推单时间为 |
| | | <n-input-number v-model:value="model.threePushTime" min="0" :show-button="false" class="mx-2" /> |
| | | 秒 |
| | | </n-form-item> |
| | | <n-form-item label="第四轮推单" path="fourPushDistance" required> |
| | | 推单距离为 |
| | | <n-input-number v-model:value="model.fourPushDistance" min="0" :show-button="false" class="mx-2" /> |
| | | 公里,推单时间为 |
| | | <n-input-number v-model:value="model.fourPushTime" min="0" :show-button="false" class="mx-2" /> |
| | | 秒 |
| | | </n-form-item> |
| | | <n-form-item label="第五轮推单" path="fivePushDistance" required> |
| | | 推单距离为 |
| | | <n-input-number v-model:value="model.fivePushDistance" min="0" :show-button="false" class="mx-2" /> |
| | | 公里,推单时间为 |
| | | <n-input-number v-model:value="model.fivePushTime" min="0" :show-button="false" class="mx-2" /> |
| | | 秒 |
| | | </n-form-item> |
| | | </NSpace> |
| | | </div> |
| | | <!-- 播单策略 --> |
| | | <div class="box mb-12px"> |
| | | <div class="head">播单策略</div> |
| | | <NSpace :size="[24, 16]" style="color: rgba(23, 31, 38, 0.8);"> |
| | | <n-form-item label="第一轮推单:" path="onePushDistance" required label-style="color: rgba(23, 31, 38, 0.8);"> |
| | | 推单距离为 |
| | | <n-input-number v-model:value="model.onePushDistance" min="0" :show-button="false" |
| | | class="mx-2 w-102px" /> |
| | | 公里,推单时间为 |
| | | <n-input-number v-model:value="model.onePushTime" min="0" :show-button="false" class="mx-2 w-102px" /> |
| | | 秒 |
| | | </n-form-item> |
| | | <n-form-item label="第二轮推单:" path="twoPushDistance" required label-style="color: rgba(23, 31, 38, 0.8);"> |
| | | 推单距离为 |
| | | <n-input-number v-model:value="model.twoPushDistance" min="0" :show-button="false" |
| | | class="mx-2 w-102px" /> |
| | | 公里,推单时间为 |
| | | <n-input-number v-model:value="model.twoPushTime" min="0" :show-button="false" class="mx-2 w-102px" /> |
| | | 秒 |
| | | </n-form-item> |
| | | <n-form-item label="第三轮推单:" path="threePushTime" required label-style="color: rgba(23, 31, 38, 0.8);"> |
| | | 推单距离为 |
| | | <n-input-number v-model:value="model.threePushDistance" min="0" :show-button="false" |
| | | class="mx-2 w-102px" /> |
| | | 公里,推单时间为 |
| | | <n-input-number v-model:value="model.threePushTime" min="0" :show-button="false" class="mx-2 w-102px" /> |
| | | 秒 |
| | | </n-form-item> |
| | | <n-form-item label="第四轮推单:" path="fourPushDistance" required label-style="color: rgba(23, 31, 38, 0.8);"> |
| | | 推单距离为 |
| | | <n-input-number v-model:value="model.fourPushDistance" min="0" :show-button="false" |
| | | class="mx-2 w-102px" /> |
| | | 公里,推单时间为 |
| | | <n-input-number v-model:value="model.fourPushTime" min="0" :show-button="false" class="mx-2 w-102px" /> |
| | | 秒 |
| | | </n-form-item> |
| | | <n-form-item label="第五轮推单:" path="fivePushDistance" required label-style="color: rgba(23, 31, 38, 0.8);"> |
| | | 推单距离为 |
| | | <n-input-number v-model:value="model.fivePushDistance" min="0" :show-button="false" |
| | | class="mx-2 w-102px" /> |
| | | 公里,推单时间为 |
| | | <n-input-number v-model:value="model.fivePushTime" min="0" :show-button="false" class="mx-2 w-102px" /> |
| | | 秒 |
| | | </n-form-item> |
| | | </NSpace> |
| | | <!-- 分单策略 --> |
| | | <NSpace vertical :size="16"> |
| | | <div class="text-base font-bold">分单策略</div> |
| | | <NSpace vertical class="pl-20" :size="16"> |
| | | <n-form-item label="举手规则配置" path="ruleType" required> |
| | | <n-radio-group v-model:value="model.ruleType" name="radiobuttongroup1"> |
| | | <n-radio-button :value="1" label="单手举手" /> |
| | | <n-radio-button :value="2" label="多手举手" /> |
| | | </n-radio-group> |
| | | </n-form-item> |
| | | <n-form-item label="最多" path="simultaneouslyOrderCount" required class="pl-20"> |
| | | <n-input-number v-model:value="model.simultaneouslyOrderCount" min="0" :show-button="false" |
| | | class="mr-2" /> |
| | | 可同时抢单 |
| | | </n-form-item> |
| | | </NSpace> |
| | | <NSpace vertical class="pl-20" :size="16"> |
| | | </div> |
| | | <!-- 分单策略 --> |
| | | <div class="box"> |
| | | <div class="head">分单策略</div> |
| | | <NSpace vertical :size="16" style="color: rgba(23, 31, 38, 0.8);" class="mb-24px"> |
| | | <n-form-item label="举手规则配置" path="ruleType" required label-style="color: rgba(23, 31, 38, 0.8);"> |
| | | <n-radio-group v-model:value="model.ruleType" name="radiobuttongroup1"> |
| | | <n-radio-button :value="1" label="单手举手" /> |
| | | <n-radio-button :value="2" label="多手举手" /> |
| | | </n-radio-group> |
| | | </n-form-item> |
| | | <n-form-item label="最多" path="simultaneouslyOrderCount" required |
| | | label-style="color: rgba(23, 31, 38, 0.8);"> |
| | | <n-input-number v-model:value="model.simultaneouslyOrderCount" min="0" :show-button="false" |
| | | class="mr-2 w-218px" /> |
| | | 可同时抢单 |
| | | </n-form-item> |
| | | </NSpace> |
| | | <NSpace :size="[24, 16]"> |
| | | <NSpace vertical :size="8"> |
| | | <n-form-item label="分单倾向配置" path="splitOrderPreference" required> |
| | | </n-form-item> |
| | | <div class="pl-30 w-[500px]"> |
| | | <n-data-table :columns="columns" :data="data" /> |
| | | <div class=" w-[424px]"> |
| | | <n-data-table :columns="columns" :data="data" :bordered="false"/> |
| | | </div> |
| | | </NSpace> |
| | | <NSpace vertical :size="8"> |
| | | <n-form-item label="订单价值权重配置" path="orderValueWeight" required> |
| | | </n-form-item> |
| | | <div class="pl-30 w-[500px]"> |
| | | <n-data-table :columns="columns1" :data="data1" /> |
| | | <div class=" w-[424px]"> |
| | | <n-data-table :columns="columns1" :data="data1" :bordered="false"/> |
| | | </div> |
| | | </NSpace> |
| | | </NSpace> |
| | | </NSpace> |
| | | </div> |
| | | </n-spin> |
| | | </n-form> |
| | | <NSpace justify="center" class="w-[50%] mt-12"> |
| | | <NButton type='primary' @click="handleSubmit"> |
| | | </div> |
| | | <div class="footer"> |
| | | <NSpace justify="end" :size="8"> |
| | | <NButton strong @click="handleCancel" class="w-84px"> |
| | | 取消 |
| | | </NButton> |
| | | <NButton type='primary' @click="handleSubmit" class="w-84px"> |
| | | 保存 |
| | | </NButton> |
| | | </NSpace> |
| | | </n-card> |
| | | </n-flex> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <style scoped lang="scss"> |
| | | .content { |
| | | height: calc(100vh - 76px); |
| | | width: 100%; |
| | | overflow-y: auto; |
| | | scrollbar-width: none; |
| | | |
| | | &::-webkit-scrollbar { |
| | | display: none; |
| | | } |
| | | } |
| | | |
| | | .box { |
| | | padding: 24px; |
| | | background-color: #fff; |
| | | border-radius: 6px; |
| | | width: 100%; |
| | | box-sizing: border-box; |
| | | --n-label-text-color: rgba(23, 31, 38, 0.8); |
| | | } |
| | | |
| | | .title { |
| | | font-size: 20px; |
| | | color: #171F26; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | .head { |
| | | font-family: PingFang SC; |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | line-height: 24px; |
| | | letter-spacing: normal; |
| | | color: #171F26; |
| | | position: relative; |
| | | text-indent: 11px; |
| | | margin-bottom: 16px; |
| | | |
| | | &::before { |
| | | content: ''; |
| | | position: absolute; |
| | | top: 50%; |
| | | left: 0; |
| | | transform: translateY(-50%); |
| | | width: 3px; |
| | | height: 14px; |
| | | z-index: 0; |
| | | border-radius: 3px; |
| | | background: #0068FF; |
| | | } |
| | | |
| | | } |
| | | |
| | | .footer { |
| | | position: sticky; |
| | | bottom: 0; |
| | | left: 0; |
| | | width: 100%; |
| | | height: 64px; |
| | | background-color: #fff; |
| | | box-shadow: 0px 0px 5px 0px rgba(23, 31, 38, 0.05); |
| | | padding: 16px 24px; |
| | | |
| | | } |
| | | </style> |