修改卡片模板.

This commit is contained in:
lijiahang
2023-10-07 18:55:24 +08:00
parent d0f0c9428e
commit 6d37fb51cf
16 changed files with 315 additions and 23 deletions

View File

@@ -100,6 +100,11 @@ public class Table {
*/
protected boolean enableRowSelection;
/**
* 使用卡片视图
*/
protected boolean enableCardView;
/**
* 生成的枚举文件
*/

View File

@@ -63,6 +63,16 @@ public class VueTemplate extends Template {
return this;
}
/**
* 启用卡片列表
*
* @return this
*/
public VueTemplate enableCardView() {
table.enableCardView = true;
return this;
}
/**
* 设置枚举
*

View File

@@ -23,6 +23,9 @@ import java.math.*;
@EqualsAndHashCode(callSuper = true)
@Schema(name = "${type}QueryRequest", description = "$!{table.comment} 查询请求对象")
public class ${type}QueryRequest extends PageRequest {
@Schema(description = "搜索")
private String searchValue;
#foreach($field in ${table.fields})
#if("$field.propertyType" == "String" && "$field.metaInfo.jdbcType" != "LONGVARCHAR")

View File

@@ -3,6 +3,7 @@ package ${package.ServiceImpl};
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.orion.lang.define.wrapper.DataGrid;
import com.orion.lang.utils.Strings;
#if($cacheMeta.enableCache)
import com.orion.ops.framework.common.constant.Const;
#end
@@ -262,10 +263,16 @@ public class ${table.serviceImplName} implements ${table.serviceName} {
* @return wrapper
*/
private LambdaQueryWrapper<${type}DO> buildQueryWrapper(${type}QueryRequest request) {
String searchValue = request.getSearchValue();
return ${typeLower}DAO.wrapper()
#foreach($field in ${table.fields})
.eq(${type}DO::get${field.capitalName}, request.get${field.capitalName}())#if(!$foreach.hasNext);#end
#end
#foreach($field in ${table.fields})
.eq(${type}DO::get${field.capitalName}, request.get${field.capitalName}())
#end
.and(Strings.isNotEmpty(searchValue), c -> c
#foreach($field in ${table.fields})
.eq(${type}DO::get${field.capitalName}, searchValue)
#end
);
}
}

View File

@@ -33,6 +33,7 @@ export interface ${vue.featureEntity}UpdateRequest extends ${vue.featureEntity}C
* ${table.comment}查询请求
*/
export interface ${vue.featureEntity}QueryRequest extends Pagination {
searchValue?: string;
#foreach($field in ${table.fields})
#if("$field.propertyType" == "String" || "$field.propertyType" == "Date")
${field.propertyName}?: string;

View File

@@ -0,0 +1,181 @@
<template>
<card-list v-model:searchValue="formModel.searchValue"
create-card-position="head"
:card-height="172"
:loading="loading"
:fieldConfig="fieldConfig"
:list="list"
:pagination="pagination"
:card-layout-cols="cardColLayout"
:filter-count="filterCount"
:add-permission="['${package.ModuleName}:${typeHyphen}:create']"
@add="emits('openAdd')"
@reset="reset"
@search="fetchTableData"
@page-change="fetchTableData">
<!-- 拓展操作 -->
<template #extra="{ record }">
<a-space>
<!-- 更多操作 -->
<a-dropdown trigger="hover">
<icon-more class="card-extra-icon" />
<template #content>
<!-- 修改 -->
<a-doption v-permission="['${package.ModuleName}:${typeHyphen}:update']"
@click="emits('openUpdate', record)">
<icon-edit />
修改
</a-doption>
<!-- 删除 -->
<a-doption v-permission="['${package.ModuleName}:${typeHyphen}:delete']"
class="span-red"
@click="deleteRow(record.id)">
<icon-delete />
删除
</a-doption>
</template>
</a-dropdown>
</a-space>
</template>
<!-- 过滤条件 -->
<template #filterContent>
<a-form :model="formModel"
class="modal-form"
size="small"
ref="formRef"
label-align="right"
:style="{ width: '300px' }"
:label-col-props="{ span: 6 }"
:wrapper-col-props="{ span: 18 }">
#foreach($field in ${table.fields})
<!-- $field.comment -->
<a-form-item field="${field.propertyName}" label="${field.comment}" label-col-flex="50px">
#if(${vue.enums.containsKey(${field.propertyName})})
<a-select v-model="formModel.${field.propertyName}"
:options="toOptions(${vue.enums.get(${field.propertyName}).className})"
placeholder="请选择${field.comment}"
allow-clear />
#else
#if("$field.propertyType" == "Integer" || "$field.propertyType" == "Long")
<a-input-number v-model="formModel.${field.propertyName}"
placeholder="请输入${field.comment}"
allow-clear
hide-button />
#elseif("$field.propertyType" == "Date")
<a-date-picker v-model="formModel.${field.propertyName}"
style="width: 100%"
placeholder="请选择${field.comment}"
show-time
allow-clear />
#else
<a-input v-model="formModel.${field.propertyName}" placeholder="请输入${field.comment}" allow-clear />
#end
#end
</a-form-item>
#end
</a-form>
</template>
</card-list>
</template>
<script lang="ts">
export default {
name: '${vue.module}-${vue.feature}-card-list'
};
</script>
<script setup lang="ts">
import { usePagination, useColLayout } from '@/types/card';
import { computed, reactive, ref } from 'vue';
import useLoading from '@/hooks/loading';
import { dataColor, objectTruthKeyCount, resetObject } from '@/utils';
import fieldConfig from '../types/card.fields';
import { deleteHost, getHostPage, HostQueryRequest, HostQueryResponse } from '@/api/asset/host';
import { Message } from '@arco-design/web-vue';
import { tagColor } from '@/views/asset/host/types/const';
import TagMultiSelector from '@/components/tag/tag-multi-selector.vue';
import useCopy from '@/hooks/copy';
const { copy } = useCopy();
const { loading, setLoading } = useLoading();
const cardColLayout = useColLayout();
const pagination = usePagination();
const list = ref<HostQueryResponse[]>([]);
const emits = defineEmits(['openAdd', 'openUpdate', 'openUpdateConfig']);
const formModel = reactive<HostQueryRequest>({
searchValue: undefined,
id: undefined,
name: undefined,
code: undefined,
address: undefined,
favorite: undefined,
tags: undefined,
extra: true
});
// 条件数量
const filterCount = computed(() => {
return objectTruthKeyCount(formModel, ['searchValue', 'extra']);
});
// 删除当前行
const deleteRow = async (id: number) => {
try {
setLoading(true);
// 调用删除接口
await deleteHost(id);
Message.success('删除成功');
// 重新加载数据
await fetchTableData();
} catch (e) {
} finally {
setLoading(false);
}
};
// 添加后回调
const addedCallback = () => {
fetchTableData();
};
// 更新后回调
const updatedCallback = () => {
fetchTableData();
};
defineExpose({
addedCallback, updatedCallback
});
// 重置条件
const reset = () => {
resetObject(formModel, ['extra']);
fetchTableData();
};
// 加载数据
const doFetchTableData = async (request: HostQueryRequest) => {
try {
setLoading(true);
const { data } = await getHostPage(request);
list.value = data.rows;
pagination.total = data.total;
pagination.current = request.page;
pagination.pageSize = request.limit;
} catch (e) {
} finally {
setLoading(false);
}
};
// 切换页码
const fetchTableData = (page = 1, limit = pagination.pageSize, form = formModel) => {
doFetchTableData({ page, limit, ...form });
};
fetchTableData();
</script>
<style scoped lang="less">
</style>

View File

@@ -133,13 +133,13 @@
<script lang="ts" setup>
import { reactive, ref } from 'vue';
import { batchDelete${vue.featureEntity}, delete${vue.featureEntity}, get${vue.featureEntity}Page, ${vue.featureEntity}QueryRequest, ${vue.featureEntity}QueryResponse } from '@/api/${vue.module}/${vue.feature}';
import { Message, PaginationProps } from '@arco-design/web-vue';
import { Message } from '@arco-design/web-vue';
import useLoading from '@/hooks/loading';
import columns from '../types/table.columns';
#if($vue.enableRowSelection)
import { defaultPagination, defaultRowSelection } from '@/types/table';
import { usePagination, useRowSelection } from '@/types/table';
#else
import { defaultPagination } from '@/types/table';
import { usePagination } from '@/types/table';
#end
import {} from '../types/const';
#if($vue.enums.isEmpty())
@@ -153,10 +153,10 @@
const { loading, setLoading } = useLoading();
const emits = defineEmits(['openAdd', 'openUpdate']);
const pagination = reactive(defaultPagination()) as PaginationProps;
const pagination = usePagination();
#if($vue.enableRowSelection)
const selectedKeys = ref<number[]>([]);
const rowSelection = reactive(defaultRowSelection());
const rowSelection = useRowSelection();
#end
const formModel = reactive<${vue.featureEntity}QueryRequest>({

View File

@@ -1,19 +1,32 @@
<template>
<div class="layout-container">
<!-- 表格 -->
#if($vue.enableCardView)
<!-- 列表-表格 -->
<${vue.feature}-table v-if="renderTable"
ref="table"
@openAdd="() =>#if($vue.enableDrawerForm) drawer#else modal#end.openAdd()"
@openUpdate="(e) =>#if($vue.enableDrawerForm) drawer#else modal#end.openUpdate(e)" />
<!-- 列表-卡片 -->
<${vue.feature}-card-list v-else
ref="card"
@openAdd="() =>#if($vue.enableDrawerForm) drawer#else modal#end.openAdd()"
@openUpdate="(e) =>#if($vue.enableDrawerForm) drawer#else modal#end.openUpdate(e)" />
#else
<!-- 表格-表格 -->
<${vue.feature}-table ref="table"
@openAdd="() =>#if($vue.enableDrawerForm) drawer#else modal#end.openAdd()"
@openUpdate="(e) =>#if($vue.enableDrawerForm) drawer#else modal#end.openUpdate(e)" />
#end
#if($vue.enableDrawerForm)
<!-- 添加修改模态框 -->
<${vue.feature}-form-drawer ref="drawer"
@added="() => table.addedCallback()"
@updated="() => table.updatedCallback()" />
@added="modalAddCallback"
@updated="modalAddCallback" />
#else
<!-- 添加修改模态框 -->
<${vue.feature}-form-modal ref="modal"
@added="() => table.addedCallback()"
@updated="() => table.updatedCallback()" />
@added="modalAddCallback"
@updated="modalAddCallback" />
#end
</div>
</template>
@@ -35,11 +48,45 @@
import { ref } from 'vue';
const table = ref();
#if($vue.enableCardView)
const card = ref();
#end
#if($vue.enableDrawerForm)
const drawer = ref();
#else
const modal = ref();
#end
#if($vue.enableCardView)
const appStore = useAppStore();
const renderTable = computed(() => appStore.${vue.featureEntityFirstLower}View === 'table');
#end
// 添加回调
const modalAddCallback = () => {
#if($vue.enableCardView)
if (renderTable.value) {
table.value.addedCallback();
} else {
card.value.addedCallback();
}
#else
table.value.addedCallback();
#end
};
// 修改回调
const modalUpdateCallback = () => {
#if($vue.enableCardView)
if (renderTable.value) {
table.value.updatedCallback();
} else {
card.value.updatedCallback();
}
#else
table.value.updatedCallback();
#end
};
</script>

View File

@@ -0,0 +1,22 @@
import { CardField, CardFieldConfig } from '@/types/card';
import { dateFormat } from '@/utils';
export const fieldConfig = {
rowGap: '10px',
labelSpan: 8,
fields: [
#foreach($field in ${table.fields}){
label: '${field.comment}',
dataIndex: '${field.propertyName}',
slotName: '${field.propertyName}',
#if(${field.propertyType} == 'String')
ellipsis: true,
#elseif(${field.propertyType} == 'Date')
render: ({ record }) => {
return record.${field.propertyName} && dateFormat(new Date(record.${field.propertyName}));
},
#end
}, #end
] as CardField[]
} as CardFieldConfig;
export default fieldConfig;

View File

@@ -22,6 +22,9 @@ import java.util.List;
@Schema(name = "HostQueryRequest", description = "主机 查询请求对象")
public class HostQueryRequest extends PageRequest {
@Schema(description = "搜索")
private String searchValue;
@Schema(description = "id")
private Long id;

View File

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.orion.lang.define.wrapper.DataGrid;
import com.orion.lang.utils.Booleans;
import com.orion.lang.utils.Strings;
import com.orion.lang.utils.collect.Lists;
import com.orion.ops.framework.common.constant.ErrorMessage;
import com.orion.ops.framework.common.utils.Valid;
@@ -249,11 +250,17 @@ public class HostServiceImpl implements HostService {
}
}
// 基础条件
String searchValue = request.getSearchValue();
LambdaQueryWrapper<HostDO> wrapper = hostDAO.wrapper()
.eq(HostDO::getId, request.getId())
.like(HostDO::getName, request.getName())
.like(HostDO::getCode, request.getCode())
.like(HostDO::getAddress, request.getAddress());
.like(HostDO::getAddress, request.getAddress())
.and(Strings.isNotEmpty(searchValue), c -> c
.like(HostDO::getName, searchValue)
.like(HostDO::getCode, searchValue)
.like(HostDO::getAddress, searchValue)
);
if (setIdList) {
wrapper.in(HostDO::getId, idList);
}

View File

@@ -163,10 +163,12 @@
]">
<slot :name="field.slotName" :record="item" :index="index" :key="item[key]">
<a-tooltip v-if="field.tooltip" :content="item[field.dataIndex]">
<span>{{ item[field.dataIndex] }}</span>
<span v-if="field.render" v-html="field.render({ record: item, index })" />
<span v-else>{{ item[field.dataIndex] }}</span>
</a-tooltip>
<template v-else>
<span>{{ item[field.dataIndex] }}</span>
<span v-if="field.render" v-html="field.render({ record: item, index })" />
<span v-else>{{ item[field.dataIndex] }}</span>
</template>
</slot>
</a-col>

View File

@@ -1,5 +1,5 @@
import { PaginationProps, ResponsiveValue } from '@arco-design/web-vue';
import { reactive } from 'vue';
import { reactive, VNodeChild } from 'vue';
/**
* 字段对齐方式
@@ -48,6 +48,10 @@ export interface CardField {
valueClass?: string;
ellipsis?: boolean;
tooltip?: boolean;
render?: (data: {
record: CardRecord;
index: number;
}) => VNodeChild;
}
/**

View File

@@ -59,7 +59,9 @@
配置
</a-doption>
<!-- 删除 -->
<a-doption class="span-red" @click="deleteRow(record.id)">
<a-doption v-permission="['asset:host:delete']"
class="span-red"
@click="deleteRow(record.id)">
<icon-delete />
删除
</a-doption>
@@ -111,7 +113,7 @@
<script lang="ts">
export default {
name: 'host-card-list'
name: 'asset-host-card-list'
};
</script>

View File

@@ -44,8 +44,7 @@
const appStore = useAppStore();
const cacheStore = useCacheStore();
// FIXME 临时
const renderTable = computed(() => appStore.hostView === 'card');
const renderTable = computed(() => appStore.hostView === 'table');
// 添加回调
const modalAddCallback = () => {
@@ -58,7 +57,6 @@
// 修改回调
const modalUpdateCallback = () => {
console.log(renderTable.value);
if (renderTable.value) {
table.value.updatedCallback();
} else {

View File

@@ -18,7 +18,7 @@ export const fieldConfig = {
label: '主机标签',
dataIndex: 'tags',
slotName: 'tags',
rowAlign: 'start'
rowAlign: 'start',
},
] as CardField[]
} as CardFieldConfig;