From a7ac91bc5ae3c2ce0badca1ae9fc7ed57af95758 Mon Sep 17 00:00:00 2001
From: riku <risaku@163.com>
Date: 星期二, 22 十月 2024 15:15:28 +0800
Subject: [PATCH] 1. 添加子任务编辑功能(暂存)
---
src/api/fysp/subtaskApi.js | 12 +
src/components.d.ts | 6
src/views/fysp/task/components/CompSubTaskEdit.vue | 157 ++++++++++++++++++++++
src/components/list-item/ItemSubTask.vue | 152 +++++++++++++++++---
src/views/fysp/task/components/CompSubTaskList.vue | 73 ++++++++-
src/views/fysp/task/TaskManage.vue | 2
6 files changed, 358 insertions(+), 44 deletions(-)
diff --git a/src/api/fysp/subtaskApi.js b/src/api/fysp/subtaskApi.js
new file mode 100644
index 0000000..972f307
--- /dev/null
+++ b/src/api/fysp/subtaskApi.js
@@ -0,0 +1,12 @@
+import { $fysp } from '../index';
+
+export default {
+ /**
+ * 璋冩暣瀛愪换鍔′俊鎭�
+ * @param {Object} subtask
+ * @returns
+ */
+ adjustSubtask(subtask){
+ return $fysp.post(`subtask/adjust`, subtask).then((res) => res.data);
+ },
+};
diff --git a/src/components.d.ts b/src/components.d.ts
index 12178e1..37e7435 100644
--- a/src/components.d.ts
+++ b/src/components.d.ts
@@ -19,7 +19,6 @@
ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb']
ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem']
ElButton: typeof import('element-plus/es')['ElButton']
- ElButtonGroup: typeof import('element-plus/es')['ElButtonGroup']
ElCalendar: typeof import('element-plus/es')['ElCalendar']
ElCard: typeof import('element-plus/es')['ElCard']
ElCascader: typeof import('element-plus/es')['ElCascader']
@@ -48,11 +47,7 @@
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
ElMenuItemGroup: typeof import('element-plus/es')['ElMenuItemGroup']
ElOption: typeof import('element-plus/es')['ElOption']
- ElPageHeader: typeof import('element-plus/es')['ElPageHeader']
- ElPagination: typeof import('element-plus/es')['ElPagination']
ElPopover: typeof import('element-plus/es')['ElPopover']
- ElRadioButton: typeof import('element-plus/es')['ElRadioButton']
- ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
ElRow: typeof import('element-plus/es')['ElRow']
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
ElSegmented: typeof import('element-plus/es')['ElSegmented']
@@ -67,6 +62,7 @@
ElTabs: typeof import('element-plus/es')['ElTabs']
ElTag: typeof import('element-plus/es')['ElTag']
ElText: typeof import('element-plus/es')['ElText']
+ ElTooltip: typeof import('element-plus/es')['ElTooltip']
ElTree: typeof import('element-plus/es')['ElTree']
ElUpload: typeof import('element-plus/es')['ElUpload']
Footer: typeof import('./components/core/Footer.vue')['default']
diff --git a/src/components/list-item/ItemSubTask.vue b/src/components/list-item/ItemSubTask.vue
index 210bebc..ac1f3ab 100644
--- a/src/components/list-item/ItemSubTask.vue
+++ b/src/components/list-item/ItemSubTask.vue
@@ -1,36 +1,68 @@
<template>
<div class="wrapper">
- <div class="text-title">
- {{ item.name }}
- </div>
- <div class="text-info">
- <div class="text-label">
- <el-icon class="m-r-4" size="16"><LocationInformation /></el-icon>
- <span>浠诲姟鍦板潃锛�</span>
- </div>
- {{ item.scenseaddress }}
- </div>
- <div class="text-info">
- <div class="text-label">
- <!-- <el-icon><Clock /></el-icon> -->
- <el-icon class="m-r-4" size="16"><AlarmClock /></el-icon>
- <span>浠诲姟鏃堕棿锛�</span>
- </div>
- {{ $fm.formatYMD(item.planstarttime) }}
- </div>
- <div class="text-info">
- <div class="text-label">
- <el-icon class="m-r-4" size="16"><User /></el-icon>
- 浠诲姟浜哄憳锛�
- </div>
- {{ item.executorrealtimes }}
- </div>
- <el-row justify="end" style="margin-top: 4px">
- <slot :item="item"></slot>
+ <el-row justify="space-between" class="m-t-4">
+ <el-col :span="20">
+ <div class="text-title">
+ <el-tag
+ size="small"
+ :type="statusType.type"
+ effect="plain"
+ class="m-r-4 m-b-4"
+ >
+ <el-space :size="4">
+ <el-icon size="16">
+ <component :is="statusType.icon"></component>
+ </el-icon>
+ {{ item.status }}
+ </el-space>
+ </el-tag>
+ {{ item.name }}
+ </div>
+ <div class="text-info">
+ <div class="text-label">
+ <el-icon class="m-r-4" size="16"><LocationInformation /></el-icon>
+ <span>浠诲姟鍦板潃锛�</span>
+ </div>
+ {{ item.scenseaddress }}
+ </div>
+ <div class="text-info">
+ <div class="text-label">
+ <!-- <el-icon><Clock /></el-icon> -->
+ <el-icon class="m-r-4" size="16"><AlarmClock /></el-icon>
+ <span>浠诲姟鏃堕棿锛�</span>
+ </div>
+ {{ $fm.formatYMD(item.planstarttime) }}
+ </div>
+ <div class="text-info">
+ <div class="text-label">
+ <el-icon class="m-r-4" size="16"><User /></el-icon>
+ 浠诲姟浜哄憳锛�
+ </div>
+ {{ item.executorrealtimes }}
+ </div>
+ <el-space class="m-t-4">
+ <el-tag size="small" type="info" effect=""
+ >闂锛歿{ status.proNum }}</el-tag
+ >
+ <el-tag size="small" type="info" effect=""
+ >鏁存敼锛歿{ status.changeNum }}</el-tag
+ >
+ <el-tag size="small" :type="changePerType" effect=""
+ >鏁存敼鐜囷細{{ status.changePer }}</el-tag
+ >
+ </el-space>
+ </el-col>
+ <el-col :span="4">
+ <slot :item="item"></slot>
+ </el-col>
</el-row>
</div>
</template>
<script setup>
+import { ref, watch, computed } from 'vue';
+import taskApi from '@/api/fysp/taskApi';
+import ProCheckProxy from '@/views/fysp/check/ProCheckProxy';
+
/**
* 鐩戠瀵硅薄
*/
@@ -40,6 +72,72 @@
default: () => {}
}
});
+
+const loading = ref(false);
+const proList = ref([]);
+const status = ref({});
+
+const statusType = computed(() => {
+ switch (props.item.status) {
+ case '鏈墽琛�':
+ return {
+ type: 'danger',
+ icon: 'WarningFilled'
+ };
+ case '姝e湪鎵ц':
+ return {
+ type: 'success',
+ icon: 'Timer'
+ };
+ case '宸茬粨鏉�':
+ return {
+ type: 'info',
+ icon: 'SuccessFilled'
+ };
+ default:
+ return {
+ type: 'danger',
+ icon: 'Warning'
+ };
+ }
+});
+
+const changePerType = computed(() => {
+ if (status.value.changeNum == 0) {
+ if (status.value.proNum == 0) {
+ return 'success';
+ } else {
+ return 'danger';
+ }
+ } else if (status.value.proNum == status.value.changeNum) {
+ return 'success';
+ } else {
+ return 'warning';
+ }
+});
+
+watch(
+ () => props.item,
+ (nV, oV) => {
+ if (nV != oV) {
+ fetchProblems(nV);
+ }
+ },
+ { immediate: true }
+);
+
+function fetchProblems(subtask) {
+ loading.value = true;
+ taskApi
+ .getProBySubtask(subtask.stguid)
+ .then((res) => {
+ proList.value = res;
+ status.value = ProCheckProxy.calProStatus(res);
+ })
+ .finally(() => {
+ loading.value = false;
+ });
+}
</script>
<style scoped>
.wrapper {
diff --git a/src/views/fysp/task/TaskManage.vue b/src/views/fysp/task/TaskManage.vue
index a3e4f21..8940905 100644
--- a/src/views/fysp/task/TaskManage.vue
+++ b/src/views/fysp/task/TaskManage.vue
@@ -48,7 +48,7 @@
<el-col v-if="curSubTaskList" :span="8">
<CompSubTaskList
create
- :data="curSubTaskList"
+ v-model="curSubTaskList"
:loading="subTaskLoading"
height="56vh"
@add="subTaskDrawer = true"
diff --git a/src/views/fysp/task/components/CompSubTaskEdit.vue b/src/views/fysp/task/components/CompSubTaskEdit.vue
new file mode 100644
index 0000000..a7d6f47
--- /dev/null
+++ b/src/views/fysp/task/components/CompSubTaskEdit.vue
@@ -0,0 +1,157 @@
+<template>
+ <FYForm
+ :form-info="formInfo"
+ :rules="rules"
+ :useCancel="true"
+ @submit="submit"
+ @cancel="cancel"
+ >
+ <template #form-item="{ formObj }">
+ <el-form-item label="浠诲姟鍚嶇О" prop="name">
+ <el-input disabled v-model="formObj.name" placeholder="浠诲姟鍚嶇О" />
+ </el-form-item>
+ <el-form-item label="鍦烘櫙鍦板潃" prop="name">
+ <el-input
+ disabled
+ v-model="formObj.scenseaddress"
+ placeholder="鍦烘櫙鍦板潃"
+ />
+ </el-form-item>
+ <FYOptionTime
+ label="璁″垝鏃堕棿"
+ prop="planstarttime"
+ :initValue="false"
+ type="date"
+ v-model:value="formObj.planstarttime"
+ ></FYOptionTime>
+ <el-form-item label="鎵ц浜�" prop="_executors">
+ <el-select
+ v-model="formObj._executors"
+ multiple
+ clearable
+ collapse-tags
+ placeholder="閫夋嫨鎵ц浜�"
+ :max-collapse-tags="3"
+ style="width: 300px"
+ >
+ <el-option
+ v-for="s in executorOptions"
+ :key="s.value"
+ :label="s.label"
+ :value="s.value"
+ />
+ </el-select>
+ </el-form-item>
+ </template>
+ </FYForm>
+</template>
+<script setup>
+import { ref, computed, onMounted, reactive } from 'vue';
+import subtaskApi from '@/api/fysp/subtaskApi';
+import userApi from '@/api/fysp/userApi';
+
+const props = defineProps({
+ //鍩烘湰淇℃伅
+ modelValue: Object,
+ //鏄垱寤烘垨鑰呮洿鏂�
+ create: Boolean
+});
+
+const emit = defineEmits(['submit', 'cancel']);
+
+// 浠诲姟鎵ц浜洪�夐」
+const executorOptions = ref([]);
+const formInfo = computed(() => {
+ return {
+ ...props.modelValue,
+ _executors: props.modelValue
+ ? props.modelValue.executorguids.split('#')
+ : []
+ };
+});
+
+const rules = reactive({
+ name: [
+ {
+ required: true,
+ message: '鍦烘櫙鍚嶇О涓嶈兘涓虹┖',
+ trigger: 'blur'
+ }
+ ],
+ _scenetype: [
+ {
+ required: true,
+ message: '鍦烘櫙绫诲瀷涓嶈兘涓虹┖',
+ trigger: 'change'
+ }
+ ]
+});
+
+function getExecutors(data) {
+ const ids = [];
+ const uNames = [];
+ const rNames = [];
+ executorOptions.value.forEach((e) => {
+ const index = data._executors.indexOf(e.value);
+ if (index != -1) {
+ ids.push(e.data.guid);
+ uNames.push(e.data.acountname);
+ rNames.push(e.data.realname);
+ }
+ });
+ return {
+ id: ids.join('#'),
+ uName: uNames.join('#'),
+ rName: rNames.join('#')
+ };
+}
+
+// 鍒涘缓鏂板満鏅�
+function createScene(v, success, fail) {
+ // return sceneApi
+ // .createScene(v)
+ // .then(() => {
+ // emit('onSubmit', v);
+ // success();
+ // })
+ // .catch((err) => {
+ // fail(err);
+ // });
+}
+// 鏇存柊鍦烘櫙
+function updateScene(v, success, fail) {
+ return subtaskApi
+ .adjustSubtask(v)
+ .then(() => {
+ emit('submit', v);
+ success();
+ })
+ .catch((err) => {
+ fail(err);
+ });
+}
+function submit(v, success, fail) {
+ return props.create
+ ? createScene(v.value, success, fail)
+ : updateScene(v.value, success, fail);
+}
+function cancel() {
+ emit('cancel');
+}
+
+function initOptions() {
+ userApi.getUserByType(1).then((res) => {
+ executorOptions.value = res.map((v) => {
+ return {
+ label: v.realname,
+ value: v.guid,
+ data: v
+ };
+ });
+ });
+}
+
+onMounted(() => {
+ initOptions();
+});
+</script>
diff --git a/src/views/fysp/task/components/CompSubTaskList.vue b/src/views/fysp/task/components/CompSubTaskList.vue
index b84adbd..b678652 100644
--- a/src/views/fysp/task/components/CompSubTaskList.vue
+++ b/src/views/fysp/task/components/CompSubTaskList.vue
@@ -2,7 +2,7 @@
<el-row justify="space-between">
<el-text>鍗曟棩璁″垝</el-text>
<el-button
- v-show="create && data && data.length > 0"
+ v-show="create && modelValue && modelValue.length > 0"
type="success"
size="small"
@click="add"
@@ -13,17 +13,26 @@
<div>
<el-scrollbar v-loading="loading" :height="height">
<el-space
- v-if="data && data.length > 0"
+ v-if="modelValue && modelValue.length > 0"
fill
:fill-ratio="100"
direction="vertical"
style="width: 100%"
>
- <ItemSubTask v-for="s in data" :key="s.guid" :item="s">
+ <ItemSubTask v-for="s in modelValue" :key="s.guid" :item="s">
<template #default="{ item }">
- <el-button type="danger" size="small" @click="remove(item)"
- >绉婚櫎</el-button
- >
+ <el-space direction="vertical">
+ <el-button plain type="primary" size="small" @click="edit(item)"
+ >缂栬緫</el-button
+ >
+ <el-button
+ :disabled="item.status != '鏈墽琛�'"
+ type="default"
+ size="small"
+ @click="remove(item)"
+ >绉婚櫎</el-button
+ >
+ </el-space>
</template>
</ItemSubTask>
</el-space>
@@ -37,12 +46,29 @@
</div>
</el-scrollbar>
</div>
+ <el-dialog
+ v-model="dialogVisible"
+ width="600"
+ title="涓�閿垱寤烘�讳换鍔�"
+ destroy-on-close
+ :close-on-click-modal="false"
+ :close-on-press-escape="false"
+ :show-close="false"
+ >
+ <CompSubTaskEdit
+ v-model="activeItem"
+ @submit="dialogVisible = false"
+ @cancel="dialogVisible = false"
+ ></CompSubTaskEdit>
+ </el-dialog>
</template>
<script setup>
-import { ref, watch, onMounted } from 'vue';
+import { ref, computed, watch, onMounted, onUnmounted } from 'vue';
+import { ElMessageBox, ElNotification, ElMessage } from 'element-plus';
+import CompSubTaskEdit from './CompSubTaskEdit.vue';
const props = defineProps({
- data: Array,
+ modelValue: Array,
height: {
type: String,
default: '70vh'
@@ -51,15 +77,40 @@
create: Boolean,
loading: Boolean
});
-const curSubTaskList = ref([]);
-const emit = defineEmits(['add', 'remove']);
+const dialogVisible = ref(false)
+const activeItem = ref(null)
+const data = computed(() => props.modelValue);
+
+const emit = defineEmits(['edit', 'add', 'remove', 'update:modelValue']);
function remove(item) {
- emit('remove', item);
+ if (item.status == '鏈墽琛�') {
+ ElMessageBox.confirm('鏄惁绉婚櫎鐩戠浠诲姟', `绉婚櫎纭`, {
+ confirmButtonText: '纭',
+ cancelButtonText: '鍙栨秷',
+ type: 'warning'
+ }).then(() => {
+ const index = data.value.indexOf(item);
+ data.value.splice(index, 1);
+
+ emit('update:modelValue', data.value);
+ emit('remove', item);
+ });
+ }
+}
+
+function edit(item) {
+ activeItem.value = item
+ dialogVisible.value = true
+ emit('edit');
}
function add() {
emit('add');
}
+
+onUnmounted(()=>{
+ dialogVisible.value = false
+})
</script>
--
Gitblit v1.9.3