考勤组

This commit is contained in:
西城念云 2020-02-24 08:33:11 +08:00
parent ea9c3b2f02
commit 65c0150f5f
8 changed files with 1413 additions and 286 deletions

View File

@ -0,0 +1,53 @@
import request from '@/utils/request'
// 查询考勤组管理列表
export function listGroup(query) {
return request({
url: '/base/group/list',
method: 'get',
params: query
})
}
// 查询考勤组管理详细
export function getGroup(id) {
return request({
url: '/base/group/' + id,
method: 'get'
})
}
// 新增考勤组管理
export function addGroup(data) {
return request({
url: '/base/group',
method: 'post',
data: data
})
}
// 修改考勤组管理
export function updateGroup(data) {
return request({
url: '/base/group',
method: 'put',
data: data
})
}
// 删除考勤组管理
export function delGroup(id) {
return request({
url: '/base/group/' + id,
method: 'delete'
})
}
// 导出考勤组管理
export function exportGroup(query) {
return request({
url: '/base/group/export',
method: 'get',
params: query
})
}

View File

@ -0,0 +1,53 @@
import request from '@/utils/request'
// 查询考勤记录列表
export function listRecord(query) {
return request({
url: '/base/record/list',
method: 'get',
params: query
})
}
// 查询考勤记录详细
export function getRecord(id) {
return request({
url: '/base/record/' + id,
method: 'get'
})
}
// 新增考勤记录
export function addRecord(data) {
return request({
url: '/base/record',
method: 'post',
data: data
})
}
// 修改考勤记录
export function updateRecord(data) {
return request({
url: '/base/record',
method: 'put',
data: data
})
}
// 删除考勤记录
export function delRecord(id) {
return request({
url: '/base/record/' + id,
method: 'delete'
})
}
// 导出考勤记录
export function exportRecord(query) {
return request({
url: '/base/record/export',
method: 'get',
params: query
})
}

View File

@ -1,127 +1,135 @@
import request from '@/utils/request'
import { praseStrEmpty } from "@/utils/ruoyi";
// 查询用户列表
export function listUser(query) {
return request({
url: '/system/user/list',
method: 'get',
params: query
})
}
// 查询用户详细
export function getUser(userId) {
return request({
url: '/system/user/' + praseStrEmpty(userId),
method: 'get'
})
}
// 新增用户
export function addUser(data) {
return request({
url: '/system/user',
method: 'post',
data: data
})
}
// 修改用户
export function updateUser(data) {
return request({
url: '/system/user',
method: 'put',
data: data
})
}
// 删除用户
export function delUser(userId) {
return request({
url: '/system/user/' + userId,
method: 'delete'
})
}
// 导出用户
export function exportUser(query) {
return request({
url: '/system/user/export',
method: 'get',
params: query
})
}
// 用户密码重置
export function resetUserPwd(userId, password) {
const data = {
userId,
password
}
return request({
url: '/system/user/resetPwd',
method: 'put',
data: data
})
}
// 用户状态修改
export function changeUserStatus(userId, status) {
const data = {
userId,
status
}
return request({
url: '/system/user/changeStatus',
method: 'put',
data: data
})
}
// 查询用户个人信息
export function getUserProfile() {
return request({
url: '/system/user/profile',
method: 'get'
})
}
// 修改用户个人信息
export function updateUserProfile(data) {
return request({
url: '/system/user/profile',
method: 'put',
data: data
})
}
// 用户密码重置
export function updateUserPwd(oldPassword, newPassword) {
const data = {
oldPassword,
newPassword
}
return request({
url: '/system/user/profile/updatePwd',
method: 'put',
params: data
})
}
// 用户头像上传
export function uploadAvatar(data) {
return request({
url: '/system/user/profile/avatar',
method: 'post',
data: data
})
}
// 下载用户导入模板
export function importTemplate() {
return request({
url: '/system/user/importTemplate',
method: 'get'
})
}
import request from '@/utils/request'
import { praseStrEmpty } from "@/utils/ruoyi";
// 查询用户列表
export function listUser(query) {
return request({
url: '/system/user/list',
method: 'get',
params: query
})
}
// 查询用户详细
export function getUser(userId) {
return request({
url: '/system/user/' + praseStrEmpty(userId),
method: 'get'
})
}
// 新增用户
export function addUser(data) {
return request({
url: '/system/user',
method: 'post',
data: data
})
}
// 修改用户
export function updateUser(data) {
return request({
url: '/system/user',
method: 'put',
data: data
})
}
// 删除用户
export function delUser(userId) {
return request({
url: '/system/user/' + userId,
method: 'delete'
})
}
// 导出用户
export function exportUser(query) {
return request({
url: '/system/user/export',
method: 'get',
params: query
})
}
// 用户密码重置
export function resetUserPwd(userId, password) {
const data = {
userId,
password
}
return request({
url: '/system/user/resetPwd',
method: 'put',
data: data
})
}
// 用户状态修改
export function changeUserStatus(userId, status) {
const data = {
userId,
status
}
return request({
url: '/system/user/changeStatus',
method: 'put',
data: data
})
}
// 查询用户个人信息
export function getUserProfile() {
return request({
url: '/system/user/profile',
method: 'get'
})
}
// 修改用户个人信息
export function updateUserProfile(data) {
return request({
url: '/system/user/profile',
method: 'put',
data: data
})
}
// 用户密码重置
export function updateUserPwd(oldPassword, newPassword) {
const data = {
oldPassword,
newPassword
}
return request({
url: '/system/user/profile/updatePwd',
method: 'put',
params: data
})
}
// 用户头像上传
export function uploadAvatar(data) {
return request({
url: '/system/user/profile/avatar',
method: 'post',
data: data
})
}
// 下载用户导入模板
export function importTemplate() {
return request({
url: '/system/user/importTemplate',
method: 'get'
})
}
// 查询用户
export function userSelect() {
return request({
url: '/system/user/userSelect',
method: 'get'
})
}

View File

@ -1,70 +1,100 @@
import Vue from 'vue'
import Cookies from 'js-cookie'
import 'normalize.css/normalize.css' // a modern alternative to CSS resets
import Element from 'element-ui'
import './assets/styles/element-variables.scss'
import '@/assets/styles/index.scss' // global css
import '@/assets/styles/ruoyi.scss' // ruoyi css
import App from './App'
import store from './store'
import router from './router'
import permission from './directive/permission'
import './assets/icons' // icon
import './permission' // permission control
import { getDicts } from "@/api/system/dict/data";
import { getConfigKey } from "@/api/system/config";
import { parseTime, resetForm, addDateRange, selectDictLabel, download } from "@/utils/ruoyi";
import Pagination from "@/components/Pagination";
// 全局方法挂载
Vue.prototype.getDicts = getDicts
Vue.prototype.getConfigKey = getConfigKey
Vue.prototype.parseTime = parseTime
Vue.prototype.resetForm = resetForm
Vue.prototype.addDateRange = addDateRange
Vue.prototype.selectDictLabel = selectDictLabel
Vue.prototype.download = download
Vue.prototype.msgSuccess = function (msg) {
this.$message({ showClose: true, message: msg, type: "success" });
}
Vue.prototype.msgError = function (msg) {
this.$message({ showClose: true, message: msg, type: "error" });
}
Vue.prototype.msgInfo = function (msg) {
this.$message.info(msg);
}
// 全局组件挂载
Vue.component('Pagination', Pagination)
Vue.use(permission)
/**
* If you don't want to use mock-server
* you want to use MockJs for mock api
* you can execute: mockXHR()
*
* Currently MockJs will be used in the production environment,
* please remove it before going online! ! !
*/
Vue.use(Element, {
size: Cookies.get('size') || 'medium' // set element-ui default size
})
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
store,
render: h => h(App)
})
import Vue from 'vue'
import Cookies from 'js-cookie'
import 'normalize.css/normalize.css' // a modern alternative to CSS resets
import Element from 'element-ui'
import './assets/styles/element-variables.scss'
import '@/assets/styles/index.scss' // global css
import '@/assets/styles/ruoyi.scss' // ruoyi css
import App from './App'
import store from './store'
import router from './router'
import permission from './directive/permission'
import './assets/icons' // icon
import './permission' // permission control
import { getDicts } from "@/api/system/dict/data";
import { getConfigKey } from "@/api/system/config";
import { parseTime, resetForm, addDateRange, selectDictLabel, download } from "@/utils/ruoyi";
import Pagination from "@/components/Pagination";
// 全局方法挂载
Vue.prototype.getDicts = getDicts
Vue.prototype.getConfigKey = getConfigKey
Vue.prototype.parseTime = parseTime
Vue.prototype.resetForm = resetForm
Vue.prototype.addDateRange = addDateRange
Vue.prototype.selectDictLabel = selectDictLabel
Vue.prototype.download = download
Vue.prototype.msgSuccess = function (msg) {
this.$message({ showClose: true, message: msg, type: "success" });
}
Vue.prototype.msgError = function (msg) {
this.$message({ showClose: true, message: msg, type: "error" });
}
Vue.prototype.msgInfo = function (msg) {
this.$message.info(msg);
}
// 全局组件挂载
Vue.component('Pagination', Pagination)
Vue.use(permission)
function formatDateByDate(date, fmt) {
date = new Date(date);
if (typeof(fmt) === "undefined") {
fmt = "yyyy-MM-dd HH:mm:ss";
}
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
}
let o = {
'M+': date.getMonth() + 1,
'd+': date.getDate(),
'H+': date.getHours(),
'm+': date.getMinutes(),
's+': date.getSeconds()
}
for (let k in o) {
if (new RegExp(`(${k})`).test(fmt)) {
let str = o[k] + ''
fmt = fmt.replace(RegExp.$1, RegExp.$1.length === 1 ? str : ('00' + str).substr(str.length));
}
}
return fmt
};
//定义一个时间过滤器
Vue.filter("FormatDateByDate", function(date, fmt) {
return formatDateByDate(date, fmt);
});
/**
* If you don't want to use mock-server
* you want to use MockJs for mock api
* you can execute: mockXHR()
*
* Currently MockJs will be used in the production environment,
* please remove it before going online! ! !
*/
Vue.use(Element, {
size: Cookies.get('size') || 'medium' // set element-ui default size
})
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
store,
render: h => h(App)
})

View File

@ -0,0 +1,443 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="90px">
<el-form-item label="考勤组名称" prop="attendanceName">
<el-input
v-model="queryParams.attendanceName"
placeholder="请输入考勤组名称"
clearable
size="small"考勤组名称
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="班次类型" prop="classType">
<el-select v-model="queryParams.classType" placeholder="请选择班次类型" clearable size="small">
<el-option
v-for="dict in classTypeOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
/>
</el-select>
</el-form-item>
<el-form-item label="班次" prop="classes">
<el-select v-model="queryParams.classes" placeholder="请选择班次" clearable size="small">
<el-option
v-for="dict in classesOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['base:group:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['base:group:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['base:group:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['base:group:export']"
>导出</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" stripe border fit highlight-current-row :data="groupList" @selection-change="handleSelectionChange" @sort-change='tableSortChange' @row-dblclick="handleUpdate">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="行号" width="80" align="center">
<template slot-scope="scope">{{scope.$index + 1}}</template>
</el-table-column>
<el-table-column label="UUID" align="center" prop="id" v-if="false"/>
<el-table-column label="考勤组名称" align="center" prop="attendanceName" sortable='custom' :sort-orders="['ascending', 'descending']" />
<el-table-column label="拍照设置" align="center" prop="photoSet" sortable='custom' :sort-orders="['ascending', 'descending']" />
<el-table-column label="班次类型" align="center" prop="classType" :formatter="classTypeFormat" />
<el-table-column label="班次" align="center" prop="classes" :formatter="classesFormat" />
<el-table-column label="备注" align="center" prop="remark" sortable='custom' :sort-orders="['ascending', 'descending']" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
plain
size="small"
type="primary"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['base:group:edit']"
>修改</el-button>
<el-button
plain
size="small"
type="primary"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['base:group:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改考勤组管理对话框 -->
<el-dialog :title="title" :visible.sync="open" width="600px">
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-form-item label="考勤组名称" prop="attendanceName">
<el-input v-model="form.attendanceName" placeholder="请输入考勤组名称" />
</el-form-item>
<el-form-item label="成员" prop="attendancePeople">
<el-select v-model="form.attendancePeople" placeholder="请选择考勤人员" @focus="getUsers"/>
</el-form-item>
<el-form-item label="日历" prop="calendarId">
<el-input v-model="form.calendarId" placeholder="请输入日历" />
</el-form-item>
<el-form-item label="定位地址" prop="address">
<el-input v-model="form.address" placeholder="请输入定位地址" />
</el-form-item>
<el-form-item label="定位误差" prop="addError">
<el-select v-model="form.addError" filterable>
<el-option
v-for="item in addErrorOptions"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="拍照设置" prop="photoSet">
<el-select v-model="form.photoSet" filterable>
<el-option
v-for="item in PhotoSetOptions"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="班次类型">
<el-select v-model="form.classType" placeholder="请选择班次类型">
<el-option
v-for="dict in classTypeOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="班次">
<el-select v-model="form.classes" placeholder="请选择班次">
<el-option
v-for="dict in classesOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
></el-option>
</el-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
<el-dialog :title="userTitle" :visible.sync="userOpen" width="600px">
<el-transfer
v-model="form.attendanceName"
:props="{
key: 'value',
label: 'desc'
}"
:data="Users">
</el-transfer>
</el-dialog>
</div>
</template>
<script>
import { listGroup, getGroup, delGroup, addGroup, updateGroup, exportGroup } from "@/api/base/group";
import { userSelect} from "@/api/system/user";
export default {
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
total: 0,
//
groupList: [],
//
title: "",
//
open: false,
//
userTitle: "",
//
userOpen: false,
//
classTypeOptions: [],
//
classesOptions: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
orderByColumn: undefined,
isAsc: undefined,
attendanceName: undefined,
classType: undefined,
classes: undefined,
},
//
addErrorOptions: [{
value: '无限制',
label: '无限制'
}, {
value: '500',
label: '500米'
}, {
value: '1000',
label: '1000米'
}, {
value: '1500',
label: '1500米'
}, {
value: '2000',
label: '2000米'
}],
PhotoSetOptions: [{
value: '必须拍照',
label: '必须拍照'
}, {
value: '可选拍照',
label: '可选拍照'
}, {
value: '定位异常拍照',
label: '定位异常拍照'
}],
//
Users:[],
//
form: {},
//
rules: {
attendanceName: [
{ required: true, message: "考勤组名称不能为空", trigger: "blur" }
],
attendancePeople: [
{ required: true, message: "成员不能为空", trigger: "blur" }
],
}
};
},
created() {
this.getList();
this.getDicts("sys_class_type").then(response => {
this.classTypeOptions = response.data;
});
this.getDicts("sys_classes").then(response => {
this.classesOptions = response.data;
});
},
methods: {
/** 通用考勤组管理排序 */
tableSortChange(column) {
this.queryParams.pageNum = 1;
if (column.order === 'descending') {
this.queryParams.orderByColumn = column.prop;
this.queryParams.isAsc = 'desc';
} else {
this.queryParams.orderByColumn = column.prop;
this.queryParams.isAsc = 'asc';
}
this.getList();
},
/** 查询人员列表 */
getUsers() {
this.loading = true;
userSelect().then(response => {
console.log(response.data);
this.userOpen = true;
this.userTitle = "选择考勤人员";
this.loading = false;
});
},
/** 查询考勤组管理列表 */
getList() {
this.loading = true;
listGroup(this.queryParams).then(response => {
this.groupList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
classTypeFormat(row, column) {
return this.selectDictLabel(this.classTypeOptions, row.classType);
},
//
classesFormat(row, column) {
return this.selectDictLabel(this.classesOptions, row.classes);
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: undefined,
attendanceName: undefined,
attendancePeople: undefined,
calendarId: undefined,
address: undefined,
addError: '无限制',
photoSet: '必须拍照',
classType: undefined,
classes: undefined,
createBy: undefined,
createTime: undefined,
updateBy: undefined,
updateTime: undefined,
remark: undefined
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!=1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加考勤组管理";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
getGroup(id).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改考勤组管理";
});
},
/** 提交按钮 */
submitForm: function() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != undefined) {
updateGroup(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess("修改成功");
this.open = false;
this.getList();
} else {
this.msgError(response.msg);
}
});
} else {
addGroup(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess("新增成功");
this.open = false;
this.getList();
} else {
this.msgError(response.msg);
}
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$confirm('是否确认删除考勤组管理编号为"' + ids + '"的数据项?', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(function() {
return delGroup(ids);
}).then(() => {
this.getList();
this.msgSuccess("删除成功");
}).catch(function() {});
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams;
this.$confirm('是否确认导出所有考勤组管理数据项?', "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(function() {
return exportGroup(queryParams);
}).then(response => {
this.download(response.msg);
}).catch(function() {});
}
}
};
</script>

View File

@ -0,0 +1,524 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="100px">
<el-form-item label="考勤组名称" prop="deptName">
<el-input
v-model="queryParams.deptName"
placeholder="请输入考勤组名称"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="姓名" prop="userName">
<el-input
v-model="queryParams.userName"
placeholder="请输入姓名"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="手机号码" prop="phonenumber">
<el-input
v-model="queryParams.phonenumber"
placeholder="请输入手机号码"
clearable
size="small"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="班次" prop="classes">
<el-select v-model="queryParams.classes" placeholder="请选择班次" clearable size="small">
<el-option
v-for="dict in classesOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
/>
</el-select>
</el-form-item>
<el-form-item label="工作日期" prop="workDate">
<el-date-picker clearable size="small" style="width: 200px"
v-model="queryParams.workDate"
type="date"
value-format="yyyy-MM-dd"
placeholder="选择工作日期">
</el-date-picker>
</el-form-item>
<el-form-item label="打卡类型" prop="punchType">
<el-select v-model="queryParams.punchType" placeholder="请选择打卡类型" clearable size="small">
<el-option
v-for="dict in punchTypeOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
/>
</el-select>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable size="small">
<el-option
v-for="dict in statusOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['base:record:add']"
>新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['base:record:edit']"
>修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['base:record:remove']"
>删除
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['base:record:export']"
>导出
</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" stripe border fit highlight-current-row :data="recordList"
@selection-change="handleSelectionChange" @sort-change='tableSortChange' @row-dblclick="handleUpdate">
<el-table-column type="selection" width="55" align="center"/>
<el-table-column label="行号" width="80" align="center">
<template slot-scope="scope">{{scope.$index + 1}}</template>
</el-table-column>
<el-table-column label="UUID" align="center" prop="id" v-if="false"/>
<el-table-column label="考勤组名称" align="center" prop="deptName" sortable='custom'
:sort-orders="['ascending', 'descending']" width="110"/>
<el-table-column label="姓名" align="center" prop="userName" sortable='custom'
:sort-orders="['ascending', 'descending']"/>
<el-table-column label="手机号码" align="center" prop="phonenumber" sortable='custom'
:sort-orders="['ascending', 'descending']" width="110"/>
<el-table-column label="班次" align="center" prop="classes" :formatter="classesFormat"/>
<el-table-column label="工作日期" align="center" prop="workDate" width="120">
<template slot-scope="scope">
<!-- <span>{{ parseTime(scope.row.workDate) }}</span>-->
<span>{{ scope.row.workDate | formatDateByDate('yyyy-MM-dd') }}</span>
</template>
</el-table-column>
<el-table-column label="打卡日期" align="center" prop="punchDate" width="120">
<template slot-scope="scope">
<!-- <span>{{ parseTime(scope.row.punchDate) }}</span>-->
<span>{{ scope.row.punchDate | formatDateByDate('yyyy-MM-dd') }}</span>
</template>
</el-table-column>
<el-table-column label="时间段" align="center" prop="timeQuantum" sortable='custom'
:sort-orders="['ascending', 'descending']"/>
<el-table-column label="打卡类型" align="center" prop="punchType" :formatter="punchTypeFormat"/>
<el-table-column label="打卡时间" align="center" prop="punchTime" width="110">
<template slot-scope="scope">
<!-- <span>{{ parseTime(scope.row.punchTime) }}</span>-->
<span>{{ scope.row.punchTime | formatDateByDate('HH:mm:ss') }}</span>
</template>
</el-table-column>
<el-table-column label="状态" align="center" prop="status" :formatter="statusFormat"/>
<el-table-column label="拍照路径" align="center" prop="picUrl" sortable='custom'
:sort-orders="['ascending', 'descending']"/>
<el-table-column label="定位地址" align="center" prop="address" sortable='custom'
:sort-orders="['ascending', 'descending']"/>
<el-table-column label="备注" align="center" prop="remark" sortable='custom'
:sort-orders="['ascending', 'descending']"/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="180">
<template slot-scope="scope">
<el-button
plain
size="small"
type="primary"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['base:record:edit']"
>修改
</el-button>
<el-button
plain
size="small"
type="primary"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['base:record:remove']"
>删除
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改考勤记录对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px">
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-row>
<el-col :span="12">
<el-form-item label="考勤组名称" prop="deptName">
<el-input v-model="form.deptName" placeholder="请输入考勤组名称"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="姓名" prop="userName">
<el-input v-model="form.userName" placeholder="请输入姓名"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="手机号码" prop="phonenumber">
<el-input v-model="form.phonenumber" placeholder="请输入手机号码" maxlength="11"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="班次">
<el-select v-model="form.classes" placeholder="请选择班次">
<el-option
v-for="dict in classesOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="工作日期" prop="workDate">
<el-date-picker clearable size="small" style="width: 200px"
v-model="form.workDate"
type="date"
value-format="yyyy-MM-dd"
placeholder="选择工作日期">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="打卡日期" prop="punchDate">
<el-date-picker clearable size="small" style="width: 200px"
v-model="form.punchDate"
type="date"
value-format="yyyy-MM-dd"
placeholder="选择打卡日期">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="时间段" prop="timeQuantum">
<el-input v-model="form.timeQuantum" placeholder="请输入时间段" disabled="false"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="打卡类型">
<el-select v-model="form.punchType" placeholder="请选择打卡类型">
<el-option
v-for="dict in punchTypeOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="打卡时间" prop="punchTime">
<el-time-picker clearable size="small" style="width: 200px"
v-model="form.punchTime"
type="date"
value-format="HH:mm:ss"
placeholder="选择打卡时间">
</el-time-picker>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="状态">
<el-select v-model="form.status" placeholder="请选择状态">
<el-option
v-for="dict in statusOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="拍照路径" prop="picUrl">
<el-input v-model="form.picUrl" placeholder="请输入拍照路径"/>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="定位地址" prop="address">
<el-input v-model="form.address" placeholder="请输入定位地址"/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listRecord, getRecord, delRecord, addRecord, updateRecord, exportRecord } from '@/api/base/record'
export default {
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
total: 0,
//
recordList: [],
//
title: '',
//
open: false,
//
classesOptions: [],
//
punchTypeOptions: [],
//
statusOptions: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
orderByColumn: undefined,
isAsc: undefined,
deptName: undefined,
userName: undefined,
phonenumber: undefined,
classes: undefined,
workDate: undefined,
punchType: undefined,
status: undefined
},
//
form: {},
//
rules: {
deptName: [
{ required: true, message: '考勤组名称不能为空', trigger: 'blur' }
], phonenumber: [
{ required: true, message: '手机号码不能为空', trigger: 'blur' }
]
}
}
},
created() {
this.getList()
this.getDicts('sys_classes').then(response => {
this.classesOptions = response.data
})
this.getDicts('sys_sign').then(response => {
this.punchTypeOptions = response.data
})
this.getDicts('sys_sign_status').then(response => {
this.statusOptions = response.data
})
},
methods: {
/** 通用考勤记录排序 */
tableSortChange(column) {
this.queryParams.pageNum = 1
if (column.order === 'descending') {
this.queryParams.orderByColumn = column.prop
this.queryParams.isAsc = 'desc'
} else {
this.queryParams.orderByColumn = column.prop
this.queryParams.isAsc = 'asc'
}
this.getList()
},
/** 查询考勤记录列表 */
getList() {
this.loading = true
listRecord(this.queryParams).then(response => {
this.recordList = response.rows
this.total = response.total
this.loading = false
})
},
//
classesFormat(row, column) {
return this.selectDictLabel(this.classesOptions, row.classes)
},
//
punchTypeFormat(row, column) {
return this.selectDictLabel(this.punchTypeOptions, row.punchType)
},
//
statusFormat(row, column) {
return this.selectDictLabel(this.statusOptions, row.status)
},
//
cancel() {
this.open = false
this.reset()
},
//
reset() {
this.form = {
id: undefined,
deptName: undefined,
userName: undefined,
phonenumber: undefined,
classes: undefined,
workDate: undefined,
punchDate: undefined,
timeQuantum: undefined,
punchType: undefined,
punchTime: undefined,
status: undefined,
picUrl: undefined,
address: undefined,
createBy: undefined,
createTime: undefined,
updateBy: undefined,
updateTime: undefined,
remark: undefined
}
this.resetForm('form')
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm')
this.handleQuery()
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length != 1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = '添加考勤记录'
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id = row.id || this.ids
getRecord(id).then(response => {
this.form = response.data
this.open = true
this.title = '修改考勤记录'
})
},
/** 提交按钮 */
submitForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.id != undefined) {
updateRecord(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess('修改成功')
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
} else {
addRecord(this.form).then(response => {
if (response.code === 200) {
this.msgSuccess('新增成功')
this.open = false
this.getList()
} else {
this.msgError(response.msg)
}
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids
this.$confirm('是否确认删除考勤记录编号为"' + ids + '"的数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return delRecord(ids)
}).then(() => {
this.getList()
this.msgSuccess('删除成功')
}).catch(function() {
})
},
/** 导出按钮操作 */
handleExport() {
const queryParams = this.queryParams
this.$confirm('是否确认导出所有考勤记录数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function() {
return exportRecord(queryParams)
}).then(response => {
this.download(response.msg)
}).catch(function() {
})
}
}
}
</script>

View File

@ -20,7 +20,6 @@
:expand-on-click-node="false"
:filter-node-method="filterNode"
ref="tree"
:default-expand-all="isExpand"
@node-click="handleNodeClick"
/>
</div>
@ -135,8 +134,8 @@
<el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="40" align="center" />
<el-table-column label="用户编号" align="center" prop="userId" />
<el-table-column label="用户名称" align="center" prop="userName" :show-overflow-tooltip="true" />
<el-table-column label="用户昵称" align="center" prop="nickName" :show-overflow-tooltip="true" />
<el-table-column label="用户账号" align="center" prop="userName" :show-overflow-tooltip="true" />
<el-table-column label="用户姓名" align="center" prop="nickName" :show-overflow-tooltip="true" />
<el-table-column label="部门" align="center" prop="dept.deptName" :show-overflow-tooltip="true" />
<el-table-column label="手机号码" align="center" prop="phonenumber" width="120" />
<el-table-column label="状态" align="center">
@ -202,8 +201,8 @@
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-row>
<el-col :span="12">
<el-form-item label="用户昵称" prop="nickName">
<el-input v-model="form.nickName" placeholder="请输入用户昵称" />
<el-form-item label="用户姓名" prop="nickName">
<el-input v-model="form.nickName" placeholder="请输入用户姓名" />
</el-form-item>
</el-col>
<el-col :span="12">
@ -222,8 +221,8 @@
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="用户名称" prop="userName">
<el-input v-model="form.userName" placeholder="请输入用户名称" />
<el-form-item label="用户账号" prop="userName">
<el-input v-model="form.userName" placeholder="请输入用户账号" />
</el-form-item>
</el-col>
<el-col :span="12">
@ -281,6 +280,18 @@
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="考勤组" prop="groupId">
<el-select v-model="form.groupId" clearable placeholder="请选择考勤组">
<el-option
v-for="item in groupOptions"
:key="item.id"
:label="item.attendanceName"
:value="item.id"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="备注">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
@ -371,6 +382,8 @@ export default {
postOptions: [],
//
roleOptions: [],
//
groupOptions: [],
//
form: {},
defaultProps: {
@ -404,10 +417,10 @@ export default {
//
rules: {
userName: [
{ required: true, message: "用户名称不能为空", trigger: "blur" }
{ required: true, message: "用户账号不能为空", trigger: "blur" }
],
nickName: [
{ required: true, message: "用户昵称不能为空", trigger: "blur" }
{ required: true, message: "用户姓名不能为空", trigger: "blur" }
],
deptId: [
{ required: true, message: "归属部门不能为空", trigger: "blur" }
@ -503,6 +516,7 @@ export default {
this.form = {
userId: undefined,
deptId: undefined,
groupId: undefined,
userName: undefined,
nickName: undefined,
password: undefined,
@ -540,6 +554,7 @@ export default {
getUser().then(response => {
this.postOptions = response.posts;
this.roleOptions = response.roles;
this.groupOptions = response.groups;
this.open = true;
this.title = "添加用户";
this.form.password = this.initPassword;
@ -554,6 +569,7 @@ export default {
this.form = response.data;
this.postOptions = response.posts;
this.roleOptions = response.roles;
this.groupOptions = response.groups;
this.form.postIds = response.postIds;
this.form.roleIds = response.roleIds;
this.open = true;

View File

@ -1,80 +1,80 @@
<template>
<el-form ref="form" :model="user" :rules="rules" label-width="80px">
<el-form-item label="用户昵称" prop="nickName">
<el-input v-model="user.nickName" />
</el-form-item>
<el-form-item label="手机号码" prop="phonenumber">
<el-input v-model="user.phonenumber" maxlength="11" />
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input v-model="user.email" maxlength="50" />
</el-form-item>
<el-form-item label="性别">
<el-radio-group v-model="user.sex">
<el-radio label="0"></el-radio>
<el-radio label="1"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-button type="primary" size="mini" @click="submit">保存</el-button>
<el-button type="danger" size="mini" @click="close">关闭</el-button>
</el-form-item>
</el-form>
</template>
<script>
import { updateUserProfile } from "@/api/system/user";
export default {
props: {
user: {
type: Object
}
},
data() {
return {
//
rules: {
nickName: [
{ required: true, message: "用户昵称不能为空", trigger: "blur" }
],
email: [
{ required: true, message: "邮箱地址不能为空", trigger: "blur" },
{
type: "email",
message: "'请输入正确的邮箱地址",
trigger: ["blur", "change"]
}
],
phonenumber: [
{ required: true, message: "手机号码不能为空", trigger: "blur" },
{
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
message: "请输入正确的手机号码",
trigger: "blur"
}
]
}
};
},
methods: {
submit() {
this.$refs["form"].validate(valid => {
if (valid) {
updateUserProfile(this.user).then(response => {
if (response.code === 200) {
this.msgSuccess("修改成功");
} else {
this.msgError(response.msg);
}
});
}
});
},
close() {
this.$store.dispatch("tagsView/delView", this.$route);
this.$router.push({ path: "/index" });
}
}
};
</script>
<template>
<el-form ref="form" :model="user" :rules="rules" label-width="80px">
<el-form-item label="用户姓名" prop="nickName">
<el-input v-model="user.nickName" />
</el-form-item>
<el-form-item label="手机号码" prop="phonenumber">
<el-input v-model="user.phonenumber" maxlength="11" />
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input v-model="user.email" maxlength="50" />
</el-form-item>
<el-form-item label="性别">
<el-radio-group v-model="user.sex">
<el-radio label="0"></el-radio>
<el-radio label="1"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-button type="primary" size="mini" @click="submit">保存</el-button>
<el-button type="danger" size="mini" @click="close">关闭</el-button>
</el-form-item>
</el-form>
</template>
<script>
import { updateUserProfile } from "@/api/system/user";
export default {
props: {
user: {
type: Object
}
},
data() {
return {
//
rules: {
nickName: [
{ required: true, message: "用户姓名不能为空", trigger: "blur" }
],
email: [
{ required: true, message: "邮箱地址不能为空", trigger: "blur" },
{
type: "email",
message: "'请输入正确的邮箱地址",
trigger: ["blur", "change"]
}
],
phonenumber: [
{ required: true, message: "手机号码不能为空", trigger: "blur" },
{
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
message: "请输入正确的手机号码",
trigger: "blur"
}
]
}
};
},
methods: {
submit() {
this.$refs["form"].validate(valid => {
if (valid) {
updateUserProfile(this.user).then(response => {
if (response.code === 200) {
this.msgSuccess("修改成功");
} else {
this.msgError(response.msg);
}
});
}
});
},
close() {
this.$store.dispatch("tagsView/delView", this.$route);
this.$router.push({ path: "/index" });
}
}
};
</script>