1 changed files with 193 additions and 93 deletions
@ -1,163 +1,263 @@ |
|||||
<template> |
<template> |
||||
<div class="p-4"> |
<div class="p-4"> |
||||
|
<!-- 标题 --> |
||||
<div class="mb-8 flex justify-between items-center"> |
<div class="mb-8 flex justify-between items-center"> |
||||
<div class="text-2xl font-semibold">流水账</div> |
<div class="text-2xl font-semibold">流水账</div> |
||||
<div class="flex items-center"> |
<div class="flex items-center"> |
||||
<a-button type="primary">早打卡</a-button> |
<a-button type="primary">早打卡</a-button> |
||||
<a-button class="mx-5" type="primary">晚打卡</a-button> |
<a-button class="mx-5" type="primary">晚打卡</a-button> |
||||
<FullscreenExitOutlined class="text-lg" style="color: #777" /> |
<FullscreenExitOutlined v-if="isFullScreen" class="text-lg" style="color: #777" @click="isFullScreen = !isFullScreen" /> |
||||
|
<FullscreenOutlined v-else class="text-lg" style="color: #777" @click="isFullScreen = !isFullScreen" /> |
||||
</div> |
</div> |
||||
</div> |
</div> |
||||
|
|
||||
<a-form class="flex flex-wrap" :model="formState" name="basic" autocomplete="off" @finish="onFinish" @finishFailed="onFinishFailed"> |
<!-- 筛选 --> |
||||
<a-form-item name="timeRange" label="时间" style="width: 250px; margin-right: 20px"> |
<a-form class="flex flex-wrap" :model="formState" name="basic" autocomplete="off"> |
||||
|
<a-form-item name="timeRange" label="时间" style="width: 250px; margin-right: 20px; margin-bottom: 12px"> |
||||
<a-range-picker v-model:value="formState.timeRange" /> |
<a-range-picker v-model:value="formState.timeRange" /> |
||||
</a-form-item> |
</a-form-item> |
||||
|
|
||||
<a-form-item name="staffRange" label="员工" style="width: 250px; margin-right: 20px"> |
<a-form-item name="staffRange" label="员工" style="width: 250px; margin-right: 20px; margin-bottom: 12px"> |
||||
<a-select |
<a-select v-model:value="formState.staffRange" :options="options" mode="multiple" placeholder="请选择员工"></a-select> |
||||
v-model:value="formState.staffRange" |
|
||||
:options="options" |
|
||||
mode="multiple" |
|
||||
placeholder="请选择员工" |
|
||||
@popupScroll="popupScroll" |
|
||||
></a-select> |
|
||||
</a-form-item> |
</a-form-item> |
||||
|
|
||||
<a-form-item name="programName" label="项目" style="width: 250px; margin-right: 20px"> |
<a-form-item name="programName" label="项目" style="width: 250px; margin-right: 20px; margin-bottom: 12px"> |
||||
<a-select |
<a-select v-model:value="formState.programName" :options="options" mode="multiple" placeholder="请输入项目名称"></a-select> |
||||
v-model:value="formState.programName" |
|
||||
:options="options" |
|
||||
mode="multiple" |
|
||||
placeholder="请输入项目名称" |
|
||||
@popupScroll="popupScroll" |
|
||||
></a-select> |
|
||||
</a-form-item> |
</a-form-item> |
||||
|
|
||||
<!-- <a-form-item :wrapper-col="{ offset: 8, span: 16 }"> |
<div class="block w-full"> |
||||
<a-button type="primary">筛选</a-button> |
<a-button type="primary">筛选</a-button> |
||||
<a-button class="mx-3" type="primary">导出</a-button> |
<a-button class="mx-3" type="primary">导出</a-button> |
||||
<a-button>重置</a-button> |
<a-button>重置</a-button> |
||||
</a-form-item> --> |
</div> |
||||
</a-form> |
</a-form> |
||||
|
|
||||
<div> |
<!-- 表格 --> |
||||
<a-button type="primary">筛选</a-button> |
<a-table class="mt-6" :columns="columns" :data-source="data" bordered :scroll="{ x: 1400 }"> |
||||
<a-button class="mx-3" type="primary">导出</a-button> |
<template #bodyCell="{ column, text }"> |
||||
<a-button>重置</a-button> |
<div style="height: 100px" :class="{ 'text-left': column.dataIndex === 'program' }" @dblclick="showModal">{{ text }}</div> |
||||
</div> |
|
||||
|
|
||||
<a-table :columns="columns" :data-source="data" :scroll="{ x: 1500, y: 300 }"> |
|
||||
<template #bodyCell="{ column }"> |
|
||||
<template v-if="column.key === 'operation'"> |
|
||||
<a>action</a> |
|
||||
</template> |
|
||||
</template> |
</template> |
||||
</a-table> |
</a-table> |
||||
</div> |
</div> |
||||
|
|
||||
|
<a-modal v-model:visible="visible" title="今日计划" centered :footer="null" width="800px"> |
||||
|
<div style="padding: 0 96px"> |
||||
|
<a-form :model="modalFormState" name="basic" autocomplete="off"> |
||||
|
<div v-for="(item, index) in modalFormState" :key="index"> |
||||
|
<div class="flex justify-between items-center text-gray-400"> |
||||
|
<div class="mb-5 text-right" style="width: 120px">计划结果{{ index + 1 }}:</div> |
||||
|
<DeleteOutlined v-if="modalFormState.length > 1" @click="delFormItem(index)" /> |
||||
|
</div> |
||||
|
|
||||
|
<a-form-item name="planValue" style="margin-bottom: 20px"> |
||||
|
<div class="flex"> |
||||
|
<label class="flex-shrink-0 text-right" style="width: 120px; line-height: 32px"> |
||||
|
<span style="color: #ff5353; margin-right: 5px">*</span>今日计划结果1: |
||||
|
</label> |
||||
|
<a-textarea v-model:value="item.planValue" placeholder="请输入今日计划" /> |
||||
|
</div> |
||||
|
</a-form-item> |
||||
|
|
||||
|
<a-form-item name="deliverable" style="margin-bottom: 20px"> |
||||
|
<div class="flex"> |
||||
|
<label class="flex-shrink-0 text-right" style="width: 120px; line-height: 32px"> |
||||
|
<span style="color: #ff5353; margin-right: 5px">*</span>交付物: |
||||
|
</label> |
||||
|
<a-input v-model:value="item.deliverable" placeholder="请输入交付物" /> |
||||
|
</div> |
||||
|
</a-form-item> |
||||
|
|
||||
|
<a-form-item name="deadline" style="margin-bottom: 20px"> |
||||
|
<div class="flex"> |
||||
|
<label class="flex-shrink-0 text-right" style="width: 120px; line-height: 32px"> |
||||
|
<span style="color: #ff5353; margin-right: 5px">*</span>截止时间: |
||||
|
</label> |
||||
|
<a-date-picker class="w-full" v-model:value="item.deadline" /> |
||||
|
</div> |
||||
|
</a-form-item> |
||||
|
|
||||
|
<a-form-item name="duration" style="margin-bottom: 20px"> |
||||
|
<div class="flex"> |
||||
|
<label class="flex-shrink-0 text-right" style="width: 120px; line-height: 32px"> |
||||
|
<span style="color: #ff5353; margin-right: 5px">*</span>时长: |
||||
|
</label> |
||||
|
<a-select |
||||
|
v-model:value="item.duration" |
||||
|
:options="workDurations" |
||||
|
placeholder="请输入工作时长" |
||||
|
@change="handleDuration($event, index)" |
||||
|
></a-select> |
||||
|
</div> |
||||
|
</a-form-item> |
||||
|
|
||||
|
<a-form-item name="inspector" style="margin-bottom: 20px"> |
||||
|
<div class="flex"> |
||||
|
<label class="flex-shrink-0 text-right" style="width: 120px; line-height: 32px"> |
||||
|
<span style="color: #ff5353; margin-right: 5px">*</span>检查人: |
||||
|
</label> |
||||
|
<a-select |
||||
|
v-model:value="item.inspector" |
||||
|
:options="inspectorOptions" |
||||
|
placeholder="请选择检查人" |
||||
|
@change="handleInspector($event, index)" |
||||
|
></a-select> |
||||
|
</div> |
||||
|
</a-form-item> |
||||
|
|
||||
|
<a-form-item name="address" style="margin-bottom: 20px"> |
||||
|
<div class="flex"> |
||||
|
<label class="flex-shrink-0 text-right" style="width: 120px; line-height: 32px"> |
||||
|
<span style="color: #ff5353; margin-right: 5px">*</span>交付物地址: |
||||
|
</label> |
||||
|
<a-textarea v-model:value="item.address" placeholder="请输入交付物地址" /> |
||||
|
</div> |
||||
|
</a-form-item> |
||||
|
</div> |
||||
|
|
||||
|
<a-form-item> |
||||
|
<div class="flex"> |
||||
|
<label class="flex-shrink-0 text-right" style="width: 120px"></label> |
||||
|
<a-button style="color: #1890ff; border-color: #1890ff" type="dashed" @click="addFormItem">+ 添加</a-button> |
||||
|
</div> |
||||
|
</a-form-item> |
||||
|
|
||||
|
<a-form-item> |
||||
|
<div class="flex items-center"> |
||||
|
<label class="flex-shrink-0 text-right" style="width: 120px"></label> |
||||
|
<a-button class="mr-4" type="primary" @click="submitForm">提交</a-button> |
||||
|
<a-button @click="cancleModal">取消</a-button> |
||||
|
</div> |
||||
|
</a-form-item> |
||||
|
</a-form> |
||||
|
</div> |
||||
|
</a-modal> |
||||
</template> |
</template> |
||||
|
|
||||
<script setup> |
<script setup> |
||||
import { reactive } from 'vue'; |
import { reactive, ref } from 'vue'; |
||||
import { FullscreenExitOutlined } from '@ant-design/icons-vue'; |
import dayjs from 'dayjs'; |
||||
|
import { FullscreenExitOutlined, FullscreenOutlined, DeleteOutlined } from '@ant-design/icons-vue'; |
||||
|
|
||||
|
const isFullScreen = ref(false); |
||||
|
const visible = ref(false); // 是否显示弹框表单 |
||||
|
|
||||
|
// 筛选表单 |
||||
const formState = reactive({ |
const formState = reactive({ |
||||
timeRange: [], // 时间范围 |
timeRange: [], // 时间范围 |
||||
staffRange: ['a1', 'b2'], // 员工 |
staffRange: ['a1', 'b2'], // 员工 |
||||
programName: ['a1', 'b2'], // 项目名称 |
programName: ['a1', 'b2'], // 项目名称 |
||||
}); |
}); |
||||
|
|
||||
|
// 下拉选选项 |
||||
const options = [...Array(25)].map((_, i) => ({ value: (i + 10).toString(36) + (i + 1) })); |
const options = [...Array(25)].map((_, i) => ({ value: (i + 10).toString(36) + (i + 1) })); |
||||
|
|
||||
|
// 表格元素 |
||||
const columns = [ |
const columns = [ |
||||
{ |
{ |
||||
title: 'Full Name', |
title: '时间', |
||||
width: 100, |
width: 100, |
||||
dataIndex: 'name', |
dataIndex: 'time', |
||||
key: 'name', |
key: 'time', |
||||
fixed: 'left', |
fixed: 'left', |
||||
|
align: 'center', |
||||
}, |
}, |
||||
{ |
{ |
||||
title: 'Age', |
title: '员工', |
||||
width: 100, |
width: 100, |
||||
dataIndex: 'age', |
dataIndex: 'staff', |
||||
key: 'age', |
key: 'staff', |
||||
fixed: 'left', |
fixed: 'left', |
||||
|
align: 'center', |
||||
}, |
}, |
||||
{ |
{ |
||||
title: 'Column 1', |
title: '项目1', |
||||
dataIndex: 'address', |
dataIndex: 'program', |
||||
key: '1', |
key: '1', |
||||
width: 150, |
width: 300, |
||||
|
align: 'center', |
||||
}, |
}, |
||||
{ |
{ |
||||
title: 'Column 2', |
title: '项目2', |
||||
dataIndex: 'address', |
dataIndex: 'program', |
||||
key: '2', |
key: '2', |
||||
width: 150, |
width: 300, |
||||
|
align: 'center', |
||||
}, |
}, |
||||
{ |
{ |
||||
title: 'Column 3', |
title: '项目3', |
||||
dataIndex: 'address', |
dataIndex: 'program', |
||||
key: '3', |
key: '3', |
||||
width: 150, |
width: 300, |
||||
|
align: 'center', |
||||
}, |
}, |
||||
{ |
{ |
||||
title: 'Column 4', |
title: '项目4', |
||||
dataIndex: 'address', |
dataIndex: 'program', |
||||
key: '4', |
key: '4', |
||||
width: 150, |
width: 300, |
||||
}, |
align: 'center', |
||||
{ |
|
||||
title: 'Column 5', |
|
||||
dataIndex: 'address', |
|
||||
key: '5', |
|
||||
width: 150, |
|
||||
}, |
|
||||
{ |
|
||||
title: 'Column 6', |
|
||||
dataIndex: 'address', |
|
||||
key: '6', |
|
||||
width: 150, |
|
||||
}, |
|
||||
{ |
|
||||
title: 'Column 7', |
|
||||
dataIndex: 'address', |
|
||||
key: '7', |
|
||||
width: 150, |
|
||||
}, |
|
||||
{ |
|
||||
title: 'Column 8', |
|
||||
dataIndex: 'address', |
|
||||
key: '8', |
|
||||
}, |
|
||||
{ |
|
||||
title: 'Action', |
|
||||
key: 'operation', |
|
||||
fixed: 'right', |
|
||||
width: 100, |
|
||||
}, |
}, |
||||
]; |
]; |
||||
const data = []; |
|
||||
|
|
||||
|
// 表格数据 |
||||
|
const data = []; |
||||
for (let i = 0; i < 100; i++) { |
for (let i = 0; i < 100; i++) { |
||||
data.push({ |
data.push({ |
||||
key: i, |
key: i, |
||||
name: `Edrward ${i}`, |
time: dayjs(+new Date().getTime()).format('MM-DD'), |
||||
age: 32, |
staff: `成员 ${i}`, |
||||
address: `London Park no. ${i}`, |
program: `我今日计划结果1是XXXXXX,交付物是XXXXXXX方法论,截止时间是:4/25,检查人是:卫老师`, |
||||
}); |
}); |
||||
} |
} |
||||
|
|
||||
const popupScroll = () => { |
// 今日计划表单 |
||||
console.log('popupScroll'); |
const modalFormState = ref([ |
||||
}; |
{ |
||||
|
planValue: '', |
||||
|
deliverable: '', |
||||
|
deadline: dayjs(+new Date().getTime()), |
||||
|
duration: '', |
||||
|
inspector: '', |
||||
|
address: '', |
||||
|
}, |
||||
|
]); |
||||
|
// 工作时长 |
||||
|
const workDurations = [...Array(8)].map((_, i) => ({ value: `${i + 1}小时` })); |
||||
|
const inspectorOptions = ref([{ value: '周勇' }, { value: '卫泽照' }]); // 检查人 |
||||
|
|
||||
const onFinish = values => { |
// 打开今日计划编辑框 |
||||
console.log('Success:', values); |
function showModal() { |
||||
}; |
visible.value = true; |
||||
|
} |
||||
|
|
||||
const onFinishFailed = errorInfo => { |
// 选择工作时长 |
||||
console.log('Failed:', errorInfo); |
function handleDuration(e, index) { |
||||
|
console.log('index', index, e); |
||||
|
modalFormState.value[index].duration = e; |
||||
|
} |
||||
|
|
||||
|
function handleInspector(e, index) { |
||||
|
modalFormState.value[index].inspector = e; |
||||
|
} |
||||
|
|
||||
|
function addFormItem() { |
||||
|
modalFormState.value.push({ |
||||
|
planValue: '', |
||||
|
deliverable: '', |
||||
|
deadline: dayjs(+new Date().getTime()), |
||||
|
duration: '', |
||||
|
inspector: '', |
||||
|
address: '', |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
const delFormItem = index => { |
||||
|
modalFormState.value.splice(index, 1); |
||||
}; |
}; |
||||
|
|
||||
|
function cancleModal() { |
||||
|
visible.value = false; |
||||
|
} |
||||
|
|
||||
|
function submitForm() {} |
||||
</script> |
</script> |
||||
|
|||||
Loading…
Reference in new issue