前端的具体实现。主要有两个 vue 页面。一个登录页面(Login.vue),一个主页面(Main.vue)。主页面中包含一个表单(用于新建请假申请),一个 table(用于显示待办列表),一个 Drawer (用于重新提交被驳回的申请),一个 Modal 对话框(用户办理或审批待办事项)。

1. 登录页面

<template>
  <div>
    <h1 align="center">登录</h1>
    <Select v-model="model1" style="width:200px">
      <Option v-for="item in users" :value="item.value" :key="item.value">{{ item.label }}</Option>
    </Select>
    <br>
    <br>
    <Button @click="login()" align="center" type="default">登录</Button>
  </div>
</template>
<script>
import { _login } from "@/api/data";
export default {
  data() {
    return {
      users: [
        {
          value: "张三",
          label: "张三"
        },
        {
          value: "李四",
          label: "李四"
        },
        {
          value: "王五",
          label: "王五"
        },
        {
          value: "赵六",
          label: "赵六"
        }
      ],
      model1: ""
    };
  },
  methods: {
    login() {
    //   alert(this.model1);
      _login({"username":this.model1}).then(res=>{
          console.log(res);
          if(res.data.success==true){
            this.$Message.success("登录成功");
            this.$store.state.username = res.data.data;
            this.$router.push({name:"main"});
          }else{
            this.$Message.error("登录失败");
          }
      })
    }
  }
};
</script>

页面很简单,只有一个 Select 和一个登录按钮。用户可以登录 4 个测试账号:张三、李四、王五、赵六,分别演示 4 种不同角色:请假人、leader、总监和 HR,用这 4 个角色刚好能够完成流程图中的一个完整流程。
如果用户登录成功,跳转到 main 路由,即 Main.vue。

login() 方法是登录方法。登录成功后,用户名保存到 vuex 的 store 中。在 main.js 中,引入了 vuex:

import store from './store'

......

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

2. 网络调用

网络调用封装在 data.js,每个方法都很类似,分别用于调用服务器的登录、查询待办、新建请假条、leader 审批、总监审批、人资备案、重新提交等接口:

import axios from 'axios'

// 登录
export const _login = (params) => {
  console.log(params)
  return axios.post('http://localhost:8080/login',
    params
  )
}
// 查询待办
export const _todoList = (params) => {
  return axios.post('http://localhost:8080/todoList',
    params
  )
}
// 新建请假条
export const _newLeave = (params) => {
  return axios.post('http://localhost:8080/newLeave',
    params
  )
}
// leader 审批
export const _leaderApprove = (params) => {
  return axios.post('http://localhost:8080/leaderApprove',
    params
  )
}
// director 审批
export const _directorApprove = (params) => {
  return axios.post('http://localhost:8080/directorApprove',
    params
  )
}
// hr 备案
export const _hrRecord = (params) => {
  return axios.post('http://localhost:8080/hrRecord',
    params
  )
}
// 申请人重新提交
export const _submitApplication = (params) => {
  return axios.post('http://localhost:8080/submitApplication',
    params
  )
}

3. 主页面

登录成功后就进入主页面(main.vue):

页面上半部分是一个表单,允许用户新建请假申请。下半部分是待办列表,允许用户对待办任务进行处理。

新建请假申请

首先编写表单:

<h1>我要请假</h1>
    <Row style="margin-bottom:1%;border-top:1px solid #ccc;padding-top:2%">
      <Col span="12" style="font-size:16px">请假事由</Col>
      <Col span="12">
        <i-input v-model="reason" placeholder="请假的原因" style="width:200px;outline:none"></i-input>
      </Col>
    </Row>
    <Row style="margin-bottom:1%">
      <Col span="12" style="font-size:16px">开始日期</Col>
      <Col span="12">
        <DatePicker
          type="date"
          v-model="date"
          placeholder="从哪天开始请假"
          format="yyyy-MM-dd"
          style="width: 200px"
        ></DatePicker>
      </Col>
    </Row>
    <Row style="margin-bottom:1%;">
      <Col span="12" style="font-size:16px">请假天数</Col>
      <Col span="12">
        <i-input v-model="days" placeholder="0" style="width:200px;outline:none"></i-input>
      </Col>
    </Row>
    <Row style="margin-bottom:1%;border-top:1px solid #ccc;padding-top:2%">
      <Col span="24">
        <i-button type="default" @click="newLeave()">提交</i-button>
      </Col>
    </Row>

“提交”按钮绑定了 newLeave() 方法:

newLeave() {
      let params = {};

      if (this.isLogin() == false) {
        // 如果未登录
        return;
      } else {
        params.username = this.$store.state.username;
      }
      if (this.reason != null) {
        params.reason = this.reason;
      }
      if (this.date == null || this.date === "") {
        this.$Message.error({
          content: "请填写开始日期",
          duration: 4,
          closable: true
        });
        return;
      } else {
        params.date = this.date;
      }
      if (this.days == null || this.days === "" || parseInt(this.days) == 0) {
        this.$Message.error({
          content: "请填写正确的请假天数",
          duration: 4,
          closable: true
        });
      } else {
        params.days = parseInt(this.days);
      }
      // 硬编码的上级和总监
      params.leader = "李四";
      params.director = "王五";
      params.hr = "赵六";

      _newLeave(params).then(res => {
        console.log(res);
        if (res.data.success == true) {
          this.reason = "";
          this.date = "";
          this.days = 0;

          this.$Message.success("请假申请提交成功");
        } else {
          this.$Message.error({
            content: res.data.message,
            duration: 10,
            closable: true
          });
        }
      });
    }

待办列表

首先是模板代码:

<h1>我的待办</h1>
    <Table :columns="columns" :data="data" stripe></Table>

Table 的数据源绑定了 columns 和 data 变量:

export default {
  data() {
    return {
      columns: [
        {
          title: "任务",
          key: "title"
        },
        {
          title: "请假日期",
          key: "date"
        },
        {
          title: "请假天数",
          key: "days"
        },
        {
          title: "请假理由",
          key: "reason"
        },
        {
          title: "操作",
          key: "action",
          render: (h, params) => {
            return h("div", [
              h(
                "Button",
                {
                  props: {
                    type: "default",
                    size: "small"
                  },
                  on: {
                    click: () => {
                      this.handle(params.row);
                    }
                  }
                },
                "办理"
              )
            ]);
          }
        }
      ],
      data: []
    };
  }
}

然后是获取待办数据。首先引入 data.js 的所有方法:

import {
  _todoList,
  _newLeave,
  _leaderApprove,
  _directorApprove,
  _hrRecord
} from "@/api/data";

然后在 methods 中声明一个方法 todoList:

todoList() {
      _todoList({ username: this.$store.state.username }).then(res => {
        if (res.data.success == true) {
          this.data = res.data.data;
          for (var i = 0; i < this.data.length; i++) {
            let obj = this.data[i];
            obj.title = obj.applicant + "有一条请假申请待您处理";
          }
        } else {
          _this.$Message.error({
            content: res.data.message,
            duration: 10,
            closable: true
          });
        }
      });
    },

然后在 mounted 中调用这个方法:

 mounted() {
    this.todoList();
  }

这样就列出了用户的所有待办。注意当前登录用户从 vuex 的 store 中获取。

办理

待办列表的“操作”列中有一个“办理”按钮,点击这个按钮,允许用户对待办任务进行处理。这是在 handle 方法中进行处理的。在 handle 方法中,判断用户的身份,如果用户是申请人,那么显示一个 Drawer ,在 Drawer 中让用户编辑表单后重新提交申请。如果用户是上级或总监,则显示审批对话框,让用户进行审批/驳回操作。如果用户是 hr,则显示备案对话框,让用户进行备案操作:

handle(task) {
      let username = this.$store.state.username;
      if (this.isLogin() == false) {
        // 如果未登录
        return;
      }
      if (username == task.applicant) {
        // 驳回后重新提交
        this.showEdit(task);
      } else {
        let title = "审批";
        let content = `<p>你同意${task.applicant}的请假申请吗?</p>
        <p>请假人:${task.applicant}<p>
        <p>请假日期:${task.date}</p><p>请假天数:${task.days}</p>
        <p>请假事由:${task.reason}</p>`;
        let cancelText = "驳回";
        let okText = "同意";
        let onOk = () => {
          this.approve(task, username, 1);
        };
        let onCancel = () => {
          this.approve(task, username, 0);
        };

        if (username == task.hr) {
          title = "备案";
          content = `<p>是否对${task.applicant}的请假申请进行备案?</p>
        <p>请假人:${task.applicant}<p>
        <p>请假日期:${task.date}</p><p>请假天数:${task.days}</p>
        <p>请假事由:${task.reason}</p>`;
          cancelText = "";
          okText = "备案";
          onOk = () => {
            
          }
        }
        this.$Modal.confirm({
          title: title,
          content: content,
          closable: true,
          cancelText: cancelText,
          okText: okText,
          onOk: onOk,
          onCancel: onCancel
        });
      }
    }
Logo

前往低代码交流专区

更多推荐