Merge branch 'main' of http://114.55.169.15:3000/qiushanhe/ss-oa-manage-web into dev-cl
# Conflicts: # .env.base
This commit is contained in:
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"i18n-ally.localesPaths": [
|
||||
"src/locales"
|
||||
]
|
||||
}
|
||||
@@ -20,10 +20,10 @@ export const updateOkrNode = (data) => {
|
||||
}
|
||||
|
||||
// 查询详情
|
||||
export const getOkrNodeDetail = (nodeId) => {
|
||||
export const getOkrNodeDetail = (params) => {
|
||||
return request.get({
|
||||
url: '/admin-api/okr/node/get',
|
||||
params: { nodeId }
|
||||
params
|
||||
// headers: { 'instance-id': 1016 }
|
||||
})
|
||||
}
|
||||
@@ -108,3 +108,38 @@ export const getOkrRelationTreeChildren = (params) => {
|
||||
// headers: { 'instance-id': 1016 }
|
||||
})
|
||||
}
|
||||
|
||||
// 获取我的组员
|
||||
export const getMyMemberList = (params) => {
|
||||
return request.get({
|
||||
url: '/admin-api/okr/node/my-members',
|
||||
params
|
||||
// headers: { 'instance-id': 1016 }
|
||||
})
|
||||
}
|
||||
|
||||
// 获取我的组员节点树
|
||||
export const getMySonNodeTree = (params) => {
|
||||
return request.get({
|
||||
url: '/admin-api/okr/node/member/node/list',
|
||||
params
|
||||
// headers: { 'instance-id': 1016 }
|
||||
})
|
||||
}
|
||||
|
||||
// 获取我的组员OKR列表
|
||||
export const getMySonOkrPage = (params) => {
|
||||
return request.get({
|
||||
url: '/admin-api/okr/node/member/objective/list',
|
||||
params
|
||||
// headers: { 'instance-id': 1016 }
|
||||
})
|
||||
}
|
||||
|
||||
// 获取渠道
|
||||
export const getChannelOptions = () => {
|
||||
return request.get({
|
||||
url: '/admin-api/okr/node/source'
|
||||
// headers: { 'instance-id': 1016 }
|
||||
})
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ export interface DeptVO {
|
||||
}
|
||||
|
||||
// 查询部门(精简)列表
|
||||
export const getSimpleDeptList = async (): Promise<DeptVO[]> => {
|
||||
return await request.get({ url: '/admin-api/system/dept/list-all-simple' })
|
||||
export const getSimpleDeptList = async (params: any): Promise<any[]> => {
|
||||
return await request.get({ url: '/admin-api/system/dept/list-all-simple', params })
|
||||
}
|
||||
|
||||
// 查询部门列表
|
||||
|
||||
@@ -106,41 +106,29 @@ const remainingRouter: AppRouteRecordRaw[] = [
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/Basic',
|
||||
component: Layout,
|
||||
name: 'Basic',
|
||||
meta: {
|
||||
title: '菜单管理'
|
||||
},
|
||||
redirect: '/Basic/menu',
|
||||
children: [
|
||||
{
|
||||
path: 'menu',
|
||||
component: () => import('@/views/Basic/Menu/index.vue'),
|
||||
name: 'Menu',
|
||||
meta: {
|
||||
canTo: true,
|
||||
// hidden: true,
|
||||
noTagsView: false,
|
||||
icon: 'ep:user',
|
||||
title: '菜单管理'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'okr',
|
||||
component: () => import('@/views/OKR/Management/index.vue'),
|
||||
name: 'OkrManagement',
|
||||
meta: {
|
||||
canTo: true,
|
||||
// hidden: true,
|
||||
noTagsView: false,
|
||||
icon: 'ep:user',
|
||||
title: 'Okr管理'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
// {
|
||||
// path: '/Basic',
|
||||
// component: Layout,
|
||||
// name: 'Basic',
|
||||
// meta: {
|
||||
// title: '菜单管理'
|
||||
// },
|
||||
// redirect: '/Basic/menu',
|
||||
// children: [
|
||||
// {
|
||||
// path: 'menu',
|
||||
// component: () => import('@/views/Basic/Menu/index.vue'),
|
||||
// name: 'Menu',
|
||||
// meta: {
|
||||
// canTo: true,
|
||||
// // hidden: true,
|
||||
// noTagsView: false,
|
||||
// icon: 'ep:user',
|
||||
// title: '菜单管理'
|
||||
// }
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
{
|
||||
path: '/login',
|
||||
component: () => import('@/views/Login/Login.vue'),
|
||||
|
||||
@@ -30,7 +30,12 @@
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12" :offset="0">
|
||||
<el-form-item label="负责人" prop="leaderUserId">
|
||||
<el-select v-model="formData.leaderUserId" clearable placeholder="请输入负责人">
|
||||
<el-select
|
||||
v-model="formData.leaderUserId"
|
||||
clearable
|
||||
filterable
|
||||
placeholder="请输入负责人"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in employeeOptions"
|
||||
:key="item.id"
|
||||
@@ -56,6 +61,24 @@
|
||||
<el-input-number v-model="formData.sort" :min="0" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" :offset="0">
|
||||
<el-form-item label="业务系统" prop="instanceId">
|
||||
<el-select
|
||||
v-model="formData.instanceId"
|
||||
placeholder="选择主业务系统"
|
||||
clearable
|
||||
filterable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in instanceIdOptions"
|
||||
:key="item.instanceId"
|
||||
:label="item.instanceName"
|
||||
:disabled="item.status == 1"
|
||||
:value="item.instanceId"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24" :offset="0">
|
||||
@@ -76,6 +99,7 @@ import { defaultProps, handleTree } from '@/utils/tree'
|
||||
import * as DeptApi from '@/api/system/dept'
|
||||
import { getEmployeeSimpleList } from '@/api/pers/employee'
|
||||
import { CommonStatusEnum } from '@/utils/constants'
|
||||
import { getSimpleAppList } from '@/api/system/app'
|
||||
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
@@ -84,15 +108,7 @@ const dialogVisible = ref(false) // 弹窗的是否展示
|
||||
const dialogTitle = ref('') // 弹窗的标题
|
||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||
const formData = ref({
|
||||
id: undefined,
|
||||
parentId: undefined,
|
||||
name: undefined,
|
||||
sort: 1,
|
||||
leaderUserId: undefined,
|
||||
status: CommonStatusEnum.ENABLE,
|
||||
remark: undefined
|
||||
})
|
||||
const formData = ref<any>({})
|
||||
const formRules = reactive<any>({
|
||||
parentId: [{ required: true, message: '上级部门不能为空', trigger: 'blur' }],
|
||||
name: [{ required: true, message: '部门名称不能为空', trigger: 'blur' }],
|
||||
@@ -106,6 +122,7 @@ const formRules = reactive<any>({
|
||||
const formRef = ref() // 表单 Ref
|
||||
const deptTree = ref() // 树形结构
|
||||
const employeeOptions = ref<any>([]) // 用户列表
|
||||
const instanceIdOptions = ref<any>([]) // 实例ids
|
||||
|
||||
/** 打开弹窗 */
|
||||
const open = async (type: string, id?: number) => {
|
||||
@@ -118,6 +135,7 @@ const open = async (type: string, id?: number) => {
|
||||
formLoading.value = true
|
||||
try {
|
||||
formData.value = await DeptApi.getDept(id)
|
||||
formData.value.remark = formData.value.remark || ''
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
@@ -126,6 +144,10 @@ const open = async (type: string, id?: number) => {
|
||||
getEmployeeSimpleList().then((data) => {
|
||||
employeeOptions.value = data
|
||||
})
|
||||
//实例
|
||||
getSimpleAppList().then((data) => {
|
||||
instanceIdOptions.value = data
|
||||
})
|
||||
// 获得部门树
|
||||
await getTree()
|
||||
}
|
||||
@@ -166,7 +188,8 @@ const resetForm = () => {
|
||||
sort: 1,
|
||||
leaderUserId: undefined,
|
||||
status: CommonStatusEnum.ENABLE,
|
||||
remark: undefined
|
||||
remark: undefined,
|
||||
instanceId: undefined
|
||||
}
|
||||
formRef.value?.resetFields()
|
||||
}
|
||||
@@ -174,7 +197,7 @@ const resetForm = () => {
|
||||
/** 获得部门树 */
|
||||
const getTree = async () => {
|
||||
deptTree.value = []
|
||||
const data = await DeptApi.getSimpleDeptList()
|
||||
const data = await DeptApi.getSimpleDeptList({ allFlag: false })
|
||||
let dept: Tree = { id: 0, name: '顶级部门', children: [] }
|
||||
dept.children = handleTree(data)
|
||||
deptTree.value.push(dept)
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<el-table v-loading="loading" :data="list" row-key="id" default-expand-all border>
|
||||
<el-table-column prop="name" label="部门名称" />
|
||||
<el-table-column prop="leaderUserName" label="负责人" width="120" />
|
||||
<el-table-column prop="" label="业务系统" width="200" />
|
||||
<el-table-column prop="instanceName" label="业务系统" width="200" />
|
||||
<el-table-column prop="sort" label="排序" width="80" />
|
||||
<el-table-column prop="status" label="状态" width="100">
|
||||
<template #default="scope">
|
||||
@@ -68,6 +68,7 @@ const { t } = useI18n() // 国际化
|
||||
const loading = ref(true) // 列表的加载中
|
||||
const list = ref() // 列表的数据
|
||||
const queryParams = reactive({
|
||||
allFlag: true,
|
||||
name: undefined
|
||||
})
|
||||
const queryFormRef = ref() // 搜索的表单
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<el-input v-model="formData.nickname" placeholder="请输入用户姓名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<!-- <el-col :span="12">
|
||||
<el-form-item label="用户性别">
|
||||
<el-radio-group v-model="formData.sex">
|
||||
<el-radio :value="1"> 男 </el-radio>
|
||||
@@ -34,7 +34,7 @@
|
||||
placeholder="请选择归属部门"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-col> -->
|
||||
<el-col :span="12">
|
||||
<el-form-item label="角色" prop="role">
|
||||
<el-select
|
||||
@@ -84,7 +84,7 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<!-- <el-row :gutter="20">
|
||||
<el-col :span="12" :offset="0">
|
||||
<el-form-item label="入职日期" prop="hireDate">
|
||||
<el-date-picker
|
||||
@@ -96,7 +96,7 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-row> -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="备注">
|
||||
@@ -113,7 +113,8 @@
|
||||
</template>
|
||||
<script lang="ts" name="SystemUserForm" setup>
|
||||
import { CommonStatusEnum } from '@/utils/constants'
|
||||
import { defaultProps, handleTree } from '@/utils/tree'
|
||||
// import { defaultProps, handleTree } from '@/utils/tree'
|
||||
import { handleTree } from '@/utils/tree'
|
||||
import { formatDate } from '@/utils/formatTime'
|
||||
|
||||
import * as RoleApi from '@/api/system/role'
|
||||
@@ -174,7 +175,7 @@ const open = async (type: string, id?: number) => {
|
||||
}
|
||||
}
|
||||
// 加载部门树
|
||||
deptList.value = handleTree(await DeptApi.getSimpleDeptList())
|
||||
deptList.value = handleTree(await DeptApi.getSimpleDeptList({ allFlag: false }))
|
||||
// 加载岗位列表
|
||||
roleOptions.value = await RoleApi.getSimpleRoleList()
|
||||
}
|
||||
|
||||
@@ -1,105 +1,100 @@
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<!-- 左侧部门树 -->
|
||||
<el-col :span="4" :xs="24">
|
||||
<!-- <el-row :gutter="20"> -->
|
||||
<!-- 左侧部门树 -->
|
||||
<!-- <el-col :span="4" :xs="24">
|
||||
<DeptTree @node-click="handleDeptNodeClick" />
|
||||
</el-col>
|
||||
<el-col :span="20" :xs="24">
|
||||
<!-- 搜索 -->
|
||||
<el-form :model="queryParams" ref="queryFormRef" inline label-width="68px">
|
||||
<el-form-item label="姓名" prop="nickname">
|
||||
<el-input
|
||||
v-model="queryParams.nickname"
|
||||
placeholder="请输入姓名"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="手机号码" prop="mobile">
|
||||
<el-input
|
||||
v-model="queryParams.mobile"
|
||||
placeholder="请输入手机号码"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="handleQuery" v-hasPermi="['basic:employee:search']">搜索</el-button>
|
||||
<el-button @click="resetQuery" v-hasPermi="['basic:employee:reset']">重置</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
@click="openForm('create')"
|
||||
v-hasPermi="['basic:employee:add']"
|
||||
>
|
||||
新增
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-table v-loading="loading" :data="list">
|
||||
<el-table-column label="用户编号" key="id" prop="id" />
|
||||
<el-table-column label="登录账号" prop="username" />
|
||||
<el-table-column label="用户姓名" prop="nickname" />
|
||||
<el-table-column label="部门" key="deptName" prop="deptName" />
|
||||
<el-table-column label="手机号码" prop="mobile" width="120" />
|
||||
<el-table-column label="状态" key="status">
|
||||
<template #default="scope">
|
||||
<el-switch
|
||||
v-model="scope.row.status"
|
||||
:active-value="0"
|
||||
:inactive-value="1"
|
||||
active-text="在职"
|
||||
inactive-text="离职"
|
||||
v-hasPermi="['basic:employee:update']"
|
||||
@change="handleStatusChange(scope.row)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="创建时间"
|
||||
prop="createTime"
|
||||
width="180"
|
||||
:formatter="dateFormatter"
|
||||
/>
|
||||
<el-table-column label="操作" width="260">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
@click="openForm('update', scope.row.id)"
|
||||
v-hasPermi="['basic:employee:update']"
|
||||
>
|
||||
修改
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
@click="handleDelete(scope.row.id)"
|
||||
v-hasPermi="['basic:employee:delete']"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
@click="handleResetPwd(scope.row)"
|
||||
v-hasPermi="['basic:employee:password']"
|
||||
>
|
||||
重置密码
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<Pagination
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNo"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
<el-col :span="20" :xs="24"> -->
|
||||
<!-- 搜索 -->
|
||||
<el-form :model="queryParams" ref="queryFormRef" inline label-width="0">
|
||||
<el-form-item prop="nickname">
|
||||
<el-input
|
||||
v-model="queryParams.nickname"
|
||||
placeholder="请输入姓名"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
<el-form-item prop="mobile">
|
||||
<el-input
|
||||
v-model="queryParams.mobile"
|
||||
placeholder="请输入手机号码"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
class="!w-240px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="handleQuery" v-hasPermi="['basic:employee:search']">搜索</el-button>
|
||||
<el-button @click="resetQuery" v-hasPermi="['basic:employee:reset']">重置</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
@click="openForm('create')"
|
||||
v-hasPermi="['basic:employee:add']"
|
||||
>
|
||||
新增
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-table v-loading="loading" :data="list">
|
||||
<el-table-column label="用户编号" key="id" prop="id" />
|
||||
<el-table-column label="登录账号" prop="username" />
|
||||
<el-table-column label="用户姓名" prop="nickname" />
|
||||
<!-- <el-table-column label="部门" key="deptName" prop="deptName" /> -->
|
||||
<el-table-column label="手机号码" prop="mobile" width="120" />
|
||||
<el-table-column label="状态" key="status">
|
||||
<template #default="scope">
|
||||
<el-switch
|
||||
v-model="scope.row.status"
|
||||
:active-value="0"
|
||||
:inactive-value="1"
|
||||
active-text="在职"
|
||||
inactive-text="离职"
|
||||
v-hasPermi="['basic:employee:update']"
|
||||
@change="handleStatusChange(scope.row)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" prop="createTime" width="180" :formatter="dateFormatter" />
|
||||
<el-table-column label="操作" width="260">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
@click="openForm('update', scope.row.id)"
|
||||
v-hasPermi="['basic:employee:update']"
|
||||
>
|
||||
修改
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
@click="handleDelete(scope.row.id)"
|
||||
v-hasPermi="['basic:employee:delete']"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
@click="handleResetPwd(scope.row)"
|
||||
v-hasPermi="['basic:employee:password']"
|
||||
>
|
||||
重置密码
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<Pagination
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNo"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
<!-- </el-col> -->
|
||||
<!-- </el-row> -->
|
||||
|
||||
<!-- 添加或修改用户对话框 -->
|
||||
<UserForm ref="formRef" @success="getList" />
|
||||
@@ -109,7 +104,7 @@ import { CommonStatusEnum } from '@/utils/constants'
|
||||
import { dateFormatter } from '@/utils/formatTime'
|
||||
import * as UserApi from '@/api/system/user'
|
||||
import UserForm from './UserForm.vue'
|
||||
import DeptTree from './DeptTree.vue'
|
||||
// import DeptTree from './DeptTree.vue'
|
||||
const message = useMessage() // 消息弹窗
|
||||
const { t } = useI18n() // 国际化
|
||||
|
||||
@@ -150,11 +145,11 @@ const resetQuery = () => {
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
/** 处理部门被点击 */
|
||||
const handleDeptNodeClick = async (row) => {
|
||||
queryParams.deptId = row.id
|
||||
await getList()
|
||||
}
|
||||
// /** 处理部门被点击 */
|
||||
// const handleDeptNodeClick = async (row) => {
|
||||
// queryParams.deptId = row.id
|
||||
// await getList()
|
||||
// }
|
||||
|
||||
/** 添加/修改操作 */
|
||||
const formRef = ref()
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<el-date-picker
|
||||
v-model="form.effectiveDate"
|
||||
type="date"
|
||||
:disabled="form.id"
|
||||
:disabled="!!form.id"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="选择日期时间"
|
||||
|
||||
@@ -72,12 +72,16 @@ const isCurrentLeafNode = ref(false)
|
||||
|
||||
function handleSearchPeroid() {
|
||||
getAllNodeTree().then((resp) => {
|
||||
peroidList.value = listToTree(resp.tree, {
|
||||
id: 'nodeId',
|
||||
pid: 'parentId',
|
||||
children: 'children'
|
||||
})
|
||||
nodeChange(resp.nodeId)
|
||||
if (resp.nodeId) {
|
||||
peroidList.value = listToTree(resp.tree, {
|
||||
id: 'nodeId',
|
||||
pid: 'parentId',
|
||||
children: 'children'
|
||||
})
|
||||
nodeChange(resp.nodeId)
|
||||
} else {
|
||||
message.warning('请先创建节点数据')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -87,6 +91,7 @@ function nodeChange(nodeId) {
|
||||
const currentNode = findNode(peroidList.value, (node) => {
|
||||
return node.nodeId == nodeId
|
||||
})
|
||||
searchForm.value.creatorId = currentNode.creatorId
|
||||
if (!currentNode.children || currentNode.children.length == 0) {
|
||||
isCurrentLeafNode.value = true
|
||||
} else {
|
||||
@@ -108,9 +113,9 @@ function handleAddNode() {
|
||||
dialogOkrInfo.value.open('create', null)
|
||||
}
|
||||
|
||||
function handleEditOkr() {
|
||||
function handleEditOkr(nodeId = undefined) {
|
||||
dialogOkr.value.close()
|
||||
dialogOkrInfo.value.open('update', searchForm.value.nodeId)
|
||||
dialogOkrInfo.value.open('update', nodeId || searchForm.value.nodeId, 2)
|
||||
}
|
||||
|
||||
function handleUpdateProcess() {
|
||||
@@ -124,7 +129,8 @@ const dialogOkr = ref(null)
|
||||
function handleShowOkr(id) {
|
||||
dialogOkr.value.open({
|
||||
nodeId: id,
|
||||
canEdit: isCurrentLeafNode.value
|
||||
canEdit: isCurrentLeafNode.value,
|
||||
queryType: 2
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -18,11 +18,31 @@
|
||||
<span class="text-14px ml-0.25">ork落地</span>
|
||||
<div class="ml-20px text-14px">
|
||||
<span>【节点】</span>
|
||||
<span>{{ nodeInfo.allNodeName }}</span>
|
||||
<span
|
||||
v-for="(item, index) in nodeInfo.parentNodes"
|
||||
:key="item.nodeId"
|
||||
@click="handleChildItem(item)"
|
||||
>
|
||||
<span
|
||||
class="cursor-pointer"
|
||||
:style="{
|
||||
color: index < nodeInfo.parentNodes.length - 1 ? '#409eff' : '#333',
|
||||
borderBottom:
|
||||
index < nodeInfo.parentNodes.length - 1 ? '1px solid #409eff' : 'none'
|
||||
}"
|
||||
>
|
||||
{{ item.nodeName }}
|
||||
</span>
|
||||
<span v-if="index != nodeInfo.parentNodes.length - 1"> -> </span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<el-button v-if="nodeInfo.creatorId == currentUserId" link @click="emit('edit')">
|
||||
<el-button
|
||||
v-if="nodeInfo.creatorId == currentUserId"
|
||||
link
|
||||
@click="emit('edit', nodeInfo.nodeId)"
|
||||
>
|
||||
<el-tooltip content="编辑" placement="top" effect="dark">
|
||||
<Icon icon="ep:edit" :size="16" />
|
||||
</el-tooltip>
|
||||
@@ -319,9 +339,19 @@ import { useUserStore } from '@/store/modules/user'
|
||||
const message = useMessage()
|
||||
const userStore = useUserStore()
|
||||
const currentUserId = userStore.getUser.id
|
||||
const emit = defineEmits(['edit'])
|
||||
const emit = defineEmits(['edit', 'close'])
|
||||
|
||||
const show = ref(false)
|
||||
|
||||
watch(
|
||||
() => show.value,
|
||||
(newValue, oldValue) => {
|
||||
if (oldValue && !newValue) {
|
||||
emit('close', nodeInfo.value)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const canEdit = ref(false)
|
||||
|
||||
const toolbarConfig = {
|
||||
@@ -351,9 +381,11 @@ const nodeInfo = ref({})
|
||||
const nodeRecords = ref([])
|
||||
const commentTypeOptions = ref([])
|
||||
|
||||
const queryType = ref(1)
|
||||
function open(curNode) {
|
||||
canEdit.value = curNode.canEdit
|
||||
nodeInfo.value.nodeId = curNode.nodeId
|
||||
queryType.value = curNode.queryType
|
||||
// 获取数据详情
|
||||
searchInfo(curNode)
|
||||
show.value = true
|
||||
@@ -363,13 +395,12 @@ const employeeOptions = ref([])
|
||||
|
||||
function searchInfo(curNode) {
|
||||
try {
|
||||
getOkrNodeDetail(curNode.nodeId).then((resp) => {
|
||||
getOkrNodeDetail({ nodeId: curNode.nodeId, queryType: queryType.value }).then((resp) => {
|
||||
nodeInfo.value = {
|
||||
...resp,
|
||||
executor: resp.executor || []
|
||||
}
|
||||
canEdit.value =
|
||||
canEdit.value && currentUserId == nodeInfo.value.executor.includes(currentUserId)
|
||||
canEdit.value = canEdit.value && nodeInfo.value.executor.includes(currentUserId + '')
|
||||
if (resp.objectives) {
|
||||
okrList.value = resp.objectives.map((item) => ({
|
||||
...item,
|
||||
@@ -414,7 +445,7 @@ function handleMention(item) {
|
||||
function handleSaveProcess() {
|
||||
okrTableRef.value.updateProcess(nodeInfo.value.nodeId).then(() => {
|
||||
message.success('更新成功')
|
||||
searchInfo()
|
||||
searchInfo({ nodeId: nodeInfo.value.nodeId })
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -332,7 +332,8 @@ import {
|
||||
createOkrNode,
|
||||
updateOkrNode,
|
||||
getAllOkrPage,
|
||||
getDefaultOkrOptions
|
||||
getDefaultOkrOptions,
|
||||
getChannelOptions
|
||||
} from '@/api/okr/okr'
|
||||
import { listToTree } from '@/utils/tree'
|
||||
import { getEmployeeSimpleList } from '@/api/pers/employee'
|
||||
@@ -378,7 +379,7 @@ const defaultProps = {
|
||||
}
|
||||
const sourceOptions = ref([])
|
||||
const objectList = ref([])
|
||||
function open(type, val) {
|
||||
function open(type, val, queryType) {
|
||||
show.value = true
|
||||
title.value = type == 'update' ? '修改Okr' : '新增Okr'
|
||||
formType.value = type
|
||||
@@ -396,10 +397,20 @@ function open(type, val) {
|
||||
getDefaultOkrOptions().then((resp) => {
|
||||
krOptions.value = resp
|
||||
})
|
||||
getChannelOptions().then((resp) => {
|
||||
sourceOptions.value = listToTree(resp, {
|
||||
id: 'sourceId',
|
||||
pid: 'parentId',
|
||||
children: 'children'
|
||||
})
|
||||
})
|
||||
if (val) {
|
||||
formLoading.value = true
|
||||
try {
|
||||
getOkrNodeDetail(val).then((resp) => {
|
||||
getOkrNodeDetail({
|
||||
nodeId: val,
|
||||
queryType
|
||||
}).then((resp) => {
|
||||
form.value = resp
|
||||
if (resp.objectives) {
|
||||
objectList.value = resp.objectives.map((item) => ({
|
||||
@@ -468,7 +479,7 @@ function removeKR(oIdx, krIdx) {
|
||||
}
|
||||
|
||||
function addChildNode() {
|
||||
childNodeList.value.push({})
|
||||
childNodeList.value.push({ dataScope: 1 })
|
||||
}
|
||||
|
||||
function removeChildNode(idx) {
|
||||
@@ -509,9 +520,31 @@ async function handleSave() {
|
||||
if (!formRef.value) return
|
||||
const valid = await formRef.value.validate()
|
||||
if (!valid) return
|
||||
|
||||
if (form.value.executor.length > 1) {
|
||||
message
|
||||
.confirm('是否按照当前节点所选的多个执行人自动新增对应的员工节点?', {
|
||||
type: 'warning',
|
||||
showCancelButton: true,
|
||||
cancelButtonText: '取消',
|
||||
confirmButtonText: '确定'
|
||||
})
|
||||
.then(() => {
|
||||
saveOkrData(true)
|
||||
})
|
||||
.catch(() => {
|
||||
saveOkrData(false)
|
||||
})
|
||||
} else {
|
||||
saveOkrData(false)
|
||||
}
|
||||
}
|
||||
|
||||
async function saveOkrData(isAutoAddChild = false) {
|
||||
// 提交请求
|
||||
formLoading.value = true
|
||||
try {
|
||||
form.value.isAutoAddChild = isAutoAddChild
|
||||
form.value.objectives = objectList.value
|
||||
form.value.children = childNodeList.value
|
||||
if (formType.value === 'create') {
|
||||
|
||||
@@ -77,9 +77,9 @@ const dialogOkrInfo = ref(null)
|
||||
// dialogOkrInfo.value.open('create', null)
|
||||
// }
|
||||
|
||||
function handleEditOkr() {
|
||||
function handleEditOkr(nodeId = undefined) {
|
||||
dialogOkr.value.close()
|
||||
dialogOkrInfo.value.open('update', 1)
|
||||
dialogOkrInfo.value.open('update', nodeId || searchForm.value.nodeId, 1)
|
||||
}
|
||||
|
||||
function handleUpdateProcess() {
|
||||
@@ -93,7 +93,8 @@ const dialogOkr = ref(null)
|
||||
function handleShowOkr(id) {
|
||||
dialogOkr.value.open({
|
||||
nodeId: id,
|
||||
canEdit: true
|
||||
canEdit: true,
|
||||
queryType: 1
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
120
src/views/OKR/Management/Components/MySon.vue
Normal file
120
src/views/OKR/Management/Components/MySon.vue
Normal file
@@ -0,0 +1,120 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="flex items-center justify-between">
|
||||
<el-row>
|
||||
<el-tree-select
|
||||
v-model="searchForm.nodeId"
|
||||
:data="peroidList"
|
||||
:props="defaultProps"
|
||||
:render-after-expand="false"
|
||||
:default-expand-all="false"
|
||||
style="width: 400px"
|
||||
@change="nodeChange"
|
||||
/>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-button type="info" @click="handleShowOkr(searchForm.nodeId)"> 节点详情 </el-button>
|
||||
<el-button
|
||||
type="warning"
|
||||
v-if="currentUserId == searchForm.creatorId"
|
||||
@click="handleEditOkr(searchForm.nodeId)"
|
||||
>
|
||||
修改当前节点
|
||||
</el-button>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
<OkrTable ref="okrTableRef" canEdit />
|
||||
<DialogOkr ref="dialogOkr" @edit="handleEditOkr" />
|
||||
<DialogOkrInfo ref="dialogOkrInfo" @success="handleSearchPeroid" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="MySon">
|
||||
import OkrTable from './OkrTable.vue'
|
||||
import DialogOkr from './DialogOkr.vue'
|
||||
import DialogOkrInfo from './DialogOkrInfo.vue'
|
||||
import { listToTree, findNode } from '@/utils/tree'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
|
||||
import { getMySonNodeTree, getMySonOkrPage } from '@/api/okr/okr'
|
||||
|
||||
const props = defineProps({
|
||||
userId: {
|
||||
type: Number,
|
||||
default: undefined
|
||||
}
|
||||
})
|
||||
|
||||
const defaultProps = {
|
||||
value: 'nodeId',
|
||||
label: 'nodeName',
|
||||
children: 'children'
|
||||
}
|
||||
|
||||
const userStore = useUserStore()
|
||||
const currentUserId = userStore.getUser.id
|
||||
|
||||
const okrTableRef = ref(null)
|
||||
const searchForm = ref({
|
||||
nodeId: undefined
|
||||
})
|
||||
|
||||
const peroidList = ref([])
|
||||
|
||||
handleSearchPeroid()
|
||||
|
||||
function handleSearchPeroid() {
|
||||
getMySonNodeTree({ userId: props.userId }).then((resp) => {
|
||||
peroidList.value = listToTree(resp.tree, {
|
||||
id: 'nodeId',
|
||||
pid: 'parentId',
|
||||
children: 'children'
|
||||
})
|
||||
nodeChange(resp.nodeId)
|
||||
})
|
||||
}
|
||||
|
||||
function getOkrList() {
|
||||
getMySonOkrPage({
|
||||
...searchForm.value,
|
||||
userId: props.userId
|
||||
}).then((resp) => {
|
||||
nextTick(() => {
|
||||
okrTableRef.value.prepareData(resp)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function nodeChange(nodeId) {
|
||||
searchForm.value.nodeId = nodeId
|
||||
getOkrList()
|
||||
const currentNode = findNode(peroidList.value, (node) => {
|
||||
return node.nodeId == nodeId
|
||||
})
|
||||
searchForm.value.creatorId = currentNode.creatorId
|
||||
}
|
||||
|
||||
const dialogOkr = ref(null)
|
||||
function handleShowOkr(id) {
|
||||
dialogOkr.value.open({
|
||||
nodeId: id,
|
||||
canEdit: true,
|
||||
queryType: 2
|
||||
})
|
||||
}
|
||||
|
||||
const dialogOkrInfo = ref(null)
|
||||
function handleEditOkr(nodeId = undefined) {
|
||||
dialogOkr.value.close()
|
||||
dialogOkrInfo.value.open('update', nodeId || searchForm.value.nodeId, 2)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.el-overlay-dialog) {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
@@ -178,6 +178,7 @@ function openOkr() {
|
||||
clickNode.value &&
|
||||
dialogOkr.value.open({
|
||||
nodeId: clickNode.value.nodeId,
|
||||
queryType: 2,
|
||||
canEdit: !clickNode.value.children || clickNode.value.children.length == 0
|
||||
})
|
||||
}
|
||||
@@ -188,9 +189,9 @@ function handleAddNode() {
|
||||
dialogOkrInfo.value.open('create', null)
|
||||
}
|
||||
|
||||
function handleEditOkr() {
|
||||
function handleEditOkr(nodeId = undefined) {
|
||||
dialogOkr.value.close()
|
||||
dialogOkrInfo.value.open('update', 1)
|
||||
dialogOkrInfo.value.open('update', nodeId || searchForm.value.nodeId, 2)
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -275,10 +275,8 @@ function handleDelete(row) {
|
||||
}
|
||||
|
||||
function handleNotice(row) {
|
||||
console.log(row)
|
||||
|
||||
message.confirm('即将发送微信通知提醒执行人,是否继续?').then(() => {
|
||||
urgeWait({ workId: row.workId }).then(() => {
|
||||
urgeWait(row.workId).then(() => {
|
||||
message.success('发送成功')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<el-tab-pane label="目标关系树" name="3">
|
||||
<ObjectList v-if="tabIndex == 3" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane disabled>
|
||||
<el-tab-pane disabled v-if="employeeList.length > 0">
|
||||
<template #label>
|
||||
<div class="w-full">
|
||||
<el-divider
|
||||
@@ -31,9 +31,14 @@
|
||||
</div>
|
||||
</template>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="张三">张三</el-tab-pane>
|
||||
<el-tab-pane label="李四">李四</el-tab-pane>
|
||||
<el-tab-pane label="王二">王二</el-tab-pane>
|
||||
<el-tab-pane
|
||||
v-for="item in employeeList"
|
||||
:key="item.userId"
|
||||
:label="item.userName"
|
||||
:name="item.userId"
|
||||
>
|
||||
<MySon v-if="tabIndex == item.userId" :userId="item.userId" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
@@ -41,11 +46,21 @@
|
||||
<script setup name="OkrManagement">
|
||||
import AllTarget from './Components/AllTarget.vue'
|
||||
import MyDuty from './Components/MyDuty.vue'
|
||||
import MySon from './Components/MySon.vue'
|
||||
import ObjectList from './Components/ObjectList.vue'
|
||||
import WaitTarget from './Components/WaitTarget.vue'
|
||||
|
||||
import { getMyMemberList } from '@/api/okr/okr'
|
||||
|
||||
const tabIndex = ref('0')
|
||||
const height = ref(innerHeight - 115)
|
||||
|
||||
const employeeList = ref([])
|
||||
onMounted(() => {
|
||||
getMyMemberList().then((res) => {
|
||||
employeeList.value = res
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -25,7 +25,14 @@
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="组织部门" prop="dept">
|
||||
<el-input v-model="formData.dept" placeholder="请输入部门" />
|
||||
<el-tree-select
|
||||
v-model="formData.deptId"
|
||||
:data="deptList"
|
||||
:props="defaultProps"
|
||||
check-strictly
|
||||
node-key="id"
|
||||
placeholder="请选择部门"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
@@ -189,8 +196,10 @@
|
||||
<script name="DialogEmployee" setup>
|
||||
import { CommonStatusEnum } from '@/utils/constants'
|
||||
import { formatDate } from '@/utils/formatTime'
|
||||
import { defaultProps, handleTree } from '@/utils/tree'
|
||||
import { getPlanSimpleList } from '@/api/pers/attendancePlan'
|
||||
import { getSimpleAppList } from '@/api/system/app'
|
||||
import * as DeptApi from '@/api/system/dept'
|
||||
|
||||
import * as EmployeeApi from '@/api/pers/employee'
|
||||
|
||||
@@ -219,6 +228,8 @@ const attendanceSettingIdOptions = ref([])
|
||||
const instanceIdsOptions = ref([])
|
||||
const employeeOptions = ref([])
|
||||
|
||||
const deptList = ref([])
|
||||
|
||||
/** 打开弹窗 */
|
||||
const open = async (type, id) => {
|
||||
dialogVisible.value = true
|
||||
@@ -234,6 +245,7 @@ const open = async (type, id) => {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
deptList.value = handleTree(await DeptApi.getSimpleDeptList({ allFlag: true }))
|
||||
getOptions()
|
||||
}
|
||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
|
||||
Reference in New Issue
Block a user