|
|
@@ -0,0 +1,512 @@
|
|
|
+<template>
|
|
|
+ <div class="user-management-container">
|
|
|
+ <div class="side-layout">
|
|
|
+ <div class="tree-side">
|
|
|
+ <div class="head-container">
|
|
|
+ <el-button
|
|
|
+ v-show="workOrderStatus != 20"
|
|
|
+ v-permissions="['order:delivery:plan:add']"
|
|
|
+ class="add-btn"
|
|
|
+ icon="el-icon-plus"
|
|
|
+ type="text"
|
|
|
+ @click="openAddPlan()">
|
|
|
+ 新建计划
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ <div class="left-scroll">
|
|
|
+ <ul class="plan-wrap">
|
|
|
+ <li
|
|
|
+ v-for="(v, i) in planList"
|
|
|
+ :key="i"
|
|
|
+ class="plan-item"
|
|
|
+ :class="v.id == curPlanId ? 'actived' : ''"
|
|
|
+ @click="selectPlanItem(v)">
|
|
|
+ <div class="flex-between" style="margin-bottom: 20px">
|
|
|
+ <span>{{ v.planTitle }}</span>
|
|
|
+ <div class="plan-status" :class="'plan-status-' + v.planStatus" @click="openChangeStatus(v)">
|
|
|
+ {{ plasnStatusObj[v.planStatus] }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="flex-between">
|
|
|
+ <div>{{ parseTime(v.planStartDate, '{m}-{d}') }} ~ {{ parseTime(v.planEndDate, '{m}-{d}') }}</div>
|
|
|
+ <el-button
|
|
|
+ v-show="workOrderStatus != 20 && v.planStatus != 30"
|
|
|
+ style="padding: 0"
|
|
|
+ type="text"
|
|
|
+ @click="openAddPlan(v.id)">
|
|
|
+ 编辑
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="tree-table">
|
|
|
+ <vab-query-form>
|
|
|
+ <vab-query-form-top-panel>
|
|
|
+ <el-form :inline="true" :model="queryForm" @submit.native.prevent>
|
|
|
+ <el-form-item>
|
|
|
+ <el-input
|
|
|
+ v-model.trim="queryForm.progressTitle"
|
|
|
+ clearable
|
|
|
+ placeholder="任务标题"
|
|
|
+ @keyup.enter.native="fetchWorkListPage1" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <el-select
|
|
|
+ v-model="queryForm.progressStatus"
|
|
|
+ clearable
|
|
|
+ placeholder="状态"
|
|
|
+ style="width: 100%"
|
|
|
+ @change="fetchWorkListPage1">
|
|
|
+ <el-option label="未开始" value="10" />
|
|
|
+ <el-option label="已开始" value="20" />
|
|
|
+ <el-option label="已完成" value="30" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <el-select
|
|
|
+ v-model="queryForm.progressLevel"
|
|
|
+ clearable
|
|
|
+ placeholder="级别"
|
|
|
+ style="width: 100%"
|
|
|
+ @change="fetchWorkListPage1">
|
|
|
+ <el-option label="最高" value="10" />
|
|
|
+ <el-option label="普通" value="20" />
|
|
|
+ <el-option label="较低" value="30" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <el-button icon="el-icon-search" type="primary" @click="fetchWorkList">查询</el-button>
|
|
|
+ <el-button icon="el-icon-refresh-right" @click="reset">重置</el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </vab-query-form-top-panel>
|
|
|
+ <vab-query-form-left-panel>
|
|
|
+ <el-button
|
|
|
+ v-show="workOrderStatus != 20 && curPlanStatus != 30"
|
|
|
+ v-permissions="['order:delivery:work:add']"
|
|
|
+ icon="el-icon-plus"
|
|
|
+ type="primary"
|
|
|
+ @click="openAddWork">
|
|
|
+ 新建工作项
|
|
|
+ </el-button>
|
|
|
+ </vab-query-form-left-panel>
|
|
|
+ <vab-query-form-right-panel>
|
|
|
+ <table-tool :columns="columns" :show-columns.sync="showColumns" table-type="productTable" />
|
|
|
+ </vab-query-form-right-panel>
|
|
|
+ </vab-query-form>
|
|
|
+
|
|
|
+ <el-table ref="table" v-loading="listLoading" border :data="tabaleList" :height="$baseTableHeight(2)">
|
|
|
+ <el-table-column align="center" label="序号" show-overflow-tooltip width="80">
|
|
|
+ <template #default="{ $index }">
|
|
|
+ {{ $index + 1 }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ v-for="(item, index) in showColumns"
|
|
|
+ :key="index"
|
|
|
+ align="center"
|
|
|
+ :label="item.label"
|
|
|
+ :min-width="item.minWidth"
|
|
|
+ :prop="item.prop"
|
|
|
+ show-overflow-tooltip
|
|
|
+ :sortable="item.sortable"
|
|
|
+ :width="item.width">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <el-button
|
|
|
+ v-if="item.prop === 'progressTitle'"
|
|
|
+ style="font-size: 14px"
|
|
|
+ type="text"
|
|
|
+ @click="handleWorkDetail(row)">
|
|
|
+ {{ row.progressTitle }}
|
|
|
+ </el-button>
|
|
|
+ <span v-else-if="item.prop === 'progressLevel'">
|
|
|
+ <el-select
|
|
|
+ v-model="row.progressLevel"
|
|
|
+ :disabled="workOrderStatus == 20 || curPlanStatus == 30 || row.progressStatus == 30"
|
|
|
+ placeholder="请选择"
|
|
|
+ @change="changeprogressLevel($event, row)">
|
|
|
+ <el-option label="最高" value="10" />
|
|
|
+ <el-option label="普通" value="20" />
|
|
|
+ <el-option label="较低" value="30" />
|
|
|
+ </el-select>
|
|
|
+ </span>
|
|
|
+ <span v-else-if="item.prop === 'progressStatus'">
|
|
|
+ {{ plasnStatusObj[row.progressStatus] }}
|
|
|
+ </span>
|
|
|
+ <span v-else-if="item.prop === 'startDate'">
|
|
|
+ {{ parseTime(row.startDate, '{y}-{m}-{d}') }}
|
|
|
+ </span>
|
|
|
+ <span v-else-if="item.prop === 'endDate'">
|
|
|
+ {{ parseTime(row.endDate, '{y}-{m}-{d}') }}
|
|
|
+ </span>
|
|
|
+ <span v-else-if="item.prop === 'reaStartDate'">
|
|
|
+ {{ parseTime(row.reaStartDate, '{y}-{m}-{d}') }}
|
|
|
+ </span>
|
|
|
+ <span v-else-if="item.prop === 'reaEndDate'">
|
|
|
+ {{ parseTime(row.reaEndDate, '{y}-{m}-{d}') }}
|
|
|
+ </span>
|
|
|
+ <span v-else>{{ row[item.prop] }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column align="center" fixed="right" label="操作" show-overflow-tooltip width="120">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <el-button
|
|
|
+ v-if="row.progressStatus == 10 && workOrderStatus != 20 && curPlanStatus != 30"
|
|
|
+ type="text"
|
|
|
+ @click="handleStartWork(row)">
|
|
|
+ 开始
|
|
|
+ </el-button>
|
|
|
+ <el-button
|
|
|
+ v-if="row.progressStatus == 20 && workOrderStatus != 20 && curPlanStatus != 30"
|
|
|
+ type="text"
|
|
|
+ @click="handleFinishWork(row)">
|
|
|
+ 完成
|
|
|
+ </el-button>
|
|
|
+ <el-button v-show="workOrderStatus != 20 && curPlanStatus != 30" type="text" @click="handleDelete(row)">
|
|
|
+ 删除
|
|
|
+ </el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <template #empty>
|
|
|
+ <el-image class="vab-data-empty" :src="require('@/assets/empty_images/data_empty.png')" />
|
|
|
+ </template>
|
|
|
+ </el-table>
|
|
|
+ <el-pagination
|
|
|
+ background
|
|
|
+ :current-page="queryForm.pageNum"
|
|
|
+ :layout="layout"
|
|
|
+ :page-size="queryForm.pageSize"
|
|
|
+ :total="total"
|
|
|
+ @current-change="handleCurrentChange"
|
|
|
+ @size-change="handleSizeChange" />
|
|
|
+ </div>
|
|
|
+ <edit-plan ref="plan" @fetch-data="fetchPlanList" />
|
|
|
+ <edit-work ref="work" @fetch-data="fetchWorkListPage1" />
|
|
|
+ <select-status ref="status" @fetch-data="fetchPlanList" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+ import orderWorkApi from '@/api/work/deliver'
|
|
|
+ import planApi from '@/api/work/deliverPlan'
|
|
|
+ import deliverWorkApi from '@/api/work/deliverWork'
|
|
|
+ import TableTool from '@/components/table/TableTool'
|
|
|
+ import EditPlan from '@/views/work/order/deliver/components/editPlan'
|
|
|
+ import EditWork from '@/views/work/order/deliver/components/editWork'
|
|
|
+ import selectStatus from './components/selectStatus'
|
|
|
+ import to from 'await-to-js'
|
|
|
+ export default {
|
|
|
+ name: 'Product',
|
|
|
+ components: { EditPlan, EditWork, TableTool, selectStatus },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ planList: [], //左侧工单列表
|
|
|
+ curPlanId: -1,
|
|
|
+ tabaleList: [],
|
|
|
+ plasnStatusObj: {
|
|
|
+ 10: '未开始',
|
|
|
+ 20: '已开始',
|
|
|
+ 30: '已关闭',
|
|
|
+ },
|
|
|
+ progressLevelOptions: {
|
|
|
+ 10: '最高',
|
|
|
+ 20: '普通',
|
|
|
+ 30: '较低',
|
|
|
+ },
|
|
|
+ listLoading: true,
|
|
|
+ layout: 'total, sizes, prev, pager, next, jumper',
|
|
|
+ total: 0,
|
|
|
+ selectRows: '',
|
|
|
+ queryForm: {
|
|
|
+ pageNum: 1,
|
|
|
+ pageSize: 10,
|
|
|
+ progressStatus: '',
|
|
|
+ progressLevel: '',
|
|
|
+ progressTitle: '',
|
|
|
+ },
|
|
|
+ showColumns: [],
|
|
|
+ columns: [
|
|
|
+ {
|
|
|
+ label: '任务标题',
|
|
|
+ width: '160px',
|
|
|
+ prop: 'progressTitle',
|
|
|
+ sortable: false,
|
|
|
+ disableCheck: true,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '任务内容',
|
|
|
+ prop: 'progressContext',
|
|
|
+ minWidth: '160px',
|
|
|
+ sortable: false,
|
|
|
+ disableCheck: true,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '优先级',
|
|
|
+ width: '120px',
|
|
|
+ prop: 'progressLevel',
|
|
|
+ sortable: false,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '状态',
|
|
|
+ width: '120px',
|
|
|
+ prop: 'progressStatus',
|
|
|
+ sortable: false,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '计划开始时间',
|
|
|
+ width: '120px',
|
|
|
+ prop: 'startDate',
|
|
|
+ sortable: false,
|
|
|
+ disableCheck: true,
|
|
|
+ },
|
|
|
+
|
|
|
+ {
|
|
|
+ label: '计划结束时间',
|
|
|
+ width: '120px',
|
|
|
+ prop: 'endDate',
|
|
|
+ sortable: false,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '实际开始时间',
|
|
|
+ width: '120px',
|
|
|
+ prop: 'reaStartDate',
|
|
|
+ sortable: false,
|
|
|
+ disableCheck: true,
|
|
|
+ },
|
|
|
+
|
|
|
+ {
|
|
|
+ label: '实际结束时间',
|
|
|
+ width: '120px',
|
|
|
+ prop: 'reaEndDate',
|
|
|
+ sortable: false,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '备注',
|
|
|
+ width: '120px',
|
|
|
+ prop: 'remark',
|
|
|
+ sortable: false,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ defaultProps: {
|
|
|
+ key: 'key',
|
|
|
+ label: 'value',
|
|
|
+ },
|
|
|
+ prodClassOptions: [], //产品分类
|
|
|
+ id: 0,
|
|
|
+ curPlanStatus: 0,
|
|
|
+ workOrderStatus: 0,
|
|
|
+ }
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ showColumns: function () {
|
|
|
+ this.$nextTick(() => this.$refs.table.doLayout())
|
|
|
+ },
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.id = parseInt(this.$route.query.id)
|
|
|
+ this.getOrderDetails()
|
|
|
+ this.fetchPlanList()
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ openChangeStatus(v) {
|
|
|
+ if (this.workOrderStatus == 20 || v.planStatus == 30) return
|
|
|
+ this.$refs.status.open(v.id)
|
|
|
+ },
|
|
|
+ selectPlanItem(row) {
|
|
|
+ if (this.curPlanId != row.id) {
|
|
|
+ this.curPlanId = row.id
|
|
|
+ this.curPlanStatus = row.planStatus
|
|
|
+
|
|
|
+ this.queryForm.pageNum = 1
|
|
|
+ this.fetchWorkListPage1()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ reset() {
|
|
|
+ this.queryForm = {
|
|
|
+ pageNum: 1,
|
|
|
+ pageSize: 10,
|
|
|
+ progressStatus: '',
|
|
|
+ progressLevel: '',
|
|
|
+ progressTitle: '',
|
|
|
+ }
|
|
|
+ this.fetchWorkListPage1()
|
|
|
+ },
|
|
|
+ async changeprogressLevel(val, row) {
|
|
|
+ console.log(val, row)
|
|
|
+ const params = {
|
|
|
+ id: row.id,
|
|
|
+ progressLevel: val,
|
|
|
+ }
|
|
|
+ const [err, res] = await to(deliverWorkApi.update(params))
|
|
|
+ if (err) return
|
|
|
+ if (res.code == 200) {
|
|
|
+ this.$baseMessage(res.msg, 'success', 'vab-hey-message-success')
|
|
|
+ }
|
|
|
+ this.fetchWorkList()
|
|
|
+ },
|
|
|
+ // 新建计划
|
|
|
+ openAddPlan(id = null) {
|
|
|
+ this.$refs.plan.open(id)
|
|
|
+ },
|
|
|
+ // 新增工作项
|
|
|
+ openAddWork() {
|
|
|
+ this.$refs.work.open(this.curPlanId)
|
|
|
+ },
|
|
|
+ //工作项详情
|
|
|
+ handleWorkDetail(row) {
|
|
|
+ if (this.workOrderStatus == 20 || this.curPlanStatus == 30 || row.progressStatus == 30) return
|
|
|
+ this.$refs['work'].open(this.planId, row)
|
|
|
+ },
|
|
|
+ // 开始工作项
|
|
|
+ async handleStartWork(row) {
|
|
|
+ this.$prompt('你确定要开始当前任务吗', '提示', {
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ })
|
|
|
+ .then(async ({ value }) => {
|
|
|
+ // 当用户点击确定按钮时,执行的逻辑
|
|
|
+ await this.fetchWorkList()
|
|
|
+ console.log('输入的值为:', value)
|
|
|
+ const [err, res] = await to(deliverWorkApi.startWork({ id: row.id, remark: value }))
|
|
|
+ if (err) return
|
|
|
+ if (res.code == 200) {
|
|
|
+ this.$baseMessage(res.msg, 'success', 'vab-hey-message-success')
|
|
|
+ this.fetchWorkList()
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .catch(() => {
|
|
|
+ // 当用户点击取消按钮时,执行的逻辑
|
|
|
+ console.log('取消输入')
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 完成工作项
|
|
|
+ async handleFinishWork(row) {
|
|
|
+ this.$prompt('你确定要完成当前任务吗', '提示', {
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ })
|
|
|
+ .then(async ({ value }) => {
|
|
|
+ // 当用户点击确定按钮时,执行的逻辑
|
|
|
+ await this.fetchWorkList()
|
|
|
+ console.log('输入的值为:', value)
|
|
|
+ const [err, res] = await to(deliverWorkApi.finishWork({ id: row.id, remark: value }))
|
|
|
+ if (err) return
|
|
|
+ if (res.code == 200) {
|
|
|
+ this.$baseMessage(res.msg, 'success', 'vab-hey-message-success')
|
|
|
+ this.fetchWorkList()
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .catch(() => {
|
|
|
+ // 当用户点击取消按钮时,执行的逻辑
|
|
|
+ console.log('取消输入')
|
|
|
+ })
|
|
|
+ },
|
|
|
+ handleDelete(row) {
|
|
|
+ this.$baseConfirm('你确定要删除当前项吗', null, async () => {
|
|
|
+ const { msg } = await deliverWorkApi.delete({ id: [row.id] })
|
|
|
+ this.$baseMessage(msg, 'success', 'vab-hey-message-success')
|
|
|
+ await this.fetchWorkList()
|
|
|
+ })
|
|
|
+ },
|
|
|
+ handleSizeChange(val) {
|
|
|
+ this.queryForm.pageSize = val
|
|
|
+ this.fetchWorkList()
|
|
|
+ },
|
|
|
+ handleCurrentChange(val) {
|
|
|
+ this.queryForm.pageNum = val
|
|
|
+ this.fetchWorkList()
|
|
|
+ },
|
|
|
+ fetchWorkListPage1() {
|
|
|
+ this.queryForm.pageNum = 1
|
|
|
+ this.fetchWorkList()
|
|
|
+ },
|
|
|
+ // 查询计划
|
|
|
+ async fetchPlanList() {
|
|
|
+ this.listLoading = true
|
|
|
+ const [err, res] = await to(planApi.getList({ deliverOrderId: this.id }))
|
|
|
+ this.listLoading = false
|
|
|
+ if (err) return
|
|
|
+ if (res.code == 200 && res.data) {
|
|
|
+ this.planList = res.data.list
|
|
|
+ if (this.curPlanId === -1 && this.planList.length > 0) {
|
|
|
+ this.curPlanId = this.planList[0].id
|
|
|
+ // this.workOrderStatus = this.planList[0].orderStatus || 10
|
|
|
+ this.curPlanStatus = this.planList[0].planStatus
|
|
|
+ }
|
|
|
+ this.fetchWorkList()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async getOrderDetails() {
|
|
|
+ const [err, res] = await to(orderWorkApi.getDeliverOrder({ id: this.id }))
|
|
|
+ if (err) return
|
|
|
+ if (res.code == 200 && res.data) {
|
|
|
+ this.workOrderStatus = res.data.orderStatus || 10
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 查询工作项
|
|
|
+ async fetchWorkList() {
|
|
|
+ this.listLoading = true
|
|
|
+ const params = Object.assign(this.queryForm, { planId: this.curPlanId })
|
|
|
+ const [err, res] = await to(deliverWorkApi.list(params))
|
|
|
+ this.listLoading = false
|
|
|
+ if (err) return
|
|
|
+ if (res.code == 200 && res.data) {
|
|
|
+ this.tabaleList = res.data.list
|
|
|
+ this.total = res.data.total
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+ }
|
|
|
+</script>
|
|
|
+<style lang="scss" scoped>
|
|
|
+ .el-form-item--small {
|
|
|
+ margin: 0 0 10px 0 !important;
|
|
|
+ }
|
|
|
+ .left-scroll {
|
|
|
+ height: 100%;
|
|
|
+ overflow: auto;
|
|
|
+ }
|
|
|
+ .tree-side {
|
|
|
+ border-right: 0;
|
|
|
+ .plan-item {
|
|
|
+ cursor: pointer;
|
|
|
+ padding: 10px 10px 10px 10px;
|
|
|
+ border-radius: 4px;
|
|
|
+ .flex-between {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .actived {
|
|
|
+ background: rgb(135 206 235 / 40%);
|
|
|
+ }
|
|
|
+ .plan-status {
|
|
|
+ border: 1px solid;
|
|
|
+ border-radius: 30px;
|
|
|
+ padding: 5px 10px;
|
|
|
+ line-height: 1;
|
|
|
+ font-size: 12px;
|
|
|
+ }
|
|
|
+ .plan-status-10 {
|
|
|
+ color: #409eff;
|
|
|
+ border-color: #409eff;
|
|
|
+ }
|
|
|
+ .plan-status-20 {
|
|
|
+ color: #67c23a;
|
|
|
+ border-color: #67c23a;
|
|
|
+ }
|
|
|
+ .plan-status-30 {
|
|
|
+ color: #f56c6c;
|
|
|
+ border-color: #f56c6c;
|
|
|
+ }
|
|
|
+ .add-btn {
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+ }
|
|
|
+</style>
|