Переглянути джерело

行政服务-请假管理

AlvisLiu 1 рік тому
батько
коміт
c623257380

BIN
src/assets/index/qjgl.png


BIN
src/assets/index/wcgl.png


+ 45 - 0
src/pages/administrativeService/leaveManagement/apiItem.js

@@ -0,0 +1,45 @@
+import request from '~/utils/request';
+//列表数据
+export const queryApi = (data = {}) =>
+  request({
+    url: '/xdbg/xzfw_qjgl/index',
+    data
+  });
+// 添加接口
+export const addApi = (data = {}) => request({
+  url: '/xdbg/xzfw_qjgl/add',
+  data: { xdbg_xzfw_qjgl: data }
+});
+//编辑接口
+export const editApi = (chooseId, data = {}) => request({
+  url: '/xdbg/xzfw_qjgl/edit',
+  data: { xxq_id: chooseId, xdbg_xzfw_qjgl: data }
+});
+//详情接口
+export const detailApi = (chooseId) => request({
+  url: '/xdbg/xzfw_qjgl/detail',
+  data: { xxq_id: chooseId }
+});
+//删除接口
+export const deleteApi = (chooseId) => request({
+  url: '/xdbg/xzfw_qjgl/delete',
+  data: { xxq_id: chooseId }
+});
+//搜索接口
+export const searchApi = (keyIn_keyword) => request({
+  url: '/xdbg/xzfw_qjgl/index',
+  data: keyIn_keyword
+})
+
+//通用-科室列表(组织机构use_org)
+export const org_list = (data = {}) =>
+  request({
+    url: '/user/org/index',
+    data
+  });
+//用户列表
+export const org_users = (data) =>
+  request({
+    url: '/user/main/index',
+    data
+  })

+ 313 - 0
src/pages/administrativeService/leaveManagement/index.vue

@@ -0,0 +1,313 @@
+<<<<<<< HEAD
+<template>
+  <div>
+2222
+  </div>
+</template>
+
+<script setup>
+
+</script>
+
+<style lang="scss" scoped>
+
+=======
+<script setup >
+import {ref} from 'vue';
+import {userInfo} from '~/store/user';
+const {uo_type,user_id,uo_id} = userInfo
+import {queryApi,org_users} from './apiItem';
+
+const isBureau = ref(false) // 当前用户是否局端
+isBureau.value = uo_type === '1'
+/***************************请假管理*******************************************/
+
+//外出管理-返回
+const onClickLeft = () => history.back();
+
+const tabActive = ref(0);
+
+const applyType = ref();
+const applyTypeOption = ref([
+  { text: '请假类型', value: '' },
+  { text: '事假', value: 1 },
+  { text: '病假', value: 2 },
+  { text: '婚假', value: 3 },
+  { text: '丧假', value: 4 },
+  { text: '产假', value: 5 },
+  { text: '年休假', value: 6 },
+  { text: '调休', value: 7 },
+  { text: '其他', value: 8 },
+]);
+const applyReason = ref();
+
+
+const tableList = ref([])
+const loading = ref(false)
+const finished = ref(false)
+
+const onLoad = () => {
+  // 异步更新数据
+  // setTimeout 仅做示例,真实场景中一般为 ajax 请求
+  setTimeout(() => {
+    for (let i = 0; i < 10; i++) {
+      list.value.push(list.value.length + 1);
+    }
+
+    // 加载状态结束
+    loading.value = false;
+
+    // 数据全部加载完成
+    if (list.value.length >= 40) {
+      finished.value = true;
+    }
+  }, 1000);
+
+  let transObjs = {
+    page:1
+  }
+  queryApi(transObjs)
+  .then(res => {
+    tableList.value = res.data.page_data;
+    if (tableList.value.length >= res.data.total_rows) {
+      finished.value = true;
+    }
+
+  })
+  .catch(error => {
+    console.log(error)
+  })
+};
+
+const onSubmit = () => {
+  show.value = true;
+}
+
+const show = ref(false);
+
+const value1 = ref('');
+const value2 = ref('');
+const value3 = ref('abc');
+const value4 = ref('');
+const pattern = /\d{6}/;
+
+// 校验函数返回 true 表示校验通过,false 表示不通过
+const validator = (val) => /1\d{10}/.test(val);
+
+// 校验函数可以直接返回一段错误提示
+const validatorMessage = (val) => `${val} 不合法,请重新输入`;
+
+// 校验函数可以返回 Promise,实现异步校验
+const asyncValidator = (val) =>
+  new Promise((resolve) => {
+    showLoadingToast('验证中...');
+
+    setTimeout(() => {
+      closeToast();
+      resolve(val === '1234');
+    }, 1000);
+  });
+
+const onFailed = (errorInfo) => {
+  console.log('failed', errorInfo);
+};
+
+/***************************请假审批*******************************************/
+const applyPerson = ref();
+
+const userLIST = ref([]);
+//获取用户列表
+const getUserList=()=> {
+  let transObjs = {
+    dept_id: uo_id,
+    page: 1,
+    limit: 99999,
+  };
+  org_users(transObjs).then((res) => {
+    if (res.code == 1) {
+      let tempArr = [];
+      res.data.page_data.forEach(item => {
+        tempArr.push({
+          text: item.user_realname,
+          value:item.user_id,
+        })
+      })
+      userLIST.value = tempArr;
+    }
+  });
+}
+getUserList();
+
+
+const handleCheckDialog = (item) => {
+  if (user_id == item.xxq_spr_user_id) {
+    this.dialogCheckVisible = true;
+    this.curCheckId = row.xxq_id;
+  } else {
+    showNotify({ type: 'warning', message: '此条申请,您无法审核~' });
+    return
+  }
+}
+
+
+</script>
+
+<template>
+<div class="leaveMag">
+  <div v-show="isBureau">
+    <div style="width: 100%;text-align: center;"><span style="font-size: 20px;">本功能仅对校端用户开放</span></div>
+  </div>
+  <div class="index" v-show="!isBureau">
+    <van-nav-bar title="请假管理" left-text="返回" left-arrow @click-left="onClickLeft"/>
+
+    <van-tabs v-model:active="tabActive">
+      <van-tab title="请假管理">
+
+        <van-dropdown-menu>
+          <van-dropdown-item v-model="applyType" title="请假类型" :options="applyTypeOption"  @change="dropItemChange" />
+          <van-dropdown-item ref="itemRef2" title="请假事由">
+            <van-cell-group inset>
+              <van-field v-model="applyReason" placeholder="请输入请假事由" />
+            </van-cell-group>
+            <div style="padding: 5px 16px;">
+              <van-button type="primary" block round @click="onConfirm(0)">
+                确认
+              </van-button>
+            </div>
+          </van-dropdown-item>
+        </van-dropdown-menu>
+
+        <van-list v-model:loading="loading" :finished="finished" finished-text="没有更多了" @load="onLoad">
+          <van-cell v-for="(item,index ) in tableList" :key="index" :title="item" >
+            <template #title>
+              <div>申请时间:{{ item.xxq_sqsj }}</div>
+              <div>请假人:{{ item.xxq_qjr }}</div>
+            </template>
+            <template #label>
+              <div>开始时间:{{ item.xxq_kssj }}</div>
+              <div>结束时间:{{ item.xxq_jssj }}</div>
+              <div>请假时长(天):{{ item.xxq_qjsc }}</div>
+              <div>状态:
+                <span :class="item.xxq_zt_option_k == '1' ? 'greenText' : (item.xxq_zt_option_k == '3' ? 'redText' : '')" >{{ item.xxq_zt }}</span>
+              </div>
+            </template>
+
+          </van-cell>
+        </van-list>
+
+        <van-submit-bar  button-text="请假申请" @submit="onSubmit" />
+
+        <van-dialog v-model:show="show" title="请假申请" confirmButtonDisabled="false">
+          <van-form @failed="onFailed">
+            <van-cell-group inset>
+              <!-- 通过 pattern 进行正则校验 -->
+              <van-field
+                v-model="value1"
+                name="申请时间"
+                label="申请时间"
+                placeholder="正则校验"
+                :rules="[{ pattern, message: '请输入正确内容' }]"
+              />
+              <!-- 通过 validator 进行函数校验 -->
+              <van-field
+                v-model="value2"
+                name="请假人:"
+                label="请假人:"
+                placeholder="函数校验"
+                :rules="[{ validator, message: '请输入正确内容' }]"
+              />
+              <!-- 通过 validator 返回错误提示 -->
+              <van-field
+                v-model="value3"
+                name="validatorMessage"
+                placeholder="校验函数返回错误提示"
+                :rules="[{ validator: validatorMessage }]"
+              />
+              <!-- 通过 validator 进行异步函数校验 -->
+              <van-field
+                v-model="value4"
+                name="asyncValidator"
+                placeholder="异步函数校验"
+                :rules="[{ validator: asyncValidator, message: '请输入正确内容' }]"
+              />
+            </van-cell-group>
+            <div style="margin: 16px;">
+              <van-button round block type="primary" native-type="submit">
+                提交
+              </van-button>
+            </div>
+          </van-form>
+
+        </van-dialog>
+
+      </van-tab>
+      <van-tab title="请假审批">
+        <van-dropdown-menu>
+          <van-dropdown-item v-model="applyType" title="请假类型" :options="applyTypeOption"  />
+          <van-dropdown-item v-model="applyPerson" title="申请人" :options="userLIST"  />
+          <van-dropdown-item ref="itemRef2" title="请假事由">
+            <van-cell-group inset>
+              <van-field v-model="applyReason" placeholder="请输入请假事由" />
+            </van-cell-group>
+            <div style="padding: 5px 16px;">
+              <van-button type="primary" block round @click="onConfirm(0)">
+                确认
+              </van-button>
+            </div>
+          </van-dropdown-item>
+        </van-dropdown-menu>
+
+        <van-list v-model:loading="loading" :finished="finished" finished-text="没有更多了" @load="onLoad">
+          <van-cell v-for="(item,index) in tableList" :key="index" :title="item" >
+            <template #title>
+              <div>申请时间:{{ item.xxq_sqsj }}</div>
+              <div>请假人:{{ item.xxq_qjr }}</div>
+            </template>
+            <template #label>
+              <div>开始时间:{{ item.xxq_kssj }}</div>
+              <div>结束时间:{{ item.xxq_jssj }}</div>
+              <div>请假时长(天):{{ item.xxq_qjsc }}</div>
+              <div>请假事由:{{ item.xxq_qjsy }}</div>
+
+            </template>
+
+            <template #right-icon>
+              <van-button type="primary" size="small" @click="handleCheckDialog(item)">审核</van-button>
+            </template>
+          </van-cell>
+        </van-list>
+
+      </van-tab>
+    </van-tabs>
+
+
+
+
+
+
+  </div>
+</div>
+</template>
+
+<style lang="scss" scoped>
+.vant-table-container {
+  width: 100%;
+  padding: 20px;
+  box-sizing: border-box;
+}
+
+.even-row {
+  background-color: #f7f7f7;
+}
+
+.odd-row {
+  background-color: #ffffff;
+}
+.greenText{
+  color: green;
+}
+.redText{
+  color: red;
+}
+>>>>>>> liua
+</style>

+ 45 - 0
src/pages/administrativeService/outManagement/apiItem.js

@@ -0,0 +1,45 @@
+import request from '@/utils/request';
+//列表数据
+export const queryApi = (choosePage, data = {}) =>
+  request({
+    url: '/xdbg/xzfw_wcgl/index',
+    data: { limit: 10, page: choosePage },
+  });
+// 添加接口
+export const addApi = (data = {}) => request({
+  url: '/xdbg/xzfw_wcgl/add',
+  data: { xdbg_xzfw_wcgl: data }
+});
+//编辑接口
+export const editApi = (chooseId, data = {}) => request({
+  url: '/xdbg/xzfw_wcgl/edit',
+  data: { xxw_id: chooseId, xdbg_xzfw_wcgl: data }
+});
+//详情接口
+export const detailApi = (chooseId) => request({
+  url: '/xdbg/xzfw_wcgl/detail',
+  data: { xxw_id: chooseId }
+});
+//删除接口
+export const deleteApi = (chooseId) => request({
+  url: '/xdbg/xzfw_wcgl/delete',
+  data: { xxw_id: chooseId }
+});
+//搜索接口
+export const searchApi = (keyIn_keyword) => request({
+  url: '/xdbg/xzfw_wcgl/index',
+  data: keyIn_keyword
+});
+
+//用户列表
+export const org_users = (data = {}) =>
+  request({
+    url: '/user/main/index',
+    data: {
+      dept_id: data.dept_id,
+      all: '1',
+      page: data.page,
+      limit: data.limit
+
+    }
+  })

+ 46 - 0
src/pages/administrativeService/outManagement/index.vue

@@ -0,0 +1,46 @@
+<<<<<<< HEAD
+<template>
+  <div>
+1111333333
+  </div>
+</template>
+
+<script setup>
+
+</script>
+
+<style lang="scss" scoped>
+
+</style>
+=======
+<script>
+import { ref } from "vue";
+import { userInfo } from "~/store/user";
+const { uo_type } = userInfo;
+import { queryApi } from "./apiItem";
+
+const isBureau = ref(false); // 当前用户是否局端
+isBureau.value = uo_type === "1";
+
+//外出管理-返回
+const onClickLeft = () => history.back();
+
+
+</script>
+
+<template>
+  <div class="outMag">
+    <div v-show="isBureau">
+      <div style="width: 100%; text-align: center">
+        <span style="font-size: 20px">本功能仅对校端用户开放</span>
+      </div>
+    </div>
+    <div class="index" v-show="!isBureau">
+      <van-nav-bar title="外出管理" left-text="返回" left-arrow @click-left="onClickLeft"/>
+
+    </div>
+  </div>
+</template>
+
+<style lang="scss" scoped></style>
+>>>>>>> liua

+ 2 - 0
src/pages/menuData.js

@@ -70,6 +70,8 @@ export const menuList = [
     title: '行政服务',
     list: [
       { icon: getAssetsImages('index/jslswc.png'), menuName: '教师临时外出', path: '/administrativeService/teacherTempGoOut' },
+      { icon: getAssetsImages('index/qjgl.png'), menuName: '请假管理', path: '/administrativeService/leaveManagement' },
+      { icon: getAssetsImages('index/wcgl.png'), menuName: '外出管理', path: '/administrativeService/outManagement' },
     ],
   },
   {

+ 28 - 13
src/store/produ/la.js

@@ -7,16 +7,16 @@ export default {
   "user_role_id": "7",
   "user_level_id": "1",
   "user_detail_id": "0",
-  "user_score": "2",
+  "user_score": "134",
   "create_dateline": "1658113811",
-  "modify_dateline": "1681286358",
+  "modify_dateline": "1692696847",
   "isdelete": "0",
   "area_id1": "0",
   "area_id2": "0",
   "area_id3": "0",
   "area_id4": "0",
-  "dept_id": "1037",
-  "dept_id_all": "1037",
+  "dept_id": "333",
+  "dept_id_all": "333",
   "class_id": null,
   "user_phone": "",
   "user_cardno": "",
@@ -55,7 +55,8 @@ export default {
   "wx_last_token": null,
   "wx_last_login": null,
   "wx_graduation": "0",
-  "token": "8acfOcfYEQGEoGEb3Tti7FSyiHWU0G9Bc_aqye6XvHRiJjsiwLemLLvh9eDTujtxSYSkVG4jJ_ab52LY6XtFg_aVAuPZGadey7jD0vqIHl_ap26t",
+  "power_set": null,
+  "token": "f2c13s93wtxoJJ8lVACuzIcuCnZSYa909r8bxoz4FACGWgAUwT4bSejSiPJkPSCzzqXv8iNFasvHeFQLexjs6veDo70Vapy00YWN2EHJBvU",
   "setting": {
       "sitename": "景宁教育魔方",
       "sitedomain": "http://60.188.226.44:8090/",
@@ -73,18 +74,32 @@ export default {
           "uo_type": "1"
       },
       {
-          "uo_id": "1037",
-          "uo_name": "钉钉部署",
-          "uo_master_username": "6360ae01f70a665a9821efbe",
+          "uo_id": "1036",
+          "uo_name": "学校人员组织",
+          "uo_master_username": "",
           "uo_type": "1"
+      },
+      {
+          "uo_id": "1045",
+          "uo_name": "小学",
+          "uo_master_username": "",
+          "uo_type": "1"
+      },
+      {
+          "uo_id": "333",
+          "uo_name": "景宁畲族自治县红星小学",
+          "uo_master_username": "6360ae4ef70a665a9821efc3",
+          "uo_type": "2"
       }
   ],
-  "uo_id": "1037",
-  "uo_type": "1",
-  "uo_name": "钉钉部署",
+  "uo_id": "333",
+  "uo_type": "2",
+  "uo_name": "景宁畲族自治县红星小学",
   "dept_ids": [
       "323",
-      "1037"
+      "1036",
+      "1045",
+      "333"
   ],
   "dept_master": []
-}
+}

+ 5 - 5
src/store/user.js

@@ -1,11 +1,11 @@
 import { defineStore } from 'pinia'
 
-// import produ from './produ/lwj'
+import produ from './produ/la'
 
-// localStorage.setItem(
-//   'userInfo',
-//   JSON.stringify(produ),
-// )
+localStorage.setItem(
+  'userInfo',
+  JSON.stringify(produ),
+)
 
 // const RoleMap = {
 //   JLD: [1, 2, 3],

+ 170 - 0
src/utils/request.js

@@ -0,0 +1,170 @@
+import axios from 'axios'
+import { showNotify  } from 'vant'
+
+import { userInfo } from '~/store/user'
+const { token } = userInfo
+
+const service = axios.create({
+  baseURL: window.globalVariables.api,
+  method: 'post',
+  timeout: 60000,
+  headers: {
+    'Content-Type': 'application/x-www-form-urlencoded',
+  },
+})
+
+service.interceptors.request.use(
+  (config) => {
+    // do something before request is sent
+
+    config.data = Object.assign(
+      {
+        token,
+        site: 'jnmf',
+        client: 'web',
+        api: 'json',
+        // from: 'backend',
+        issubmit: (config.url.endsWith('add') || config.url.endsWith('edit')) ? 1 : undefined
+      },
+      config.data || {}
+    )
+    if (config.method === 'get') {
+      config.params = Object.assign(
+        {
+          token,
+        },
+        config.params || {}
+      )
+    }
+    // 短时间多个请求会冲突
+    // console.groupCollapsed('axios: ' + config.url)
+    // console.log('request', config.data)
+    return config
+  },
+  (error) => {
+    // do something with request error
+    console.log(error) // for debug
+    return Promise.reject(error)
+  }
+)
+
+// response interceptor
+let isRelogin = false
+service.interceptors.response.use(
+  (response, c) => {
+    const { code, msg, data } = response.data
+    if (code === '10001') {
+      if (!isRelogin) {
+        isRelogin = true
+        showNotify({
+          type: 'warning',
+          message: msg
+        })
+        request({
+          url: '/user/main/login',
+          data: {
+            token: data.token
+          }
+        }).then(res => {
+          if (res.code == 1) {
+            localStorage.setItem('userInfo', JSON.stringify(res.data));
+            isRelogin = false
+            // 视情况打开
+            location.reload()
+          }
+        })
+      }
+
+    } else if (code != '1') {
+      // Message.error({ message: msg, dangerouslyUseHTMLString: true })
+      showNotify({
+        type: 'warning',
+        message: msg
+      })
+    }
+    // console.log('response', response.data)
+    // console.groupEnd()
+    return response.data
+  },
+  (error) => {
+    console.error('err' + error) // for debug
+    return Promise.reject(error)
+  }
+)
+
+// 上传
+export const request = axios.create({
+  baseURL: window.globalVariables.api,
+  method: 'post',
+  timeout: 5000,
+  headers: {
+    'Content-Type': 'application/x-www-form-urlencoded',
+  },
+})
+request.interceptors.response.use(
+  (response) => {
+    const { code, msg } = response.data
+    if (code !== '1') {
+      showNotify({
+        type: 'warning',
+        message: msg
+      })
+    }
+    return response.data
+  },
+  (error) => {
+    console.log('err' + error) // for debug
+    return Promise.reject(error)
+  }
+)
+
+export function download(url, data, name) {
+  const params = Object.assign({ token, limit: 10000, page: 1, api: 'xls' }, data)
+  const paramsStr = Object.entries(params).map(([k, v]) => `${k}=${v}`).join('&')
+  const el = document.createElement('a')
+  const href = `${window.globalVariables.api}${url}?${paramsStr}`
+  el.setAttribute('href', href)
+  name && el.setAttribute('download', name)
+  el.click()
+}
+
+export function download2(url, data, name) {
+  const el = document.createElement('a')
+  // const href = `${window.globalVariables.api}/openapi/download.php?path=${url}&name=${name}`
+  const ext = url.split('.').pop()
+  const filename = name.endsWith(`.${ext}`) ? name : `${name}.${ext}`
+  const href = `${window.globalVariables.oss}/${url}/${filename}`
+  el.setAttribute('href', href)
+  name && el.setAttribute('download', name)
+  console.log('download2:', href)
+  el.click()
+}
+
+export function download3(url, data, name) {
+  const el = document.createElement('a')
+  const href = `${url}/${name}`
+  el.setAttribute('href', href)
+  name && el.setAttribute('download', name)
+  el.click()
+}
+
+const obj2form = (data) => {
+  const formData = new FormData()
+  Object.keys(data).forEach(key => formData.append(key, data[key]))
+  return formData;
+}
+export default (...args) => {
+  console.log('args :>> ', args);
+  if (!isRelogin) {
+    const c = args[0]
+    if (c.$type === 'import')
+      return service(Object.assign({ ...c }, {
+        timeout: 10 * 60 * 1000,
+        transformRequest: [obj2form],
+      }))
+    return service(...args)
+  }
+  else
+    return Promise.reject({})
+}
+