修改后台代码
This commit is contained in:
parent
d975457af2
commit
998e2c068c
2
admin-client/.env
Normal file
2
admin-client/.env
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
VITE_BASE=/ #
|
||||||
|
VITE_BASEURL=http://localhost:5500
|
||||||
|
|
@ -2,19 +2,11 @@
|
||||||
<html lang="zh-cn">
|
<html lang="zh-cn">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<script>
|
|
||||||
var _hmt = _hmt || [];
|
|
||||||
(function () {
|
|
||||||
var hm = document.createElement("script");
|
|
||||||
hm.src = "https://hm.baidu.com/hm.js?a046a7e7384c191e3f44957ab08fe190";
|
|
||||||
var s = document.getElementsByTagName("script")[0];
|
|
||||||
s.parentNode.insertBefore(hm, s);
|
|
||||||
})();
|
|
||||||
</script>
|
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>HZY-Microservices</title>
|
<title>寰梦后台管理</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
<!-- 脚本 -->
|
<!-- 脚本 -->
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {Table, TablePaginationConfig} from "ant-design-vue";
|
import { Table, TablePaginationConfig } from "ant-design-vue";
|
||||||
import {FilterValue, SorterResult, TableCurrentDataSource, TableRowSelection} from "ant-design-vue/es/table/interface";
|
import { FilterValue, SorterResult, TableCurrentDataSource, TableRowSelection } from "ant-design-vue/es/table/interface";
|
||||||
import {SizeType} from "ant-design-vue/lib/config-provider";
|
import { SizeType } from "ant-design-vue/lib/config-provider";
|
||||||
import {ref, computed, unref, watch} from "vue";
|
import { ref, computed, unref, watch } from "vue";
|
||||||
import AppIcon from "@/core/components/AppIcon.vue";
|
import AppIcon from "@/core/components/AppIcon.vue";
|
||||||
import ColumnSetting from "@/core/components/curd/components/ColumnSetting.vue";
|
import ColumnSetting from "@/core/components/curd/components/ColumnSetting.vue";
|
||||||
|
|
||||||
|
|
@ -12,6 +12,7 @@ interface ITableConfig {
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
page: number;
|
page: number;
|
||||||
size: number;
|
size: number;
|
||||||
|
scroll?: any;
|
||||||
total: number;
|
total: number;
|
||||||
/**
|
/**
|
||||||
* 列头
|
* 列头
|
||||||
|
|
@ -24,66 +25,88 @@ interface ITableConfig {
|
||||||
data: any[];
|
data: any[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 定义默认的配置
|
||||||
|
const defaultTableConfig: ITableConfig = {
|
||||||
|
search: {},
|
||||||
|
loading: false,
|
||||||
|
page: 1,
|
||||||
|
size: 10,
|
||||||
|
scroll: { x: 'calc(100wh - 300px)' }, // 设置默认值
|
||||||
|
total: 0,
|
||||||
|
columns: [],
|
||||||
|
data: [],
|
||||||
|
};
|
||||||
|
|
||||||
//定义 props
|
//定义 props
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
config: ITableConfig;
|
config: ITableConfig;
|
||||||
/**
|
/**
|
||||||
* 是否展示分页
|
* 是否展示分页
|
||||||
*/
|
*/
|
||||||
isPagination?: boolean;
|
isPagination?: boolean;
|
||||||
/**
|
/**
|
||||||
* 展开行keys
|
* 展开行keys
|
||||||
*/
|
*/
|
||||||
expandedRowKeys?: string[];
|
expandedRowKeys?: string[];
|
||||||
/**
|
/**
|
||||||
* 数据行的唯一 key
|
* 数据行的唯一 key
|
||||||
*/
|
*/
|
||||||
rowKey?: string;
|
rowKey?: string;
|
||||||
/**
|
/**
|
||||||
* 是否默认表格
|
* 是否默认表格
|
||||||
* true: 默认表格 - 采用 dom 元素配置列头
|
* true: 默认表格 - 采用 dom 元素配置列头
|
||||||
* false: 自定义表格 - 采用属性 columns 配置列头
|
* false: 自定义表格 - 采用属性 columns 配置列头
|
||||||
*/
|
*/
|
||||||
isDefaultTable?: boolean;
|
isDefaultTable?: boolean;
|
||||||
/**
|
/**
|
||||||
* 是否显示列设置
|
* 是否显示列设置
|
||||||
*/
|
*/
|
||||||
columnSetting?: boolean;
|
columnSetting?: boolean;
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
isPagination: true,
|
isPagination: true,
|
||||||
rowKey: "id",
|
rowKey: "id",
|
||||||
isDefaultTable: true,
|
isDefaultTable: true,
|
||||||
columnSetting: true,
|
columnSetting: true,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
//定义事件
|
//定义事件
|
||||||
const emits = defineEmits<{
|
const emits = defineEmits<{
|
||||||
(
|
(
|
||||||
e: "change",
|
e: "change",
|
||||||
{
|
{
|
||||||
pagination,
|
pagination,
|
||||||
filters,
|
filters,
|
||||||
sorter,
|
sorter,
|
||||||
extra,
|
extra,
|
||||||
}: {
|
}: {
|
||||||
pagination: TablePaginationConfig;
|
pagination: TablePaginationConfig;
|
||||||
filters: Record<string, FilterValue | null>;
|
filters: Record<string, FilterValue | null>;
|
||||||
sorter: SorterResult<any> | SorterResult<any>[];
|
sorter: SorterResult<any> | SorterResult<any>[];
|
||||||
extra: TableCurrentDataSource<any>;
|
extra: TableCurrentDataSource<any>;
|
||||||
}
|
}
|
||||||
): void;
|
): void;
|
||||||
(e: "paginationChange", {page, pageSize}: { page: number; pageSize: number }): void;
|
(e: "paginationChange", { page, pageSize }: { page: number; pageSize: number }): void;
|
||||||
(e: "showSizeChange", {current, size}: { current: number; size: number }): void;
|
(e: "showSizeChange", { current, size }: { current: number; size: number }): void;
|
||||||
(e: "update:expandedRowKeys", value: string[]): void;
|
(e: "update:expandedRowKeys", value: string[]): void;
|
||||||
(e: "update:config", value: ITableConfig): void;
|
(e: "update:config", value: ITableConfig): void;
|
||||||
}>();
|
}>();
|
||||||
|
// props.config
|
||||||
|
// // 使用默认配置初始化
|
||||||
|
// const tableConfig = {
|
||||||
|
// ...defaultTableConfig,
|
||||||
|
// ...props.config
|
||||||
|
// };
|
||||||
//表格配置信息
|
//表格配置信息
|
||||||
const tableConfig = computed({
|
const tableConfig = computed({
|
||||||
get: () => props.config,
|
get: () => {
|
||||||
|
if (props.config.scroll == null) {
|
||||||
|
props.config.scroll = defaultTableConfig.scroll
|
||||||
|
}
|
||||||
|
return props.config;
|
||||||
|
},
|
||||||
set: (value: ITableConfig) => emits("update:config", value),
|
set: (value: ITableConfig) => emits("update:config", value),
|
||||||
});
|
});
|
||||||
//分页大小选项
|
//分页大小选项
|
||||||
|
|
@ -151,23 +174,23 @@ defineExpose({
|
||||||
* @param extra
|
* @param extra
|
||||||
*/
|
*/
|
||||||
const onChange = (pagination: TablePaginationConfig, filters: Record<string, FilterValue | null>, sorter: SorterResult<any> | SorterResult<any>[], extra: TableCurrentDataSource<any>) => {
|
const onChange = (pagination: TablePaginationConfig, filters: Record<string, FilterValue | null>, sorter: SorterResult<any> | SorterResult<any>[], extra: TableCurrentDataSource<any>) => {
|
||||||
emits("change", {pagination, filters, sorter, extra});
|
emits("change", { pagination, filters, sorter, extra });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 页码或 pageSize 改变的回调,参数是改变后的页码及每页条数
|
* 页码或 pageSize 改变的回调,参数是改变后的页码及每页条数
|
||||||
* @param param0
|
* @param param0
|
||||||
*/
|
*/
|
||||||
const onPaginationChange = ({page, pageSize}: { page: number; pageSize: number }) => {
|
const onPaginationChange = ({ page, pageSize }: { page: number; pageSize: number }) => {
|
||||||
emits("paginationChange", {page, pageSize});
|
emits("paginationChange", { page, pageSize });
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pageSize 变化的回调
|
* pageSize 变化的回调
|
||||||
* @param param0
|
* @param param0
|
||||||
*/
|
*/
|
||||||
const onShowSizeChange = ({current, size}: { current: number; size: number }) => {
|
const onShowSizeChange = ({ current, size }: { current: number; size: number }) => {
|
||||||
emits("showSizeChange", {current, size});
|
emits("showSizeChange", { current, size });
|
||||||
};
|
};
|
||||||
|
|
||||||
//多选配置
|
//多选配置
|
||||||
|
|
@ -232,33 +255,32 @@ const rowSelection = computed(() => {
|
||||||
<!-- 工具栏右侧插槽 -->
|
<!-- 工具栏右侧插槽 -->
|
||||||
<slot name="toolbar-right"></slot>
|
<slot name="toolbar-right"></slot>
|
||||||
<!-- 列设置 -->
|
<!-- 列设置 -->
|
||||||
<ColumnSetting
|
<ColumnSetting v-model:columns="tableConfig.columns"
|
||||||
v-model:columns="tableConfig.columns"
|
v-if="props.columnSetting && tableConfig.columns && tableConfig.columns.length > 0" />
|
||||||
v-if="props.columnSetting && tableConfig.columns && tableConfig.columns.length>0"/>
|
|
||||||
<!-- 表格大小控制 -->
|
<!-- 表格大小控制 -->
|
||||||
<a-dropdown>
|
<a-dropdown>
|
||||||
<a-button type="text">
|
<a-button type="text">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<AppIcon name="column-height-outlined"/>
|
<AppIcon name="column-height-outlined" />
|
||||||
</template>
|
</template>
|
||||||
</a-button>
|
</a-button>
|
||||||
<template #overlay>
|
<template #overlay>
|
||||||
<a-menu v-model:selectedKeys="selectedKeys">
|
<a-menu v-model:selectedKeys="selectedKeys">
|
||||||
<a-menu-item key="large" @click="() => {
|
<a-menu-item key="large" @click="() => {
|
||||||
tableSizeType = 'large'
|
tableSizeType = 'large'
|
||||||
selectedKeys=[tableSizeType]
|
selectedKeys = [tableSizeType]
|
||||||
}">
|
}">
|
||||||
默认
|
默认
|
||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
<a-menu-item key="middle" @click="() => {
|
<a-menu-item key="middle" @click="() => {
|
||||||
tableSizeType = 'middle'
|
tableSizeType = 'middle'
|
||||||
selectedKeys=[tableSizeType]
|
selectedKeys = [tableSizeType]
|
||||||
}">
|
}">
|
||||||
中等
|
中等
|
||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
<a-menu-item key="small" @click="() => {
|
<a-menu-item key="small" @click="() => {
|
||||||
tableSizeType = 'small';
|
tableSizeType = 'small';
|
||||||
selectedKeys=[tableSizeType]
|
selectedKeys = [tableSizeType]
|
||||||
}">
|
}">
|
||||||
紧凑
|
紧凑
|
||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
|
|
@ -273,39 +295,30 @@ const rowSelection = computed(() => {
|
||||||
<!-- 表格 -->
|
<!-- 表格 -->
|
||||||
<div>
|
<div>
|
||||||
<slot name="table">
|
<slot name="table">
|
||||||
<a-table
|
<a-table :columns="props.isDefaultTable ? undefined : tableConfig.columns" :size="tableSizeType"
|
||||||
:columns="props.isDefaultTable ? undefined : tableConfig.columns"
|
:row-selection="rowSelection" :data-source="tableConfig.data" :pagination="props.isPagination
|
||||||
:size="tableSizeType"
|
? {
|
||||||
:row-selection="rowSelection"
|
size: 'default',
|
||||||
:data-source="tableConfig.data"
|
pageSize: tableConfig.size,
|
||||||
:pagination="
|
total: tableConfig.total,
|
||||||
props.isPagination
|
current: tableConfig.page,
|
||||||
? {
|
pageSizeOptions,
|
||||||
size: 'default',
|
showSizeChanger: true,
|
||||||
pageSize: tableConfig.size,
|
onChange: (page, pageSize) => onPaginationChange({ page, pageSize }),
|
||||||
total: tableConfig.total,
|
onShowSizeChange: (current, size) => onShowSizeChange({ current, size }),
|
||||||
current: tableConfig.page,
|
showTotal: (total) => `共${total}条`,
|
||||||
pageSizeOptions,
|
showQuickJumper: true,
|
||||||
showSizeChanger: true,
|
}
|
||||||
onChange: (page, pageSize) => onPaginationChange({ page, pageSize }),
|
: false
|
||||||
onShowSizeChange: (current, size) => onShowSizeChange({ current, size }),
|
" :loading="tableConfig.loading" :scroll="tableConfig.scroll" :row-key="props.rowKey"
|
||||||
showTotal: (total) => `共${total}条`,
|
v-model:expandedRowKeys="expandedRowKeys"
|
||||||
showQuickJumper: true,
|
@change="(pagination, filters, sorter, extra) => onChange(pagination, filters, sorter, extra)">
|
||||||
}
|
|
||||||
: false
|
|
||||||
"
|
|
||||||
:loading="tableConfig.loading"
|
|
||||||
:scroll="{ x: 'calc(100wh - 300px)' }"
|
|
||||||
:row-key="props.rowKey"
|
|
||||||
v-model:expandedRowKeys="expandedRowKeys"
|
|
||||||
@change="(pagination, filters, sorter, extra) => onChange(pagination, filters, sorter, extra)"
|
|
||||||
>
|
|
||||||
|
|
||||||
<!-- 菜单用 dom 自定义列-->
|
<!-- 菜单用 dom 自定义列-->
|
||||||
<slot name="table-col" v-if="props.isDefaultTable">
|
<slot name="table-col" v-if="props.isDefaultTable">
|
||||||
<template v-for="(item,index) in tableConfig.columns.filter((w:any) => w.show)" :key="item.dataIndex">
|
<template v-for="(item, index) in tableConfig.columns.filter((w: any) => w.show)" :key="item.dataIndex">
|
||||||
<slot :name="item.dataIndex" v-bind="item">
|
<slot :name="item.dataIndex" v-bind="item">
|
||||||
<a-table-column v-bind="item" :index="index"/>
|
<a-table-column v-bind="item" :index="index" />
|
||||||
</slot>
|
</slot>
|
||||||
</template>
|
</template>
|
||||||
</slot>
|
</slot>
|
||||||
|
|
|
||||||
|
|
@ -55,8 +55,8 @@ let left = computed(() => {
|
||||||
|
|
||||||
<!-- 返回顶部 -->
|
<!-- 返回顶部 -->
|
||||||
<a-back-top/>
|
<a-back-top/>
|
||||||
<a-layout-footer style="text-align: center">{{ appStore.state.title }} ©{{ year }} created by hzy
|
<!-- <a-layout-footer style="text-align: center">{{ appStore.state.title }} ©{{ year }} created by hzy
|
||||||
</a-layout-footer>
|
</a-layout-footer> -->
|
||||||
</a-layout-content>
|
</a-layout-content>
|
||||||
</a-layout>
|
</a-layout>
|
||||||
</a-layout>
|
</a-layout>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,8 @@ import NProgress from "nprogress";
|
||||||
|
|
||||||
import Cookies from "universal-cookie";
|
import Cookies from "universal-cookie";
|
||||||
import AppConsts from "../../utils/AppConsts";
|
import AppConsts from "../../utils/AppConsts";
|
||||||
|
import TImageConfigService from "@/services/Apps/T_Image_Configs/TImageConfigService";
|
||||||
|
import COS from "cos-js-sdk-v5";
|
||||||
/**
|
/**
|
||||||
* 程序工具类
|
* 程序工具类
|
||||||
*
|
*
|
||||||
|
|
@ -351,7 +352,7 @@ class Tools {
|
||||||
/**
|
/**
|
||||||
* 判断文件类型是否是图片
|
* 判断文件类型是否是图片
|
||||||
* @param fileType 文件类型
|
* @param fileType 文件类型
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
static isImageFile(fileType: string) {
|
static isImageFile(fileType: string) {
|
||||||
// 定义常见的图片 MIME 类型
|
// 定义常见的图片 MIME 类型
|
||||||
|
|
@ -369,6 +370,170 @@ class Tools {
|
||||||
// 检查文件的 MIME 类型是否在定义的图片 MIME 类型列表中
|
// 检查文件的 MIME 类型是否在定义的图片 MIME 类型列表中
|
||||||
return imageMimeTypes.includes(fileType);
|
return imageMimeTypes.includes(fileType);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 上传cos
|
||||||
|
* @param file 文件流
|
||||||
|
* @param modelName 模块名称
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
static async cosUploadFile(file: File, modelName?: string) {
|
||||||
|
var request = await TImageConfigService.getGenerateTemporaryKey(
|
||||||
|
file.name,
|
||||||
|
modelName
|
||||||
|
);
|
||||||
|
let cosTemporaryKey = request.data;
|
||||||
|
const cos = new COS({
|
||||||
|
// getAuthorization 必选参数
|
||||||
|
getAuthorization: function (options, callback) {
|
||||||
|
callback({
|
||||||
|
TmpSecretId: cosTemporaryKey.credentials.tmpSecretId,
|
||||||
|
TmpSecretKey: cosTemporaryKey.credentials.tmpSecretKey,
|
||||||
|
SecurityToken: cosTemporaryKey.credentials.token,
|
||||||
|
// 建议返回服务器时间作为签名的开始时间,避免用户浏览器本地时间偏差过大导致签名错误
|
||||||
|
StartTime: cosTemporaryKey.startTime, // 时间戳,单位秒,如:1580000000
|
||||||
|
ExpiredTime: cosTemporaryKey.expiredTime, // 时间戳,单位秒,如:1580000000
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
let _tempFilePaht = cosTemporaryKey.filePath;
|
||||||
|
|
||||||
|
if (_tempFilePaht.indexOf(".") == -1) {
|
||||||
|
_tempFilePaht = _tempFilePaht + file.name;
|
||||||
|
}
|
||||||
|
// 上传文件
|
||||||
|
const cosUploadFile = await cos.uploadFile({
|
||||||
|
Bucket: cosTemporaryKey.bucket,
|
||||||
|
Region: cosTemporaryKey.region,
|
||||||
|
Key: _tempFilePaht,
|
||||||
|
Body: file,
|
||||||
|
SliceSize: 1024 * 1024, // 大于1mb才进行分块上传
|
||||||
|
onTaskReady: function (tid) {},
|
||||||
|
onProgress: function (progressData) {
|
||||||
|
console.log("上传中", JSON.stringify(progressData));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
console.log(cosUploadFile);
|
||||||
|
// DomainName
|
||||||
|
const imageData = Object.assign({}, cosUploadFile, {
|
||||||
|
_cosData: cosTemporaryKey,
|
||||||
|
domainName: cosTemporaryKey.domainName,
|
||||||
|
imageUrl: cosTemporaryKey.domainName + _tempFilePaht,
|
||||||
|
path: _tempFilePaht,
|
||||||
|
});
|
||||||
|
// cosUploadFile.DomainName=cosTemporaryKey.DomainName;
|
||||||
|
return imageData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件后缀
|
||||||
|
* @param file 文件流
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
static getFileNameWithoutExtension(file: File) {
|
||||||
|
const fileName = file.name; // 获取文件名
|
||||||
|
const dotIndex = fileName.lastIndexOf("."); // 找到最后一个点的位置
|
||||||
|
|
||||||
|
if (dotIndex === -1) {
|
||||||
|
// 如果文件名中没有点,返回完整文件名
|
||||||
|
return fileName;
|
||||||
|
} else {
|
||||||
|
// 截取从开始到最后一个点之前的部分
|
||||||
|
return fileName.substring(0, dotIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 选择文件
|
||||||
|
* @returns 文件
|
||||||
|
*/
|
||||||
|
static async selectFile(): Promise<File> {
|
||||||
|
return new Promise<File>((resolve, reject) => {
|
||||||
|
const fileInput = document.createElement("input");
|
||||||
|
fileInput.type = "file";
|
||||||
|
fileInput.style.display = "none";
|
||||||
|
|
||||||
|
fileInput.addEventListener("change", function (event: any) {
|
||||||
|
const file = event.target.files[0];
|
||||||
|
if (file) {
|
||||||
|
resolve(file);
|
||||||
|
} else {
|
||||||
|
reject(new Error("No file selected"));
|
||||||
|
}
|
||||||
|
fileInput.remove();
|
||||||
|
});
|
||||||
|
document.body.appendChild(fileInput);
|
||||||
|
fileInput.click();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 图片上传
|
||||||
|
* @param imgaeId imageId
|
||||||
|
* @param imageType 图片类型
|
||||||
|
* @param modelName 模块
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
static async imageFileUpload(
|
||||||
|
imgaeId: number,
|
||||||
|
imageType: number,
|
||||||
|
modelName?: string
|
||||||
|
): Promise<any> {
|
||||||
|
//#region 创建文件选择器
|
||||||
|
const file = await this.selectFile();
|
||||||
|
if (file == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return await this.imageUpdate(file, imgaeId, imageType, modelName);
|
||||||
|
//#endregion
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 上传图片
|
||||||
|
* @param file 文件流
|
||||||
|
* @param imgaeId 图片编号
|
||||||
|
* @param imageType 图片类型
|
||||||
|
* @param modelName 模块
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
static async imageUpdate(
|
||||||
|
file: File,
|
||||||
|
imgaeId: number,
|
||||||
|
imageType: number,
|
||||||
|
modelName?: string
|
||||||
|
): Promise<any> {
|
||||||
|
const key = "updatable";
|
||||||
|
AntdvMessage.loading({ content: "上传图片中", key });
|
||||||
|
try {
|
||||||
|
if (modelName == null || modelName == "") {
|
||||||
|
if (imageType == 0) {
|
||||||
|
modelName = "images/common";
|
||||||
|
} else {
|
||||||
|
modelName = "images/common";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const fileInfo = await this.cosUploadFile(file, modelName);
|
||||||
|
if (imgaeId == undefined || imgaeId == null) {
|
||||||
|
imgaeId = 0;
|
||||||
|
}
|
||||||
|
const fromData = await TImageConfigService.findForm(imgaeId);
|
||||||
|
const _data = fromData.data;
|
||||||
|
//#region 处理数据
|
||||||
|
_data.form.url = fileInfo.imageUrl;
|
||||||
|
if (_data.form.name == null || _data.form.name == "") {
|
||||||
|
_data.form.name = Tools.getFileNameWithoutExtension(file);
|
||||||
|
}
|
||||||
|
_data.form.ossPath = fileInfo._cosData.filePath;
|
||||||
|
_data.form.region = fileInfo._cosData.bucket;
|
||||||
|
// _data.form.imageId = imgaeId;
|
||||||
|
_data.form.imageType = imageType;
|
||||||
|
//#endregion
|
||||||
|
const result = await TImageConfigService.saveForm(_data.id, _data.form);
|
||||||
|
AntdvMessage.success({ content: "上传成功", key, duration: 2 });
|
||||||
|
return { imageId: result.data, imageUrl: fileInfo.imageUrl };
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
AntdvMessage.error({ content: "上传失败", key, duration: 2 });
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Tools;
|
export default Tools;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
export default {
|
export default {
|
||||||
"login.title": "欢迎使用,HzyAdmin",
|
"login.title": "欢迎使用,寰梦后台管理",
|
||||||
"login.submit": "登录",
|
"login.submit": "登录",
|
||||||
"login.validate.username": "请输入用户名",
|
"login.validate.username": "请输入用户名",
|
||||||
"login.validate.userPassword": "请输入密码",
|
"login.validate.userPassword": "请输入密码",
|
||||||
|
|
|
||||||
|
|
@ -4,79 +4,102 @@
|
||||||
* TImageConfig服务
|
* TImageConfig服务
|
||||||
*/
|
*/
|
||||||
export default class TImageConfigService {
|
export default class TImageConfigService {
|
||||||
|
static urlPrefix = "/api/v1/admin/TImageConfig";
|
||||||
|
|
||||||
static urlPrefix = "/api/v1/admin/TImageConfig";
|
/**
|
||||||
|
* 获取数据列表
|
||||||
|
* @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 current
|
*
|
||||||
* @param pageSize
|
* @param ids
|
||||||
* @param search
|
* @returns
|
||||||
* @param searchSort
|
*/
|
||||||
* @returns
|
static deleteList(ids: string[]) {
|
||||||
*/
|
return Http.post(`${this.urlPrefix}/deleteList`, ids);
|
||||||
static findList(current: number, pageSize: number, search: any = {}, searchSort: any[] = []) {
|
}
|
||||||
return Http.post(`${this.urlPrefix}/findList`, {
|
|
||||||
page: current,
|
|
||||||
size: pageSize,
|
|
||||||
search,
|
|
||||||
searchSort
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除集合数据
|
* 查询表单
|
||||||
*
|
*
|
||||||
* @param ids
|
* @param id
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
static deleteList(ids: string[]) {
|
static findForm(id?: string | undefined | number) {
|
||||||
return Http.post(`${this.urlPrefix}/deleteList`, ids)
|
return Http.get(`${this.urlPrefix}/findForm${id ? "/" + id : ""}`);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 获取上传key
|
||||||
|
*
|
||||||
|
* @param
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
static getCosSign() {
|
||||||
|
return Http.get(`${this.urlPrefix}/GetCosSign`);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询表单
|
* 获取上传的临时token
|
||||||
*
|
*
|
||||||
* @param id
|
* @param
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
static findForm(id?: string | undefined) {
|
static getGenerateTemporaryKey(fileName?: string, modelName?: string) {
|
||||||
return Http.get(`${this.urlPrefix}/findForm${(id ? '/' + id : '')}`)
|
if (fileName != null) {
|
||||||
}
|
fileName = escape(fileName);
|
||||||
/**
|
// query
|
||||||
* 获取上传key
|
|
||||||
*
|
|
||||||
* @param
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
static getCosSign() {
|
|
||||||
return Http.get(`${this.urlPrefix}/GetCosSign`)
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 保存表单数据
|
|
||||||
*
|
|
||||||
* @param id
|
|
||||||
* @param formData
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
static saveForm(id: string | undefined, formData: any) {
|
|
||||||
return Http.post(`${this.urlPrefix}/${id ? 'update' : 'create'}`, formData)
|
|
||||||
}
|
}
|
||||||
|
return Http.get(
|
||||||
|
`${
|
||||||
|
this.urlPrefix
|
||||||
|
}/GetGenerateTemporaryKey?fileName=${fileName}&modelName=${escape(
|
||||||
|
modelName || ""
|
||||||
|
)}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 保存表单数据
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @param formData
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
static saveForm(id: string | undefined, formData: any) {
|
||||||
|
return Http.post(`${this.urlPrefix}/${id ? "update" : "create"}`, formData);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出 excel
|
* 导出 excel
|
||||||
*
|
*
|
||||||
* @param search
|
* @param search
|
||||||
* @param searchSort
|
* @param searchSort
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
static exportExcel(search: any = {}, searchSort: any[] = []) {
|
static exportExcel(search: any = {}, searchSort: any[] = []) {
|
||||||
return Http.download(`${this.urlPrefix}/exportExcel`, {
|
return Http.download(`${this.urlPrefix}/exportExcel`, {
|
||||||
page: -1,
|
page: -1,
|
||||||
size: -1,
|
size: -1,
|
||||||
search,
|
search,
|
||||||
searchSort
|
searchSort,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ class AppConsts {
|
||||||
/**
|
/**
|
||||||
* token 键值
|
* token 键值
|
||||||
*/
|
*/
|
||||||
static tokenKey: string = "Authorization_HZY_ADMIN_SPA"
|
static tokenKey: string = "Authorization_HuanMeng_ADMIN_SPA"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Guid Empty String
|
* Guid Empty String
|
||||||
|
|
@ -23,12 +23,12 @@ class AppConsts {
|
||||||
/**
|
/**
|
||||||
* 后台服务api域名
|
* 后台服务api域名
|
||||||
*/
|
*/
|
||||||
static domainServerApi: string = process.env.NODE_ENV == "production" ? "" : "http://localhost:5500"
|
static domainServerApi: string =import.meta.env.VITE_BASEURL// process.env.NODE_ENV == "production" ? "" : "http://localhost:5500"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* app 前缀 用于浏览器本地缓存 key 的前缀
|
* app 前缀 用于浏览器本地缓存 key 的前缀
|
||||||
*/
|
*/
|
||||||
static appPrefix: string = `HzyAdminAntdVue-${domainName}`
|
static appPrefix: string = `HuanMeng-${domainName}`
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于请求头部授权码key名称
|
* 用于请求头部授权码key名称
|
||||||
|
|
@ -38,7 +38,7 @@ class AppConsts {
|
||||||
/**
|
/**
|
||||||
* 系统标题
|
* 系统标题
|
||||||
*/
|
*/
|
||||||
static appTitle: string = "HzyAdmin";
|
static appTitle: string = "寰梦后台管理";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 默认首页标签页信息配置
|
* 默认首页标签页信息配置
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
import { reactive, ref } from "vue";
|
import { reactive, ref } from "vue";
|
||||||
import { FormInstance } from "ant-design-vue";
|
import { FormInstance } from "ant-design-vue";
|
||||||
import Tools from "@/core/utils/Tools";
|
import Tools from "@/core/utils/Tools";
|
||||||
import TCharacterLabelService from "@/services/apps/T_Character_Labels/TCharacterLabelService";
|
import TCharacterLabelService from "@/services/Apps/T_Character_Labels/TCharacterLabelService";
|
||||||
|
|
||||||
//定义组件事件
|
//定义组件事件
|
||||||
const props = defineProps<{ onSuccess: () => void }>();
|
const props = defineProps<{ onSuccess: () => void }>();
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import Info from "./Info.vue";
|
||||||
import Tools from "@/core/utils/Tools";
|
import Tools from "@/core/utils/Tools";
|
||||||
import PageContainer from "@/core/components/PageContainer.vue";
|
import PageContainer from "@/core/components/PageContainer.vue";
|
||||||
import TableCurd from "@/core/components/curd/TableCurd.vue";
|
import TableCurd from "@/core/components/curd/TableCurd.vue";
|
||||||
import T_CharacterService from "@/services/apps/T_Characters/T_CharacterService";
|
import T_CharacterService from "@/services/Apps/T_Characters/T_CharacterService";
|
||||||
//views/Apps/T_Characters/Index.vue
|
//views/Apps/T_Characters/Index.vue
|
||||||
defineOptions({ name: "T_CharacterIndex" });
|
defineOptions({ name: "T_CharacterIndex" });
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
import { reactive, ref } from "vue";
|
import { reactive, ref } from "vue";
|
||||||
import { FormInstance } from "ant-design-vue";
|
import { FormInstance } from "ant-design-vue";
|
||||||
import Tools from "@/core/utils/Tools";
|
import Tools from "@/core/utils/Tools";
|
||||||
import T_CharacterService from "@/services/apps/T_Characters/T_CharacterService";
|
import T_CharacterService from "@/services/Apps/T_Characters/T_CharacterService";
|
||||||
|
|
||||||
//定义组件事件
|
//定义组件事件
|
||||||
const props = defineProps<{ onSuccess: () => void }>();
|
const props = defineProps<{ onSuccess: () => void }>();
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { reactive, ref, onMounted } from "vue";
|
import { reactive, ref, onMounted } from "vue";
|
||||||
import { FormInstance } from "ant-design-vue";
|
import { FormInstance,SelectProps } from "ant-design-vue";
|
||||||
import { useAuthority } from "@/utils/Authority";
|
import { useAuthority } from "@/utils/Authority";
|
||||||
import AppIcon from "@/core/components/AppIcon.vue";
|
import AppIcon from "@/core/components/AppIcon.vue";
|
||||||
import Info from "./Info.vue";
|
import Info from "./Info.vue";
|
||||||
|
|
@ -8,14 +8,18 @@ import Tools from "@/core/utils/Tools";
|
||||||
import PageContainer from "@/core/components/PageContainer.vue";
|
import PageContainer from "@/core/components/PageContainer.vue";
|
||||||
import TableCurd from "@/core/components/curd/TableCurd.vue";
|
import TableCurd from "@/core/components/curd/TableCurd.vue";
|
||||||
import TImageConfigService from "@/services/Apps/T_Image_Configs/TImageConfigService";
|
import TImageConfigService from "@/services/Apps/T_Image_Configs/TImageConfigService";
|
||||||
|
|
||||||
defineOptions({ name: "tImageConfigIndex" });
|
|
||||||
|
|
||||||
|
defineOptions({ name: "tImageConfigIndex" });
|
||||||
|
const options = ref<SelectProps['options']>([
|
||||||
|
{ value: -1, label: '全部' },
|
||||||
|
{ value: 0, label: '默认' },
|
||||||
|
]);
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
search: {
|
search: {
|
||||||
state: false,
|
state: false,
|
||||||
vm: {
|
vm: {
|
||||||
name: undefined,
|
name: undefined,
|
||||||
|
imageType:undefined,
|
||||||
},
|
},
|
||||||
sort: [] as any[],
|
sort: [] as any[],
|
||||||
},
|
},
|
||||||
|
|
@ -25,6 +29,7 @@ const state = reactive({
|
||||||
total: 100,
|
total: 100,
|
||||||
columns: [] as any,
|
columns: [] as any,
|
||||||
data: [] as any,
|
data: [] as any,
|
||||||
|
scroll: { x: 'calc(100vw - 300px)', y: '60vh' }
|
||||||
});
|
});
|
||||||
|
|
||||||
//权限
|
//权限
|
||||||
|
|
@ -43,6 +48,80 @@ onMounted(() => {
|
||||||
findList();
|
findList();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
"fieldName": "id",
|
||||||
|
"dataIndex": "id",
|
||||||
|
"title": "id",
|
||||||
|
"show": true,
|
||||||
|
"width": "80px",
|
||||||
|
"sorter": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldName": "imageId",
|
||||||
|
"dataIndex": "imageId",
|
||||||
|
"title": "图片Id",
|
||||||
|
"show": true,
|
||||||
|
"width": "100px",
|
||||||
|
"sorter": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldName": "name",
|
||||||
|
"dataIndex": "name",
|
||||||
|
"title": "图片名称",
|
||||||
|
"show": true,
|
||||||
|
"width": "120px",
|
||||||
|
"sorter": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldName": "url",
|
||||||
|
"dataIndex": "url",
|
||||||
|
"title": "图片地址",
|
||||||
|
"show": true,
|
||||||
|
"width": "300px",
|
||||||
|
"sorter": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldName": "ossPath",
|
||||||
|
"dataIndex": "ossPath",
|
||||||
|
"title": "oss存放路径",
|
||||||
|
"show": false,
|
||||||
|
"width": "150px",
|
||||||
|
"sorter": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldName": "bucket",
|
||||||
|
"dataIndex": "bucket",
|
||||||
|
"title": "存储桶",
|
||||||
|
"show": false,
|
||||||
|
"width": "150px",
|
||||||
|
"sorter": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldName": "region",
|
||||||
|
"dataIndex": "region",
|
||||||
|
"title": "地域",
|
||||||
|
"show": false,
|
||||||
|
"width": "150px",
|
||||||
|
"sorter": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldName": "updateAt",
|
||||||
|
"dataIndex": "updateAt",
|
||||||
|
"title": "修改时间",
|
||||||
|
"show": true,
|
||||||
|
"width": "150px",
|
||||||
|
"sorter": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldName": "tenantId",
|
||||||
|
"dataIndex": "tenantId",
|
||||||
|
"title": "租户",
|
||||||
|
"show": false,
|
||||||
|
"width": "",
|
||||||
|
"sorter": true
|
||||||
|
}
|
||||||
|
]
|
||||||
/**
|
/**
|
||||||
*获取数据
|
*获取数据
|
||||||
*/
|
*/
|
||||||
|
|
@ -53,10 +132,10 @@ async function findList() {
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
if (result.code != 200) return;
|
if (result.code != 200) return;
|
||||||
state.page = result.data.page;
|
state.page = result.data.page;
|
||||||
state.size = result.data.size;
|
state.size = 50;//result.data.size;
|
||||||
state.total = result.data.total;
|
state.total = result.data.total;
|
||||||
state.columns = result.data.columns;
|
state.columns = columns,//result.data.columns;
|
||||||
state.data = result.data.dataSource;
|
state.data = result.data.dataSource;
|
||||||
// state.visible = false;
|
// state.visible = false;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
|
|
@ -95,6 +174,15 @@ async function deleteList(id?: string) {
|
||||||
function exportExcel() {
|
function exportExcel() {
|
||||||
TImageConfigService.exportExcel(state.search.vm, state.search.sort);
|
TImageConfigService.exportExcel(state.search.vm, state.search.sort);
|
||||||
}
|
}
|
||||||
|
async function imageUpdate(image: any) {
|
||||||
|
// imageUpdate
|
||||||
|
console.log(image);
|
||||||
|
|
||||||
|
const imageInfo = await Tools.imageFileUpload(image.id, image.imageType);
|
||||||
|
if (imageInfo != null) {
|
||||||
|
image.url = imageInfo.imageUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -120,6 +208,13 @@ function exportExcel() {
|
||||||
<a-input v-model:value="state.search.vm.name" placeholder="名称" />
|
<a-input v-model:value="state.search.vm.name" placeholder="名称" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
|
<a-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
|
||||||
|
<a-form-item class="mb-0" name="name" label="名称">
|
||||||
|
<a-select v-model:value="state.search.vm.imageType" :options="options">
|
||||||
|
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
<!--button-->
|
<!--button-->
|
||||||
<a-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="text-right">
|
<a-col :xs="24" :sm="12" :md="8" :lg="6" :xl="6" class="text-right">
|
||||||
<a-space :size="8">
|
<a-space :size="8">
|
||||||
|
|
@ -181,7 +276,7 @@ function exportExcel() {
|
||||||
<!-- 列设置 -->
|
<!-- 列设置 -->
|
||||||
<a-popover>
|
<a-popover>
|
||||||
<template #content>
|
<template #content>
|
||||||
<div v-for="item in state.columns.filter((w: any) => w.fieldName.substr(0, 1) != '_')" >
|
<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>
|
<a-checkbox v-model:checked="item.show">{{ item.title }}</a-checkbox>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -192,24 +287,28 @@ function exportExcel() {
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-popover>
|
</a-popover>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- table-col -->
|
<!-- table-col -->
|
||||||
<template #table-col>
|
<template #table-col>
|
||||||
<template v-for="item, index in state.columns.filter((w: any) => w.fieldName !== 'id' && w.show)"
|
<template v-for="item, index in state.columns.filter((w: any) => w.fieldName !== 'id' && w.show)"
|
||||||
:key="item.fieldName">
|
:key="item.fieldName">
|
||||||
<a-table-column :title="item.title" :data-index="item.fieldName"
|
<a-table-column :title="item.title" :data-index="item.fieldName"
|
||||||
:sorter="item.sort ? { multiple: index + 1 } : false" />
|
:sorter="item.sort ? { multiple: index + 1 } : false" />
|
||||||
|
<!-- 操作 -->
|
||||||
|
<a-table-column v-if="index == 1" title="图片" data-index="id" width="300px">
|
||||||
|
<template #default="{ record }">
|
||||||
|
<a-image :width="100" :src="record.url + '/htslt'" :preview="{ src: record.url }" />
|
||||||
|
|
||||||
|
<!-- <img :src="'https://miaoyu-1308826010.cos.ap-shanghai.myqcloud.com/'+record.ossPath+''" style="width:100px;height:100px" /> -->
|
||||||
|
<!-- <img :src="record.url" style="width:100px;height:100px" /> -->
|
||||||
|
</template>
|
||||||
|
</a-table-column>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 操作 -->
|
<!-- 操作 -->
|
||||||
<a-table-column title="图片" data-index="id">
|
<a-table-column title="操作" data-index="id" v-if="power.update || power.delete" fixed="right" width="200px">
|
||||||
<template #default="{ record }">
|
|
||||||
<img :src="'https://miaoyu-1308826010.cos.ap-shanghai.myqcloud.com/'+record.ossPath+''" style="width:100px;height:100px" />
|
|
||||||
<!-- <img :src="record.url" style="width:100px;height:100px" /> -->
|
|
||||||
</template>
|
|
||||||
</a-table-column>
|
|
||||||
<!-- 操作 -->
|
|
||||||
<a-table-column title="操作" data-index="id" v-if="power.update || power.delete">
|
|
||||||
<template #default="{ record }">
|
<template #default="{ record }">
|
||||||
|
<a href="javascript:;" @click="imageUpdate(record)" v-if="power.update">更换图片</a>
|
||||||
|
<a-divider type="vertical" />
|
||||||
<a href="javascript:;" @click="() => refInfo?.open(record.id)" v-if="power.update">编辑</a>
|
<a href="javascript:;" @click="() => refInfo?.open(record.id)" v-if="power.update">编辑</a>
|
||||||
<a-divider type="vertical" />
|
<a-divider type="vertical" />
|
||||||
<a-popconfirm title="您确定要删除?" @confirm="deleteList(record.id)" okText="确定" cancelText="取消"
|
<a-popconfirm title="您确定要删除?" @confirm="deleteList(record.id)" okText="确定" cancelText="取消"
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,11 @@ import Tools from "@/core/utils/Tools";
|
||||||
import TImageConfigService from "@/services/Apps/T_Image_Configs/TImageConfigService";
|
import TImageConfigService from "@/services/Apps/T_Image_Configs/TImageConfigService";
|
||||||
import { UploadOutlined } from '@ant-design/icons-vue';
|
import { UploadOutlined } from '@ant-design/icons-vue';
|
||||||
import { message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
import type { UploadProps } from 'ant-design-vue';
|
import type { UploadProps, SelectProps } from 'ant-design-vue';
|
||||||
|
|
||||||
|
|
||||||
|
const options = ref<SelectProps['options']>([
|
||||||
|
{ value: 0, label: '默认' },
|
||||||
|
]);
|
||||||
//定义组件事件
|
//定义组件事件
|
||||||
const props = defineProps<{ onSuccess: () => void }>();
|
const props = defineProps<{ onSuccess: () => void }>();
|
||||||
|
|
||||||
|
|
@ -31,7 +33,7 @@ defineExpose({
|
||||||
*/
|
*/
|
||||||
open: (key: string = "") => {
|
open: (key: string = "") => {
|
||||||
state.visible = true;
|
state.visible = true;
|
||||||
fileList.value=[];
|
fileList.value = [];
|
||||||
if (state.visible) {
|
if (state.visible) {
|
||||||
state.vm.id = key;
|
state.vm.id = key;
|
||||||
}
|
}
|
||||||
|
|
@ -74,7 +76,7 @@ const handleRemove: UploadProps['onRemove'] = file => {
|
||||||
fileList.value = newFileList;
|
fileList.value = newFileList;
|
||||||
};
|
};
|
||||||
|
|
||||||
const beforeUpload: UploadProps['beforeUpload'] = file => {
|
const beforeUpload: UploadProps['beforeUpload'] = async file => {
|
||||||
const isPNG = Tools.isImageFile(file.type)// file.type === 'image/png';
|
const isPNG = Tools.isImageFile(file.type)// file.type === 'image/png';
|
||||||
console.log(file.type);
|
console.log(file.type);
|
||||||
|
|
||||||
|
|
@ -82,12 +84,23 @@ const beforeUpload: UploadProps['beforeUpload'] = file => {
|
||||||
message.error(`${file.name} 不是图片文件`);
|
message.error(`${file.name} 不是图片文件`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
state.loading = true;
|
||||||
// fileList.value = [...(fileList.value || []), file];
|
// fileList.value = [...(fileList.value || []), file];
|
||||||
fileList.value = [file];
|
try {
|
||||||
console.log(fileList.value);
|
fileList.value = [file];
|
||||||
var url = Tools.getFileUrl(file);
|
console.log(fileList.value);
|
||||||
console.log(url);
|
var url = Tools.getFileUrl(file);
|
||||||
|
console.log(url);
|
||||||
|
var imageData = await Tools.cosUploadFile(file, "images/common");
|
||||||
|
console.log(imageData);
|
||||||
|
state.vm.form.url = imageData.imageUrl;
|
||||||
|
state.vm.form.name = Tools.getFileNameWithoutExtension(file);
|
||||||
|
state.vm.form.ossPath = imageData._cosData.filePath;
|
||||||
|
state.vm.form.region = imageData._cosData.bucket;
|
||||||
|
} catch (e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
state.loading = false;
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -96,7 +109,7 @@ const beforeUpload: UploadProps['beforeUpload'] = file => {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<a-modal v-model:open="state.visible" :title="state.vm.id ? '编辑' : '新建'" centered @ok="state.visible = false"
|
<a-modal v-model:open="state.visible" :title="state.vm.id ? '编辑' : '新建'" centered @ok="state.visible = false"
|
||||||
:width="500">
|
:width="800">
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<a-button type="primary" :loading="state.loading" @click="save()"> 提交</a-button>
|
<a-button type="primary" :loading="state.loading" @click="save()"> 提交</a-button>
|
||||||
<a-button @click="state.visible = false">关闭</a-button>
|
<a-button @click="state.visible = false">关闭</a-button>
|
||||||
|
|
@ -105,32 +118,49 @@ const beforeUpload: UploadProps['beforeUpload'] = file => {
|
||||||
<a-form ref="refForm" layout="vertical" :model="state.vm.form">
|
<a-form ref="refForm" layout="vertical" :model="state.vm.form">
|
||||||
<a-row :gutter="[16, 0]">
|
<a-row :gutter="[16, 0]">
|
||||||
<a-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
|
<a-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
|
||||||
<a-form-item label="租户" name="tenantId" :rules="[{ required: true, message: '请输入', trigger: 'blur' }]">
|
<a-form-item label="租户" name="tenantId">
|
||||||
<a-input v-model:value="state.vm.form.tenantId" placeholder="请输入" />
|
<a-select v-model:value="state.vm.form.tenantId">
|
||||||
|
<a-select-option value="00000000-0000-0000-0000-000000000000">妙语</a-select-option>
|
||||||
|
</a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
|
<a-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
|
||||||
<a-form-item label="图片Id" name="imageId" :rules="[{ required: true, message: '请输入', trigger: 'blur' }]">
|
<a-form-item label="图片类型" name="imageType">
|
||||||
|
<a-select v-model:value="state.vm.form.imageType" :options="options">
|
||||||
|
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
|
||||||
|
<a-form-item label="图片Id(0自动生成)" name="imageId"
|
||||||
|
:rules="[{ required: true, message: '请输入', trigger: 'blur' }]">
|
||||||
<a-input v-model:value="state.vm.form.imageId" placeholder="请输入" />
|
<a-input v-model:value="state.vm.form.imageId" placeholder="请输入" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
|
<a-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
|
||||||
<a-form-item label="图片名称" name="name" :rules="[{ required: true, message: '请输入', trigger: 'blur' }]">
|
<a-form-item label="图片名称(上传图片自动生成)" name="name"
|
||||||
|
:rules="[{ required: true, message: '请输入', trigger: 'blur' }]">
|
||||||
<a-input v-model:value="state.vm.form.name" placeholder="请输入" />
|
<a-input v-model:value="state.vm.form.name" placeholder="请输入" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
|
<a-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
|
||||||
<a-form-item label="图片地址" name="url" :rules="[{ required: true, message: '请输入', trigger: 'blur' }]">
|
<a-form-item label="图片地址(上传图片自动生成)" name="url"
|
||||||
|
:rules="[{ required: true, message: '请输入', trigger: 'blur' }]">
|
||||||
<a-input v-model:value="state.vm.form.url" placeholder="请输入" />
|
<a-input v-model:value="state.vm.form.url" placeholder="请输入" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
|
<a-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
|
||||||
<a-upload-dragger :file-list="fileList" :before-upload="beforeUpload" @remove="handleRemove" name="file"
|
<a-upload-dragger :file-list="fileList" :before-upload="beforeUpload" @remove="handleRemove" name="file"
|
||||||
:multiple="false" :showUploadList="false">
|
:multiple="false" :showUploadList="false">
|
||||||
<div v-if="fileList.length > 0">
|
<div v-if="fileList != null && fileList.length > 0">
|
||||||
<img :src="Tools.getFileUrl(fileList[0])" style="width:100%;max-height: 100%;" />
|
<a-image width="300px" height="200px" style="object-fit: contain;" :src="Tools.getFileUrl(fileList[0])"
|
||||||
|
@click.stop />
|
||||||
</div>
|
</div>
|
||||||
<div v-else >
|
<div v-else-if="state.vm.form.url != null && state.vm.form.url.length > 0">
|
||||||
|
<a-image width="300px" height="200px" style="object-fit: contain;" :src="state.vm.form.url + '/htslt'"
|
||||||
|
:preview="{ src: state.vm.form.url }" @click.stop />
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
<p class="ant-upload-drag-icon">
|
<p class="ant-upload-drag-icon">
|
||||||
<inbox-outlined></inbox-outlined>
|
<inbox-outlined></inbox-outlined>
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -139,6 +169,13 @@ const beforeUpload: UploadProps['beforeUpload'] = file => {
|
||||||
</a-upload-dragger>
|
</a-upload-dragger>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
|
<div style="display: none;">
|
||||||
|
<a-input type="hidden" v-model:value="state.vm.form.ossPath" />
|
||||||
|
<a-input type="hidden" v-model:value="state.vm.form.region" />
|
||||||
|
<a-input type="hidden" v-model:value="state.vm.form.updateAt" />
|
||||||
|
<a-input type="hidden" v-model:value="state.vm.form.createAt" />
|
||||||
|
<a-input type="hidden" v-model:value="state.vm.form.bucket" />
|
||||||
|
</div>
|
||||||
</a-form>
|
</a-form>
|
||||||
<div style="height:100px"> </div>
|
<div style="height:100px"> </div>
|
||||||
</a-spin>
|
</a-spin>
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,10 @@ import LanguageComponent from "@/locale/components/LanguageComponent.vue";
|
||||||
import i18n from "@/locale/Main.js";
|
import i18n from "@/locale/Main.js";
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
userName: "admin",
|
// userName: "admin",
|
||||||
userPassword: "123456",
|
// userPassword: "123456",
|
||||||
|
userName: "MiaoYu",
|
||||||
|
userPassword: "MiaoYu",
|
||||||
});
|
});
|
||||||
const inputPassword = ref<HTMLElement | null>(null);
|
const inputPassword = ref<HTMLElement | null>(null);
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ export default defineConfig({
|
||||||
* 生产环境默认:client 文件夹包起来
|
* 生产环境默认:client 文件夹包起来
|
||||||
* 开发环境默认:/
|
* 开发环境默认:/
|
||||||
*/
|
*/
|
||||||
base: process.env.NODE_ENV == "production" ? "/client/" : "/",
|
base: process.env.VITE_BASE, // process.env.NODE_ENV == "production" ? "/client/" : "/",
|
||||||
server: {
|
server: {
|
||||||
port: 5501,
|
port: 5501,
|
||||||
host: true,
|
host: true,
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,14 @@
|
||||||
|
using HZY.Framework.Repository.EntityFramework.Extensions;
|
||||||
|
|
||||||
using IdGen;
|
using IdGen;
|
||||||
|
|
||||||
|
using MiaoYu.Api.Admin.Models.Dtos.Apps.Cos;
|
||||||
|
using MiaoYu.Core.Cos.Models;
|
||||||
using MiaoYu.Core.Cos.Services;
|
using MiaoYu.Core.Cos.Services;
|
||||||
using MiaoYu.Repository.ChatAI.Admin.Entities;
|
using MiaoYu.Repository.ChatAI.Admin.Entities;
|
||||||
|
|
||||||
using NPOI.SS.Formula.Functions;
|
using NPOI.SS.Formula.Functions;
|
||||||
|
using NPOI.Util;
|
||||||
namespace MiaoYu.Api.Admin.ApplicationServices.Apps;
|
namespace MiaoYu.Api.Admin.ApplicationServices.Apps;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -28,6 +33,7 @@ public class TImageConfigService : ApplicationService<IRepository<T_Image_Config
|
||||||
{
|
{
|
||||||
var query = this._defaultRepository.Select
|
var query = this._defaultRepository.Select
|
||||||
.WhereIf(!string.IsNullOrWhiteSpace(pagingSearchInput.Search?.Name), w => w.Name.Contains(pagingSearchInput.Search.Name ?? ""))
|
.WhereIf(!string.IsNullOrWhiteSpace(pagingSearchInput.Search?.Name), w => w.Name.Contains(pagingSearchInput.Search.Name ?? ""))
|
||||||
|
.WhereIf(pagingSearchInput.Search?.ImageType > -1, w => w.ImageType == pagingSearchInput.Search.ImageType)
|
||||||
.OrderByDescending(w => w.Id)
|
.OrderByDescending(w => w.Id)
|
||||||
.Select(w => new
|
.Select(w => new
|
||||||
{
|
{
|
||||||
|
|
@ -40,6 +46,7 @@ public class TImageConfigService : ApplicationService<IRepository<T_Image_Config
|
||||||
w.Region,
|
w.Region,
|
||||||
w.UpdateAt,
|
w.UpdateAt,
|
||||||
w.TenantId,
|
w.TenantId,
|
||||||
|
w.ImageType
|
||||||
//w.LastModificationTime,
|
//w.LastModificationTime,
|
||||||
//w.CreationTime
|
//w.CreationTime
|
||||||
})
|
})
|
||||||
|
|
@ -91,20 +98,24 @@ public class TImageConfigService : ApplicationService<IRepository<T_Image_Config
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="form">form</param>
|
/// <param name="form">form</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<T_Image_Config> SaveFormAsync(T_Image_Config form)
|
public async Task<T_Image_Config> SaveFormAsync(T_Image_Config form, bool isUpdate)
|
||||||
{
|
{
|
||||||
form.UpdateAt = DateTime.Now;
|
form.UpdateAt = DateTime.Now;
|
||||||
form.CreateAt = DateTime.Now;
|
if (form.CreateAt == DateTime.MinValue)
|
||||||
var isUpdate = false;
|
|
||||||
if (form.Id != 0)
|
|
||||||
{
|
{
|
||||||
var _tempform = this._defaultRepository.FindById(form.Id);
|
form.CreateAt = DateTime.Now;
|
||||||
if (_tempform != null)
|
|
||||||
{
|
|
||||||
form.CreateAt = _tempform.CreateAt;
|
|
||||||
isUpdate = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//var isUpdate = false;
|
||||||
|
//if (form.Id != 0)
|
||||||
|
//{
|
||||||
|
// var _tempform = this._defaultRepository.FindById(form.Id);
|
||||||
|
// if (_tempform != null)
|
||||||
|
// {
|
||||||
|
// form.CreateAt = _tempform.CreateAt;
|
||||||
|
// isUpdate = true;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
var x = await this._defaultRepository.InsertOrUpdateAsync(form);
|
var x = await this._defaultRepository.InsertOrUpdateAsync(form);
|
||||||
if (x.ImageId == 0 && !isUpdate)
|
if (x.ImageId == 0 && !isUpdate)
|
||||||
{
|
{
|
||||||
|
|
@ -130,10 +141,48 @@ public class TImageConfigService : ApplicationService<IRepository<T_Image_Config
|
||||||
/// 获取签名
|
/// 获取签名
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public string GetCosSign() {
|
public string GetCosSign()
|
||||||
var (sign,ex) = codeCosService.GenerateSignURL(new MiaoYu.Core.Cos.Models.CosGenerateSign());
|
{
|
||||||
|
var (sign, ex) = codeCosService.GenerateSignURL(new MiaoYu.Core.Cos.Models.CosGenerateSign());
|
||||||
return sign;
|
return sign;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取临时签名
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public GenerateTemporaryModel GetGenerateTemporaryKey(string fileName = "", string modelName = "")
|
||||||
|
{
|
||||||
|
var t = new CosGenerateSign()
|
||||||
|
{
|
||||||
|
Prefixes = "miaoyu"
|
||||||
|
};
|
||||||
|
if (string.IsNullOrEmpty(modelName))
|
||||||
|
{
|
||||||
|
modelName = $"images";
|
||||||
|
}
|
||||||
|
var tempFile = fileName;
|
||||||
|
if (!string.IsNullOrEmpty(tempFile))
|
||||||
|
{
|
||||||
|
var ext = Path.GetExtension(tempFile);
|
||||||
|
if (!string.IsNullOrEmpty(ext))
|
||||||
|
{
|
||||||
|
Random random = new Random();
|
||||||
|
|
||||||
|
tempFile = $"{DateTime.Now.ToUnixTimeSeconds()}{ext}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var model = codeCosService.GenerateTemporaryKey(t);
|
||||||
|
//
|
||||||
|
GenerateTemporaryModel generateTemporaryModel = model.CopyObject<CodeCosGenerateTemporaryKeyEntity, GenerateTemporaryModel>() ?? new GenerateTemporaryModel();
|
||||||
|
generateTemporaryModel.Bucket = t.Bucket + "-" + t.AppId;
|
||||||
|
generateTemporaryModel.Region = t.Region;
|
||||||
|
generateTemporaryModel.Prefixes = t.Prefixes;
|
||||||
|
generateTemporaryModel.FilePath = $"{t.Prefixes}/{modelName}/{DateTime.Now.ToString("yyyMMdd")}/{tempFile}";
|
||||||
|
generateTemporaryModel.DomainName = "https://cos.shhuanmeng.com/";
|
||||||
|
return generateTemporaryModel;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
using MiaoYu.Api.Admin.ApplicationServices.Apps;
|
using MiaoYu.Api.Admin.ApplicationServices.Apps;
|
||||||
|
using MiaoYu.Api.Admin.Models.Dtos.Apps.Cos;
|
||||||
|
using MiaoYu.Core.Cos.Models;
|
||||||
using MiaoYu.Repository.ChatAI.Admin.Entities;
|
using MiaoYu.Repository.ChatAI.Admin.Entities;
|
||||||
namespace MiaoYu.Api.Admin.Controllers.Apps;
|
namespace MiaoYu.Api.Admin.Controllers.Apps;
|
||||||
|
|
||||||
|
|
@ -60,9 +62,13 @@ public class TImageConfigController : AdminControllerBase<TImageConfigService>
|
||||||
[ActionDescriptor(PermissionFunctionConsts.Function_Insert, DisplayName = "创建表单")]
|
[ActionDescriptor(PermissionFunctionConsts.Function_Insert, DisplayName = "创建表单")]
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[ApiCheckModel]
|
[ApiCheckModel]
|
||||||
public Task CreateAsync([FromBody] T_Image_Config form)
|
public async Task<int> CreateAsync([FromBody] T_Image_Config form)
|
||||||
{
|
{
|
||||||
return this._defaultService.SaveFormAsync(form);
|
|
||||||
|
form.UpdateAt = DateTime.Now;
|
||||||
|
form.CreateAt = DateTime.Now;
|
||||||
|
var image = await this._defaultService.SaveFormAsync(form,false);
|
||||||
|
return image?.ImageId ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -74,9 +80,11 @@ public class TImageConfigController : AdminControllerBase<TImageConfigService>
|
||||||
[ActionDescriptor(PermissionFunctionConsts.Function_Update, DisplayName = "编辑表单")]
|
[ActionDescriptor(PermissionFunctionConsts.Function_Update, DisplayName = "编辑表单")]
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[ApiCheckModel]
|
[ApiCheckModel]
|
||||||
public Task UpdateAsync([FromBody] T_Image_Config form)
|
public async Task<int> UpdateAsync([FromBody] T_Image_Config form)
|
||||||
{
|
{
|
||||||
return this._defaultService.SaveFormAsync(form);
|
form.UpdateAt = DateTime.Now;
|
||||||
|
var image = await this._defaultService.SaveFormAsync(form, true);
|
||||||
|
return image?.ImageId ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -94,7 +102,7 @@ public class TImageConfigController : AdminControllerBase<TImageConfigService>
|
||||||
base.HttpContext.DownLoadFile(data, Tools.GetFileContentType[".xls"].ToStr(), name);
|
base.HttpContext.DownLoadFile(data, Tools.GetFileContentType[".xls"].ToStr(), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -106,5 +114,17 @@ public class TImageConfigController : AdminControllerBase<TImageConfigService>
|
||||||
return this._defaultService.GetCosSign();
|
return this._defaultService.GetCosSign();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取临时密钥
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet]
|
||||||
|
[AllowAnonymous]
|
||||||
|
[ActionDescriptor(DisplayName = "获取cos临时密钥")]
|
||||||
|
public GenerateTemporaryModel GetGenerateTemporaryKey(string fileName = "", string modelName = "")
|
||||||
|
{
|
||||||
|
return this._defaultService.GetGenerateTemporaryKey(fileName, modelName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -195,7 +195,7 @@
|
||||||
<param name="id">id</param>
|
<param name="id">id</param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:MiaoYu.Api.Admin.ApplicationServices.Apps.TImageConfigService.SaveFormAsync(MiaoYu.Repository.ChatAI.Admin.Entities.T_Image_Config)">
|
<member name="M:MiaoYu.Api.Admin.ApplicationServices.Apps.TImageConfigService.SaveFormAsync(MiaoYu.Repository.ChatAI.Admin.Entities.T_Image_Config,System.Boolean)">
|
||||||
<summary>
|
<summary>
|
||||||
保存数据
|
保存数据
|
||||||
</summary>
|
</summary>
|
||||||
|
|
@ -215,6 +215,12 @@
|
||||||
</summary>
|
</summary>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:MiaoYu.Api.Admin.ApplicationServices.Apps.TImageConfigService.GetGenerateTemporaryKey(System.String,System.String)">
|
||||||
|
<summary>
|
||||||
|
获取临时签名
|
||||||
|
</summary>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="T:MiaoYu.Api.Admin.ApplicationServices.Apps.T_CharacterService">
|
<member name="T:MiaoYu.Api.Admin.ApplicationServices.Apps.T_CharacterService">
|
||||||
<summary>
|
<summary>
|
||||||
人物表 服务 T_CharacterService
|
人物表 服务 T_CharacterService
|
||||||
|
|
@ -1531,6 +1537,12 @@
|
||||||
</summary>
|
</summary>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:MiaoYu.Api.Admin.Controllers.Apps.TImageConfigController.GetGenerateTemporaryKey(System.String,System.String)">
|
||||||
|
<summary>
|
||||||
|
获取临时密钥
|
||||||
|
</summary>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="T:MiaoYu.Api.Admin.Controllers.Apps.T_CharacterController">
|
<member name="T:MiaoYu.Api.Admin.Controllers.Apps.T_CharacterController">
|
||||||
<summary>
|
<summary>
|
||||||
人物表 控制器
|
人物表 控制器
|
||||||
|
|
@ -2489,6 +2501,36 @@
|
||||||
</summary>
|
</summary>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="T:MiaoYu.Api.Admin.Models.Dtos.Apps.Cos.GenerateTemporaryModel">
|
||||||
|
<summary>
|
||||||
|
cos临时密钥
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:MiaoYu.Api.Admin.Models.Dtos.Apps.Cos.GenerateTemporaryModel.Bucket">
|
||||||
|
<summary>
|
||||||
|
存储桶名称
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:MiaoYu.Api.Admin.Models.Dtos.Apps.Cos.GenerateTemporaryModel.Region">
|
||||||
|
<summary>
|
||||||
|
关于地域的详情见
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:MiaoYu.Api.Admin.Models.Dtos.Apps.Cos.GenerateTemporaryModel.Prefixes">
|
||||||
|
<summary>
|
||||||
|
前缀
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:MiaoYu.Api.Admin.Models.Dtos.Apps.Cos.GenerateTemporaryModel.FilePath">
|
||||||
|
<summary>
|
||||||
|
文件路径
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:MiaoYu.Api.Admin.Models.Dtos.Apps.Cos.GenerateTemporaryModel.DomainName">
|
||||||
|
<summary>
|
||||||
|
域名
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
<member name="T:MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenContextDto">
|
<member name="T:MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenContextDto">
|
||||||
<summary>
|
<summary>
|
||||||
生成代码上下文
|
生成代码上下文
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
using MiaoYu.Core.Cos.Models;
|
||||||
|
|
||||||
|
namespace MiaoYu.Api.Admin.Models.Dtos.Apps.Cos
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// cos临时密钥
|
||||||
|
/// </summary>
|
||||||
|
public class GenerateTemporaryModel : CodeCosGenerateTemporaryKeyEntity
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 存储桶名称
|
||||||
|
/// </summary>
|
||||||
|
public string Bucket { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 关于地域的详情见
|
||||||
|
/// </summary>
|
||||||
|
public string Region { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 前缀
|
||||||
|
/// </summary>
|
||||||
|
public string Prefixes { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 文件路径
|
||||||
|
/// </summary>
|
||||||
|
public string FilePath { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 域名
|
||||||
|
/// </summary>
|
||||||
|
public string DomainName { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -44,8 +44,8 @@
|
||||||
},
|
},
|
||||||
//腾讯云配置
|
//腾讯云配置
|
||||||
"TencentCloud": {
|
"TencentCloud": {
|
||||||
"SecretId": "AKIDLbhdP0Vs57yd7QZWu8A2jFbno8JKBUp6",
|
"SecretId": "AKIDVyMfzKZdZP8zkNyOdsFuSsBJDB7EScs0",
|
||||||
"SecretKey": "MlP5tcUG6mdj7TwOpDWnZNFGIrJY8eH4",
|
"SecretKey": "89GWr7JPWYTL8ueHlAYowGZnvzKZjqs9",
|
||||||
"AppId": "1308826010",
|
"AppId": "1308826010",
|
||||||
"SMSCode": {
|
"SMSCode": {
|
||||||
//请求方式
|
//请求方式
|
||||||
|
|
@ -61,8 +61,8 @@
|
||||||
},
|
},
|
||||||
"CosConfig": {
|
"CosConfig": {
|
||||||
"AppId": "1308826010",
|
"AppId": "1308826010",
|
||||||
"SecretId": "AKIDLbhdP0Vs57yd7QZWu8A2jFbno8JKBUp6",
|
"SecretId": "AKIDVyMfzKZdZP8zkNyOdsFuSsBJDB7EScs0",
|
||||||
"SecretKey": "MlP5tcUG6mdj7TwOpDWnZNFGIrJY8eH4",
|
"SecretKey": "89GWr7JPWYTL8ueHlAYowGZnvzKZjqs9",
|
||||||
"DurationSecond": "300",
|
"DurationSecond": "300",
|
||||||
"Region": "ap-shanghai",
|
"Region": "ap-shanghai",
|
||||||
"Bucket": "miaoyu"
|
"Bucket": "miaoyu"
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
|
||||||
<PackageReference Include="Tencent.QCloud.Cos.Sdk" Version="5.4.38" />
|
<PackageReference Include="Tencent.QCloud.Cos.Sdk" Version="5.4.38" />
|
||||||
|
<PackageReference Include="Tencent.QCloud.Cos.Sts.Sdk" Version="3.0.5" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,13 @@ namespace MiaoYu.Core.Cos.Models
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 生成签名
|
/// 生成签名
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CosGenerateSign: TencentCosConfig
|
public class CosGenerateSign : TencentCosConfig
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 允许的前缀
|
||||||
|
/// </summary>
|
||||||
|
public string Prefixes { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace MiaoYu.Core.Cos.Models
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取临时访问凭证
|
||||||
|
/// </summary>
|
||||||
|
public class CodeCosGenerateTemporaryKeyEntity
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 临时访问凭证
|
||||||
|
/// </summary>
|
||||||
|
public Credentials Credentials { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 临时访问凭证有效的时间,返回 Unix 时间戳,精确到秒
|
||||||
|
/// </summary>
|
||||||
|
public string Expiration { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 临时访问凭证有效的时间,以 iso8601 格式的 UTC 时间表示 注意:此字段可能返回 null,表示取不到有效值。
|
||||||
|
/// </summary>
|
||||||
|
public long ExpiredTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 开始时间
|
||||||
|
/// </summary>
|
||||||
|
public long StartTime { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 唯一请求 ID,由服务端生成,每次请求都会返回(若请求因其他原因未能抵达服务端,则该次请求不会获得 RequestId)。定位问题时需要提供该次请求的 RequestId。
|
||||||
|
/// </summary>
|
||||||
|
public string RequestId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 临时访问凭证
|
||||||
|
/// </summary>
|
||||||
|
public class Credentials
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Token
|
||||||
|
/// </summary>
|
||||||
|
public string Token { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// SecretId
|
||||||
|
/// </summary>
|
||||||
|
public string TmpSecretId { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// SecretKey
|
||||||
|
/// </summary>
|
||||||
|
public string TmpSecretKey { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -4,7 +4,7 @@ namespace MiaoYu.Core.Cos.Services;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface ICodeCosService:ISingletonDependency //:ITransientDependency: IScopedDependency
|
public interface ICodeCosService : ISingletonDependency //:ITransientDependency: IScopedDependency
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 返回签名地址
|
/// 返回签名地址
|
||||||
|
|
@ -12,5 +12,11 @@ public interface ICodeCosService:ISingletonDependency //:ITransientDependency: I
|
||||||
/// <param name="cosGenerateSign"></param>
|
/// <param name="cosGenerateSign"></param>
|
||||||
/// <returns>sign签名值,过期时间</returns>
|
/// <returns>sign签名值,过期时间</returns>
|
||||||
(string sign, int expiredSeconds) GenerateSignURL(CosGenerateSign cosGenerateSign);
|
(string sign, int expiredSeconds) GenerateSignURL(CosGenerateSign cosGenerateSign);
|
||||||
|
/// <summary>
|
||||||
|
/// 生成临时密钥
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
CodeCosGenerateTemporaryKeyEntity GenerateTemporaryKey(CosGenerateSign cosGenerateSign);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,10 @@ using System.Threading.Tasks;
|
||||||
using COSXML.Auth;
|
using COSXML.Auth;
|
||||||
using MiaoYu.Core.Cos.Configs;
|
using MiaoYu.Core.Cos.Configs;
|
||||||
using NPOI.SS.Formula.Functions;
|
using NPOI.SS.Formula.Functions;
|
||||||
|
using COSSTS;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Collections;
|
||||||
|
using TencentCloud.Tci.V20190318.Models;
|
||||||
|
|
||||||
namespace MiaoYu.Core.Cos.Services.Impl
|
namespace MiaoYu.Core.Cos.Services.Impl
|
||||||
{
|
{
|
||||||
|
|
@ -77,5 +81,70 @@ namespace MiaoYu.Core.Cos.Services.Impl
|
||||||
}
|
}
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="cosGenerateSign"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public CodeCosGenerateTemporaryKeyEntity GenerateTemporaryKey(CosGenerateSign cosGenerateSign)
|
||||||
|
{
|
||||||
|
#region 验证区域
|
||||||
|
if (string.IsNullOrEmpty(cosGenerateSign.Bucket))
|
||||||
|
{
|
||||||
|
cosGenerateSign.Bucket = tencentCosConfig.Bucket;
|
||||||
|
}
|
||||||
|
if (string.IsNullOrEmpty(cosGenerateSign.AppId))
|
||||||
|
{
|
||||||
|
cosGenerateSign.AppId = tencentCosConfig.AppId;
|
||||||
|
}
|
||||||
|
if (string.IsNullOrEmpty(cosGenerateSign.Region))
|
||||||
|
{
|
||||||
|
cosGenerateSign.Region = tencentCosConfig.Region;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
string bucket = cosGenerateSign.Bucket + "-" + cosGenerateSign.AppId; // 您的 bucket
|
||||||
|
|
||||||
|
string region = cosGenerateSign.Region;// bucket 所在区域
|
||||||
|
|
||||||
|
// 改成允许的路径前缀,根据自己网站的用户判断允许上传的路径,例子:a.jpg 或者 a/* 或者 * (通配符*存在重大安全风险, 谨慎评估使用)
|
||||||
|
string allowPrefix = "*";
|
||||||
|
/*
|
||||||
|
* 密钥的权限列表。必须在这里指定本次临时密钥所需要的权限。权限列表请参见 https://cloud.tencent.com/document/product/436/31923
|
||||||
|
* 规则为 {project}:{interfaceName}
|
||||||
|
* project : 产品缩写 cos相关授权为值为cos,数据万象(数据处理)相关授权值为ci
|
||||||
|
* 授权所有接口用*表示,例如 cos:*,ci:*
|
||||||
|
*/
|
||||||
|
string[] allowActions = new string[]
|
||||||
|
{
|
||||||
|
"name/cos:PutObject",
|
||||||
|
"name/cos:PostObject",
|
||||||
|
"name/cos:InitiateMultipartUpload",
|
||||||
|
"name/cos:ListMultipartUploads",
|
||||||
|
"name/cos:ListParts",
|
||||||
|
"name/cos:UploadPart",
|
||||||
|
"name/cos:CompleteMultipartUpload"
|
||||||
|
};
|
||||||
|
|
||||||
|
//设置参数
|
||||||
|
Dictionary<string, object> values = new Dictionary<string, object>();
|
||||||
|
values.Add("bucket", bucket);
|
||||||
|
values.Add("region", region);
|
||||||
|
values.Add("allowPrefix", allowPrefix);
|
||||||
|
// 也可以通过 allowPrefixes 指定路径前缀的集合
|
||||||
|
values.Add("allowPrefixes", new string[] {
|
||||||
|
string.IsNullOrEmpty(cosGenerateSign.Prefixes)?"miaoyu/*":cosGenerateSign.Prefixes,
|
||||||
|
});
|
||||||
|
values.Add("allowActions", allowActions);
|
||||||
|
values.Add("durationSeconds", 600);//指定临时证书的有效期, 参考 https://cloud.tencent.com/document/product/1312/48195
|
||||||
|
values.Add("secretId", tencentCosConfig.SecretId);
|
||||||
|
values.Add("secretKey", tencentCosConfig.SecretKey);
|
||||||
|
|
||||||
|
Dictionary<string, object> credential = STSClient.genCredential(values); //返回值说明见README.md
|
||||||
|
var json = JsonConvert.SerializeObject(credential);
|
||||||
|
var person = JsonConvert.DeserializeObject<CodeCosGenerateTemporaryKeyEntity>(json);
|
||||||
|
return person;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -657,6 +657,13 @@
|
||||||
<param name="sourceObj"></param>
|
<param name="sourceObj"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:MiaoYu.Core.Tools.CopyObject``2(``0)">
|
||||||
|
<summary>
|
||||||
|
复制对象
|
||||||
|
</summary>
|
||||||
|
<param name="sourceObj"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
<member name="M:MiaoYu.Core.Tools.ToJsonString``1(``0)">
|
<member name="M:MiaoYu.Core.Tools.ToJsonString``1(``0)">
|
||||||
<summary>
|
<summary>
|
||||||
转 json string
|
转 json string
|
||||||
|
|
|
||||||
|
|
@ -862,6 +862,16 @@ public static class Tools
|
||||||
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(sourceObj));
|
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(sourceObj));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 复制对象
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sourceObj"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static T1? CopyObject<T, T1>(this T sourceObj)
|
||||||
|
{
|
||||||
|
return JsonConvert.DeserializeObject<T1>(JsonConvert.SerializeObject(sourceObj));
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 转 json string
|
/// 转 json string
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,9 @@ namespace MiaoYu.Repository.ChatAI.Admin.Entities
|
||||||
public partial class T_Image_Config : DefaultEntityV4
|
public partial class T_Image_Config : DefaultEntityV4
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 图片Id
|
/// 图片Id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -27,13 +30,12 @@ namespace MiaoYu.Repository.ChatAI.Admin.Entities
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 图片名称
|
/// 图片名称
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Name { get; set; }
|
public string Name { get; set; } = null!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 图片url
|
/// 图片地址
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
public string Url { get; set; } = null!;
|
||||||
public string Url { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建时间
|
/// 创建时间
|
||||||
|
|
@ -60,6 +62,11 @@ namespace MiaoYu.Repository.ChatAI.Admin.Entities
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Region { get; set; }
|
public string? Region { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 图片类型
|
||||||
|
/// </summary>
|
||||||
|
public int ImageType { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@
|
||||||
</member>
|
</member>
|
||||||
<member name="P:MiaoYu.Repository.ChatAI.Admin.Entities.T_Image_Config.Url">
|
<member name="P:MiaoYu.Repository.ChatAI.Admin.Entities.T_Image_Config.Url">
|
||||||
<summary>
|
<summary>
|
||||||
图片url
|
图片地址
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
<member name="P:MiaoYu.Repository.ChatAI.Admin.Entities.T_Image_Config.CreateAt">
|
<member name="P:MiaoYu.Repository.ChatAI.Admin.Entities.T_Image_Config.CreateAt">
|
||||||
|
|
@ -162,5 +162,10 @@
|
||||||
地域
|
地域
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="P:MiaoYu.Repository.ChatAI.Admin.Entities.T_Image_Config.ImageType">
|
||||||
|
<summary>
|
||||||
|
图片类型
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
</members>
|
</members>
|
||||||
</doc>
|
</doc>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user