Commit a69180e1 authored by jiaxu.yan's avatar jiaxu.yan

feat: 列表页面搭建框架

parent 2e22ff34
......@@ -7,7 +7,7 @@ import { theme } from 'ant-design-vue/lib';
import convertLegacyToken from 'ant-design-vue/lib/theme/convertLegacyToken';
const { defaultAlgorithm, defaultSeed } = theme;
const primaryColor = '#0960bd';
const primaryColor = '#166ACB';
function generateAntColors(color: string, theme: 'default' | 'dark' = 'default') {
return generate(color, {
......
......@@ -25,4 +25,13 @@ export interface ProjectListItem {
update_by: string;
}
export interface ProjectModel {
id?: string | number;
constructionMode: string;
isReserveProject: string;
projectType: string;
projectOverview: string;
constructionPurpose: string;
}
export type ProjectListGetResultModel = ProjectListItem[];
import { ProjectParams, ProjectListGetResultModel } from './model/projectModel';
import { ProjectParams, ProjectListGetResultModel, ProjectModel } from './model/projectModel';
import { defHttp } from '@/utils/http/axios';
enum Api {
GetAllProjectList = '/mgapi/project/project/list/page',
AddProject = '/mgapi/project/projectManage/add',
UpdateProject = '/mgapi/project/projectManage/update',
}
export const getProjectListByPage = (params?: ProjectParams) =>
defHttp.post<ProjectListGetResultModel>({ url: Api.GetAllProjectList, data: params });
export const addProjectItem = (params?: any) =>
defHttp.post<ProjectModel>({ url: Api.AddProject, data: params });
export const updateProjectItem = (params?: any) =>
defHttp.post<ProjectModel>({ url: Api.UpdateProject, data: params });
......@@ -327,9 +327,9 @@
.@{prefix-cls} {
.ant-form-item {
&-label label::after {
margin: 0 6px 0 2px;
}
// &-label label::after {
margin-right: 6px;
// }
// &-with-help {
// margin-bottom: 0;
......@@ -339,12 +339,14 @@
// margin-bottom: 20px;
// }
&.suffix-item, &.prefix-item {
&.suffix-item,
&.prefix-item {
.ant-form-item-children {
display: flex;
}
}
}
&.suffix-item, &.prefix-item{
&.suffix-item,
&.prefix-item {
.prefix {
display: inline-flex;
align-items: center;
......@@ -361,7 +363,7 @@
}
}
}
.ant-form-explain {
font-size: 14px;
}
......
......@@ -41,14 +41,14 @@
</template>
<script lang="ts" setup>
import type { ColEx } from '../types';
import { computed, PropType } from 'vue';
import { computed, PropType, h } from 'vue';
import { Form, Col } from 'ant-design-vue';
import { Button, ButtonProps } from '@/components/Button';
import { BasicArrow } from '@/components/Basic';
import { useFormContext } from '../hooks/useFormContext';
import { useI18n } from '@/hooks/web/useI18n';
import { propTypes } from '@/utils/propTypes';
import { SearchOutlined, RedoOutlined } from '@ant-design/icons-vue';
defineOptions({ name: 'BasicFormAction' });
const props = defineProps({
......@@ -95,6 +95,8 @@
return Object.assign(
{
text: t('common.resetText'),
icon: h(RedoOutlined),
type:"default"
},
props.resetButtonOptions,
);
......@@ -104,6 +106,7 @@
return Object.assign(
{
text: t('common.queryText'),
icon: h(SearchOutlined),
},
props.submitButtonOptions,
);
......
......@@ -264,12 +264,13 @@
&-dark&-vertical &-submenu-title {
color: @menu-dark-subsidiary-color;
&-active:not(.@{menu-prefix-cls}-submenu) {
background-color: @primary-color !important;
color: #fff !important;
background-color: #fff !important;
color: @primary-color!important;
}
&:hover {
color: #fff;
background-color: #fff !important;
color: @primary-color!important;
}
}
......
<template>
<div ref="wrapRef" :class="getWrapperClass">
<BasicForm
ref="formRef"
submitOnReset
v-bind="getFormProps"
v-if="getBindValues.useSearchForm"
:tableAction="tableAction"
@register="registerForm"
@submit="handleSearchInfoChange"
@advanced-change="redoHeight"
>
<template #[replaceFormSlotKey(item)]="data" v-for="item in getFormSlotKeys">
<slot :name="item" v-bind="data || {}"></slot>
</template>
</BasicForm>
<Table
ref="tableElRef"
v-bind="getBindValues"
:rowClassName="getRowClassName"
v-show="getEmptyDataIsShowTable"
@change="handleTableChange"
@resize-column="setColumnWidth"
@expand="handleTableExpand"
>
<template #[item]="data" v-for="item in Object.keys($slots)" :key="item">
<slot :name="item" v-bind="data || {}"></slot>
</template>
<template #headerCell="{ column }">
<slot name="headerCell" v-bind="{ column }">
<HeaderCell :column="column" />
</slot>
</template>
<template #bodyCell="data">
<slot name="bodyCell" v-bind="data || {}"></slot>
</template>
</Table>
<div class="page-card">
<div class="page-card-title"> {{ title }}</div>
<div class="page-card-body">
<BasicForm
ref="formRef"
submitOnReset
v-bind="getFormProps"
v-if="getBindValues.useSearchForm"
:tableAction="tableAction"
@register="registerForm"
@submit="handleSearchInfoChange"
@advanced-change="redoHeight"
>
<template #[replaceFormSlotKey(item)]="data" v-for="item in getFormSlotKeys">
<slot :name="item" v-bind="data || {}"></slot>
</template>
</BasicForm>
<div class="toolbar">
<slot name="toolbar"></slot>
</div>
<Table
ref="tableElRef"
v-bind="getBindValues"
:rowClassName="getRowClassName"
v-show="getEmptyDataIsShowTable"
@change="handleTableChange"
@resize-column="setColumnWidth"
@expand="handleTableExpand"
>
<template #[item]="data" v-for="item in Object.keys($slots)" :key="item">
<slot :name="item" v-bind="data || {}"></slot>
</template>
<template #headerCell="{ column }">
<slot name="headerCell" v-bind="{ column }">
<HeaderCell :column="column" />
</slot>
</template>
<template #bodyCell="data">
<slot name="bodyCell" v-bind="data || {}"></slot>
</template>
</Table>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
......@@ -351,8 +358,8 @@
.ant-form {
width: 100%;
margin-bottom: 16px;
padding: 12px 10px 6px;
// margin-bottom: 16px;
// padding: 12px 10px 6px;
border-radius: 2px;
background-color: @component-background;
}
......@@ -365,13 +372,14 @@
}
.ant-table-wrapper {
padding: 6px;
// padding: 6px;
border-radius: 2px;
background-color: @component-background;
.ant-table-title {
min-height: 40px;
padding: 0 0 8px !important;
display: none;
// min-height: 40px;
// padding: 0 0 8px !important;
}
.ant-table.ant-table-bordered .ant-table-title {
......@@ -427,4 +435,31 @@
}
}
}
.page-card {
background: #ffffff;
border-radius: 4px;
padding: 0 8px;
.page-card-title {
height: 35px;
padding: 10px 0;
border-bottom: 1px solid #f0f0f0;
display: flex;
align-items: center;
justify-content: flex-start;
&::before {
content: ' ';
display: block;
width: 4px;
height: 12px;
background: #166acb;
margin-right: 8px;
}
}
.page-card-body {
padding: 24px;
.toolbar {
margin-bottom: 10px;
}
}
}
</style>
......@@ -27,7 +27,6 @@ export function useTableHeader(
h(
TableHeader,
{
title,
titleHelpMessage,
showTableSetting,
tableSetting,
......@@ -37,23 +36,23 @@ export function useTableHeader(
count: methods.getSelectRowKeys().length,
showSelectionBar,
} as Recordable,
{
...(slots.toolbar
? {
toolbar: () => getSlot(slots, 'toolbar'),
}
: {}),
...(slots.tableTitle
? {
tableTitle: () => getSlot(slots, 'tableTitle'),
}
: {}),
...(slots.headerTop
? {
headerTop: () => getSlot(slots, 'headerTop'),
}
: {}),
},
// {
// ...(slots.toolbar
// ? {
// toolbar: () => getSlot(slots, 'toolbar'),
// }
// : {}),
// ...(slots.tableTitle
// ? {
// tableTitle: () => getSlot(slots, 'tableTitle'),
// }
// : {}),
// ...(slots.headerTop
// ? {
// headerTop: () => getSlot(slots, 'headerTop'),
// }
// : {}),
// },
),
};
});
......
......@@ -15,12 +15,14 @@ import type { FormProps } from '@/components/Form';
import { DEFAULT_FILTER_FN, DEFAULT_SORT_FN, FETCH_SETTING, DEFAULT_SIZE } from './const';
import { propTypes } from '@/utils/propTypes';
import type { Key } from 'ant-design-vue/lib/table/interface';
import { string } from 'vue-types';
export const basicProps = {
clickToRowSelect: { type: Boolean, default: true },
isTreeTable: Boolean,
tableSetting: propTypes.shape<TableSetting>({}),
inset: Boolean,
title: string,
sortFn: {
type: Function as PropType<(sortInfo: SorterResult) => any>,
default: DEFAULT_SORT_FN,
......
......@@ -11,9 +11,9 @@ html {
--header-active-menu-bg-color: #273352;
// sider
--sider-dark-bg-color: #273352;
--sider-dark-darken-bg-color: #273352;
--sider-dark-lighten-bg-color: #273352;
--sider-dark-bg-color: #166ACB;
--sider-dark-darken-bg-color: #166ACB;
--sider-dark-lighten-bg-color: #166ACB;
// component
--component-background-color: #fff;
......
......@@ -11,25 +11,26 @@
<template #overlay>
<Menu @click="handleMenuClick">
<MenuItem
<!-- <MenuItem
key="doc"
:text="t('layout.header.dropdownItemDoc')"
icon="ion:document-text-outline"
v-if="getShowDoc"
/>
<Menu.Divider v-if="getShowDoc" />
<MenuItem
/> -->
<!-- <Menu.Divider v-if="getShowDoc" /> -->
<!-- <MenuItem
v-if="getShowApi"
key="api"
:text="t('layout.header.dropdownChangeApi')"
icon="ant-design:swap-outlined"
/>
/> -->
<MenuItem
v-if="getUseLockPage"
key="lock"
:text="t('layout.header.tooltipLock')"
icon="ion:lock-closed-outline"
/>
<Menu.Divider />
<MenuItem
key="logout"
:text="t('layout.header.dropdownItemLoginOut')"
......
......@@ -104,6 +104,7 @@
display: flex;
// padding-right: 12px;
align-items: center;
justify-content: flex-end;
min-width: 180px;
&__item {
......
......@@ -33,7 +33,7 @@
<!-- action -->
<div :class="`${prefixCls}-action`">
<AppSearch v-if="getShowSearch" :class="`${prefixCls}-action__item `" />
<!-- <AppSearch v-if="getShowSearch" :class="`${prefixCls}-action__item `" />
<ErrorAction v-if="getUseErrorHandle" :class="`${prefixCls}-action__item error-action`" />
......@@ -46,11 +46,11 @@
:reload="true"
:showText="false"
:class="`${prefixCls}-action__item`"
/>
/> -->
<UserDropDown :theme="getHeaderTheme" />
<SettingDrawer v-if="getShowSetting" :class="`${prefixCls}-action__item`" />
<!-- <SettingDrawer v-if="getShowSetting" :class="`${prefixCls}-action__item`" /> -->
</div>
</Layout.Header>
</template>
......
......@@ -5,6 +5,7 @@
:style="getHiddenDomStyle"
></div>
<!--
ewewew
针对场景:菜单折叠按钮为“底部”时:
关于 breakpoint,
组件定义的是 lg: '992px',
......
......@@ -441,8 +441,8 @@
}
// &:hover,
&--active {
background-color: @sider-dark-darken-bg-color;
color: @white;
background-color: #fff;
color: #166acb;
font-weight: 700;
&::before {
......
......@@ -15,7 +15,7 @@ export const layoutMultipleHeadePlaceholderTime = 0.6;
// app theme preset color
export const APP_PRESET_COLOR_LIST: string[] = [
'#0960bd',
'#ffffff',
'#0084f4',
'#009688',
'#536dfe',
......@@ -43,7 +43,7 @@ export const HEADER_PRESET_BG_COLOR_LIST: string[] = [
// sider preset color
export const SIDE_BAR_BG_COLOR_LIST: string[] = [
'#001529',
'#166ACB',
'#212121',
'#273352',
'#ffffff',
......
......@@ -160,13 +160,13 @@ export const useUserStore = defineStore({
* @description: logout
*/
async logout(goLogin = false) {
if (this.getToken) {
try {
await doLogout();
} catch {
console.log('注销Token失败');
}
}
// if (this.getToken) {
// try {
// await doLogout();
// } catch {
// console.log('注销Token失败');
// }
// }
this.setToken(undefined);
this.setSessionTimeout(false);
this.setUserInfo(null);
......
......@@ -8,16 +8,7 @@
@ok="handleSubmit"
>
<BasicForm @register="registerForm">
<template #menu="{ model, field }">
<BasicTree
v-model:value="model[field]"
:treeData="treeData"
:fieldNames="{ title: 'menuName', key: 'id' }"
checkable
toolbar
title="菜单分配"
/>
</template>
<!-- <template #menu="{ model, field }"> </template> -->
</BasicForm>
</BasicDrawer>
</template>
......@@ -26,13 +17,10 @@
import { BasicForm, useForm } from '@/components/Form';
import { formSchema } from './project.data';
import { BasicDrawer, useDrawerInner } from '@/components/Drawer';
import { BasicTree, TreeItem } from '@/components/Tree';
import { getMenuList } from '@/api/demo/system';
import { addProjectItem, updateProjectItem } from '@/api/project/project';
import { is } from '@/utils/is';
const emit = defineEmits(['success', 'register']);
const isUpdate = ref(true);
const treeData = ref<TreeItem[]>([]);
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
labelWidth: 90,
......@@ -44,10 +32,6 @@
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
resetFields();
setDrawerProps({ confirmLoading: false });
// 需要在setFieldsValue之前先填充treeData,否则Tree组件可能会报key not exist警告
if (unref(treeData).length === 0) {
treeData.value = (await getMenuList()) as any as TreeItem[];
}
isUpdate.value = !!data?.isUpdate;
if (unref(isUpdate)) {
......@@ -57,7 +41,7 @@
}
});
const getTitle = computed(() => (!unref(isUpdate) ? '新增角色' : '编辑角色'));
const getTitle = computed(() => (!unref(isUpdate) ? '新增项目' : '编辑项目'));
async function handleSubmit() {
try {
......@@ -65,6 +49,9 @@
setDrawerProps({ confirmLoading: true });
// TODO custom api
console.log(values);
let res = isUpdate.value ? await updateProjectItem(values) : await addProjectItem(values);
console.log(res);
closeDrawer();
emit('success');
} finally {
......
<template>
<div>
<BasicTable @register="registerTable">
<BasicTable @register="registerTable" :title="'房产档案列表'">
<template #toolbar>
<a-button type="primary" @click="handleCreate"> 新增项目 </a-button>
</template>
......@@ -26,7 +26,7 @@
</template>
</template>
</BasicTable>
<RoleDrawer @register="registerDrawer" @success="handleSuccess" />
<ProjectDrawer @register="registerDrawer" @success="handleSuccess" />
</div>
</template>
<script lang="ts" setup>
......@@ -34,7 +34,7 @@
import { getProjectListByPage } from '@/api/project/project';
import { useDrawer } from '@/components/Drawer';
import RoleDrawer from './RoleDrawer.vue';
import ProjectDrawer from './ProjectDrawer.vue';
import { columns, searchFormSchema } from './project.data';
......@@ -42,15 +42,15 @@
const [registerDrawer, { openDrawer }] = useDrawer();
const [registerTable, { reload }] = useTable({
title: '项目列表',
api: getProjectListByPage,
title: '123',
columns,
formConfig: {
labelWidth: 120,
schemas: searchFormSchema,
},
useSearchForm: true,
showTableSetting: true,
showTableSetting: false,
bordered: true,
showIndexColumn: false,
actionColumn: {
......
......@@ -46,9 +46,21 @@ export const columns: BasicColumn[] = [
export const searchFormSchema: FormSchema[] = [
{
field: 'ProjecName',
label: '项目名称',
label: '',
component: 'Input',
colProps: { span: 8 },
componentProps: {
placeholder: '点击选择图标',
},
colProps: { span: 4 },
},
{
field: 'ProjecName',
label: '',
component: 'Input',
componentProps: {
placeholder: '点击选择图标',
},
colProps: { span: 4 },
},
// {
// field: 'status',
......@@ -66,37 +78,56 @@ export const searchFormSchema: FormSchema[] = [
export const formSchema: FormSchema[] = [
{
field: 'roleName',
label: '角色名称',
required: true,
component: 'Input',
},
{
field: 'roleValue',
label: '角色值',
field: 'projectName',
label: '项目名称',
required: true,
component: 'Input',
},
{
field: 'status',
label: '状态',
field: 'isReserveProject',
label: '是否为储备项目',
component: 'RadioButtonGroup',
defaultValue: '0',
componentProps: {
options: [
{ label: '启用', value: '1' },
{ label: '停用', value: '0' },
{ label: '', value: '1' },
{ label: '', value: '0' },
],
},
},
// {
// field: 'status',
// label: '状态',
// component: 'RadioButtonGroup',
// defaultValue: '0',
// componentProps: {
// options: [
// { label: '启用', value: '1' },
// { label: '停用', value: '0' },
// ],
// },
// },
{
label: '建设模式',
field: 'constructionMode',
component: 'InputTextArea',
},
{
label: '项目类型',
field: 'projectType',
required: true,
component: 'Input',
},
{
label: '备注',
field: 'remark',
label: '项目概况',
field: 'projectOverview',
required: true,
component: 'InputTextArea',
},
{
label: ' ',
field: 'menu',
slot: 'menu',
label: '建设目的及项目功能',
field: 'constructionPurpose',
required: true,
component: 'InputTextArea',
},
];
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment