Skip to content

Commit

Permalink
Merge pull request #37 from daichen-daisy/main
Browse files Browse the repository at this point in the history
feat: create a component for set orgs form
  • Loading branch information
daichen-daisy authored May 17, 2023
2 parents f6f5023 + b880009 commit 67e6138
Show file tree
Hide file tree
Showing 15 changed files with 364 additions and 235 deletions.
8 changes: 6 additions & 2 deletions src/components/DropdownButton.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<q-btn flat dense :class="btnClass" :style="btnStyle">
<q-icon v-if="btnIcon" size="18px" :name="btnIcon" />{{ btnLabel }}
<q-icon v-if="btnIcon" :size="btnIconSize" :name="btnIcon" />{{ btnLabel }}
<q-menu class="q-px-xs" anchor="bottom right" self="top right">
<q-list dense>
<q-item
Expand All @@ -14,7 +14,7 @@
@click="$emit(button.actionType.replace('_', '-'))"
>
<q-item-section v-if="button.icon" avatar class="q-pr-none">
<q-icon :name="button.icon" size="16px" />
<q-icon :name="button.icon" size="18px" />
</q-item-section>
<q-item-section> {{ button.label }} </q-item-section>
<q-tooltip
Expand Down Expand Up @@ -43,6 +43,10 @@ export default defineComponent({
type: String,
default: 'more_horiz',
},
btnIconSize: {
type: String,
default: '18px',
},
btnLabel: {
type: String,
default: '',
Expand Down
40 changes: 30 additions & 10 deletions src/components/form/TreeSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -89,23 +89,43 @@ export default defineComponent({
return {
selected: ref(null),
ticked: ref<string[]>([]),
selectedNode: ref<QTreeNode>(),
selectedNode: ref<QTreeNode>({}),
tickedNodes: ref<QTreeNode>([]),
};
},
mounted() {
if (!this.multiSelect && this.initialSelectedItems.length) {
this.selectedNode = this.initialSelectedItems[0];
this.selected = this.selectedNode ? this.selectedNode.id : null;
}
if (this.multiSelect && this.initialSelectedItems.length) {
this.tickedNodes = this.initialSelectedItems;
this.ticked = this.initialSelectedItems.map((item: QTreeNode) => item.id);
}
watch: {
nodes() {
this.resetTree();
this.initTree();
},
},
unmounted() {
this.resetTree();
},
methods: {
resetTree() {
this.selected = null;
this.ticked = [];
this.selectedNode = {};
this.tickedNodes = [];
},
initTree() {
if (!this.multiSelect && this.initialSelectedItems.length) {
this.selectedNode = this.initialSelectedItems[0];
this.selected = this.selectedNode ? this.selectedNode.id : null;
}
if (this.multiSelect && this.initialSelectedItems.length) {
this.tickedNodes = this.initialSelectedItems;
this.ticked = this.initialSelectedItems.map(
(item: QTreeNode) => item.id
);
}
},
nodeSelected() {
this.selectedNode = (this.$refs.popupTree as QTree).getNodeByKey(
this.selected
Expand Down
2 changes: 1 addition & 1 deletion src/components/role/RoleOperations.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { api } from 'boot/axios';
import { Dialog } from 'quasar';
import { User } from 'src/pages/user/type';

import ConfirmDialog from 'components/dialog/ConfirmDialog.vue';
import { Role } from 'pages/role/type';
import { User } from 'pages/user/type';

import { RoleOperationsType } from './type';

Expand Down
3 changes: 1 addition & 2 deletions src/components/role/type.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { User } from 'src/pages/user/type';

import { Role } from 'pages/role/type';
import { User } from 'pages/user/type';

export interface RoleOperationsType {
methods: {
Expand Down
141 changes: 141 additions & 0 deletions src/components/user/SetOrganizationsForm.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
<template>
<form-dialog
ref="transferDialog"
v-model="transferForm"
title="配置组织"
width="450px"
@confirm="saveTransferForm"
@close="resetTransferForm"
>
<template #form-content>
<div class="q-gutter-md q-pa-md">
<div v-if="!user.org_type">
<field-label name="组织类型" required />
<q-select
v-model="selectedOrgTypeId"
:options="orgTypeOptions"
dense
filled
class="full-width"
option-label="name"
option-value="id"
emit-value
map-options
hide-bottom-space
:disable="!!user.org_type"
@update:model-value="loadOrgTree"
/>
</div>
<div>
<field-label name="组织归属" required />
<tree-select
v-model="transferFormData.organization_ids"
:nodes="orgTreeData"
multi-select
:initial-selected-items="parentDepartment"
/>
<div
v-if="!!transferFormError.organization_ids"
class="error-hint text-negative"
>
{{ transferFormError.organization_ids }}
</div>
</div>
<div class="text-caption hint-label">
提示:如需彻底移除所有组织归属,请点击【办理离职】。
</div>
</div>
</template>
</form-dialog>
</template>

<script lang="ts">
import { defineComponent, ref } from 'vue';
import { QTreeNode } from 'quasar';
import { OrgType } from 'pages/type';
import { User } from 'pages/user/type';
import { FormDialogComponent } from '../dialog/type';
import { SetOrganizationsPostData, SetOrganizationsPostError } from './type';
export default defineComponent({
name: 'SetOrganizationsForm',
emits: ['userUpdated'],
setup() {
return {
user: ref<User>({ id: '' }),
orgTreeData: ref<QTreeNode[]>(),
parentDepartment: ref<QTreeNode[]>(),
orgTypeOptions: ref<OrgType[]>([]),
selectedOrgTypeId: ref(''),
transferForm: ref(false),
transferFormData: ref<SetOrganizationsPostData>({}),
transferFormError: ref<SetOrganizationsPostError>({}),
};
},
methods: {
async show(user: User) {
this.user = user;
this.transferForm = true;
this.loadOrgTypes();
if (user.departments?.length !== 0) {
this.parentDepartment = user.departments;
this.transferFormData.organization_ids = user.departments?.map(
(d) => d.id
);
}
},
async saveTransferForm() {
this.transferFormData.user_id = this.user.id;
this.transferFormData.org_type_id = this.selectedOrgTypeId;
try {
this.transferFormError = {};
await this.$api.put(
`/users/${this.transferFormData.user_id}/organizations`,
this.transferFormData,
{
successMsg: '组织归属变更成功',
}
);
(this.$refs.transferDialog as FormDialogComponent).hide();
this.$emit('userUpdated');
this.resetTransferForm();
} catch (e) {
this.transferFormError = (e as Error).cause || {};
}
},
resetTransferForm() {
this.transferFormData = {};
this.transferFormError = {};
this.parentDepartment = [];
},
async loadOrgTypes() {
const resp = await this.$api.get('/org_types');
this.orgTypeOptions = resp.data.org_types;
this.selectedOrgTypeId = this.user.org_type?.id
? this.user.org_type.id
: this.orgTypeOptions[0].id;
this.loadOrgTree(this.selectedOrgTypeId);
},
async loadOrgTree(org_type_id: string) {
this.transferFormData.organization_ids = [];
const resp = await this.$api.get(
`/org_types/${org_type_id}/organization_tree`
);
this.orgTreeData = resp.data;
},
},
});
</script>

<style lang="scss" scoped></style>
23 changes: 9 additions & 14 deletions src/components/user/SetRolesForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,9 @@

<script lang="ts">
import { defineComponent, ref } from 'vue';
import { Role } from 'src/pages/role/type';
import { User } from 'src/pages/user/type';
import { Role } from 'pages/role/type';
import { User } from 'pages/user/type';
import { FormDialogComponent } from '../dialog/type';
Expand All @@ -101,25 +102,19 @@ export default defineComponent({
this.user = user;
this.loadAvailableRoles();
this.setRolesForm = true;
this.setRolesFormData.user_id = user.id;
this.selectedRoles = user.roles || [];
},
async loadAvailableRoles() {
if (this.user.org_type?.id) {
const resp = await this.$api.post('/roles/query', {
org_type_id: this.user.org_type.id,
});
this.availableRoleOptions = resp.data.rows;
} else {
const resp = await this.$api.post('/roles/query', {});
this.availableRoleOptions = resp.data.rows.filter(
(role: Role) => !role.org_type
);
}
const params = this.user.org_type?.id
? { org_type_id: this.user.org_type.id }
: { include_org_type_roles: false };
const resp = await this.$api.post('/roles/query', params);
this.availableRoleOptions = resp.data.rows;
},
async saveSetRolesForm() {
this.setRolesFormData.user_id = this.user.id;
this.setRolesFormData.role_ids = this.selectedRoles.map(
(role) => role.id
);
Expand Down
52 changes: 52 additions & 0 deletions src/components/user/UserOperations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,5 +90,57 @@ export const UserOperationsMixin: UserOperationsType = {
}
});
},

resignUsers(users: User[], handler?: (...args: [string]) => void) {
const userDesc = `【${users[0].name}${
users.length > 1 ? `等 ${users.length} 人` : ''
}`;

Dialog.create({
component: ConfirmDialog,
componentProps: {
title: '办理离职',
content: `您正在请求为成员${userDesc}办理离职。操作后,该成员授权、组织部门和角色等关系将被删除,转为普通用户。如需同时禁用该用户,请点击【离职并禁用】。
`,
buttons: [
{ label: '取消', class: 'secondary-btn' },
{
label: '离职',
actionType: 'resign',
class: 'accent-btn',
},
{
label: '离职并禁用',
actionType: 'resign_disable',
class: 'accent-btn',
},
],
},
}).onOk(async ({ type }) => {
if (['resign', 'resign_disable'].indexOf(type) >= 0) {
let postData = {};
if (type === 'resign') {
postData = { user_ids: users.map((u: User) => u.id) };
} else if (type === 'resign_disable') {
postData = {
user_ids: users.map((u: User) => u.id),
is_deleted: true,
};
}
try {
await api.request({
method: 'POST',
url: '/users/resign',
data: postData,
successMsg: '离职办理成功',
});
} finally {
if (handler) {
handler('resign');
}
}
}
});
},
},
};
20 changes: 20 additions & 0 deletions src/components/user/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export interface UserOperationsType {
handler?: (...args: [string]) => void
) => void;
deleteUsers: (users: User[], handler?: (...args: [string]) => void) => void;
resignUsers: (users: User[], handler?: (...args: [string]) => void) => void;
};
}

Expand All @@ -27,3 +28,22 @@ export interface SetRolesPostError {
user_id?: string;
role_ids?: string;
}

export interface SetOrganizationsComponent {
/** 唤醒设置组织对话框 */
show: (user: User) => void;
}

export interface SetOrganizationsPostData {
/** 用户的 ID */
user_id?: string;
/** 多个组织的 ID 集合 */
organization_ids?: string[];
/** 组织类型 ID */
org_type_id?: string;
}

export interface SetOrganizationsPostError {
user_id?: string;
organization_ids?: string;
}
Loading

0 comments on commit 67e6138

Please sign in to comment.