mirror of
https://github.com/bufanyun/hotgo.git
synced 2025-12-30 03:56:02 +08:00
发布v2.15.7版本,更新内容请查看:https://github.com/bufanyun/hotgo/tree/v2.0/docs/guide-zh-CN/addon-version-upgrade.md
This commit is contained in:
@@ -44,9 +44,9 @@
|
||||
primaryColorHover: lightenStr,
|
||||
primaryColorPressed: lightenStr,
|
||||
// 纵向滚动条宽
|
||||
scrollbarWidth: '10px',
|
||||
scrollbarWidth: '8px',
|
||||
// 横向滚动条高
|
||||
scrollbarHeight: '10px',
|
||||
scrollbarHeight: '8px',
|
||||
},
|
||||
LoadingBar: {
|
||||
colorLoading: appTheme,
|
||||
|
||||
@@ -40,13 +40,6 @@ export function View(params) {
|
||||
});
|
||||
}
|
||||
|
||||
export function ChooserOption() {
|
||||
return http.request({
|
||||
url: '/attachment/chooserOption',
|
||||
method: 'GET',
|
||||
});
|
||||
}
|
||||
|
||||
export function ClearKind(params) {
|
||||
return http.request({
|
||||
url: '/attachment/clearKind',
|
||||
|
||||
@@ -27,6 +27,15 @@ export function Edit(params) {
|
||||
});
|
||||
}
|
||||
|
||||
// 修改CURD列表状态
|
||||
export function Status(params) {
|
||||
return http.request({
|
||||
url: '/curdDemo/status',
|
||||
method: 'POST',
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
// 操作CURD列表开关
|
||||
export function Switch(params) {
|
||||
return http.request({
|
||||
@@ -56,4 +65,4 @@ export function MaxSort() {
|
||||
// 导出CURD列表
|
||||
export function Export(params) {
|
||||
jumpExport('/curdDemo/export', params);
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
<n-grid :x-gap="5" :y-gap="5" :cols="pageGridCols" responsive="screen">
|
||||
<n-gi :span="2">
|
||||
<n-menu
|
||||
:options="options.kind"
|
||||
:options="generateKindOptions()"
|
||||
style="width: 100%"
|
||||
:default-value="defaultKindValue"
|
||||
:on-update:value="handleUpdateKind"
|
||||
@@ -60,8 +60,8 @@
|
||||
</n-ellipsis>
|
||||
</template>
|
||||
|
||||
<template #action style="padding: 5px">
|
||||
<n-space justify="center">
|
||||
<template #action>
|
||||
<n-space justify="center" style="padding: 5px">
|
||||
<n-button
|
||||
strong
|
||||
secondary
|
||||
@@ -75,7 +75,6 @@
|
||||
<DownloadOutlined v-else />
|
||||
</n-icon>
|
||||
</template>
|
||||
|
||||
{{ item.kind === 'image' ? '预览' : '下载' }}
|
||||
</n-button>
|
||||
<n-button
|
||||
@@ -130,14 +129,15 @@
|
||||
import { defRangeShortcuts } from '@/utils/dateUtil';
|
||||
import { EyeOutlined, DeleteOutlined, DownloadOutlined, ClearOutlined } from '@vicons/antd';
|
||||
import { useProjectSettingStore } from '@/store/modules/projectSetting';
|
||||
import { ChooserOption, ClearKind, Delete, List } from '@/api/apply/attachment';
|
||||
import { ClearKind, Delete, List } from '@/api/apply/attachment';
|
||||
import { constantRouterIcon } from '@/router/router-icons';
|
||||
import { errorImg } from '@/utils/hotgo';
|
||||
import { getFileExt } from '@/utils/urlUtils';
|
||||
import { renderIcon } from '@/utils';
|
||||
import { Attachment, FileType, KindOption, KindRawOption } from './model';
|
||||
import { Attachment, FileType, KindOption } from './model';
|
||||
import Preview from './Preview.vue';
|
||||
import { VNode } from '@vue/runtime-core';
|
||||
import { VNode } from 'vue';
|
||||
import { Option, useDictStore } from '@/store/modules/dict';
|
||||
|
||||
export interface Props {
|
||||
fileList: string[] | null;
|
||||
@@ -152,6 +152,7 @@
|
||||
});
|
||||
|
||||
const emit = defineEmits(['saveChange']);
|
||||
const dict = useDictStore();
|
||||
const settingStore = useProjectSettingStore();
|
||||
const message = useMessage();
|
||||
const dialog = useDialog();
|
||||
@@ -191,7 +192,7 @@
|
||||
defaultValue: null,
|
||||
componentProps: {
|
||||
placeholder: '请选择上传驱动',
|
||||
options: options.value.drive,
|
||||
options: dict.getOption('config_upload_drive'),
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -250,9 +251,6 @@
|
||||
reloadTable();
|
||||
});
|
||||
},
|
||||
onNegativeClick: () => {
|
||||
// message.error('取消');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -295,14 +293,14 @@
|
||||
return selectList.value.some((selected) => selected === item.fileUrl);
|
||||
}
|
||||
|
||||
function generateKindOptions(kinds: KindRawOption[]): any {
|
||||
function generateKindOptions(): any {
|
||||
const option: KindOption[] = [];
|
||||
kinds.forEach((item: KindRawOption) => {
|
||||
dict.getOptionUnRef('AttachmentKindOption').forEach((item: Option) => {
|
||||
const data: KindOption = {
|
||||
label: () => h(NEllipsis, null, { default: () => item.label }),
|
||||
key: item.key,
|
||||
key: item.key.toString(),
|
||||
extra: () => (item.key !== '' ? createExtraContent(item) : null),
|
||||
icon: constantRouterIcon[item.icon] || null,
|
||||
icon: constantRouterIcon[item.extra] || null,
|
||||
disabled: isDisabledKindOption(item),
|
||||
};
|
||||
option.push(data);
|
||||
@@ -310,14 +308,14 @@
|
||||
return option;
|
||||
}
|
||||
|
||||
function isDisabledKindOption(item: KindRawOption): boolean {
|
||||
function isDisabledKindOption(item: Option): boolean {
|
||||
if (props.fileType === 'default') {
|
||||
return false;
|
||||
}
|
||||
return item.key !== props.fileType;
|
||||
}
|
||||
|
||||
function createExtraContent(item: KindRawOption): VNode {
|
||||
function createExtraContent(item: Option): VNode {
|
||||
return h(
|
||||
NButton,
|
||||
{
|
||||
@@ -338,9 +336,6 @@
|
||||
reloadTable();
|
||||
});
|
||||
},
|
||||
onNegativeClick: () => {
|
||||
// message.error('取消');
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
@@ -348,20 +343,6 @@
|
||||
);
|
||||
}
|
||||
|
||||
async function loadOptions() {
|
||||
let tmpOptions = await ChooserOption();
|
||||
options.value.drive = tmpOptions.drive;
|
||||
options.value.kind = generateKindOptions(tmpOptions.kind);
|
||||
|
||||
for (const item of schemas.value) {
|
||||
switch (item.field) {
|
||||
case 'drive':
|
||||
item.componentProps.options = options.value.drive;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function loadList() {
|
||||
loading.value = true;
|
||||
List({ ...params.value, ...searchFormRef.value?.formModel }).then((res) => {
|
||||
@@ -392,8 +373,12 @@
|
||||
loadList();
|
||||
}
|
||||
|
||||
function loadOptions() {
|
||||
dict.loadOptions(['AttachmentKindOption', 'config_upload_drive']);
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await loadOptions();
|
||||
loadOptions();
|
||||
loadList();
|
||||
});
|
||||
|
||||
|
||||
@@ -21,12 +21,6 @@ export type Attachment = {
|
||||
sizeFormat: string;
|
||||
};
|
||||
|
||||
export interface KindRawOption {
|
||||
key: string;
|
||||
label: string;
|
||||
icon: string;
|
||||
}
|
||||
|
||||
export interface KindOption {
|
||||
key: string;
|
||||
label: any;
|
||||
|
||||
124
web/src/enums/localDictEnum.ts
Normal file
124
web/src/enums/localDictEnum.ts
Normal file
@@ -0,0 +1,124 @@
|
||||
// 本地字典
|
||||
// 一些不需要放在服务端注册的字典,也可以在这里进行注册
|
||||
|
||||
import { DictOptions, Option } from '@/store/modules/dict';
|
||||
|
||||
export const noticeTypeOptions: Option[] = [
|
||||
{
|
||||
key: 1,
|
||||
value: 1,
|
||||
label: '通知',
|
||||
listClass: 'warning',
|
||||
extra: null,
|
||||
},
|
||||
{
|
||||
key: 2,
|
||||
value: 2,
|
||||
label: '公告',
|
||||
listClass: 'error',
|
||||
extra: null,
|
||||
},
|
||||
{
|
||||
key: 3,
|
||||
value: 3,
|
||||
label: '私信',
|
||||
listClass: 'info',
|
||||
extra: null,
|
||||
},
|
||||
];
|
||||
|
||||
export const noticeTagOptions: Option[] = [
|
||||
{
|
||||
value: 0,
|
||||
label: '无标签',
|
||||
key: 0,
|
||||
listClass: 'default',
|
||||
extra: null,
|
||||
},
|
||||
{
|
||||
value: 1,
|
||||
label: '一般',
|
||||
key: 1,
|
||||
listClass: 'info',
|
||||
extra: null,
|
||||
},
|
||||
{
|
||||
value: 2,
|
||||
label: '紧急',
|
||||
key: 2,
|
||||
listClass: 'error',
|
||||
extra: null,
|
||||
},
|
||||
{
|
||||
value: 3,
|
||||
label: '重要',
|
||||
key: 3,
|
||||
listClass: 'warning',
|
||||
extra: null,
|
||||
},
|
||||
{
|
||||
value: 4,
|
||||
label: '提醒',
|
||||
key: 4,
|
||||
listClass: 'success',
|
||||
extra: null,
|
||||
},
|
||||
{
|
||||
value: 5,
|
||||
label: '次要',
|
||||
key: 5,
|
||||
listClass: 'default',
|
||||
extra: null,
|
||||
},
|
||||
];
|
||||
|
||||
export const tagTypeOptions: Option[] = [
|
||||
{
|
||||
value: 'success',
|
||||
label: '绿色',
|
||||
key: 'success',
|
||||
listClass: 'success',
|
||||
extra: null,
|
||||
},
|
||||
{
|
||||
value: 'warning',
|
||||
label: '橙色',
|
||||
key: 'warning',
|
||||
listClass: 'warning',
|
||||
extra: null,
|
||||
},
|
||||
{
|
||||
value: 'error',
|
||||
label: '红色',
|
||||
key: 'error',
|
||||
listClass: 'error',
|
||||
extra: null,
|
||||
},
|
||||
{
|
||||
value: 'info',
|
||||
label: '蓝色',
|
||||
key: 'info',
|
||||
listClass: 'info',
|
||||
extra: null,
|
||||
},
|
||||
{
|
||||
value: 'default',
|
||||
label: '灰色',
|
||||
key: 'default',
|
||||
listClass: 'default',
|
||||
extra: null,
|
||||
},
|
||||
{
|
||||
value: 'primary',
|
||||
label: '主题色',
|
||||
key: 'primary',
|
||||
listClass: 'primary',
|
||||
extra: null,
|
||||
},
|
||||
];
|
||||
|
||||
export const localDict: DictOptions = {
|
||||
noticeTypeOptions: noticeTypeOptions, // 消息通知类型
|
||||
noticeTagOptions: noticeTagOptions, // 消息标签类型
|
||||
tagTypeOptions: tagTypeOptions, // 标签类型选项
|
||||
};
|
||||
@@ -1,67 +1,7 @@
|
||||
import { NAvatar, NTag, NText, SelectRenderLabel, SelectRenderTag } from 'naive-ui';
|
||||
import { Component, h } from 'vue';
|
||||
import { getOptionLabel, getOptionTag, Option } from '@/utils/hotgo';
|
||||
import { BellOutlined, NotificationOutlined, SendOutlined } from '@vicons/antd';
|
||||
|
||||
export const noticeTypeOptions: Option[] = [
|
||||
{
|
||||
key: 1,
|
||||
value: 1,
|
||||
label: '通知',
|
||||
listClass: 'warning',
|
||||
},
|
||||
{
|
||||
key: 2,
|
||||
value: 2,
|
||||
label: '公告',
|
||||
listClass: 'error',
|
||||
},
|
||||
{
|
||||
key: 3,
|
||||
value: 3,
|
||||
label: '私信',
|
||||
listClass: 'info',
|
||||
},
|
||||
];
|
||||
|
||||
export const noticeTagOptions: Option[] = [
|
||||
{
|
||||
value: 0,
|
||||
label: '无标签',
|
||||
key: 0,
|
||||
listClass: 'default',
|
||||
},
|
||||
{
|
||||
value: 1,
|
||||
label: '一般',
|
||||
key: 1,
|
||||
listClass: 'info',
|
||||
},
|
||||
{
|
||||
value: 2,
|
||||
label: '紧急',
|
||||
key: 2,
|
||||
listClass: 'error',
|
||||
},
|
||||
{
|
||||
value: 3,
|
||||
label: '重要',
|
||||
key: 3,
|
||||
listClass: 'warning',
|
||||
},
|
||||
{
|
||||
value: 4,
|
||||
label: '提醒',
|
||||
key: 4,
|
||||
listClass: 'success',
|
||||
},
|
||||
{
|
||||
value: 5,
|
||||
label: '次要',
|
||||
key: 5,
|
||||
listClass: 'default',
|
||||
},
|
||||
];
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
|
||||
export interface personOption {
|
||||
value: number;
|
||||
@@ -231,8 +171,9 @@ export function parseMessage(row): MessageRow {
|
||||
if (row.tag <= 0) {
|
||||
return row;
|
||||
}
|
||||
|
||||
row.tagTitle = getOptionLabel(noticeTagOptions, row.tag);
|
||||
row.tagProps = { type: getOptionTag(noticeTagOptions, row.tag) };
|
||||
const dict = useDictStore();
|
||||
const label = dict.getLabel('noticeTagOptions', row.tag);
|
||||
row.tagTitle = label;
|
||||
row.tagProps = { type: label };
|
||||
return row;
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import { RedirectRoute } from '@/router/base';
|
||||
import { PageEnum } from '@/enums/pageEnum';
|
||||
import { createRouterGuards } from './router-guards';
|
||||
|
||||
// @ts-ignore
|
||||
const modules = import.meta.globEager('./modules/**/*.ts');
|
||||
|
||||
const routeModuleList: RouteRecordRaw[] = [];
|
||||
|
||||
Object.keys(modules).forEach((key) => {
|
||||
|
||||
181
web/src/store/modules/dict.ts
Normal file
181
web/src/store/modules/dict.ts
Normal file
@@ -0,0 +1,181 @@
|
||||
import { computed, ComputedRef } from 'vue';
|
||||
import { defineStore } from 'pinia';
|
||||
import { createStorage, storage } from '@/utils/Storage';
|
||||
import { store } from '@/store';
|
||||
import { CURRENT_DICT } from '@/store/mutation-types';
|
||||
import { Dicts } from '@/api/dict/dict';
|
||||
import { SelectMixedOption } from 'naive-ui/es/select/src/interface';
|
||||
import { localDict } from '@/enums/localDictEnum';
|
||||
|
||||
const Storage = createStorage({ storage: localStorage });
|
||||
|
||||
// 默认字典类型,通过后台字典管理添加的
|
||||
export type DefaultDictType = 'sys_normal_disable' | 'sys_switch' | 'sys_user_sex';
|
||||
|
||||
// 枚举字典类型
|
||||
export type EnumsDictType = 'creditType' | 'creditGroup' | 'deptType';
|
||||
|
||||
// 方法字典类型
|
||||
export type FuncDictType = 'testCategoryOption';
|
||||
|
||||
// 可以把常用的字典类型加入进来,这样会有IDE提示
|
||||
export type DictType = DefaultDictType | EnumsDictType | FuncDictType | string;
|
||||
|
||||
export interface Option {
|
||||
label: string;
|
||||
value: string | number;
|
||||
key: string | number;
|
||||
listClass: 'default' | 'error' | 'primary' | 'info' | 'success' | 'warning';
|
||||
extra: any;
|
||||
}
|
||||
|
||||
export class DictOptions {
|
||||
[name: DictType]: Option[];
|
||||
}
|
||||
|
||||
export type IDictState = {
|
||||
options: DictOptions;
|
||||
};
|
||||
|
||||
export const useDictStore = defineStore({
|
||||
id: 'app-dict',
|
||||
state: (): IDictState => ({
|
||||
options: Storage.get(CURRENT_DICT, new DictOptions()),
|
||||
}),
|
||||
getters: {},
|
||||
actions: {
|
||||
// 加载字典数据选项
|
||||
loadOptions(types: DictType[]) {
|
||||
Dicts({
|
||||
types: types,
|
||||
}).then((res) => {
|
||||
if (!res) {
|
||||
return;
|
||||
}
|
||||
Object.keys(res).forEach((key) => {
|
||||
if (res[key]) {
|
||||
this.options[key] = res[key] as unknown as Option[];
|
||||
}
|
||||
});
|
||||
storage.set(CURRENT_DICT, this.options);
|
||||
});
|
||||
},
|
||||
|
||||
// 设置指定类型的字典选项
|
||||
setOption(type: DictType, opts: Option[]) {
|
||||
this.options[type] = opts;
|
||||
storage.set(CURRENT_DICT, this.options);
|
||||
},
|
||||
|
||||
// 获取指定类型的字典选项
|
||||
getOption(type: DictType): ComputedRef<SelectMixedOption[]> {
|
||||
return computed(() => {
|
||||
const opts = this.checkOptionValue(type) ?? [];
|
||||
return opts as unknown as SelectMixedOption[];
|
||||
});
|
||||
},
|
||||
|
||||
// 获取指定类型的字典选项
|
||||
getOptionUnRef(type: DictType): any[] {
|
||||
return this.checkOptionValue(type) ?? [];
|
||||
},
|
||||
|
||||
// 是否存在选项,不存在返回null,存在就返回选项
|
||||
checkOptionValue(type: DictType): null | Option[] {
|
||||
// 本地字典
|
||||
const local = localDict[type] ?? [];
|
||||
if (local && local.length > 0) {
|
||||
return local;
|
||||
}
|
||||
const opts = this.options[type] ?? [];
|
||||
if (opts === undefined || opts?.length === 0) {
|
||||
return null;
|
||||
}
|
||||
return opts;
|
||||
},
|
||||
|
||||
// 获取选项名称
|
||||
getLabel(type: DictType, value: any) {
|
||||
const opts = this.checkOptionValue(type);
|
||||
if (!opts) {
|
||||
return ``;
|
||||
}
|
||||
for (const item of opts) {
|
||||
if (item.value.toString() === value.toString()) {
|
||||
return item.label;
|
||||
}
|
||||
}
|
||||
return ``;
|
||||
},
|
||||
|
||||
// 获取选项标签类型
|
||||
getType(
|
||||
type: DictType,
|
||||
value: any
|
||||
): 'default' | 'error' | 'primary' | 'info' | 'success' | 'warning' {
|
||||
const opts = this.checkOptionValue(type);
|
||||
if (!opts) {
|
||||
return `default`;
|
||||
}
|
||||
for (const item of opts) {
|
||||
if (item.value.toString() === value.toString()) {
|
||||
return item.listClass;
|
||||
}
|
||||
}
|
||||
return `default`;
|
||||
},
|
||||
|
||||
// 获取选项额外的数据配置
|
||||
getExtra(type: DictType, value: any): any {
|
||||
const opts = this.checkOptionValue(type);
|
||||
if (!opts) {
|
||||
return null;
|
||||
}
|
||||
for (const item of opts) {
|
||||
if (item.value.toString() === value.toString()) {
|
||||
return item?.extra;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
// 是否存在指定选项值
|
||||
hasValue(type: DictType, value: any): boolean {
|
||||
const opts = this.checkOptionValue(type);
|
||||
if (!opts) {
|
||||
return false;
|
||||
}
|
||||
for (const item of opts) {
|
||||
if (item.value.toString() === value.toString()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
// 获取指定类型的可选项数量
|
||||
getOptionLength(type: DictType): number {
|
||||
const opts = this.checkOptionValue(type);
|
||||
if (!opts) {
|
||||
return 0;
|
||||
}
|
||||
return opts?.length;
|
||||
},
|
||||
|
||||
// 生成单个选项
|
||||
genOption(key: any, label: string, type = 'default', extra: any = null): Option {
|
||||
return <Option>{
|
||||
label: label,
|
||||
value: key,
|
||||
key: key,
|
||||
listClass: type,
|
||||
extra: extra,
|
||||
};
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Need to be used outside the setup
|
||||
export function useDictStoreWidthOut() {
|
||||
return useDictStore(store);
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// @ts-ignore
|
||||
const allModules = import.meta.globEager('./*/index.ts');
|
||||
const modules = {} as any;
|
||||
Object.keys(allModules).forEach((path) => {
|
||||
@@ -14,10 +15,13 @@ import user from './user';
|
||||
import tabsView from './tabs-view';
|
||||
// @ts-ignore
|
||||
import lockscreen from './lockscreen';
|
||||
// @ts-ignore
|
||||
import dict from './dict';
|
||||
|
||||
export default {
|
||||
asyncRoute,
|
||||
user,
|
||||
tabsView,
|
||||
lockscreen,
|
||||
dict,
|
||||
};
|
||||
|
||||
@@ -4,6 +4,7 @@ import { store } from '@/store';
|
||||
import {
|
||||
ACCESS_TOKEN,
|
||||
CURRENT_CONFIG,
|
||||
CURRENT_DICT,
|
||||
CURRENT_LOGIN_CONFIG,
|
||||
CURRENT_USER,
|
||||
IS_LOCKSCREEN,
|
||||
@@ -256,6 +257,7 @@ export const useUserStore = defineStore({
|
||||
this.setUserInfo(null);
|
||||
storage.remove(ACCESS_TOKEN);
|
||||
storage.remove(CURRENT_USER);
|
||||
storage.remove(CURRENT_DICT);
|
||||
}
|
||||
return Promise.resolve(response);
|
||||
} catch (e) {
|
||||
|
||||
@@ -4,3 +4,4 @@ export const CURRENT_CONFIG = 'CURRENT-CONFIG'; // 当前基础配置
|
||||
export const CURRENT_LOGIN_CONFIG = 'CURRENT-LOGIN-CONFIG'; // 当前登录配置
|
||||
export const IS_LOCKSCREEN = 'IS-LOCKSCREEN'; // 是否锁屏
|
||||
export const TABS_ROUTES = 'TABS-ROUTES'; // 标签页
|
||||
export const CURRENT_DICT = 'CURRENT-DICT'; // 当前用户字典配置
|
||||
|
||||
@@ -3,12 +3,14 @@ import { IUserState } from '@/store/modules/user';
|
||||
import { ILockscreenState } from '@/store/modules/lockscreen';
|
||||
import { ITabsViewState } from '@/store/modules/tabsView';
|
||||
import { INotificationStore } from '@/store/modules/notification';
|
||||
import { IDictState } from '@/store/modules/dict';
|
||||
|
||||
export interface IStore {
|
||||
asyncRoute: IAsyncRouteState;
|
||||
user: IUserState;
|
||||
lockscreen: ILockscreenState;
|
||||
tabsView: ITabsViewState;
|
||||
dict: IDictState;
|
||||
notification: INotificationStore;
|
||||
count: number;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
// @ts-ignore
|
||||
import onerrorImg from '@/assets/images/onerror.png';
|
||||
import { usePermission } from '@/hooks/web/usePermission';
|
||||
import { ActionItem } from '@/components/Table';
|
||||
import { isBoolean, isFunction } from '@/utils/is';
|
||||
import { PermissionsEnum } from '@/enums/permissionsEnum';
|
||||
|
||||
/**
|
||||
* @deprecated 这个方法将来未来版本完全弃用,请统一使用useDictStore()来维护字典选项
|
||||
*/
|
||||
export interface Option {
|
||||
label: string;
|
||||
value: string | number;
|
||||
@@ -12,11 +16,17 @@ export interface Option {
|
||||
listClass: 'default' | 'error' | 'primary' | 'info' | 'success' | 'warning';
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 这个方法将来未来版本完全弃用,请统一使用useDictStore()来维护字典选项
|
||||
*/
|
||||
export interface Options {
|
||||
[name: string]: Option[];
|
||||
}
|
||||
|
||||
// 获取选项名称
|
||||
/**
|
||||
* 获取选项名称
|
||||
* @deprecated 这个方法将来未来版本完全弃用,请统一使用useDictStore()来维护字典选项
|
||||
*/
|
||||
export function getOptionLabel(options: Option[], value) {
|
||||
if (options === undefined || options?.length === 0) {
|
||||
return `unknown`;
|
||||
@@ -30,7 +40,10 @@ export function getOptionLabel(options: Option[], value) {
|
||||
return `unknown`;
|
||||
}
|
||||
|
||||
// 获取选项标签
|
||||
/**
|
||||
* 获取选项标签
|
||||
* @deprecated 这个方法将来未来版本完全弃用,请统一使用useDictStore()来维护字典选项
|
||||
*/
|
||||
export function getOptionTag(options: Option[], value) {
|
||||
if (options === undefined || options?.length === 0) {
|
||||
return 'default';
|
||||
@@ -54,7 +67,7 @@ export function adaModalWidth(def = 840) {
|
||||
}
|
||||
}
|
||||
|
||||
interface TableColumn {
|
||||
export interface TableColumn {
|
||||
width?: number | string;
|
||||
auth?: PermissionsEnum | PermissionsEnum[] | string | string[];
|
||||
ifShow?: boolean | ((action: ActionItem) => boolean);
|
||||
@@ -91,12 +104,17 @@ export function isIfShow(action: ActionItem): boolean {
|
||||
return isIfShow;
|
||||
}
|
||||
|
||||
// 图片加载失败显示自定义默认图片(缺省图)
|
||||
// 图片加载失败显示自定义默认图片(缺省图) img标签使用
|
||||
export function errorImg(e: any): void {
|
||||
e.target.src = onerrorImg;
|
||||
e.target.onerror = null;
|
||||
}
|
||||
|
||||
// 图片加载失败显示自定义默认图片(缺省图) NImage组件使用
|
||||
export function fallbackSrc(): string {
|
||||
return onerrorImg;
|
||||
}
|
||||
|
||||
export function timeFix() {
|
||||
const time = new Date();
|
||||
const hour = time.getHours();
|
||||
@@ -144,8 +162,8 @@ export function convertListToTree(list: any[], idField = 'id', pidField = 'pid')
|
||||
|
||||
// 从树选项中获取所有key
|
||||
export function getTreeKeys(data: any[], idField = 'id') {
|
||||
const keys = [];
|
||||
data.map((item) => {
|
||||
const keys: any = [];
|
||||
data.map((item: any) => {
|
||||
keys.push(item[idField]);
|
||||
if (item.children && item.children.length) {
|
||||
keys.push(...getTreeKeys(item.children));
|
||||
|
||||
@@ -13,9 +13,10 @@ import {
|
||||
} from 'naive-ui';
|
||||
import { EllipsisHorizontalCircleOutline } from '@vicons/ionicons5';
|
||||
import { PageEnum } from '@/enums/pageEnum';
|
||||
import { isObject } from './is/index';
|
||||
import { isNullObject, isObject } from './is/index';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { VNode } from '@vue/runtime-core';
|
||||
import { VNode } from 'vue';
|
||||
import { DictType, useDictStore } from '@/store/modules/dict';
|
||||
|
||||
export const renderTooltip = (trigger, content) => {
|
||||
return h(NTooltip, null, {
|
||||
@@ -73,6 +74,27 @@ export const renderTag: SelectRenderTag = ({ option }) => {
|
||||
);
|
||||
};
|
||||
|
||||
// renderOptionTag 选项标签
|
||||
export const renderOptionTag = (type: DictType, value: any) => {
|
||||
if (isNullObject(value)) {
|
||||
return ``;
|
||||
}
|
||||
const dict = useDictStore();
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: dict.getType(type, value),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => dict.getLabel(type, value),
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export interface MemberSumma {
|
||||
id: number; // 用户ID
|
||||
realName: string; // 真实姓名
|
||||
@@ -329,7 +351,7 @@ export function lighten(color: string, amount: number) {
|
||||
|
||||
// 获取树的所有节点key
|
||||
export function getAllExpandKeys(treeData: any): any[] {
|
||||
let expandedKeys = [];
|
||||
let expandedKeys: any = [];
|
||||
const expandKeys = (items: any[]) => {
|
||||
items.forEach((item: any) => {
|
||||
expandedKeys.push(item.key);
|
||||
@@ -347,7 +369,7 @@ export function getAllExpandKeys(treeData: any): any[] {
|
||||
}
|
||||
|
||||
// 从树中查找指定节点
|
||||
export function findTreeNode(data: any[], key?: string | number, keyField = 'key'): any {
|
||||
export function findTreeNode(data: any, key?: string | number, keyField = 'key'): any {
|
||||
for (const item of data) {
|
||||
if (item[keyField] == key) {
|
||||
return item;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import { RouteLocationRaw } from 'vue-router';
|
||||
import router from '@/router';
|
||||
|
||||
/**
|
||||
* 将对象添加当作参数拼接到URL上面
|
||||
* @param baseUrl 需要拼接的url
|
||||
@@ -49,3 +52,14 @@ export function getNowUrl(): string {
|
||||
const w = window.location;
|
||||
return w.protocol + '//' + w.host + w.pathname;
|
||||
}
|
||||
|
||||
// 返回上一页
|
||||
export function goBackOrToPage(to: RouteLocationRaw): void {
|
||||
if (router.currentRoute.value.matched.length > 0) {
|
||||
router.go(-1);
|
||||
} else {
|
||||
router.push(to).catch((e) => {
|
||||
console.log('返回上一页失败:', e);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@ import { FormItemRule } from 'naive-ui';
|
||||
* @description 表单验证封装
|
||||
*/
|
||||
export const validate = {
|
||||
ip(rule: FormItemRule, value: any, callback: Function) {
|
||||
// 验证ipv4
|
||||
ip(rule: FormItemRule, value: any, callback: Function): boolean | Error {
|
||||
// 支持通配符的ipv4正则
|
||||
const ipv4Regex =
|
||||
/^(?:[1-9]?[0-9]|1[0-9]{2}|2(?:[0-4][0-9]|5[0-5]))(?!.*?\.\*\.[*\d])(?:\.(?:(?:[1-9]?[0-9]|1[0-9]{2}|2(?:[0-4][0-9]|5[0-5]))|\*)){1,3}$/;
|
||||
@@ -20,9 +21,10 @@ export const validate = {
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
return true;
|
||||
},
|
||||
//0-100百分比验证
|
||||
percentage(rule: FormItemRule, value: any, callback: Function) {
|
||||
percentage(rule: FormItemRule, value: any, callback: Function): boolean | Error {
|
||||
const reg = /^([1-9]{1,2}$)|(^[0-9]{1,2}\.[0-9]{1,2}$)|100$/;
|
||||
if (!value && !rule.required) {
|
||||
callback(new Error('请输入比例'));
|
||||
@@ -31,9 +33,10 @@ export const validate = {
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
return true;
|
||||
},
|
||||
// 手机号 (eg:138********,159********)
|
||||
phone(rule: FormItemRule, value: any, callback: Function) {
|
||||
phone(rule: FormItemRule, value: any, callback: Function): boolean | Error {
|
||||
const regPhone = /^1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])\d{8}$/;
|
||||
if (!value && !rule.required) {
|
||||
callback();
|
||||
@@ -44,9 +47,10 @@ export const validate = {
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
return true;
|
||||
},
|
||||
// 用户名 (eg:a123456)
|
||||
userName(rule: FormItemRule, value: any, callback: Function) {
|
||||
userName(rule: FormItemRule, value: any, callback: Function): boolean | Error {
|
||||
const regUserName = /^[0-9a-zA-Z]{6,16}$/;
|
||||
if (!value && !rule.required) {
|
||||
callback(new Error('请输入登录账号'));
|
||||
@@ -55,9 +59,10 @@ export const validate = {
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
return true;
|
||||
},
|
||||
// 账号
|
||||
account(rule: FormItemRule, value: any, callback: Function) {
|
||||
account(rule: FormItemRule, value: any, callback: Function): boolean | Error {
|
||||
const regex = /^[\w_\d]{6,16}$/;
|
||||
if (!value && !rule.required) {
|
||||
callback();
|
||||
@@ -68,9 +73,10 @@ export const validate = {
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
return true;
|
||||
},
|
||||
// 密码
|
||||
password(rule: FormItemRule, value: any, callback: Function) {
|
||||
password(rule: FormItemRule, value: any, callback: Function): boolean | Error {
|
||||
const regPassword = /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,18}$/;
|
||||
if (!value && !rule.required) {
|
||||
callback(new Error('请输入密码'));
|
||||
@@ -79,9 +85,10 @@ export const validate = {
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
return true;
|
||||
},
|
||||
// 邮箱
|
||||
email(rule: FormItemRule, value: any, callback: Function) {
|
||||
email(rule: FormItemRule, value: any, callback: Function): boolean | Error {
|
||||
const regEmails = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
|
||||
// console.log('isRequired is: ', JSON.stringify(isRequired))
|
||||
if (!value && !rule.required) {
|
||||
@@ -93,9 +100,10 @@ export const validate = {
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
return true;
|
||||
},
|
||||
// 金额验证
|
||||
amount(rule: FormItemRule, value: any, callback: Function) {
|
||||
amount(rule: FormItemRule, value: any, callback: Function): boolean | Error {
|
||||
const regAmount = /(^[0-9]{1,10}$)|(^[0-9]{1,10}[\.]{1}[0-9]{1,2}$)/;
|
||||
if (!value && !rule.required) {
|
||||
callback();
|
||||
@@ -106,9 +114,10 @@ export const validate = {
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
return true;
|
||||
},
|
||||
// 身份证验证
|
||||
idCard(rule: FormItemRule, value: any, callback: Function, isEnabled = true) {
|
||||
idCard(rule: FormItemRule, value: any, callback: Function, isEnabled = true): boolean | Error {
|
||||
const regIdCard =
|
||||
/^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$|^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X|x)$/;
|
||||
if (!isEnabled) {
|
||||
@@ -122,9 +131,10 @@ export const validate = {
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
return true;
|
||||
},
|
||||
// 银行卡验证
|
||||
bank(rule: FormItemRule, value: any, callback: Function) {
|
||||
bank(rule: FormItemRule, value: any, callback: Function): boolean | Error {
|
||||
const regBank = /^([1-9]{1})(\d{15}|\d{16}|\d{18})$/;
|
||||
if (!value && !rule.required) {
|
||||
callback();
|
||||
@@ -135,9 +145,10 @@ export const validate = {
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
return true;
|
||||
},
|
||||
// 非零正整数验证
|
||||
num(rule: FormItemRule, value: any, callback: Function) {
|
||||
num(rule: FormItemRule, value: any, callback: Function): boolean | Error {
|
||||
const reg = /^\+?[1-9][0-9]*$/;
|
||||
if (!value && !rule.required) {
|
||||
callback(new Error('请填写非零正整数'));
|
||||
@@ -148,9 +159,10 @@ export const validate = {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
// 银行卡
|
||||
bankCard(rule: FormItemRule, value: any, callback: Function) {
|
||||
bankCard(rule: FormItemRule, value: any, callback: Function): boolean | Error {
|
||||
const regBankCard = /^(\d{16}|\d{19})$/;
|
||||
if (value == '' && !rule.required) {
|
||||
callback(new Error('请输入银行卡号'));
|
||||
@@ -161,9 +173,10 @@ export const validate = {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
// 固话格式
|
||||
tel(rule: FormItemRule, value: any, callback: Function) {
|
||||
tel(rule: FormItemRule, value: any, callback: Function): boolean | Error {
|
||||
const regTel = /^(0\d{2,3}-?)?\d{7,8}$/;
|
||||
if (value == '' && !rule.required) {
|
||||
callback(new Error('请输入座机号码'));
|
||||
@@ -174,9 +187,10 @@ export const validate = {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
// QQ号码
|
||||
qq(rule: FormItemRule, value: any, callback: Function) {
|
||||
qq(rule: FormItemRule, value: any, callback: Function): boolean | Error {
|
||||
const regex = /^[1-9][0-9]{4,}$/;
|
||||
if (!value && !rule.required) {
|
||||
callback();
|
||||
@@ -189,9 +203,10 @@ export const validate = {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
// weibo号
|
||||
weibo(rule: FormItemRule, value: any, callback: Function) {
|
||||
weibo(rule: FormItemRule, value: any, callback: Function): boolean | Error {
|
||||
const regex = /^[0-9a-zA-Z\u4e00-\u9fa5_-]*$/;
|
||||
if (!value && !rule.required) {
|
||||
callback();
|
||||
@@ -204,9 +219,11 @@ export const validate = {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
// 不验证
|
||||
none(_rule: FormItemRule, _value: any, callback: Function) {
|
||||
none(_rule: FormItemRule, _value: any, callback: Function): boolean {
|
||||
callback();
|
||||
return true;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<n-checkbox-group v-model:value="params.flag">
|
||||
<n-space>
|
||||
<n-checkbox
|
||||
v-for="item in options.sys_notice_type"
|
||||
v-for="item in dict.getOptionUnRef('sys_notice_type')"
|
||||
:key="item.value"
|
||||
:value="item.value"
|
||||
:label="item.label"
|
||||
@@ -96,7 +96,10 @@
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item label="用户渠道" path="channel">
|
||||
<n-select v-model:value="params.channel" :options="options.sys_user_channel" />
|
||||
<n-select
|
||||
v-model:value="params.channel"
|
||||
:options="dict.getOptionUnRef('sys_user_channel')"
|
||||
/>
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item label="所在城市" path="cityId">
|
||||
@@ -104,7 +107,11 @@
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item label="用户爱好" path="hobby">
|
||||
<n-select multiple v-model:value="params.hobby" :options="options.sys_user_hobby" />
|
||||
<n-select
|
||||
multiple
|
||||
v-model:value="params.hobby"
|
||||
:options="dict.getOptionUnRef('sys_user_hobby')"
|
||||
/>
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item label="QQ" path="qq">
|
||||
@@ -126,7 +133,7 @@
|
||||
<n-form-item label="状态" path="status">
|
||||
<n-radio-group v-model:value="params.status" name="status">
|
||||
<n-radio-button
|
||||
v-for="status in options.sys_normal_disable"
|
||||
v-for="status in dict.getOptionUnRef('sys_normal_disable')"
|
||||
:key="Number(status.value)"
|
||||
:value="Number(status.value)"
|
||||
:label="status.label"
|
||||
@@ -151,7 +158,7 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, watch } from 'vue';
|
||||
import { rules, options, State, newState } from './model';
|
||||
import { rules, State, newState } from './model';
|
||||
import { Edit, MaxSort } from '@/api/addons/hgexample/table';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { adaModalWidth } from '@/utils/hotgo';
|
||||
@@ -161,6 +168,7 @@
|
||||
import UploadFile from '@/components/Upload/uploadFile.vue';
|
||||
import CitySelector from '@/components/CitySelector/citySelector.vue';
|
||||
import FileChooser from '@/components/FileChooser/index.vue';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
const emit = defineEmits(['reloadTable', 'updateShowModal']);
|
||||
|
||||
interface Props {
|
||||
@@ -188,6 +196,7 @@
|
||||
return props.formParams;
|
||||
});
|
||||
|
||||
const dict = useDictStore();
|
||||
const message = useMessage();
|
||||
const formRef = ref<any>({});
|
||||
const formBtnLoading = ref(false);
|
||||
|
||||
@@ -66,8 +66,8 @@
|
||||
</BasicTable>
|
||||
</n-card>
|
||||
<Edit
|
||||
@reloadTable="reloadTable"
|
||||
@updateShowModal="updateShowModal"
|
||||
@reload-table="reloadTable"
|
||||
@update-show-modal="updateShowModal"
|
||||
:showModal="showModal"
|
||||
:formParams="formParams"
|
||||
/>
|
||||
@@ -75,18 +75,20 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, h, reactive, ref } from 'vue';
|
||||
import { computed, h, onMounted, reactive, ref } from 'vue';
|
||||
import { useDialog, useMessage } from 'naive-ui';
|
||||
import { BasicTable, TableAction } from '@/components/Table';
|
||||
import { BasicForm, useForm } from '@/components/Form/index';
|
||||
import { useSorter } from '@/hooks/common';
|
||||
import { Delete, List, Status, Export } from '@/api/addons/hgexample/table';
|
||||
import { State, columns, schemas, options, newState } from './model';
|
||||
import { State, columns, schemas, newState, loadOptions } from './model';
|
||||
import { DeleteOutlined, PlusOutlined, ExportOutlined } from '@vicons/antd';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { adaTableScrollX, getOptionLabel } from '@/utils/hotgo';
|
||||
import { adaTableScrollX } from '@/utils/hotgo';
|
||||
import Edit from './edit.vue';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
|
||||
const dict = useDictStore();
|
||||
const router = useRouter();
|
||||
const dialog = useDialog();
|
||||
const message = useMessage();
|
||||
@@ -218,9 +220,6 @@
|
||||
reloadTable();
|
||||
});
|
||||
},
|
||||
onNegativeClick: () => {
|
||||
// message.error('取消');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -238,9 +237,6 @@
|
||||
reloadTable();
|
||||
});
|
||||
},
|
||||
onNegativeClick: () => {
|
||||
// message.error('取消');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -251,12 +247,16 @@
|
||||
|
||||
function handleStatus(record: Recordable, status: number) {
|
||||
Status({ id: record.id, status: status }).then((_res) => {
|
||||
message.success('设为' + getOptionLabel(options.value.sys_normal_disable, status) + '成功');
|
||||
message.success('设为' + dict.getLabel('sys_normal_disable', status) + '成功');
|
||||
setTimeout(() => {
|
||||
reloadTable();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadOptions();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
|
||||
@@ -2,14 +2,19 @@ import { h, ref } from 'vue';
|
||||
import { NAvatar, NImage, NTag, NSwitch, NRate } from 'naive-ui';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { FormSchema } from '@/components/Form';
|
||||
import { Dicts } from '@/api/dict/dict';
|
||||
import { Switch } from '@/api/addons/hgexample/table';
|
||||
import { isNullObject } from '@/utils/is';
|
||||
import { getFileExt } from '@/utils/urlUtils';
|
||||
import { defRangeShortcuts, defShortcuts, formatToDate } from '@/utils/dateUtil';
|
||||
import { validate } from '@/utils/validateUtil';
|
||||
import { errorImg, getOptionLabel, getOptionTag, Options } from '@/utils/hotgo';
|
||||
import { fallbackSrc } from '@/utils/hotgo';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import { renderOptionTag } from '@/utils';
|
||||
import type { FormRules } from 'naive-ui/es/form/src/interface';
|
||||
|
||||
const dict = useDictStore();
|
||||
const $message = window['$message'];
|
||||
|
||||
export interface State {
|
||||
id: number;
|
||||
memberId: number;
|
||||
@@ -95,16 +100,7 @@ export function newState(state: State | null): State {
|
||||
return cloneDeep(defaultState);
|
||||
}
|
||||
|
||||
export const options = ref<Options>({
|
||||
sys_normal_disable: [],
|
||||
sys_user_sex: [],
|
||||
sys_notice_type: [],
|
||||
sys_user_channel: [],
|
||||
sys_user_hobby: [],
|
||||
sys_switch: [],
|
||||
});
|
||||
|
||||
export const rules = {
|
||||
export const rules: FormRules = {
|
||||
title: {
|
||||
required: true,
|
||||
trigger: ['blur', 'input'],
|
||||
@@ -207,7 +203,7 @@ export const schemas = ref<FormSchema[]>([
|
||||
},
|
||||
componentProps: {
|
||||
placeholder: '请选择标签',
|
||||
options: [],
|
||||
options: dict.getOption('sys_notice_type'),
|
||||
onUpdateChecked: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -221,7 +217,7 @@ export const schemas = ref<FormSchema[]>([
|
||||
//span: 24,
|
||||
},
|
||||
componentProps: {
|
||||
options: [],
|
||||
options: dict.getOption('sys_switch'),
|
||||
onUpdateChecked: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -235,7 +231,7 @@ export const schemas = ref<FormSchema[]>([
|
||||
componentProps: {
|
||||
multiple: true,
|
||||
placeholder: '请选择爱好',
|
||||
options: [],
|
||||
options: dict.getOption('sys_user_hobby'),
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -248,7 +244,7 @@ export const schemas = ref<FormSchema[]>([
|
||||
defaultValue: null,
|
||||
componentProps: {
|
||||
placeholder: '请选择类型',
|
||||
options: [],
|
||||
options: dict.getOption('sys_normal_disable'),
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -280,19 +276,7 @@ export const columns = [
|
||||
return ``;
|
||||
}
|
||||
return row.flag.map((tagKey) => {
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(options.value.sys_notice_type, tagKey),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(options.value.sys_notice_type, tagKey),
|
||||
}
|
||||
);
|
||||
return renderOptionTag('sys_notice_type', tagKey);
|
||||
});
|
||||
},
|
||||
},
|
||||
@@ -304,7 +288,7 @@ export const columns = [
|
||||
width: 32,
|
||||
height: 32,
|
||||
src: row.image,
|
||||
fallbackSrc: errorImg,
|
||||
fallbackSrc: fallbackSrc(),
|
||||
style: {
|
||||
width: '32px',
|
||||
height: '32px',
|
||||
@@ -326,7 +310,7 @@ export const columns = [
|
||||
width: 32,
|
||||
height: 32,
|
||||
src: image,
|
||||
fallbackSrc: errorImg,
|
||||
fallbackSrc: fallbackSrc(),
|
||||
style: {
|
||||
width: '32px',
|
||||
height: '32px',
|
||||
@@ -443,22 +427,7 @@ export const columns = [
|
||||
title: '状态',
|
||||
key: 'status',
|
||||
render(row) {
|
||||
if (isNullObject(row.status)) {
|
||||
return ``;
|
||||
}
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(options.value.sys_normal_disable, row.status),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(options.value.sys_normal_disable, row.status),
|
||||
}
|
||||
);
|
||||
return renderOptionTag('sys_normal_disable', row.status);
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -469,19 +438,7 @@ export const columns = [
|
||||
return ``;
|
||||
}
|
||||
return row.hobby.map((tagKey) => {
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(options.value.sys_user_hobby, tagKey),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(options.value.sys_user_hobby, tagKey),
|
||||
}
|
||||
);
|
||||
return renderOptionTag('sys_user_hobby', tagKey);
|
||||
});
|
||||
},
|
||||
},
|
||||
@@ -497,33 +454,13 @@ export const columns = [
|
||||
},
|
||||
];
|
||||
|
||||
async function loadOptions() {
|
||||
options.value = await Dicts({
|
||||
types: [
|
||||
'sys_normal_disable',
|
||||
'sys_user_sex',
|
||||
'sys_notice_type',
|
||||
'sys_switch',
|
||||
'sys_user_hobby',
|
||||
'sys_user_channel',
|
||||
],
|
||||
});
|
||||
for (const item of schemas.value) {
|
||||
switch (item.field) {
|
||||
case 'status':
|
||||
item.componentProps.options = options.value.sys_normal_disable;
|
||||
break;
|
||||
case 'flag':
|
||||
item.componentProps.options = options.value.sys_notice_type;
|
||||
break;
|
||||
case 'switch':
|
||||
item.componentProps.options = options.value.sys_switch;
|
||||
break;
|
||||
case 'hobby':
|
||||
item.componentProps.options = options.value.sys_user_hobby;
|
||||
break;
|
||||
}
|
||||
}
|
||||
export function loadOptions() {
|
||||
dict.loadOptions([
|
||||
'sys_normal_disable',
|
||||
'sys_user_sex',
|
||||
'sys_notice_type',
|
||||
'sys_switch',
|
||||
'sys_user_hobby',
|
||||
'sys_user_channel',
|
||||
]);
|
||||
}
|
||||
|
||||
await loadOptions();
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<n-card :bordered="false" title="基础详情"> 基础详情,有时也用于显示只读信息。 </n-card>
|
||||
</div>
|
||||
<n-card :bordered="false" class="proCard mt-4" size="small" :segmented="{ content: true }">
|
||||
<n-descriptions label-placement="left" class="py-2" column="4">
|
||||
<n-descriptions label-placement="left" class="py-2" :column="4">
|
||||
<n-descriptions-item>
|
||||
<template #label>分类ID</template>
|
||||
{{ formValue.categoryId }}
|
||||
@@ -13,10 +13,10 @@
|
||||
<n-descriptions-item label="标签">
|
||||
<template v-for="(item, key) in formValue?.flag" :key="key">
|
||||
<n-tag
|
||||
:type="getOptionTag(options.sys_notice_type, item)"
|
||||
:type="dict.getType('sys_notice_type', item)"
|
||||
size="small"
|
||||
class="min-left-space"
|
||||
>{{ getOptionLabel(options.sys_notice_type, item) }}</n-tag
|
||||
>{{ dict.getLabel('sys_notice_type', item) }}</n-tag
|
||||
>
|
||||
</template>
|
||||
</n-descriptions-item>
|
||||
@@ -37,19 +37,19 @@
|
||||
</n-card>
|
||||
|
||||
<n-card :bordered="false" class="proCard mt-4" size="small" :segmented="{ content: true }">
|
||||
<n-descriptions label-placement="top" title="内容" class="py-2" column="1">
|
||||
<n-descriptions label-placement="top" title="内容" class="py-2" :column="1">
|
||||
<n-descriptions-item><span v-html="formValue.content"></span></n-descriptions-item>
|
||||
</n-descriptions>
|
||||
</n-card>
|
||||
|
||||
<n-card :bordered="false" class="proCard mt-4" size="small" :segmented="{ content: true }">
|
||||
<n-descriptions label-placement="top" title="单图" class="py-2" column="1">
|
||||
<n-descriptions label-placement="top" title="单图" class="py-2" :column="1">
|
||||
<n-descriptions-item>
|
||||
<n-image style="margin-left: 10px; height: 100px; width: 100px" :src="formValue.image"
|
||||
/></n-descriptions-item>
|
||||
</n-descriptions>
|
||||
|
||||
<n-descriptions label-placement="top" title="多图" class="py-2" column="1">
|
||||
<n-descriptions label-placement="top" title="多图" class="py-2" :column="1">
|
||||
<n-descriptions-item>
|
||||
<n-image-group>
|
||||
<n-space>
|
||||
@@ -61,7 +61,7 @@
|
||||
</n-descriptions-item>
|
||||
</n-descriptions>
|
||||
|
||||
<n-descriptions label-placement="top" title="附件" class="py-2" column="1">
|
||||
<n-descriptions label-placement="top" title="附件" class="py-2" :column="1">
|
||||
<n-descriptions-item>
|
||||
<div
|
||||
class="upload-card"
|
||||
@@ -79,7 +79,7 @@
|
||||
</n-descriptions-item>
|
||||
</n-descriptions>
|
||||
|
||||
<n-descriptions label-placement="top" title="多附件" class="py-2" column="1">
|
||||
<n-descriptions label-placement="top" title="多附件" class="py-2" :column="1">
|
||||
<n-descriptions-item>
|
||||
<div class="upload-card">
|
||||
<n-space style="gap: 0px 0px">
|
||||
@@ -110,10 +110,11 @@
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { View } from '@/api/addons/hgexample/table';
|
||||
import { newState, options } from './model';
|
||||
import { getOptionLabel, getOptionTag } from '@/utils/hotgo';
|
||||
import { newState } from './model';
|
||||
import { getFileExt } from '@/utils/urlUtils';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
|
||||
const dict = useDictStore();
|
||||
const message = useMessage();
|
||||
const router = useRouter();
|
||||
const id = Number(router.currentRoute.value.params.id);
|
||||
|
||||
@@ -71,7 +71,10 @@
|
||||
</n-gi>
|
||||
<n-gi span="1">
|
||||
<n-form-item label="支付状态" path="status">
|
||||
<n-select v-model:value="formValue.status" :options="options.payStatus" />
|
||||
<n-select
|
||||
v-model:value="formValue.status"
|
||||
:options="dict.getOptionUnRef('payStatus')"
|
||||
/>
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
@@ -91,13 +94,15 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import { Edit, View } from '@/api/addons/hgexample/tenantOrder';
|
||||
import { options, State, newState, rules } from './model';
|
||||
import { State, newState, rules } from './model';
|
||||
import { useProjectSettingStore } from '@/store/modules/projectSetting';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { adaModalWidth } from '@/utils/hotgo';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
|
||||
const emit = defineEmits(['reloadTable']);
|
||||
const dict = useDictStore();
|
||||
const message = useMessage();
|
||||
const settingStore = useProjectSettingStore();
|
||||
const userStore = useUserStore();
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { h, ref } from 'vue';
|
||||
import { NTag } from 'naive-ui';
|
||||
import { ref } from 'vue';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { FormSchema } from '@/components/Form';
|
||||
import { Dicts } from '@/api/dict/dict';
|
||||
import { isNullObject } from '@/utils/is';
|
||||
import { defRangeShortcuts } from '@/utils/dateUtil';
|
||||
import { Option, getOptionLabel, getOptionTag } from '@/utils/hotgo';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import { renderOptionTag } from '@/utils';
|
||||
import type { FormRules } from 'naive-ui/es/form/src/interface';
|
||||
|
||||
const dict = useDictStore();
|
||||
const userStore = useUserStore();
|
||||
|
||||
export class State {
|
||||
@@ -41,7 +41,7 @@ export function newState(state: State | Record<string, any> | null): State {
|
||||
}
|
||||
|
||||
// 表单验证规则
|
||||
export const rules = {
|
||||
export const rules: FormRules = {
|
||||
money: {
|
||||
required: true,
|
||||
trigger: ['blur', 'input'],
|
||||
@@ -195,22 +195,7 @@ export const columns = [
|
||||
align: 'left',
|
||||
width: 100,
|
||||
render(row) {
|
||||
if (isNullObject(row.status)) {
|
||||
return ``;
|
||||
}
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(options.value.payStatus, row.status),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(options.value.payStatus, row.status),
|
||||
}
|
||||
);
|
||||
return renderOptionTag('payStatus', row.status);
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -221,23 +206,7 @@ export const columns = [
|
||||
},
|
||||
];
|
||||
|
||||
// 字典数据选项
|
||||
export const options = ref({
|
||||
payStatus: [] as Option[],
|
||||
});
|
||||
|
||||
// 加载字典数据选项
|
||||
export function loadOptions() {
|
||||
Dicts({
|
||||
types: ['payStatus'],
|
||||
}).then((res) => {
|
||||
options.value = res;
|
||||
for (const item of schemas.value) {
|
||||
switch (item.field) {
|
||||
case 'status':
|
||||
item.componentProps.options = options.value.payStatus;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
dict.loadOptions(['payStatus']);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
<n-checkbox-group v-model:value="params.flag">
|
||||
<n-space>
|
||||
<n-checkbox
|
||||
v-for="item in options.sys_notice_type"
|
||||
v-for="item in dict.getOptionUnRef('sys_notice_type')"
|
||||
:key="item.value"
|
||||
:value="item.value"
|
||||
:label="item.label"
|
||||
@@ -104,7 +104,10 @@
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item label="用户渠道" path="channel">
|
||||
<n-select v-model:value="params.channel" :options="options.sys_user_channel" />
|
||||
<n-select
|
||||
v-model:value="params.channel"
|
||||
:options="dict.getOptionUnRef('sys_user_channel')"
|
||||
/>
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item label="所在城市" path="cityId">
|
||||
@@ -112,7 +115,11 @@
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item label="用户爱好" path="hobby">
|
||||
<n-select multiple v-model:value="params.hobby" :options="options.sys_user_hobby" />
|
||||
<n-select
|
||||
multiple
|
||||
v-model:value="params.hobby"
|
||||
:options="dict.getOptionUnRef('sys_user_hobby')"
|
||||
/>
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item label="QQ" path="qq">
|
||||
@@ -134,7 +141,7 @@
|
||||
<n-form-item label="状态" path="status">
|
||||
<n-radio-group v-model:value="params.status" name="status">
|
||||
<n-radio-button
|
||||
v-for="status in options.sys_normal_disable"
|
||||
v-for="status in dict.getOptionUnRef('sys_normal_disable')"
|
||||
:key="Number(status.value)"
|
||||
:value="Number(status.value)"
|
||||
:label="status.label"
|
||||
@@ -158,8 +165,8 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref, computed, watch } from 'vue';
|
||||
import { rules, options, State, newState } from './model';
|
||||
import { ref, computed, watch } from 'vue';
|
||||
import { rules, State, newState } from './model';
|
||||
import { Edit, MaxSort } from '@/api/addons/hgexample/treeTable';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { adaModalWidth } from '@/utils/hotgo';
|
||||
@@ -169,6 +176,7 @@
|
||||
import UploadFile from '@/components/Upload/uploadFile.vue';
|
||||
import CitySelector from '@/components/CitySelector/citySelector.vue';
|
||||
import FileChooser from '@/components/FileChooser/index.vue';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
const emit = defineEmits(['reloadTable', 'updateShowModal']);
|
||||
|
||||
interface Props {
|
||||
@@ -198,6 +206,7 @@
|
||||
return props.formParams;
|
||||
});
|
||||
|
||||
const dict = useDictStore();
|
||||
const message = useMessage();
|
||||
const formRef = ref<any>({});
|
||||
const formBtnLoading = ref(false);
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
type="info"
|
||||
icon-placement="left"
|
||||
@click="openEditDrawer"
|
||||
:disabled="formParams?.id === null || formParams?.id <= 0"
|
||||
:disabled="!formParams?.id || formParams?.id < 1"
|
||||
>
|
||||
<template #icon>
|
||||
<div class="flex items-center">
|
||||
@@ -104,15 +104,15 @@
|
||||
<List
|
||||
:checkedId="checkedId"
|
||||
:optionTreeData="optionTreeData"
|
||||
@reloadTable="reloadTable"
|
||||
@reload-table="reloadTable"
|
||||
/>
|
||||
</n-card>
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
|
||||
<Edit
|
||||
@reloadTable="reloadTable"
|
||||
@updateShowModal="updateShowModal"
|
||||
@reload-table="reloadTable"
|
||||
@update-show-modal="updateShowModal"
|
||||
:showModal="showModal"
|
||||
:formParams="formParams"
|
||||
:optionTreeData="optionTreeData"
|
||||
@@ -133,7 +133,7 @@
|
||||
import List from './list.vue';
|
||||
import { Delete, Select } from '@/api/addons/hgexample/treeTable';
|
||||
import Edit from './edit.vue';
|
||||
import { newState } from './model';
|
||||
import { newState, loadOptions } from './model';
|
||||
|
||||
const showModal = ref(false);
|
||||
const message = useMessage();
|
||||
@@ -228,4 +228,8 @@
|
||||
function updateShowModal(value) {
|
||||
showModal.value = value;
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadOptions();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -71,8 +71,8 @@
|
||||
</n-card>
|
||||
|
||||
<Edit
|
||||
@reloadTable="reloadTable"
|
||||
@updateShowModal="updateShowModal"
|
||||
@reload-table="reloadTable"
|
||||
@update-show-modal="updateShowModal"
|
||||
:showModal="showModal"
|
||||
:formParams="formParams"
|
||||
:optionTreeData="optionTreeData"
|
||||
@@ -87,10 +87,11 @@
|
||||
import { BasicForm, useForm } from '@/components/Form/index';
|
||||
import { useSorter } from '@/hooks/common';
|
||||
import { Delete, List, Status, Export } from '@/api/addons/hgexample/treeTable';
|
||||
import { State, columns, schemas, options, newState } from './model';
|
||||
import { State, columns, schemas, newState } from './model';
|
||||
import { DeleteOutlined, PlusOutlined, ExportOutlined } from '@vicons/antd';
|
||||
import { adaTableScrollX, getOptionLabel } from '@/utils/hotgo';
|
||||
import { adaTableScrollX } from '@/utils/hotgo';
|
||||
import Edit from './edit.vue';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
|
||||
interface Props {
|
||||
checkedId?: number;
|
||||
@@ -99,6 +100,7 @@
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), { checkedId: 0, optionTreeData: [] });
|
||||
const emit = defineEmits(['reloadTable']);
|
||||
const dict = useDictStore();
|
||||
const dialog = useDialog();
|
||||
const message = useMessage();
|
||||
const searchFormRef = ref<any>();
|
||||
@@ -232,7 +234,7 @@
|
||||
|
||||
function handleStatus(record: Recordable, status: number) {
|
||||
Status({ id: record.id, status: status }).then((_res) => {
|
||||
message.success('设为' + getOptionLabel(options.value.sys_normal_disable, status) + '成功');
|
||||
message.success('设为' + dict.getLabel('sys_normal_disable', status) + '成功');
|
||||
setTimeout(() => {
|
||||
reloadTable();
|
||||
});
|
||||
|
||||
@@ -2,14 +2,18 @@ import { h, ref } from 'vue';
|
||||
import { NAvatar, NImage, NTag, NSwitch, NRate } from 'naive-ui';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { FormSchema } from '@/components/Form';
|
||||
import { Dicts } from '@/api/dict/dict';
|
||||
import { Switch } from '@/api/addons/hgexample/table';
|
||||
import { isNullObject } from '@/utils/is';
|
||||
import { getFileExt } from '@/utils/urlUtils';
|
||||
import { defRangeShortcuts, defShortcuts, formatToDate } from '@/utils/dateUtil';
|
||||
import { validate } from '@/utils/validateUtil';
|
||||
import { errorImg, getOptionLabel, getOptionTag, Options } from '@/utils/hotgo';
|
||||
import { fallbackSrc } from '@/utils/hotgo';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import { renderOptionTag } from '@/utils';
|
||||
|
||||
const dict = useDictStore();
|
||||
const $message = window['$message'];
|
||||
|
||||
export interface State {
|
||||
id: number;
|
||||
memberId: number;
|
||||
@@ -21,7 +25,7 @@ export interface State {
|
||||
images: string[] | null;
|
||||
attachfile: string;
|
||||
attachfiles: string[] | null;
|
||||
map: unknown[] | null;
|
||||
map: any | null;
|
||||
star: number;
|
||||
description: string;
|
||||
price: number;
|
||||
@@ -95,15 +99,6 @@ export function newState(state: State | null): State {
|
||||
return cloneDeep(defaultState);
|
||||
}
|
||||
|
||||
export const options = ref<Options>({
|
||||
sys_normal_disable: [],
|
||||
sys_user_sex: [],
|
||||
sys_notice_type: [],
|
||||
sys_user_channel: [],
|
||||
sys_user_hobby: [],
|
||||
sys_switch: [],
|
||||
});
|
||||
|
||||
export const rules = {
|
||||
title: {
|
||||
required: true,
|
||||
@@ -207,7 +202,7 @@ export const schemas = ref<FormSchema[]>([
|
||||
},
|
||||
componentProps: {
|
||||
placeholder: '请选择标签',
|
||||
options: [],
|
||||
options: dict.getOption('sys_notice_type'),
|
||||
onUpdateChecked: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -221,7 +216,7 @@ export const schemas = ref<FormSchema[]>([
|
||||
//span: 24,
|
||||
},
|
||||
componentProps: {
|
||||
options: [],
|
||||
options: dict.getOption('sys_switch'),
|
||||
onUpdateChecked: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -235,7 +230,7 @@ export const schemas = ref<FormSchema[]>([
|
||||
componentProps: {
|
||||
multiple: true,
|
||||
placeholder: '请选择爱好',
|
||||
options: [],
|
||||
options: dict.getOption('sys_user_hobby'),
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -248,7 +243,7 @@ export const schemas = ref<FormSchema[]>([
|
||||
defaultValue: null,
|
||||
componentProps: {
|
||||
placeholder: '请选择类型',
|
||||
options: [],
|
||||
options: dict.getOption('sys_normal_disable'),
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -280,19 +275,7 @@ export const columns = [
|
||||
return ``;
|
||||
}
|
||||
return row.flag.map((tagKey) => {
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(options.value.sys_notice_type, tagKey),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(options.value.sys_notice_type, tagKey),
|
||||
}
|
||||
);
|
||||
return renderOptionTag('sys_notice_type', tagKey);
|
||||
});
|
||||
},
|
||||
},
|
||||
@@ -304,7 +287,7 @@ export const columns = [
|
||||
width: 32,
|
||||
height: 32,
|
||||
src: row.image,
|
||||
fallbackSrc: errorImg,
|
||||
fallbackSrc: fallbackSrc(),
|
||||
style: {
|
||||
width: '32px',
|
||||
height: '32px',
|
||||
@@ -326,7 +309,7 @@ export const columns = [
|
||||
width: 32,
|
||||
height: 32,
|
||||
src: image,
|
||||
fallbackSrc: errorImg,
|
||||
fallbackSrc: fallbackSrc(),
|
||||
style: {
|
||||
width: '32px',
|
||||
height: '32px',
|
||||
@@ -443,46 +426,14 @@ export const columns = [
|
||||
title: '状态',
|
||||
key: 'status',
|
||||
render(row) {
|
||||
if (isNullObject(row.status)) {
|
||||
return ``;
|
||||
}
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(options.value.sys_normal_disable, row.status),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(options.value.sys_normal_disable, row.status),
|
||||
}
|
||||
);
|
||||
return renderOptionTag('sys_normal_disable', row.status);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '爱好',
|
||||
key: 'hobby',
|
||||
render(row) {
|
||||
if (isNullObject(row.hobby)) {
|
||||
return ``;
|
||||
}
|
||||
return row.hobby.map((tagKey) => {
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(options.value.sys_user_hobby, tagKey),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(options.value.sys_user_hobby, tagKey),
|
||||
}
|
||||
);
|
||||
});
|
||||
return renderOptionTag('sys_user_hobby', row.hobby);
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -497,33 +448,13 @@ export const columns = [
|
||||
},
|
||||
];
|
||||
|
||||
async function loadOptions() {
|
||||
options.value = await Dicts({
|
||||
types: [
|
||||
'sys_normal_disable',
|
||||
'sys_user_sex',
|
||||
'sys_notice_type',
|
||||
'sys_switch',
|
||||
'sys_user_hobby',
|
||||
'sys_user_channel',
|
||||
],
|
||||
});
|
||||
for (const item of schemas.value) {
|
||||
switch (item.field) {
|
||||
case 'status':
|
||||
item.componentProps.options = options.value.sys_normal_disable;
|
||||
break;
|
||||
case 'flag':
|
||||
item.componentProps.options = options.value.sys_notice_type;
|
||||
break;
|
||||
case 'switch':
|
||||
item.componentProps.options = options.value.sys_switch;
|
||||
break;
|
||||
case 'hobby':
|
||||
item.componentProps.options = options.value.sys_user_hobby;
|
||||
break;
|
||||
}
|
||||
}
|
||||
export function loadOptions() {
|
||||
dict.loadOptions([
|
||||
'sys_normal_disable',
|
||||
'sys_user_sex',
|
||||
'sys_notice_type',
|
||||
'sys_switch',
|
||||
'sys_user_hobby',
|
||||
'sys_user_channel',
|
||||
]);
|
||||
}
|
||||
|
||||
await loadOptions();
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
import { h, ref } from 'vue';
|
||||
import { NAvatar, NImage, NTag } from 'naive-ui';
|
||||
import { NAvatar, NImage } from 'naive-ui';
|
||||
import { getFileExt } from '@/utils/urlUtils';
|
||||
import { getOptionLabel, getOptionTag, Options } from '@/utils/hotgo';
|
||||
import { FormSchema } from '@/components/Form';
|
||||
import { errorImg } from '@/utils/hotgo';
|
||||
import { fallbackSrc } from '@/utils/hotgo';
|
||||
import { defRangeShortcuts } from '@/utils/dateUtil';
|
||||
import { ChooserOption } from '@/api/apply/attachment';
|
||||
export const options = ref<Options>({
|
||||
kind: [],
|
||||
drive: [],
|
||||
});
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import { renderOptionTag } from '@/utils';
|
||||
|
||||
const dict = useDictStore();
|
||||
|
||||
export const schemas = ref<FormSchema[]>([
|
||||
{
|
||||
@@ -19,7 +17,7 @@ export const schemas = ref<FormSchema[]>([
|
||||
defaultValue: null,
|
||||
componentProps: {
|
||||
placeholder: '请选择上传驱动',
|
||||
options: [],
|
||||
options: dict.getOption('config_upload_drive'),
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -32,7 +30,7 @@ export const schemas = ref<FormSchema[]>([
|
||||
defaultValue: null,
|
||||
componentProps: {
|
||||
placeholder: '请选择上传类型',
|
||||
options: [],
|
||||
options: dict.getOption('AttachmentKindOption'),
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -89,11 +87,6 @@ export const columns = [
|
||||
key: 'appId',
|
||||
width: 100,
|
||||
},
|
||||
// {
|
||||
// title: '用户ID',
|
||||
// key: 'memberId',
|
||||
// width: 100,
|
||||
// },
|
||||
{
|
||||
title: '驱动',
|
||||
key: 'drive',
|
||||
@@ -106,19 +99,7 @@ export const columns = [
|
||||
title: '上传类型',
|
||||
key: 'kind',
|
||||
render(row) {
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(options.value.kind, row.kind),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(options.value.kind, row.kind),
|
||||
}
|
||||
);
|
||||
return renderOptionTag('AttachmentKindOption', row.kind);
|
||||
},
|
||||
width: 120,
|
||||
},
|
||||
@@ -153,7 +134,7 @@ export const columns = [
|
||||
width: 40,
|
||||
height: 40,
|
||||
src: row.fileUrl,
|
||||
fallbackSrc: errorImg,
|
||||
fallbackSrc: fallbackSrc(),
|
||||
style: {
|
||||
width: '40px',
|
||||
height: '40px',
|
||||
@@ -185,18 +166,6 @@ export const columns = [
|
||||
},
|
||||
];
|
||||
|
||||
async function loadOptions() {
|
||||
options.value = await ChooserOption();
|
||||
for (const item of schemas.value) {
|
||||
switch (item.field) {
|
||||
case 'kind':
|
||||
item.componentProps.options = options.value.kind;
|
||||
break;
|
||||
case 'drive':
|
||||
item.componentProps.options = options.value.drive;
|
||||
break;
|
||||
}
|
||||
}
|
||||
export function loadOptions() {
|
||||
dict.loadOptions(['AttachmentKindOption', 'config_upload_drive']);
|
||||
}
|
||||
|
||||
await loadOptions();
|
||||
|
||||
@@ -72,17 +72,17 @@
|
||||
<FileUpload ref="fileUploadRef" :finish-call="handleFinishCall" />
|
||||
<FileUpload ref="imageUploadRef" :finish-call="handleFinishCall" upload-type="image" />
|
||||
<FileUpload ref="docUploadRef" :finish-call="handleFinishCall" upload-type="doc" />
|
||||
<MultipartUpload ref="multipartUploadRef" @onFinish="handleFinishCall" />
|
||||
<MultipartUpload ref="multipartUploadRef" @on-finish="handleFinishCall" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { h, reactive, ref } from 'vue';
|
||||
import { h, onMounted, reactive, ref } from 'vue';
|
||||
import { useDialog, useMessage } from 'naive-ui';
|
||||
import { BasicTable, TableAction } from '@/components/Table';
|
||||
import { BasicForm, useForm } from '@/components/Form/index';
|
||||
import { Delete, List } from '@/api/apply/attachment';
|
||||
import { columns, schemas } from './columns';
|
||||
import { columns, schemas, loadOptions } from './columns';
|
||||
import {
|
||||
DeleteOutlined,
|
||||
UploadOutlined,
|
||||
@@ -179,9 +179,6 @@
|
||||
reloadTable();
|
||||
});
|
||||
},
|
||||
onNegativeClick: () => {
|
||||
// message.error('取消');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -197,9 +194,6 @@
|
||||
reloadTable();
|
||||
});
|
||||
},
|
||||
onNegativeClick: () => {
|
||||
// message.error('取消');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -216,6 +210,10 @@
|
||||
reloadTable();
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
loadOptions();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { h } from 'vue';
|
||||
import { NAvatar, NAvatarGroup, NTag, NTooltip } from 'naive-ui';
|
||||
import { noticeTagOptions, noticeTypeOptions } from '@/enums/systemMessageEnum';
|
||||
import { getOptionLabel, getOptionTag } from '@/utils/hotgo';
|
||||
import { NAvatar, NAvatarGroup, NTooltip } from 'naive-ui';
|
||||
import { renderOptionTag } from '@/utils';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
|
||||
const dict = useDictStore();
|
||||
export const columns = [
|
||||
{
|
||||
title: 'ID',
|
||||
@@ -25,19 +26,7 @@ export const columns = [
|
||||
title: '消息类型',
|
||||
key: 'type',
|
||||
render(row) {
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(noticeTypeOptions, row.type),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(noticeTypeOptions, row.type),
|
||||
}
|
||||
);
|
||||
return renderOptionTag('noticeTypeOptions', row.type);
|
||||
},
|
||||
width: 100,
|
||||
},
|
||||
@@ -45,19 +34,7 @@ export const columns = [
|
||||
title: '标签',
|
||||
key: 'tag',
|
||||
render(row) {
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(noticeTagOptions, row.tag),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(noticeTagOptions, row.tag),
|
||||
}
|
||||
);
|
||||
return renderOptionTag('noticeTagOptions', row.tag);
|
||||
},
|
||||
width: 100,
|
||||
},
|
||||
@@ -129,3 +106,7 @@ export const columns = [
|
||||
width: 180,
|
||||
},
|
||||
];
|
||||
|
||||
export function loadOptions() {
|
||||
dict.loadOptions(['sys_normal_disable']);
|
||||
}
|
||||
|
||||
@@ -97,8 +97,8 @@
|
||||
preset="dialog"
|
||||
:title="
|
||||
formParams.id > 0
|
||||
? '编辑' + getOptionLabel(noticeTypeOptions, formParams.type) + ' #' + formParams.id
|
||||
: '发送' + getOptionLabel(noticeTypeOptions, formParams.type)
|
||||
? '编辑' + dict.getLabel('noticeTypeOptions', formParams.type) + ' #' + formParams.id
|
||||
: '发送' + dict.getLabel('noticeTypeOptions', formParams.type)
|
||||
"
|
||||
:style="{
|
||||
width: dialogWidth,
|
||||
@@ -152,7 +152,7 @@
|
||||
placeholder="可以不填"
|
||||
:render-tag="renderTag"
|
||||
v-model:value="formParams.tag"
|
||||
:options="noticeTagOptions"
|
||||
:options="dict.getOptionUnRef('noticeTagOptions')"
|
||||
/>
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
@@ -208,23 +208,19 @@
|
||||
MaxSort,
|
||||
Status,
|
||||
} from '@/api/apply/notice';
|
||||
import { columns } from './columns';
|
||||
import { columns, loadOptions } from './columns';
|
||||
import { BellOutlined, DeleteOutlined, NotificationOutlined, SendOutlined } from '@vicons/antd';
|
||||
import { statusOptions } from '@/enums/optionsiEnum';
|
||||
import {
|
||||
noticeTagOptions,
|
||||
noticeTypeOptions,
|
||||
personOption,
|
||||
renderLabel,
|
||||
renderMultipleSelectTag,
|
||||
} from '@/enums/systemMessageEnum';
|
||||
import { adaModalWidth, getOptionLabel } from '@/utils/hotgo';
|
||||
import { personOption, renderLabel, renderMultipleSelectTag } from '@/enums/systemMessageEnum';
|
||||
import { adaModalWidth } from '@/utils/hotgo';
|
||||
import { renderTag } from '@/utils';
|
||||
import Editor from '@/components/Editor/editor.vue';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { GetMemberOption } from '@/api/org/user';
|
||||
import { usePermission } from '@/hooks/web/usePermission';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
|
||||
const dict = useDictStore();
|
||||
const rules = {
|
||||
title: {
|
||||
required: true,
|
||||
@@ -241,7 +237,7 @@
|
||||
defaultValue: null,
|
||||
componentProps: {
|
||||
placeholder: '请选择消息类型',
|
||||
options: noticeTypeOptions,
|
||||
options: dict.getOption('noticeTypeOptions'),
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -278,7 +274,7 @@
|
||||
defaultValue: null,
|
||||
componentProps: {
|
||||
placeholder: '请选择类型',
|
||||
options: statusOptions,
|
||||
options: dict.getOption('sys_normal_disable'),
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -483,6 +479,7 @@
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
loadOptions();
|
||||
await getMemberOption();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
<n-form-item label="状态" path="status">
|
||||
<n-radio-group v-model:value="params.status" name="status">
|
||||
<n-radio-button
|
||||
v-for="status in options.sys_normal_disable"
|
||||
v-for="status in dict.getOptionUnRef('sys_normal_disable')"
|
||||
:key="Number(status.value)"
|
||||
:value="Number(status.value)"
|
||||
:label="status.label"
|
||||
@@ -80,10 +80,11 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, watch } from 'vue';
|
||||
import { options, State, newState } from './model';
|
||||
import { State, newState } from './model';
|
||||
import { Edit, MaxSort, CheckProvincesUniqueId } from '@/api/apply/provinces';
|
||||
import { FormItemRule, useMessage } from 'naive-ui';
|
||||
import { adaModalWidth } from '@/utils/hotgo';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
const emit = defineEmits(['reloadTable', 'updateShowModal']);
|
||||
|
||||
interface Props {
|
||||
@@ -138,6 +139,7 @@
|
||||
},
|
||||
};
|
||||
|
||||
const dict = useDictStore();
|
||||
const message = useMessage();
|
||||
const formRef = ref<any>({});
|
||||
const formBtnLoading = ref(false);
|
||||
|
||||
@@ -101,14 +101,14 @@
|
||||
</n-space>
|
||||
</template>
|
||||
|
||||
<List :checkedId="checkedId" :optionTreeData="optionTreeData" @reloadTable="loadData" />
|
||||
<List :checkedId="checkedId" :optionTreeData="optionTreeData" @reload-table="loadData" />
|
||||
</n-card>
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
|
||||
<Edit
|
||||
@reloadTable="loadData"
|
||||
@updateShowModal="updateShowModal"
|
||||
@reload-table="loadData"
|
||||
@update-show-modal="updateShowModal"
|
||||
:showModal="showModal"
|
||||
:formParams="formParams"
|
||||
:optionTreeData="optionTreeData"
|
||||
@@ -130,7 +130,7 @@
|
||||
import List from './list.vue';
|
||||
import { getProvincesTree, Delete } from '@/api/apply/provinces';
|
||||
import Edit from './edit.vue';
|
||||
import { newState } from './model';
|
||||
import { newState, loadOptions } from './model';
|
||||
|
||||
const isUpdate = ref(false);
|
||||
const showModal = ref(false);
|
||||
@@ -196,10 +196,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await loadData();
|
||||
});
|
||||
|
||||
async function loadData() {
|
||||
const treeMenuList = await getProvincesTree();
|
||||
Object.assign(
|
||||
@@ -228,4 +224,9 @@
|
||||
function updateShowModal(value) {
|
||||
showModal.value = value;
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
loadOptions();
|
||||
await loadData();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -183,9 +183,6 @@
|
||||
reloadTable();
|
||||
});
|
||||
},
|
||||
onNegativeClick: () => {
|
||||
// message.error('取消');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { h, ref } from 'vue';
|
||||
import { h } from 'vue';
|
||||
import { NTag } from 'naive-ui';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { getOptionLabel, getOptionTag, Options } from '@/utils/hotgo';
|
||||
import { Dicts } from '@/api/dict/dict';
|
||||
import { isNullObject } from '@/utils/is';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import { renderOptionTag } from '@/utils';
|
||||
|
||||
const dict = useDictStore();
|
||||
|
||||
export const listColumns = [
|
||||
{
|
||||
@@ -45,22 +46,7 @@ export const listColumns = [
|
||||
title: '状态',
|
||||
key: 'status',
|
||||
render(row) {
|
||||
if (isNullObject(row.status)) {
|
||||
return ``;
|
||||
}
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(options.value.sys_normal_disable, row.status),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(options.value.sys_normal_disable, row.status),
|
||||
}
|
||||
);
|
||||
return renderOptionTag('sys_normal_disable', row.status);
|
||||
},
|
||||
},
|
||||
];
|
||||
@@ -96,14 +82,6 @@ export function newState(state: State | null): State {
|
||||
return cloneDeep(defaultState);
|
||||
}
|
||||
|
||||
export const options = ref<Options>({
|
||||
sys_normal_disable: [],
|
||||
});
|
||||
|
||||
async function loadOptions() {
|
||||
options.value = await Dicts({
|
||||
types: ['sys_normal_disable'],
|
||||
});
|
||||
export function loadOptions() {
|
||||
dict.loadOptions(['sys_normal_disable']);
|
||||
}
|
||||
|
||||
await loadOptions();
|
||||
|
||||
@@ -100,7 +100,6 @@
|
||||
>
|
||||
<n-form
|
||||
:model="paymentParams"
|
||||
:rules="rules"
|
||||
ref="PaymentRef"
|
||||
label-placement="left"
|
||||
:label-width="100"
|
||||
@@ -329,15 +328,14 @@
|
||||
formBtnLoading.value = true;
|
||||
formRef.value.validate((errors) => {
|
||||
if (!errors) {
|
||||
Apply({ money: formParams.value.money })
|
||||
.then((_res) => {
|
||||
message.success('操作成功');
|
||||
setTimeout(() => {
|
||||
showModal.value = false;
|
||||
reloadTable();
|
||||
formParams.value = ref(resetFormParams);
|
||||
});
|
||||
Apply({ money: formParams.value.money }).then((_res) => {
|
||||
message.success('操作成功');
|
||||
setTimeout(() => {
|
||||
showModal.value = false;
|
||||
reloadTable();
|
||||
formParams.value = ref(resetFormParams);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
message.error('请填写完整信息');
|
||||
}
|
||||
@@ -358,15 +356,14 @@
|
||||
id: PaymentRef.value.model.id,
|
||||
status: PaymentRef.value.model.status,
|
||||
msg: PaymentRef.value.model.msg,
|
||||
})
|
||||
.then((_res) => {
|
||||
message.success('操作成功');
|
||||
setTimeout(() => {
|
||||
showPaymentModal.value = false;
|
||||
reloadTable();
|
||||
PaymentRef.value = ref(resetPaymentParams);
|
||||
});
|
||||
}).then((_res) => {
|
||||
message.success('操作成功');
|
||||
setTimeout(() => {
|
||||
showPaymentModal.value = false;
|
||||
reloadTable();
|
||||
PaymentRef.value = ref(resetPaymentParams);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
message.error('请填写完整信息');
|
||||
}
|
||||
|
||||
@@ -26,19 +26,21 @@
|
||||
import { onMounted, ref } from 'vue';
|
||||
import List from './list.vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { loadOptions } from './model';
|
||||
|
||||
const router = useRouter();
|
||||
const defaultTab = ref('');
|
||||
|
||||
function handleBeforeLeave(tabName: string) {
|
||||
defaultTab.value = tabName;
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (router.currentRoute.value.query?.type) {
|
||||
defaultTab.value = router.currentRoute.value.query.type as string;
|
||||
}
|
||||
loadOptions();
|
||||
});
|
||||
|
||||
function handleBeforeLeave(tabName: string) {
|
||||
defaultTab.value = tabName;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
|
||||
@@ -1,62 +1,10 @@
|
||||
import { h, ref } from 'vue';
|
||||
import { NTag } from 'naive-ui';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { ref } from 'vue';
|
||||
import { FormSchema } from '@/components/Form';
|
||||
import { Option } from '@/api/creditsLog';
|
||||
import { isNullObject } from '@/utils/is';
|
||||
import { defRangeShortcuts } from '@/utils/dateUtil';
|
||||
import { getOptionLabel, getOptionTag, Options } from '@/utils/hotgo';
|
||||
import {Dicts} from "@/api/dict/dict";
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import { renderOptionTag } from '@/utils';
|
||||
|
||||
export interface State {
|
||||
id: number;
|
||||
memberId: number;
|
||||
appId: string;
|
||||
addonsName: string;
|
||||
creditType: string;
|
||||
creditGroup: string;
|
||||
beforeNum: number;
|
||||
num: number;
|
||||
afterNum: number;
|
||||
remark: string;
|
||||
ip: string;
|
||||
mapId: number;
|
||||
status: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export const defaultState = {
|
||||
id: 0,
|
||||
memberId: 0,
|
||||
appId: '',
|
||||
addonsName: '',
|
||||
creditType: '',
|
||||
creditGroup: '',
|
||||
beforeNum: 0,
|
||||
num: 0,
|
||||
afterNum: 0,
|
||||
remark: '',
|
||||
ip: '',
|
||||
mapId: 0,
|
||||
status: 1,
|
||||
createdAt: '',
|
||||
updatedAt: '',
|
||||
};
|
||||
|
||||
export function newState(state: State | null): State {
|
||||
if (state !== null) {
|
||||
return cloneDeep(state);
|
||||
}
|
||||
return cloneDeep(defaultState);
|
||||
}
|
||||
|
||||
export const options = ref<Options>({
|
||||
creditType: [],
|
||||
creditGroup: [],
|
||||
});
|
||||
|
||||
export const rules = {};
|
||||
const dict = useDictStore();
|
||||
|
||||
export const schemas = ref<FormSchema[]>([
|
||||
{
|
||||
@@ -77,7 +25,7 @@ export const schemas = ref<FormSchema[]>([
|
||||
defaultValue: null,
|
||||
componentProps: {
|
||||
placeholder: '请选择变动的组别',
|
||||
options: [],
|
||||
options: dict.getOption('creditGroup'),
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -146,22 +94,7 @@ export const columns = [
|
||||
title: '变动类型',
|
||||
key: 'creditType',
|
||||
render(row) {
|
||||
if (isNullObject(row.creditType)) {
|
||||
return ``;
|
||||
}
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(options.value.creditType, row.creditType),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(options.value.creditType, row.creditType),
|
||||
}
|
||||
);
|
||||
return renderOptionTag('creditType', row.creditType);
|
||||
},
|
||||
width: 150,
|
||||
},
|
||||
@@ -169,22 +102,7 @@ export const columns = [
|
||||
title: '组别',
|
||||
key: 'creditGroup',
|
||||
render(row) {
|
||||
if (isNullObject(row.creditGroup)) {
|
||||
return ``;
|
||||
}
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(options.value.creditGroup, row.creditGroup),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(options.value.creditGroup, row.creditGroup),
|
||||
}
|
||||
);
|
||||
return renderOptionTag('creditGroup', row.creditGroup);
|
||||
},
|
||||
width: 150,
|
||||
},
|
||||
@@ -240,20 +158,6 @@ export const columns = [
|
||||
},
|
||||
];
|
||||
|
||||
async function loadOptions() {
|
||||
options.value = await Dicts({
|
||||
types: ['creditType', 'creditGroup'],
|
||||
});
|
||||
for (const item of schemas.value) {
|
||||
switch (item.field) {
|
||||
case 'creditType':
|
||||
item.componentProps.options = options.value.creditType;
|
||||
break;
|
||||
case 'creditGroup':
|
||||
item.componentProps.options = options.value.creditGroup;
|
||||
break;
|
||||
}
|
||||
}
|
||||
export function loadOptions() {
|
||||
dict.loadOptions(['creditType', 'creditGroup']);
|
||||
}
|
||||
|
||||
await loadOptions();
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
:request="loadDataTable"
|
||||
:row-key="(row) => row.id"
|
||||
ref="actionRef"
|
||||
:actionColumn="actionColumn"
|
||||
@update:checked-row-keys="onCheckedRow"
|
||||
:scroll-x="1090"
|
||||
:resizeHeightOffset="-10000"
|
||||
size="small"
|
||||
@@ -51,33 +49,19 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { h, reactive, ref } from 'vue';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { BasicTable, TableAction } from '@/components/Table';
|
||||
import { BasicTable } from '@/components/Table';
|
||||
import { BasicForm, useForm } from '@/components/Form/index';
|
||||
import { usePermission } from '@/hooks/web/usePermission';
|
||||
import { List, Export } from '@/api/pay/refund';
|
||||
import { columns, schemas } from './model';
|
||||
import { columns, schemas, loadOptions } from './model';
|
||||
import { ExportOutlined } from '@vicons/antd';
|
||||
|
||||
const { hasPermission } = usePermission();
|
||||
const actionRef = ref();
|
||||
const message = useMessage();
|
||||
const searchFormRef = ref<any>({});
|
||||
|
||||
const actionColumn = reactive({
|
||||
width: 300,
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
// fixed: 'right',
|
||||
render(record) {
|
||||
return h(TableAction as any, {
|
||||
style: 'button',
|
||||
actions: [],
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const [register, {}] = useForm({
|
||||
gridProps: { cols: '1 s:1 m:2 l:3 xl:4 2xl:4' },
|
||||
labelWidth: 80,
|
||||
@@ -96,6 +80,10 @@
|
||||
message.loading('正在导出列表...', { duration: 1200 });
|
||||
Export(searchFormRef.value?.formModel);
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
loadOptions();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
|
||||
@@ -1,60 +1,10 @@
|
||||
import { h, ref } from 'vue';
|
||||
import { NAvatar, NImage, NTag, NSwitch, NRate } from 'naive-ui';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { ref } from 'vue';
|
||||
import { FormSchema } from '@/components/Form';
|
||||
import { Dicts } from '@/api/dict/dict';
|
||||
import { isNullObject } from '@/utils/is';
|
||||
import { defRangeShortcuts } from '@/utils/dateUtil';
|
||||
import { getOptionLabel, getOptionTag, Options } from '@/utils/hotgo';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import { renderOptionTag } from '@/utils';
|
||||
|
||||
export interface State {
|
||||
id: number;
|
||||
memberId: number;
|
||||
appId: string;
|
||||
addonsName: string;
|
||||
creditType: string;
|
||||
creditGroup: string;
|
||||
beforeNum: number;
|
||||
num: number;
|
||||
afterNum: number;
|
||||
remark: string;
|
||||
ip: string;
|
||||
mapId: number;
|
||||
status: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export const defaultState = {
|
||||
id: 0,
|
||||
memberId: 0,
|
||||
appId: '',
|
||||
addonsName: '',
|
||||
creditType: '',
|
||||
creditGroup: '',
|
||||
beforeNum: 0,
|
||||
num: 0,
|
||||
afterNum: 0,
|
||||
remark: '',
|
||||
ip: '',
|
||||
mapId: 0,
|
||||
status: 1,
|
||||
createdAt: '',
|
||||
updatedAt: '',
|
||||
};
|
||||
|
||||
export function newState(state: State | null): State {
|
||||
if (state !== null) {
|
||||
return cloneDeep(state);
|
||||
}
|
||||
return cloneDeep(defaultState);
|
||||
}
|
||||
|
||||
export const options = ref<Options>({
|
||||
sys_normal_disable: [],
|
||||
});
|
||||
|
||||
export const rules = {};
|
||||
const dict = useDictStore();
|
||||
|
||||
export const schemas = ref<FormSchema[]>([
|
||||
{
|
||||
@@ -211,22 +161,7 @@ export const columns = [
|
||||
title: '状态',
|
||||
key: 'status',
|
||||
render(row) {
|
||||
if (isNullObject(row.status)) {
|
||||
return ``;
|
||||
}
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(options.value.sys_normal_disable, row.status),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(options.value.sys_normal_disable, row.status),
|
||||
}
|
||||
);
|
||||
return renderOptionTag('sys_normal_disable', row.status);
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -239,17 +174,8 @@ export const columns = [
|
||||
},
|
||||
];
|
||||
|
||||
async function loadOptions() {
|
||||
options.value = await Dicts({
|
||||
types: ['sys_normal_disable'],
|
||||
});
|
||||
for (const item of schemas.value) {
|
||||
switch (item.field) {
|
||||
case 'status':
|
||||
item.componentProps.options = options.value.sys_normal_disable;
|
||||
break;
|
||||
}
|
||||
}
|
||||
export function loadOptions() {
|
||||
dict.loadOptions(['sys_normal_disable']);
|
||||
}
|
||||
|
||||
await loadOptions();
|
||||
loadOptions();
|
||||
|
||||
@@ -36,7 +36,10 @@
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item label="更新状态" path="status">
|
||||
<n-select v-model:value="params.status" :options="options.acceptRefundStatus" />
|
||||
<n-select
|
||||
v-model:value="params.status"
|
||||
:options="dict.getOptionUnRef('acceptRefundStatus')"
|
||||
/>
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item label="拒绝原因" path="rejectRefundReason" v-if="params.status === 9">
|
||||
@@ -64,10 +67,11 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, watch } from 'vue';
|
||||
import { rules, State, newState, options } from './model';
|
||||
import { rules, State, newState } from './model';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { adaModalWidth } from '@/utils/hotgo';
|
||||
import { AcceptRefund, View } from '@/api/order';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
const emit = defineEmits(['reloadTable', 'updateShowModal']);
|
||||
|
||||
interface Props {
|
||||
@@ -93,6 +97,7 @@
|
||||
|
||||
const loading = ref(false);
|
||||
const params = ref<State>(props.formParams);
|
||||
const dict = useDictStore();
|
||||
const message = useMessage();
|
||||
const formRef = ref<any>({});
|
||||
const formBtnLoading = ref(false);
|
||||
|
||||
@@ -86,20 +86,21 @@
|
||||
|
||||
function confirmForm(e) {
|
||||
e.preventDefault();
|
||||
formBtnLoading.value = true;
|
||||
formRef.value.validate((errors) => {
|
||||
if (!errors) {
|
||||
ApplyRefund(params.value).then((_res) => {
|
||||
message.success('操作成功');
|
||||
setTimeout(() => {
|
||||
formBtnLoading.value = true;
|
||||
ApplyRefund(params.value)
|
||||
.then((_res) => {
|
||||
message.success('操作成功');
|
||||
isShowModal.value = false;
|
||||
emit('reloadTable');
|
||||
})
|
||||
.finally(() => {
|
||||
formBtnLoading.value = false;
|
||||
});
|
||||
});
|
||||
} else {
|
||||
message.error('请填写完整信息');
|
||||
}
|
||||
formBtnLoading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<n-tab-pane
|
||||
:name="item.key.toString()"
|
||||
:tab="item.label"
|
||||
v-for="item in options.orderStatus"
|
||||
v-for="item in dict.getOptionUnRef('orderStatus')"
|
||||
:key="item.key"
|
||||
>
|
||||
<List :type="defaultTab" />
|
||||
@@ -28,18 +28,21 @@
|
||||
import { onMounted, ref } from 'vue';
|
||||
import List from './list.vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { options } from '@/views/asset/rechargeLog/model';
|
||||
import { loadOptions } from './model';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
|
||||
const dict = useDictStore();
|
||||
const router = useRouter();
|
||||
const defaultTab = ref('-1');
|
||||
|
||||
function handleBeforeLeave(tabName: string) {
|
||||
defaultTab.value = tabName;
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (router.currentRoute.value.query?.type) {
|
||||
defaultTab.value = router.currentRoute.value.query.type as string;
|
||||
}
|
||||
loadOptions();
|
||||
});
|
||||
|
||||
function handleBeforeLeave(tabName: string) {
|
||||
defaultTab.value = tabName;
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -58,15 +58,15 @@
|
||||
</n-card>
|
||||
|
||||
<ApplyRefund
|
||||
@reloadTable="reloadTable"
|
||||
@updateShowModal="updateShowModal"
|
||||
@reload-table="reloadTable"
|
||||
@update-show-modal="updateShowModal"
|
||||
:showModal="showModal"
|
||||
:formParams="formParams"
|
||||
/>
|
||||
|
||||
<AcceptRefund
|
||||
@reloadTable="reloadTable"
|
||||
@updateShowModal="updateAcceptShowModal"
|
||||
@reload-table="reloadTable"
|
||||
@update-show-modal="updateAcceptShowModal"
|
||||
:showModal="showAcceptModal"
|
||||
:formParams="formParams"
|
||||
/>
|
||||
@@ -184,9 +184,6 @@
|
||||
reloadTable();
|
||||
});
|
||||
},
|
||||
onNegativeClick: () => {
|
||||
// message.error('取消');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
import { h, ref } from 'vue';
|
||||
import { NTag } from 'naive-ui';
|
||||
import { ref } from 'vue';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { FormSchema } from '@/components/Form';
|
||||
import { Option } from '@/api/order';
|
||||
import { isNullObject } from '@/utils/is';
|
||||
import { defRangeShortcuts } from '@/utils/dateUtil';
|
||||
import { getOptionLabel, getOptionTag, Options } from '@/utils/hotgo';
|
||||
import { Dicts } from '@/api/dict/dict';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import { renderOptionTag } from '@/utils';
|
||||
|
||||
export interface State {
|
||||
id: number;
|
||||
@@ -49,12 +46,7 @@ export function newState(state: State | null): State {
|
||||
return cloneDeep(defaultState);
|
||||
}
|
||||
|
||||
export const options = ref<Options>({
|
||||
orderStatus: [],
|
||||
acceptRefundStatus: [],
|
||||
payType: [],
|
||||
});
|
||||
|
||||
const dict = useDictStore();
|
||||
export const rules = {};
|
||||
|
||||
export const schemas = ref<FormSchema[]>([
|
||||
@@ -131,22 +123,7 @@ export const columns = [
|
||||
title: '支付方式',
|
||||
key: 'payLogPayType',
|
||||
render(row) {
|
||||
if (isNullObject(row.payLogPayType)) {
|
||||
return ``;
|
||||
}
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(options.value.payType, row.payLogPayType),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(options.value.payType, row.payLogPayType),
|
||||
}
|
||||
);
|
||||
return renderOptionTag('payType', row.payLogPayType);
|
||||
},
|
||||
width: 150,
|
||||
},
|
||||
@@ -162,24 +139,7 @@ export const columns = [
|
||||
title: '订单状态',
|
||||
key: 'status',
|
||||
render(row) {
|
||||
if (isNullObject(row.status)) {
|
||||
return ``;
|
||||
}
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(options.value.orderStatus, row.status),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () =>
|
||||
getOptionLabel(options.value.orderStatus, row.status) +
|
||||
(row.status === 9 ? ',' + row.rejectRefundReason : ''),
|
||||
}
|
||||
);
|
||||
return renderOptionTag('orderStatus', row.status);
|
||||
},
|
||||
width: 150,
|
||||
},
|
||||
@@ -190,23 +150,6 @@ export const columns = [
|
||||
},
|
||||
];
|
||||
|
||||
async function loadOptions() {
|
||||
options.value = await Dicts({
|
||||
types: ['payType', 'orderStatus', 'acceptRefundStatus'],
|
||||
});
|
||||
for (const item of schemas.value) {
|
||||
switch (item.field) {
|
||||
case 'status':
|
||||
item.componentProps.options = options.value.orderStatus;
|
||||
break;
|
||||
case 'acceptRefundStatus':
|
||||
item.componentProps.options = options.value.acceptRefundStatus;
|
||||
break;
|
||||
case 'payType':
|
||||
item.componentProps.options = options.value.payType;
|
||||
break;
|
||||
}
|
||||
}
|
||||
export function loadOptions() {
|
||||
dict.loadOptions(['payType', 'orderStatus', 'acceptRefundStatus']);
|
||||
}
|
||||
|
||||
await loadOptions();
|
||||
|
||||
@@ -63,16 +63,6 @@
|
||||
/>
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
<n-gi span="1">
|
||||
<n-form-item label="状态" path="status">
|
||||
<n-select v-model:value="formValue.status" :options="options.sys_normal_disable" />
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
<n-gi span="1">
|
||||
<n-form-item label="测试分类" path="categoryId">
|
||||
<n-select v-model:value="formValue.categoryId" :options="options.testCategoryOption" />
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
</n-form>
|
||||
</n-spin>
|
||||
@@ -93,8 +83,9 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import { Edit, View, MaxSort } from '@/api/curdDemo';
|
||||
import { options, State, newState, rules } from './model';
|
||||
import { State, newState, rules } from './model';
|
||||
import Editor from '@/components/Editor/editor.vue';
|
||||
import UploadImage from '@/components/Upload/uploadImage.vue';
|
||||
import UploadFile from '@/components/Upload/uploadFile.vue';
|
||||
@@ -106,6 +97,7 @@
|
||||
const emit = defineEmits(['reloadTable']);
|
||||
const message = useMessage();
|
||||
const settingStore = useProjectSettingStore();
|
||||
const dict = useDictStore();
|
||||
const loading = ref(false);
|
||||
const showModal = ref(false);
|
||||
const formValue = ref<State>(newState(null));
|
||||
@@ -144,25 +136,28 @@
|
||||
});
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
function confirmForm(e) {
|
||||
e.preventDefault();
|
||||
formBtnLoading.value = true;
|
||||
formRef.value.validate((errors) => {
|
||||
if (!errors) {
|
||||
Edit(formValue.value).then((_res) => {
|
||||
message.success('操作成功');
|
||||
setTimeout(() => {
|
||||
formBtnLoading.value = true;
|
||||
Edit(formValue.value)
|
||||
.then((_res) => {
|
||||
message.success('操作成功');
|
||||
closeForm();
|
||||
emit('reloadTable');
|
||||
})
|
||||
.finally(() => {
|
||||
formBtnLoading.value = false;
|
||||
});
|
||||
});
|
||||
} else {
|
||||
message.error('请填写完整信息');
|
||||
}
|
||||
formBtnLoading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
// 关闭表单
|
||||
function closeForm() {
|
||||
showModal.value = false;
|
||||
loading.value = false;
|
||||
@@ -173,4 +168,4 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less"></style>
|
||||
<style lang="less"></style>
|
||||
@@ -50,7 +50,8 @@
|
||||
import { BasicTable, TableAction } from '@/components/Table';
|
||||
import { BasicForm, useForm } from '@/components/Form/index';
|
||||
import { usePermission } from '@/hooks/web/usePermission';
|
||||
import { List, Export, Delete } from '@/api/curdDemo';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import { List, Export, Delete, Status } from '@/api/curdDemo';
|
||||
import { PlusOutlined, ExportOutlined, DeleteOutlined } from '@vicons/antd';
|
||||
import { columns, schemas, loadOptions } from './model';
|
||||
import { adaTableScrollX } from '@/utils/hotgo';
|
||||
@@ -59,6 +60,7 @@
|
||||
const dialog = useDialog();
|
||||
const message = useMessage();
|
||||
const { hasPermission } = usePermission();
|
||||
const dict = useDictStore();
|
||||
const actionRef = ref();
|
||||
const searchFormRef = ref<any>({});
|
||||
const editRef = ref();
|
||||
@@ -66,7 +68,7 @@
|
||||
const checkedIds = ref([]);
|
||||
|
||||
const actionColumn = reactive({
|
||||
width: 144,
|
||||
width: 216,
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
fixed: 'right',
|
||||
@@ -80,6 +82,22 @@
|
||||
auth: ['/curdDemo/edit'],
|
||||
},
|
||||
|
||||
{
|
||||
label: '禁用',
|
||||
onClick: handleStatus.bind(null, record, 2),
|
||||
ifShow: () => {
|
||||
return record.status === 1;
|
||||
},
|
||||
auth: ['/curdDemo/status'],
|
||||
},
|
||||
{
|
||||
label: '启用',
|
||||
onClick: handleStatus.bind(null, record, 1),
|
||||
ifShow: () => {
|
||||
return record.status === 2;
|
||||
},
|
||||
auth: ['/curdDemo/status'],
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
@@ -170,9 +188,20 @@
|
||||
Export(searchFormRef.value?.formModel);
|
||||
}
|
||||
|
||||
// 修改状态
|
||||
function handleStatus(record: Recordable, status: number) {
|
||||
Status({ id: record.id, status: status }).then((_res) => {
|
||||
message.success('设为' + dict.getLabel('sys_normal_disable', status) + '成功');
|
||||
setTimeout(() => {
|
||||
reloadTable();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadOptions();
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
<style lang="less" scoped></style>
|
||||
@@ -1,15 +1,16 @@
|
||||
import { h, ref } from 'vue';
|
||||
import { NImage, NAvatar, NSwitch, NTag } from 'naive-ui';
|
||||
import { NImage, NAvatar, NSwitch } from 'naive-ui';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { FormSchema } from '@/components/Form';
|
||||
import { Dicts } from '@/api/dict/dict';
|
||||
import { isNullObject } from '@/utils/is';
|
||||
import { getFileExt } from '@/utils/urlUtils';
|
||||
import { defRangeShortcuts } from '@/utils/dateUtil';
|
||||
import { Option, errorImg, getOptionLabel, getOptionTag } from '@/utils/hotgo';
|
||||
import { fallbackSrc } from '@/utils/hotgo';
|
||||
import { renderPopoverMemberSumma, MemberSumma } from '@/utils';
|
||||
import { Switch } from '@/api/curdDemo';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import { usePermission } from '@/hooks/web/usePermission';
|
||||
|
||||
const dict = useDictStore();
|
||||
const { hasPermission } = usePermission();
|
||||
const $message = window['$message'];
|
||||
|
||||
@@ -76,12 +77,6 @@ export const rules = {
|
||||
type: 'number',
|
||||
message: '请输入排序',
|
||||
},
|
||||
categoryId: {
|
||||
required: true,
|
||||
trigger: ['blur', 'input'],
|
||||
type: 'number',
|
||||
message: '请输入测试分类',
|
||||
},
|
||||
};
|
||||
|
||||
// 表格搜索表单
|
||||
@@ -119,19 +114,6 @@ export const schemas = ref<FormSchema[]>([
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'status',
|
||||
component: 'NSelect',
|
||||
label: '状态',
|
||||
defaultValue: null,
|
||||
componentProps: {
|
||||
placeholder: '请选择状态',
|
||||
options: [],
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'createdBy',
|
||||
component: 'NInput',
|
||||
@@ -156,19 +138,6 @@ export const schemas = ref<FormSchema[]>([
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'categoryId',
|
||||
component: 'NSelect',
|
||||
label: '测试分类',
|
||||
defaultValue: null,
|
||||
componentProps: {
|
||||
placeholder: '请选择测试分类',
|
||||
options: [],
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'testCategoryName',
|
||||
component: 'NInput',
|
||||
@@ -212,8 +181,7 @@ export const columns = [
|
||||
width: 32,
|
||||
height: 32,
|
||||
src: row.image,
|
||||
fallbackSrc: errorImg,
|
||||
onError: errorImg,
|
||||
fallbackSrc: fallbackSrc(),
|
||||
style: {
|
||||
width: '32px',
|
||||
height: '32px',
|
||||
@@ -270,30 +238,6 @@ export const columns = [
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
key: 'status',
|
||||
align: 'left',
|
||||
width: 100,
|
||||
render(row) {
|
||||
if (isNullObject(row.status)) {
|
||||
return ``;
|
||||
}
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(options.value.sys_normal_disable, row.status),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(options.value.sys_normal_disable, row.status),
|
||||
}
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '创建者',
|
||||
key: 'createdBy',
|
||||
@@ -324,30 +268,6 @@ export const columns = [
|
||||
align: 'left',
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: '测试分类',
|
||||
key: 'categoryId',
|
||||
align: 'left',
|
||||
width: 100,
|
||||
render(row) {
|
||||
if (isNullObject(row.categoryId)) {
|
||||
return ``;
|
||||
}
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(options.value.testCategoryOption, row.categoryId),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(options.value.testCategoryOption, row.categoryId),
|
||||
}
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '关联分类',
|
||||
key: 'testCategoryName',
|
||||
@@ -356,27 +276,7 @@ export const columns = [
|
||||
},
|
||||
];
|
||||
|
||||
// 字典数据选项
|
||||
export const options = ref({
|
||||
sys_normal_disable: [] as Option[],
|
||||
testCategoryOption: [] as Option[],
|
||||
});
|
||||
|
||||
// 加载字典数据选项
|
||||
export function loadOptions() {
|
||||
Dicts({
|
||||
types: ['sys_normal_disable', 'testCategoryOption'],
|
||||
}).then((res) => {
|
||||
options.value = res;
|
||||
for (const item of schemas.value) {
|
||||
switch (item.field) {
|
||||
case 'status':
|
||||
item.componentProps.options = options.value.sys_normal_disable;
|
||||
break;
|
||||
case 'categoryId':
|
||||
item.componentProps.options = options.value.testCategoryOption;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
dict.loadOptions(['sys_normal_disable', 'testCategoryOption']);
|
||||
}
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<n-drawer v-model:show="showModal" :width="dialogWidth">
|
||||
<n-drawer-content title="CURD列表详情" closable>
|
||||
<n-spin :show="loading" description="请稍候...">
|
||||
<n-descriptions label-placement="left" class="py-2" column="1">
|
||||
<n-descriptions-item label="测试分类">
|
||||
<n-tag :type="getOptionTag(options.testCategoryOption, formValue?.categoryId)" size="small" class="min-left-space">
|
||||
{{ getOptionLabel(options.testCategoryOption, formValue?.categoryId) }}
|
||||
</n-tag>
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item>
|
||||
<template #label>
|
||||
标题
|
||||
</template>
|
||||
{{ formValue.title }}
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item>
|
||||
<template #label>
|
||||
描述
|
||||
</template>
|
||||
<span v-html="formValue.description"></span>
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item>
|
||||
<template #label>
|
||||
内容
|
||||
</template>
|
||||
<span v-html="formValue.content"></span>
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item>
|
||||
<template #label>
|
||||
所在城市
|
||||
</template>
|
||||
{{ formValue.cityId }}
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item>
|
||||
<template #label>
|
||||
排序
|
||||
</template>
|
||||
{{ formValue.sort }}
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item>
|
||||
<template #label>
|
||||
单图
|
||||
</template>
|
||||
<n-image style="margin-left: 10px; height: 100px; width: 100px" :src="formValue.image"/>
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item label="显示开关">
|
||||
<n-switch v-model:value="formValue.switch" :unchecked-value="2" :checked-value="1" :disabled="true"/>
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item>
|
||||
<template #label>
|
||||
附件
|
||||
</template>
|
||||
<div class="upload-card" v-show="formValue.attachfile !== ''" @click="download(formValue.attachfile)">
|
||||
<div class="upload-card-item" style="height: 100px; width: 100px">
|
||||
<div class="upload-card-item-info">
|
||||
<div class="img-box">
|
||||
<n-avatar :style="fileAvatarCSS">
|
||||
{{ getFileExt(formValue.attachfile) }}
|
||||
</n-avatar>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item label="状态">
|
||||
<n-tag :type="getOptionTag(options.sys_normal_disable, formValue?.status)" size="small" class="min-left-space">
|
||||
{{ getOptionLabel(options.sys_normal_disable, formValue?.status) }}
|
||||
</n-tag>
|
||||
</n-descriptions-item>
|
||||
</n-descriptions>
|
||||
</n-spin>
|
||||
</n-drawer-content>
|
||||
</n-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref } from 'vue';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { View } from '@/api/curdDemo';
|
||||
import { State, newState, options } from './model';
|
||||
import { adaModalWidth, getOptionLabel, getOptionTag } from '@/utils/hotgo';
|
||||
import { getFileExt } from '@/utils/urlUtils';
|
||||
|
||||
const message = useMessage();
|
||||
const loading = ref(false);
|
||||
const showModal = ref(false);
|
||||
const formValue = ref(newState(null));
|
||||
const dialogWidth = computed(() => {
|
||||
return adaModalWidth(580);
|
||||
});
|
||||
const fileAvatarCSS = computed(() => {
|
||||
return {
|
||||
'--n-merged-size': `var(--n-avatar-size-override, 80px)`,
|
||||
'--n-font-size': `18px`,
|
||||
};
|
||||
});
|
||||
|
||||
//下载
|
||||
function download(url: string) {
|
||||
window.open(url);
|
||||
}
|
||||
|
||||
function openModal(state: State) {
|
||||
showModal.value = true;
|
||||
loading.value = true;
|
||||
View({ id: state.id })
|
||||
.then((res) => {
|
||||
formValue.value = res;
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
openModal,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
@@ -3,9 +3,7 @@
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, onMounted, ref, Ref } from 'vue';
|
||||
|
||||
import { useECharts } from '@/hooks/web/useECharts';
|
||||
|
||||
import { basicProps } from './props';
|
||||
|
||||
export default defineComponent({
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
<n-form-item label="功能分组" path="group">
|
||||
<n-select
|
||||
placeholder="请选择"
|
||||
:options="options.addonsGroupOptions"
|
||||
:options="dict.getOptionUnRef('addonsGroupOptions')"
|
||||
v-model:value="formParams.group"
|
||||
:on-update:value="onUpdateValueGroup"
|
||||
/>
|
||||
@@ -86,7 +86,7 @@
|
||||
<n-checkbox
|
||||
:value="option.value"
|
||||
:label="option.label"
|
||||
v-for="option in options.addonsExtend"
|
||||
v-for="option in dict.getOptionUnRef('addonsExtend')"
|
||||
:key="option"
|
||||
/>
|
||||
</n-space>
|
||||
@@ -128,15 +128,17 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, h, reactive, ref } from 'vue';
|
||||
import { computed, h, onMounted, reactive, ref } from 'vue';
|
||||
import { NIcon, useMessage, useDialog, useNotification } from 'naive-ui';
|
||||
import { BasicTable, TableAction } from '@/components/Table';
|
||||
import { BasicForm, useForm } from '@/components/Form/index';
|
||||
import { List, Build, UnInstall, Install, Upgrade } from '@/api/develop/addons';
|
||||
import { PlusOutlined } from '@vicons/antd';
|
||||
import { newState, schemas, columns, options } from './model';
|
||||
import { newState, schemas, columns, loadOptions } from './model';
|
||||
import { adaModalWidth } from '@/utils/hotgo';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
|
||||
const dict = useDictStore();
|
||||
const dialog = useDialog();
|
||||
const message = useMessage();
|
||||
const notification = useNotification();
|
||||
@@ -315,6 +317,10 @@
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
loadOptions();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { h, ref } from 'vue';
|
||||
import { Dicts } from '@/api/dict/dict';
|
||||
import { errorImg, Option, Options } from '@/utils/hotgo';
|
||||
import { fallbackSrc } from '@/utils/hotgo';
|
||||
import { isUrl } from '@/utils/is';
|
||||
import { NIcon, NIconWrapper, NImage, NTag } from 'naive-ui';
|
||||
import { getIconComponent } from '@/utils/icons';
|
||||
import { FormSchema } from '@/components/Form';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
|
||||
const dict = useDictStore();
|
||||
|
||||
export const genInfoObj = {
|
||||
label: '',
|
||||
@@ -36,7 +38,7 @@ export const columns = [
|
||||
width: 48,
|
||||
height: 48,
|
||||
src: row.logo,
|
||||
fallbackSrc: errorImg,
|
||||
fallbackSrc: fallbackSrc(),
|
||||
style: {
|
||||
width: '48px',
|
||||
height: '48px',
|
||||
@@ -152,7 +154,7 @@ export const schemas = ref<FormSchema[]>([
|
||||
label: '分组',
|
||||
componentProps: {
|
||||
placeholder: '请选择分组',
|
||||
options: [],
|
||||
options: dict.getOption('addonsGroupOptions'),
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -164,7 +166,7 @@ export const schemas = ref<FormSchema[]>([
|
||||
label: '安装状态',
|
||||
componentProps: {
|
||||
placeholder: '请选择状态',
|
||||
options: [],
|
||||
options: dict.getOption('addonsInstallStatus'),
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -172,32 +174,6 @@ export const schemas = ref<FormSchema[]>([
|
||||
},
|
||||
]);
|
||||
|
||||
export interface IOptions extends Options {
|
||||
addonsGroupOptions: Option[];
|
||||
addonsInstallStatus: Option[];
|
||||
addonsExtend: Option[];
|
||||
export function loadOptions() {
|
||||
dict.loadOptions(['addonsGroupOptions', 'addonsInstallStatus', 'addonsExtend']);
|
||||
}
|
||||
|
||||
export const options = ref<IOptions>({
|
||||
addonsGroupOptions: [],
|
||||
addonsInstallStatus: [],
|
||||
addonsExtend: [],
|
||||
});
|
||||
|
||||
async function loadOptions() {
|
||||
options.value = await Dicts({
|
||||
types: ['addonsGroupOptions', 'addonsInstallStatus', 'addonsExtend'],
|
||||
});
|
||||
for (const item of schemas.value) {
|
||||
switch (item.field) {
|
||||
case 'status':
|
||||
item.componentProps.options = options.value.addonsInstallStatus;
|
||||
break;
|
||||
case 'group':
|
||||
item.componentProps.options = options.value.addonsGroupOptions;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await loadOptions();
|
||||
|
||||
@@ -31,7 +31,12 @@
|
||||
</template>
|
||||
立即生成
|
||||
</n-button>
|
||||
<n-button type="error" @click="batchDelete" :disabled="batchDeleteDisabled" class="min-left-space">
|
||||
<n-button
|
||||
type="error"
|
||||
@click="batchDelete"
|
||||
:disabled="batchDeleteDisabled"
|
||||
class="min-left-space"
|
||||
>
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<DeleteOutlined />
|
||||
@@ -145,14 +150,13 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { h, onBeforeMount, reactive, ref } from 'vue';
|
||||
import { NTag, TreeSelectOption, useDialog, useMessage } from 'naive-ui';
|
||||
import { NTag, useDialog, useMessage } from 'naive-ui';
|
||||
import { BasicTable, TableAction } from '@/components/Table';
|
||||
import { BasicForm, FormSchema, useForm } from '@/components/Form/index';
|
||||
import { List, Delete, Edit, Selects, TableSelect } from '@/api/develop/code';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { PlusOutlined, DeleteOutlined } from '@vicons/antd';
|
||||
import { newState } from '@/views/develop/code/components/model';
|
||||
import { getOptionLabel } from '@/utils/hotgo';
|
||||
|
||||
const selectList = ref({
|
||||
db: [],
|
||||
@@ -347,9 +351,6 @@
|
||||
reloadTable();
|
||||
});
|
||||
},
|
||||
onNegativeClick: () => {
|
||||
// message.error('取消');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -365,9 +366,6 @@
|
||||
reloadTable();
|
||||
});
|
||||
},
|
||||
onNegativeClick: () => {
|
||||
// message.error('取消');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -401,9 +399,7 @@
|
||||
e.preventDefault();
|
||||
formBtnLoading.value = true;
|
||||
formRef.value.validate((errors) => {
|
||||
console.log('formParams:' + JSON.stringify(formParams.value));
|
||||
if (!errors) {
|
||||
console.log('formParams:' + JSON.stringify(formParams.value));
|
||||
Edit(formParams.value).then((res) => {
|
||||
message.success('生成成功,正在前往配置');
|
||||
setTimeout(() => {
|
||||
@@ -427,17 +423,23 @@
|
||||
} else {
|
||||
dialogWidth.value = def + 'px';
|
||||
}
|
||||
|
||||
return dialogWidth.value;
|
||||
}
|
||||
|
||||
onBeforeMount(async () => {
|
||||
await loadSelect();
|
||||
});
|
||||
function getOptionLabel(options, value) {
|
||||
if (!options || options?.length === 0) {
|
||||
return `unknown`;
|
||||
}
|
||||
for (const item of options) {
|
||||
if (item.value == value) {
|
||||
return item.label;
|
||||
}
|
||||
}
|
||||
return `unknown`;
|
||||
}
|
||||
|
||||
const loadSelect = async () => {
|
||||
selectList.value = await Selects({});
|
||||
|
||||
for (const item of schemas.value) {
|
||||
switch (item.field) {
|
||||
case 'status':
|
||||
@@ -452,10 +454,7 @@
|
||||
|
||||
const tablesLoading = ref(false);
|
||||
// 处理选项更新
|
||||
async function handleDbUpdateValue(
|
||||
value: string | number | Array<string | number> | null,
|
||||
_option: TreeSelectOption | null | Array<TreeSelectOption | null>
|
||||
) {
|
||||
async function handleDbUpdateValue(value: string | number | Array<string | number> | null) {
|
||||
tablesLoading.value = true;
|
||||
await loadTableSelect(value);
|
||||
tablesLoading.value = false;
|
||||
@@ -491,6 +490,10 @@
|
||||
formParams.value.genTemplate = value;
|
||||
selectAddon.value = option.isAddon === true;
|
||||
}
|
||||
|
||||
onBeforeMount(async () => {
|
||||
await loadSelect();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
|
||||
@@ -1,8 +1,39 @@
|
||||
import { FormSchema } from '@/components/Form';
|
||||
import { ref } from 'vue';
|
||||
import { defRangeShortcuts } from '@/utils/dateUtil';
|
||||
import { Option } from '@/utils/hotgo';
|
||||
import { Dicts } from '@/api/dict/dict';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
|
||||
const dict = useDictStore();
|
||||
|
||||
export class State {
|
||||
id = 0;
|
||||
reqId = '';
|
||||
appId = '';
|
||||
merchantId = 0;
|
||||
memberId = 0;
|
||||
method = '';
|
||||
module = '';
|
||||
url = '';
|
||||
getData: Record<string, any> | null = null;
|
||||
postData: Record<string, string[]> | null = null;
|
||||
headerData: Record<string, string[]> | null = null;
|
||||
ip = '';
|
||||
provinceId = 0;
|
||||
cityId = 0;
|
||||
errorCode = 0;
|
||||
errorMsg = '';
|
||||
errorData: string[] = [];
|
||||
userAgent = '';
|
||||
takeUpTime = 0;
|
||||
timestamp = 0;
|
||||
status = 0;
|
||||
createdAt = '';
|
||||
updatedAt = '';
|
||||
cityLabel = '';
|
||||
tags = '';
|
||||
summary = '';
|
||||
description = '';
|
||||
}
|
||||
|
||||
export const schemas = ref<FormSchema[]>([
|
||||
{
|
||||
@@ -39,6 +70,17 @@ export const schemas = ref<FormSchema[]>([
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'keyword',
|
||||
component: 'NInput',
|
||||
label: '关键词',
|
||||
componentProps: {
|
||||
placeholder: '请输入关键词',
|
||||
onInput: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'ip',
|
||||
component: 'NInput',
|
||||
@@ -56,7 +98,7 @@ export const schemas = ref<FormSchema[]>([
|
||||
label: '请求方式',
|
||||
componentProps: {
|
||||
placeholder: '请选择请求方式',
|
||||
options: [],
|
||||
options: dict.getOption('HTTPMethod'),
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -81,7 +123,7 @@ export const schemas = ref<FormSchema[]>([
|
||||
label: '请求耗时',
|
||||
componentProps: {
|
||||
placeholder: '请选择请求耗时',
|
||||
options: [],
|
||||
options: dict.getOption('HTTPHandlerTime'),
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -94,7 +136,7 @@ export const schemas = ref<FormSchema[]>([
|
||||
labelMessage: '支持填入自定义状态码',
|
||||
componentProps: {
|
||||
placeholder: '请选择状态码',
|
||||
options: [],
|
||||
options: dict.getOption('HTTPApiCode'),
|
||||
filterable: true,
|
||||
tag: true,
|
||||
onUpdateValue: (e: any) => {
|
||||
@@ -104,31 +146,7 @@ export const schemas = ref<FormSchema[]>([
|
||||
},
|
||||
]);
|
||||
|
||||
// 字典数据选项
|
||||
export const options = ref({
|
||||
HTTPMethod: [] as Option[],
|
||||
HTTPHandlerTime: [] as Option[],
|
||||
HTTPApiCode: [] as Option[],
|
||||
});
|
||||
|
||||
// 加载字典数据选项
|
||||
export function loadOptions() {
|
||||
Dicts({
|
||||
types: ['HTTPMethod', 'HTTPHandlerTime', 'HTTPApiCode'],
|
||||
}).then((res) => {
|
||||
options.value = res;
|
||||
for (const item of schemas.value) {
|
||||
switch (item.field) {
|
||||
case 'method':
|
||||
item.componentProps.options = options.value.HTTPMethod;
|
||||
break;
|
||||
case 'takeUpTime':
|
||||
item.componentProps.options = options.value.HTTPHandlerTime;
|
||||
break;
|
||||
case 'errorCode':
|
||||
item.componentProps.options = options.value.HTTPApiCode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
dict.loadOptions(['HTTPMethod', 'HTTPHandlerTime', 'HTTPApiCode']);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,17 @@
|
||||
:segmented="{ content: true }"
|
||||
:title="data.id ? '日志详情 ID:' + data.id : '日志详情'"
|
||||
>
|
||||
<n-descriptions label-placement="left" class="py-2">
|
||||
<template #header-extra>
|
||||
<n-button icon-placement="right" @click="goBackOrToPage({ name: 'log' })">
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<ArrowRightOutlined />
|
||||
</n-icon>
|
||||
</template>
|
||||
返回
|
||||
</n-button>
|
||||
</template>
|
||||
<n-descriptions label-placement="left" class="py-2" :column="settingStore.isMobile ? 1 : 3">
|
||||
<n-descriptions-item label="请求方式">{{ data.method }}</n-descriptions-item>
|
||||
<n-descriptions-item>
|
||||
<template #label>请求地址</template>
|
||||
@@ -131,18 +141,23 @@
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { View } from '@/api/log/log';
|
||||
import { timestampToTime } from '@/utils/dateUtil';
|
||||
import { ArrowRightOutlined } from '@vicons/antd';
|
||||
import { goBackOrToPage } from '@/utils/urlUtils';
|
||||
import { State } from '@/views/log/log/model';
|
||||
import { useProjectSettingStore } from '@/store/modules/projectSetting';
|
||||
|
||||
const message = useMessage();
|
||||
const router = useRouter();
|
||||
const settingStore = useProjectSettingStore();
|
||||
const params = router.currentRoute.value.params;
|
||||
const loading = ref(false);
|
||||
const data = ref({});
|
||||
const data = ref<State>(new State());
|
||||
|
||||
const getInfo = () => {
|
||||
loading.value = true;
|
||||
View(params)
|
||||
.then((res) => {
|
||||
data.value = res;
|
||||
data.value = res as unknown as State;
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
const checkedIds = ref([]);
|
||||
|
||||
const actionColumn = reactive({
|
||||
width: 180,
|
||||
width: 160,
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
fixed: 'right',
|
||||
|
||||
@@ -1,46 +1,11 @@
|
||||
import { h, ref } from 'vue';
|
||||
import { NTag } from 'naive-ui';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { FormSchema } from '@/components/Form';
|
||||
import { isNullObject } from '@/utils/is';
|
||||
import { defRangeShortcuts } from '@/utils/dateUtil';
|
||||
import { getOptionLabel, getOptionTag, Option } from '@/utils/hotgo';
|
||||
import { Dicts } from '@/api/dict/dict';
|
||||
import { NTag } from 'naive-ui';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import { renderOptionTag } from '@/utils';
|
||||
|
||||
export interface State {
|
||||
id: number;
|
||||
reqId: string;
|
||||
memberId: number;
|
||||
username: string;
|
||||
response: any;
|
||||
loginAt: number;
|
||||
errMsg: string;
|
||||
status: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export const defaultState = {
|
||||
id: 0,
|
||||
reqId: '',
|
||||
memberId: 0,
|
||||
username: '',
|
||||
response: null,
|
||||
loginAt: 0,
|
||||
errMsg: '',
|
||||
status: 1,
|
||||
createdAt: '',
|
||||
updatedAt: '',
|
||||
};
|
||||
|
||||
export function newState(state: State | null): State {
|
||||
if (state !== null) {
|
||||
return cloneDeep(state);
|
||||
}
|
||||
return cloneDeep(defaultState);
|
||||
}
|
||||
|
||||
export const rules = {};
|
||||
const dict = useDictStore();
|
||||
|
||||
export const schemas = ref<FormSchema[]>([
|
||||
{
|
||||
@@ -72,7 +37,7 @@ export const schemas = ref<FormSchema[]>([
|
||||
defaultValue: null,
|
||||
componentProps: {
|
||||
placeholder: '请选择状态',
|
||||
options: [],
|
||||
options: dict.getOption('sys_login_status'),
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -143,22 +108,7 @@ export const columns = [
|
||||
title: '状态',
|
||||
key: 'status',
|
||||
render(row) {
|
||||
if (isNullObject(row.status)) {
|
||||
return ``;
|
||||
}
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(options.value.sys_login_status, row.status),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(options.value.sys_login_status, row.status),
|
||||
}
|
||||
);
|
||||
return renderOptionTag('sys_login_status', row.status);
|
||||
},
|
||||
width: 150,
|
||||
},
|
||||
@@ -184,23 +134,7 @@ export const columns = [
|
||||
},
|
||||
];
|
||||
|
||||
// 字典数据选项
|
||||
export const options = ref({
|
||||
sys_login_status: [] as Option[],
|
||||
});
|
||||
|
||||
// 加载字典数据选项
|
||||
export function loadOptions() {
|
||||
Dicts({
|
||||
types: ['sys_login_status'],
|
||||
}).then((res) => {
|
||||
options.value = res;
|
||||
for (const item of schemas.value) {
|
||||
switch (item.field) {
|
||||
case 'status':
|
||||
item.componentProps.options = options.value.sys_login_status;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
dict.loadOptions(['sys_login_status']);
|
||||
}
|
||||
|
||||
@@ -44,19 +44,18 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, h, reactive, ref } from 'vue';
|
||||
import { NTag, useDialog, useMessage } from 'naive-ui';
|
||||
import { computed, h, onMounted, reactive, ref } from 'vue';
|
||||
import { useDialog, useMessage } from 'naive-ui';
|
||||
import { BasicTable, TableAction } from '@/components/Table';
|
||||
import { BasicForm, FormSchema, useForm } from '@/components/Form/index';
|
||||
import { getLogList, Delete } from '@/api/log/smslog';
|
||||
import { DeleteOutlined } from '@vicons/antd';
|
||||
import { Dicts } from '@/api/dict/dict';
|
||||
import { adaTableScrollX, getOptionLabel, getOptionTag, Options } from '@/utils/hotgo';
|
||||
import { adaTableScrollX } from '@/utils/hotgo';
|
||||
import { defRangeShortcuts } from '@/utils/dateUtil';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import { renderOptionTag } from '@/utils';
|
||||
|
||||
const options = ref<Options>({
|
||||
config_sms_template: [],
|
||||
});
|
||||
const dict = useDictStore();
|
||||
|
||||
const columns = [
|
||||
{
|
||||
@@ -68,19 +67,7 @@
|
||||
title: '事件模板',
|
||||
key: 'event',
|
||||
render(row) {
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(options.value.config_sms_template, row.event),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(options.value.config_sms_template, row.event),
|
||||
}
|
||||
);
|
||||
return renderOptionTag('config_sms_template', row.event);
|
||||
},
|
||||
width: 150,
|
||||
},
|
||||
@@ -111,19 +98,7 @@
|
||||
title: '状态',
|
||||
key: 'status',
|
||||
render(row) {
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: row.status == 2 ? 'success' : 'warning',
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => (row.status == 2 ? '已使用' : '未使用'),
|
||||
}
|
||||
);
|
||||
return renderOptionTag('CodeStatusOptions', row.status);
|
||||
},
|
||||
width: 100,
|
||||
},
|
||||
@@ -153,7 +128,7 @@
|
||||
label: '事件模板',
|
||||
componentProps: {
|
||||
placeholder: '请选择事件模板',
|
||||
options: [],
|
||||
options: dict.getOption('config_sms_template'),
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -188,16 +163,7 @@
|
||||
label: '状态',
|
||||
componentProps: {
|
||||
placeholder: '请选择状态',
|
||||
options: [
|
||||
{
|
||||
label: '未使用',
|
||||
value: '1',
|
||||
},
|
||||
{
|
||||
label: '已使用',
|
||||
value: '2',
|
||||
},
|
||||
],
|
||||
options: dict.getOption('CodeStatusOptions'),
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -264,9 +230,6 @@
|
||||
reloadTable();
|
||||
});
|
||||
},
|
||||
onNegativeClick: () => {
|
||||
// message.error('不确定');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -282,14 +245,10 @@
|
||||
reloadTable();
|
||||
});
|
||||
},
|
||||
onNegativeClick: () => {
|
||||
// message.error('不确定');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const loadDataTable = async (res) => {
|
||||
await loadOptions();
|
||||
return await getLogList({ ...searchFormRef.value?.formModel, ...res });
|
||||
};
|
||||
|
||||
@@ -307,18 +266,13 @@
|
||||
reloadTable();
|
||||
}
|
||||
|
||||
async function loadOptions() {
|
||||
options.value = await Dicts({
|
||||
types: ['config_sms_template'],
|
||||
});
|
||||
for (const item of schemas.value) {
|
||||
switch (item.field) {
|
||||
case 'event':
|
||||
item.componentProps.options = options.value.config_sms_template;
|
||||
break;
|
||||
}
|
||||
}
|
||||
function loadOptions() {
|
||||
dict.loadOptions(['config_sms_template', 'CodeStatusOptions']);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadOptions();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import { h } from 'vue';
|
||||
import { NButton, NTag } from 'naive-ui';
|
||||
import { timestampToTime, formatBefore } from '@/utils/dateUtil';
|
||||
import { getOptionLabel } from '@/utils/hotgo';
|
||||
import { options } from '@/views/monitor/netconn/modal/model';
|
||||
import { renderIcon, renderTooltip } from '@/utils';
|
||||
import { renderIcon, renderOptionTag, renderTooltip } from '@/utils';
|
||||
import { HelpCircleOutline } from '@vicons/ionicons5';
|
||||
|
||||
export const columns = [
|
||||
@@ -95,19 +93,7 @@ export const columns = [
|
||||
key: 'group',
|
||||
width: 100,
|
||||
render(row) {
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: 'info',
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(options.value.group, row.group),
|
||||
}
|
||||
);
|
||||
return renderOptionTag('ServerLicenseGroupOptions', row.group);
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -38,8 +38,8 @@
|
||||
<GroupModal ref="GroupModalRef" />
|
||||
|
||||
<Edit
|
||||
@reloadTable="reloadTable"
|
||||
@updateShowModal="updateShowModal"
|
||||
@reload-table="reloadTable"
|
||||
@update-show-modal="updateShowModal"
|
||||
:showModal="showModal"
|
||||
:formParams="formEditParams"
|
||||
/>
|
||||
@@ -47,7 +47,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, h, reactive, ref } from 'vue';
|
||||
import { computed, h, onMounted, reactive, ref } from 'vue';
|
||||
import { useDialog, useMessage } from 'naive-ui';
|
||||
import { BasicTable, TableAction } from '@/components/Table';
|
||||
import { BasicForm, FormSchema, useForm } from '@/components/Form/index';
|
||||
@@ -56,12 +56,14 @@
|
||||
import { TrademarkOutlined } from '@vicons/antd';
|
||||
import GroupModal from './modal/modal.vue';
|
||||
import Edit from '@/views/monitor/netconn/modal/edit.vue';
|
||||
import { newState, options, State } from '@/views/monitor/netconn/modal/model';
|
||||
import { loadOptions, newState, State } from '@/views/monitor/netconn/modal/model';
|
||||
import { defRangeShortcuts } from '@/utils/dateUtil';
|
||||
import { adaTableScrollX } from '@/utils/hotgo';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
|
||||
const message = useMessage();
|
||||
const dialog = useDialog();
|
||||
const dict = useDictStore();
|
||||
const showModal = ref(false);
|
||||
const formEditParams = ref<State>(newState(null));
|
||||
const actionRef = ref();
|
||||
@@ -115,7 +117,7 @@
|
||||
defaultValue: null,
|
||||
componentProps: {
|
||||
placeholder: '请选择授权分组',
|
||||
options: options.value.group,
|
||||
options: dict.getOption('ServerLicenseGroupOptions'),
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -213,6 +215,10 @@
|
||||
function updateShowModal(value) {
|
||||
showModal.value = value;
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
loadOptions();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
|
||||
@@ -24,7 +24,10 @@
|
||||
<n-grid x-gap="24" :cols="2">
|
||||
<n-gi>
|
||||
<n-form-item label="分组" path="group">
|
||||
<n-select v-model:value="params.group" :options="options.group" />
|
||||
<n-select
|
||||
v-model:value="params.group"
|
||||
:options="dict.getOptionUnRef('ServerLicenseGroupOptions')"
|
||||
/>
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
@@ -78,7 +81,10 @@
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item label="授权状态" path="status">
|
||||
<n-select v-model:value="params.status" :options="options.sys_normal_disable" />
|
||||
<n-select
|
||||
v-model:value="params.status"
|
||||
:options="dict.getOptionUnRef('sys_normal_disable')"
|
||||
/>
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item label="备注" path="remark">
|
||||
@@ -100,9 +106,10 @@
|
||||
import { ref, computed, watch } from 'vue';
|
||||
import { Edit, View } from '@/api/serveLicense';
|
||||
import DatePicker from '@/components/DatePicker/datePicker.vue';
|
||||
import { rules, options, State, newState } from './model';
|
||||
import { rules, State, newState } from './model';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { adaModalWidth } from '@/utils/hotgo';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
|
||||
const emit = defineEmits(['reloadTable', 'updateShowModal']);
|
||||
|
||||
@@ -129,6 +136,7 @@
|
||||
|
||||
const loading = ref(false);
|
||||
const params = ref<State>(props.formParams);
|
||||
const dict = useDictStore();
|
||||
const message = useMessage();
|
||||
const formRef = ref<any>({});
|
||||
const formBtnLoading = ref(false);
|
||||
|
||||
@@ -70,8 +70,8 @@
|
||||
</BasicTable>
|
||||
</n-card>
|
||||
<Edit
|
||||
@reloadTable="reloadTable"
|
||||
@updateShowModal="updateShowModal"
|
||||
@reload-table="reloadTable"
|
||||
@update-show-modal="updateShowModal"
|
||||
:showModal="showModal"
|
||||
:formParams="formParams"
|
||||
/>
|
||||
@@ -99,7 +99,7 @@
|
||||
ref="transfer"
|
||||
v-model:value="formParams.routes"
|
||||
virtual-scroll
|
||||
:options="options.routes"
|
||||
:options="routesOptions"
|
||||
source-filterable
|
||||
:render-source-label="renderLabel"
|
||||
:render-target-label="renderLabel"
|
||||
@@ -117,17 +117,20 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, h, reactive, ref } from 'vue';
|
||||
import { computed, h, onMounted, reactive, ref } from 'vue';
|
||||
import { useDialog, useMessage, NTag } from 'naive-ui';
|
||||
import { BasicTable, TableAction } from '@/components/Table';
|
||||
import { BasicForm, useForm } from '@/components/Form/index';
|
||||
import { usePermission } from '@/hooks/web/usePermission';
|
||||
import { Delete, Export, List, Status, AssignRouter } from '@/api/serveLicense';
|
||||
import { columns, newState, options, schemas, State } from './model';
|
||||
import { columns, newState, loadOptions, schemas, State } from './model';
|
||||
import { DeleteOutlined, ExportOutlined, PlusOutlined } from '@vicons/antd';
|
||||
import { adaModalWidth, adaTableScrollX, getOptionLabel } from '@/utils/hotgo';
|
||||
import { adaModalWidth, adaTableScrollX } from '@/utils/hotgo';
|
||||
import Edit from './edit.vue';
|
||||
import { NetOption } from '@/api/monitor/monitor';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
|
||||
const dict = useDictStore();
|
||||
const { hasPermission } = usePermission();
|
||||
const actionRef = ref();
|
||||
const dialog = useDialog();
|
||||
@@ -136,10 +139,11 @@
|
||||
const batchDeleteDisabled = ref(true);
|
||||
const checkedIds = ref([]);
|
||||
const showModal = ref(false);
|
||||
const formParams = ref<State>();
|
||||
const formParams = ref<State>(newState(null));
|
||||
const showRoutesModal = ref(false);
|
||||
const formBtnLoading = ref(false);
|
||||
const formRef = ref<any>({});
|
||||
const routesOptions = ref([]);
|
||||
const dialogWidth = computed(() => {
|
||||
return adaModalWidth();
|
||||
});
|
||||
@@ -265,7 +269,7 @@
|
||||
|
||||
function handleStatus(record: Recordable, status: number) {
|
||||
Status({ id: record.id, status: status }).then((_res) => {
|
||||
message.success('设为' + getOptionLabel(options.value.sys_normal_disable, status) + '成功');
|
||||
message.success('设为' + dict.getLabel('sys_normal_disable', status) + '成功');
|
||||
setTimeout(() => {
|
||||
reloadTable();
|
||||
});
|
||||
@@ -276,7 +280,6 @@
|
||||
e.preventDefault();
|
||||
formBtnLoading.value = true;
|
||||
formRef.value.validate((errors) => {
|
||||
console.log('formParams.value:' + JSON.stringify(formParams.value));
|
||||
if (!errors) {
|
||||
AssignRouter(formParams.value).then((_res) => {
|
||||
message.success('操作成功');
|
||||
@@ -340,6 +343,17 @@
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function loadRoutesOptions() {
|
||||
NetOption().then((res) => {
|
||||
routesOptions.value = res.routes;
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
loadOptions();
|
||||
loadRoutesOptions();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import { h, ref } from 'vue';
|
||||
import { NTag } from 'naive-ui';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { FormSchema } from '@/components/Form';
|
||||
import { Dicts } from '@/api/dict/dict';
|
||||
import { isNullObject } from '@/utils/is';
|
||||
import { defRangeShortcuts, formatBefore } from '@/utils/dateUtil';
|
||||
import { getOptionLabel, getOptionTag, Options } from '@/utils/hotgo';
|
||||
import { NetOption } from '@/api/monitor/monitor';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import { renderOptionTag } from '@/utils';
|
||||
|
||||
const dict = useDictStore();
|
||||
|
||||
export interface State {
|
||||
id: number;
|
||||
@@ -55,12 +54,6 @@ export function newState(state: State | null): State {
|
||||
return cloneDeep(defaultState);
|
||||
}
|
||||
|
||||
export const options = ref<Options>({
|
||||
sys_normal_disable: [],
|
||||
group: [],
|
||||
routes: [],
|
||||
});
|
||||
|
||||
export const rules = {
|
||||
group: {
|
||||
required: true,
|
||||
@@ -107,7 +100,7 @@ export const schemas = ref<FormSchema[]>([
|
||||
defaultValue: null,
|
||||
componentProps: {
|
||||
placeholder: '请选择授权分组',
|
||||
options: options.value.group,
|
||||
options: dict.getOption('ServerLicenseGroupOptions'),
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -142,7 +135,7 @@ export const schemas = ref<FormSchema[]>([
|
||||
defaultValue: null,
|
||||
componentProps: {
|
||||
placeholder: '请选择状态',
|
||||
options: [],
|
||||
options: dict.getOption('sys_normal_disable'),
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -187,19 +180,7 @@ export const columns = [
|
||||
key: 'group',
|
||||
width: 100,
|
||||
render(row) {
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: 'info',
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(options.value.group, row.group),
|
||||
}
|
||||
);
|
||||
return renderOptionTag('ServerLicenseGroupOptions', row.group);
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -235,22 +216,7 @@ export const columns = [
|
||||
key: 'status',
|
||||
width: 100,
|
||||
render(row) {
|
||||
if (isNullObject(row.status)) {
|
||||
return ``;
|
||||
}
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(options.value.sys_normal_disable, row.status),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(options.value.sys_normal_disable, row.status),
|
||||
}
|
||||
);
|
||||
return renderOptionTag('sys_normal_disable', row.status);
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -283,25 +249,6 @@ export const columns = [
|
||||
},
|
||||
];
|
||||
|
||||
async function loadOptions() {
|
||||
options.value = await Dicts({
|
||||
types: ['sys_normal_disable'],
|
||||
});
|
||||
|
||||
const netOption = await NetOption();
|
||||
options.value.group = netOption.licenseGroup;
|
||||
options.value.routes = netOption.routes;
|
||||
|
||||
for (const item of schemas.value) {
|
||||
switch (item.field) {
|
||||
case 'status':
|
||||
item.componentProps.options = options.value.sys_normal_disable;
|
||||
break;
|
||||
case 'group':
|
||||
item.componentProps.options = options.value.group;
|
||||
break;
|
||||
}
|
||||
}
|
||||
export function loadOptions() {
|
||||
dict.loadOptions(['sys_normal_disable', 'ServerLicenseGroupOptions']);
|
||||
}
|
||||
|
||||
await loadOptions();
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, h, reactive, ref } from 'vue';
|
||||
import { computed, h, onMounted, reactive, ref } from 'vue';
|
||||
import { useDialog, useMessage } from 'naive-ui';
|
||||
import { BasicTable, TableAction } from '@/components/Table';
|
||||
import { BasicForm, useForm } from '@/components/Form/index';
|
||||
@@ -112,6 +112,7 @@
|
||||
import { JsonViewer } from 'vue3-json-viewer';
|
||||
import 'vue3-json-viewer/dist/index.css';
|
||||
import { adaTableScrollX } from '@/utils/hotgo';
|
||||
import { loadOptions } from './model';
|
||||
|
||||
const { hasPermission } = usePermission();
|
||||
const router = useRouter();
|
||||
@@ -198,9 +199,6 @@
|
||||
reloadTable();
|
||||
});
|
||||
},
|
||||
onNegativeClick: () => {
|
||||
// message.error('取消');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -218,9 +216,6 @@
|
||||
reloadTable();
|
||||
});
|
||||
},
|
||||
onNegativeClick: () => {
|
||||
// message.error('取消');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -228,6 +223,10 @@
|
||||
message.loading('正在导出列表...', { duration: 1200 });
|
||||
Export(searchFormRef.value?.formModel);
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
loadOptions();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
|
||||
@@ -1,57 +1,13 @@
|
||||
import { h, ref } from 'vue';
|
||||
import { NTag, NButton } from 'naive-ui';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { FormSchema } from '@/components/Form';
|
||||
import { Dicts } from '@/api/dict/dict';
|
||||
|
||||
import { isNullObject } from '@/utils/is';
|
||||
import { defRangeShortcuts } from '@/utils/dateUtil';
|
||||
import { format } from 'date-fns';
|
||||
import { getOptionLabel, getOptionTag, Options } from '@/utils/hotgo';
|
||||
import { renderIcon, renderTooltip } from '@/utils';
|
||||
import { renderIcon, renderOptionTag, renderTooltip } from '@/utils';
|
||||
import { HelpCircleOutline } from '@vicons/ionicons5';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
|
||||
export interface State {
|
||||
id: number;
|
||||
env: string;
|
||||
traceid: string;
|
||||
levelFormat: string;
|
||||
content: string;
|
||||
stack: any;
|
||||
line: string;
|
||||
triggerNs: number;
|
||||
status: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export const defaultState = {
|
||||
id: 0,
|
||||
env: '',
|
||||
traceid: '',
|
||||
levelFormat: '',
|
||||
content: '',
|
||||
stack: null,
|
||||
line: '',
|
||||
triggerNs: 0,
|
||||
status: 1,
|
||||
createdAt: '',
|
||||
updatedAt: '',
|
||||
};
|
||||
|
||||
export function newState(state: State | null): State {
|
||||
if (state !== null) {
|
||||
return cloneDeep(state);
|
||||
}
|
||||
return cloneDeep(defaultState);
|
||||
}
|
||||
|
||||
export const options = ref<Options>({
|
||||
sys_normal_disable: [],
|
||||
sys_log_type: [],
|
||||
});
|
||||
|
||||
export const rules = {};
|
||||
const dict = useDictStore();
|
||||
|
||||
export const schemas = ref<FormSchema[]>([
|
||||
{
|
||||
@@ -65,6 +21,17 @@ export const schemas = ref<FormSchema[]>([
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'content',
|
||||
component: 'NInput',
|
||||
label: '日志内容',
|
||||
componentProps: {
|
||||
placeholder: '请输入日志内容关键词',
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'levelFormat',
|
||||
component: 'NSelect',
|
||||
@@ -72,7 +39,7 @@ export const schemas = ref<FormSchema[]>([
|
||||
defaultValue: null,
|
||||
componentProps: {
|
||||
placeholder: '请选择日志级别',
|
||||
options: [],
|
||||
options: dict.getOption('sys_log_type'),
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -138,22 +105,7 @@ export const columns = [
|
||||
title: '日志级别',
|
||||
key: 'levelFormat',
|
||||
render(row) {
|
||||
if (isNullObject(row.levelFormat)) {
|
||||
return ``;
|
||||
}
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(options.value.sys_log_type, row.levelFormat),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(options.value.sys_log_type, row.levelFormat),
|
||||
}
|
||||
);
|
||||
return renderOptionTag('sys_log_type', row.levelFormat);
|
||||
},
|
||||
width: 120,
|
||||
},
|
||||
@@ -162,11 +114,6 @@ export const columns = [
|
||||
key: 'content',
|
||||
width: 320,
|
||||
},
|
||||
// {
|
||||
// title: '调用行',
|
||||
// key: 'line',
|
||||
// width: 150,
|
||||
// },
|
||||
{
|
||||
title: '触发时间',
|
||||
key: 'triggerNs',
|
||||
@@ -185,20 +132,6 @@ export const columns = [
|
||||
},
|
||||
];
|
||||
|
||||
async function loadOptions() {
|
||||
options.value = await Dicts({
|
||||
types: ['sys_normal_disable', 'sys_log_type'],
|
||||
});
|
||||
for (const item of schemas.value) {
|
||||
switch (item.field) {
|
||||
case 'status':
|
||||
item.componentProps.options = options.value.sys_normal_disable;
|
||||
break;
|
||||
case 'levelFormat':
|
||||
item.componentProps.options = options.value.sys_log_type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
export function loadOptions() {
|
||||
dict.loadOptions(['sys_normal_disable', 'sys_log_type']);
|
||||
}
|
||||
|
||||
await loadOptions();
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
</n-gi>
|
||||
<n-gi span="2">
|
||||
<n-form-item label="测试分类" path="categoryId">
|
||||
<n-select v-model:value="formValue.categoryId" :options="options.testCategoryOption" />
|
||||
<n-select v-model:value="formValue.categoryId" :options="dict.getOptionUnRef('testCategoryOption')" />
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
<n-gi span="2">
|
||||
@@ -58,7 +58,7 @@
|
||||
</n-gi>
|
||||
<n-gi span="1">
|
||||
<n-form-item label="状态" path="status">
|
||||
<n-select v-model:value="formValue.status" :options="options.sys_normal_disable" />
|
||||
<n-select v-model:value="formValue.status" :options="dict.getOptionUnRef('sys_normal_disable')" />
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
@@ -81,8 +81,9 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import { Edit, View, MaxSort } from '@/api/normalTreeDemo';
|
||||
import { options, State, newState, treeOption, loadTreeOption, rules } from './model';
|
||||
import { State, newState, treeOption, loadTreeOption, rules } from './model';
|
||||
import { useProjectSettingStore } from '@/store/modules/projectSetting';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { adaModalWidth } from '@/utils/hotgo';
|
||||
@@ -90,6 +91,7 @@
|
||||
const emit = defineEmits(['reloadTable']);
|
||||
const message = useMessage();
|
||||
const settingStore = useProjectSettingStore();
|
||||
const dict = useDictStore();
|
||||
const loading = ref(false);
|
||||
const showModal = ref(false);
|
||||
const formValue = ref<State>(newState(null));
|
||||
@@ -131,25 +133,28 @@
|
||||
});
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
function confirmForm(e) {
|
||||
e.preventDefault();
|
||||
formBtnLoading.value = true;
|
||||
formRef.value.validate((errors) => {
|
||||
if (!errors) {
|
||||
Edit(formValue.value).then((_res) => {
|
||||
message.success('操作成功');
|
||||
setTimeout(() => {
|
||||
formBtnLoading.value = true;
|
||||
Edit(formValue.value)
|
||||
.then((_res) => {
|
||||
message.success('操作成功');
|
||||
closeForm();
|
||||
emit('reloadTable');
|
||||
})
|
||||
.finally(() => {
|
||||
formBtnLoading.value = false;
|
||||
});
|
||||
});
|
||||
} else {
|
||||
message.error('请填写完整信息');
|
||||
}
|
||||
formBtnLoading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
// 关闭表单
|
||||
function closeForm() {
|
||||
showModal.value = false;
|
||||
loading.value = false;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<n-input v-model:value="model[field]" />
|
||||
</template>
|
||||
</BasicForm>
|
||||
<BasicTable ref="actionRef" openChecked :columns="columns" :request="loadDataTable" :row-key="(row) => row.id" :actionColumn="actionColumn" :scroll-x="1280" :resizeHeightOffset="-10000" :cascade="false" :expanded-row-keys="expandedKeys" @update:expanded-row-keys="updateExpandedKeys" :checked-row-keys="checkedIds" @update:checked-row-keys="handleOnCheckedRow">
|
||||
<BasicTable ref="actionRef" openChecked :columns="columns" :request="loadDataTable" :row-key="(row) => row.id" :actionColumn="actionColumn" :scroll-x="scrollX" :resizeHeightOffset="-10000" :cascade="false" :expanded-row-keys="expandedKeys" @update:expanded-row-keys="updateExpandedKeys" :checked-row-keys="checkedIds" @update:checked-row-keys="handleOnCheckedRow">
|
||||
<template #tableTitle>
|
||||
<n-button type="primary" @click="addTable" class="min-left-space" v-if="hasPermission(['/normalTreeDemo/edit'])">
|
||||
<template #icon>
|
||||
@@ -47,15 +47,16 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { h, reactive, ref, onMounted } from 'vue';
|
||||
import { h, reactive, ref, computed, onMounted } from 'vue';
|
||||
import { useDialog, useMessage } from 'naive-ui';
|
||||
import { BasicTable, TableAction } from '@/components/Table';
|
||||
import { BasicForm, useForm } from '@/components/Form/index';
|
||||
import { usePermission } from '@/hooks/web/usePermission';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import { List, Delete } from '@/api/normalTreeDemo';
|
||||
import { PlusOutlined, DeleteOutlined, AlignLeftOutlined } from '@vicons/antd';
|
||||
import { columns, schemas, loadOptions, newState } from './model';
|
||||
import { convertListToTree } from '@/utils/hotgo';
|
||||
import { adaTableScrollX, convertListToTree } from '@/utils/hotgo';
|
||||
import Edit from './edit.vue';
|
||||
|
||||
const dialog = useDialog();
|
||||
@@ -63,8 +64,9 @@
|
||||
const { hasPermission } = usePermission();
|
||||
const actionRef = ref();
|
||||
const searchFormRef = ref<any>({});
|
||||
const viewRef = ref();
|
||||
const editRef = ref();
|
||||
const dict = useDictStore();
|
||||
|
||||
const checkedIds = ref([]);
|
||||
const expandedKeys = ref([]);
|
||||
const allTreeKeys = ref([]);
|
||||
@@ -100,6 +102,10 @@
|
||||
},
|
||||
});
|
||||
|
||||
const scrollX = computed(() => {
|
||||
return adaTableScrollX(columns, actionColumn.width);
|
||||
});
|
||||
|
||||
const [register, {}] = useForm({
|
||||
gridProps: { cols: '1 s:1 m:2 l:3 xl:4 2xl:4' },
|
||||
labelWidth: 80,
|
||||
@@ -196,6 +202,7 @@
|
||||
|
||||
onMounted(() => {
|
||||
loadOptions();
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -2,12 +2,13 @@ import { h, ref } from 'vue';
|
||||
import { NTag } from 'naive-ui';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { FormSchema } from '@/components/Form';
|
||||
import { Dicts } from '@/api/dict/dict';
|
||||
import { isNullObject } from '@/utils/is';
|
||||
import { defRangeShortcuts } from '@/utils/dateUtil';
|
||||
import { Option, getOptionLabel, getOptionTag } from '@/utils/hotgo';
|
||||
import { renderPopoverMemberSumma, MemberSumma } from '@/utils';
|
||||
import { TreeOption } from '@/api/normalTreeDemo';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
|
||||
const dict = useDictStore();
|
||||
|
||||
export class State {
|
||||
public title = ''; // 标题
|
||||
@@ -73,7 +74,7 @@ export const schemas = ref<FormSchema[]>([
|
||||
defaultValue: null,
|
||||
componentProps: {
|
||||
placeholder: '请选择测试分类',
|
||||
options: [],
|
||||
options: dict.getOption('testCategoryOption'),
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -86,7 +87,7 @@ export const schemas = ref<FormSchema[]>([
|
||||
defaultValue: null,
|
||||
componentProps: {
|
||||
placeholder: '请选择状态',
|
||||
options: [],
|
||||
options: dict.getOption('sys_normal_disable'),
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -130,11 +131,11 @@ export const columns = [
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(options.value.testCategoryOption, row.categoryId),
|
||||
type: dict.getType('testCategoryOption', row.categoryId),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(options.value.testCategoryOption, row.categoryId),
|
||||
default: () => dict.getLabel('testCategoryOption', row.categoryId),
|
||||
}
|
||||
);
|
||||
},
|
||||
@@ -160,11 +161,11 @@ export const columns = [
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(options.value.sys_normal_disable, row.status),
|
||||
type: dict.getType('sys_normal_disable', row.status),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(options.value.sys_normal_disable, row.status),
|
||||
default: () => dict.getLabel('sys_normal_disable', row.status),
|
||||
}
|
||||
);
|
||||
},
|
||||
@@ -186,29 +187,9 @@ export const columns = [
|
||||
},
|
||||
];
|
||||
|
||||
// 字典数据选项
|
||||
export const options = ref({
|
||||
sys_normal_disable: [] as Option[],
|
||||
testCategoryOption: [] as Option[],
|
||||
});
|
||||
|
||||
// 加载字典数据选项
|
||||
export function loadOptions() {
|
||||
Dicts({
|
||||
types: ['sys_normal_disable', 'testCategoryOption'],
|
||||
}).then((res) => {
|
||||
options.value = res;
|
||||
for (const item of schemas.value) {
|
||||
switch (item.field) {
|
||||
case 'status':
|
||||
item.componentProps.options = options.value.sys_normal_disable;
|
||||
break;
|
||||
case 'categoryId':
|
||||
item.componentProps.options = options.value.testCategoryOption;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
dict.loadOptions(['sys_normal_disable', 'testCategoryOption']);
|
||||
}
|
||||
|
||||
// 关系树选项
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<n-drawer v-model:show="showModal" :width="dialogWidth">
|
||||
<n-drawer-content title="普通树表详情" closable>
|
||||
<n-spin :show="loading" description="请稍候...">
|
||||
<n-descriptions label-placement="left" class="py-2" column="1">
|
||||
<n-descriptions-item>
|
||||
<template #label>
|
||||
标题
|
||||
</template>
|
||||
{{ formValue.title }}
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item>
|
||||
<template #label>
|
||||
上级
|
||||
</template>
|
||||
{{ formValue.pid }}
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item label="测试分类">
|
||||
<n-tag :type="getOptionTag(options.testCategoryOption, formValue?.categoryId)" size="small" class="min-left-space">
|
||||
{{ getOptionLabel(options.testCategoryOption, formValue?.categoryId) }}
|
||||
</n-tag>
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item>
|
||||
<template #label>
|
||||
描述
|
||||
</template>
|
||||
{{ formValue.description }}
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item>
|
||||
<template #label>
|
||||
排序
|
||||
</template>
|
||||
{{ formValue.sort }}
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item label="状态">
|
||||
<n-tag :type="getOptionTag(options.sys_normal_disable, formValue?.status)" size="small" class="min-left-space">
|
||||
{{ getOptionLabel(options.sys_normal_disable, formValue?.status) }}
|
||||
</n-tag>
|
||||
</n-descriptions-item>
|
||||
</n-descriptions>
|
||||
</n-spin>
|
||||
</n-drawer-content>
|
||||
</n-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref } from 'vue';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { View } from '@/api/normalTreeDemo';
|
||||
import { State, newState, options } from './model';
|
||||
import { adaModalWidth, getOptionLabel, getOptionTag } from '@/utils/hotgo';
|
||||
import { getFileExt } from '@/utils/urlUtils';
|
||||
|
||||
const message = useMessage();
|
||||
const loading = ref(false);
|
||||
const showModal = ref(false);
|
||||
const formValue = ref(newState(null));
|
||||
const dialogWidth = computed(() => {
|
||||
return adaModalWidth(580);
|
||||
});
|
||||
const fileAvatarCSS = computed(() => {
|
||||
return {
|
||||
'--n-merged-size': `var(--n-avatar-size-override, 80px)`,
|
||||
'--n-font-size': `18px`,
|
||||
};
|
||||
});
|
||||
|
||||
//下载
|
||||
function download(url: string) {
|
||||
window.open(url);
|
||||
}
|
||||
|
||||
function openModal(state: State) {
|
||||
showModal.value = true;
|
||||
loading.value = true;
|
||||
View({ id: state.id })
|
||||
.then((res) => {
|
||||
formValue.value = res;
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
openModal,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
@@ -43,12 +43,12 @@
|
||||
</n-gi>
|
||||
<n-gi span="2">
|
||||
<n-form-item label="测试分类" path="categoryId">
|
||||
<n-select v-model:value="formValue.categoryId" :options="options.testCategoryOption" />
|
||||
<n-select v-model:value="formValue.categoryId" :options="dict.getOptionUnRef('testCategoryOption')" />
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
<n-gi span="2">
|
||||
<n-form-item label="描述" path="description">
|
||||
<n-input type="textarea" placeholder="描述" v-model:value="formValue.description" />
|
||||
<n-input placeholder="请输入描述" v-model:value="formValue.description" />
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
<n-gi span="1">
|
||||
@@ -58,7 +58,7 @@
|
||||
</n-gi>
|
||||
<n-gi span="1">
|
||||
<n-form-item label="状态" path="status">
|
||||
<n-select v-model:value="formValue.status" :options="options.sys_normal_disable" />
|
||||
<n-select v-model:value="formValue.status" :options="dict.getOptionUnRef('sys_normal_disable')" />
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
@@ -81,8 +81,9 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import { Edit, View, MaxSort } from '@/api/optionTreeDemo';
|
||||
import { options, State, newState, treeOption, loadTreeOption, rules } from './model';
|
||||
import { State, newState, treeOption, loadTreeOption, rules } from './model';
|
||||
import { useProjectSettingStore } from '@/store/modules/projectSetting';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { adaModalWidth } from '@/utils/hotgo';
|
||||
@@ -90,6 +91,7 @@
|
||||
const emit = defineEmits(['reloadTable']);
|
||||
const message = useMessage();
|
||||
const settingStore = useProjectSettingStore();
|
||||
const dict = useDictStore();
|
||||
const loading = ref(false);
|
||||
const showModal = ref(false);
|
||||
const formValue = ref<State>(newState(null));
|
||||
@@ -99,6 +101,34 @@
|
||||
return adaModalWidth(840);
|
||||
});
|
||||
|
||||
// 提交表单
|
||||
function confirmForm(e) {
|
||||
e.preventDefault();
|
||||
formRef.value.validate((errors) => {
|
||||
if (!errors) {
|
||||
formBtnLoading.value = true;
|
||||
Edit(formValue.value)
|
||||
.then((_res) => {
|
||||
message.success('操作成功');
|
||||
closeForm();
|
||||
emit('reloadTable');
|
||||
})
|
||||
.finally(() => {
|
||||
formBtnLoading.value = false;
|
||||
});
|
||||
} else {
|
||||
message.error('请填写完整信息');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 关闭表单
|
||||
function closeForm() {
|
||||
showModal.value = false;
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
// 打开模态框
|
||||
function openModal(state: State) {
|
||||
showModal.value = true;
|
||||
|
||||
@@ -131,30 +161,6 @@
|
||||
});
|
||||
}
|
||||
|
||||
function confirmForm(e) {
|
||||
e.preventDefault();
|
||||
formBtnLoading.value = true;
|
||||
formRef.value.validate((errors) => {
|
||||
if (!errors) {
|
||||
Edit(formValue.value).then((_res) => {
|
||||
message.success('操作成功');
|
||||
setTimeout(() => {
|
||||
closeForm();
|
||||
emit('reloadTable');
|
||||
});
|
||||
});
|
||||
} else {
|
||||
message.error('请填写完整信息');
|
||||
}
|
||||
formBtnLoading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
function closeForm() {
|
||||
showModal.value = false;
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
openModal,
|
||||
});
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
</template>
|
||||
编辑
|
||||
</n-button>
|
||||
<n-button v-if="hasPermission(['/optionTreeDemo/delete'])" type="error" icon-placement="left" @click="handleEdit(selectedState)" :disabled="selectedState.id < 1">
|
||||
<n-button v-if="hasPermission(['/optionTreeDemo/delete'])" type="error" icon-placement="left" @click="handleDelete(selectedState)" :disabled="selectedState.id < 1">
|
||||
<template #icon>
|
||||
<div class="flex items-center">
|
||||
<n-icon size="14">
|
||||
@@ -135,12 +135,14 @@
|
||||
import { BasicTable, TableAction } from '@/components/Table';
|
||||
import { BasicForm, useForm } from '@/components/Form/index';
|
||||
import { usePermission } from '@/hooks/web/usePermission';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import { List, Delete, TreeOption } from '@/api/optionTreeDemo';
|
||||
import { PlusOutlined, EditOutlined, DeleteOutlined, AlignLeftOutlined, FormOutlined, SearchOutlined } from '@vicons/antd';
|
||||
import { columns, schemas, loadOptions, loadTreeOption, treeOption, State, newState } from './model';
|
||||
import { adaTableScrollX, getTreeKeys } from '@/utils/hotgo';
|
||||
import Edit from './edit.vue';
|
||||
|
||||
const dict = useDictStore();
|
||||
const dialog = useDialog();
|
||||
const message = useMessage();
|
||||
const { hasPermission } = usePermission();
|
||||
@@ -160,7 +162,7 @@
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
fixed: 'right',
|
||||
render(record) {
|
||||
render(record: State) {
|
||||
return h(TableAction as any, {
|
||||
style: 'button',
|
||||
actions: [
|
||||
@@ -274,6 +276,7 @@
|
||||
});
|
||||
}
|
||||
|
||||
// 选中树节点
|
||||
function handleSelected(keys, option) {
|
||||
if (keys.length) {
|
||||
selectedState.value = newState(option[0]);
|
||||
@@ -283,10 +286,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 展开指定节点
|
||||
function handleOnExpandedKeys(keys) {
|
||||
expandedKeys.value = keys;
|
||||
}
|
||||
|
||||
// 展开全部节点
|
||||
function handleAllExpanded() {
|
||||
if (expandedKeys.value.length) {
|
||||
expandedKeys.value = [];
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
import { h, ref } from 'vue';
|
||||
import { NTag } from 'naive-ui';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { FormSchema } from '@/components/Form';
|
||||
import { Dicts } from '@/api/dict/dict';
|
||||
import { isNullObject } from '@/utils/is';
|
||||
import { defRangeShortcuts } from '@/utils/dateUtil';
|
||||
import { Option, getOptionLabel, getOptionTag } from '@/utils/hotgo';
|
||||
import { renderPopoverMemberSumma, MemberSumma } from '@/utils';
|
||||
import { renderOptionTag, renderPopoverMemberSumma, MemberSumma } from '@/utils';
|
||||
import { TreeOption } from '@/api/optionTreeDemo';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
|
||||
const dict = useDictStore();
|
||||
|
||||
export class State {
|
||||
public title = ''; // 标题
|
||||
public id = 0; // ID
|
||||
public pid = 0; // 上级
|
||||
public level = 1; // 关系树级别
|
||||
public tree = ''; // 关系树
|
||||
public tree = null; // 关系树
|
||||
public categoryId = null; // 测试分类
|
||||
public description = ''; // 描述
|
||||
public sort = 0; // 排序
|
||||
@@ -73,7 +72,7 @@ export const schemas = ref<FormSchema[]>([
|
||||
defaultValue: null,
|
||||
componentProps: {
|
||||
placeholder: '请选择测试分类',
|
||||
options: [],
|
||||
options: dict.getOption('testCategoryOption'),
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -86,7 +85,7 @@ export const schemas = ref<FormSchema[]>([
|
||||
defaultValue: null,
|
||||
componentProps: {
|
||||
placeholder: '请选择状态',
|
||||
options: [],
|
||||
options: dict.getOption('sys_normal_disable'),
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -120,23 +119,8 @@ export const columns = [
|
||||
key: 'categoryId',
|
||||
align: 'left',
|
||||
width: 100,
|
||||
render(row) {
|
||||
if (isNullObject(row.categoryId)) {
|
||||
return ``;
|
||||
}
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(options.value.testCategoryOption, row.categoryId),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(options.value.testCategoryOption, row.categoryId),
|
||||
}
|
||||
);
|
||||
render(row: State) {
|
||||
return renderOptionTag('testCategoryOption', row.categoryId);
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -144,23 +128,8 @@ export const columns = [
|
||||
key: 'status',
|
||||
align: 'left',
|
||||
width: 150,
|
||||
render(row) {
|
||||
if (isNullObject(row.status)) {
|
||||
return ``;
|
||||
}
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(options.value.sys_normal_disable, row.status),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(options.value.sys_normal_disable, row.status),
|
||||
}
|
||||
);
|
||||
render(row: State) {
|
||||
return renderOptionTag('sys_normal_disable', row.status);
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -168,7 +137,7 @@ export const columns = [
|
||||
key: 'createdBy',
|
||||
align: 'left',
|
||||
width: 100,
|
||||
render(row) {
|
||||
render(row: State) {
|
||||
return renderPopoverMemberSumma(row.createdBySumma);
|
||||
},
|
||||
},
|
||||
@@ -180,29 +149,9 @@ export const columns = [
|
||||
},
|
||||
];
|
||||
|
||||
// 字典数据选项
|
||||
export const options = ref({
|
||||
sys_normal_disable: [] as Option[],
|
||||
testCategoryOption: [] as Option[],
|
||||
});
|
||||
|
||||
// 加载字典数据选项
|
||||
export function loadOptions() {
|
||||
Dicts({
|
||||
types: ['sys_normal_disable', 'testCategoryOption'],
|
||||
}).then((res) => {
|
||||
options.value = res;
|
||||
for (const item of schemas.value) {
|
||||
switch (item.field) {
|
||||
case 'status':
|
||||
item.componentProps.options = options.value.sys_normal_disable;
|
||||
break;
|
||||
case 'categoryId':
|
||||
item.componentProps.options = options.value.testCategoryOption;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
dict.loadOptions(['sys_normal_disable', 'testCategoryOption']);
|
||||
}
|
||||
|
||||
// 关系树选项
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<n-drawer v-model:show="showModal" :width="dialogWidth">
|
||||
<n-drawer-content title="选项树表详情" closable>
|
||||
<n-spin :show="loading" description="请稍候...">
|
||||
<n-descriptions label-placement="left" class="py-2" column="1">
|
||||
<n-descriptions-item>
|
||||
<template #label>
|
||||
标题
|
||||
</template>
|
||||
{{ formValue.title }}
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item>
|
||||
<template #label>
|
||||
上级
|
||||
</template>
|
||||
{{ formValue.pid }}
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item label="测试分类">
|
||||
<n-tag :type="getOptionTag(options.testCategoryOption, formValue?.categoryId)" size="small" class="min-left-space">
|
||||
{{ getOptionLabel(options.testCategoryOption, formValue?.categoryId) }}
|
||||
</n-tag>
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item>
|
||||
<template #label>
|
||||
描述
|
||||
</template>
|
||||
{{ formValue.description }}
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item>
|
||||
<template #label>
|
||||
排序
|
||||
</template>
|
||||
{{ formValue.sort }}
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item label="状态">
|
||||
<n-tag :type="getOptionTag(options.sys_normal_disable, formValue?.status)" size="small" class="min-left-space">
|
||||
{{ getOptionLabel(options.sys_normal_disable, formValue?.status) }}
|
||||
</n-tag>
|
||||
</n-descriptions-item>
|
||||
</n-descriptions>
|
||||
</n-spin>
|
||||
</n-drawer-content>
|
||||
</n-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref } from 'vue';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { View } from '@/api/optionTreeDemo';
|
||||
import { State, newState, options } from './model';
|
||||
import { adaModalWidth, getOptionLabel, getOptionTag } from '@/utils/hotgo';
|
||||
import { getFileExt } from '@/utils/urlUtils';
|
||||
|
||||
const message = useMessage();
|
||||
const loading = ref(false);
|
||||
const showModal = ref(false);
|
||||
const formValue = ref(newState(null));
|
||||
const dialogWidth = computed(() => {
|
||||
return adaModalWidth(580);
|
||||
});
|
||||
const fileAvatarCSS = computed(() => {
|
||||
return {
|
||||
'--n-merged-size': `var(--n-avatar-size-override, 80px)`,
|
||||
'--n-font-size': `18px`,
|
||||
};
|
||||
});
|
||||
|
||||
//下载
|
||||
function download(url: string) {
|
||||
window.open(url);
|
||||
}
|
||||
|
||||
function openModal(state: State) {
|
||||
showModal.value = true;
|
||||
loading.value = true;
|
||||
View({ id: state.id })
|
||||
.then((res) => {
|
||||
formValue.value = res;
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
openModal,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
@@ -50,7 +50,7 @@
|
||||
<n-form-item label="部门类型" path="type">
|
||||
<n-radio-group v-model:value="formValue.type" name="type">
|
||||
<n-space>
|
||||
<n-radio v-for="item in options.deptType" :value="item.value">
|
||||
<n-radio v-for="item in dict.getOptionUnRef('deptType')" :value="item.value">
|
||||
{{ item.label }}
|
||||
</n-radio>
|
||||
</n-space>
|
||||
@@ -86,7 +86,7 @@
|
||||
<n-form-item label="状态" path="status">
|
||||
<n-radio-group v-model:value="formValue.status" name="status">
|
||||
<n-radio-button
|
||||
v-for="status in options.sys_normal_disable"
|
||||
v-for="status in dict.getOptionUnRef('sys_normal_disable')"
|
||||
:key="status.value"
|
||||
:value="status.value"
|
||||
:label="status.label"
|
||||
@@ -111,14 +111,16 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import { Edit, View, MaxSort } from '@/api/org/dept';
|
||||
import { options, State, newState, treeOption, loadTreeOption, rules } from './model';
|
||||
import { State, newState, treeOption, loadTreeOption, rules } from './model';
|
||||
import { useProjectSettingStore } from '@/store/modules/projectSetting';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { adaModalWidth } from '@/utils/hotgo';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
|
||||
const emit = defineEmits(['reloadTable']);
|
||||
const message = useMessage();
|
||||
const settingStore = useProjectSettingStore();
|
||||
const dict = useDictStore();
|
||||
const loading = ref(false);
|
||||
const showModal = ref(false);
|
||||
const formValue = ref<State>(newState(null));
|
||||
|
||||
@@ -2,14 +2,15 @@ import { h, ref } from 'vue';
|
||||
import { NTag, NButton } from 'naive-ui';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { FormSchema } from '@/components/Form';
|
||||
import { Dicts } from '@/api/dict/dict';
|
||||
import { defRangeShortcuts } from '@/utils/dateUtil';
|
||||
import { validate } from '@/utils/validateUtil';
|
||||
import { Option, getOptionLabel, getOptionTag } from '@/utils/hotgo';
|
||||
import { renderTooltip, renderIcon } from '@/utils';
|
||||
import { renderTooltip, renderIcon, renderOptionTag } from '@/utils';
|
||||
import { HelpCircleOutline } from '@vicons/ionicons5';
|
||||
import { TreeOption } from '@/api/org/dept';
|
||||
import { isNullObject } from '@/utils/is';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import type { FormRules } from 'naive-ui/es/form/src/interface';
|
||||
|
||||
const dict = useDictStore();
|
||||
|
||||
export class State {
|
||||
public id = 0; // 部门ID
|
||||
@@ -45,7 +46,7 @@ export function newState(state: State | Record<string, any> | null): State {
|
||||
}
|
||||
|
||||
// 表单验证规则
|
||||
export const rules = {
|
||||
export const rules: FormRules = {
|
||||
email: {
|
||||
required: false,
|
||||
trigger: ['blur', 'input'],
|
||||
@@ -155,22 +156,7 @@ export const columns = [
|
||||
align: 'left',
|
||||
width: 100,
|
||||
render(row) {
|
||||
if (isNullObject(row.type)) {
|
||||
return ``;
|
||||
}
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(options.value.deptType, row.type),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(options.value.deptType, row.type),
|
||||
}
|
||||
);
|
||||
return renderOptionTag('deptType', row.type);
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -189,22 +175,7 @@ export const columns = [
|
||||
align: 'left',
|
||||
width: 80,
|
||||
render(row) {
|
||||
if (isNullObject(row.status)) {
|
||||
return ``;
|
||||
}
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(options.value.sys_normal_disable, row.status),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(options.value.sys_normal_disable, row.status),
|
||||
}
|
||||
);
|
||||
return renderOptionTag('sys_normal_disable', row.status);
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -214,26 +185,9 @@ export const columns = [
|
||||
},
|
||||
];
|
||||
|
||||
// 字典数据选项
|
||||
export const options = ref({
|
||||
sys_normal_disable: [] as Option[],
|
||||
deptType: [] as Option[],
|
||||
});
|
||||
|
||||
// 加载字典数据选项
|
||||
export function loadOptions() {
|
||||
Dicts({
|
||||
types: ['sys_normal_disable', 'deptType'],
|
||||
}).then((res) => {
|
||||
options.value = res;
|
||||
for (const item of schemas.value) {
|
||||
switch (item.field) {
|
||||
case 'status':
|
||||
item.componentProps.options = options.value.sys_normal_disable;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
dict.loadOptions(['sys_normal_disable', 'deptType']);
|
||||
}
|
||||
|
||||
// 关系树选项
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
ref="actionRef"
|
||||
:actionColumn="actionColumn"
|
||||
@update:checked-row-keys="onCheckedRow"
|
||||
:scroll-x="1500"
|
||||
:scroll-x="scrollX"
|
||||
:resizeHeightOffset="-10000"
|
||||
>
|
||||
<template #tableTitle>
|
||||
@@ -108,7 +108,7 @@
|
||||
<n-form-item label="所属部门" path="deptId">
|
||||
<n-tree-select
|
||||
key-field="id"
|
||||
:options="options.dept"
|
||||
:options="deptTreeOptions"
|
||||
:default-value="formParams.deptId"
|
||||
@update:value="handleUpdateDeptValue"
|
||||
clearable
|
||||
@@ -121,7 +121,7 @@
|
||||
<n-form-item label="绑定角色" path="roleId">
|
||||
<n-tree-select
|
||||
key-field="id"
|
||||
:options="options.role"
|
||||
:options="roleTreeOptions"
|
||||
:default-value="formParams.roleId"
|
||||
@update:value="handleUpdateRoleValue"
|
||||
clearable
|
||||
@@ -143,7 +143,7 @@
|
||||
<n-form-item label="绑定岗位" path="postIds">
|
||||
<n-select
|
||||
:default-value="formParams.postIds"
|
||||
:options="options.post"
|
||||
:options="dict.getOptionUnRef('adminPostOption')"
|
||||
@update:value="handleUpdatePostValue"
|
||||
multiple
|
||||
clearable
|
||||
@@ -171,7 +171,7 @@
|
||||
<n-form-item label="性别" path="sex">
|
||||
<n-radio-group v-model:value="formParams.sex" name="sex">
|
||||
<n-radio-button
|
||||
v-for="status in options.sys_user_sex"
|
||||
v-for="status in dict.getOptionUnRef('sys_user_sex')"
|
||||
:key="status.value"
|
||||
:value="status.value"
|
||||
:label="status.label"
|
||||
@@ -183,7 +183,7 @@
|
||||
<n-form-item label="状态" path="status">
|
||||
<n-radio-group v-model:value="formParams.status" name="status">
|
||||
<n-radio-button
|
||||
v-for="status in options.sys_normal_disable"
|
||||
v-for="status in dict.getOptionUnRef('sys_normal_disable')"
|
||||
:key="status.value"
|
||||
:value="status.value"
|
||||
:label="status.label"
|
||||
@@ -207,15 +207,15 @@
|
||||
</n-modal>
|
||||
|
||||
<AddBalance
|
||||
@reloadTable="reloadTable"
|
||||
@updateShowModal="updateBalanceShowModal"
|
||||
@reload-table="reloadTable"
|
||||
@update-show-modal="updateBalanceShowModal"
|
||||
:showModal="showBalanceModal"
|
||||
:formParams="formParams"
|
||||
/>
|
||||
|
||||
<AddIntegral
|
||||
@reloadTable="reloadTable"
|
||||
@updateShowModal="updateIntegralShowModal"
|
||||
@reload-table="reloadTable"
|
||||
@update-show-modal="updateIntegralShowModal"
|
||||
:showModal="showIntegralModal"
|
||||
:formParams="formParams"
|
||||
/>
|
||||
@@ -237,25 +237,33 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { h, reactive, ref, onMounted, computed } from 'vue';
|
||||
import { h, reactive, ref, computed } from 'vue';
|
||||
import { useDialog, useMessage } from 'naive-ui';
|
||||
import { ActionItem, BasicTable, TableAction } from '@/components/Table';
|
||||
import { BasicForm } from '@/components/Form/index';
|
||||
import { Delete, Edit, List, Status, ResetPwd } from '@/api/org/user';
|
||||
import { Delete, Edit, List, ResetPwd } from '@/api/org/user';
|
||||
import { columns } from './columns';
|
||||
import { PlusOutlined, DeleteOutlined } from '@vicons/antd';
|
||||
import { QrCodeOutline } from '@vicons/ionicons5';
|
||||
import { adaModalWidth } from '@/utils/hotgo';
|
||||
import { adaModalWidth, adaTableScrollX } from '@/utils/hotgo';
|
||||
import { getRandomString } from '@/utils/charset';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import QrcodeVue from 'qrcode.vue';
|
||||
import AddBalance from './addBalance.vue';
|
||||
import AddIntegral from './addIntegral.vue';
|
||||
import { addNewState, addState, options, register, defaultState, loadOptions } from './model';
|
||||
import {
|
||||
addNewState,
|
||||
addState,
|
||||
register,
|
||||
defaultState,
|
||||
deptTreeOptions,
|
||||
roleTreeOptions,
|
||||
} from './model';
|
||||
import { usePermission } from '@/hooks/web/usePermission';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { LoginRoute } from '@/router';
|
||||
import { getNowUrl } from '@/utils/urlUtils';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
|
||||
interface Props {
|
||||
type?: string;
|
||||
@@ -273,6 +281,7 @@
|
||||
},
|
||||
};
|
||||
|
||||
const dict = useDictStore();
|
||||
const { hasPermission } = usePermission();
|
||||
const userStore = useUserStore();
|
||||
const showIntegralModal = ref(false);
|
||||
@@ -292,12 +301,13 @@
|
||||
name: '',
|
||||
qrUrl: '',
|
||||
});
|
||||
|
||||
const dialogWidth = computed(() => {
|
||||
return adaModalWidth();
|
||||
});
|
||||
|
||||
const actionColumn = reactive({
|
||||
width: 280,
|
||||
width: 200,
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
fixed: 'right',
|
||||
@@ -306,22 +316,6 @@
|
||||
return h(TableAction as any, {
|
||||
style: 'button',
|
||||
actions: [
|
||||
{
|
||||
label: '已启用',
|
||||
onClick: handleStatus.bind(null, record, 2),
|
||||
ifShow: () => {
|
||||
return record.status === 1 && record.id !== 1;
|
||||
},
|
||||
auth: ['/member/status'],
|
||||
},
|
||||
{
|
||||
label: '已禁用',
|
||||
onClick: handleStatus.bind(null, record, 1),
|
||||
ifShow: () => {
|
||||
return record.status === 2 && record.id !== 1;
|
||||
},
|
||||
auth: ['/member/status'],
|
||||
},
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
@@ -362,6 +356,10 @@
|
||||
},
|
||||
});
|
||||
|
||||
const scrollX = computed(() => {
|
||||
return adaTableScrollX(columns, actionColumn.width);
|
||||
});
|
||||
|
||||
function getDropDownActions(record: Recordable): ActionItem[] {
|
||||
if (record.id === 1) {
|
||||
return [];
|
||||
@@ -488,15 +486,6 @@
|
||||
reloadTable();
|
||||
}
|
||||
|
||||
function handleStatus(record: Recordable, status) {
|
||||
Status({ id: record.id, status: status }).then((_res) => {
|
||||
message.success('操作成功');
|
||||
setTimeout(() => {
|
||||
reloadTable();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function handleUpdateDeptValue(value) {
|
||||
formParams.value.deptId = Number(value);
|
||||
}
|
||||
@@ -532,10 +521,6 @@
|
||||
qrParams.value.qrUrl = domain + LoginRoute.path + '?scope=register&inviteCode=' + code;
|
||||
showQrModal.value = true;
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await loadOptions();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
|
||||
@@ -3,12 +3,13 @@ import { ref } from 'vue';
|
||||
import { getDeptOption } from '@/api/org/dept';
|
||||
import { getRoleOption } from '@/api/system/role';
|
||||
import { FormSchema, useForm } from '@/components/Form';
|
||||
import { statusOptions } from '@/enums/optionsiEnum';
|
||||
import { defRangeShortcuts } from '@/utils/dateUtil';
|
||||
import { Dicts } from '@/api/dict/dict';
|
||||
import { useDictStore, Option } from '@/store/modules/dict';
|
||||
|
||||
// 增加余额/积分.
|
||||
|
||||
const dict = useDictStore();
|
||||
|
||||
export interface addState {
|
||||
id: number;
|
||||
username: string;
|
||||
@@ -166,7 +167,7 @@ const schemas: FormSchema[] = [
|
||||
defaultValue: null,
|
||||
componentProps: {
|
||||
placeholder: '请选择类型',
|
||||
options: statusOptions,
|
||||
options: dict.getOption('sys_normal_disable'),
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -193,42 +194,44 @@ export const [register, {}] = useForm({
|
||||
schemas,
|
||||
});
|
||||
|
||||
export const options = ref<any>({
|
||||
role: [],
|
||||
roleTabs: [{ id: -1, name: '全部' }],
|
||||
dept: [],
|
||||
post: [],
|
||||
sys_user_sex: [],
|
||||
sys_normal_disable: [],
|
||||
});
|
||||
export const deptTreeOptions = ref([]);
|
||||
export const roleTreeOptions = ref([]);
|
||||
|
||||
export async function loadOptions() {
|
||||
const dept = await getDeptOption();
|
||||
if (dept.list) {
|
||||
options.value.dept = dept.list;
|
||||
}
|
||||
dict.loadOptions(['adminPostOption', 'sys_user_sex', 'sys_normal_disable']);
|
||||
|
||||
const role = await getRoleOption();
|
||||
if (role.list) {
|
||||
options.value.role = role.list;
|
||||
options.value.roleTabs = [{ id: -1, name: '全部' }];
|
||||
treeDataToCompressed(role.list);
|
||||
}
|
||||
|
||||
const tmpOptions = await Dicts({
|
||||
types: ['adminPostOption', 'sys_user_sex', 'sys_normal_disable'],
|
||||
getDeptOption().then((res) => {
|
||||
if (res.list) {
|
||||
deptTreeOptions.value = res.list;
|
||||
}
|
||||
});
|
||||
|
||||
getRoleOption().then((res) => {
|
||||
if (res.list) {
|
||||
roleTreeOptions.value = res.list;
|
||||
registerRoleTabsOption();
|
||||
}
|
||||
});
|
||||
options.value.post = tmpOptions?.adminPostOption;
|
||||
options.value.sys_user_sex = tmpOptions?.sys_user_sex;
|
||||
options.value.sys_normal_disable = tmpOptions?.sys_normal_disable;
|
||||
}
|
||||
|
||||
function treeDataToCompressed(source) {
|
||||
// 将角色Tabs选项注册到字典
|
||||
function registerRoleTabsOption() {
|
||||
const items = [{ id: -1, name: '全部' }];
|
||||
treeDataToCompressed(items, roleTreeOptions.value);
|
||||
|
||||
const roleTabs: Option[] = [];
|
||||
for (const item of items) {
|
||||
roleTabs.push(dict.genOption(item.id, item.name));
|
||||
}
|
||||
dict.setOption('roleTabs', roleTabs);
|
||||
}
|
||||
|
||||
function treeDataToCompressed(items: any[], source: any) {
|
||||
for (const i in source) {
|
||||
options.value.roleTabs.push(source[i]);
|
||||
items.push(source[i]);
|
||||
source[i].children && source[i].children.length > 0
|
||||
? treeDataToCompressed(source[i].children)
|
||||
? treeDataToCompressed(items, source[i].children)
|
||||
: ''; // 子级递归
|
||||
}
|
||||
return options.value.roleTabs;
|
||||
return items;
|
||||
}
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
@before-leave="handleBeforeLeave"
|
||||
>
|
||||
<n-tab-pane
|
||||
:name="item.id.toString()"
|
||||
:tab="item.name"
|
||||
v-for="item in options.roleTabs"
|
||||
:name="item.key.toString()"
|
||||
:tab="item.label"
|
||||
v-for="item in dict.getOptionUnRef('roleTabs')"
|
||||
:key="item.key"
|
||||
>
|
||||
<List :type="defaultTab" />
|
||||
@@ -28,8 +28,10 @@
|
||||
import { onMounted, ref } from 'vue';
|
||||
import List from './list.vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { options } from './model';
|
||||
import { loadOptions } from './model';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
|
||||
const dict = useDictStore();
|
||||
const router = useRouter();
|
||||
const defaultTab = ref('-1');
|
||||
|
||||
@@ -37,6 +39,7 @@
|
||||
if (router.currentRoute.value.query?.type) {
|
||||
defaultTab.value = router.currentRoute.value.query.type as string;
|
||||
}
|
||||
loadOptions();
|
||||
});
|
||||
|
||||
function handleBeforeLeave(tabName: string): boolean | Promise<boolean> {
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
:on-update:value="handleUpdateType"
|
||||
>
|
||||
<n-radio-button
|
||||
v-for="menuType in options.sys_menu_types"
|
||||
v-for="menuType in dict.getOptionUnRef('sys_menu_types')"
|
||||
:key="menuType.value"
|
||||
:value="menuType.value"
|
||||
:label="menuType.label"
|
||||
@@ -91,7 +91,7 @@
|
||||
<n-form-item label="目录组件" path="component">
|
||||
<n-select
|
||||
v-if="formParams.type === 1"
|
||||
:options="options.sys_menu_component"
|
||||
:options="dict.getOptionUnRef('sys_menu_component')"
|
||||
v-model:value="formParams.component"
|
||||
placeholder="请选择目录组件"
|
||||
clearable
|
||||
@@ -159,7 +159,7 @@
|
||||
<n-input-group>
|
||||
<n-select
|
||||
:style="{ width: '33%', minWidth: '80px' }"
|
||||
:options="options.sys_switch"
|
||||
:options="dict.getOptionUnRef('sys_switch')"
|
||||
v-model:value="formParams.isFrame"
|
||||
/>
|
||||
<n-input
|
||||
@@ -173,7 +173,7 @@
|
||||
<n-form-item label="菜单状态" path="status">
|
||||
<n-radio-group v-model:value="formParams.status" name="status">
|
||||
<n-radio-button
|
||||
v-for="status in options.sys_normal_disable"
|
||||
v-for="status in dict.getOptionUnRef('sys_normal_disable')"
|
||||
:key="status.value"
|
||||
:value="status.value"
|
||||
:label="status.label"
|
||||
@@ -210,13 +210,15 @@
|
||||
import { QuestionCircleOutlined } from '@vicons/antd';
|
||||
import IconSelector from '@/components/IconSelector/index.vue';
|
||||
import { computed, ref } from 'vue';
|
||||
import { newState, State, options } from '@/views/permission/menu/model';
|
||||
import { newState, State } from '@/views/permission/menu/model';
|
||||
import { FormItemRule, useDialog, useMessage } from 'naive-ui';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { DeleteMenu, EditMenu } from '@/api/system/menu';
|
||||
import { findTreeNode } from '@/utils';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import type { FormRules } from 'naive-ui/es/form/src/interface';
|
||||
|
||||
const rules = {
|
||||
const rules: FormRules = {
|
||||
title: {
|
||||
required: true,
|
||||
message: '请输入名称',
|
||||
@@ -231,15 +233,17 @@
|
||||
required: false,
|
||||
message: '请输入路由地址',
|
||||
trigger: 'blur',
|
||||
validator: function (_rule: FormItemRule, value: any, callback: Function) {
|
||||
validator: function (_rule: FormItemRule, value: any, callback: Function): boolean | Error {
|
||||
if (formParams.value.type != 3 && !value) {
|
||||
callback(new Error('请输入路由地址'));
|
||||
}
|
||||
return true;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const emit = defineEmits(['reloadTable', 'closeForm']);
|
||||
const dict = useDictStore();
|
||||
const message = useMessage();
|
||||
const dialog = useDialog();
|
||||
const loading = ref(false);
|
||||
|
||||
@@ -21,14 +21,14 @@
|
||||
import { computed, ref } from 'vue';
|
||||
import Menu from './menu.vue';
|
||||
import { adaModalWidth } from '@/utils/hotgo';
|
||||
|
||||
const emit = defineEmits(['reloadTable']);
|
||||
const showModal = ref(false);
|
||||
const isModal = ref(true);
|
||||
const dialogWidth = computed(() => {
|
||||
return adaModalWidth(1280);
|
||||
});
|
||||
|
||||
const emit = defineEmits(['reloadTable']);
|
||||
|
||||
function openModal() {
|
||||
showModal.value = true;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { ref } from 'vue';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { Option } from '@/utils/hotgo';
|
||||
import { Dicts } from '@/api/dict/dict';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
|
||||
const dict = useDictStore();
|
||||
|
||||
export interface State {
|
||||
id: number;
|
||||
pid?: number;
|
||||
pid?: number | null;
|
||||
title: string;
|
||||
name: string;
|
||||
path: string;
|
||||
@@ -15,7 +15,7 @@ export interface State {
|
||||
redirect: string;
|
||||
permissions: string;
|
||||
permissionName: string;
|
||||
component?: string;
|
||||
component?: string | null;
|
||||
alwaysShow: number;
|
||||
activeMenu: string;
|
||||
isRoot: number;
|
||||
@@ -27,7 +27,7 @@ export interface State {
|
||||
status: number;
|
||||
sort: number;
|
||||
disabled: boolean;
|
||||
children?: State[];
|
||||
children?: State[] | null;
|
||||
}
|
||||
|
||||
export const defaultState: State = {
|
||||
@@ -66,7 +66,10 @@ export function newState(state: State | null): State {
|
||||
|
||||
// 默认值校正,主要为了解决历史数据格式不规范问题
|
||||
export function defaultValueCheck(state: State): State {
|
||||
if (state.pid < 1) {
|
||||
if (!state) {
|
||||
state = newState(null);
|
||||
}
|
||||
if (!state.pid || state.pid < 1) {
|
||||
state.pid = null;
|
||||
}
|
||||
if (state.alwaysShow != 1) {
|
||||
@@ -93,19 +96,7 @@ export function defaultValueCheck(state: State): State {
|
||||
return state;
|
||||
}
|
||||
|
||||
// 字典数据选项
|
||||
export const options = ref({
|
||||
sys_menu_types: [] as Option[],
|
||||
sys_menu_component: [] as Option[],
|
||||
sys_normal_disable: [] as Option[],
|
||||
sys_switch: [] as Option[],
|
||||
});
|
||||
|
||||
// 加载字典数据选项
|
||||
export function loadOptions() {
|
||||
Dicts({
|
||||
types: ['sys_menu_types', 'sys_menu_component', 'sys_normal_disable', 'sys_switch'],
|
||||
}).then((res) => {
|
||||
options.value = res;
|
||||
});
|
||||
dict.loadOptions(['sys_menu_types', 'sys_menu_component', 'sys_normal_disable', 'sys_switch']);
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
<n-form-item label="状态" path="status">
|
||||
<n-radio-group v-model:value="formParams.status" name="status">
|
||||
<n-radio-button
|
||||
v-for="status in blacklistOptions"
|
||||
v-for="status in dict.getOptionUnRef('BlacklistStatusOptions')"
|
||||
:key="status.value"
|
||||
:value="status.value"
|
||||
:label="status.label"
|
||||
@@ -98,31 +98,18 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { h, reactive, ref } from 'vue';
|
||||
import { NTag, useDialog, useMessage } from 'naive-ui';
|
||||
import { h, onMounted, reactive, ref } from 'vue';
|
||||
import { useDialog, useMessage } from 'naive-ui';
|
||||
import { BasicTable, TableAction } from '@/components/Table';
|
||||
import { BasicForm, FormSchema, useForm } from '@/components/Form/index';
|
||||
import { Delete, Edit, List, Status } from '@/api/sys/blacklist';
|
||||
import { DeleteOutlined, PlusOutlined } from '@vicons/antd';
|
||||
import { statusActions } from '@/enums/optionsiEnum';
|
||||
import { getOptionLabel, getOptionTag, Option } from '@/utils/hotgo';
|
||||
import { defRangeShortcuts } from '@/utils/dateUtil';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import { renderOptionTag } from '@/utils';
|
||||
|
||||
const blacklistOptions: Option[] = [
|
||||
{
|
||||
key: 1,
|
||||
value: 1,
|
||||
label: '封禁中',
|
||||
listClass: 'warning',
|
||||
},
|
||||
{
|
||||
key: 2,
|
||||
value: 2,
|
||||
label: '已解封',
|
||||
listClass: 'success',
|
||||
},
|
||||
];
|
||||
|
||||
const dict = useDictStore();
|
||||
const columns = [
|
||||
{
|
||||
title: 'ID',
|
||||
@@ -140,19 +127,7 @@
|
||||
title: '状态',
|
||||
key: 'status',
|
||||
render(row) {
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(blacklistOptions, row.status),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(blacklistOptions, row.status),
|
||||
}
|
||||
);
|
||||
return renderOptionTag('BlacklistStatusOptions', row.status);
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -190,7 +165,7 @@
|
||||
defaultValue: null,
|
||||
componentProps: {
|
||||
placeholder: '请选择类型',
|
||||
options: blacklistOptions,
|
||||
options: dict.getOption('BlacklistStatusOptions'),
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -240,13 +215,13 @@
|
||||
sort: 0,
|
||||
status: 1,
|
||||
};
|
||||
let formParams = ref<any>(resetFormParams);
|
||||
const formParams = ref<any>(resetFormParams);
|
||||
|
||||
const actionColumn = reactive({
|
||||
width: 220,
|
||||
width: 150,
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
// fixed: 'right',
|
||||
fixed: 'right',
|
||||
render(record) {
|
||||
return h(TableAction as any, {
|
||||
style: 'button',
|
||||
@@ -260,10 +235,6 @@
|
||||
onClick: handleDelete.bind(null, record),
|
||||
},
|
||||
],
|
||||
dropDownActions: statusActions,
|
||||
select: (key) => {
|
||||
updateStatus(record.id, key);
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -284,7 +255,6 @@
|
||||
};
|
||||
|
||||
function onCheckedRow(rowKeys) {
|
||||
console.log(rowKeys);
|
||||
batchDeleteDisabled.value = rowKeys.length <= 0;
|
||||
checkedIds.value = rowKeys;
|
||||
}
|
||||
@@ -334,9 +304,6 @@
|
||||
reloadTable();
|
||||
});
|
||||
},
|
||||
onNegativeClick: () => {
|
||||
// message.error('取消');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -356,9 +323,6 @@
|
||||
message.error(e.message ?? '操作失败');
|
||||
});
|
||||
},
|
||||
onNegativeClick: () => {
|
||||
// message.error('取消');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -372,14 +336,9 @@
|
||||
reloadTable();
|
||||
}
|
||||
|
||||
function updateStatus(id, status) {
|
||||
Status({ id: id, status: status }).then((_res) => {
|
||||
message.success('操作成功');
|
||||
setTimeout(() => {
|
||||
reloadTable();
|
||||
});
|
||||
});
|
||||
}
|
||||
onMounted(() => {
|
||||
dict.loadOptions(['BlacklistStatusOptions']);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
|
||||
@@ -119,7 +119,10 @@
|
||||
class="py-4"
|
||||
>
|
||||
<n-form-item label="事件模板" path="event">
|
||||
<n-select :options="options.config_sms_template" v-model:value="formParams.event" />
|
||||
<n-select
|
||||
:options="dict.getOptionUnRef('config_sms_template')"
|
||||
v-model:value="formParams.event"
|
||||
/>
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item label="手机号" path="mobile">
|
||||
@@ -153,8 +156,7 @@
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { getConfig, sendTestSms, updateConfig } from '@/api/sys/config';
|
||||
import { Dicts } from '@/api/dict/dict';
|
||||
import { Options } from '@/utils/hotgo';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
|
||||
const group = ref('pay');
|
||||
const show = ref(false);
|
||||
@@ -165,11 +167,7 @@
|
||||
const formTestRef = ref<any>();
|
||||
const formRef: any = ref(null);
|
||||
const message = useMessage();
|
||||
|
||||
const options = ref<Options>({
|
||||
config_sms_template: [],
|
||||
config_sms_drive: [],
|
||||
});
|
||||
const dict = useDictStore();
|
||||
|
||||
const formValue = ref({
|
||||
payDebug: true,
|
||||
@@ -188,11 +186,6 @@
|
||||
payQQPayApiKey: '',
|
||||
});
|
||||
|
||||
function sendTest() {
|
||||
showModal.value = true;
|
||||
formBtnLoading.value = false;
|
||||
}
|
||||
|
||||
function formSubmit() {
|
||||
formRef.value.validate((errors) => {
|
||||
if (!errors) {
|
||||
@@ -206,28 +199,20 @@
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
load();
|
||||
});
|
||||
|
||||
async function load() {
|
||||
function load() {
|
||||
show.value = true;
|
||||
await loadOptions();
|
||||
new Promise((_resolve, _reject) => {
|
||||
getConfig({ group: group.value })
|
||||
.then((res) => {
|
||||
formValue.value = res.list;
|
||||
})
|
||||
.finally(() => {
|
||||
show.value = false;
|
||||
});
|
||||
});
|
||||
loadOptions();
|
||||
getConfig({ group: group.value })
|
||||
.then((res) => {
|
||||
formValue.value = res.list;
|
||||
})
|
||||
.finally(() => {
|
||||
show.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
async function loadOptions() {
|
||||
options.value = await Dicts({
|
||||
types: ['config_sms_template', 'config_sms_drive'],
|
||||
});
|
||||
function loadOptions() {
|
||||
dict.loadOptions(['config_sms_template', 'config_sms_drive']);
|
||||
}
|
||||
|
||||
function confirmForm(e) {
|
||||
@@ -245,4 +230,8 @@
|
||||
formBtnLoading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
load();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -6,17 +6,16 @@
|
||||
:model="formValue"
|
||||
:rules="rules"
|
||||
ref="formRef"
|
||||
label-placement="left"
|
||||
label-placement="top"
|
||||
>
|
||||
<n-divider title-placement="left">基础设置</n-divider>
|
||||
<n-form-item label="默认驱动" path="smsDrive">
|
||||
<n-select
|
||||
placeholder="默认发送驱动"
|
||||
:options="options.config_sms_drive"
|
||||
:options="dict.getOptionUnRef('config_sms_drive')"
|
||||
v-model:value="formValue.smsDrive"
|
||||
/>
|
||||
</n-form-item>
|
||||
|
||||
<n-divider title-placement="left">发信限制</n-divider>
|
||||
<n-form-item label="最小发送间隔" path="smsMinInterval">
|
||||
<n-input-number
|
||||
:show-button="false"
|
||||
@@ -179,7 +178,10 @@
|
||||
class="py-4"
|
||||
>
|
||||
<n-form-item label="事件模板" path="event">
|
||||
<n-select :options="options.config_sms_template" v-model:value="formParams.event" />
|
||||
<n-select
|
||||
:options="dict.getOptionUnRef('config_sms_template')"
|
||||
v-model:value="formParams.event"
|
||||
/>
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item label="手机号" path="mobile">
|
||||
@@ -213,17 +215,23 @@
|
||||
import { ref, onMounted, watch } from 'vue';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { getConfig, sendTestSms, updateConfig } from '@/api/sys/config';
|
||||
import { Dicts } from '@/api/dict/dict';
|
||||
import { Options } from '@/utils/hotgo';
|
||||
import { GlassesOutline, Glasses } from '@vicons/ionicons5';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import type { FormRules } from 'naive-ui/es/form/src/interface';
|
||||
|
||||
const dict = useDictStore();
|
||||
const message = useMessage();
|
||||
const group = ref('sms');
|
||||
const show = ref(false);
|
||||
const showModal = ref(false);
|
||||
const formBtnLoading = ref(false);
|
||||
const formParams = ref({ mobile: '', event: '', code: '1234' });
|
||||
const formTestRef = ref<any>();
|
||||
const formRef: any = ref(null);
|
||||
const defaultTabName = 'aliyun';
|
||||
const tabName = ref<string>(defaultTabName);
|
||||
|
||||
const rules = {
|
||||
const rules: FormRules = {
|
||||
smsDrive: {
|
||||
required: true,
|
||||
message: '请输入默认驱动',
|
||||
@@ -231,20 +239,6 @@
|
||||
},
|
||||
};
|
||||
|
||||
const formTestRef = ref<any>();
|
||||
const formRef: any = ref(null);
|
||||
const message = useMessage();
|
||||
|
||||
const options = ref<Options>({
|
||||
config_sms_template: [],
|
||||
config_sms_drive: [],
|
||||
});
|
||||
|
||||
/** 默认选项卡 */
|
||||
const defaultTabName = 'aliyun';
|
||||
/** 选项卡名称 */
|
||||
const tabName = ref<string>(defaultTabName);
|
||||
|
||||
const formValue = ref({
|
||||
smsDrive: defaultTabName,
|
||||
smsMinInterval: 60,
|
||||
@@ -263,14 +257,6 @@
|
||||
smsTencentTemplate: null,
|
||||
});
|
||||
|
||||
/** 监听类型变化,同步到选项卡中 */
|
||||
watch(
|
||||
() => formValue.value.smsDrive,
|
||||
(smsDrive: string) => {
|
||||
tabName.value = smsDrive;
|
||||
}
|
||||
);
|
||||
|
||||
function sendTest() {
|
||||
showModal.value = true;
|
||||
formBtnLoading.value = false;
|
||||
@@ -289,30 +275,21 @@
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
load();
|
||||
});
|
||||
|
||||
async function load() {
|
||||
function load() {
|
||||
show.value = true;
|
||||
await loadOptions();
|
||||
new Promise((_resolve, _reject) => {
|
||||
getConfig({ group: group.value })
|
||||
.then((res) => {
|
||||
res.list.smsAliYunTemplate = JSON.parse(res.list.smsAliYunTemplate);
|
||||
res.list.smsTencentTemplate = JSON.parse(res.list.smsTencentTemplate);
|
||||
formValue.value = res.list;
|
||||
})
|
||||
.finally(() => {
|
||||
show.value = false;
|
||||
});
|
||||
});
|
||||
getConfig({ group: group.value })
|
||||
.then((res) => {
|
||||
res.list.smsAliYunTemplate = JSON.parse(res.list.smsAliYunTemplate);
|
||||
res.list.smsTencentTemplate = JSON.parse(res.list.smsTencentTemplate);
|
||||
formValue.value = res.list;
|
||||
})
|
||||
.finally(() => {
|
||||
show.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
async function loadOptions() {
|
||||
options.value = await Dicts({
|
||||
types: ['config_sms_template', 'config_sms_drive'],
|
||||
});
|
||||
function loadOptions() {
|
||||
dict.loadOptions(['config_sms_template', 'config_sms_drive']);
|
||||
}
|
||||
|
||||
function confirmForm(e) {
|
||||
@@ -330,4 +307,16 @@
|
||||
formBtnLoading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
watch(
|
||||
() => formValue.value.smsDrive,
|
||||
(smsDrive: string) => {
|
||||
tabName.value = smsDrive;
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
loadOptions();
|
||||
load();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -6,17 +6,16 @@
|
||||
:model="formValue"
|
||||
:rules="rules"
|
||||
ref="formRef"
|
||||
label-placement="left"
|
||||
label-placement="top"
|
||||
>
|
||||
<n-divider title-placement="left">基础设置</n-divider>
|
||||
<n-form-item label="默认驱动" path="uploadDrive">
|
||||
<n-select
|
||||
placeholder="默认驱动"
|
||||
:options="options.config_upload_drive"
|
||||
:options="dict.getOptionUnRef('config_upload_drive')"
|
||||
v-model:value="formValue.uploadDrive"
|
||||
/>
|
||||
</n-form-item>
|
||||
|
||||
<n-divider title-placement="left">上传限制</n-divider>
|
||||
<n-form-item label="图片大小限制" path="uploadImageSize">
|
||||
<n-input-number
|
||||
:show-button="false"
|
||||
@@ -311,15 +310,18 @@
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { getConfig, updateConfig } from '@/api/sys/config';
|
||||
import { Glasses, GlassesOutline } from '@vicons/ionicons5';
|
||||
import { Dicts } from '@/api/dict/dict';
|
||||
import { Options } from '@/utils/hotgo';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import type { FormRules } from 'naive-ui/es/form/src/interface';
|
||||
|
||||
const dict = useDictStore();
|
||||
const message = useMessage();
|
||||
const group = ref('upload');
|
||||
const show = ref(false);
|
||||
const formRef: any = ref(null);
|
||||
const message = useMessage();
|
||||
const defaultTabName = 'local';
|
||||
const tabName = ref<string>(defaultTabName);
|
||||
|
||||
const rules = {
|
||||
const rules: FormRules = {
|
||||
uploadDrive: {
|
||||
required: true,
|
||||
message: '请输入默认驱动',
|
||||
@@ -327,15 +329,6 @@
|
||||
},
|
||||
};
|
||||
|
||||
const options = ref<Options>({
|
||||
config_upload_drive: [],
|
||||
});
|
||||
|
||||
/** 默认选项卡 */
|
||||
const defaultTabName = 'local';
|
||||
/** 选项卡名称 */
|
||||
const tabName = ref<string>(defaultTabName);
|
||||
|
||||
const formValue = ref({
|
||||
uploadDrive: defaultTabName,
|
||||
uploadImageSize: 2,
|
||||
@@ -374,14 +367,6 @@
|
||||
uploadMinioDomain: '',
|
||||
});
|
||||
|
||||
/** 监听类型变化,同步到选项卡中 */
|
||||
watch(
|
||||
() => formValue.value.uploadDrive,
|
||||
(uploadDrive: string) => {
|
||||
tabName.value = uploadDrive;
|
||||
}
|
||||
);
|
||||
|
||||
function formSubmit() {
|
||||
formRef.value.validate((errors) => {
|
||||
if (!errors) {
|
||||
@@ -395,27 +380,30 @@
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
load();
|
||||
await loadOptions();
|
||||
});
|
||||
|
||||
function load() {
|
||||
show.value = true;
|
||||
new Promise((_resolve, _reject) => {
|
||||
getConfig({ group: group.value })
|
||||
.then((res) => {
|
||||
formValue.value = res.list;
|
||||
})
|
||||
.finally(() => {
|
||||
show.value = false;
|
||||
});
|
||||
});
|
||||
getConfig({ group: group.value })
|
||||
.then((res) => {
|
||||
formValue.value = res.list;
|
||||
})
|
||||
.finally(() => {
|
||||
show.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
async function loadOptions() {
|
||||
options.value = await Dicts({
|
||||
types: ['config_upload_drive'],
|
||||
});
|
||||
function loadOptions() {
|
||||
dict.loadOptions(['config_upload_drive']);
|
||||
}
|
||||
|
||||
watch(
|
||||
() => formValue.value.uploadDrive,
|
||||
(uploadDrive: string) => {
|
||||
tabName.value = uploadDrive;
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(async () => {
|
||||
loadOptions();
|
||||
load();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
<template>
|
||||
<n-drawer v-model:show="isDrawer" :width="width" :placement="placement">
|
||||
<n-drawer
|
||||
v-model:show="isDrawer"
|
||||
:width="dialogWidth"
|
||||
:label-placement="settingStore.isMobile ? 'top' : 'left'"
|
||||
>
|
||||
<n-drawer-content :title="title" closable>
|
||||
<n-form
|
||||
:model="formParams"
|
||||
@@ -28,7 +32,7 @@
|
||||
<n-form-item label="状态" path="status">
|
||||
<n-radio-group v-model:value="formParams.status" name="status">
|
||||
<n-radio-button
|
||||
v-for="status in statusMap"
|
||||
v-for="status in dict.getOptionUnRef('sys_normal_disable')"
|
||||
:key="status.value"
|
||||
:value="status.value"
|
||||
:label="status.label"
|
||||
@@ -39,34 +43,25 @@
|
||||
|
||||
<template #footer>
|
||||
<n-space>
|
||||
<n-button type="primary" :loading="subLoading" @click="formSubmit">提交</n-button>
|
||||
<n-button @click="handleReset">重置</n-button>
|
||||
<n-button type="primary" :loading="btnLoading" @click="formSubmit">提交</n-button>
|
||||
<n-button @click="closeDrawer">取消</n-button>
|
||||
</n-space>
|
||||
</template>
|
||||
</n-drawer-content>
|
||||
</n-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, reactive, ref, toRefs } from 'vue';
|
||||
import { TreeSelectOption, useMessage } from 'naive-ui';
|
||||
import { QuestionCircleOutlined } from '@vicons/antd';
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref } from 'vue';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { EditDict } from '@/api/dict/dict';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import type { FormRules } from 'naive-ui/es/form/src/interface';
|
||||
import { State } from '@/views/system/dict/model';
|
||||
import { adaModalWidth } from '@/utils/hotgo';
|
||||
import { useProjectSettingStore } from '@/store/modules/projectSetting';
|
||||
|
||||
const statusMap = [
|
||||
{
|
||||
value: 0,
|
||||
label: '禁用',
|
||||
},
|
||||
{
|
||||
value: 1,
|
||||
label: '启用',
|
||||
},
|
||||
].map((s) => {
|
||||
return s;
|
||||
});
|
||||
|
||||
const rules = {
|
||||
const rules: FormRules = {
|
||||
label: {
|
||||
required: true,
|
||||
message: '请输入标题',
|
||||
@@ -78,96 +73,60 @@
|
||||
trigger: 'blur',
|
||||
},
|
||||
};
|
||||
export default defineComponent({
|
||||
name: 'CreateDrawer',
|
||||
components: {},
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: '添加顶级菜单',
|
||||
},
|
||||
optionTreeData: {
|
||||
type: Object || Array,
|
||||
default: [],
|
||||
},
|
||||
},
|
||||
emits: ['loadData'],
|
||||
setup(_props, context) {
|
||||
const message = useMessage();
|
||||
const formRef: any = ref(null);
|
||||
const defaultValueRef = () => ({
|
||||
id: 0,
|
||||
pid: 0,
|
||||
type: '',
|
||||
name: '',
|
||||
remark: '',
|
||||
status: 1,
|
||||
sort: 10,
|
||||
});
|
||||
|
||||
const state = reactive<any>({
|
||||
width: 500,
|
||||
isDrawer: false,
|
||||
subLoading: false,
|
||||
formParams: defaultValueRef(),
|
||||
placement: 'right',
|
||||
icon: '',
|
||||
alertText:
|
||||
'该功能主要实时预览各种布局效果,更多完整配置在 projectSetting.ts 中设置,建议在生产环境关闭该布局预览功能。',
|
||||
});
|
||||
interface Props {
|
||||
title: '添加顶级菜单';
|
||||
optionTreeData: [];
|
||||
}
|
||||
|
||||
function openDrawer(form) {
|
||||
if (document.body.clientWidth < 500) {
|
||||
state.width = document.body.clientWidth;
|
||||
}
|
||||
state.isDrawer = true;
|
||||
state.formParams = Object.assign(state.formParams, form);
|
||||
const emit = defineEmits(['loadData']);
|
||||
const props = withDefaults(defineProps<Props>(), {});
|
||||
const dict = useDictStore();
|
||||
const message = useMessage();
|
||||
const settingStore = useProjectSettingStore();
|
||||
const formRef: any = ref(null);
|
||||
const formParams = ref<State>(new State());
|
||||
const btnLoading = ref(false);
|
||||
const isDrawer = ref(false);
|
||||
|
||||
const dialogWidth = computed(() => {
|
||||
return adaModalWidth(500);
|
||||
});
|
||||
|
||||
function openDrawer(state: State) {
|
||||
isDrawer.value = true;
|
||||
formParams.value = state;
|
||||
}
|
||||
|
||||
function closeDrawer() {
|
||||
isDrawer.value = false;
|
||||
}
|
||||
|
||||
function formSubmit() {
|
||||
formRef.value.validate((errors) => {
|
||||
if (!errors) {
|
||||
btnLoading.value = true;
|
||||
EditDict(formParams.value)
|
||||
.then(async (_res) => {
|
||||
message.success('操作成功');
|
||||
emit('loadData');
|
||||
closeDrawer();
|
||||
})
|
||||
.finally(() => {
|
||||
btnLoading.value = false;
|
||||
});
|
||||
} else {
|
||||
message.error('请填写完整信息');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function closeDrawer() {
|
||||
state.isDrawer = false;
|
||||
}
|
||||
// 处理选项更新
|
||||
function handleUpdateValue(value: number) {
|
||||
formParams.value.pid = value;
|
||||
}
|
||||
|
||||
function formSubmit() {
|
||||
formRef.value.validate((errors) => {
|
||||
if (!errors) {
|
||||
EditDict({ ...state.formParams }).then(async (_res) => {
|
||||
message.success('操作成功');
|
||||
handleReset();
|
||||
await context.emit('loadData');
|
||||
closeDrawer();
|
||||
});
|
||||
} else {
|
||||
message.error('请填写完整信息');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function handleReset() {
|
||||
formRef.value.restoreValidation();
|
||||
state.formParams = Object.assign(state.formParams, defaultValueRef());
|
||||
}
|
||||
|
||||
// 处理选项更新
|
||||
function handleUpdateValue(
|
||||
value: string | number | Array<string | number> | null,
|
||||
_option: TreeSelectOption | null | Array<TreeSelectOption | null>
|
||||
) {
|
||||
state.formParams.pid = value;
|
||||
}
|
||||
|
||||
return {
|
||||
...toRefs(state),
|
||||
formRef,
|
||||
rules,
|
||||
formSubmit,
|
||||
handleReset,
|
||||
openDrawer,
|
||||
closeDrawer,
|
||||
statusMap,
|
||||
handleUpdateValue,
|
||||
QuestionCircleOutlined,
|
||||
};
|
||||
},
|
||||
defineExpose({
|
||||
openDrawer,
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
</n-space>
|
||||
</template>
|
||||
<div class="w-full menu">
|
||||
<n-input type="input" v-model:value="pattern" placeholder="输入字典名称搜索">
|
||||
<n-input type="text" v-model:value="pattern" placeholder="输入字典名称搜索">
|
||||
<template #suffix>
|
||||
<n-icon size="18" class="cursor-pointer">
|
||||
<SearchOutlined />
|
||||
@@ -111,7 +111,7 @@
|
||||
ref="createDrawerRef"
|
||||
:title="drawerTitle"
|
||||
:optionTreeData="optionTreeData"
|
||||
@loadData="loadData"
|
||||
@load-data="loadData"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -129,6 +129,7 @@
|
||||
import CreateDrawer from './CreateDrawer.vue';
|
||||
import List from './list.vue';
|
||||
import { DeleteDict, getDictTree } from '@/api/dict/dict';
|
||||
import { State } from '@/views/system/dict/model';
|
||||
|
||||
const createDrawerRef = ref();
|
||||
const message = useMessage();
|
||||
@@ -143,28 +144,18 @@
|
||||
const pattern = ref('');
|
||||
const drawerTitle = ref('');
|
||||
const optionTreeData = ref([]);
|
||||
const defaultValueRef = () => ({
|
||||
id: 0,
|
||||
pid: 0,
|
||||
type: '',
|
||||
name: '',
|
||||
remark: '',
|
||||
status: 1,
|
||||
sort: 10,
|
||||
});
|
||||
|
||||
const formParams = reactive(defaultValueRef());
|
||||
const formParams = ref<State>(new State());
|
||||
|
||||
function openCreateDrawer() {
|
||||
drawerTitle.value = '添加字典类型';
|
||||
const { openDrawer } = createDrawerRef.value;
|
||||
openDrawer(defaultValueRef());
|
||||
openDrawer(new State());
|
||||
}
|
||||
|
||||
function openEditDrawer() {
|
||||
drawerTitle.value = '编辑字典类型';
|
||||
const { openDrawer } = createDrawerRef.value;
|
||||
openDrawer(formParams);
|
||||
openDrawer(formParams.value);
|
||||
}
|
||||
|
||||
function selectedTree(keys, opts) {
|
||||
@@ -172,7 +163,7 @@
|
||||
const treeItem = opts[0];
|
||||
treeItemKey.value = keys;
|
||||
treeItemTitle.value = treeItem.label;
|
||||
Object.assign(formParams, treeItem);
|
||||
formParams.value = unref(treeItem);
|
||||
isEditMenu.value = true;
|
||||
checkedId.value = treeItem.id;
|
||||
} else {
|
||||
@@ -189,14 +180,11 @@
|
||||
positiveText: '确定',
|
||||
negativeText: '取消',
|
||||
onPositiveClick: () => {
|
||||
DeleteDict({ ...formParams }).then(async (_res) => {
|
||||
DeleteDict(formParams.value).then(async (_res) => {
|
||||
message.success('操作成功');
|
||||
await loadData();
|
||||
});
|
||||
},
|
||||
onNegativeClick: () => {
|
||||
message.error('已取消');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -208,14 +196,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await loadData();
|
||||
});
|
||||
|
||||
async function loadData() {
|
||||
const treeMenuList = await getDictTree();
|
||||
const keys = treeMenuList.list.map((item) => item.key);
|
||||
Object.assign(formParams, keys);
|
||||
Object.assign(formParams.value, keys);
|
||||
treeData.value = [];
|
||||
optionTreeData.value = [];
|
||||
treeData.value = treeMenuList.list;
|
||||
@@ -226,4 +210,8 @@
|
||||
function onExpandedKeys(keys) {
|
||||
expandedKeys.value = keys;
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await loadData();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
<n-select
|
||||
:render-tag="renderTag"
|
||||
v-model:value="formParams.listClass"
|
||||
:options="labelOptions"
|
||||
:options="dict.getOptionUnRef('tagTypeOptions')"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="字典键值" path="value">
|
||||
@@ -72,7 +72,7 @@
|
||||
<n-form-item label="状态" path="status">
|
||||
<n-radio-group v-model:value="formParams.status" name="status">
|
||||
<n-radio-button
|
||||
v-for="status in statusOptions"
|
||||
v-for="status in dict.getOptionUnRef('sys_normal_disable')"
|
||||
:key="status.value"
|
||||
:value="status.value"
|
||||
:label="status.label"
|
||||
@@ -103,17 +103,17 @@
|
||||
import { getDataList, getDictSelect, EditData, DeleteData } from '@/api/dict/dict';
|
||||
import { columns } from './columns';
|
||||
import { PlusOutlined } from '@vicons/antd';
|
||||
import { statusOptions } from '@/enums/optionsiEnum';
|
||||
import { TypeSelect } from '@/api/sys/config';
|
||||
import { Option } from '@/utils/hotgo';
|
||||
import { findTreeNode } from '@/utils';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { defRangeShortcuts } from '@/utils/dateUtil';
|
||||
import { Option, useDictStore } from '@/store/modules/dict';
|
||||
import { State } from '@/views/system/dict/model';
|
||||
|
||||
interface Props {
|
||||
checkedId?: number;
|
||||
}
|
||||
|
||||
const dict = useDictStore();
|
||||
const props = withDefaults(defineProps<Props>(), { checkedId: 0 });
|
||||
const typeList = ref<any>([]);
|
||||
const rules = {
|
||||
@@ -162,53 +162,22 @@
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
type: option.type as 'success' | 'warning' | 'error' | 'info' | 'primary' | 'default',
|
||||
type: option.listClass as 'success' | 'warning' | 'error' | 'info' | 'primary' | 'default',
|
||||
},
|
||||
{ default: () => option.label }
|
||||
);
|
||||
};
|
||||
|
||||
const labelOptions = ref([
|
||||
{
|
||||
label: '绿色',
|
||||
value: 'success',
|
||||
type: 'success',
|
||||
},
|
||||
{
|
||||
label: '橙色',
|
||||
value: 'warning',
|
||||
type: 'warning',
|
||||
},
|
||||
{
|
||||
label: '红色',
|
||||
value: 'error',
|
||||
type: 'error',
|
||||
},
|
||||
{
|
||||
label: '蓝色',
|
||||
value: 'info',
|
||||
type: 'info',
|
||||
},
|
||||
{
|
||||
label: '灰色',
|
||||
value: 'default',
|
||||
type: 'default',
|
||||
},
|
||||
{
|
||||
label: '主题色',
|
||||
value: 'primary',
|
||||
type: 'primary',
|
||||
},
|
||||
]);
|
||||
|
||||
const formRef: any = ref(null);
|
||||
const message = useMessage();
|
||||
const dialog = useDialog();
|
||||
const actionRef = ref();
|
||||
const showModal = ref(false);
|
||||
const formBtnLoading = ref(false);
|
||||
const formParams = ref<any>({ typeId: 0 });
|
||||
const formParams = ref<State>(new State());
|
||||
const options = ref<Option>();
|
||||
const typeId = ref(0);
|
||||
|
||||
const params = ref({
|
||||
pageSize: 10,
|
||||
typeId: props.checkedId,
|
||||
@@ -217,7 +186,7 @@
|
||||
});
|
||||
|
||||
const actionColumn = reactive({
|
||||
width: 120,
|
||||
width: 140,
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
fixed: 'right',
|
||||
@@ -246,16 +215,10 @@
|
||||
|
||||
function addTable() {
|
||||
showModal.value = true;
|
||||
formParams.value = {
|
||||
typeId: props.checkedId,
|
||||
label: '',
|
||||
value: '',
|
||||
listClass: 'default',
|
||||
valueType: 'string',
|
||||
sort: 0,
|
||||
status: 1,
|
||||
remark: '',
|
||||
};
|
||||
formParams.value = new State();
|
||||
if (typeId.value > 0) {
|
||||
formParams.value.typeId = typeId.value;
|
||||
}
|
||||
}
|
||||
|
||||
const loadDataTable = async (res) => {
|
||||
@@ -272,25 +235,26 @@
|
||||
|
||||
function confirmForm(e) {
|
||||
e.preventDefault();
|
||||
formBtnLoading.value = true;
|
||||
|
||||
formRef.value.validate((errors) => {
|
||||
if (!errors) {
|
||||
EditData(formParams.value).then((_res) => {
|
||||
message.success('操作成功');
|
||||
setTimeout(() => {
|
||||
formBtnLoading.value = true;
|
||||
EditData(formParams.value)
|
||||
.then((_res) => {
|
||||
message.success('操作成功');
|
||||
showModal.value = false;
|
||||
reloadTable();
|
||||
})
|
||||
.finally(() => {
|
||||
formBtnLoading.value = false;
|
||||
});
|
||||
});
|
||||
} else {
|
||||
message.error('请填写完整信息');
|
||||
}
|
||||
formBtnLoading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
function handleDelete(record: Recordable) {
|
||||
console.log('点击了删除', record);
|
||||
dialog.warning({
|
||||
title: '警告',
|
||||
content: '你确定要删除?',
|
||||
@@ -307,7 +271,7 @@
|
||||
|
||||
function handleEdit(record: Recordable) {
|
||||
showModal.value = true;
|
||||
formParams.value = cloneDeep(record);
|
||||
formParams.value = cloneDeep(record) as unknown as State;
|
||||
}
|
||||
|
||||
function handleSubmit(_values: Recordable) {
|
||||
@@ -316,16 +280,10 @@
|
||||
|
||||
function handleReset(_values: Recordable) {
|
||||
params.value.label = '';
|
||||
params.value.value = '';
|
||||
reloadTable();
|
||||
}
|
||||
|
||||
watch(props, (newVal, _oldVal) => {
|
||||
params.value.typeId = newVal.checkedId;
|
||||
formParams.value.typeId = newVal.checkedId;
|
||||
actionRef.value.reload();
|
||||
setDictSelect();
|
||||
});
|
||||
|
||||
async function setDictSelect() {
|
||||
const tmp = await getDictSelect({});
|
||||
typeList.value = tmp.list;
|
||||
@@ -344,13 +302,23 @@
|
||||
formParams.value.type = row.type;
|
||||
}
|
||||
|
||||
async function loadOptions() {
|
||||
options.value = await TypeSelect();
|
||||
function loadOptions() {
|
||||
dict.loadOptions(['sys_normal_disable']);
|
||||
TypeSelect().then((res) => {
|
||||
options.value = res;
|
||||
});
|
||||
}
|
||||
|
||||
watch(props, (newVal, _oldVal) => {
|
||||
params.value.typeId = newVal.checkedId;
|
||||
typeId.value = newVal.checkedId;
|
||||
actionRef.value.reload();
|
||||
setDictSelect();
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
loadOptions();
|
||||
await setDictSelect();
|
||||
await loadOptions();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
18
web/src/views/system/dict/model.ts
Normal file
18
web/src/views/system/dict/model.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
export class State {
|
||||
typeId = 0;
|
||||
key = '';
|
||||
id = 0;
|
||||
label = '';
|
||||
value = '';
|
||||
valueType = 'string';
|
||||
type = '';
|
||||
listClass = 'primary';
|
||||
isDefault = 0;
|
||||
sort = 0;
|
||||
remark = '';
|
||||
status = 1;
|
||||
createdAt = '';
|
||||
updatedAt = '';
|
||||
pid: number | null = 0;
|
||||
name = '';
|
||||
}
|
||||
@@ -44,7 +44,7 @@
|
||||
</n-gi>
|
||||
<n-gi span="1">
|
||||
<n-form-item label="状态" path="status">
|
||||
<n-select v-model:value="formValue.status" :options="options.sys_normal_disable" />
|
||||
<n-select v-model:value="formValue.status" :options="dict.getOptionUnRef('sys_normal_disable')" />
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
<n-gi span="2">
|
||||
@@ -72,8 +72,9 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import { Edit, View, MaxSort } from '@/api/testCategory';
|
||||
import { options, State, newState, rules } from './model';
|
||||
import { State, newState, rules } from './model';
|
||||
import { useProjectSettingStore } from '@/store/modules/projectSetting';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { adaModalWidth } from '@/utils/hotgo';
|
||||
@@ -81,6 +82,7 @@
|
||||
const emit = defineEmits(['reloadTable']);
|
||||
const message = useMessage();
|
||||
const settingStore = useProjectSettingStore();
|
||||
const dict = useDictStore();
|
||||
const loading = ref(false);
|
||||
const showModal = ref(false);
|
||||
const formValue = ref<State>(newState(null));
|
||||
@@ -119,25 +121,28 @@
|
||||
});
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
function confirmForm(e) {
|
||||
e.preventDefault();
|
||||
formBtnLoading.value = true;
|
||||
formRef.value.validate((errors) => {
|
||||
if (!errors) {
|
||||
Edit(formValue.value).then((_res) => {
|
||||
message.success('操作成功');
|
||||
setTimeout(() => {
|
||||
formBtnLoading.value = true;
|
||||
Edit(formValue.value)
|
||||
.then((_res) => {
|
||||
message.success('操作成功');
|
||||
closeForm();
|
||||
emit('reloadTable');
|
||||
})
|
||||
.finally(() => {
|
||||
formBtnLoading.value = false;
|
||||
});
|
||||
});
|
||||
} else {
|
||||
message.error('请填写完整信息');
|
||||
}
|
||||
formBtnLoading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
// 关闭表单
|
||||
function closeForm() {
|
||||
showModal.value = false;
|
||||
loading.value = false;
|
||||
|
||||
@@ -42,10 +42,11 @@
|
||||
import { BasicTable, TableAction } from '@/components/Table';
|
||||
import { BasicForm, useForm } from '@/components/Form/index';
|
||||
import { usePermission } from '@/hooks/web/usePermission';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import { List, Delete, Status } from '@/api/testCategory';
|
||||
import { PlusOutlined, DeleteOutlined } from '@vicons/antd';
|
||||
import { columns, schemas, options, loadOptions } from './model';
|
||||
import { adaTableScrollX, getOptionLabel } from '@/utils/hotgo';
|
||||
import { columns, schemas, loadOptions } from './model';
|
||||
import { adaTableScrollX } from '@/utils/hotgo';
|
||||
import Edit from './edit.vue';
|
||||
|
||||
const dialog = useDialog();
|
||||
@@ -54,6 +55,7 @@
|
||||
const actionRef = ref();
|
||||
const searchFormRef = ref<any>({});
|
||||
const editRef = ref();
|
||||
const dict = useDictStore();
|
||||
|
||||
const checkedIds = ref([]);
|
||||
|
||||
@@ -175,7 +177,7 @@
|
||||
// 修改状态
|
||||
function handleStatus(record: Recordable, status: number) {
|
||||
Status({ id: record.id, status: status }).then((_res) => {
|
||||
message.success('设为' + getOptionLabel(options.value.sys_normal_disable, status) + '成功');
|
||||
message.success('设为' + dict.getLabel('sys_normal_disable', status) + '成功');
|
||||
setTimeout(() => {
|
||||
reloadTable();
|
||||
});
|
||||
@@ -184,6 +186,7 @@
|
||||
|
||||
onMounted(() => {
|
||||
loadOptions();
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -2,10 +2,12 @@ import { h, ref } from 'vue';
|
||||
import { NTag } from 'naive-ui';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { FormSchema } from '@/components/Form';
|
||||
import { Dicts } from '@/api/dict/dict';
|
||||
import { isNullObject } from '@/utils/is';
|
||||
import { defRangeShortcuts } from '@/utils/dateUtil';
|
||||
import { Option, getOptionLabel, getOptionTag } from '@/utils/hotgo';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import type { FormRules } from 'naive-ui/es/form/src/interface';
|
||||
|
||||
const dict = useDictStore();
|
||||
|
||||
export class State {
|
||||
public id = 0; // 分类ID
|
||||
@@ -37,7 +39,7 @@ export function newState(state: State | Record<string, any> | null): State {
|
||||
}
|
||||
|
||||
// 表单验证规则
|
||||
export const rules = {
|
||||
export const rules: FormRules = {
|
||||
name: {
|
||||
required: true,
|
||||
trigger: ['blur', 'input'],
|
||||
@@ -83,7 +85,7 @@ export const schemas = ref<FormSchema[]>([
|
||||
defaultValue: null,
|
||||
componentProps: {
|
||||
placeholder: '请选择状态',
|
||||
options: [],
|
||||
options: dict.getOption('sys_normal_disable'),
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
@@ -145,11 +147,11 @@ export const columns = [
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: getOptionTag(options.value.sys_normal_disable, row.status),
|
||||
type: dict.getType('sys_normal_disable', row.status),
|
||||
bordered: false,
|
||||
},
|
||||
{
|
||||
default: () => getOptionLabel(options.value.sys_normal_disable, row.status),
|
||||
default: () => dict.getLabel('sys_normal_disable', row.status),
|
||||
}
|
||||
);
|
||||
},
|
||||
@@ -162,23 +164,7 @@ export const columns = [
|
||||
},
|
||||
];
|
||||
|
||||
// 字典数据选项
|
||||
export const options = ref({
|
||||
sys_normal_disable: [] as Option[],
|
||||
});
|
||||
|
||||
// 加载字典数据选项
|
||||
export function loadOptions() {
|
||||
Dicts({
|
||||
types: ['sys_normal_disable'],
|
||||
}).then((res) => {
|
||||
options.value = res;
|
||||
for (const item of schemas.value) {
|
||||
switch (item.field) {
|
||||
case 'status':
|
||||
item.componentProps.options = options.value.sys_normal_disable;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
dict.loadOptions(['sys_normal_disable']);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user