This commit is contained in:
孟帅
2024-07-21 22:21:02 +08:00
parent 7d8330f72f
commit a37d088360
440 changed files with 6303 additions and 3339 deletions

View File

@@ -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);

View File

@@ -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>

View File

@@ -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();

View File

@@ -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);

View File

@@ -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();

View File

@@ -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']);
}

View File

@@ -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);

View File

@@ -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>

View File

@@ -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();
});

View File

@@ -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();

View File

@@ -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();

View File

@@ -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>

View File

@@ -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']);
}

View File

@@ -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>

View File

@@ -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);

View File

@@ -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>

View File

@@ -183,9 +183,6 @@
reloadTable();
});
},
onNegativeClick: () => {
// message.error('取消');
},
});
}

View File

@@ -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();

View File

@@ -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('请填写完整信息');
}

View File

@@ -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>

View File

@@ -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();

View File

@@ -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>

View File

@@ -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();

View File

@@ -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);

View File

@@ -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;
});
}

View File

@@ -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>

View File

@@ -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('取消');
},
});
}

View File

@@ -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();

View File

@@ -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>

View File

@@ -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>

View File

@@ -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']);
}

View File

@@ -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>

View File

@@ -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({

View File

@@ -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>

View File

@@ -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();

View File

@@ -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>

View File

@@ -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']);
}

View File

@@ -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;

View File

@@ -83,7 +83,7 @@
const checkedIds = ref([]);
const actionColumn = reactive({
width: 180,
width: 160,
title: '操作',
key: 'action',
fixed: 'right',

View File

@@ -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']);
}

View File

@@ -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>

View File

@@ -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);
},
},
{

View File

@@ -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>

View File

@@ -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);

View File

@@ -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>

View File

@@ -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();

View File

@@ -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>

View File

@@ -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();

View File

@@ -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;

View File

@@ -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>

View File

@@ -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']);
}
// 关系树选项

View File

@@ -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>

View File

@@ -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,
});

View File

@@ -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 = [];

View File

@@ -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']);
}
// 关系树选项

View File

@@ -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>

View File

@@ -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));

View File

@@ -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']);
}
// 关系树选项

View File

@@ -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>

View File

@@ -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;
}

View File

@@ -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> {

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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']);
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View 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 = '';
}

View File

@@ -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;

View File

@@ -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>

View File

@@ -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']);
}