123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422 |
- <template>
- <div class="h-full flex">
- <div class="p-5 w-80 pr-0">
- <div class="bg-white w-full h-full shadow-md rounded-md flex flex-col">
- <div class="flex-1 p-3 overflow-y-auto scroll-bar">
- <el-form :model="searchForm">
- <el-form-item label="任务名称:" label-width="7em" prop="taskName">
- <el-input v-model="searchForm.taskName" placeholder="请输入" />
- </el-form-item>
- <el-form-item label="优先级:" label-width="7em" prop="priority">
- <el-select v-model="searchForm.priority" placeholder="请选择">
- <el-option v-for="item in PRIORITY" :key="item.value" :value="item.value" :label="item.label" />
- </el-select>
- </el-form-item>
- <el-form-item label="客户名称:" label-width="7em" prop="customName">
- <el-input v-model="searchForm.customName" placeholder="请输入" />
- </el-form-item>
- <el-form-item label="联系人号码:" label-width="7em" prop="contactsName">
- <el-input v-model="searchForm.contactsName" placeholder="请输入" />
- </el-form-item>
- <el-form-item label="执行人:" label-width="7em" prop="executorName">
- <el-input v-model="searchForm.executorName" placeholder="请输入" />
- </el-form-item>
- <el-form-item label="商机名称:" label-width="7em" prop="businessName">
- <el-input v-model="searchForm.businessName" placeholder="请输入" />
- </el-form-item>
- <el-form-item label="销售订单:" label-width="7em" prop="orderName">
- <el-input v-model="searchForm.orderName" placeholder="请输入" />
- </el-form-item>
- <el-form-item label="线索名称:" label-width="7em" prop="clueName">
- <el-input v-model="searchForm.clueName" placeholder="请输入" />
- </el-form-item>
- <el-form-item label="任务状态:" label-width="7em" prop="status">
- <el-select v-model="searchForm.status" placeholder="请选择">
- <el-option v-for="item in STATUS" :key="item.value" :value="item.value" :label="item.label" />
- </el-select>
- </el-form-item>
- <el-form-item label="开始时间:" label-width="7em" prop="startDate">
- <el-date-picker v-model="searchForm.startDate" type="date" placeholder="选择日期" value-format="YYYY-MM-DD" />
- </el-form-item>
- <el-form-item label="截止时间:" label-width="7em" prop="endDate">
- <el-date-picker v-model="searchForm.endDate" type="date" placeholder="选择日期" value-format="YYYY-MM-DD" />
- </el-form-item>
- </el-form>
- </div>
- <div class="w-full flex p-3 shadow-[0_-3px_5px_0px_rgba(0,0,0,0.2)]">
- <el-button size="large" class="w-full" @click="reset()">重置</el-Button>
- <el-button type="primary" size="large" class="w-full" @click="search()">搜索</el-Button>
- </div>
- </div>
- </div>
- <div class="flex-1 p-5 overflow-auto">
- <div class="bg-white w-full h-full p-3 shadow-md rounded-md flex flex-col">
- <div class="ml-auto p-3">
- <el-button type="primary" v-permission="['tasksAdd']" @click="createTasks()">创建任务</el-Button>
- <el-button type="primary" :disabled="len == 0" :loading="btnLoading" @click="deleteTasks()">批量删除</el-Button>
- <el-button type="primary" v-permission="['tasksImport']" @click="openImportModal()">导入</el-Button>
- <!-- <el-button type="primary" :loading="btnLoading" @click="exportTasks()">导出</el-Button> -->
- <el-button type="primary" v-permission="['tasksExport']" :loading="btnLoading" @click="newExportTasks()">导出</el-Button>
- </div>
- <div class="flex-1 overflow-y-auto">
- <el-table :data="tableData" :show-overflow-tooltip="tableShowOverflowTooltip" style="width: 100%;height: 100%;" ref="tableRef" v-loading="loading">
- <el-table-column type="selection" width="55" />
- <el-table-column prop="taskName" label="任务名称" header-align="center" align="center" show-overflow-tooltip
- width="200" />
- <el-table-column prop="priority" label="优先级" width="90" :sortable="true" header-align="center"
- align="center">
- <template #default="scope">
- {{ PRIORITY.find(item => item.value == scope.row.priority)?.label }}
- </template>
- </el-table-column>
- <el-table-column prop="status" label="状态" width="100" header-align="center" align="center">
- <template #default="scope">
- <el-text :type="STATUS[scope.row.status]?.type">
- {{ STATUS[scope.row.status]?.label }}
- </el-text>
- </template>
- </el-table-column>
- <el-table-column prop="executorNames" label="执行人" width="120" header-align="center" align="center" />
- <el-table-column prop="startDate" label="开始时间" width="200" :sortable="true" header-align="center"
- align="center" value-format="YYYY-MM-DD" />
- <el-table-column prop="endDate" label="截止时间" width="200" :sortable="true" header-align="center"
- align="center" value-format="YYYY-MM-DD" />
- <el-table-column prop="customName" label="客户名称" header-align="center" align="center" width="120">
- <template #default="scope">
- <el-link :underline="false" type="primary" @click="goDetail(scope.row, 'customer', 'customId')">
- {{ scope.row.customName }}
- </el-link>
- </template>
- </el-table-column>
- <el-table-column prop="businessName" label="商机名称" header-align="center" align="center" width="200">
- <template #default="scope">
- <el-link :underline="false" type="primary"
- @click="goDetail(scope.row, 'business', 'businessOpportunityId')">
- {{ scope.row.businessName }}
- </el-link>
- </template>
- </el-table-column>
- <el-table-column prop="orderName" label="销售订单" header-align="center" align="center" width="200">
- <template #default="scope">
- <el-link :underline="false" type="primary" @click="goDetail(scope.row, 'order', 'orderId')">
- {{ scope.row.orderName }}
- </el-link>
- </template>
- </el-table-column>
- <el-table-column prop="clueName" label="线索名称" header-align="center" align="center" width="200">
- <template #default="scope">
- <el-link :underline="false" type="primary" @click="goDetail(scope.row, 'thread', 'clueId')">
- {{ scope.row.clueName }}
- </el-link>
- </template>
- </el-table-column>
- <el-table-column prop="contactsName" label="联系人名称" header-align="center" align="center" width="120">
- <template #default="scope">
- <el-link :underline="false" type="primary" @click="goDetail(scope.row, 'contacts', 'contactsId')">
- {{ scope.row.contactsName }}
- </el-link>
- </template>
- </el-table-column>
- <el-table-column prop="contactsTel" label="联系人号码" header-align="center" align="center" width="140" />
- <el-table-column fixed="right" label="操作" header-align="center" align="center" width="160" v-permission="['tasksEdit']">
- <template #default="scope">
- <el-button link type="primary" @click.prevent="editRow(scope.row)">
- 编辑
- </el-button>
- <el-button link type="primary" v-if="scope.row.status == '2'"
- @click.prevent="restart(scope.row)">
- 重启
- </el-button>
- <el-button link type="primary" v-else @click.prevent="finishRow(scope.row)">
- 完成
- </el-button>
- <el-button link type="danger" @click.prevent="deleteRow(scope.row)">
- 删除
- </el-button>
- </template>
- </el-table-column>
- </el-table>
- </div>
- <div class="ml-auto">
- <el-pagination layout="total, prev, pager, next, sizes" :total="totalCount"
- :current-page="searchForm.pageIndex" @size-change="sizeChage" @current-change="currentChange" />
- </div>
- </div>
- </div>
- <TaskModal :visible="taskModalVisible" :title="isEdit ? '编辑任务' : '新建任务'" :save-loading="taskLoading"
- :edit-form="taskForm" :show-log="isEdit" @close="closeTaskModal" @submit="submitForm" />
- <ImportModal :visible="importVisible" :save-loading="importLoading" @close="closeImportModal"
- @submit="importExcel" />
- <ExportModal :visible="exportVisible" :save-loading="exportLoading" @close="closeExportModal"
- @submit="exportExcel" />
- </div>
- </template>
- <script lang="ts" setup>
- import { computed, inject, onBeforeMount, onMounted, ref, } from 'vue';
- import { useRouter } from 'vue-router';
- import { useStore } from '@/store';
- import { MOD, PRIORITY, STATUS, defaultSearchForm, PAGE_LIST, ADD_TASK, DELETE_TASKS, UPDATE_TASK, UPDATE_TASK_STATUS, IMPORT_DATA, EXPORT_DATA, EXPORT_DATA_BY_TASK_ID } from './api';
- import { ElTable, dayjs } from 'element-plus';
- import TaskModal from '@/components/TaskModal/index.vue';
- import ImportModal from './ImportModal.vue';
- import ExportModal from './ExportModal.vue';
- import { post, uploadFile } from '@/utils/request';
- import { getFromValue, confirmAction, downloadFile } from '@/utils/tools';
- import { tableShowOverflowTooltip } from '@/utils/globalVariables'
- import { pushMap } from './type';
- const router = useRouter()
- const { getFunctionList } = useStore()
- const globalPopup = inject<GlobalPopup>('globalPopup')
- const pagePermission = ref<any[]>();
- const taskModalVisible = ref(false);
- const taskForm = ref<any>();
- const isEdit = ref(false);
- const len = computed(() => {
- return tableRef.value?.getSelectionRows().length
- })
- const taskLoading = ref<saveLoadingType>("1");
- function closeTaskModal() {
- taskModalVisible.value = false;
- taskForm.value = null;
- }
- function submitForm(data: any, isClose: boolean) {
- const { executorId, startDate, endDate, repeatEndDate } = data;
- let params = {
- ...data,
- startDate: startDate && dayjs(startDate).format('YYYY-MM-DD 00:00:00'),
- endDate: endDate && dayjs(endDate).format('YYYY-MM-DD 23:59:59'),
- repeatEndDate: repeatEndDate && dayjs(repeatEndDate).format('YYYY-MM-DD 23:59:59')
- }
- if (executorId) {
- params = {
- ...params,
- executorId: executorId.join(','),
- taskLogs: []
- }
- }
- taskLoading.value = "2";
- let url = isEdit.value ? UPDATE_TASK : ADD_TASK
- let msg = isEdit.value ? "修改成功" : "新建成功"
- post(url, getFromValue(params)).then(() => {
- taskLoading.value = "3";
- taskModalVisible.value = isClose;
- globalPopup?.showSuccess(msg)
- search();
- }).catch(err => {
- taskLoading.value = "4"
- globalPopup?.showError(err.msg)
- })
- }
- const searchForm = ref<any>();
- const tableRef = ref<InstanceType<typeof ElTable>>();
- const loading = ref<boolean>(false);
- const totalCount = ref<number>(0);
- const tableData = ref<any[]>([])
- function newExportTasks() {
- btnLoading.value = true
- const { startDate, endDate } = searchForm.value;
- let params = {
- ...searchForm.value,
- startDate: startDate && dayjs(startDate).format('YYYY-MM-DD 00:00:00'),
- endDate: endDate && dayjs(endDate).format('YYYY-MM-DD 23:59:59')
- }
- post(EXPORT_DATA_BY_TASK_ID, {...getFromValue(params)}).then((res) => {
- globalPopup?.showSuccess("导出成功")
- downloadFile(res.data, "任务列表.xlsx");
- }).finally(() => {
- btnLoading.value = false
- })
- }
- function search() {
- loading.value = true;
- const { startDate, endDate } = searchForm.value;
- let params = {
- ...searchForm.value,
- startDate: startDate && dayjs(startDate).format('YYYY-MM-DD 00:00:00'),
- endDate: endDate && dayjs(endDate).format('YYYY-MM-DD 23:59:59')
- }
- post(PAGE_LIST, getFromValue(params)).then(({ data }) => {
- loading.value = false;
- const { total, record } = data;
- totalCount.value = total;
- tableData.value = record.map((item: any) => ({
- ...item,
- executorNames: item.taskExecutors?.join(',') ?? ''
- }));
- }).catch(err => {
- globalPopup?.showError(err);
- loading.value = false;
- })
- }
- function reset() {
- searchForm.value = { ...defaultSearchForm };
- }
- function sizeChage(currentSize: number): void {
- searchForm.value = {
- ...searchForm.value,
- pageSize: currentSize,
- pageIndex: 1
- }
- search()
- }
- function currentChange(currentPage: number): void {
- searchForm.value = {
- ...searchForm.value,
- pageIndex: currentPage
- }
- search()
- }
- function createTasks() {
- taskModalVisible.value = true;
- taskForm.value = null;
- isEdit.value = false;
- }
- function deleteTasks() {
- confirmAction("确定删除所选内容吗?").then(() => {
- const taskIds = tableRef.value?.getSelectionRows()?.map((item: any) => item.id).join(",")
- post(DELETE_TASKS, {
- taskIds
- }).then(() => {
- search();
- globalPopup?.showSuccess("删除成功")
- }).catch(err => {
- globalPopup?.showError(err)
- })
- });
- }
- const importVisible = ref(false);
- const importLoading = ref<saveLoadingType>("1");
- function openImportModal() {
- importVisible.value = true;
- }
- function closeImportModal() {
- importVisible.value = false;
- }
- function importExcel(data: any) {
- const formData = new FormData();
- formData.append("multipartFile", data);
- importLoading.value = "2";
- uploadFile(IMPORT_DATA, formData).then(_res => {
- globalPopup?.showSuccess("导入成功")
- importLoading.value = "3";
- search();
- }).catch(err => {
- globalPopup?.showError(err)
- importLoading.value = "4";
- })
- }
- const exportVisible = ref(false);
- const exportLoading = ref<saveLoadingType>("1");
- const btnLoading = ref(false);
- function exportTasks() {
- const data: any[] = tableRef.value?.getSelectionRows()
- if (data.length === 0) {
- // TODO
- exportVisible.value = true;
- return
- }
- btnLoading.value = true;
- const taskIds = data.map((v: any) => v.id).join(",");
- post(EXPORT_DATA_BY_TASK_ID, {
- taskIds
- }).then(({ data }) => {
- downloadFile(data, "任务列表.xlsx");
- btnLoading.value = false;
- }).catch(err => {
- btnLoading.value = false;
- globalPopup?.showError(err)
- })
- }
- function closeExportModal() {
- exportVisible.value = false;
- }
- function exportExcel(data: any) {
- exportLoading.value = "2";
- post(EXPORT_DATA, getFromValue(data)).then(({ data }) => {
- downloadFile(data, "任务列表.xlsx");
- exportLoading.value = "3";
- exportVisible.value = false;
- }).catch(err => {
- globalPopup?.showError(err)
- })
- setTimeout(() => {
- }, 2000)
- }
- function editRow(row: any) {
- isEdit.value = true;
- taskModalVisible.value = true;
- let value = {
- ...row
- }
- if (value.executorId) {
- value.executorId = value.executorId.split(",")
- }
- taskForm.value = value;
- }
- function finishRow(item: any) {
- post(UPDATE_TASK_STATUS, {
- id: item.id,
- status: 2
- }).then(() => {
- search()
- globalPopup?.showSuccess("操作成功")
- }).catch(err => {
- globalPopup?.showError(err)
- })
- }
- function restart(item: any) {
- post(UPDATE_TASK_STATUS, {
- id: item.id,
- status: 0
- }).then(() => {
- search()
- globalPopup?.showSuccess("操作成功")
- }).catch(err => {
- globalPopup?.showError(err)
- })
- }
- function deleteRow(item: any) {
- confirmAction("确定删除吗?").then(() => {
- post(DELETE_TASKS, {
- taskIds: item.id
- }).then(() => {
- search();
- globalPopup?.showSuccess("删除成功")
- }).catch(err => {
- console.log("err", err);
- globalPopup?.showError(err)
- })
- })
- }
- function goDetail(item: any, path: keyof pushMap, typeId: pushMap[keyof pushMap]) {
- router.push({
- path: `/${path}/detail`,
- query: {
- id: item[typeId]
- }
- })
- }
- onBeforeMount(() => {
- pagePermission.value = getFunctionList(MOD);
- searchForm.value = { ...defaultSearchForm };
- })
- onMounted(() => {
- search()
- })
- </script>
- <style lang="scss" scoped></style>
|