mirror of
https://github.com/YunaiV/ruoyi-vue-pro.git
synced 2026-04-19 13:28:38 +00:00
feat:【infra】移动端 admin uniapp 的代码生成的初始化
This commit is contained in:
@@ -23,6 +23,8 @@ public enum CodegenFrontTypeEnum {
|
|||||||
|
|
||||||
VUE3_VBEN5_EP_SCHEMA(50), // Vue3 VBEN5 + EP + schema 模版
|
VUE3_VBEN5_EP_SCHEMA(50), // Vue3 VBEN5 + EP + schema 模版
|
||||||
VUE3_VBEN5_EP_GENERAL(51), // Vue3 VBEN5 + EP 标准模版
|
VUE3_VBEN5_EP_GENERAL(51), // Vue3 VBEN5 + EP 标准模版
|
||||||
|
|
||||||
|
VUE3_ADMIN_UNIAPP_WOT(60), // Vue3 Admin + Uniapp + WOT 标准模版
|
||||||
;
|
;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -137,6 +137,16 @@ public class CodegenEngine {
|
|||||||
vue3FilePath("views/${table.moduleName}/${table.businessName}/components/${subSimpleClassName}List.vue"))
|
vue3FilePath("views/${table.moduleName}/${table.businessName}/components/${subSimpleClassName}List.vue"))
|
||||||
.put(CodegenFrontTypeEnum.VUE3_ELEMENT_PLUS.getType(), vue3TemplatePath("api/api.ts"),
|
.put(CodegenFrontTypeEnum.VUE3_ELEMENT_PLUS.getType(), vue3TemplatePath("api/api.ts"),
|
||||||
vue3FilePath("api/${table.moduleName}/${table.businessName}/index.ts"))
|
vue3FilePath("api/${table.moduleName}/${table.businessName}/index.ts"))
|
||||||
|
.put(CodegenFrontTypeEnum.VUE3_ADMIN_UNIAPP_WOT.getType(), vue3AdminUniappTemplatePath("api/api.ts"),
|
||||||
|
vue3UniappFilePath("api/${table.moduleName}/${table.businessName}/index.ts"))
|
||||||
|
.put(CodegenFrontTypeEnum.VUE3_ADMIN_UNIAPP_WOT.getType(), vue3AdminUniappTemplatePath("views/index.vue"),
|
||||||
|
vue3UniappFilePath("pages-${table.moduleName}/${table.businessName}/index.vue"))
|
||||||
|
.put(CodegenFrontTypeEnum.VUE3_ADMIN_UNIAPP_WOT.getType(), vue3AdminUniappTemplatePath("components/search-form.vue"),
|
||||||
|
vue3UniappFilePath("pages-${table.moduleName}/${table.businessName}/components/search-form.vue"))
|
||||||
|
.put(CodegenFrontTypeEnum.VUE3_ADMIN_UNIAPP_WOT.getType(), vue3AdminUniappTemplatePath("views/form/index.vue"),
|
||||||
|
vue3UniappFilePath("pages-${table.moduleName}/${table.businessName}/form/index.vue"))
|
||||||
|
.put(CodegenFrontTypeEnum.VUE3_ADMIN_UNIAPP_WOT.getType(), vue3AdminUniappTemplatePath("views/detail/index.vue"),
|
||||||
|
vue3UniappFilePath("pages-${table.moduleName}/${table.businessName}/detail/index.vue"))
|
||||||
// VUE3_VBEN2_ANTD_SCHEMA
|
// VUE3_VBEN2_ANTD_SCHEMA
|
||||||
.put(CodegenFrontTypeEnum.VUE3_VBEN2_ANTD_SCHEMA.getType(), vue3VbenTemplatePath("views/data.ts"),
|
.put(CodegenFrontTypeEnum.VUE3_VBEN2_ANTD_SCHEMA.getType(), vue3VbenTemplatePath("views/data.ts"),
|
||||||
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/${classNameVar}.data.ts"))
|
vue3VbenFilePath("views/${table.moduleName}/${table.businessName}/${classNameVar}.data.ts"))
|
||||||
@@ -617,6 +627,15 @@ public class CodegenEngine {
|
|||||||
"src/" + path;
|
"src/" + path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String vue3AdminUniappTemplatePath(String path) {
|
||||||
|
return "codegen/vue3_admin_uniapp/" + path + ".vm";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String vue3UniappFilePath(String path) {
|
||||||
|
return "yudao-ui-${sceneEnum.basePackage}-uniapp/" + // 顶级目录
|
||||||
|
"src/" + path;
|
||||||
|
}
|
||||||
|
|
||||||
private static String vue3VbenFilePath(String path) {
|
private static String vue3VbenFilePath(String path) {
|
||||||
return "yudao-ui-${sceneEnum.basePackage}-vben/" + // 顶级目录
|
return "yudao-ui-${sceneEnum.basePackage}-vben/" + // 顶级目录
|
||||||
"src/" + path;
|
"src/" + path;
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
import type { PageParam, PageResult } from '@/http/types'
|
||||||
|
import { http } from '@/http/http'
|
||||||
|
|
||||||
|
// TODO @AI:不使用 baseUrl,而是参考之前的,直接写在每个方法里。
|
||||||
|
#set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")
|
||||||
|
const baseUrl = '${baseURL}'
|
||||||
|
|
||||||
|
#set ($primaryJavaType = $primaryColumn.javaType.toLowerCase())
|
||||||
|
#if(${primaryJavaType} == "long" || ${primaryJavaType} == "integer" || ${primaryJavaType} == "short" || ${primaryJavaType} == "double" || ${primaryJavaType} == "bigdecimal" || ${primaryJavaType} == "byte")
|
||||||
|
#set ($primaryTsType = "number")
|
||||||
|
#else
|
||||||
|
#set ($primaryTsType = "string")
|
||||||
|
#end
|
||||||
|
|
||||||
|
/** ${table.classComment}信息 */
|
||||||
|
export interface ${simpleClassName} {
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if ($column.primaryKey || $column.createOperation || $column.updateOperation || $column.listOperationResult)
|
||||||
|
#set ($javaType = $column.javaType.toLowerCase())
|
||||||
|
#set ($optional = $column.nullable || $column.primaryKey)
|
||||||
|
#if(${javaType} == "long" || ${javaType} == "integer" || ${javaType} == "short" || ${javaType} == "double" || ${javaType} == "bigdecimal" || ${javaType} == "byte")
|
||||||
|
${column.javaField}#if($optional)?#end: number
|
||||||
|
#elseif(${javaType} == "boolean")
|
||||||
|
${column.javaField}#if($optional)?#end: boolean
|
||||||
|
#else
|
||||||
|
${column.javaField}#if($optional)?#end: string
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 获取${table.classComment}分页列表 */
|
||||||
|
export function get${simpleClassName}Page(params: PageParam) {
|
||||||
|
return http.get<PageResult<${simpleClassName}>>(baseUrl + '/page', params)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 获取${table.classComment}详情 */
|
||||||
|
export function get${simpleClassName}(id: ${primaryTsType}) {
|
||||||
|
return http.get<${simpleClassName}>(baseUrl + '/get?id=' + id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 创建${table.classComment} */
|
||||||
|
export function create${simpleClassName}(data: ${simpleClassName}) {
|
||||||
|
return http.post<number>(baseUrl + '/create', data)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 更新${table.classComment} */
|
||||||
|
export function update${simpleClassName}(data: ${simpleClassName}) {
|
||||||
|
return http.put<boolean>(baseUrl + '/update', data)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除${table.classComment} */
|
||||||
|
export function delete${simpleClassName}(id: ${primaryTsType}) {
|
||||||
|
return http.delete<boolean>(baseUrl + '/delete?id=' + id)
|
||||||
|
}
|
||||||
@@ -0,0 +1,257 @@
|
|||||||
|
<template>
|
||||||
|
<wd-search
|
||||||
|
:placeholder="searchPlaceholder"
|
||||||
|
:hide-cancel="true"
|
||||||
|
disabled
|
||||||
|
@click="visible = true"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<wd-popup
|
||||||
|
v-model="visible"
|
||||||
|
position="top"
|
||||||
|
custom-style="border-radius: 0 0 24rpx 24rpx;"
|
||||||
|
safe-area-inset-top
|
||||||
|
@close="visible = false"
|
||||||
|
>
|
||||||
|
<view class="p-32rpx">
|
||||||
|
<view class="mb-24rpx text-32rpx text-[#333] font-semibold">
|
||||||
|
搜索${table.classComment}
|
||||||
|
</view>
|
||||||
|
|
||||||
|
#set ($hasDict = 0)
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if ($hasDict == 0 && $column.listOperation && $column.dictType && "" != $column.dictType)
|
||||||
|
#set ($hasDict = 1)
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if ($column.listOperation)
|
||||||
|
#set ($dictType = $column.dictType)
|
||||||
|
#set ($javaField = $column.javaField)
|
||||||
|
#set ($javaType = $column.javaType)
|
||||||
|
#set ($comment = $column.columnComment)
|
||||||
|
#set ($dictMethod = "getDictOptions")
|
||||||
|
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||||
|
#set ($dictMethod = "getIntDictOptions")
|
||||||
|
#elseif ($javaType == "String")
|
||||||
|
#set ($dictMethod = "getStrDictOptions")
|
||||||
|
#elseif ($javaType == "Boolean")
|
||||||
|
#set ($dictMethod = "getBoolDictOptions")
|
||||||
|
#end
|
||||||
|
|
||||||
|
#if ($column.htmlType == "input")
|
||||||
|
<view class="mb-24rpx">
|
||||||
|
<view class="mb-12rpx text-28rpx text-[#666]">
|
||||||
|
${comment}
|
||||||
|
</view>
|
||||||
|
<wd-input
|
||||||
|
v-model="formData.${javaField}"
|
||||||
|
placeholder="请输入${comment}"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
#elseif (($column.htmlType == "select" || $column.htmlType == "radio") && $dictType && "" != $dictType)
|
||||||
|
<view class="mb-32rpx">
|
||||||
|
<view class="mb-12rpx text-28rpx text-[#666]">
|
||||||
|
${comment}
|
||||||
|
</view>
|
||||||
|
<wd-radio-group v-model="formData.${javaField}" shape="button" size="medium">
|
||||||
|
<wd-radio :value="-1">
|
||||||
|
全部
|
||||||
|
</wd-radio>
|
||||||
|
<wd-radio
|
||||||
|
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||||
|
:key="dict.value"
|
||||||
|
:value="dict.value"
|
||||||
|
>
|
||||||
|
{{ dict.label }}
|
||||||
|
</wd-radio>
|
||||||
|
</wd-radio-group>
|
||||||
|
</view>
|
||||||
|
#else
|
||||||
|
<view class="mb-24rpx">
|
||||||
|
<view class="mb-12rpx text-28rpx text-[#666]">
|
||||||
|
${comment}
|
||||||
|
</view>
|
||||||
|
<wd-input
|
||||||
|
v-model="formData.${javaField}"
|
||||||
|
placeholder="请输入${comment}"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
|
||||||
|
<view class="w-full flex justify-center gap-24rpx">
|
||||||
|
<wd-button class="flex-1" plain @click="handleReset">
|
||||||
|
重置
|
||||||
|
</wd-button>
|
||||||
|
<wd-button class="flex-1" type="primary" @click="handleSearch">
|
||||||
|
搜索
|
||||||
|
</wd-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</wd-popup>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { computed, reactive, ref, watch } from 'vue'
|
||||||
|
|
||||||
|
#set ($hasDict = 0)
|
||||||
|
#set ($hasGetDictOptions = 0)
|
||||||
|
#set ($hasGetIntDictOptions = 0)
|
||||||
|
#set ($hasGetStrDictOptions = 0)
|
||||||
|
#set ($hasGetBoolDictOptions = 0)
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if ($column.listOperation && $column.dictType && "" != $column.dictType)
|
||||||
|
#set ($hasDict = 1)
|
||||||
|
#if ($column.htmlType == "select" || $column.htmlType == "radio")
|
||||||
|
#if ($column.javaType == "Integer" || $column.javaType == "Long" || $column.javaType == "Byte" || $column.javaType == "Short")
|
||||||
|
#set ($hasGetIntDictOptions = 1)
|
||||||
|
#elseif ($column.javaType == "String")
|
||||||
|
#set ($hasGetStrDictOptions = 1)
|
||||||
|
#elseif ($column.javaType == "Boolean")
|
||||||
|
#set ($hasGetBoolDictOptions = 1)
|
||||||
|
#else
|
||||||
|
#set ($hasGetDictOptions = 1)
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#if ($hasDict == 1)
|
||||||
|
import { DICT_TYPE } from '@/utils/constants'
|
||||||
|
import {
|
||||||
|
#if ($hasGetDictOptions == 1)
|
||||||
|
getDictOptions,
|
||||||
|
#end
|
||||||
|
#if ($hasGetIntDictOptions == 1)
|
||||||
|
getIntDictOptions,
|
||||||
|
#end
|
||||||
|
#if ($hasGetStrDictOptions == 1)
|
||||||
|
getStrDictOptions,
|
||||||
|
#end
|
||||||
|
#if ($hasGetBoolDictOptions == 1)
|
||||||
|
getBoolDictOptions,
|
||||||
|
#end
|
||||||
|
getDictLabel,
|
||||||
|
} from '@/hooks/useDict'
|
||||||
|
#end
|
||||||
|
|
||||||
|
/** 搜索表单数据 */
|
||||||
|
export interface SearchFormData {
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if ($column.listOperation)
|
||||||
|
#set ($javaType = $column.javaType.toLowerCase())
|
||||||
|
#if ($column.dictType && "" != $column.dictType)
|
||||||
|
#if(${javaType} == "string")
|
||||||
|
${column.javaField}?: string | number
|
||||||
|
#elseif(${javaType} == "boolean")
|
||||||
|
${column.javaField}?: boolean | number
|
||||||
|
#else
|
||||||
|
${column.javaField}?: number
|
||||||
|
#end
|
||||||
|
#elseif(${javaType} == "long" || ${javaType} == "integer" || ${javaType} == "short" || ${javaType} == "double" || ${javaType} == "bigdecimal" || ${javaType} == "byte")
|
||||||
|
${column.javaField}?: number
|
||||||
|
#elseif(${javaType} == "boolean")
|
||||||
|
${column.javaField}?: boolean
|
||||||
|
#else
|
||||||
|
${column.javaField}?: string
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
searchParams?: Partial<SearchFormData>
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
search: [data: SearchFormData]
|
||||||
|
reset: []
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const visible = ref(false)
|
||||||
|
|
||||||
|
/** 搜索条件 placeholder 拼接 */
|
||||||
|
const searchPlaceholder = computed(() => {
|
||||||
|
const conditions: string[] = []
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if ($column.listOperation)
|
||||||
|
#set ($dictType = $column.dictType)
|
||||||
|
#set ($javaField = $column.javaField)
|
||||||
|
#set ($javaType = $column.javaType.toLowerCase())
|
||||||
|
#set ($comment = $column.columnComment)
|
||||||
|
#if ($dictType && "" != $dictType)
|
||||||
|
if (props.searchParams?.${javaField} !== undefined && props.searchParams.${javaField} !== -1) {
|
||||||
|
conditions.push('${comment}:' + getDictLabel(DICT_TYPE.$dictType.toUpperCase(), props.searchParams.${javaField}))
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#if(${javaType} == "long" || ${javaType} == "integer" || ${javaType} == "short" || ${javaType} == "double" || ${javaType} == "bigdecimal" || ${javaType} == "byte" || ${javaType} == "boolean")
|
||||||
|
if (props.searchParams?.${javaField} !== undefined) {
|
||||||
|
conditions.push('${comment}:' + props.searchParams.${javaField})
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (props.searchParams?.${javaField}) {
|
||||||
|
conditions.push('${comment}:' + props.searchParams.${javaField})
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
return conditions.length > 0 ? conditions.join(' | ') : '搜索${table.classComment}'
|
||||||
|
})
|
||||||
|
|
||||||
|
const formData = reactive<SearchFormData>({
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if ($column.listOperation)
|
||||||
|
#if ($column.dictType && "" != $column.dictType)
|
||||||
|
#set ($javaType = $column.javaType.toLowerCase())
|
||||||
|
#if(${javaType} == "string")
|
||||||
|
${column.javaField}: -1 as number | string,
|
||||||
|
#elseif(${javaType} == "boolean")
|
||||||
|
${column.javaField}: -1 as number | boolean,
|
||||||
|
#else
|
||||||
|
${column.javaField}: -1 as number,
|
||||||
|
#end
|
||||||
|
#else
|
||||||
|
${column.javaField}: undefined,
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(visible, (val) => {
|
||||||
|
if (val && props.searchParams) {
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if ($column.listOperation)
|
||||||
|
#if ($column.dictType && "" != $column.dictType)
|
||||||
|
formData.${column.javaField} = props.searchParams.${column.javaField} ?? -1
|
||||||
|
#else
|
||||||
|
formData.${column.javaField} = props.searchParams.${column.javaField}
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function handleSearch() {
|
||||||
|
visible.value = false
|
||||||
|
emit('search', { ...formData } as SearchFormData)
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleReset() {
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if ($column.listOperation)
|
||||||
|
#if ($column.dictType && "" != $column.dictType)
|
||||||
|
formData.${column.javaField} = -1
|
||||||
|
#else
|
||||||
|
formData.${column.javaField} = undefined
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
visible.value = false
|
||||||
|
emit('reset')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
<template>
|
||||||
|
<view class="page-container">
|
||||||
|
<wd-navbar
|
||||||
|
title="${table.classComment}详情"
|
||||||
|
left-arrow placeholder safe-area-inset-top fixed
|
||||||
|
@click-left="handleBack"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<view>
|
||||||
|
<wd-cell-group border>
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if ($column.primaryKey || $column.listOperationResult || $column.createOperation || $column.updateOperation)
|
||||||
|
#set ($javaField = $column.javaField)
|
||||||
|
#set ($comment = $column.columnComment)
|
||||||
|
#if ($column.dictType && "" != $column.dictType)
|
||||||
|
<wd-cell title="${comment}">
|
||||||
|
<dict-tag :type="DICT_TYPE.${column.dictType.toUpperCase()}" :value="formData?.${javaField}" />
|
||||||
|
</wd-cell>
|
||||||
|
#elseif ($column.javaType == "LocalDateTime")
|
||||||
|
<wd-cell title="${comment}" :value="formatDateTime(formData?.${javaField}) || '-'" />
|
||||||
|
#else
|
||||||
|
<wd-cell title="${comment}" :value="String(formData?.${javaField} ?? '-')" />
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
</wd-cell-group>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="fixed bottom-0 left-0 right-0 bg-white p-24rpx">
|
||||||
|
<view class="w-full flex gap-24rpx">
|
||||||
|
<wd-button
|
||||||
|
v-if="hasAccessByCodes(['${permissionPrefix}:update'])"
|
||||||
|
class="flex-1" type="warning" @click="handleEdit"
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</wd-button>
|
||||||
|
<wd-button
|
||||||
|
v-if="hasAccessByCodes(['${permissionPrefix}:delete'])"
|
||||||
|
class="flex-1" type="error" :loading="deleting" @click="handleDelete"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</wd-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { ${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}'
|
||||||
|
import { onMounted, ref } from 'vue'
|
||||||
|
import { useToast } from 'wot-design-uni'
|
||||||
|
import { delete${simpleClassName}, get${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}'
|
||||||
|
import { useAccess } from '@/hooks/useAccess'
|
||||||
|
import { navigateBackPlus } from '@/utils'
|
||||||
|
#set ($hasDict = 0)
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if ($hasDict == 0 && $column.dictType && "" != $column.dictType)
|
||||||
|
#set ($hasDict = 1)
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#if ($hasDict == 1)
|
||||||
|
import { DICT_TYPE } from '@/utils/constants'
|
||||||
|
#end
|
||||||
|
#set ($hasDateTime = 0)
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if ($hasDateTime == 0 && $column.javaType == "LocalDateTime")
|
||||||
|
#set ($hasDateTime = 1)
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#if ($hasDateTime == 1)
|
||||||
|
import { formatDateTime } from '@/utils/date'
|
||||||
|
#end
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
id?: number | any
|
||||||
|
}>()
|
||||||
|
|
||||||
|
definePage({
|
||||||
|
style: {
|
||||||
|
navigationBarTitleText: '',
|
||||||
|
navigationStyle: 'custom',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const { hasAccessByCodes } = useAccess()
|
||||||
|
const toast = useToast()
|
||||||
|
const formData = ref<${simpleClassName}>()
|
||||||
|
const deleting = ref(false)
|
||||||
|
|
||||||
|
function handleBack() {
|
||||||
|
navigateBackPlus('/pages-${table.moduleName}/${table.businessName}/index')
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getDetail() {
|
||||||
|
if (!props.id) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
toast.loading('加载中...')
|
||||||
|
formData.value = await get${simpleClassName}(props.id)
|
||||||
|
} finally {
|
||||||
|
toast.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleEdit() {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages-${table.moduleName}/${table.businessName}/form/index?id=' + props.id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDelete() {
|
||||||
|
if (!props.id) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
uni.showModal({
|
||||||
|
title: '提示',
|
||||||
|
content: '确定要删除该${table.classComment}吗?',
|
||||||
|
success: async (res) => {
|
||||||
|
if (!res.confirm) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
deleting.value = true
|
||||||
|
try {
|
||||||
|
await delete${simpleClassName}(props.id)
|
||||||
|
toast.success('删除成功')
|
||||||
|
setTimeout(() => {
|
||||||
|
handleBack()
|
||||||
|
}, 500)
|
||||||
|
} finally {
|
||||||
|
deleting.value = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getDetail()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,225 @@
|
|||||||
|
<template>
|
||||||
|
<view class="page-container">
|
||||||
|
<wd-navbar
|
||||||
|
:title="getTitle"
|
||||||
|
left-arrow placeholder safe-area-inset-top fixed
|
||||||
|
@click-left="handleBack"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<view>
|
||||||
|
<wd-form ref="formRef" :model="formData" :rules="formRules">
|
||||||
|
<wd-cell-group border>
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if (($column.createOperation || $column.updateOperation) && !$column.primaryKey)
|
||||||
|
#set ($dictType = $column.dictType)
|
||||||
|
#set ($javaField = $column.javaField)
|
||||||
|
#set ($javaType = $column.javaType)
|
||||||
|
#set ($comment = $column.columnComment)
|
||||||
|
#set ($dictMethod = "getDictOptions")
|
||||||
|
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||||
|
#set ($dictMethod = "getIntDictOptions")
|
||||||
|
#elseif ($javaType == "String")
|
||||||
|
#set ($dictMethod = "getStrDictOptions")
|
||||||
|
#elseif ($javaType == "Boolean")
|
||||||
|
#set ($dictMethod = "getBoolDictOptions")
|
||||||
|
#end
|
||||||
|
|
||||||
|
#if (${javaType.toLowerCase()} == "long" || ${javaType.toLowerCase()} == "integer" || ${javaType.toLowerCase()} == "short" || ${javaType.toLowerCase()} == "double" || ${javaType.toLowerCase()} == "bigdecimal" || ${javaType.toLowerCase()} == "byte")
|
||||||
|
<wd-cell title="${comment}" title-width="180rpx" prop="${javaField}" center>
|
||||||
|
<wd-input-number
|
||||||
|
v-model="formData.${javaField}"
|
||||||
|
:min="0"
|
||||||
|
/>
|
||||||
|
</wd-cell>
|
||||||
|
#elseif (${javaType.toLowerCase()} == "boolean")
|
||||||
|
<wd-cell title="${comment}" title-width="180rpx" prop="${javaField}" center>
|
||||||
|
<wd-switch v-model="formData.${javaField}" />
|
||||||
|
</wd-cell>
|
||||||
|
#elseif ($column.htmlType == "textarea")
|
||||||
|
<wd-textarea
|
||||||
|
v-model="formData.${javaField}"
|
||||||
|
label="${comment}"
|
||||||
|
label-width="180rpx"
|
||||||
|
placeholder="请输入${comment}"
|
||||||
|
:maxlength="200"
|
||||||
|
show-word-limit
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
#elseif (($column.htmlType == "select" || $column.htmlType == "radio") && $dictType && "" != $dictType)
|
||||||
|
<wd-cell title="${comment}" title-width="180rpx" prop="${javaField}" center>
|
||||||
|
<wd-radio-group v-model="formData.${javaField}" shape="button" size="medium">
|
||||||
|
<wd-radio
|
||||||
|
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||||
|
:key="dict.value"
|
||||||
|
:value="dict.value"
|
||||||
|
>
|
||||||
|
{{ dict.label }}
|
||||||
|
</wd-radio>
|
||||||
|
</wd-radio-group>
|
||||||
|
</wd-cell>
|
||||||
|
#else
|
||||||
|
<wd-input
|
||||||
|
v-model="formData.${javaField}"
|
||||||
|
label="${comment}"
|
||||||
|
label-width="180rpx"
|
||||||
|
prop="${javaField}"
|
||||||
|
clearable
|
||||||
|
placeholder="请输入${comment}"
|
||||||
|
/>
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
</wd-cell-group>
|
||||||
|
</wd-form>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="fixed bottom-0 left-0 right-0 bg-white p-24rpx">
|
||||||
|
<wd-button
|
||||||
|
type="primary"
|
||||||
|
block
|
||||||
|
:loading="formLoading"
|
||||||
|
@click="handleSubmit"
|
||||||
|
>
|
||||||
|
保存
|
||||||
|
</wd-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { ${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}'
|
||||||
|
import { computed, onMounted, ref } from 'vue'
|
||||||
|
import { useToast } from 'wot-design-uni'
|
||||||
|
import { create${simpleClassName}, get${simpleClassName}, update${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}'
|
||||||
|
import { navigateBackPlus } from '@/utils'
|
||||||
|
|
||||||
|
#set ($primaryJavaType = $primaryColumn.javaType.toLowerCase())
|
||||||
|
#if(${primaryJavaType} == "long" || ${primaryJavaType} == "integer" || ${primaryJavaType} == "short" || ${primaryJavaType} == "double" || ${primaryJavaType} == "bigdecimal" || ${primaryJavaType} == "byte")
|
||||||
|
#set ($primaryTsType = "number")
|
||||||
|
#else
|
||||||
|
#set ($primaryTsType = "string")
|
||||||
|
#end
|
||||||
|
|
||||||
|
#set ($hasDict = 0)
|
||||||
|
#set ($hasGetDictOptions = 0)
|
||||||
|
#set ($hasGetIntDictOptions = 0)
|
||||||
|
#set ($hasGetStrDictOptions = 0)
|
||||||
|
#set ($hasGetBoolDictOptions = 0)
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if (($column.createOperation || $column.updateOperation) && !$column.primaryKey
|
||||||
|
&& ($column.htmlType == "select" || $column.htmlType == "radio")
|
||||||
|
&& $column.dictType && "" != $column.dictType)
|
||||||
|
#set ($hasDict = 1)
|
||||||
|
#if ($column.javaType == "Integer" || $column.javaType == "Long" || $column.javaType == "Byte" || $column.javaType == "Short")
|
||||||
|
#set ($hasGetIntDictOptions = 1)
|
||||||
|
#elseif ($column.javaType == "String")
|
||||||
|
#set ($hasGetStrDictOptions = 1)
|
||||||
|
#elseif ($column.javaType == "Boolean")
|
||||||
|
#set ($hasGetBoolDictOptions = 1)
|
||||||
|
#else
|
||||||
|
#set ($hasGetDictOptions = 1)
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#if ($hasDict == 1)
|
||||||
|
import { DICT_TYPE } from '@/utils/constants'
|
||||||
|
import {
|
||||||
|
#if ($hasGetDictOptions == 1)
|
||||||
|
getDictOptions,
|
||||||
|
#end
|
||||||
|
#if ($hasGetIntDictOptions == 1)
|
||||||
|
getIntDictOptions,
|
||||||
|
#end
|
||||||
|
#if ($hasGetStrDictOptions == 1)
|
||||||
|
getStrDictOptions,
|
||||||
|
#end
|
||||||
|
#if ($hasGetBoolDictOptions == 1)
|
||||||
|
getBoolDictOptions,
|
||||||
|
#end
|
||||||
|
} from '@/hooks/useDict'
|
||||||
|
#end
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
id?: ${primaryTsType} | any
|
||||||
|
}>()
|
||||||
|
|
||||||
|
definePage({
|
||||||
|
style: {
|
||||||
|
navigationBarTitleText: '',
|
||||||
|
navigationStyle: 'custom',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const toast = useToast()
|
||||||
|
const getTitle = computed(() => props.id ? '编辑${table.classComment}' : '新增${table.classComment}')
|
||||||
|
const formLoading = ref(false)
|
||||||
|
|
||||||
|
// TODO @AI:date + 时间范围,需要特殊处理;参考 /Users/yunai/Java/yudao-ui-admin-uniapp-next-v4/src/pages/message/components/search-form.vue 里的开始结束时间的处理;注意,index.vue.vm 也要调整;
|
||||||
|
const formData = ref<${simpleClassName}>({
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if (($column.createOperation || $column.updateOperation) || $column.primaryKey)
|
||||||
|
#set ($javaType = $column.javaType.toLowerCase())
|
||||||
|
#if ($column.primaryKey)
|
||||||
|
${column.javaField}: undefined,
|
||||||
|
#elseif(${javaType} == "long" || ${javaType} == "integer" || ${javaType} == "short" || ${javaType} == "double" || ${javaType} == "bigdecimal" || ${javaType} == "byte")
|
||||||
|
${column.javaField}: 0,
|
||||||
|
#elseif(${javaType} == "boolean")
|
||||||
|
${column.javaField}: false,
|
||||||
|
#else
|
||||||
|
${column.javaField}: '',
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
})
|
||||||
|
|
||||||
|
const formRules = {
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !$column.primaryKey)
|
||||||
|
${column.javaField}: [{ required: true, message: '${column.columnComment}不能为空' }],
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
}
|
||||||
|
|
||||||
|
const formRef = ref()
|
||||||
|
|
||||||
|
function handleBack() {
|
||||||
|
navigateBackPlus('/pages-${table.moduleName}/${table.businessName}/index')
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getDetail() {
|
||||||
|
if (!props.id) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
formData.value = await get${simpleClassName}(props.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleSubmit() {
|
||||||
|
const { valid } = await formRef.value.validate()
|
||||||
|
if (!valid) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
if (props.id) {
|
||||||
|
await update${simpleClassName}(formData.value)
|
||||||
|
toast.success('修改成功')
|
||||||
|
} else {
|
||||||
|
await create${simpleClassName}(formData.value)
|
||||||
|
toast.success('新增成功')
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
handleBack()
|
||||||
|
}, 500)
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getDetail()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,220 @@
|
|||||||
|
<template>
|
||||||
|
<view class="page-container">
|
||||||
|
<!-- 顶部导航栏 -->
|
||||||
|
<wd-navbar
|
||||||
|
title="${table.classComment}管理"
|
||||||
|
left-arrow placeholder safe-area-inset-top fixed
|
||||||
|
@click-left="handleBack"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 搜索组件 -->
|
||||||
|
<SearchForm
|
||||||
|
:search-params="queryParams"
|
||||||
|
@search="handleQuery"
|
||||||
|
@reset="handleReset"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- ${table.classComment}列表 -->
|
||||||
|
<view class="p-24rpx">
|
||||||
|
<view
|
||||||
|
v-for="item in list"
|
||||||
|
:key="item.${primaryColumn.javaField}"
|
||||||
|
class="mb-24rpx overflow-hidden rounded-12rpx bg-white shadow-sm"
|
||||||
|
@click="handleDetail(item)"
|
||||||
|
>
|
||||||
|
<!-- TODO @AI:下面的 view 部分代码,缩进可能不太对; -->
|
||||||
|
<view class="p-24rpx">
|
||||||
|
#set ($titleField = "")
|
||||||
|
#set ($statusField = "")
|
||||||
|
#set ($statusDictType = "")
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if ($titleField == "" && !$column.primaryKey && $column.listOperationResult)
|
||||||
|
#set ($titleField = $column.javaField)
|
||||||
|
#set ($titleComment = $column.columnComment)
|
||||||
|
#end
|
||||||
|
#if ($statusField == "" && $column.listOperationResult && $column.dictType && "" != $column.dictType)
|
||||||
|
#set ($statusField = $column.javaField)
|
||||||
|
#set ($statusDictType = $column.dictType)
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
<view class="mb-16rpx flex items-center justify-between">
|
||||||
|
<view class="text-32rpx text-[#333] font-semibold">
|
||||||
|
{{ item.#if($titleField != "")${titleField}#else ${primaryColumn.javaField}#end }}
|
||||||
|
</view>
|
||||||
|
#if($statusField != "")
|
||||||
|
<dict-tag :type="DICT_TYPE.$statusDictType.toUpperCase()" :value="item.$statusField" />
|
||||||
|
#end
|
||||||
|
</view>
|
||||||
|
#set ($infoCount = 0)
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if ($column.listOperationResult && !$column.primaryKey && $column.javaField != $titleField && $column.javaField != $statusField)
|
||||||
|
#if ($infoCount < 2)
|
||||||
|
<view class="mb-12rpx flex items-center text-28rpx text-[#666]">
|
||||||
|
<text class="mr-8rpx text-[#999]">${column.columnComment}:</text>
|
||||||
|
<text class="line-clamp-1">{{ item.${column.javaField} }}</text>
|
||||||
|
</view>
|
||||||
|
#set ($infoCount = $infoCount + 1)
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 加载更多 -->
|
||||||
|
<view v-if="loadMoreState !== 'loading' && list.length === 0" class="py-100rpx text-center">
|
||||||
|
<wd-status-tip image="content" tip="暂无${table.classComment}数据" />
|
||||||
|
</view>
|
||||||
|
<wd-loadmore
|
||||||
|
v-if="list.length > 0"
|
||||||
|
:state="loadMoreState"
|
||||||
|
@reload="loadMore"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 新增按钮 -->
|
||||||
|
<wd-fab
|
||||||
|
v-if="hasAccessByCodes(['${permissionPrefix}:create'])"
|
||||||
|
position="right-bottom"
|
||||||
|
type="primary"
|
||||||
|
:expandable="false"
|
||||||
|
@click="handleAdd"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { SearchFormData } from './components/search-form.vue'
|
||||||
|
import type { ${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}'
|
||||||
|
import type { LoadMoreState } from '@/http/types'
|
||||||
|
import { onReachBottom } from '@dcloudio/uni-app'
|
||||||
|
import { onMounted, reactive, ref } from 'vue'
|
||||||
|
import { get${simpleClassName}Page } from '@/api/${table.moduleName}/${table.businessName}'
|
||||||
|
import { useAccess } from '@/hooks/useAccess'
|
||||||
|
import { navigateBackPlus } from '@/utils'
|
||||||
|
import SearchForm from './components/search-form.vue'
|
||||||
|
#set ($hasDict = 0)
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if ($hasDict == 0 && $column.listOperationResult && $column.dictType && "" != $column.dictType)
|
||||||
|
#set ($hasDict = 1)
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#if ($hasDict == 1)
|
||||||
|
import { DICT_TYPE } from '@/utils/constants'
|
||||||
|
#end
|
||||||
|
|
||||||
|
definePage({
|
||||||
|
style: {
|
||||||
|
navigationBarTitleText: '',
|
||||||
|
navigationStyle: 'custom',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const { hasAccessByCodes } = useAccess()
|
||||||
|
const total = ref(0)
|
||||||
|
const list = ref<${simpleClassName}[]>([])
|
||||||
|
const loadMoreState = ref<LoadMoreState>('loading') // 加载更多状态
|
||||||
|
|
||||||
|
const queryParams = reactive({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if ($column.listOperation)
|
||||||
|
#set ($javaType = $column.javaType.toLowerCase())
|
||||||
|
#if ($column.dictType && "" != $column.dictType)
|
||||||
|
#if(${javaType} == "string")
|
||||||
|
${column.javaField}: -1 as number | string, // -1 表示全部
|
||||||
|
#elseif(${javaType} == "boolean")
|
||||||
|
${column.javaField}: -1 as number | boolean, // -1 表示全部
|
||||||
|
#else
|
||||||
|
${column.javaField}: -1 as number, // -1 表示全部
|
||||||
|
#end
|
||||||
|
#elseif(${javaType} == "long" || ${javaType} == "integer" || ${javaType} == "short" || ${javaType} == "double" || ${javaType} == "bigdecimal" || ${javaType} == "byte")
|
||||||
|
${column.javaField}: undefined as number | undefined,
|
||||||
|
#elseif(${javaType} == "boolean")
|
||||||
|
${column.javaField}: undefined as boolean | undefined,
|
||||||
|
#else
|
||||||
|
${column.javaField}: undefined as string | undefined,
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
})
|
||||||
|
|
||||||
|
/** 返回上一页 */
|
||||||
|
function handleBack() {
|
||||||
|
navigateBackPlus()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 查询${table.classComment}列表 */
|
||||||
|
async function getList() {
|
||||||
|
loadMoreState.value = 'loading'
|
||||||
|
try {
|
||||||
|
const data = await get${simpleClassName}Page({
|
||||||
|
...queryParams,
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if ($column.listOperation && $column.dictType && "" != $column.dictType)
|
||||||
|
${column.javaField}: queryParams.${column.javaField} === -1 ? undefined : queryParams.${column.javaField},
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
})
|
||||||
|
list.value = [...list.value, ...data.list]
|
||||||
|
total.value = data.total
|
||||||
|
loadMoreState.value = list.value.length >= total.value ? 'finished' : 'loading'
|
||||||
|
} catch {
|
||||||
|
queryParams.pageNo = queryParams.pageNo > 1 ? queryParams.pageNo - 1 : 1
|
||||||
|
loadMoreState.value = 'error'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
function handleQuery(data?: SearchFormData) {
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if ($column.listOperation)
|
||||||
|
queryParams.${column.javaField} = data?.${column.javaField}#if ($column.dictType && "" != $column.dictType) ?? -1#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
queryParams.pageNo = 1
|
||||||
|
list.value = []
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
function handleReset() {
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 加载更多 */
|
||||||
|
function loadMore() {
|
||||||
|
if (loadMoreState.value === 'finished') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
queryParams.pageNo++
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 新增${table.classComment} */
|
||||||
|
function handleAdd() {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages-${table.moduleName}/${table.businessName}/form/index',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 查看详情 */
|
||||||
|
function handleDetail(item: ${simpleClassName}) {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages-${table.moduleName}/${table.businessName}/detail/index?id=' + item.${primaryColumn.javaField},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 触底加载更多 */
|
||||||
|
onReachBottom(() => {
|
||||||
|
loadMore()
|
||||||
|
})
|
||||||
|
|
||||||
|
/** 初始化 */
|
||||||
|
onMounted(() => {
|
||||||
|
getList()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user