generated from Leo_Ding/web-template
Merge branch 'master' of https://gitlab.guxuan.icu/Leo_Ding/hahaPension_admin
This commit is contained in:
commit
1c7f8b381d
@ -20,3 +20,6 @@ export const getBackWorkOrderList = (params) => request.basic.get(`/api/v1/order
|
|||||||
// 工单详情
|
// 工单详情
|
||||||
export const getWorkOrderDetail = (id) => request.basic.get(`/api/v1/orders/${id}`)
|
export const getWorkOrderDetail = (id) => request.basic.get(`/api/v1/orders/${id}`)
|
||||||
|
|
||||||
|
// 派单
|
||||||
|
export const sendWorkOrder = (id, params) => request.basic.put(`/api/v1/orders${id}`, params)
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-modal :open="modal.open" :title="modal.title" :width="600" :confirm-loading="modal.confirmLoading"
|
<a-modal :open="modal.open" :title="modal.title" :width="750" :confirm-loading="modal.confirmLoading"
|
||||||
:after-close="onAfterClose" :cancel-text="cancelText" @ok="handleOk" @cancel="handleCancel">
|
:after-close="onAfterClose" :cancel-text="cancelText" @ok="handleOk" @cancel="handleCancel">
|
||||||
<a-card>
|
<a-card>
|
||||||
<a-form ref="formRef" :model="formData" :rules="formRules">
|
<a-form ref="formRef" :model="formData" :rules="formRules">
|
||||||
@ -33,7 +33,7 @@
|
|||||||
<template #addonAfter>
|
<template #addonAfter>
|
||||||
<a-select v-model:value="formData.priceUnit" style="width: 100px">
|
<a-select v-model:value="formData.priceUnit" style="width: 100px">
|
||||||
<a-select-option value="次">元/次</a-select-option>
|
<a-select-option value="次">元/次</a-select-option>
|
||||||
<a-select-option value="时">元/时</a-select-option>
|
<a-select-option value="时">元/小时</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</template>
|
</template>
|
||||||
</a-input-number>
|
</a-input-number>
|
||||||
@ -52,9 +52,9 @@
|
|||||||
<a-form-item label="服务频次" name="frequency">
|
<a-form-item label="服务频次" name="frequency">
|
||||||
<a-input-number v-model:value="formData.frequency" style="width: 100%;">
|
<a-input-number v-model:value="formData.frequency" style="width: 100%;">
|
||||||
<template #addonAfter>
|
<template #addonAfter>
|
||||||
<a-select v-model:value="formData.frequencyUnit" style="width: 80px">
|
<a-select v-model:value="formData.frequencyUnit" style="width: 120px">
|
||||||
<a-select-option value="元/次">元/次</a-select-option>
|
<a-select-option value="元/次">小时/次</a-select-option>
|
||||||
<a-select-option value="元/台">元/台</a-select-option>
|
<a-select-option value="元/台">小时/台</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</template>
|
</template>
|
||||||
</a-input-number>
|
</a-input-number>
|
||||||
|
|||||||
@ -50,6 +50,10 @@
|
|||||||
<template v-if="column.key === 'categoryType'">
|
<template v-if="column.key === 'categoryType'">
|
||||||
<span>{{ dicsStore.getDictLabel('PROJECT_TYPE', record.categoryType) }}</span>
|
<span>{{ dicsStore.getDictLabel('PROJECT_TYPE', record.categoryType) }}</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template v-if="column.key === 'price'">
|
||||||
|
<span>{{ record.price + record.frequencyUnit }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
<template v-if="'action' === column.key">
|
<template v-if="'action' === column.key">
|
||||||
<x-action-button @click="$refs.editDialogRef.handleEdit(record)">
|
<x-action-button @click="$refs.editDialogRef.handleEdit(record)">
|
||||||
@ -85,7 +89,7 @@ const columns = [
|
|||||||
{ title: '分类名称', dataIndex: 'name', key: 'name', align: 'center', width: 180, },
|
{ title: '分类名称', dataIndex: 'name', key: 'name', align: 'center', width: 180, },
|
||||||
{ title: '项目名称', dataIndex: 'name', key: 'name', align: 'center', },
|
{ title: '项目名称', dataIndex: 'name', key: 'name', align: 'center', },
|
||||||
{ title: '价格', dataIndex: 'price', key: 'price', align: 'center', },
|
{ title: '价格', dataIndex: 'price', key: 'price', align: 'center', },
|
||||||
{ title: '简介', dataIndex: 'remark', key: 'remark', align: 'center', },
|
{ title: '简介', dataIndex: 'content', key: 'content', align: 'center', },
|
||||||
|
|
||||||
{ title: '操作', dataIndex: 'action', key: 'action', align: 'center', width: 120, fixed: 'right', }
|
{ title: '操作', dataIndex: 'action', key: 'action', align: 'center', width: 120, fixed: 'right', }
|
||||||
];
|
];
|
||||||
|
|||||||
@ -28,12 +28,17 @@
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
<a-form-item :label="'组织机构代码'" name="orgCode" :required="true">
|
<a-form-item :label="'服务组织编号'" name="orgCode" :required="true">
|
||||||
<a-input v-model:value="formData.orgCode" placeholder="统一社会信用代码或组织机构代码" allow-clear />
|
<a-input v-model:value="formData.orgCode" placeholder="请输入服务组织编号" allow-clear />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
<a-row :gutter="16">
|
<a-row :gutter="16">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item :label="'组织机构代码'" name="orgCode33" :required="false">
|
||||||
|
<a-input v-model:value="formData.orgCode33" placeholder="请输入服务组织编号" allow-clear />
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
<a-form-item :label="'组织等级'" name="orgLv" :required="true">
|
<a-form-item :label="'组织等级'" name="orgLv" :required="true">
|
||||||
<a-select v-model:value="formData.orgLv" placeholder="请选择组织等级" allow-clear>
|
<a-select v-model:value="formData.orgLv" placeholder="请选择组织等级" allow-clear>
|
||||||
@ -242,6 +247,7 @@ const editingId = ref(null);
|
|||||||
const formData = reactive({
|
const formData = reactive({
|
||||||
name: '',
|
name: '',
|
||||||
orgCode: '',
|
orgCode: '',
|
||||||
|
orgCode33: '',
|
||||||
orgLv: '',
|
orgLv: '',
|
||||||
concatName: '',
|
concatName: '',
|
||||||
concatPhone: '',
|
concatPhone: '',
|
||||||
|
|||||||
@ -119,7 +119,7 @@
|
|||||||
<a-button type="link" size="small" @click="handleDetail(record)">详情</a-button>
|
<a-button type="link" size="small" @click="handleDetail(record)">详情</a-button>
|
||||||
<a-divider type="vertical" />
|
<a-divider type="vertical" />
|
||||||
<a-button type="link" size="small" @click="handleToggleStatus(record)">
|
<a-button type="link" size="small" @click="handleToggleStatus(record)">
|
||||||
{{ record.status === 'enabled' ? '停用' : '启用' }}
|
{{ record.status === '1' ? '停用' : '启用' }}
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-divider type="vertical" />
|
<a-divider type="vertical" />
|
||||||
<!-- <a-button type="link" size="small" @click="handleDeviceManagement(record)">设备管理</a-button> -->
|
<!-- <a-button type="link" size="small" @click="handleDeviceManagement(record)">设备管理</a-button> -->
|
||||||
|
|||||||
@ -1,28 +1,12 @@
|
|||||||
<!-- src/components/DispatchDrawer.vue -->
|
<!-- src/components/DispatchDrawer.vue -->
|
||||||
<template>
|
<template>
|
||||||
<a-drawer
|
<a-drawer title="派单" :open="open" :width="600" @close="handleCancel" :destroy-on-close="true">
|
||||||
title="派单"
|
<a-form :rules="rules" ref="formRef" layout="vertical" class="form-mode" :model="formModel">
|
||||||
:open="visible"
|
|
||||||
:width="600"
|
|
||||||
@close="handleClose"
|
|
||||||
:destroy-on-close="true"
|
|
||||||
>
|
|
||||||
<a-form
|
|
||||||
:model="formModel"
|
|
||||||
:rules="rules"
|
|
||||||
ref="formRef"
|
|
||||||
layout="vertical"
|
|
||||||
class="form-mode"
|
|
||||||
>
|
|
||||||
<!-- 服务对象 -->
|
<!-- 服务对象 -->
|
||||||
<a-row :gutter="16">
|
<a-row :gutter="16">
|
||||||
<a-col :xs="12">
|
<a-col :xs="12">
|
||||||
<a-form-item label="服务对象">
|
<a-form-item label="服务对象">
|
||||||
<a-input
|
<a-input v-model:value="formModel.serviceTarget" placeholder="请输入服务对象名称" disabled />
|
||||||
v-model:value="formModel.serviceTarget"
|
|
||||||
placeholder="请输入服务对象名称"
|
|
||||||
disabled
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
@ -31,11 +15,7 @@
|
|||||||
<a-row :gutter="16">
|
<a-row :gutter="16">
|
||||||
<a-col :xs="12">
|
<a-col :xs="12">
|
||||||
<a-form-item label="服务项目" name="serviceItem">
|
<a-form-item label="服务项目" name="serviceItem">
|
||||||
<a-select
|
<a-select v-model:value="formModel.serviceItem" placeholder="请选择服务项目" mode="multiple">
|
||||||
v-model:value="formModel.serviceItem"
|
|
||||||
placeholder="请选择服务项目"
|
|
||||||
mode="multiple"
|
|
||||||
>
|
|
||||||
<a-select-option value="兴趣活动">兴趣活动</a-select-option>
|
<a-select-option value="兴趣活动">兴趣活动</a-select-option>
|
||||||
<a-select-option value="居家照护">居家照护</a-select-option>
|
<a-select-option value="居家照护">居家照护</a-select-option>
|
||||||
<a-select-option value="医疗护理">医疗护理</a-select-option>
|
<a-select-option value="医疗护理">医疗护理</a-select-option>
|
||||||
@ -44,12 +24,8 @@
|
|||||||
</a-col>
|
</a-col>
|
||||||
<a-col :xs="12">
|
<a-col :xs="12">
|
||||||
<a-form-item label="服务费用">
|
<a-form-item label="服务费用">
|
||||||
<a-input-number
|
<a-input-number v-model:value="formModel.serviceFee" placeholder="由关联服务项目计算得出" style="width: 100%"
|
||||||
v-model:value="formModel.serviceFee"
|
:min="0" />
|
||||||
placeholder="由关联服务项目计算得出"
|
|
||||||
style="width: 100%"
|
|
||||||
:min="0"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
@ -58,15 +34,8 @@
|
|||||||
<a-row :gutter="16">
|
<a-row :gutter="16">
|
||||||
<a-col :xs="12">
|
<a-col :xs="12">
|
||||||
<a-form-item label="服务人员" name="serviceStaff">
|
<a-form-item label="服务人员" name="serviceStaff">
|
||||||
<a-select
|
<a-select v-model:value="formModel.serviceStaff" placeholder="请选择服务人员">
|
||||||
v-model:value="formModel.serviceStaff"
|
<a-select-option v-for="user in assignees" :key="user.id" :value="user.id">
|
||||||
placeholder="请选择服务人员"
|
|
||||||
>
|
|
||||||
<a-select-option
|
|
||||||
v-for="user in assignees"
|
|
||||||
:key="user.id"
|
|
||||||
:value="user.id"
|
|
||||||
>
|
|
||||||
{{ user.name }}
|
{{ user.name }}
|
||||||
</a-select-option>
|
</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
@ -78,11 +47,7 @@
|
|||||||
<a-row :gutter="16">
|
<a-row :gutter="16">
|
||||||
<a-col :xs="24">
|
<a-col :xs="24">
|
||||||
<a-form-item label="计划日期" name="plannedDate">
|
<a-form-item label="计划日期" name="plannedDate">
|
||||||
<a-range-picker
|
<a-range-picker v-model:value="formModel.plannedDate" style="width: 100%" :placeholder="['开始日期', '结束日期']" />
|
||||||
v-model:value="formModel.plannedDate"
|
|
||||||
style="width: 100%"
|
|
||||||
:placeholder="['开始日期', '结束日期']"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
@ -91,21 +56,13 @@
|
|||||||
<a-row :gutter="16">
|
<a-row :gutter="16">
|
||||||
<a-col :xs="12">
|
<a-col :xs="12">
|
||||||
<a-form-item label="计划开始时间" name="plannedStartTime">
|
<a-form-item label="计划开始时间" name="plannedStartTime">
|
||||||
<a-time-picker
|
<a-time-picker v-model:value="formModel.plannedStartTime" placeholder="请选择计划开始时间" style="width: 100%"
|
||||||
v-model:value="formModel.plannedStartTime"
|
format="HH:mm" :minute-step="5" />
|
||||||
placeholder="请选择计划开始时间"
|
|
||||||
style="width: 100%"
|
|
||||||
format="HH:mm"
|
|
||||||
:minute-step="5"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :xs="12">
|
<a-col :xs="12">
|
||||||
<a-form-item label="要求工单时长" name="requiredDuration">
|
<a-form-item label="要求工单时长" name="requiredDuration">
|
||||||
<a-input
|
<a-input v-model:value="formModel.requiredDuration" placeholder="请输入要求工单时长">
|
||||||
v-model:value="formModel.requiredDuration"
|
|
||||||
placeholder="请输入要求工单时长"
|
|
||||||
>
|
|
||||||
<template #suffix>分钟</template>
|
<template #suffix>分钟</template>
|
||||||
</a-input>
|
</a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
@ -116,14 +73,8 @@
|
|||||||
<a-row :gutter="16">
|
<a-row :gutter="16">
|
||||||
<a-col :xs="24">
|
<a-col :xs="24">
|
||||||
<a-form-item label="服务地址" name="serviceArea">
|
<a-form-item label="服务地址" name="serviceArea">
|
||||||
<AreaCascader
|
<AreaCascader v-model:value="formModel.serviceArea" style="width: 100%; margin-bottom: 8px;" />
|
||||||
v-model:value="formModel.serviceArea"
|
<a-input v-model:value="formModel.detailedAddress" placeholder="详细地址" />
|
||||||
style="width: 100%; margin-bottom: 8px;"
|
|
||||||
/>
|
|
||||||
<a-input
|
|
||||||
v-model:value="formModel.detailedAddress"
|
|
||||||
placeholder="详细地址"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
@ -132,10 +83,7 @@
|
|||||||
<a-row :gutter="16">
|
<a-row :gutter="16">
|
||||||
<a-col :xs="24">
|
<a-col :xs="24">
|
||||||
<a-form-item label="服务内容">
|
<a-form-item label="服务内容">
|
||||||
<a-input
|
<a-input v-model:value="formModel.serviceContent" placeholder="填写服务内容,充当备注作用,此字段数据会在app工单中显示" />
|
||||||
v-model:value="formModel.serviceContent"
|
|
||||||
placeholder="填写服务内容,充当备注作用,此字段数据会在app工单中显示"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
@ -143,8 +91,8 @@
|
|||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="select-btn" style="display: flex; justify-content: flex-end; gap: 8px;">
|
<div class="select-btn" style="display: flex; justify-content: flex-end; gap: 8px;">
|
||||||
<a-button @click="handleClose">取消</a-button>
|
<a-button @click="handleCancel">取消</a-button>
|
||||||
<a-button type="primary" @click="handleSubmit">确定</a-button>
|
<a-button type="primary" @click="handleOk" :loading="confirmLoading">确定</a-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</a-drawer>
|
</a-drawer>
|
||||||
@ -153,9 +101,13 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, watch, nextTick } from 'vue'
|
import { ref, reactive, watch, nextTick } from 'vue'
|
||||||
import AreaCascader from '@/components/AreaCascader/index.vue'
|
import AreaCascader from '@/components/AreaCascader/index.vue'
|
||||||
|
import { message } from 'ant-design-vue'
|
||||||
|
import apis from '@/apis'
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
|
||||||
|
// 定义 props
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
visible: {
|
open: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
@ -171,12 +123,17 @@ const props = defineProps({
|
|||||||
|
|
||||||
const emit = defineEmits(['close', 'submit'])
|
const emit = defineEmits(['close', 'submit'])
|
||||||
|
|
||||||
|
// 响应式数据
|
||||||
const formRef = ref()
|
const formRef = ref()
|
||||||
|
const confirmLoading = ref(false)
|
||||||
|
|
||||||
|
// 使用 formModel 替代 formData,保持与模板一致
|
||||||
const formModel = reactive({
|
const formModel = reactive({
|
||||||
serviceTarget: '',
|
serviceTarget: '',
|
||||||
serviceItem: [],
|
serviceItem: [],
|
||||||
serviceFee: undefined,
|
serviceFee: undefined,
|
||||||
serviceStaff: undefined,
|
serviceStaff: undefined,
|
||||||
|
serviceStaffId: undefined,
|
||||||
plannedDate: [],
|
plannedDate: [],
|
||||||
plannedStartTime: null,
|
plannedStartTime: null,
|
||||||
requiredDuration: '',
|
requiredDuration: '',
|
||||||
@ -185,6 +142,7 @@ const formModel = reactive({
|
|||||||
serviceContent: ''
|
serviceContent: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 表单验证规则
|
||||||
const rules = {
|
const rules = {
|
||||||
serviceItem: [{ required: true, message: '请选择服务项目', trigger: 'change' }],
|
serviceItem: [{ required: true, message: '请选择服务项目', trigger: 'change' }],
|
||||||
serviceStaff: [{ required: true, message: '请选择服务人员', trigger: 'change' }],
|
serviceStaff: [{ required: true, message: '请选择服务人员', trigger: 'change' }],
|
||||||
@ -195,47 +153,195 @@ const rules = {
|
|||||||
detailedAddress: [{ required: true, message: '请输入详细地址', trigger: 'blur' }]
|
detailedAddress: [{ required: true, message: '请输入详细地址', trigger: 'blur' }]
|
||||||
}
|
}
|
||||||
|
|
||||||
// 监听 visible 变化,初始化表单
|
// ================== Methods ==================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确认提交
|
||||||
|
*/
|
||||||
|
async function handleOk() {
|
||||||
|
try {
|
||||||
|
confirmLoading.value = true
|
||||||
|
await formRef.value.validate()
|
||||||
|
|
||||||
|
// 构建日期时间
|
||||||
|
let plannedStart = null
|
||||||
|
let plannedEnd = null
|
||||||
|
if (formModel.plannedDate[0] && formModel.plannedStartTime) {
|
||||||
|
const datePart = formModel.plannedDate[0].format('YYYY-MM-DD')
|
||||||
|
const timePart = formModel.plannedStartTime.format('HH:mm')
|
||||||
|
plannedStart = dayjs(`${datePart} ${timePart}`)
|
||||||
|
plannedEnd = plannedStart.add(Number(formModel.requiredDuration) || 0, 'minute')
|
||||||
|
}
|
||||||
|
|
||||||
|
const submitData = {
|
||||||
|
customerId: props.initialValues.id,
|
||||||
|
projects: formModel.serviceItem,
|
||||||
|
price: formModel.serviceFee,
|
||||||
|
servicePerson: formModel.serviceStaff,
|
||||||
|
servicePersonId: formModel.serviceStaffId,
|
||||||
|
plannedStartDate: plannedStart?.toISOString() || null,
|
||||||
|
plannedEndDate: plannedEnd?.toISOString() || null,
|
||||||
|
plannedServiceStartDate: Number(formModel.requiredDuration) || 0,
|
||||||
|
areaLabels: formModel.serviceArea,
|
||||||
|
areaCodes: formModel.serviceArea.join(','),
|
||||||
|
detailAddress: formModel.detailedAddress,
|
||||||
|
content: formModel.serviceContent
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('提交数据:', submitData)
|
||||||
|
|
||||||
|
const { success } = await apis.workOrder.sendWorkOrder(submitData)
|
||||||
|
if (success) {
|
||||||
|
message.success('派单成功')
|
||||||
|
emit('submit', submitData)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log('表单校验或提交失败:', error)
|
||||||
|
// 可选:message.error('派单失败')
|
||||||
|
} finally {
|
||||||
|
confirmLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消/关闭弹框
|
||||||
|
*/
|
||||||
|
function handleCancel() {
|
||||||
|
resetFormModel()
|
||||||
|
emit('close')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置表单数据
|
||||||
|
*/
|
||||||
|
function resetFormModel() {
|
||||||
|
Object.keys(formModel).forEach(key => {
|
||||||
|
if (Array.isArray(formModel[key])) {
|
||||||
|
formModel[key] = []
|
||||||
|
} else if (typeof formModel[key] === 'string') {
|
||||||
|
formModel[key] = ''
|
||||||
|
} else {
|
||||||
|
formModel[key] = undefined
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 使用 clearValidate 而不是 resetFields
|
||||||
|
if (formRef.value?.clearValidate) {
|
||||||
|
formRef.value.clearValidate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置表单字段值
|
||||||
|
*/
|
||||||
|
function setFormFields(values) {
|
||||||
|
// 逐个字段赋值,确保响应式系统能追踪
|
||||||
|
for (const key in formModel) {
|
||||||
|
if (key in values) {
|
||||||
|
formModel[key] = values[key]
|
||||||
|
} else {
|
||||||
|
// 重置为默认值(可选)
|
||||||
|
formModel[key] = Array.isArray(formModel[key]) ? [] : typeof formModel[key] === 'string' ? '' : undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nextTick(() => {
|
||||||
|
if (formRef.value?.clearValidate) {
|
||||||
|
formRef.value.clearValidate()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载工单详情并填充表单
|
||||||
|
* @param {string} id - 工单ID
|
||||||
|
*/
|
||||||
|
async function loadWorkOrderDetail(id) {
|
||||||
|
console.log('开始加载工单详情,ID:', id)
|
||||||
|
try {
|
||||||
|
const { success, data } = await apis.workOrder.getWorkOrderDetail(id)
|
||||||
|
console.log('工单详情接口响应:', { success, data })
|
||||||
|
|
||||||
|
if (success && data) {
|
||||||
|
const detailData = data
|
||||||
|
console.log('工单详情数据:', detailData)
|
||||||
|
let projects = detailData.projects.map(item => item.name)
|
||||||
|
|
||||||
|
// 构建表单数据
|
||||||
|
const formData = {
|
||||||
|
serviceTarget: detailData.customer.name || '',
|
||||||
|
serviceItem: projects,
|
||||||
|
serviceFee: detailData.price,
|
||||||
|
serviceStaff: detailData.servicePerson || undefined,
|
||||||
|
servicePersonId: detailData.servicePersonId,
|
||||||
|
plannedDate: detailData.plannedEndDate ? [
|
||||||
|
dayjs(detailData.plannedEndDate),
|
||||||
|
dayjs(detailData.plannedEndDate)
|
||||||
|
] : [],
|
||||||
|
// ✅ 修复:直接用完整时间字符串构造 Day.js 对象
|
||||||
|
plannedStartTime: detailData.plannedStartDate
|
||||||
|
? dayjs(detailData.plannedStartDate)
|
||||||
|
: null,
|
||||||
|
requiredDuration: detailData.plannedServiceStartDate ?
|
||||||
|
String(detailData.plannedServiceStartDate) : '',
|
||||||
|
serviceArea: (detailData.areaLabels || []).join('/'),
|
||||||
|
detailedAddress: detailData.detailAddress || '',
|
||||||
|
serviceContent: detailData.content || ''
|
||||||
|
}
|
||||||
|
console.log('构建的表单数据:', formData)
|
||||||
|
|
||||||
|
// 设置表单字段
|
||||||
|
setFormFields(formData)
|
||||||
|
|
||||||
|
console.log('设置后的 formModel:', formModel)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
message.error('获取工单详情失败')
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取工单详情失败:', error)
|
||||||
|
// message.error('加载工单信息失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 辅助函数:将区域字符串转换为数组格式
|
||||||
|
* @param {string} areaString - 区域字符串
|
||||||
|
* @returns {Array} 区域数组
|
||||||
|
*/
|
||||||
|
function parseAreaToArray(areaString) {
|
||||||
|
if (!areaString) return []
|
||||||
|
return areaString.split('/') || []
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听 open 变化,初始化表单
|
||||||
watch(
|
watch(
|
||||||
() => props.visible,
|
() => props.open,
|
||||||
(newVal) => {
|
async (newVal) => {
|
||||||
if (newVal) {
|
if (newVal) {
|
||||||
nextTick(() => {
|
console.log('抽屉打开,重置表单')
|
||||||
if (Object.keys(props.initialValues).length > 0) {
|
resetFormModel()
|
||||||
Object.assign(formModel, props.initialValues)
|
|
||||||
} else {
|
// 等待 DOM 更新完成
|
||||||
// 重置
|
await nextTick()
|
||||||
for (const key in formModel) {
|
|
||||||
if (Array.isArray(formModel[key])) {
|
if (props.initialValues && props.initialValues.id) {
|
||||||
formModel[key] = []
|
console.log('加载工单详情,ID:', props.initialValues.id)
|
||||||
} else if (typeof formModel[key] === 'string') {
|
await loadWorkOrderDetail(props.initialValues.id)
|
||||||
formModel[key] = ''
|
} else {
|
||||||
} else {
|
console.log('新建派单,无初始值')
|
||||||
formModel[key] = undefined
|
// 设置测试数据
|
||||||
}
|
setFormFields({
|
||||||
}
|
serviceTarget: '新建测试数据',
|
||||||
formRef.value?.resetFields()
|
serviceItem: ['兴趣活动'],
|
||||||
}
|
serviceFee: 100,
|
||||||
})
|
requiredDuration: '60'
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const handleClose = () => {
|
|
||||||
formRef.value?.resetFields()
|
|
||||||
emit('close')
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
|
||||||
try {
|
|
||||||
const values = await formRef.value.validateFields()
|
|
||||||
// 合并 model 和校验后的值(确保类型正确)
|
|
||||||
emit('submit', { ...formModel })
|
|
||||||
handleClose()
|
|
||||||
} catch (error) {
|
|
||||||
console.log('校验失败:', error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@ -135,7 +135,7 @@
|
|||||||
<a-button type="primary">导出记录</a-button>
|
<a-button type="primary">导出记录</a-button>
|
||||||
</a-space>
|
</a-space>
|
||||||
</div>
|
</div>
|
||||||
<a-table rowKey="id" :loading="loading" :pagination="paginationConfig" :columns="columns"
|
<a-table rowKey="id" :loading="loading" :pagination="paginationState" :columns="columns"
|
||||||
:data-source="listData" :scroll="{ x: totalWidth }" @change="onTableChange">
|
:data-source="listData" :scroll="{ x: totalWidth }" @change="onTableChange">
|
||||||
<template #bodyCell="{ column, record, index }">
|
<template #bodyCell="{ column, record, index }">
|
||||||
<template v-if="column.key === 'serialNumber'">
|
<template v-if="column.key === 'serialNumber'">
|
||||||
@ -161,8 +161,12 @@
|
|||||||
</a-row>
|
</a-row>
|
||||||
|
|
||||||
<!-- 派单抽屉(右侧弹出) -->
|
<!-- 派单抽屉(右侧弹出) -->
|
||||||
<DispatchDrawer :visible="showDrawer" :assignees="staffList" :initial-values="initialValues"
|
<DispatchDrawer
|
||||||
@close="showDrawer = false" @submit="handleDispatchSubmit" />
|
:open="showDrawer"
|
||||||
|
:assignees="staffList"
|
||||||
|
:initial-values="drawerInitialValues"
|
||||||
|
@close="handleDrawerClose"
|
||||||
|
@submit="handleDispatchSubmit" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@ -172,14 +176,18 @@ import { message } from 'ant-design-vue'
|
|||||||
import { ref, computed } from 'vue'
|
import { ref, computed } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import DispatchDrawer from './components/DispatchDrawer.vue';
|
import DispatchDrawer from './components/DispatchDrawer.vue';
|
||||||
|
import apis from '@/apis'
|
||||||
|
import { usePagination } from '@/hooks'
|
||||||
|
import storage from '@/utils/storage'
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'allocation',
|
name: 'allocation',
|
||||||
})
|
})
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
const { listData, loading, showLoading, hideLoading, paginationState, resetPagination, searchFormData } = usePagination()
|
||||||
|
|
||||||
// 表格列(修正部分字段映射,原 columns 有错误)
|
// 表格列
|
||||||
const columns = [
|
const columns = [
|
||||||
{ title: '序号', key: 'serialNumber', align: 'center', width: 60 },
|
{ title: '序号', key: 'serialNumber', align: 'center', width: 60 },
|
||||||
{ title: '工单号', dataIndex: 'orderNum', key: 'orderNum', align: 'center', width: 120 },
|
{ title: '工单号', dataIndex: 'orderNum', key: 'orderNum', align: 'center', width: 120 },
|
||||||
@ -197,80 +205,56 @@ const columns = [
|
|||||||
{ title: '操作', key: 'action', width: 100, fixed: 'right' }
|
{ title: '操作', key: 'action', width: 100, fixed: 'right' }
|
||||||
]
|
]
|
||||||
|
|
||||||
// 分页状态
|
|
||||||
const paginationState = ref({
|
|
||||||
current: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
total: 0,
|
|
||||||
})
|
|
||||||
const loading = ref(false)
|
|
||||||
const listData = ref([])
|
|
||||||
|
|
||||||
// 搜索表单
|
|
||||||
const searchFormData = ref({
|
|
||||||
name: '',
|
|
||||||
idCard: '',
|
|
||||||
exceptionType: undefined,
|
|
||||||
serviceOrderNo: '',
|
|
||||||
serviceOrg: undefined,
|
|
||||||
satisfaction: undefined,
|
|
||||||
staffSatisfaction: undefined,
|
|
||||||
isVisited: undefined,
|
|
||||||
plannedDate: [],
|
|
||||||
serviceDuration: undefined,
|
|
||||||
currentNode: [],
|
|
||||||
})
|
|
||||||
|
|
||||||
// 高级搜索
|
// 高级搜索
|
||||||
const advancedSearchVisible = ref([])
|
const advancedSearchVisible = ref([])
|
||||||
|
|
||||||
|
|
||||||
// 计算总宽度
|
// 计算总宽度
|
||||||
const totalWidth = computed(() => {
|
const totalWidth = computed(() => {
|
||||||
return columns.reduce((sum, col) => sum + (col.width || 100), 0)
|
return columns.reduce((sum, col) => sum + (col.width || 100), 0)
|
||||||
})
|
})
|
||||||
|
|
||||||
// 分页配置(用于 a-table)
|
// ====== 响应式变量 ======
|
||||||
const paginationConfig = computed(() => ({
|
const showDrawer = ref(false)
|
||||||
current: paginationState.value.current,
|
const currentRecord = ref(null)
|
||||||
pageSize: paginationState.value.pageSize,
|
const staffList = ref([
|
||||||
total: paginationState.value.total,
|
{ id: '1', name: '张三' },
|
||||||
showSizeChanger: true,
|
{ id: '2', name: '李四' },
|
||||||
showQuickJumper: true,
|
{ id: '3', name: '王五' },
|
||||||
}))
|
])
|
||||||
|
|
||||||
// 模拟本地数据
|
// 传递给抽屉的初始值
|
||||||
function mockData() {
|
const drawerInitialValues = computed(() => {
|
||||||
return Array.from({ length: 5 }, (_, i) => ({
|
if (!currentRecord.value) return {}
|
||||||
id: i + 1,
|
console.log('当前记录传递给抽屉:', currentRecord.value)
|
||||||
orderNum: `GD20251021${String(i + 1).padStart(4, '0')}`,
|
|
||||||
customerName: `客户${i + 1}`,
|
|
||||||
idCard: `11010119900101${String(i + 1).padStart(4, '0')}`,
|
|
||||||
otherPhone1: `1380013800${i}`,
|
|
||||||
otherPhone2: i % 2 === 0 ? `1390013900${i}` : null,
|
|
||||||
plannedServiceStartDate: '2025-10-25 09:00:00',
|
|
||||||
serviceDurationMinutes: 120 + i * 10,
|
|
||||||
serviceName: '居家照护',
|
|
||||||
area: '北京市朝阳区',
|
|
||||||
serviceAddress: '朝阳区某某街道XX号',
|
|
||||||
creator: '管理员',
|
|
||||||
createTime: '2025-10-20 14:30:00',
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取列表(使用 mock 数据)
|
return {
|
||||||
|
id: currentRecord.value.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取列表
|
||||||
async function getPageList() {
|
async function getPageList() {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
// 模拟接口延迟
|
showLoading()
|
||||||
await new Promise(resolve => setTimeout(resolve, 300))
|
const { pageSize, current } = paginationState
|
||||||
listData.value = mockData()
|
const params = {
|
||||||
paginationState.value.total = listData.value.length
|
status:'Initialize',
|
||||||
|
stationId: storage.local.getItem('stationId'),
|
||||||
|
companyId: storage.local.getItem('companyId'),
|
||||||
|
pageSize,
|
||||||
|
current,
|
||||||
|
...searchFormData.value
|
||||||
|
}
|
||||||
|
const { success, data, total } = await apis.workOrder.getWorkOrderList(params)
|
||||||
|
listData.value = data
|
||||||
|
paginationState.total = total
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取列表失败:', error)
|
console.error('获取工单列表失败:', error)
|
||||||
message.error('加载数据失败')
|
message.error('获取数据失败')
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
hideLoading()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,26 +302,14 @@ function formatDate(dateStr) {
|
|||||||
return dateStr || '—'
|
return dateStr || '—'
|
||||||
}
|
}
|
||||||
|
|
||||||
// ====== 新增响应式变量 ======
|
// ====== 派单抽屉操作函数 ======
|
||||||
const showDrawer = ref(false)
|
|
||||||
const currentRecord = ref(null)
|
|
||||||
const staffList = ref([
|
|
||||||
{ id: '1', name: '张三' },
|
|
||||||
{ id: '2', name: '李四' },
|
|
||||||
{ id: '3', name: '王五' },
|
|
||||||
])
|
|
||||||
|
|
||||||
const initialValues = computed(() => {
|
|
||||||
return {}
|
|
||||||
})
|
|
||||||
|
|
||||||
// ====== 修正后的派单抽屉操作函数 ======
|
|
||||||
function openDispatchDrawer(record) {
|
function openDispatchDrawer(record) {
|
||||||
currentRecord.value = record
|
currentRecord.value = record
|
||||||
showDrawer.value = true
|
showDrawer.value = true
|
||||||
|
console.log('打开派单抽屉,记录ID:', record.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeDispatchDrawer() {
|
function handleDrawerClose() {
|
||||||
showDrawer.value = false
|
showDrawer.value = false
|
||||||
currentRecord.value = null
|
currentRecord.value = null
|
||||||
}
|
}
|
||||||
@ -346,15 +318,21 @@ function handleDispatchSubmit(values) {
|
|||||||
console.log('派单数据:', values)
|
console.log('派单数据:', values)
|
||||||
console.log('派给工单:', currentRecord.value)
|
console.log('派给工单:', currentRecord.value)
|
||||||
|
|
||||||
|
// 这里可以调用派单提交接口
|
||||||
|
// await apis.workOrder.dispatchWorkOrder({
|
||||||
|
// workOrderId: currentRecord.value.id,
|
||||||
|
// ...values
|
||||||
|
// })
|
||||||
|
|
||||||
message.success('派单成功')
|
message.success('派单成功')
|
||||||
closeDispatchDrawer()
|
handleDrawerClose()
|
||||||
|
|
||||||
|
// 刷新列表
|
||||||
|
getPageList()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化
|
// 初始化
|
||||||
getPageList()
|
getPageList()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped></style>
|
<style lang="less" scoped></style>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user