Browse Source

🎟 框架升级

master
wangxiang 3 years ago
parent
commit
e660125c10
  1. 9
      kicc-platform/kicc-platform-biz/kicc-system-biz/src/main/java/com/cloud/kicc/system/controller/UserController.java
  2. 2
      kicc-register/src/main/resources/bootstrap.yml
  3. 12
      kicc-ui/src/views/system/user/DeptTree.vue
  4. 63
      kicc-ui/src/views/system/user/UserDetail.vue
  5. 100
      kicc-ui/src/views/system/user/UserModal.vue
  6. 185
      kicc-ui/src/views/system/user/index.vue
  7. 170
      kicc-ui/src/views/system/user/user.data.ts

9
kicc-platform/kicc-platform-biz/kicc-system-biz/src/main/java/com/cloud/kicc/system/controller/UserController.java

@ -26,6 +26,7 @@ import com.cloud.kicc.common.security.util.SecurityUtils; @@ -26,6 +26,7 @@ import com.cloud.kicc.common.security.util.SecurityUtils;
import com.pig4cloud.plugin.excel.annotation.ResponseExcel;
import com.pig4cloud.plugin.excel.annotation.Sheet;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@ -45,8 +46,8 @@ import java.util.stream.Collectors; @@ -45,8 +46,8 @@ import java.util.stream.Collectors;
* @Date: 2022/2/24
*/
@RestController
@RequiredArgsConstructor
@RequestMapping(AppConstants.APP_SYSTEM + "/user")
@AllArgsConstructor
public class UserController {
private final UserService userService;
@ -134,10 +135,10 @@ public class UserController { @@ -134,10 +135,10 @@ public class UserController {
@GetMapping("/profile")
public R profile() {
KiccUser entfrmUser = SecurityUtils.getUser();
if (entfrmUser != null) {
KiccUser kiccUser = SecurityUtils.getUser();
if (kiccUser != null) {
ResultVo resultVo = new ResultVo();
User user = userService.getById(entfrmUser.getId() + "");
User user = userService.getById(kiccUser.getId() + "");
if (user != null) {
String roleNames = SecurityUtils.getRoles().stream().map(roleId -> roleService.getById(roleId).getName())
.collect(Collectors.joining(","));

2
kicc-register/src/main/resources/bootstrap.yml

@ -7,7 +7,7 @@ db: @@ -7,7 +7,7 @@ db:
user: ${MYSQL_USER:root}
password: ${MYSQL_PWD:root}
url:
0: jdbc:mysql://${MYSQL_HOST:120.26.168.56}:${MYSQL_PORT:8052}/${MYSQL_DB:kicc_config}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true
0: jdbc:mysql://${MYSQL_HOST:127.0.0.1}:${MYSQL_PORT:3306}/${MYSQL_DB:kicc_config}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true
nacos:
core:

12
kicc-ui/src/views/system/user/DeptTree.vue

@ -13,7 +13,8 @@ @@ -13,7 +13,8 @@
<script lang="ts">
import { defineComponent, onMounted, ref } from 'vue';
import { BasicTree, TreeItem } from '/@/components/Tree';
import { departTreeList } from '/@/api/system/dept';
import { deptList } from '/@/api/system/dept';
import { listToTree } from "/@/utils/helper/treeHelper";
export default defineComponent({
name: 'DeptTree',
@ -23,17 +24,16 @@ @@ -23,17 +24,16 @@
const treeData = ref<TreeItem[]>([]);
async function fetch() {
treeData.value = await departTreeList();
treeData.value = listToTree(await deptList());
}
function handleSelect(keys: string, e) {
emit('select', keys[0]);
console.log(keys, e);
}
onMounted(() => {
fetch();
});
onMounted(() => fetch());
return { treeData, handleSelect };
},
}
});
</script>

63
kicc-ui/src/views/system/user/UserDetail.vue

@ -1,63 +0,0 @@ @@ -1,63 +0,0 @@
<template>
<PageWrapper
:title="`用户` + userId + `的资料`"
content="这是用户资料详情页面。本页面仅用于演示相同路由在tab中打开多个页面并且显示不同的数据"
contentBackground
@back="goBack"
>
<template #extra>
<a-button type="primary" danger> 禁用账号 </a-button>
<a-button type="primary"> 修改密码 </a-button>
</template>
<template #footer>
<a-tabs default-active-key="detail" v-model:activeKey="currentKey">
<a-tab-pane key="detail" tab="用户资料" />
<a-tab-pane key="logs" tab="操作日志" />
</a-tabs>
</template>
<div class="pt-4 m-4 desc-wrap">
<template v-if="currentKey == 'detail'">
<div v-for="i in 10" :key="i">这是用户{{ userId }}资料Tab</div>
</template>
<template v-if="currentKey == 'logs'">
<div v-for="i in 10" :key="i">这是用户{{ userId }}操作日志Tab</div>
</template>
</div>
</PageWrapper>
</template>
<script>
import { defineComponent, ref } from 'vue';
import { useRoute } from 'vue-router';
import { PageWrapper } from '/@/components/Page';
import { useGo } from '/@/hooks/web/usePage';
import { useTabs } from '/@/hooks/web/useTabs';
import { Tabs } from 'ant-design-vue';
export default defineComponent({
name: 'AccountDetail',
components: { PageWrapper, ATabs: Tabs, ATabPane: Tabs.TabPane },
setup() {
const route = useRoute();
const go = useGo();
// ID
const userId = ref(route.params?.id);
const currentKey = ref('detail');
const { setTitle } = useTabs();
// TODO
// userId
// Tab
setTitle('详情:用户' + userId.value);
//
function goBack() {
//
go('/system/account');
}
return { userId, currentKey, goBack };
},
});
</script>
<style></style>

100
kicc-ui/src/views/system/user/UserModal.vue

@ -1,73 +1,95 @@ @@ -1,73 +1,95 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="getTitle" @ok="handleSubmit">
<BasicForm @register="registerForm" />
<BasicModal v-bind="$attrs"
width="720px"
@ok="handleSubmit"
@register="registerModal"
>
<BasicForm @register="registerForm"/>
</BasicModal>
</template>
<script lang="ts">
import { defineComponent, ref, computed, unref } from 'vue';
/**
* Copyright © 2020-2022 <a href="http://www.entfrm.com/">entfrm</a> All rights reserved.
* author entfrm开发团队-王翔
*/
import { defineComponent, ref, computed, unref, reactive } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import { accountFormSchema } from './user.data';
import { departList } from '/@/api/system/dept';
//import { set } from '/@/api/system/user';
import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
import { userFormSchema } from './user.data';
import { deptList } from '/@/api/system/dept';
import { addUser, editUser, getUser } from '/@/api/system/user';
import { listToTree } from "/@/utils/helper/treeHelper";
import { addMenu, editMenu, getMenu, getRoleMenuIds, listMenu } from "/@/api/system/menu";
import { ModalProps } from "/@/components/Modal";
export default defineComponent({
name: 'UserModal',
components: { BasicModal, BasicForm },
emits: ['success', 'register'],
setup(_, { emit }) {
const isUpdate = ref(true);
const rowId = ref('');
setup(props, { emit }) {
const tag = ref('');
const [registerForm, { setFieldsValue, updateSchema, resetFields, validate }] = useForm({
const [registerForm, {resetFields, setFieldsValue, updateSchema, validate, clearValidate}] = useForm({
labelWidth: 100,
schemas: accountFormSchema,
schemas: userFormSchema,
showActionButtonGroup: false,
actionColOptions: {
span: 23,
},
span: 24
}
});
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
resetFields();
setModalProps({ confirmLoading: false });
isUpdate.value = !!data?.isUpdate;
if (unref(isUpdate)) {
rowId.value = data.record.id;
setFieldsValue({
...data.record,
});
}
const treeData = await departList();
updateSchema([
await resetFields();
await clearValidate();
tag.value = data._tag;
const userId = data.record?.id;
const props: Partial<ModalProps> = { confirmLoading: false };
await updateSchema([
{
field: 'pwd',
show: !unref(isUpdate),
field: 'deptId',
componentProps: { treeData: listToTree(await deptList()) }
},
{
field: 'departId',
componentProps: { treeData },
},
field: 'password',
show: tag.value == 'add'
}
]);
switch (tag.value) {
case 'add':
props.title = '新增用户';
break;
case 'edit':
props.title = '编辑用户';
await setFieldsValue(await getUser(userId) || {});
break;
}
setModalProps(props);
});
const getTitle = computed(() => (!unref(isUpdate) ? '新增用户' : '编辑用户'));
async function handleSubmit() {
try {
const values = await validate();
const formData = await validate();
setModalProps({ confirmLoading: true });
await set(values);
switch (unref(tag)) {
case 'add':
await addMenu(formData);
break;
case 'edit':
await editMenu(formData);
break;
}
closeModal();
emit('success', { isUpdate: unref(isUpdate), values: { ...values, id: rowId.value } });
emit('success');
} finally {
setModalProps({ confirmLoading: false });
}
}
return { registerModal, registerForm, getTitle, handleSubmit };
},
return {
registerModal,
registerForm,
handleSubmit
};
}
});
</script>

185
kicc-ui/src/views/system/user/index.vue

@ -1,155 +1,182 @@ @@ -1,155 +1,182 @@
<template>
<PageWrapper dense contentFullHeight fixedHeight contentClass="flex">
<PageWrapper dense
contentFullHeight
fixedHeight
contentClass="flex"
>
<DeptTree class="w-1/4 xl:w-1/5" @select="handleSelect"/>
<BasicTable @register="registerTable" class="w-3/4 xl:w-4/5" :searchInfo="searchInfo">
<BasicTable class="w-3/4 xl:w-4/5" @register="registerTable">
<template #toolbar>
<a-button type="primary" @click="handleCreate">新增用户</a-button>
<a-button v-auth="['role_edit']"
<a-button v-auth="['user_add']"
type="primary"
@click="handleAdd()"
>新增用户</a-button>
<a-button v-auth="['user_edit']"
type="primary"
:disabled="state.single"
@click="handleEdit()"
>修改用户</a-button>
<a-button v-auth="['role_del']"
<a-button v-auth="['user_del']"
type="primary"
:disabled="state.multiple"
@click="handleDel()"
>删除用户</a-button>
</template>
<template #action="{ record }">
<TableAction
:actions="[
{
icon: 'clarity:lock-line',
tooltip: '修改密码',
onClick: handleSetPassword.bind(null, record),
},
{
icon: 'clarity:note-edit-line',
tooltip: '编辑用户资料',
onClick: handleEdit.bind(null, record),
},
{
icon: 'ant-design:delete-outlined',
color: 'error',
tooltip: '删除此账号',
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
},
},
]"
<TableAction :actions="[
{
icon: 'clarity:lock-line',
tooltip: '修改密码',
onClick: handleUpdatePwd.bind(null, record),
},
{
label: '编辑',
icon: 'fa6-regular:pen-to-square',
auth: ['role_edit'],
onClick: handleEdit.bind(null, record)
},
{
label: '删除',
icon: 'ant-design:delete-outlined',
auth: ['role_del'],
color: 'error',
onClick: handleDel.bind(null, record)
}]"
/>
</template>
</BasicTable>
<UserModal @register="registerModal" @success="handleSuccess" />
<PasswordModal @register="registerPasswordModal" @success="handlePasswordSuccess" />
<UserModal @register="registerModal" @success="handleSuccess"/>
<PasswordModal @register="registerPasswordModal" @success="handleUpdatePwd"/>
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent, reactive } from 'vue';
import { defineComponent, reactive, toRaw } from 'vue';
import { BasicTable, useTable, TableAction } from '/@/components/Table';
//import { del, page } from '/@/api/system/user';
import { listUser, delUser, updatePwd } from '/@/api/system/user';
import { PageWrapper } from '/@/components/Page';
import DeptTree from './DeptTree.vue';
import { useModal } from '/@/components/Modal';
import UserModal from './UserModal.vue';
import PasswordModal from './PasswordModal.vue';
import { columns, searchFormSchema } from './user.data';
import { useGo } from '/@/hooks/web/usePage';
import { useMessage } from '/@/hooks/web/useMessage';
const { createConfirm } = useMessage();
const { createMessage } = useMessage();
export default defineComponent({
name: 'UserManagement',
components: { BasicTable, PageWrapper, DeptTree, UserModal, TableAction, PasswordModal },
components: {
BasicTable,
PageWrapper,
DeptTree,
TableAction,
UserModal,
PasswordModal
},
setup() {
const go = useGo();
const state = reactive({
//
ids: [],
//
single: true,
//
multiple: true,
//
searchInfo: {} as Recordable
});
const [registerModal, { openModal }] = useModal();
const [registerPasswordModal, { openModal: openPasswordModal }] = useModal();
const searchInfo = reactive<Recordable>({});
const [registerTable, { reload, updateTableDataRecord }] = useTable({
const [registerTable, { reload }] = useTable({
title: '用户列表',
api: page,
api: listUser,
rowKey: 'id',
columns,
formConfig: {
labelWidth: 120,
schemas: searchFormSchema,
autoSubmitOnEnter: true,
autoSubmitOnEnter: true
},
rowSelection: { type: 'checkbox' },
useSearchForm: true,
showTableSetting: true,
bordered: true,
handleSearchInfoFn(info) {
console.log('handleSearchInfoFn', info);
return info;
},
clickToRowSelect: false,
searchInfo: state.searchInfo,
actionColumn: {
width: 120,
title: '操作',
dataIndex: 'action',
slots: { customRender: 'action' },
},
slots: { customRender: 'action' }
}
});
function handleCreate() {
openModal(true, {
isUpdate: false,
});
/** 处理多选框选中数据 */
function handleSelectionChange(selection?: Recordable) {
const rawRows = toRaw(selection?.rows) || [];
state.ids = rawRows.map(item => item.id);
state.single = rawRows.length != 1;
state.multiple = !rawRows.length;
}
function handleEdit(record: Recordable) {
openModal(true, {
record,
isUpdate: true,
});
/** 新增按钮操作,行内新增与工具栏局域新增通用 */
function handleAdd() {
openModal(true,{ _tag: 'add' });
}
async function handleDelete(record: Recordable) {
await del({ ids: record.id });
createMessage.success('删除成功!');
handleSuccess();
/** 编辑按钮操作,行内编辑 */
function handleEdit(record?: Recordable) {
record = record || { id: toRaw(state.ids) };
openModal(true, { _tag: 'edit', record });
}
function handleSuccess() {
reload();
/** 处理修改用户密码 */
function handleUpdatePwd(record: Recordable) {
record = record || { id: toRaw(state.ids) };
openPasswordModal(true, { _tag: 'edit', record });
}
function handleSelect(departId = '') {
searchInfo.departId = departId;
reload();
}
function handleSetPassword(record: Recordable) {
openPasswordModal(true, {
record,
isUpdate: true,
/** 删除按钮操作,行内删除 */
async function handleDel(record?: Recordable) {
const ids = record?.id || toRaw(state.ids);
createConfirm({
iconType: 'warning',
title: '警告',
content: `是否确认删除用户编号为${ids}用户吗?`,
onOk: async () => {
await delUser(ids);
createMessage.success('删除成功!');
handleSuccess();
}
});
}
function handleView(record: Recordable) {
go('/system/account_detail/' + record.id);
/** 处理表单提交成功 */
function handleSuccess() {
reload();
}
function handlePasswordSuccess() {
/** 处理部门管理点击 */
function handleSelect(departId = '') {
state.searchInfo.departId = departId;
reload();
}
return {
state,
registerTable,
registerModal,
handleCreate,
registerPasswordModal,
handleAdd,
handleEdit,
handleDelete,
handleDel,
handleSelectionChange,
handleSuccess,
handleSelect,
handleView,
searchInfo,
handleSetPassword,
registerPasswordModal,
handlePasswordSuccess,
handleUpdatePwd
};
},
}
});
</script>

170
kicc-ui/src/views/system/user/user.data.ts

@ -1,8 +1,8 @@ @@ -1,8 +1,8 @@
// import { roleAllList } from './../../../api/system/role';
import { BasicColumn } from '/@/components/Table';
import { FormSchema } from '/@/components/Table';
import { h } from 'vue';
import { Tag } from 'ant-design-vue';
import { listRole } from '/@/api/system/role';
export const columns: BasicColumn[] = [
{
@ -55,113 +55,155 @@ export const searchFormSchema: FormSchema[] = [ @@ -55,113 +55,155 @@ export const searchFormSchema: FormSchema[] = [
colProps: { span: 8 },
},
{
field: 'startDate',
label: '起始时间',
component: 'DatePicker',
colProps: { span: 8 },
},
{
field: 'endDate',
label: '截止时间',
component: 'DatePicker',
colProps: { span: 8 },
},
field: 'dateRange',
label: '创建时间',
component: 'RangePicker',
componentProps: {
style: { width:'100%' },
valueFormat: 'YYYY-MM-DD',
placeholder: ['开始日期','结束日期']
},
colProps: { span: 8 }
}
];
export const accountFormSchema: FormSchema[] = [
export const userFormSchema: FormSchema[] = [
{
field: 'id',
label: 'ID',
component: 'Input',
show: false,
show: false
},
{
field: 'account',
label: '用户',
field: 'nickName',
label: '用户昵称',
component: 'Input',
helpMessage: ['本字段演示异步验证', '不能输入带有admin的用户名'],
},
{
field: 'pwd',
label: '密码',
component: 'InputPassword',
required: true,
ifShow: false,
},
{
field: 'sex',
label: '性别',
component: 'RadioButtonGroup',
defaultValue: 1,
componentProps: {
options: [
{ label: '男', value: 1 },
{ label: '女', value: 2 },
],
},
},
{
label: '授权角色',
field: 'roleId',
component: 'ApiSelect',
componentProps: {
// api: roleAllList,
resultField: 'list',
labelField: 'roleName',
valueField: 'id',
},
required: true,
colProps: {
span: 12
}
},
{
field: 'departId',
label: '所属部门',
field: 'deptId',
label: '归属机构',
component: 'TreeSelect',
componentProps: {
replaceFields: {
title: 'name',
key: 'id',
value: 'id',
value: 'id'
},
getPopupContainer: () => document.body,
getPopupContainer: () => document.body
},
required: true,
colProps: {
span: 12
}
},
{
field: 'realName',
label: '姓名',
field: 'phone',
label: '手机号',
component: 'Input',
required: true,
rules: [
{
required: true,
message: '请输入手机号!',
},
{
pattern: new RegExp('^1[3|4|5|6|7|8|9][0-9]\\d{8}$'),
message: '请输入正确的手机号码!',
validateTrigger: 'blur'
}
]
},
{
field: 'name',
label: '昵称',
field: 'email',
label: '邮箱',
component: 'Input',
required: true,
rules: [
{
required: true,
message: '请输入邮箱!',
},
{
type: 'email',
message: '请输入正确的邮箱地址!',
validateTrigger: ['blur', 'change']
}
]
},
{
label: '邮箱',
field: 'email',
field: 'userName',
label: '用户名',
component: 'Input',
required: true,
colProps: {
span: 12
}
},
{
field: 'password',
label: '密码',
component: 'InputPassword',
required: true,
colProps: {
span: 12
}
},
{
field: 'sex',
label: '性别',
component: 'Select',
required: true,
componentProps: {
options: [
{ label: '男', value: '0' },
{ label: '女', value: '1' }
]
},
colProps: {
span: 12
}
},
{
field: 'status',
label: '状态',
component: 'RadioButtonGroup',
component: 'RadioGroup',
defaultValue: '0',
componentProps: {
options: [
{ label: '在职', value: '0' },
{ label: '离职', value: '1' },
],
{ label: '正常', value: '0' },
{ label: '停用', value: '1' }
]
},
colProps: {
span: 12
}
},
{
field: 'roleIds',
label: '授权角色',
component: 'ApiSelect',
componentProps: {
mode: 'multiple',
api: listRole,
labelField: 'name',
valueField: 'id'
},
colProps: {
span: 12
}
},
{
label: '备注',
field: 'remark',
field: 'remarks',
component: 'InputTextArea',
},
colProps: {
span: 24
}
}
];
export const passwordFormSchema: FormSchema[] = [

Loading…
Cancel
Save