Commit 18656f01 by wangchunyang

日常管理框架代码

parent 083e4d98
import axios from '@/libs/api.request'
// 入库列表
export const getInboundList = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmInbound/selectList',
method: 'post',
data: param
})
}
// 保存入库(含明细)
export const saveInbound = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmInbound/save',
method: 'post',
data: param
})
}
// 删除入库记录
export const deleteInbound = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmInbound/delete',
method: 'post',
data: param
})
}
// 执行入库(生成库存变更与日志)
export const doInbound = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmInbound/doInbound',
method: 'post',
data: param
})
}
// 待归还列表(从申领中查询)
export const getPendingReturnList = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmInbound/selectPendingReturnList',
method: 'post',
data: param
})
}
// 处理归还(生成入库单并更新库存)
export const processReturn = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmInbound/processReturn',
method: 'post',
data: param
})
}
// 库存查询
export const getInventoryList = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmInbound/selectInventoryList',
method: 'post',
data: param
})
}
// 详情
export const getInboundById = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmInbound/getById',
method: 'post',
data: param
})
}
import axios from '@/libs/api.request'
// 申领列表(包含历史与查询)
export const getBorrowList = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmBorrow/selectList',
method: 'post',
data: param
})
}
// 待审核列表
export const getPendingBorrowList = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmBorrow/selectPendingList',
method: 'post',
data: param
})
}
// 保存申请(含明细)
export const saveBorrowApplication = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmBorrow/save',
method: 'post',
data: param
})
}
// 提交
export const submitBorrow = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmBorrow/submit',
method: 'post',
data: param
})
}
// 撤回
export const revokeBorrow = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmBorrow/revoke',
method: 'post',
data: param
})
}
// 审批通过(内部生成出库、更新库存)
export const approveBorrow = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmBorrow/approve',
method: 'post',
data: param
})
}
// 驳回
export const rejectBorrow = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmBorrow/reject',
method: 'post',
data: param
})
}
// 查询申请及明细/日志
export const getBorrowById = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmBorrow/getById',
method: 'post',
data: param
})
}
import axios from '@/libs/api.request'
// 列表查询(支持分页与筛选)
export const getLeaveList = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmLeave/selectList',
method: 'post',
data: param
})
}
// 获取待审核列表
export const getPendingList = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmLeave/selectPendingList',
method: 'post',
data: param
})
}
// 保存(新增/修改)请假申请
export const saveLeaveApplication = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmLeave/save',
method: 'post',
data: param
})
}
// 提交请假申请进入审批
export const submitLeaveApplication = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmLeave/submit',
method: 'post',
data: param
})
}
// 撤回请假申请
export const revokeLeaveApplication = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmLeave/revoke',
method: 'post',
data: param
})
}
// 审批通过
export const approveLeave = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmLeave/approve',
method: 'post',
data: param
})
}
// 驳回
export const rejectLeave = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmLeave/reject',
method: 'post',
data: param
})
}
// 获取某申请的详情(含审批记录)
export const getLeaveById = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmLeave/getById',
method: 'post',
data: param
})
}
// 审批历史(用于历史查询)
export const getApprovalHistory = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmLeave/selectApprovalHistory',
method: 'post',
data: param
})
}
// 请假统计
export const getLeaveStats = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmLeave/selectStats',
method: 'post',
data: param
})
}
import axios from '@/libs/api.request'
// 使用统计
export const getUsageStats = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmStats/selectUsageStats',
method: 'post',
data: param
})
}
export const getUsageDetails = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmStats/selectUsageDetails',
method: 'post',
data: param
})
}
// 工作量统计
export const getWorkloadStats = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmStats/selectWorkloadStats',
method: 'post',
data: param
})
}
export const getWorkloadDetails = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmStats/selectWorkloadDetails',
method: 'post',
data: param
})
}
import axios from '@/libs/api.request'
// 获取日常人员列表
export const getDmUserList = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmUser/selectList',
method: 'post',
data: param
})
}
// 根据机构编码同步本级及下属机构用户(存在则更新、不存在则新增;null 不覆盖)
export const syncDmUsersByOffice = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmUser/syncByOffice',
method: 'post',
data: param
})
}
// 保存单个日常人员(前端编辑后保存)
export const saveDmUser = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmUser/save',
method: 'post',
data: param
})
}
import axios from '@/libs/api.request'
// ===== 人员分类管理 =====
export const getUserCategoryList = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmUserCategory/selectList',
method: 'post',
data: param
})
}
export const saveUserCategory = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmUserCategory/save',
method: 'post',
data: param
})
}
export const deleteUserCategory = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmUserCategory/delete',
method: 'post',
data: param
})
}
// ===== 人员分类权限管理 =====
export const getUserCategoryPermissionList = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmUserCategoryPermission/selectList',
method: 'post',
data: param
})
}
export const saveUserCategoryPermission = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmUserCategoryPermission/save',
method: 'post',
data: param
})
}
// ===== 请假类型管理 =====
export const getLeaveTypeList = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmLeaveType/selectList',
method: 'post',
data: param
})
}
export const saveLeaveType = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmLeaveType/save',
method: 'post',
data: param
})
}
export const deleteLeaveType = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmLeaveType/delete',
method: 'post',
data: param
})
}
// ===== 办公用品分类管理 =====
export const getMaterialCategoryList = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmMaterialCategory/selectList',
method: 'post',
data: param
})
}
export const saveMaterialCategory = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmMaterialCategory/save',
method: 'post',
data: param
})
}
export const deleteMaterialCategory = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmMaterialCategory/delete',
method: 'post',
data: param
})
}
// ===== 办公用品管理 =====
export const getMaterialList = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmMaterial/selectList',
method: 'post',
data: param
})
}
export const saveMaterial = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmMaterial/save',
method: 'post',
data: param
})
}
export const deleteMaterial = (param) => {
return axios.request({
url: '/api/ac/jilinsscgsdp/keyDmMaterial/delete',
method: 'post',
data: param
})
}
<template>
<div class="key-dm-stats-wrapper">
<Tabs v-model="activeTab" @on-click="handleTabChange">
<TabPane label="办公用品使用统计" name="usage">
<div class="search-div">
<Row type="flex" :gutter="16" align="middle">
<Col :span="8">
<span>时间段:</span>
<DatePicker v-model="usageRange" type="daterange" style="width:70%" />
</Col>
<Col :span="8">
<span>物料:</span>
<Input v-model="usageMaterial" placeholder="物料名称或编码" style="width:70%" />
</Col>
<Col :span="8" class="text-right">
<Button type="primary" class="mr10" @click="loadUsage">统计</Button>
<Button @click="resetUsage">重置</Button>
</Col>
</Row>
</div>
<Table :data="tables.usage" :loading="loading.usage" border>
<TableColumn type="index" title="序号" width="60" align="center" />
<TableColumn prop="department_name" title="部门" align="center" />
<TableColumn prop="material_name" title="物料" align="center" />
<TableColumn prop="total_quantity" title="领用数量" align="center" />
<TableColumn title="操作" width="100" align="center">
<template slot-scope="{ row }">
<Button size="small" @click="openUsageDetail(row)">详细</Button>
</template>
</TableColumn>
</Table>
</TabPane>
<TabPane label="工作量统计" name="workload">
<div class="search-div">
<Row type="flex" :gutter="16" align="middle">
<Col :span="10">
<span>时间段:</span>
<DatePicker v-model="workRange" type="daterange" style="width:70%" />
</Col>
<Col :span="6" class="text-right">
<Button type="primary" class="mr10" @click="loadWorkload">统计</Button>
<Button @click="resetWorkload">重置</Button>
</Col>
</Row>
</div>
<Table :data="tables.workload" :loading="loading.workload" border>
<TableColumn type="index" title="序号" width="60" align="center" />
<TableColumn prop="user_name" title="人员" align="center" />
<TableColumn prop="leave_applications" title="请假申请次数" align="center" />
<TableColumn prop="leave_approvals" title="请假审批次数" align="center" />
<TableColumn prop="borrow_applications" title="用品申请次数" align="center" />
<TableColumn prop="inbound_count" title="入库次数" align="center" />
<TableColumn prop="leave_duration" title="请假时长(天)" align="center" />
<TableColumn title="操作" width="160" align="center">
<template slot-scope="{ row }">
<Button size="small" @click="openWorkloadDetail(row,'leave')">请假明细</Button>
<Button size="small" class="ml5" @click="openWorkloadDetail(row,'inventory')">用品明细</Button>
</template>
</TableColumn>
</Table>
</TabPane>
</Tabs>
<!-- 使用明细弹窗 -->
<Modal v-model="detailModal.visible" title="明细" width="800">
<Table :data="detailModal.rows" size="small" border>
<TableColumn v-for="col in detailModal.columns" :key="col.key" :prop="col.key" :title="col.title" />
</Table>
<div slot="footer"><Button type="primary" @click="detailModal.visible=false">关闭</Button></div>
</Modal>
</div>
</template>
<script>
import { getUsageStats, getUsageDetails, getWorkloadStats, getWorkloadDetails } from '@/api/key-dm-stats'
export default {
name: 'key-dm-stats-index',
data () {
return {
activeTab: 'usage',
usageRange: [],
usageMaterial: '',
workRange: [],
tables: { usage: [], workload: [] },
loading: { usage: false, workload: false },
detailModal: { visible: false, rows: [], columns: [] }
}
},
methods: {
handleTabChange (name) {
this.activeTab = name
},
loadUsage () {
this.loading.usage = true
const params = { start: this.usageRange[0], end: this.usageRange[1], material: this.usageMaterial }
getUsageStats({ params }).then(ret => {
if (ret.data && ret.data.errcode === 0) this.tables.usage = ret.data.data || []
else this.$Notice.error({ title: '查询失败', desc: ret.data && ret.data.errmsg })
}).finally(() => { this.loading.usage = false })
},
resetUsage () { this.usageRange = []; this.usageMaterial = ''; this.tables.usage = [] },
openUsageDetail (row) {
this.detailModal.columns = [{ key: 'user_name', title: '人员' }, { key: 'quantity', title: '数量' }, { key: 'material_name', title: '物料' }, { key: 'department_name', title: '部门' }]
this.detailModal.visible = true
getUsageDetails({ params: { start: this.usageRange[0], end: this.usageRange[1], material: this.usageMaterial, department: row.department_id } }).then(ret => {
if (ret.data && ret.data.errcode === 0) this.detailModal.rows = ret.data.data || []
else this.$Notice.error({ title: '查询失败', desc: ret.data && ret.data.errmsg })
})
},
loadWorkload () {
this.loading.workload = true
const params = { start: this.workRange[0], end: this.workRange[1] }
getWorkloadStats({ params }).then(ret => {
if (ret.data && ret.data.errcode === 0) this.tables.workload = ret.data.data || []
else this.$Notice.error({ title: '查询失败', desc: ret.data && ret.data.errmsg })
}).finally(() => { this.loading.workload = false })
},
resetWorkload () { this.workRange = []; this.tables.workload = [] },
openWorkloadDetail (row, type) {
if (type === 'leave') {
this.detailModal.columns = [{ key: 'user_name', title: '人员' }, { key: 'start_time', title: '开始' }, { key: 'end_time', title: '结束' }, { key: 'duration', title: '时长' }]
getWorkloadDetails({ params: { user_id: row.user_id, start: this.workRange[0], end: this.workRange[1], type: 'leave' } }).then(ret => {
if (ret.data && ret.data.errcode === 0) { this.detailModal.rows = ret.data.data || []; this.detailModal.visible = true } else this.$Notice.error({ title: '查询失败', desc: ret.data && ret.data.errmsg })
})
} else {
this.detailModal.columns = [{ key: 'application_no', title: '申请单号' }, { key: 'material_name', title: '物料' }, { key: 'apply_quantity', title: '数量' }]
getWorkloadDetails({ params: { user_id: row.user_id, start: this.workRange[0], end: this.workRange[1], type: 'inventory' } }).then(ret => {
if (ret.data && ret.data.errcode === 0) { this.detailModal.rows = ret.data.data || []; this.detailModal.visible = true } else this.$Notice.error({ title: '查询失败', desc: ret.data && ret.data.errmsg })
})
}
}
}
}
</script>
<style scoped>
.key-dm-stats-wrapper { padding: 10px; }
.search-div { border: 1px solid #dce1e7; padding: 12px; margin-bottom: 12px; background-color: #f8fbff; }
.mr10 { margin-right: 10px; }
.text-right { text-align: right; }
.page_style { margin-top: 12px; text-align: right; }
.mt8 { margin-top: 8px; }
</style>
<template>
<div class="key-dm-user-wrapper">
<Card>
<div class="search-div">
<Row type="flex" :gutter="16" align="middle">
<Col :span="8">
<span>机构编码:</span>
<Input v-model="officeCode" placeholder="请输入机构编码或留空为当前机构" style="width: 60%" />
<Button type="primary" class="mr10" @click="handleSync">同步</Button>
<Button @click="fetchList">刷新</Button>
</Col>
<Col :span="8" class="text-right">
<span>姓名:</span>
<Input v-model="filters.name" placeholder="请输入姓名" style="width: 40%" />
<Button type="primary" class="mr10" @click="handleSearch">搜索</Button>
<Button @click="handleReset">重置</Button>
</Col>
</Row>
</div>
<Table :data="rows" :loading="loading" border>
<template slot="index" slot-scope="{ index }">
<span>{{ index + 1 }}</span>
</template>
<TableColumn type="index" title="序号" width="60" align="center" />
<TableColumn prop="name" title="姓名" align="center" />
<TableColumn prop="gh" title="工号" align="center" />
<TableColumn prop="office_name" title="归属部门" align="center" />
<TableColumn prop="email" title="邮箱" align="center" />
<TableColumn prop="phone" title="电话" align="center" />
<TableColumn prop="mobile" title="手机" align="center" />
<TableColumn prop="is_leave" title="离职" width="80" align="center" :render="renderIsLeave" />
<TableColumn prop="is_ext" title="同步来源" width="120" align="center" :render="renderIsExt" />
<TableColumn title="操作" width="200" align="center">
<template slot-scope="{ row }">
<Button size="small" type="primary" @click="openEdit(row)">修改</Button>
</template>
</TableColumn>
</Table>
<Page class="page_style" :total="pager.totalRecord" :current="pager.pageNo" :page-size="pager.pageSize"
show-total show-sizer @on-change="pageChange" @on-page-size-change="sizeChange" />
</Card>
<Modal v-model="editModal.visible" title="编辑日常人员" width="700" :mask-closable="false">
<Form :model="editModal.form" :label-width="120" ref="editForm">
<FormItem label="姓名">
<Input v-model="editModal.form.name" disabled />
</FormItem>
<FormItem label="工号">
<Input v-model="editModal.form.gh" disabled />
</FormItem>
<FormItem label="邮箱">
<Input v-model="editModal.form.email" />
</FormItem>
<FormItem label="电话">
<Input v-model="editModal.form.phone" />
</FormItem>
<FormItem label="手机">
<Input v-model="editModal.form.mobile" />
</FormItem>
<FormItem label="出生日期">
<DatePicker v-model="editModal.form.birthday" type="date" placeholder="请选择日期" />
</FormItem>
<FormItem label="参加工作时间">
<DatePicker v-model="editModal.form.in_work_time" type="date" placeholder="请选择日期" />
</FormItem>
<FormItem label="归属部门">
<Input v-model="editModal.form.office_id" placeholder="请输入机构ID(可通过列表选择扩展)" />
</FormItem>
<FormItem label="直属领导ID">
<Input v-model="editModal.form.leader" placeholder="只能选择本级或父机构人员ID" />
</FormItem>
<FormItem label="是否离职">
<Select v-model="editModal.form.is_leave" style="width: 160px">
<Option :value="0">未离职</Option>
<Option :value="1">离职</Option>
</Select>
</FormItem>
</Form>
<div slot="footer">
<Button @click="editModal.visible = false">取消</Button>
<Button type="primary" :loading="editModal.saving" @click="saveEdit">保存</Button>
</div>
</Modal>
</div>
</template>
<script>
import { getDmUserList, syncDmUsersByOffice, saveDmUser } from '@/api/key-dm-user'
export default {
name: 'key-dm-user-index',
data () {
return {
officeCode: '',
filters: { name: '' },
rows: [],
loading: false,
pager: { pageNo: 1, pageSize: 10, totalRecord: 0 },
editModal: {
visible: false,
saving: false,
form: {}
}
}
},
created () {
this.fetchList()
},
methods: {
renderIsLeave (h, { row }) {
return row.is_leave === 1 ? '是' : '否'
},
renderIsExt (h, { row }) {
return row.is_ext === 1 ? '系统同步' : '手工录入'
},
fetchList () {
this.loading = true
const payload = { pageNo: this.pager.pageNo, pageSize: this.pager.pageSize, params: Object.assign({}, this.filters) }
getDmUserList(payload).then(ret => {
if (ret.data && ret.data.errcode === 0) {
const data = ret.data.data || {}
this.rows = data.results || []
this.pager.totalRecord = data.totalRecord || 0
} else {
this.$Notice.error({ title: '查询失败', desc: ret.data && ret.data.errmsg })
}
}).finally(() => { this.loading = false })
},
handleSearch () {
this.pager.pageNo = 1
this.fetchList()
},
handleReset () {
this.filters = { name: '' }
this.pager.pageNo = 1
this.fetchList()
},
pageChange (pageNo) {
this.pager.pageNo = pageNo
this.fetchList()
},
sizeChange (size) {
this.pager.pageSize = size
this.pager.pageNo = 1
this.fetchList()
},
handleSync () {
const params = { office_code: this.officeCode }
this.$Modal.confirm({
title: '确认同步',
content: '将同步本机构及下属机构的用户,已存在的记录会被更新(不覆盖 null 值),是否继续?',
onOk: () => {
this.loading = true
syncDmUsersByOffice(params).then(ret => {
if (ret.data && ret.data.errcode === 0) {
this.$Message.success('同步完成')
this.fetchList()
} else {
this.$Notice.error({ title: '同步失败', desc: ret.data && ret.data.errmsg })
}
}).finally(() => { this.loading = false })
}
})
},
openEdit (row) {
this.editModal.form = Object.assign({}, row)
this.editModal.visible = true
},
saveEdit () {
this.$refs.editForm.validate(valid => {
// no strict validation here, just save
this.editModal.saving = true
saveDmUser(this.editModal.form).then(ret => {
if (ret.data && ret.data.errcode === 0) {
this.$Message.success('保存成功')
this.editModal.visible = false
this.fetchList()
} else {
this.$Notice.error({ title: '保存失败', desc: ret.data && ret.data.errmsg })
}
}).finally(() => { this.editModal.saving = false })
})
}
}
}
</script>
<style scoped>
.key-dm-user-wrapper { padding: 10px; }
.search-div { border: 1px solid #dce1e7; padding: 12px; margin-bottom: 12px; background-color: #f8fbff; }
.mr10 { margin-right: 10px; }
.page_style { margin-top: 12px; text-align: right; }
</style>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论