feat: 前端完成保洁订单流程

This commit is contained in:
fyy 2025-07-01 14:39:49 +08:00
parent 38267d7a4a
commit ea185bfcea
5 changed files with 118 additions and 173 deletions

View File

@ -77,7 +77,7 @@ export interface Clean_orderForm extends BaseEntity {
/** /**
* *
*/ */
id?: string | number; id?: string;
/** /**
* *

View File

@ -7,16 +7,24 @@ import { useVbenForm } from '#/adapter/form';
import { cleanList } from '#/api/property/clean'; import { cleanList } from '#/api/property/clean';
import { defaultFormValueGetter, useBeforeCloseDiff } from '#/utils/popup'; import { defaultFormValueGetter, useBeforeCloseDiff } from '#/utils/popup';
const emit = defineEmits<{ reload: [data: any] }>(); const emit = defineEmits<{ reload: [data: any], editReload: [data: any] }>();
const isUpdate = ref(false); const isUpdate = ref(false);
const isAdd = ref(false);
const isView = ref(false);
const title = computed(() => { const title = computed(() => {
return isUpdate.value ? $t('pages.common.edit') : $t('pages.common.add'); if(isAdd.value){
return $t('pages.common.add');
}else if(isView.value){
return '查看';
}else{
return $t('pages.common.edit');
}
}); });
// //
let cleanListData: any[] = []; let cleanListData: any[] = [];
const detailIndex = ref<number>();//index,
const detailSchema = [ const detailSchema = [
{ {
label: '劳务名称', label: '劳务名称',
@ -50,7 +58,7 @@ const detailSchema = [
}, },
rules: 'required', rules: 'required',
}, },
{ {
label: '保洁面积', label: '保洁面积',
fieldName: 'area', fieldName: 'area',
component: 'InputNumber', component: 'InputNumber',
@ -132,7 +140,6 @@ const detailSchema = [
}, },
rules: 'required', rules: 'required',
}, },
{ {
label: '合计费用', label: '合计费用',
fieldName: 'sumPeices', fieldName: 'sumPeices',
@ -170,11 +177,20 @@ const [BasicModal, modalApi] = useVbenModal({
return null; return null;
} }
modalApi.modalLoading(true); modalApi.modalLoading(true);
const { id } = modalApi.getData() as { id?: number | string }; const data = modalApi.getData();
isUpdate.value = !!id; detailIndex.value = modalApi.getData().index;
if (isUpdate.value && id) { if(!data || Object.keys(data).length === 0){
// TODO: //modalApi.getData()
isAdd.value = true;
}else if(detailIndex.value == undefined || detailIndex.value == null){
//detailIndex.value
isView.value = true;
}else{
//
isUpdate.value = true;
} }
// TODO:
await formApi.setValues(modalApi.getData());
await markInitialized(); await markInitialized();
modalApi.modalLoading(false); modalApi.modalLoading(false);
}, },
@ -188,15 +204,16 @@ async function handleConfirm() {
return; return;
} }
const data = cloneDeep(await formApi.getValues()); const data = cloneDeep(await formApi.getValues());
// //
const selectedService = cleanListData.find(item => item.id === data.name); const selectedService = cleanListData.find(item => item.id === data.name);
if (selectedService) { if (selectedService) {
data.name = selectedService.name; data.name = selectedService.name;
data.id = selectedService.id data.id = selectedService.id
} }
console.log(data); //index>=0
if (detailIndex.value! >= 0) {
emit('editReload', data);
}
handleClosed() handleClosed()
await markInitialized(); await markInitialized();
emit('reload', data); emit('reload', data);
@ -209,6 +226,9 @@ async function handleConfirm() {
} }
async function handleClosed() { async function handleClosed() {
isAdd.value = false;
isView.value = false;
isUpdate.value = false;
await formApi.resetForm(); await formApi.resetForm();
resetInitialized(); resetInitialized();
} }
@ -216,7 +236,8 @@ async function handleClosed() {
<template> <template>
<BasicModal :title="title"> <BasicModal :title="title">
<BasicForm /> <BasicForm >
</BasicForm>
</BasicModal> </BasicModal>
</template> </template>
<style scoped> <style scoped>

View File

@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import type { VxeGridProps } from '#/adapter/vxe-table'; import type { VxeGridProps } from '#/adapter/vxe-table';
import type { CleanVO } from '#/api/property/clean/model'; import type { CleanVO } from '#/api/property/clean/model';
import { h } from 'vue';
import { computed, ref } from 'vue'; import { computed, ref } from 'vue';
import { useVbenModal } from '@vben/common-ui'; import { useVbenModal } from '@vben/common-ui';
@ -40,7 +40,7 @@ const totalSumPeices = computed(() => {
const isUpdate = ref(false); const isUpdate = ref(false);
const isReadonly = ref(false); const isReadonly = ref(false);
const title = computed(() => { const title = computed(() => {
return isUpdate.value ? $t('pages.common.edit') : $t('pages.common.add'); return isUpdate.value ? $t('pages.common.edit') : isReadonly.value ? '详情' : $t('pages.common.add');
}); });
// cleanList // cleanList
@ -50,7 +50,8 @@ let cleanListData: CleanVO[] = [];
let unitListData: { id: any; name: string }[] = []; let unitListData: { id: any; name: string }[] = [];
const editUnitId = ref(''); const editUnitId = ref('');
const editCleanId = ref(''); const editCleanOrderId = ref('');
const detailModal = ref(null);
const [BasicForm, formApi] = useVbenForm({ const [BasicForm, formApi] = useVbenForm({
commonConfig: { commonConfig: {
@ -117,20 +118,27 @@ const [BasicModal, modalApi] = useVbenModal({
if (!isOpen) { if (!isOpen) {
return null; return null;
} }
//
setupCommunitySelect() setupCommunitySelect()
modalApi.modalLoading(true); modalApi.modalLoading(true);
const { id, readonly } = modalApi.getData() as { const { id, readonly } = modalApi.getData() as {
id?: number | string; id?: string;
readonly?: boolean; readonly?: boolean;
}; };
isUpdate.value = !!id; editCleanOrderId.value = id || '';
isReadonly.value = !!readonly; isReadonly.value = !!readonly;
if (isUpdate.value && id) { //
if(isReadonly.value){
isUpdate.value = false;
}else{
isUpdate.value = !!id;
}
if ((isUpdate.value || isReadonly.value) && id) {
const record: any = await clean_orderInfo(id); const record: any = await clean_orderInfo(id);
if (record.starTime) record.starTime = dayjs(record.starTime); if (record.starTime) record.starTime = dayjs(record.starTime);
if (record.endTime) record.endTime = dayjs(record.endTime); if (record.endTime) record.endTime = dayjs(record.endTime);
editUnitId.value = record.unitId || ''; editUnitId.value = record.unitId || '';
editCleanId.value = record.cleanId || ''; detailTable.value = record.cleanList || [];
await formApi.setValues(record); await formApi.setValues(record);
} }
await markInitialized(); await markInitialized();
@ -245,11 +253,11 @@ const detailColumns = [
dataIndex: 'sumPeices', dataIndex: 'sumPeices',
key: 'sumPeices', key: 'sumPeices',
}, },
{ {
title: '操作', title: '操作',
key: 'action', key: 'action',
fixed: 'right' as const, fixed: 'right' as const,
}, },
]; ];
const [DetailTable, detailTableApi] = useVbenVxeGrid({ const [DetailTable, detailTableApi] = useVbenVxeGrid({
@ -265,20 +273,32 @@ function handleAddDetail() {
detailModalApi.setData({}); detailModalApi.setData({});
detailModalApi.open(); detailModalApi.open();
} }
//
function handleDetailReload(data: any) { function handleDetailReload(data: any) {
detailTable.value.push(data); detailTable.value.push(data);
} }
//
function handleEditDetailReload(data: any) {
detailTable.value[data.index] = data;
}
//
function handleDeleteDetail(record: any, index: number) { function handleDeleteDetail(record: any, index: number) {
console.log(record, index);
detailTable.value.splice(index, 1); detailTable.value.splice(index, 1);
} }
async function handleConfirm() { function handleViewDetail(record: any) {
console.log('handleConfirm123123123'); detailModalApi.setData({ ...record, readonly: true });
detailModalApi.open();
}
function handleEditDetail(record: any, index: number) {
detailModalApi.setData({ ...record, index, readonly: false });
detailModalApi.open();
}
async function handleConfirm() {
if (isReadonly.value) { if (isReadonly.value) {
detailTable.value = [];
modalApi.close(); modalApi.close();
return; return;
} }
@ -289,7 +309,6 @@ async function handleConfirm() {
return; return;
} }
const data = cloneDeep(await formApi.getValues()); const data = cloneDeep(await formApi.getValues());
console.log(data);
// //
if (unitListData.length === 0) { if (unitListData.length === 0) {
const res = await resident_unitList(); const res = await resident_unitList();
@ -297,31 +316,16 @@ async function handleConfirm() {
} }
// cleanListData // cleanListData
// label // label
const unitObj = unitListData.find((item) => item.id === data.unit); const unitObj = unitListData.find((item) => item.id === data.unitId);
console.log(unitObj,'unitObj');
const cleanObj = cleanListData.find((item) => item.id === data.name); const cleanObj = cleanListData.find((item) => item.id === data.name);
data.unit = unitObj ? unitObj.name : data.unit || ''; data.unit = unitObj ? unitObj.name : data.unit || '';
data.name = cleanObj ? cleanObj.name : data.name || ''; data.name = cleanObj ? cleanObj.name : data.name || '';
data.unitId = unitObj ? unitObj.id : isUpdate.value ? editUnitId.value : ''; data.unitId = unitObj ? unitObj.id : isUpdate.value ? editUnitId.value : '';
data.cleanId = cleanObj data.sumPeices = parseInt(totalSumPeices.value, 10);
? cleanObj.id
: isUpdate.value
? editCleanId.value
: '';
data.sumPeices = parseInt(totalSumPeices.value, 10);
// cleanIds // cleanIds
// data.cleanIds = detailTable.value.map((item: any) => item.id); // data.cleanIds = detailTable.value.map((item: any) => item.id);
data.cleanList = detailTable.value; data.cleanList = detailTable.value;
console.log(data); isUpdate.value ? await clean_orderUpdate({...data,id:editCleanOrderId.value}) : await clean_orderAdd(data);
console.log(12037847120120);
await clean_orderAdd(data)
// isUpdate.value ? await clean_orderUpdate(data) : await clean_orderAdd(data);
console.log('1231273');
resetInitialized(); resetInitialized();
emit('reload'); emit('reload');
modalApi.close(); modalApi.close();
@ -334,6 +338,7 @@ await clean_orderAdd(data)
async function handleClosed() { async function handleClosed() {
await formApi.resetForm(); await formApi.resetForm();
detailTable.value = [];//
resetInitialized(); resetInitialized();
} }
// //
@ -343,9 +348,7 @@ async function setupCommunitySelect() {
// addFullName(areaList, 'areaName', ' / '); // addFullName(areaList, 'areaName', ' / ');
const splitStr = '/'; const splitStr = '/';
handleNode(areaList, 'label', splitStr, function (node: any) { handleNode(areaList, 'label', splitStr, function (node: any) {
if (node.level != 5) {
node.disabled = true;
}
}); });
formApi.updateSchema([ formApi.updateSchema([
{ {
@ -381,8 +384,8 @@ async function setupCommunitySelect() {
<!-- 添加订单详情部分 --> <!-- 添加订单详情部分 -->
<div class="mt-4"> <div class="mt-4">
<div class="mb-2 flex items-center justify-between"> <div class="mb-2 flex items-center justify-between">
<h3 class="text-lg font-medium">添加保洁订单详情</h3> <h3 class="text-lg font-medium">{{ isUpdate ? '编辑保洁订单详情' : isReadonly ? '查看保洁订单详情' : '添加保洁订单详情' }} </h3>
<a-button type="primary" @click="handleAddDetail"> <a-button v-if="!isReadonly" type="primary" @click="handleAddDetail">
{{ $t('pages.common.add') }} {{ $t('pages.common.add') }}
</a-button> </a-button>
</div> </div>
@ -396,15 +399,22 @@ async function setupCommunitySelect() {
{{ index + 1 }} {{ index + 1 }}
</template> </template>
<template v-else-if="column.key === 'action'"> <template v-else-if="column.key === 'action'">
<Button danger @click="handleDeleteDetail(record, index)"> <template v-if="isReadonly">
删除 <Button @click="handleViewDetail(record)">查看</Button>
</Button> </template>
<template v-else >
<Button type="primary" size="small" style="margin-right: 5px;" @click="handleViewDetail(record)">查看</Button>
<Button type="primary" size="small" style="margin-right: 5px;" @click="handleEditDetail(record, index)">编辑</Button>
<Button danger size="small" @click="handleDeleteDetail(record, index)">
删除
</Button>
</template>
</template> </template>
</template> </template>
</Table> </Table>
<div>费用合计{{ totalSumPeices }}</div> <div>费用合计{{ totalSumPeices }}</div>
</div> </div>
<CleanDetailModal @reload="handleDetailReload" /> <CleanDetailModal @reload="handleDetailReload" @editReload="handleEditDetailReload"/>
</BasicModal> </BasicModal>
</template> </template>

View File

@ -3,52 +3,34 @@ import type { VxeGridProps } from '#/adapter/vxe-table';
import { resident_unitList } from '#/api/property/resident/unit'; import { resident_unitList } from '#/api/property/resident/unit';
import { useCleanStore } from '#/store'; import { useCleanStore } from '#/store';
import type { FormSchema } from '../../../../../../../packages/@core/ui-kit/form-ui/src/types';
const cleanStore = useCleanStore(); const cleanStore = useCleanStore();
export const querySchema: FormSchemaGetter = () => [ export const querySchema: (areaList: any[]) => FormSchema[] = (areaList) => [
{ {
component: 'Input',
fieldName: 'location',
label: '服务地址', label: '服务地址',
component: 'TreeSelect',
fieldName: 'location',
componentProps: {
treeData: areaList,
fieldNames: {
label: 'label',
value: 'id',
children: 'children',
},
placeholder: '请选择服务地址',
showSearch: true,
treeDefaultExpandAll: true,
},
}, },
// { // {
// label: '服务地址(房间号)', // label: '服务地址',
// component: 'TreeSelect', // component: 'TreeSelect',
// defaultValue: undefined, // defaultValue: undefined,
// fieldName: 'location', // fieldName: 'location',
// rules: 'required', // rules: 'required',
// }, // },
// {
// label: '服务地址(房间号)',
// fieldName: 'location',
// component: 'ApiSelect',
// componentProps: {
// api: resident_unitList,
// resultField: 'rows',
// labelField: 'name',
// valueField: 'id',
// placeholder: '请选择服务地址',
// onChange: (val: string | number) => {
// cleanStore.setLocation(val);
// },
// },
// rules: 'required',
// },
// {
// label: '申请人hhh',
// fieldName: 'persion',
// component: 'ApiSelect',
// componentProps: {
// api: cleanList,
// resultField: 'rows',
// labelField: 'name',
// valueField: 'id',
// placeholder: '请选择申请人',
// disabled: computed(() => !cleanStore.isPersionEnabled),
// },
// rules: 'required',
// },
{ {
component: 'Input', component: 'Input',
fieldName: 'persion', fieldName: 'persion',
@ -91,21 +73,6 @@ export const columns: VxeGridProps['columns'] = [
field: 'location', field: 'location',
width: '180', width: '180',
}, },
// {
// title: '服务面积(㎡)',
// field: 'area',
// width: 'auto',
// },
// {
// title: '劳务名称',
// field: 'name',
// width: 'auto',
// },
// {
// title: '申报单价含税(元)',
// field: 'prices',
// width: 'auto',
// },
{ {
title: '合计费用(元)', title: '合计费用(元)',
field: 'sumPeices', field: 'sumPeices',
@ -168,69 +135,11 @@ export const modalSchema: FormSchemaGetter = () => [
}, },
{ {
label: '服务地址(房间号)', label: '服务地址(房间号)',
component: 'Input', component: 'TreeSelect',
defaultValue: undefined, defaultValue: undefined,
fieldName: 'location', fieldName: 'location',
rules: 'required', rules: 'required',
}, },
// {
// label: '服务面积(㎡)',
// fieldName: 'area',
// component: 'Input',
// rules: 'required',
// },
// {
// label: '劳务名称',
// fieldName: 'name',
// component: 'ApiSelect',
// componentProps: {
// api: cleanList,
// resultField: 'rows',
// labelField: 'name',
// valueField: 'id',
// },
// rules: 'required',
// },
// {
// label: '服务单价',
// fieldName: 'prices',
// component: 'Input',
// rules: 'required',
// componentProps: {
// placeholder: '',
// disabled: true,
// },
// },
// {
// label: '保洁频率',
// fieldName: 'frequency',
// component: 'Input',
// rules: 'required',
// componentProps: {
// placeholder: '',
// disabled: true,
// },
// },
// {
// label: '保洁内容',
// fieldName: 'standard',
// component: 'Input',
// rules: 'required',
// componentProps: {
// placeholder: '',
// disabled: true,
// },
// },
// {
// label: '保洁标准',
// fieldName: 'peices',
// component: 'Input',
// rules: 'required',
// componentProps: {
// placeholder: '',
// disabled: true,
// },
// },
{ {
label: '开始时间', label: '开始时间',
fieldName: 'starTime', fieldName: 'starTime',
@ -267,7 +176,7 @@ export const modalSchema: FormSchemaGetter = () => [
}, },
{ {
label: '申请单位', label: '申请单位',
fieldName: 'unit', fieldName: 'unitId',
component: 'ApiSelect', component: 'ApiSelect',
componentProps: { componentProps: {
api: resident_unitList, api: resident_unitList,

View File

@ -19,7 +19,12 @@ import { commonDownloadExcel } from '#/utils/file/download';
import cleanModal from './clean-modal.vue'; import cleanModal from './clean-modal.vue';
import { columns, querySchema } from './data'; import { columns, querySchema } from './data';
import { onMounted, ref } from 'vue';
import { communityTree } from '#/api/property/community';
const areaList = ref<any>(null);
onMounted(async () => {
areaList.value = await communityTree(5);
});
const formOptions: VbenFormProps = { const formOptions: VbenFormProps = {
commonConfig: { commonConfig: {
labelWidth: 120, labelWidth: 120,
@ -27,7 +32,7 @@ const formOptions: VbenFormProps = {
allowClear: true, allowClear: true,
}, },
}, },
schema: querySchema(), schema: querySchema(areaList.value),
wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4', wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4',
// RangePicker / // RangePicker /
// //