Procházet zdrojové kódy

页面修改

master
1341924763@qq.com před 1 týdnem
rodič
revize
d9f296b57c

+ 31
- 12
src/api/daka/attendance-group.js Zobrazit soubor

@@ -1,6 +1,6 @@
import request from '@/utils/request'

// 查询预警结果列表
// 查询考勤组列表
export function queryList(query) {
return request({
url: '/dk/attendanceGroup/list',
@@ -9,15 +9,17 @@ export function queryList(query) {
})
}

// 查询预警结果详细
export function getOperationWarnresult(id) {
// 查询区域列表
export function queryArea(query) {
return request({
url: '/dk/attendanceGroup/' + id,
method: 'get'
url: '/dk/config/list',
method: 'get',
params: query
})
}

// 新增预警结果

// 新增考勤组
export function add(data) {
return request({
url: '/dk/attendanceGroup/add',
@@ -26,19 +28,36 @@ export function add(data) {
})
}

// 修改预警结果
export function updateOperationWarnresult(data) {
// 修改考勤组
export function update(data) {
return request({
url: '/system/operationWarnresult',
url: '/system/attendanceGroup/update',
method: 'put',
data: data
})
}

// 删除预警结果
export function delOperationWarnresult(id) {
// 删除考勤组
export function del(id) {
return request({
url: '/dk/attendanceGroup/del/' + id,
method: 'delete'
})
}

//
export function test(query) {
return request({
url: '/dk/app/getCurrentDayRecord',
method: 'get',
params: query
})
}

// 删除考勤组
export function delUser(id) {
return request({
url: '/system/operationWarnresult/' + id,
url: '/dk/attendanceGroup/delUser/' + id,
method: 'delete'
})
}

+ 1
- 0
src/api/daka/daka-config.js Zobrazit soubor

@@ -37,6 +37,7 @@ export function updateConfig(data) {

// 删除
export function deleteConfig(id) {
console.log(id)
return request({
url: '/dk/config/deleteConfig/' + id,
method: 'delete'

+ 11
- 0
src/api/daka/daka-record.js Zobrazit soubor

@@ -1,4 +1,15 @@
import request from '@/utils/request'
import axios from 'axios';

export const exportExcel = (params) => {
return request({
url: 'dk/record/exportNew',
method: 'get',
params: params,
timeout: 60000,
responseType: 'blob', // 重要:指定响应类型为二进制流
});
};

// 查询预警结果列表
export function queryList(query) {

+ 869
- 0
src/views/components/daka/index.vue Zobrazit soubor

@@ -0,0 +1,869 @@
<template>
<div class="app-container">
<el-row :gutter="20">
<!--部门数据-->
<el-col :span="4" :xs="24" class="app-container--tree">
<!-- <div class="app-container--tree-search">
<el-input
v-model="deptName"
placeholder="请输入部门名称"
clearable
size="small"
prefix-icon="el-icon-search"
style="margin-bottom: 20px"
/>
</div> -->
<div class="app-container--tree-content">
<el-tree
ref="tree"
:data="deptOptions"
:props="defaultProps"
:expand-on-click-node="false"
:filter-node-method="filterNode"
node-key="id"
default-expand-all
highlight-current
@node-click="handleNodeClick"
/>
</div>
</el-col>
<!--用户数据-->
<el-col :span="20" :xs="24">
<el-form
v-show="showSearch"
ref="queryForm"
:model="queryParams"
size="small"
:inline="true"
label-width="68px"
class="app-container--search"
>
<!-- <el-form-item label="用户名称" prop="userName">
<el-input
v-model="queryParams.userName"
placeholder="请输入用户名称"
clearable
style="width: 140px"
@keyup.enter.native="handleQuery"
/>
</el-form-item> -->
<!-- <el-form-item label="手机号码" prop="phonenumber">
<el-input
v-model="queryParams.phonenumber"
placeholder="请输入手机号码"
clearable
style="width: 140px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="用户状态"
clearable
style="width: 140px"
>
<el-option
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker
v-model="dateRange"
style="width: 240px"
value-format="yyyy-MM-dd HH:mm:ss"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="['00:00:00', '23:59:59']"
/>
</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>

<!-- <div class="app-container--toolbar">
<div class="app-container--toolbar-left">
<div class="toolbar-title">
<span>数据列表</span>
</div>
</div>
<div class="app-container--toolbar-right">
<el-button
v-hasPermi="['system:user:add']"
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增</el-button>
<el-button
v-hasPermi="['system:user:edit']"
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改</el-button>
<el-button
v-hasPermi="['system:user:remove']"
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除</el-button>
<el-button
v-hasPermi="['system:user:import']"
type="info"
plain
icon="el-icon-upload2"
size="mini"
@click="handleImport"
>导入</el-button>
<el-button
v-hasPermi="['system:user:export']"
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
>导出</el-button>
<right-toolbar
:show-search.sync="showSearch"
:columns="columns"
@queryTable="getList"
/>
</div>
</div> -->

<el-table
v-loading="loading"
:data="userList"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="50" align="center" />
<el-table-column
v-if="columns[0].visible"
key="userId"
label="用户编号"
align="center"
prop="userId"
/>
<el-table-column
v-if="columns[1].visible"
key="userName"
label="用户名称"
align="center"
prop="userName"
:show-overflow-tooltip="true"
/>
<el-table-column
v-if="columns[2].visible"
key="nickName"
label="用户昵称"
align="center"
prop="nickName"
:show-overflow-tooltip="true"
/>
<el-table-column
v-if="columns[3].visible"
key="deptName"
label="部门"
align="center"
prop="dept.deptName"
:show-overflow-tooltip="true"
/>
<el-table-column
v-if="columns[4].visible"
key="phonenumber"
label="手机号码"
align="center"
prop="phonenumber"
width="120"
/>
<!-- <el-table-column
v-if="columns[5].visible"
key="status"
label="状态"
align="center"
>
<template slot-scope="scope">
<el-switch
v-model="scope.row.status"
active-value="0"
inactive-value="1"
@change="handleStatusChange(scope.row)"
/>
</template>
</el-table-column> -->
<el-table-column
v-if="columns[6].visible"
label="创建时间"
align="center"
prop="createTime"
width="160"
>
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<!-- <el-table-column
label="操作"
align="center"
width="160"
class-name="small-padding fixed-width"
>
<template v-if="scope.row.userId !== 1" slot-scope="scope">
<el-button
v-hasPermi="['system:user:edit']"
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
>修改</el-button>
<el-button
v-hasPermi="['system:user:remove']"
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>删除</el-button>
<el-dropdown
v-hasPermi="['system:user:resetPwd', 'system:user:edit']"
size="mini"
@command="(command) => handleCommand(command, scope.row)"
>
<el-button
size="mini"
type="text"
icon="el-icon-d-arrow-right"
>更多</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
v-hasPermi="['system:user:resetPwd']"
command="handleResetPwd"
icon="el-icon-key"
>重置密码</el-dropdown-item>
<el-dropdown-item
v-hasPermi="['system:user:edit']"
command="handleAuthRole"
icon="el-icon-circle-check"
>分配角色</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</el-table-column> -->
</el-table>

<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</el-col>
</el-row>

<!-- 添加或修改用户配置对话框 -->
<el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
<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="请输入用户昵称"
maxlength="30"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="归属部门" prop="deptId">
<treeselect
v-model="form.deptId"
:options="deptOptions"
:show-count="true"
placeholder="请选择归属部门"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<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="邮箱" prop="email">
<el-input
v-model="form.email"
placeholder="请输入邮箱"
maxlength="50"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item
v-if="form.userId == undefined"
label="用户名称"
prop="userName"
>
<el-input
v-model="form.userName"
placeholder="请输入用户名称"
maxlength="30"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
v-if="form.userId == undefined"
label="用户密码"
prop="password"
>
<el-input
v-model="form.password"
placeholder="请输入用户密码"
type="password"
maxlength="20"
show-password
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="用户性别">
<el-select v-model="form.sex" placeholder="请选择性别">
<el-option
v-for="dict in dict.type.sys_user_sex"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="状态">
<el-radio-group v-model="form.status">
<el-radio
v-for="dict in dict.type.sys_normal_disable"
:key="dict.value"
:label="dict.value"
>{{ dict.label }}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="岗位">
<el-select
v-model="form.postIds"
multiple
placeholder="请选择岗位"
>
<el-option
v-for="item in postOptions"
:key="item.postId"
:label="item.postName"
:value="item.postId"
:disabled="item.status == 1"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="角色">
<el-select
v-model="form.roleIds"
multiple
placeholder="请选择角色"
>
<el-option
v-for="item in roleOptions"
:key="item.roleId"
:label="item.roleName"
:value="item.roleId"
:disabled="item.status == 1"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="备注">
<el-input
v-model="form.remark"
type="textarea"
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>

<!-- 用户导入对话框 -->
<el-dialog
:title="upload.title"
:visible.sync="upload.open"
width="400px"
append-to-body
>
<el-upload
ref="upload"
:limit="1"
accept=".xlsx, .xls"
:headers="upload.headers"
:action="upload.url + '?updateSupport=' + upload.updateSupport"
:disabled="upload.isUploading"
:on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess"
:auto-upload="false"
drag
>
<i class="el-icon-upload" />
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<div slot="tip" class="el-upload__tip text-center">
<div slot="tip" class="el-upload__tip">
<el-checkbox v-model="upload.updateSupport" />
是否更新已经存在的用户数据
</div>
<span>仅允许导入xls、xlsx格式文件。</span>
<el-link
type="primary"
:underline="false"
style="font-size: 12px; vertical-align: baseline"
@click="importTemplate"
>下载模板</el-link>
</div>
</el-upload>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitFileForm">确 定</el-button>
<el-button @click="upload.open = false">取 消</el-button>
</div>
</el-dialog>
</div>
</template>

<script>
import {
listUser,
getUser,
delUser,
addUser,
updateUser,
resetUserPwd,
changeUserStatus,
deptTreeSelect
} from '@/api/system/user'
import { getToken } from '@/utils/auth'
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'

export default {
name: 'User',
dicts: ['sys_normal_disable', 'sys_user_sex'],
components: { Treeselect },
props: {
message: Object,
},
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 用户表格数据
userList: null,
// 弹出层标题
title: '',
// 部门树选项
deptOptions: undefined,
// 是否显示弹出层
open: false,
// 部门名称
deptName: undefined,
// 默认密码
initPassword: undefined,
// 日期范围
dateRange: [],
// 岗位选项
postOptions: [],
// 角色选项
roleOptions: [],
// 表单参数
form: {},
defaultProps: {
children: 'children',
label: 'label'
},
// 用户导入参数
upload: {
// 是否显示弹出层(用户导入)
open: false,
// 弹出层标题(用户导入)
title: '',
// 是否禁用上传
isUploading: false,
// 是否更新已经存在的用户数据
updateSupport: 0,
// 设置上传的请求头部
headers: { Authorization: 'Bearer ' + getToken() },
// 上传的地址
url: process.env.VUE_APP_BASE_API + '/system/user/importData'
},
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
userName: undefined,
phonenumber: undefined,
status: undefined,
deptId: undefined
},
// 列信息
columns: [
{ key: 0, label: `用户编号`, visible: true },
{ key: 1, label: `用户名称`, visible: true },
{ key: 2, label: `用户昵称`, visible: true },
{ key: 3, label: `部门`, visible: true },
{ key: 4, label: `手机号码`, visible: true },
{ key: 5, label: `状态`, visible: true },
{ key: 6, label: `创建时间`, visible: true }
],
// 表单校验
rules: {
userName: [
{ required: true, message: '用户名称不能为空', trigger: 'blur' },
{
min: 2,
max: 20,
message: '用户名称长度必须介于 2 和 20 之间',
trigger: 'blur'
}
],
nickName: [
{ required: true, message: '用户昵称不能为空', trigger: 'blur' }
],
password: [
{ required: true, message: '用户密码不能为空', trigger: 'blur' },
{
min: 5,
max: 20,
message: '用户密码长度必须介于 5 和 20 之间',
trigger: 'blur'
}
],
email: [
{
type: 'email',
message: '请输入正确的邮箱地址',
trigger: ['blur', 'change']
}
],
phonenumber: [
{
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
message: '请输入正确的手机号码',
trigger: 'blur'
}
]
}
}
},
watch: {
// 根据名称筛选部门树
deptName(val) {
this.$refs.tree.filter(val)
},
message(newVal, oldVal) {
// 当 prop 变化时执行此函数
// console.log('接收到新消息:', newVal, this.userList)
oldVal = newVal
// this.handleNewMessage(newVal)
this.getList()
}
},
created() {
this.getList()
this.getDeptTree()
this.getConfigKey('sys.user.initPassword').then((response) => {
this.initPassword = response.msg
})
},
methods: {
/** 查询用户列表 */
getList() {
this.loading = true
console.log(this.message)
listUser(this.addDateRange(this.queryParams, this.dateRange)).then(
(response) => {
const groupMemberIds = this.message.members.map(member => member.userId);
const availableUsers = response.rows.filter(user =>
!groupMemberIds.includes(user.userId)
)
this.userList = availableUsers
this.total = response.total
this.loading = false
}
)
},
/** 查询部门下拉树结构 */
getDeptTree() {
deptTreeSelect().then((response) => {
this.deptOptions = response.data
})
},
// 筛选节点
filterNode(value, data) {
if (!value) return true
return data.label.indexOf(value) !== -1
},
// 节点单击事件
handleNodeClick(data) {
this.queryParams.deptId = data.id
this.handleQuery()
},
// 用户状态修改
handleStatusChange(row) {
const text = row.status === '0' ? '启用' : '停用'
this.$modal
.confirm('确认要"' + text + '""' + row.userName + '"用户吗?')
.then(function() {
return changeUserStatus(row.userId, row.status)
})
.then(() => {
this.$modal.msgSuccess(text + '成功')
})
.catch(function() {
row.status = row.status === '0' ? '1' : '0'
})
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
userId: undefined,
deptId: undefined,
userName: undefined,
nickName: undefined,
password: undefined,
phonenumber: undefined,
email: undefined,
sex: undefined,
status: '0',
remark: undefined,
postIds: [],
roleIds: []
}
this.resetForm('form')
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.queryParams.deptId = undefined
this.$refs.tree.setCurrentKey(null)
this.handleQuery()
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map((item) => item.userId)
this.single = selection.length != 1
this.multiple = !selection.length
this.$emit("handleUserSelectionChange", selection)
},
// 更多操作触发
handleCommand(command, row) {
switch (command) {
case 'handleResetPwd':
this.handleResetPwd(row)
break
case 'handleAuthRole':
this.handleAuthRole(row)
break
default:
break
}
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
getUser().then((response) => {
this.postOptions = response.data.posts
this.roleOptions = response.data.roles
this.open = true
this.title = '添加用户'
this.form.password = this.initPassword
})
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const userId = row.userId || this.ids
getUser(userId).then((response) => {
this.form = response.data.user
this.postOptions = response.data.posts
this.roleOptions = response.data.roles
this.$set(this.form, 'postIds', response.data.postIds)
this.$set(this.form, 'roleIds', response.data.roleIds)
this.open = true
this.title = '修改用户'
this.form.password = ''
})
},
/** 重置密码按钮操作 */
handleResetPwd(row) {
this.$prompt('请输入"' + row.userName + '"的新密码', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
closeOnClickModal: false,
inputPattern: /^.{5,20}$/,
inputErrorMessage: '用户密码长度必须介于 5 和 20 之间'
})
.then(({ value }) => {
resetUserPwd(row.userId, value).then((response) => {
this.$modal.msgSuccess('修改成功,新密码是:' + value)
})
})
.catch(() => {})
},
/** 分配角色操作 */
handleAuthRole: function(row) {
const userId = row.userId
this.$router.push('/system/user-auth/role/' + userId)
},
/** 提交按钮 */
submitForm: function() {
this.$refs['form'].validate((valid) => {
if (valid) {
if (this.form.userId != undefined) {
updateUser(this.form).then((response) => {
this.$modal.msgSuccess('修改成功')
this.open = false
this.getList()
})
} else {
addUser(this.form).then((response) => {
this.$modal.msgSuccess('新增成功')
this.open = false
this.getList()
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
const userIds = row.userId || this.ids
this.$modal
.confirm('是否确认删除用户编号为"' + userIds + '"的数据项?')
.then(function() {
return delUser(userIds)
})
.then(() => {
this.getList()
this.$modal.msgSuccess('删除成功')
})
.catch(() => {})
},
/** 导出按钮操作 */
handleExport() {
this.download(
'system/user/export',
{
...this.queryParams
},
`user_${new Date().getTime()}.xlsx`
)
},
/** 导入按钮操作 */
handleImport() {
this.upload.title = '用户导入'
this.upload.open = true
},
/** 下载模板操作 */
importTemplate() {
this.download(
'system/user/importTemplate',
{},
`user_template_${new Date().getTime()}.xlsx`
)
},
// 文件上传中处理
handleFileUploadProgress(event, file, fileList) {
this.upload.isUploading = true
},
// 文件上传成功处理
handleFileSuccess(response, file, fileList) {
this.upload.open = false
this.upload.isUploading = false
this.$refs.upload.clearFiles()
this.$alert(
"<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
response.msg +
'</div>',
'导入结果',
{ dangerouslyUseHTMLString: true }
)
this.getList()
},
// 提交上传文件
submitFileForm() {
this.$refs.upload.submit()
}
}
}
</script>

+ 1064
- 395
src/views/daka/attendanceteam/index.vue
Diff nebyl zobrazen, protože je příliš veliký
Zobrazit soubor


+ 394
- 123
src/views/daka/config/index.vue Zobrazit soubor

@@ -1,75 +1,184 @@
<template>
<div class="attendance-area-config">
<div class="page-header">
<h1>打卡区域配置</h1>
<p>配置打卡区域,包括地点名称、经纬度和打卡半径</p>
</div>
<div class="content-wrapper">
<!-- 区域列表 -->
<div class="area-list">
<div class="list-header">
<h2>区域列表</h2>
<!-- <button @click="showAddModal = true" class="btn-add">
<i class="fa fa-plus"></i> 添加区域
</button> -->
</div>
<div class="area-table">
<table>
<thead>
<tr>
<th>序号</th>
<th>地点名称</th>
<th>经纬度</th>
<th>打卡半径(米)</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(area, index) in areaList" :key="area.id">
<td>{{ index + 1 }}</td>
<td>{{ area.name }}</td>
<td>{{ area.lng }}, {{ area.lat }}</td>
<td>{{ area.radius }}</td>
<td>
<span :class="area.enableStatus == '0' ? 'status-enabled' : 'status-disabled'">
{{ area.enableStatus == '0' ? '已启用' : '启用' }}
</span>
</td>
<td>
<button @click="editArea(area)" class="btn-edit">
<i class="fa fa-pencil"></i> 编辑
</button>
<button
@click="toggleAreaStatus(area)"
class="btn-status"
:disabled="area.enableStatus =='0'"
>
<i class="fa fa-toggle-on"></i> {{ area.enableStatus == '0' ? '已启用' : '启用' }}
</button>
<button
@click="deleteArea(area)"
class="btn-delete"
:disabled="area.enableStatus == '0'"
>
<i class="fa fa-trash"></i> 删除
</button>
</td>
</tr>
</tbody>
</table>
<div v-if="areaList.length === 0" class="empty-state">
<i class="fa fa-map-o"></i>
<p>暂无打卡区域,请点击上方"添加区域"按钮创建</p>
</div>
</div>
</div>
<!-- 地图选点区域 -->
<div class="map-section">
<div class="app-container">
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增</el-button>
</el-col>
<!-- <el-col :span="1.5">
<el-button
v-hasPermi="['demo:leave:edit']"
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-hasPermi="['demo:leave:remove']"
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-hasPermi="['demo:leave:export']"
type="warning"
plain
icon="el-icon-download"
size="mini"
:loading="exportLoading"
@click="handleExport"
>导出</el-button>
</el-col> -->
<right-toolbar :show-search.sync="showSearch" @queryTable="getList" />
</el-row>

<el-table
v-loading="loading"
:data="areaList"
@selection-change="handleSelectionChange"
>
<!-- <el-table-column type="selection" width="55" align="center" /> -->
<el-table-column v-if="false" label="主键ID" align="center" prop="id" />
<el-table-column
label="地点名称"
align="center"
prop="name"
width="180"
>
</el-table-column>
<el-table-column label="经纬度" align="center" prop="lnglat">
<template slot-scope="scope">
<span
style="
display: inline-flex;
align-items: center;
justify-content: center;
text-align: center;
"
>
{{ scope.row.lng }}, {{ scope.row.lat }}
</span>
</template>
</el-table-column>
<el-table-column
width="150"
label="打卡半径(米)"
align="center"
prop="radius"
>
</el-table-column>
<el-table-column label="状态" align="center" prop="enabled">
<template slot-scope="scope">
<span
v-if="scope.row.enabled"
:class="scope.row.enabled ? 'status-enabled' : 'status-disabled'"
style="
display: inline-flex;
align-items: center;
justify-content: center;
text-align: center;
"
>
已启用
</span>
<span
v-else
style="
display: inline-flex;
align-items: center;
justify-content: center;
text-align: center;
"
>
启用
</span>
</template>
</el-table-column>
<el-table-column
label="操作"
align="center"
width="220"
class-name="small-padding fixed-width"
>
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-circle-check"
@click="editArea(scope.row)"
>编辑</el-button>

<el-button
size="mini"
type="text"
icon="el-icon-camera"
@click="deleteArea(scope.row)"
>删除</el-button>

<el-button
size="mini"
type="text"
icon="el-icon-setting"
@click="toggleAreaStatus(scope.row)"
:disabled="scope.row.enabled"
>{{ scope.row.enabled ? '已启用' : '启用' }}</el-button>

<el-button
size="mini"
type="text"
icon="el-icon-setting"
@click="forbiddenAreaStatus(scope.row)"
:disabled="!scope.row.enabled"
>{{ !scope.row.enabled ? '已禁用' : '禁用' }}</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="960px" append-to-body>
<el-form ref="form" :model="formData" label-width="80px">
<el-form-item label="地点名称" prop="name" label-width="120px">
<el-input v-model="formData.name" placeholder="请输入地点名称" />
</el-form-item>
<el-form-item label="经度" prop="lng" label-width="120px">
<el-input v-model="formData.lng" placeholder="请输入经度" />
</el-form-item>
<el-form-item label="纬度" prop="lat" label-width="120px">
<el-input v-model="formData.lat" placeholder="请输入纬度" />
</el-form-item>
<el-form-item label="打卡半径(米)" prop="radius" label-width="120px">
<el-input v-model="formData.radius" placeholder="请输入用打卡半径(米)" />
</el-form-item>
<!-- <el-form-item label="用途描述" prop="descripetion">
<el-input v-model="formData.descripetion" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="排序权重" prop="sort">
<el-input v-model="formData.sort" placeholder="请输入排序权重" />
</el-form-item> -->
</el-form>
<!-- <div class="map-section">
<h2>地图选点</h2>
<div class="map-controls">
<div class="control-group">
@@ -100,9 +209,6 @@
<span>{{ formData.radius }}米</span>
</div>
</div>
<!-- <div ref="mapContainer" class="map" :style="{ height: mapHeight }"></div> -->
<div class="map-actions">
<button @click="clearMapSelection" class="btn-clear">
<i class="fa fa-eraser"></i> 清除选择
@@ -115,20 +221,21 @@
<i class="fa fa-save"></i> 保存区域
</button>
</div>
</div> -->
<div slot="footer" class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="saveArea">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</div>
<!-- 确认删除模态框 -->
<div v-if="showDeleteModal" class="modal-overlay">
<div class="modal-content">
<h3>确认删除</h3>
<p>确定要删除 "{{ currentDeletingArea.name }}" 区域吗?</p>
<div class="modal-actions">
<button @click="showDeleteModal = false" class="btn-cancel">取消</button>
<button @click="confirmDeleteArea" class="btn-confirm">确认删除</button>
</div>
</el-dialog>


<el-dialog title="删除对话框" :visible.sync="showDeleteModal" width="960px" append-to-body>
删除所选有可能影响打卡,是否确认删除?
<div slot="footer" class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="confirmDeleteArea">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</div>
</el-dialog>
</div>
</template>

@@ -140,10 +247,60 @@ import {
updateConfig
} from '@/api/daka/daka-config'

import map from '@/views/components/daka/map';

export default {
name: 'AttendanceAreaConfig',
dicts: [
'zs_operation_warn_types',
'zs_operation_status',
'zs_operation_compare_status',
'zs_operation_platform',
'daka_check_in_status'
],
data() {
return {
// 按钮loading
buttonLoading: false,
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 表格数据
resultList: [],
// 弹出层标题
title: '',
// 是否显示弹出层
open: false,
// 图片快照时间范围
daterangeWarnTime: [],
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
sysUserName: undefined,
checkInStatus: undefined,
exportRange: undefined,
},
// 表单参数
form: {},
// 结果
warnResult: '',
// 表单校验
rules: {
snapshotUrl: [
{ required: true, message: '图片快照不能为空', trigger: 'blur' }
]
},
daka_check_in_status: [{label: '正常', value: '0'},{label: '迟到', value: '1'},{label: '缺卡', value: '2'}],
// 地图相关
map: null,
marker: null,
@@ -183,44 +340,87 @@ export default {
},
mounted() {
// 加载模拟数据
this.loadMockData();
this.getList();
// 加载地图
this.loadMapScript();
},
methods: {
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
this.buttonLoading = true;
if (this.form.id != null) {
updatePurpose(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
} else {
addPurpose(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
}
}
});
},
// 取消按钮
cancel() {
this.open = false
this.showDeleteModal = false
// this.reset();
},
/** 新增按钮操作 */
handleAdd() {
// this.reset()
this.open = true
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map((item) => item.id)
this.single = selection.length !== 1
this.multiple = !selection.length
},
// 加载模拟数据
loadMockData() {
getList() {
// 这里应该从API获取数据,现在使用模拟数据
this.areaList = [
{
id: 1,
name: '总部办公楼',
lng: 116.404,
lat: 39.915,
radius: 300,
enabled: true
},
{
id: 2,
name: '研发中心',
lng: 116.414,
lat: 39.905,
radius: 200,
enabled: false
},
{
id: 3,
name: '南区仓库',
lng: 116.394,
lat: 39.925,
radius: 500,
enabled: false
}
];
// this.areaList = [
// {
// id: 1,
// name: '总部办公楼',
// lng: 116.404,
// lat: 39.915,
// radius: 300,
// enabled: true
// },
// {
// id: 2,
// name: '研发中心',
// lng: 116.414,
// lat: 39.905,
// radius: 200,
// enabled: false
// },
// {
// id: 3,
// name: '南区仓库',
// lng: 116.394,
// lat: 39.925,
// radius: 500,
// enabled: false
// }
// ];
queryList().then((response) => {
console.log(response)
this.areaList = response
this.loading = false
})

},
@@ -234,9 +434,9 @@ export default {
const script = document.createElement('script');
script.src = `https://api.map.baidu.com/api?type=webgl&v=1.0&ak=${this.baiduMapKey}`;
script.onload = () => {
this.initMap();
};
// script.onload = () => {
// this.initMap();
// };
document.body.appendChild(script);
},
@@ -347,6 +547,11 @@ export default {
addConfig(this.formData).then((res)=>{
console.log(this.formData)
console.log(res)
if(res.code == 200){
this.$message.success("添加成功")
}
this.getList()
this.open = false;
})
// 重置表单
this.clearMapSelection();
@@ -355,6 +560,7 @@ export default {
// 编辑区域
editArea(area) {
this.open = true
// 复制对象,避免直接修改原始数据
this.formData = { ...area };
@@ -366,7 +572,7 @@ export default {
// 切换区域状态
toggleAreaStatus(area) {
if (area.enableStatus == '0') {
if (area.enabled) {
// 已启用的区域不允许禁用
alert('已启用的区域不允许禁用');
return;
@@ -375,10 +581,22 @@ export default {
// 启用区域
const index = this.areaList.findIndex(a => a.id === area.id);
if (index !== -1) {
this.areaList[index].enableStatus = '0';
this.areaList[index].enabled = true;
}
area.enabled = true
updateConfig(area).then((res) => {
console.log(res)
})
},

area.enableStatus = '0'
forbiddenAreaStatus(area) {
// 启用区域
const index = this.areaList.findIndex(a => a.id === area.id);
if (index !== -1) {
this.areaList[index].enabled = false;
}
area.enabled = false
updateConfig(area).then((res) => {
console.log(res)
})
@@ -386,7 +604,7 @@ export default {
// 删除区域
deleteArea(area) {
if (area.enabled == '0') {
if (area.enabled) {
// 已启用的区域不允许删除
alert('已启用的区域不允许删除');
return;
@@ -408,6 +626,14 @@ export default {
console.log(this.currentDeletingArea)
deleteConfig(this.currentDeletingArea.id).then((res)=> {
console.log(res)
if(res.code == 200){
if(res.data == -1){
this.$message.error("此配置已经被绑定,请先接解除绑定后在删除");
}else{
this.$message.success("删除成功")
}
}
this.getList()
})
this.currentDeletingArea = null;
@@ -422,10 +648,55 @@ export default {
this.map = null;
}
}
};
}
</script>
<style lang="scss">
.warn-result table {
width: 100% !important;
}
.warn-result table td a {
display: none;
}
.warn-result table img {
width: 100% !important;
}
.warn-result-message {
.warn-result-text {
font-size: 14px;
color: #303133;
a {
color: #409eff;
text-decoration: underline;
}
}
.warn-result-tips {
font-size: 12px;
color: #999;
margin-top: 10px;
}
}
</style>
<style lang="scss" scoped>
.goods--info {
display: flex;
flex-direction: column;
justify-content: center;
text-align: left;
.el-link {
font-size: 14px;
display: -webkit-box;
-webkit-line-clamp: 2;
line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
em {
font-size: 12px;
color: #999;
font-style: normal;
}
}

<style scoped>
.attendance-area-config {
padding: 20px;
font-family: Arial, sans-serif;

+ 60
- 7
src/views/daka/record/index.vue Zobrazit soubor

@@ -69,10 +69,29 @@
@click="handleExport"
>导出</el-button>
</el-col>
<el-radio-group v-model="queryParams.exportRange" class="ml-4">
<el-radio label="day" size="large">按日</el-radio>
<el-radio label="month" size="large">按月</el-radio>
</el-radio-group>
<el-col :span="8.5">
<div class="block">
<span class="demonstration">按日</span>
<el-date-picker
type="date"
v-model="queryParams.strDay"
size="mini"
format="yyyy 年 MM 月 dd 日"
value-format="yyyy-MM-dd"
placeholder="选择日">
</el-date-picker>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<span class="demonstration">按月</span>
<el-date-picker
v-model="queryParams.strMonth"
type="month"
size="mini"
format="yyyy 年 MM 月"
value-format="yyyy-MM"
placeholder="选择月">
</el-date-picker>
</div>
</el-col>
<right-toolbar :show-search.sync="showSearch" @queryTable="getList" />
</el-row>

@@ -196,7 +215,8 @@ import {
queryList,
delOperationWarnresult,
addOperationWarnresult,
updateOperationWarnresult
updateOperationWarnresult,
exportExcel
} from '@/api/daka/daka-record'

import map from '@/views/components/daka/map';
@@ -241,6 +261,8 @@ export default {
sysUserName: undefined,
checkInStatus: undefined,
exportRange: undefined,
strDay: undefined,
strMonth: undefined,
},
// 表单参数
form: {},
@@ -252,7 +274,8 @@ export default {
{ required: true, message: '图片快照不能为空', trigger: 'blur' }
]
},
daka_check_in_status: [{label: '正常', value: '0'},{label: '迟到', value: '1'},{label: '缺卡', value: '2'}]
daka_check_in_status: [{label: '正常', value: '0'},{label: '迟到', value: '1'},{label: '缺卡', value: '2'}],
}
},
created() {
@@ -262,6 +285,7 @@ export default {
/** 查询结果列表 */
getList() {
this.loading = true
console.log(this.queryParams)
queryList(this.queryParams).then((response) => {
this.resultList = response.rows
this.total = response.total
@@ -396,13 +420,42 @@ export default {
},
/** 导出按钮操作 */
handleExport() {
console.log(this.queryParams)
if(this.queryParams.day && this.queryParams.month){
this.$modal.msgError('日,月只能选择一个')
return
}
if(!this.queryParams.strDay && !this.queryParams.strMonth){
this.$modal.msgError('日,月必须选择一个')
return
}
this.download(
'dk/record/export',
'dk/record/exportNew',
{
...this.queryParams
},
`result_${new Date().getTime()}.xlsx`
)
// exportExcel(this.queryParams).then(response => {
// console.log(response)
// // 创建Blob对象
// const blob = new Blob([response.data], {
// type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
// });
// // 创建下载链接
// const url = window.URL.createObjectURL(blob);
// const a = document.createElement('a');
// a.href = url;
// a.download = '用户数据.xlsx'; // 文件名
// // 触发下载
// document.body.appendChild(a);
// a.click();
// // 释放资源
// document.body.removeChild(a);
// window.URL.revokeObjectURL(url);
// })
}
}
}

Načítá se…
Zrušit
Uložit