pc端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

273 lines
8.9 KiB

<template>
<div class="p-4">
<!-- 标题 -->
<div class="mb-8 flex justify-between items-center">
<div class="text-2xl font-semibold">流水账</div>
<div class="flex items-center">
<a-button type="primary">早打卡</a-button>
<a-button class="mx-5" type="primary">晚打卡</a-button>
<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>
<!-- 筛选 -->
<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-form-item>
<a-form-item name="staffRange" label="员工" style="width: 250px; margin-right: 20px; margin-bottom: 12px">
<a-select v-model:value="formState.staffRange" :options="options" mode="multiple" placeholder="请选择员工"></a-select>
</a-form-item>
<a-form-item name="programName" label="项目" style="width: 250px; margin-right: 20px; margin-bottom: 12px">
<a-select v-model:value="formState.programName" :options="options" mode="multiple" placeholder="请输入项目名称"></a-select>
</a-form-item>
<div class="block w-full">
<a-button type="primary">筛选</a-button>
<a-button class="mx-3" type="primary">导出</a-button>
<a-button>重置</a-button>
</div>
</a-form>
<!-- 表格 -->
<a-table class="mt-6" :columns="columns" :data-source="data" bordered :scroll="{ x: 1400 }">
<template #bodyCell="{ column, text }">
<div style="height: 100px" :class="{ 'text-left': column.dataIndex === 'program' }" @dblclick="showModal">{{ text }}</div>
</template>
</a-table>
</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="members"
show-search
placeholder="请选择检查人"
:field-names="{ label: 'name', value: 'memberId' }"
:filter-option="filterOption"
@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>
<script setup>
import { useStore } from 'vuex';
import { reactive, ref, computed } from 'vue';
import dayjs from 'dayjs';
import { FullscreenExitOutlined, FullscreenOutlined, DeleteOutlined } from '@ant-design/icons-vue';
const store = useStore();
const isFullScreen = ref(false);
const visible = ref(false); // 是否显示弹框表单
const members = computed(() => store.state.role.members); // 项目成员
// 筛选表单
const formState = reactive({
timeRange: [], // 时间范围
staffRange: ['a1', 'b2'], // 员工
programName: ['a1', 'b2'], // 项目名称
});
// 下拉选选项
const options = [...Array(25)].map((_, i) => ({ value: (i + 10).toString(36) + (i + 1) }));
// 表格元素
const columns = [
{
title: '时间',
width: 100,
dataIndex: 'time',
key: 'time',
fixed: 'left',
align: 'center',
},
{
title: '员工',
width: 100,
dataIndex: 'staff',
key: 'staff',
fixed: 'left',
align: 'center',
},
{
title: '项目1',
dataIndex: 'program',
key: '1',
width: 300,
align: 'center',
},
{
title: '项目2',
dataIndex: 'program',
key: '2',
width: 300,
align: 'center',
},
{
title: '项目3',
dataIndex: 'program',
key: '3',
width: 300,
align: 'center',
},
{
title: '项目4',
dataIndex: 'program',
key: '4',
width: 300,
align: 'center',
},
];
// 表格数据
const data = [];
for (let i = 0; i < 100; i++) {
data.push({
key: i,
time: dayjs(+new Date().getTime()).format('MM-DD'),
staff: `成员 ${i}`,
program: `我今日计划结果1是XXXXXX,交付物是XXXXXXX方法论,截止时间是:4/25,检查人是:卫老师`,
});
}
// 今日计划表单
const modalFormState = ref([
{
planValue: '',
deliverable: '',
deadline: dayjs(+new Date().getTime()),
duration: '',
inspector: '',
address: '',
},
]);
// 工作时长
const workDurations = [...Array(8)].map((_, i) => ({ value: `${i + 1}小时` }));
// 打开今日计划编辑框
function showModal() {
visible.value = true;
}
function filterOption(input, option) {
return option.name.indexOf(input) >= 0;
}
// 选择工作时长
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>