This commit is contained in:
zpc 2025-11-12 23:15:15 +08:00
parent af085658a2
commit 727d2fea87
19 changed files with 938 additions and 140 deletions

View File

@ -17,7 +17,10 @@ declare module 'vue' {
ACardGrid: typeof import('ant-design-vue/es')['CardGrid']
ACardMeta: typeof import('ant-design-vue/es')['CardMeta']
ACheckbox: typeof import('ant-design-vue/es')['Checkbox']
ACheckboxGroup: typeof import('ant-design-vue/es')['CheckboxGroup']
ACol: typeof import('ant-design-vue/es')['Col']
ACollapse: typeof import('ant-design-vue/es')['Collapse']
ACollapsePanel: typeof import('ant-design-vue/es')['CollapsePanel']
ADescriptions: typeof import('ant-design-vue/es')['Descriptions']
ADescriptionsItem: typeof import('ant-design-vue/es')['DescriptionsItem']
ADivider: typeof import('ant-design-vue/es')['Divider']
@ -25,7 +28,9 @@ declare module 'vue' {
ADropdown: typeof import('ant-design-vue/es')['Dropdown']
AForm: typeof import('ant-design-vue/es')['Form']
AFormItem: typeof import('ant-design-vue/es')['FormItem']
AImage: typeof import('ant-design-vue/es')['Image']
AInput: typeof import('ant-design-vue/es')['Input']
AInputNumber: typeof import('ant-design-vue/es')['InputNumber']
AInputPassword: typeof import('ant-design-vue/es')['InputPassword']
AInputSearch: typeof import('ant-design-vue/es')['InputSearch']
ALayout: typeof import('ant-design-vue/es')['Layout']
@ -43,6 +48,7 @@ declare module 'vue' {
ARadio: typeof import('ant-design-vue/es')['Radio']
ARadioButton: typeof import('ant-design-vue/es')['RadioButton']
ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
AResult: typeof import('ant-design-vue/es')['Result']
ARow: typeof import('ant-design-vue/es')['Row']
ASelect: typeof import('ant-design-vue/es')['Select']
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
@ -61,6 +67,8 @@ declare module 'vue' {
ATimeline: typeof import('ant-design-vue/es')['Timeline']
ATimelineItem: typeof import('ant-design-vue/es')['TimelineItem']
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
ATree: typeof import('ant-design-vue/es')['Tree']
ATreeSelect: typeof import('ant-design-vue/es')['TreeSelect']
ATypographyLink: typeof import('ant-design-vue/es')['TypographyLink']
BarChartTransverse: typeof import('./core/components/charts/BarChartTransverse.vue')['default']
ColumnSetting: typeof import('./core/components/curd/components/ColumnSetting.vue')['default']

View File

@ -1,42 +1,18 @@
<template>
<a-row :gutter="[16, 0]">
<a-col :xs="12" :sm="12" :md="12" :lg="12" :xl="12">
<a-input
v-model:value="props.modelValue"
placeholder="请选择或者输入图片Id"
@change="updateValue"
:rules="[{ required: true, message: '请输入', trigger: 'blur' }]"
/>
</a-col>
<a-col :xs="8" :sm="8" :md="8" :lg="8" :xl="8">
<a-select
v-model:value="value"
show-search
:default-active-first-option="false"
:show-arrow="false"
:filter-option="false"
:not-found-content="null"
:options="data"
@search="handleSearch"
@change="handleChange"
></a-select>
<a-col :xs="18" :sm="18" :md="18" :lg="18" :xl="18">
<a-input v-model:value="props.modelValue" placeholder="请输入图片地址" @change="updateValue"
:rules="[{ required: true, message: '请输入', trigger: 'blur' }]" />
</a-col>
<a-col :xs="4" :sm="4" :md="4" :lg="4" :xl="4">
<a-button type="primary" @click="fileupload">上传</a-button>
</a-col>
<a-col
:xs="24"
:sm="24"
:md="24"
:lg="24"
:xl="24"
style="margin-top: 10px"
>
<a-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" style="margin-top: 10px">
<a-collapse>
<a-collapse-panel key="1" header="预览图片">
<p>
<a-image :src="TImageConfigService.getImageUrl(props.modelValue)" />
<a-image :src="props.modelValue" />
</p>
</a-collapse-panel>
</a-collapse>
@ -49,11 +25,11 @@ import { ref } from "vue";
import type { SelectProps } from "ant-design-vue";
import AppDictionaryCache from "@/core/utils/AppDictionaryCache";
import type { SelectValue } from "ant-design-vue/lib/select";
import TImageConfigService from "@/services/apps/T_Image_Configs/TImageConfigService";
import Tools from "@/core/utils/Tools";
// 使 withDefaults
const props = defineProps<{
modelValue: number;
modelValue: string;
tenantId: string | undefined;
}>();
console.log(props.modelValue);
@ -73,18 +49,17 @@ const emits = defineEmits(["update:modelValue"]);
// update:modelValue
function updateValue(event: any) {
console.log(event);
emits("update:modelValue", event.target.value);
}
function updateValueNumber(event: number) {
function updateValueNumber(event: string) {
emits("update:modelValue", event);
}
async function fileupload() {
const response = await Tools.imageFileUpload(0, 0, "", props.tenantId);
const response = await Tools.imageFileUpload(0, 0, "", "");
console.log(response);
updateValueNumber(response.imageId);
updateValueNumber(response.imageUrl);
}
let timeout: any;
let currentValue = "";
@ -97,19 +72,19 @@ function fetch(value: string, callback: any) {
currentValue = value;
function fake() {
TImageConfigService.getImageList(value).then((res) => {
if (res.data != null) {
const data: any[] = [];
res.data.forEach((r: any) => {
data.push({
value: r.imageId,
label: "[" + r.imageId + "]" + r.name,
code: r.url,
});
});
callback(data);
}
});
// TImageConfigService.getImageList(value).then((res) => {
// if (res.data != null) {
// const data: any[] = [];
// res.data.forEach((r: any) => {
// data.push({
// value: r.imageId,
// label: "[" + r.imageId + "]" + r.name,
// code: r.url,
// });
// });
// callback(data);
// }
// });
}
timeout = setTimeout(fake, 300);
@ -121,7 +96,7 @@ const value = ref();
const handleSearch = (val: string) => {
fetch(val, (d: any[]) => (data.value = d));
};
const handleChange = (val: number) => {
const handleChange = (val: string) => {
console.log(val);
updateValueNumber(val);
// emits("update:modelValue", val);

View File

@ -1,57 +1,57 @@
import AppDictionaryImageCache from "./cache/AppDictionaryImageCache";
// import AppDictionaryImageCache from "./cache/AppDictionaryImageCache";
import { AbstractDictionaryCache } from "./cache/AbstractDictionaryCache";
import AppDictionaryTenantCache from "./cache/AppDictionaryTenantCache";
import AppDictionaryTypesCache from "./cache/AppDictionaryTypesCache";
import AppDictionaryPersonalitysCache from "./cache/AppDictionaryPersonalitysCache";
import AppDictionaryLablesCache from "./cache/AppDictionaryLablesCache";
import AppDictionaryActionTypeCache from "./cache/AppDictionaryActionTypeCache";
import AppDictionaryProductTypeCache from "./cache/AppDictionaryProductTypeCache";
import AppDictionaryCurrencyCache from "./cache/AppDictionaryCurrencyCache";
// import AppDictionaryTenantCache from "./cache/AppDictionaryTenantCache";
// import AppDictionaryTypesCache from "./cache/AppDictionaryTypesCache";
// import AppDictionaryPersonalitysCache from "./cache/AppDictionaryPersonalitysCache";
// import AppDictionaryLablesCache from "./cache/AppDictionaryLablesCache";
// import AppDictionaryActionTypeCache from "./cache/AppDictionaryActionTypeCache";
// import AppDictionaryProductTypeCache from "./cache/AppDictionaryProductTypeCache";
// import AppDictionaryCurrencyCache from "./cache/AppDictionaryCurrencyCache";
/**
*
*/
class AppDictionaryCache {
/**
*
*/
static appDictionaryImageCache: AbstractDictionaryCache = new AppDictionaryImageCache();
// /**
// * 图片类型
// */
// static appDictionaryImageCache: AbstractDictionaryCache = new AppDictionaryImageCache();
/**
*
*/
static appDictionaryTenantCache: AbstractDictionaryCache = new AppDictionaryTenantCache();
// /**
// * 多租户配置
// */
// static appDictionaryTenantCache: AbstractDictionaryCache = new AppDictionaryTenantCache();
/**
*
*/
static appDictionaryPersonalitysCache: AbstractDictionaryCache = new AppDictionaryPersonalitysCache();
// /**
// * 性格缓存
// */
// static appDictionaryPersonalitysCache: AbstractDictionaryCache = new AppDictionaryPersonalitysCache();
/**
*
*/
static appDictionaryTypesCache: AbstractDictionaryCache = new AppDictionaryTypesCache();
// /**
// * 类型配置
// */
// static appDictionaryTypesCache: AbstractDictionaryCache = new AppDictionaryTypesCache();
/**
*
*/
static appDictionaryLablesCache: AbstractDictionaryCache = new AppDictionaryLablesCache();
// /**
// * 标签配置
// */
// static appDictionaryLablesCache: AbstractDictionaryCache = new AppDictionaryLablesCache();
/**
*
*/
static appDictionaryActionTypeCache: AbstractDictionaryCache = new AppDictionaryActionTypeCache();
// /**
// * 动作类型
// */
// static appDictionaryActionTypeCache: AbstractDictionaryCache = new AppDictionaryActionTypeCache();
/**
* hm-product-type
*/
static appDictionaryProductTypeCache: AbstractDictionaryCache = new AppDictionaryProductTypeCache();
// /**
// * 产品类型 hm-product-type
// */
// static appDictionaryProductTypeCache: AbstractDictionaryCache = new AppDictionaryProductTypeCache();
/**
*
*/
static appDictionaryCurrencyCache: AbstractDictionaryCache = new AppDictionaryCurrencyCache();
// /**
// * 用户货币类型
// */
// static appDictionaryCurrencyCache: AbstractDictionaryCache = new AppDictionaryCurrencyCache();
}

View File

@ -431,7 +431,7 @@ class Tools {
const imageData = Object.assign({}, cosUploadFile, {
_cosData: cosTemporaryKey,
domainName: cosTemporaryKey.domainName,
imageUrl: cosTemporaryKey.domainName + _tempFilePaht,
imageUrl: "https://" + cosUploadFile.Location,
path: _tempFilePaht,
});
// cosUploadFile.DomainName=cosTemporaryKey.DomainName;
@ -528,8 +528,6 @@ class Tools {
if (imgaeId == undefined || imgaeId == null) {
imgaeId = 0;
}
AntdvMessage.success({ content: "上传成功", key, duration: 2 });
return { imageUrl: fileInfo.imageUrl };
} catch (error) {

View File

@ -1,6 +1,5 @@
import { AbstractDictionaryCache } from './AbstractDictionaryCache'
import { DefaultOptionType } from "ant-design-vue/es/select";
import T_Character_LabelService from "@/services/apps/T_Character_Labels/T_Character_LabelService";
/**
*
*/
@ -15,17 +14,7 @@ class AppDictionaryLablesCache extends AbstractDictionaryCache {
* @returns Promise<any>
*/
protected override async getSysDictionaryService(): Promise<any> {
const response = await T_Character_LabelService.findList(1, 9999, {}, []);
// console.log(response);
const _data = response.data.dataSource.map(item => {
return {
name: item.labelName,
value: item.id,
code: item.labelValue
// name: item.name, value, code: item.code
};
});
return _data;
return [];
}

View File

@ -0,0 +1,74 @@
import Http from "@/core/utils/Http";
/**
* T_UserLevels服务
*/
export default class T_UserLevelsService {
static urlPrefix = "/api/v1/admin/T_UserLevels";
/**
*
* @param current
* @param pageSize
* @param search
* @param searchSort
* @returns
*/
static findList(current: number, pageSize: number, search: any = {}, searchSort: any[] = []) {
return Http.post(`${this.urlPrefix}/findList`, {
page: current,
size: pageSize,
search,
searchSort
})
}
/**
*
*
* @param ids
* @returns
*/
static deleteList(ids: string[]) {
return Http.post(`${this.urlPrefix}/deleteList`, ids)
}
/**
*
*
* @param id
* @returns
*/
static findForm(id?: string | undefined) {
return Http.get(`${this.urlPrefix}/findForm${(id ? '/' + id : '')}`)
}
/**
*
*
* @param id
* @param formData
* @returns
*/
static saveForm(id: string | undefined, formData: any) {
return Http.post(`${this.urlPrefix}/${id ? 'update' : 'create'}`, formData)
}
/**
* excel
*
* @param search
* @param searchSort
* @returns
*/
static exportExcel(search: any = {}, searchSort: any[] = []) {
return Http.download(`${this.urlPrefix}/exportExcel`, {
page: -1,
size: -1,
search,
searchSort
});
}
}

View File

@ -0,0 +1,226 @@
<script lang="ts" setup>
import { reactive, ref, onMounted } from "vue";
import { FormInstance } from "ant-design-vue";
import { useAuthority } from "@/utils/Authority";
import AppIcon from "@/core/components/AppIcon.vue";
import Info from "./Info.vue";
import Tools from "@/core/utils/Tools";
import PageContainer from "@/core/components/PageContainer.vue";
import TableCurd from "@/core/components/curd/TableCurd.vue";
import T_UserLevelsService from "@/services/apps/liveforum/T_UserLevelsService";
defineOptions({ name: "T_UserLevelsIndex" });
const state = reactive({
search: {
state: false,
vm: {
name: undefined,
},
sort: [] as any[],
},
loading: false,
page: 1,
size: 50,
total: 100,
columns: [] as any,
data: [] as any,
});
//
const power = useAuthority();
//
const refTableCurd = ref<InstanceType<typeof TableCurd>>();
//
const refInfo = ref<InstanceType<typeof Info>>();
//
const refSearchForm = ref<FormInstance>();
/**
* 初始化
*/
onMounted(() => {
findList();
});
/**
*获取数据
*/
async function findList() {
try {
state.loading = true;
let keys = Object.keys(state.search.vm);
keys.map(k => {
if (state.search.vm[k] == null || state.search.vm[k] == "") {
delete state.search.vm[k];
}
});
const result = await T_UserLevelsService.findList(state.page, state.size, state.search.vm, state.search.sort);
state.loading = false;
if (result.code != 200) return;
state.page = result.data.page;
state.size = result.data.size;
state.total = result.data.total;
state.columns = result.data.columns;
state.data = result.data.dataSource;
// state.visible = false;
} catch (error) {
state.loading = false;
}
}
/**
* 删除数据
* @param id
*/
async function deleteList(id?: string) {
let ids: string[] = [];
if (id) {
ids.push(id);
} else {
ids = refTableCurd.value?.getSelectedRowKeys() ?? [];
}
if (ids.length == 0) return Tools.message.error("请选择要删除的行!");
try {
state.loading = true;
const result = await T_UserLevelsService.deleteList(ids);
state.loading = false;
if (result.code != 200) return;
Tools.message.success("删除成功!");
findList();
} catch (error) {
state.loading = false;
}
}
/**
* 导出excel
*/
function exportExcel() {
T_UserLevelsService.exportExcel(state.search.vm, state.search.sort);
}
</script>
<template>
<PageContainer>
<TableCurd ref="refTableCurd" :config="state" @change="
(changeTable) => {
state.page = changeTable.pagination.current ?? 1;
state.size = changeTable.pagination.pageSize ?? state.size;
state.search.sort = changeTable.sorter instanceof Array ? [...changeTable.sorter] : [changeTable.sorter];
findList();
}
" @show-size-change="
({ current, size }) => {
state.page = current == 0 ? 1 : current;
state.size = size;
findList();
}
">
<!-- search -->
<template #search>
<a-form ref="refSearchForm" :model="state.search.vm" v-if="power.search">
<a-row :gutter="[16, 0]">
<a-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
<a-form-item class="mb-0" name="LevelName" label="等级名称">
<a-input v-model:value="state.search.vm.levelName" placeholder="等级名称" />
</a-form-item>
</a-col>
<!--button-->
<a-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="text-right">
<a-space :size="8">
<a-button @click="
state.page = 1;
refSearchForm?.resetFields();
findList();
">
重置
</a-button>
<a-button type="primary" @click="
state.page = 1;
findList();
">
查询
</a-button>
</a-space>
</a-col>
</a-row>
</a-form>
</template>
<!-- toolbar-left -->
<template #toolbar-left>
<a-button @click="state.search.state = !state.search.state" v-if="power.search">
<div v-if="state.search.state">
<AppIcon name="UpOutlined" />&nbsp;&nbsp;收起
</div>
<div v-else>
<AppIcon name="DownOutlined" />&nbsp;&nbsp;展开
</div>
</a-button>
<a-button type="primary" @click="() => refInfo?.open()" v-if="power.insert">
<template #icon>
<AppIcon name="PlusOutlined" />
</template>
新建
</a-button>
<a-popconfirm title="您确定要删除?" @confirm="deleteList()" okText="确定" cancelText="取消" v-if="power.delete">
<a-button type="primary" danger>
<template #icon>
<AppIcon name="DeleteOutlined" />
</template>
批量删除
</a-button>
</a-popconfirm>
</template>
<!-- toolbar-right -->
<template #toolbar-right>
<a-dropdown>
<template #overlay>
<a-menu>
<a-menu-item key="1" @click="exportExcel()">导出 Excel</a-menu-item>
</a-menu>
</template>
<a-button> 更多
<AppIcon name="ellipsis-outlined" />
</a-button>
</a-dropdown>
<!-- 列设置 -->
<a-popover>
<template #content>
<div v-for="item in state.columns.filter((w: any) => w.fieldName.substr(0, 1) != '_')">
<a-checkbox v-model:checked="item.show">{{ item.title }}</a-checkbox>
</div>
</template>
<a-button type="text">
<template #icon>
<AppIcon name="setting-outlined" />
</template>
</a-button>
</a-popover>
</template>
<!-- table-col -->
<template #table-col>
<template v-for="item, index in state.columns.filter((w: any) => w.fieldName !== 'id' && w.show)"
:key="item.fieldName">
<a-table-column :title="item.title" :data-index="item.fieldName"
:sorter="item.sort ? { multiple: index + 1 } : false" />
</template>
<!-- 操作 -->
<a-table-column title="操作" data-index="id" v-if="power.update || power.delete" width="200px" fixed="right">
<template #default="{ record }">
<a href="javascript:;" @click="() => refInfo?.open(record.id)" v-if="power.update">编辑</a>
<a-divider type="vertical" />
<a-popconfirm title="您确定要删除?" @confirm="deleteList(record.id)" okText="确定" cancelText="取消"
v-if="power.delete">
<a class="text-danger">删除</a>
</a-popconfirm>
</template>
</a-table-column>
</template>
</TableCurd>
<!-- Info -->
<Info ref="refInfo" :onSuccess="() => findList()" />
</PageContainer>
</template>

View File

@ -0,0 +1,130 @@
<script lang="ts" setup>
import { reactive, ref } from "vue";
import { FormInstance } from "ant-design-vue";
import Tools from "@/core/utils/Tools";
import T_UserLevelsService from "@/services/apps/liveforum/T_UserLevelsService";
//
const props = defineProps<{ onSuccess: () => void }>();
const state = reactive({
vm: {
id: "",
form: {} as any,
},
visible: false,
loading: false,
});
//
const refForm = ref<FormInstance>();
//
defineExpose({
/**
* 打开表单初始化
* @param key
*/
open: (key: string = "") => {
state.visible = true;
if (state.visible) {
state.vm.id = key;
}
refForm.value?.resetFields();
//
state.loading = true;
T_UserLevelsService.findForm(key).then((res) => {
state.loading = false;
if (res.code != 200) return;
state.vm = res.data;
});
},
});
/**
*保存数据
*/
function save() {
refForm.value?.validate().then(async () => {
try {
state.loading = true;
const result = await T_UserLevelsService.saveForm(state.vm.id, state.vm.form);
state.loading = false;
if (result.code != 200) return;
Tools.message.success("操作成功!");
props.onSuccess();
state.visible = false;
} catch (error) {
state.loading = false;
}
});
}
</script>
<template>
<a-modal v-model:open="state.visible" :title="state.vm.id ? '编辑' : '新建'" centered @ok="state.visible = false"
:width="800">
<template #footer>
<a-button type="primary" :loading="state.loading" @click="save()"> 提交</a-button>
<a-button @click="state.visible = false">关闭</a-button>
</template>
<a-spin :spinning="state.loading">
<a-form ref="refForm" layout="vertical" :model="state.vm.form">
<a-row :gutter="[16, 0]">
<!-- <a-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
<a-form-item label="项目" name="tenantId">
<hm-tenant-select v-model:value="state.vm.form.tenantId" />
</a-form-item>
</a-col> -->
<a-col :xs="12" :sm="12" :md="12" :lg="12" :xl="12">
<a-form-item label="等级名称" name="levelName"
:rules="[{ required: true, message: '请输入', trigger: 'blur' }]">
<a-input v-model:value="state.vm.form.levelName" placeholder="请输入" />
</a-form-item>
</a-col>
<a-col :xs="12" :sm="12" :md="12" :lg="12" :xl="12">
<a-form-item label="最小经验值" name="minExperience"
:rules="[{ required: true, message: '请输入', trigger: 'blur' }]">
<a-input v-model:value="state.vm.form.minExperience" placeholder="请输入" />
</a-form-item>
</a-col>
<a-col :xs="12" :sm="12" :md="12" :lg="12" :xl="12">
<a-form-item label="最大经验值" name="maxExperience"
:rules="[{ required: true, message: '请输入', trigger: 'blur' }]">
<a-input v-model:value="state.vm.form.maxExperience" placeholder="请输入" />
</a-form-item>
</a-col>
<a-col :xs="12" :sm="12" :md="12" :lg="12" :xl="12">
<a-form-item label="颜色" name="levelColor">
<a-input v-model:value="state.vm.form.levelColor" placeholder="请输入" />
</a-form-item>
</a-col>
<a-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
<a-form-item label="配置" name="privileges">
<a-input v-model:value="state.vm.form.privileges" placeholder="请输入" />
</a-form-item>
</a-col>
<a-col :xs="12" :sm="12" :md="12" :lg="12" :xl="12">
<a-form-item label="状态" name="isActive"
:rules="[{ required: true, message: '请输入', trigger: 'blur' }]">
<a-radio-group v-model:value="state.vm.form.isActive" name="radioGroup">
<a-radio :value="true">启用</a-radio>
<a-radio :value="false">禁用</a-radio>
</a-radio-group>
</a-form-item>
</a-col>
<a-col :xs="12" :sm="12" :md="12" :lg="12" :xl="12">
<a-form-item label="等级图标" name="levelIcon"
:rules="[{ required: true, message: '请输入', trigger: 'blur' }]">
<hm-image v-model:modelValue="state.vm.form.levelIcon"></hm-image>
</a-form-item>
</a-col>
</a-row>
</a-form>
</a-spin>
</a-modal>
</template>

View File

@ -0,0 +1,108 @@
using MiaoYu.Repository.LiveForum.Admin.Entities.Apps;
namespace MiaoYu.Api.Admin.ApplicationServices.Apps.LiveForum;
/// <summary>
/// 用户等级配置表,定义用户等级体系和升级规则 服务 T_UserLevelsService
/// </summary>
public class T_UserLevelsService : ApplicationService<IRepository<T_UserLevels>>
{
public T_UserLevelsService(IRepository<T_UserLevels> defaultRepository)
: base(defaultRepository)
{
}
/// <summary>
/// 获取列表数据
/// </summary>
/// <param name="pagingSearchInput"></param>
/// <returns></returns>
public async Task<PagingView> FindListAsync(PagingSearchInput<T_UserLevels> pagingSearchInput)
{
var query = this._defaultRepository.Select
//等级名称
.WhereIf(!string.IsNullOrWhiteSpace(pagingSearchInput.Search?.LevelName),
w => w.LevelName.Contains(pagingSearchInput.Search.LevelName ?? ""))
.OrderByDescending(w => w.Id)
.Select(w => new
{
w.Id,
w.LevelName,w.MinExperience,w.MaxExperience,w.LevelIcon,w.LevelColor,w.Privileges,w.CreatedAt,w.UpdatedAt,w.IsActive,
// w.LastModificationTime,
// w.CreationTime
})
;
var result = await _defaultRepository.AsPagingViewAsync(query, pagingSearchInput);
// result
// .FormatValue(query, w => w.CreationTime, (oldValue) => oldValue.ToString("yyyy-MM-dd"))
// .FormatValue(query, w => w.LastModificationTime, (oldValue) => oldValue?.ToString("yyyy-MM-dd"))
// ;
// 设置列
//result.GetColumn(query, w => w.OperatorName).SetColumn("操作人");
//result.GetColumn(query, w => w.OperatorName!).SetColumn<SysUser>(w => w.Name!);
return result;
}
/// <summary>
/// 根据id数组删除
/// </summary>
/// <param name="ids">ids</param>
/// <returns></returns>
public async Task DeleteListAsync(List<int> ids)
{
await this._defaultRepository.DeleteByIdsAsync(ids);
}
/// <summary>
/// 查询表单数据
/// </summary>
/// <param name="id">id</param>
/// <returns></returns>
public async Task<Dictionary<string,object>> FindFormAsync(int id)
{
var res = new Dictionary<string, object>();
var form = await this._defaultRepository.FindByIdAsync(id);
form = form.NullSafe();
//if (form.CreateTime == null || form.CreateTime == DateTime.MinValue)
//{
// form.CreateTime = DateTime.Now;
//}
//if (form.UpdateTime == null || form.UpdateTime == DateTime.MinValue)
//{
// form.UpdateTime = DateTime.Now;
//}
res[nameof(id)] = id;
res[nameof(form)] = form;
return res;
}
/// <summary>
/// 保存数据
/// </summary>
/// <param name="form">form</param>
/// <returns></returns>
public Task SaveFormAsync(T_UserLevels form)
{
return this._defaultRepository.InsertOrUpdateAsync(form);
}
/// <summary>
/// 导出Excel
/// </summary>
/// <param name="pagingSearchInput"></param>
/// <returns></returns>
public async Task<byte[]> ExportExcelAsync(PagingSearchInput<T_UserLevels> pagingSearchInput)
{
pagingSearchInput.Page = -1;
var tableViewModel = await this.FindListAsync(pagingSearchInput);
return ExcelUtil.ExportExcelByPagingView(tableViewModel, null, "Id");
}
}

View File

@ -41,7 +41,7 @@ public class CosService : ApplicationService
var cosConfig = _tencentConfig.CosConfig;
var t = new CosGenerateSign()
{
Prefixes = "miaoyu",
Prefixes = cosConfig.Prefixes ?? "file",
Bucket = cosConfig?.Bucket,
Region = cosConfig?.Region,
AppId = cosConfig?.AppId,
@ -49,12 +49,12 @@ public class CosService : ApplicationService
SecretKey = cosConfig?.SecretKey,
DurationSecond = cosConfig?.DurationSecond ?? 300
};
if (string.IsNullOrEmpty(modelName))
{
modelName = "images";
}
var tempFile = fileName;
if (!string.IsNullOrEmpty(tempFile))
{
@ -65,9 +65,9 @@ public class CosService : ApplicationService
tempFile = $"{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}{ext}";
}
}
var model = _codeCosService.GenerateTemporaryKey(t);
// 复制对象属性
var generateTemporaryModel = model.CopyObject<CodeCosGenerateTemporaryKeyEntity, GenerateTemporaryModel>() ?? new GenerateTemporaryModel();
generateTemporaryModel.Bucket = t.Bucket + "-" + t.AppId;
@ -76,7 +76,7 @@ public class CosService : ApplicationService
// 修复日期格式yyyMMdd -> yyyyMMdd
generateTemporaryModel.FilePath = $"{t.Prefixes}/{modelName}/{DateTime.Now.ToString("yyyyMMdd")}/{tempFile}";
generateTemporaryModel.DomainName = cosConfig.DomainName;
return generateTemporaryModel;
}
}

View File

@ -0,0 +1,100 @@
using MiaoYu.Api.Admin.ApplicationServices.Apps.LiveForum;
using MiaoYu.Repository.LiveForum.Admin.Entities.Apps;
namespace MiaoYu.Api.Admin.Controllers.Apps.LiveForum;
/// <summary>
/// 用户等级配置表,定义用户等级体系和升级规则 控制器
/// </summary>
[ControllerDescriptor(MenuId = "请设置菜单Id 系统菜单表中查找,如果不设置不受权限保护!", DisplayName = "用户等级配置表,定义用户等级体系和升级规则")]
public class T_UserLevelsController : AdminControllerBase<T_UserLevelsService>
{
public T_UserLevelsController(T_UserLevelsService defaultService)
: base(defaultService)
{
}
/// <summary>
/// 获取列表
/// </summary>
/// <param name="pagingSearchInput"></param>
/// <returns></returns>
[ActionDescriptor(PermissionFunctionConsts.Function_Display, DisplayName = "查看数据")]
[HttpPost]
public Task<PagingView> FindListAsync([FromBody] PagingSearchInput<T_UserLevels> pagingSearchInput)
{
return this._defaultService.FindListAsync(pagingSearchInput);
}
/// <summary>
/// 根据id数组删除
/// </summary>
/// <param name="ids">ids</param>
/// <returns></returns>
[ActionDescriptor(PermissionFunctionConsts.Function_Delete, DisplayName = "删除数据")]
[HttpPost]
public async Task<bool> DeleteListAsync([FromBody] List<int> ids)
{
await this._defaultService.DeleteListAsync(ids);
return true;
}
/// <summary>
/// 查询表单数据
/// </summary>
/// <param name="id">id</param>
/// <returns></returns>
[ActionDescriptor(DisplayName = "查看表单")]
[HttpGet("{id?}")]
public Task<Dictionary<string, object>> FindFormAsync([FromRoute] int id)
{
return this._defaultService.FindFormAsync(id);
}
/// <summary>
/// 添加
/// </summary>
/// <param name="form"></param>
/// <returns></returns>
[RequestLimitFilter(Duration = 1, LimitCount = 1)]
[ActionDescriptor(PermissionFunctionConsts.Function_Insert, DisplayName = "创建表单")]
[HttpPost]
[ApiCheckModel]
public Task CreateAsync([FromBody] T_UserLevels form)
{
return this._defaultService.SaveFormAsync(form);
}
/// <summary>
/// 编辑
/// </summary>
/// <param name="form"></param>
/// <returns></returns>
[RequestLimitFilter(Duration = 1, LimitCount = 1)]
[ActionDescriptor(PermissionFunctionConsts.Function_Update, DisplayName = "编辑表单")]
[HttpPost]
[ApiCheckModel]
public Task UpdateAsync([FromBody] T_UserLevels form)
{
return this._defaultService.SaveFormAsync(form);
}
/// <summary>
/// 导出Excel
/// </summary>
/// <param name="pagingSearchInput"></param>
/// <returns></returns>
[ActionDescriptor(PermissionFunctionConsts.Function_Export, DisplayName = "导出数据")]
[ApiResourceCacheFilter(10)]
[HttpPost]
public async Task ExportExcelAsync([FromBody] PagingSearchInput<T_UserLevels> pagingSearchInput)
{
var data = await this._defaultService.ExportExcelAsync(pagingSearchInput);
var name = $"{PermissionUtil.GetControllerDisplayName(this.GetType())}列表数据 {DateTime.Now.ToString("yyyy-MM-dd")}.xls";
base.HttpContext.DownLoadFile(data, Tools.GetFileContentType[".xls"].ToStr(), name);
}
}

View File

@ -129,6 +129,46 @@
<param name="id"></param>
<returns></returns>
</member>
<member name="T:MiaoYu.Api.Admin.ApplicationServices.Apps.LiveForum.T_UserLevelsService">
<summary>
用户等级配置表,定义用户等级体系和升级规则 服务 T_UserLevelsService
</summary>
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.Apps.LiveForum.T_UserLevelsService.FindListAsync(MiaoYu.Shared.Admin.Models.PagingViews.PagingSearchInput{MiaoYu.Repository.LiveForum.Admin.Entities.Apps.T_UserLevels})">
<summary>
获取列表数据
</summary>
<param name="pagingSearchInput"></param>
<returns></returns>
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.Apps.LiveForum.T_UserLevelsService.DeleteListAsync(System.Collections.Generic.List{System.Int32})">
<summary>
根据id数组删除
</summary>
<param name="ids">ids</param>
<returns></returns>
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.Apps.LiveForum.T_UserLevelsService.FindFormAsync(System.Int32)">
<summary>
查询表单数据
</summary>
<param name="id">id</param>
<returns></returns>
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.Apps.LiveForum.T_UserLevelsService.SaveFormAsync(MiaoYu.Repository.LiveForum.Admin.Entities.Apps.T_UserLevels)">
<summary>
保存数据
</summary>
<param name="form">form</param>
<returns></returns>
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.Apps.LiveForum.T_UserLevelsService.ExportExcelAsync(MiaoYu.Shared.Admin.Models.PagingViews.PagingSearchInput{MiaoYu.Repository.LiveForum.Admin.Entities.Apps.T_UserLevels})">
<summary>
导出Excel
</summary>
<param name="pagingSearchInput"></param>
<returns></returns>
</member>
<member name="T:MiaoYu.Api.Admin.ApplicationServices.Apps.LiveForum.T_UsersService">
<summary>
用户表,存储用户基本信息(移除登录相关字段) 服务 T_UsersService
@ -1154,6 +1194,53 @@
</summary>
<param name="defaultService">默认服务</param>
</member>
<member name="T:MiaoYu.Api.Admin.Controllers.Apps.LiveForum.T_UserLevelsController">
<summary>
用户等级配置表,定义用户等级体系和升级规则 控制器
</summary>
</member>
<member name="M:MiaoYu.Api.Admin.Controllers.Apps.LiveForum.T_UserLevelsController.FindListAsync(MiaoYu.Shared.Admin.Models.PagingViews.PagingSearchInput{MiaoYu.Repository.LiveForum.Admin.Entities.Apps.T_UserLevels})">
<summary>
获取列表
</summary>
<param name="pagingSearchInput"></param>
<returns></returns>
</member>
<member name="M:MiaoYu.Api.Admin.Controllers.Apps.LiveForum.T_UserLevelsController.DeleteListAsync(System.Collections.Generic.List{System.Int32})">
<summary>
根据id数组删除
</summary>
<param name="ids">ids</param>
<returns></returns>
</member>
<member name="M:MiaoYu.Api.Admin.Controllers.Apps.LiveForum.T_UserLevelsController.FindFormAsync(System.Int32)">
<summary>
查询表单数据
</summary>
<param name="id">id</param>
<returns></returns>
</member>
<member name="M:MiaoYu.Api.Admin.Controllers.Apps.LiveForum.T_UserLevelsController.CreateAsync(MiaoYu.Repository.LiveForum.Admin.Entities.Apps.T_UserLevels)">
<summary>
添加
</summary>
<param name="form"></param>
<returns></returns>
</member>
<member name="M:MiaoYu.Api.Admin.Controllers.Apps.LiveForum.T_UserLevelsController.UpdateAsync(MiaoYu.Repository.LiveForum.Admin.Entities.Apps.T_UserLevels)">
<summary>
编辑
</summary>
<param name="form"></param>
<returns></returns>
</member>
<member name="M:MiaoYu.Api.Admin.Controllers.Apps.LiveForum.T_UserLevelsController.ExportExcelAsync(MiaoYu.Shared.Admin.Models.PagingViews.PagingSearchInput{MiaoYu.Repository.LiveForum.Admin.Entities.Apps.T_UserLevels})">
<summary>
导出Excel
</summary>
<param name="pagingSearchInput"></param>
<returns></returns>
</member>
<member name="T:MiaoYu.Api.Admin.Controllers.Apps.LiveForum.T_UsersController">
<summary>
用户表,存储用户基本信息(移除登录相关字段) 控制器

View File

@ -14,7 +14,7 @@
//"ConnectionString": "Server=localhost; port=3306; Database=hzy_admin_mysql_20230227; uid=root; pwd=123456; Convert Zero Datetime=False"
//// - sqlserver
//"ConnectionString": "Server=192.168.195.2;Database=MiaoYu;User ID=zpc;Password=zpc;MultipleActiveResultSets=true;Encrypt=True;TrustServerCertificate=True;",
"ConnectionString": "Server=192.168.195.15;Database=HZY;User Id=sa;Password=Dbt@com@123;MultipleActiveResultSets=true;Encrypt=True;TrustServerCertificate=True;"
"ConnectionString": "Server=192.168.195.15;Database=LiveForumAdminDB;User Id=sa;Password=Dbt@com@123;MultipleActiveResultSets=true;Encrypt=True;TrustServerCertificate=True;"
//// - postgresql
//"ConnectionString": "User ID=postgres;Password=123456;Host=localhost;Port=5432;Database=hzy_microservices_pgsql_20230227;Pooling=true;TimeZone=Asia/Shanghai",
//// - oracle

View File

@ -67,7 +67,8 @@
"DurationSecond": "300",
"Region": "ap-shanghai",
"Bucket": "miaoyu",
"DomainName": "miaoyu-1259071413.cos.ap-shanghai.myqcloud.com"
"DomainName": "miaoyu-1259071413.cos.ap-shanghai.myqcloud.com",
"Prefixes": "file"
}
},
//

View File

@ -1,4 +1,4 @@
@model GenDbTableDto
@model GenDbTableDto
@{
var className = Model.EntityName;
var tableName = Model.TableName;
@ -48,7 +48,7 @@ import Info from "./Info.vue";
import Tools from "@@/core/utils/Tools";
import PageContainer from "@@/core/components/PageContainer.vue";
import TableCurd from "@@/core/components/curd/TableCurd.vue";
import @(className)Service from "@(clientServiceNamespace)/@(className)Service";
import @(className)Service from "@(clientServiceNamespace)/@(className)Service";
defineOptions({ name: "@(className)Index" });
@ -176,11 +176,6 @@ function exportExcel() {
</a-form-item>
</a-col>
-->
<a-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
<a-form-item class="mb-0" name="tenantId" label="项目">
<hm-tenant-select v-model:value="state.search.vm.tenantId" :ShowAll="true" />
</a-form-item>
</a-col>
@foreach (var x in selectTable)
{
<a-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
@ -192,21 +187,11 @@ function exportExcel() {
<!--button-->
<a-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="text-right">
<a-space :size="8">
<a-button
@@click="
state.page = 1;
refSearchForm?.resetFields();
findList();
"
>
<a-button @@click="state.page = 1;refSearchForm?.resetFields();findList();" >
重置
</a-button>
<a-button
type="primary"
@@click="
state.page = 1;
findList();
"
type="primary" @@click="state.page = 1;findList();"
>
查询
</a-button>

View File

@ -1,4 +1,4 @@
@model GenDbTableDto
@model GenDbTableDto
@{
var className = Model.EntityName;
var tableName = Model.TableName;
@ -98,11 +98,7 @@
<a-spin :spinning="state.loading">
<a-form ref="refForm" layout="vertical" :model="state.vm.form">
<a-row :gutter="[16, 0]">
<a-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
<a-form-item label="项目" name="tenantId">
<hm-tenant-select v-model:value="state.vm.form.tenantId" />
</a-form-item>
</a-col>
@foreach (var item in tableInfos)
{
@ -115,7 +111,7 @@
else
{
<a-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
<a-col :xs="12" :sm="12" :md="12" :lg="12" :xl="12">
<a-form-item label="@(title ?? "请设置列信息 > " + item.ColumnName)" name="@(name)" :rules="[{ required: true, message: '请输入', trigger: 'blur' }]">
<a-input v-model:value="state.vm.form.@(name)" placeholder="请输入" />
</a-form-item>

View File

@ -10,7 +10,7 @@ namespace MiaoYu.Core.Cos.Configs
/// <summary>
/// 对象存储
/// </summary>
public class TencentCosConfig:TencentBaseConfig
public class TencentCosConfig : TencentBaseConfig
{
/// <summary>
/// 最大超时时间
@ -30,6 +30,11 @@ namespace MiaoYu.Core.Cos.Configs
/// <summary>
/// 域名
/// </summary>
public string DomainName { get; set; }
public string DomainName { get; set; }
/// <summary>
///
/// </summary>
public string Prefixes { get; set; }
}
}

View File

@ -0,0 +1,66 @@
namespace MiaoYu.Repository.LiveForum.Admin.Entities.Apps;
/// <summary>
/// 用户等级配置表,定义用户等级体系和升级规则
/// </summary>
[EntityDescription(FieldIgnored = true)]
[Table("T_UserLevels")]
public class T_UserLevels : EntityIdentity<int>
{
/// <summary>
/// 等级名称 => 备注: 等级名称如LV0、LV1等
/// </summary>
public string? LevelName { get; set; }
/// <summary>
/// 最小经验值 => 备注: 达到该等级所需的最小经验值
/// </summary>
public Int32 MinExperience { get; set; }
/// <summary>
/// 最大经验值 => 备注: 该等级的最大经验值上限
/// </summary>
public Int32 MaxExperience { get; set; }
/// <summary>
/// 等级图标 => 备注: 等级图标URL地址
/// </summary>
public string? LevelIcon { get; set; }
/// <summary>
/// 颜色 => 备注: 等级显示颜色(十六进制)
/// </summary>
public string? LevelColor { get; set; }
/// <summary>
/// 配置 => 备注: 等级特权配置JSON格式
/// </summary>
public string? Privileges { get; set; }
/// <summary>
/// 创建时间 => 备注: 记录创建时间
/// </summary>
public DateTime CreatedAt { get; set; }
/// <summary>
/// 更新时间 => 备注: 记录更新时间
/// </summary>
public DateTime UpdatedAt { get; set; }
/// <summary>
/// 状态 => 备注: 是否启用该等级
/// </summary>
public Boolean IsActive { get; set; }
}

View File

@ -4,6 +4,56 @@
<name>MiaoYu.Repository.LiveForum.Admin</name>
</assembly>
<members>
<member name="T:MiaoYu.Repository.LiveForum.Admin.Entities.Apps.T_UserLevels">
<summary>
用户等级配置表,定义用户等级体系和升级规则
</summary>
</member>
<member name="P:MiaoYu.Repository.LiveForum.Admin.Entities.Apps.T_UserLevels.LevelName">
<summary>
等级名称 => 备注: 等级名称如LV0、LV1等
</summary>
</member>
<member name="P:MiaoYu.Repository.LiveForum.Admin.Entities.Apps.T_UserLevels.MinExperience">
<summary>
最小经验值 => 备注: 达到该等级所需的最小经验值
</summary>
</member>
<member name="P:MiaoYu.Repository.LiveForum.Admin.Entities.Apps.T_UserLevels.MaxExperience">
<summary>
最大经验值 => 备注: 该等级的最大经验值上限
</summary>
</member>
<member name="P:MiaoYu.Repository.LiveForum.Admin.Entities.Apps.T_UserLevels.LevelIcon">
<summary>
等级图标 => 备注: 等级图标URL地址
</summary>
</member>
<member name="P:MiaoYu.Repository.LiveForum.Admin.Entities.Apps.T_UserLevels.LevelColor">
<summary>
颜色 => 备注: 等级显示颜色(十六进制)
</summary>
</member>
<member name="P:MiaoYu.Repository.LiveForum.Admin.Entities.Apps.T_UserLevels.Privileges">
<summary>
配置 => 备注: 等级特权配置JSON格式
</summary>
</member>
<member name="P:MiaoYu.Repository.LiveForum.Admin.Entities.Apps.T_UserLevels.CreatedAt">
<summary>
创建时间 => 备注: 记录创建时间
</summary>
</member>
<member name="P:MiaoYu.Repository.LiveForum.Admin.Entities.Apps.T_UserLevels.UpdatedAt">
<summary>
更新时间 => 备注: 记录更新时间
</summary>
</member>
<member name="P:MiaoYu.Repository.LiveForum.Admin.Entities.Apps.T_UserLevels.IsActive">
<summary>
状态 => 备注: 是否启用该等级
</summary>
</member>
<member name="T:MiaoYu.Repository.LiveForum.Admin.Entities.Apps.T_Users">
<summary>
用户表,存储用户基本信息(移除登录相关字段)