riku
2024-10-22 a7ac91bc5ae3c2ce0badca1ae9fc7ed57af95758
1. 添加子任务编辑功能(暂存)
已修改4个文件
已添加2个文件
344 ■■■■■ 文件已修改
src/api/fysp/subtaskApi.js 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components.d.ts 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/list-item/ItemSubTask.vue 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/fysp/task/TaskManage.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/fysp/task/components/CompSubTaskEdit.vue 157 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/fysp/task/components/CompSubTaskList.vue 67 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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);
  },
};
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']
src/components/list-item/ItemSubTask.vue
@@ -1,6 +1,21 @@
<template>
  <div class="wrapper">
    <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">
@@ -25,12 +40,29 @@
      </div>
      {{ item.executorrealtimes }}
    </div>
    <el-row justify="end" style="margin-top: 4px">
        <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 '正在执行':
      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 {
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"
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>
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-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) {
  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>