refactor(系统管理): 组织模板页面重构&级联对接接口
This commit is contained in:
parent
3e29ff80d2
commit
347d548fa9
|
@ -2,12 +2,20 @@ import MSR from '@/api/http/index';
|
|||
import {
|
||||
DeletePluginUrl,
|
||||
GetPluginListUrl,
|
||||
GetPluginOptionsUrl,
|
||||
GetScriptUrl,
|
||||
UpdatePluginUrl,
|
||||
UploadPluginUrl,
|
||||
} from '@/api/requrls/setting/plugin';
|
||||
|
||||
import type { AddReqData, PluginItem, PluginList, UpdatePluginModel, UploadFile } from '@/models/setting/plugin';
|
||||
import type {
|
||||
AddReqData,
|
||||
OptionsParams,
|
||||
PluginItem,
|
||||
PluginList,
|
||||
UpdatePluginModel,
|
||||
UploadFile,
|
||||
} from '@/models/setting/plugin';
|
||||
|
||||
export function getPluginList() {
|
||||
return MSR.get<PluginList>({ url: GetPluginListUrl });
|
||||
|
@ -24,3 +32,8 @@ export function deletePluginReq(id: string) {
|
|||
export function getScriptDetail(pluginId: string, scriptId: string) {
|
||||
return MSR.get({ url: GetScriptUrl, params: `${pluginId}/${scriptId}` });
|
||||
}
|
||||
|
||||
// 获取插件下拉选项级联统一接口
|
||||
export function getPluginOptions(data: OptionsParams) {
|
||||
return MSR.post<{ text: string; value: string }[]>({ url: GetPluginOptionsUrl, data });
|
||||
}
|
||||
|
|
|
@ -46,8 +46,12 @@ export function updateOrganizeTemplateInfo(data: ActionTemplateManage) {
|
|||
return MSR.post({ url: `${UpdateOrganizeTemplateUrl}`, data });
|
||||
}
|
||||
// 是否启用组织XX模板
|
||||
export function isEnableTemplate(organizationId: string, scene: string) {
|
||||
return MSR.get<boolean>({ url: `${isEnableTemplateUrl}/${organizationId}/${scene}` });
|
||||
export function isEnableTemplate(organizationId: string) {
|
||||
return MSR.get<Record<string, boolean>>({ url: `${isEnableTemplateUrl}/${organizationId}` });
|
||||
}
|
||||
// 删除模板
|
||||
export function deleteOrdTemplate(id: string) {
|
||||
return MSR.get({ url: `${DeleteOrganizeTemplateUrl}/${id}` });
|
||||
}
|
||||
|
||||
/** *
|
||||
|
|
|
@ -3,3 +3,4 @@ export const UploadPluginUrl = '/plugin/add';
|
|||
export const UpdatePluginUrl = '/plugin/update';
|
||||
export const DeletePluginUrl = '/plugin/delete';
|
||||
export const GetScriptUrl = '/plugin/script/get';
|
||||
export const GetPluginOptionsUrl = '/plugin/options';
|
||||
|
|
|
@ -30,7 +30,7 @@ export const DeleteOrganizeTemplateUrl = '/organization/template/delete';
|
|||
// 关闭组织模板,开启项目模版
|
||||
export const EnableOrOffTemplateUrl = '/organization/template/disable';
|
||||
// 是否启用组织模板
|
||||
export const isEnableTemplateUrl = '/organization/template/is-enable';
|
||||
export const isEnableTemplateUrl = '/organization/template/enable/config';
|
||||
|
||||
// 系统设置-组织-自定义字段
|
||||
|
||||
|
|
|
@ -359,6 +359,9 @@
|
|||
border: 1px solid var(--color-text-input-border);
|
||||
}
|
||||
}
|
||||
.arco-checkbox-disabled.arco-checkbox-checked .arco-checkbox-icon {
|
||||
background: rgb(var(--primary-2)) !important ;
|
||||
}
|
||||
|
||||
/** radio **/
|
||||
.arco-radio-group-button {
|
||||
|
|
|
@ -20,6 +20,7 @@ export const SELECT = {
|
|||
multiple: false,
|
||||
placeholder: '请选择',
|
||||
options: [],
|
||||
modelValue: '',
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -33,6 +34,7 @@ export const MULTIPLE_SELECT = {
|
|||
multiple: true,
|
||||
placeholder: '请选择',
|
||||
options: [],
|
||||
modelValue: [],
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -61,6 +63,7 @@ export const MEMBER = {
|
|||
props: {
|
||||
multiple: false,
|
||||
placeholder: '请选择',
|
||||
modelValue: '',
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -74,6 +77,7 @@ export const MULTIPLE_MEMBER = {
|
|||
multiple: true,
|
||||
placeholder: '请选择',
|
||||
options: [],
|
||||
modelValue: [],
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<FormCreate v-model:api="formApi" :rule="formRules" :option="props.options || option"></FormCreate>
|
||||
<FormCreate v-model:api="formApi" :rule="formRuleList" :option="props.options || option"></FormCreate>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
@ -16,7 +16,7 @@
|
|||
|
||||
import type { FormItem } from './types';
|
||||
import { FormRuleItem } from './types';
|
||||
import formCreate, { FormRule } from '@form-create/arco-design';
|
||||
import formCreate from '@form-create/arco-design';
|
||||
|
||||
const formCreateStore = useFormCreateStore();
|
||||
|
||||
|
@ -49,9 +49,9 @@
|
|||
formCreateKey: FormCreateKeyEnum[keyof FormCreateKeyEnum]; // 唯一表单Key
|
||||
}>();
|
||||
|
||||
const formApi = ref<any>({});
|
||||
const emit = defineEmits(['update:form-rule']);
|
||||
|
||||
const formRules = ref<FormRule | undefined>([]);
|
||||
const formApi = ref<any>({});
|
||||
|
||||
// 计算被级联的项
|
||||
const cascadeItem = computed(() => {
|
||||
|
@ -97,11 +97,62 @@
|
|||
);
|
||||
|
||||
watchEffect(() => {
|
||||
formCreateStore.setInitFormCreate(props.formCreateKey, props.formRule);
|
||||
formCreateStore.initFormCreateFormRules(props.formCreateKey);
|
||||
formRules.value = formCreateStore.formCreateRuleMap.get(props.formCreateKey);
|
||||
// formRules.value = cloneDeep(props.formRule);
|
||||
// formCreateStore.setInitFormCreate(props.formCreateKey, props.formRule);
|
||||
// formCreateStore.initFormCreateFormRules(props.formCreateKey);
|
||||
});
|
||||
|
||||
const formRuleList = ref<FormRuleItem[]>([]); // 存放转换格式后
|
||||
const formRules = ref<FormItem[]>([]);
|
||||
watch(
|
||||
() => props.formRule,
|
||||
(val) => {
|
||||
formRules.value = props.formRule;
|
||||
formCreateStore.setInitFormCreate(props.formCreateKey, props.formRule);
|
||||
formCreateStore.initFormCreateFormRules(props.formCreateKey);
|
||||
formRuleList.value = formCreateStore.formCreateRuleMap.get(props.formCreateKey) as FormRuleItem[];
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
|
||||
const formData = computed(() => {
|
||||
return formCreateStore.formRuleMap.get(props.formCreateKey);
|
||||
});
|
||||
|
||||
watch(
|
||||
() => formData.value,
|
||||
(val) => {
|
||||
formRuleList.value = formCreateStore.formCreateRuleMap.get(props.formCreateKey) as FormRuleItem[];
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => formRuleList.value,
|
||||
() => {
|
||||
// 处理数据格式更新
|
||||
const result = formRuleList.value.map((item: any) => {
|
||||
const type = props.formRule.find((it) => it.name === item.field)?.type;
|
||||
const formItemRule = {
|
||||
name: item.field,
|
||||
type,
|
||||
label: item.title,
|
||||
value: item.value,
|
||||
required: item?.effect?.required,
|
||||
inputSearch: item.props.inputSearch || false,
|
||||
instructionsIcon: item.props.instructionsIcon || '',
|
||||
optionMethod: item.props.optionMethod || '',
|
||||
couplingConfig: {
|
||||
type: item.props.couplingConfig.type,
|
||||
cascade: item.link,
|
||||
},
|
||||
};
|
||||
return formItemRule;
|
||||
});
|
||||
formCreateStore.setInitFormCreate(props.formCreateKey, result as FormItem[]);
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
defineExpose({
|
||||
formApi, // 对外暴漏用于表单校验和清除校验状态 具体参考form-create文档API
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<a-select
|
||||
v-model="selectValue"
|
||||
v-model:model-value="selectValue"
|
||||
:placeholder="t(props.placeholder || 'common.pleaseSelect')"
|
||||
allow-search
|
||||
:multiple="props.multiple"
|
||||
|
@ -14,7 +14,18 @@
|
|||
import { ref } from 'vue';
|
||||
import { debounce } from 'lodash-es';
|
||||
|
||||
import { getPluginOptions } from '@/api/modules/setting/pluginManger';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { useAppStore } from '@/store';
|
||||
import useFormCreateStore from '@/store/modules/form-create/form-create';
|
||||
|
||||
import type { OptionsParams } from '@/models/setting/plugin';
|
||||
import { FormCreateKeyEnum } from '@/enums/formCreateEnum';
|
||||
|
||||
const appStore = useAppStore();
|
||||
|
||||
const attrs = useAttrs();
|
||||
const formCreateStore = useFormCreateStore();
|
||||
|
||||
const { t } = useI18n();
|
||||
const props = withDefaults(
|
||||
|
@ -35,54 +46,70 @@
|
|||
);
|
||||
|
||||
const emit = defineEmits(['update:model-value']);
|
||||
const selectValue = ref([]);
|
||||
const selectValue = ref<string[] | string>();
|
||||
|
||||
const optionsList = ref<{ label: string; value: string }[]>([]);
|
||||
|
||||
// 内部的关键词
|
||||
const innerKeyword = ref<string | undefined>('');
|
||||
async function getOptionsList() {
|
||||
if (props.inputSearch && props.optionMethod) {
|
||||
const params = ref<OptionsParams>();
|
||||
|
||||
async function getLinksItem() {
|
||||
const { formKey } = attrs;
|
||||
const formRulesList = formCreateStore.formRuleMap.get(formKey as FormCreateKeyEnum[keyof FormCreateKeyEnum]);
|
||||
if (formRulesList && props.optionMethod) {
|
||||
params.value = {
|
||||
pluginId: props.keyword as string,
|
||||
organizationId: appStore.currentOrgId,
|
||||
projectConfig: formRulesList,
|
||||
optionMethod: props.optionMethod,
|
||||
};
|
||||
// 请求参数
|
||||
// console.log(selectValue.value, props.keyword, props.modelValue);
|
||||
try {
|
||||
setTimeout(() => {
|
||||
// console.log('模拟请求');
|
||||
optionsList.value = [
|
||||
{
|
||||
value: '111',
|
||||
label: '测试测试测试111111',
|
||||
},
|
||||
];
|
||||
}, 1000);
|
||||
const res = await getPluginOptions(params.value);
|
||||
optionsList.value = res.map((item) => {
|
||||
return {
|
||||
label: item.text,
|
||||
value: item.value,
|
||||
};
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
const searchHandler = debounce(async (inputVal: string) => {
|
||||
// 内部的关键词
|
||||
const innerKeyword = ref<string | undefined>('');
|
||||
const searchHandler = debounce((inputVal: string) => {
|
||||
innerKeyword.value = inputVal;
|
||||
getOptionsList();
|
||||
}, 300);
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(val) => {
|
||||
selectValue.value = val as any;
|
||||
}
|
||||
if (val) {
|
||||
selectValue.value = val as any;
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.keyword,
|
||||
(val) => {
|
||||
if (val) {
|
||||
innerKeyword.value = val;
|
||||
getOptionsList();
|
||||
if (props.inputSearch && props.optionMethod) {
|
||||
getLinksItem();
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => selectValue.value,
|
||||
(val) => {
|
||||
emit('update:model-value', val);
|
||||
async (val) => {
|
||||
selectValue.value = val;
|
||||
await emit('update:model-value', val);
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -18,7 +18,8 @@ export type FormItemType =
|
|||
| 'MULTIPLE_INPUT'
|
||||
| 'INT'
|
||||
| 'FLOAT'
|
||||
| 'NUMBER';
|
||||
| 'NUMBER'
|
||||
| undefined;
|
||||
|
||||
// 表单选项
|
||||
export interface FormItemComplexCommonConfig {
|
||||
|
@ -51,10 +52,10 @@ export interface FormItem {
|
|||
// 表单联动配置
|
||||
couplingConfig?: {
|
||||
// 联动类型,visible:显示隐藏,disabled:禁用启用,filterOptions:过滤选项,disabledOptions:禁用选项,initOptions:初始化选项。都由联动的表单项触发
|
||||
type: 'visible' | 'disabled' | 'filterOptions' | 'disabledOptions' | 'initOptions'; // 目前初始化选项
|
||||
cascade: string; // 联动表单项名称
|
||||
matchRule: 'same' | 'includes' | 'excludes' | RegExp; // 联动匹配规则,same:值相同,includes:值包含,excludes:值不包含, RegExp:自定义匹配正则表达式 // 场景 目前只考虑等于情况
|
||||
}[];
|
||||
type?: 'initOptions'; // 目前初始化选项
|
||||
cascade?: string; // 联动表单项名称
|
||||
matchRule?: 'same' | 'includes' | 'excludes' | RegExp; // 联动匹配规则,same:值相同,includes:值包含,excludes:值不包含, RegExp:自定义匹配正则表达式 // 场景 目前只考虑等于情况
|
||||
};
|
||||
// 表单布局
|
||||
wrap?: Record<string, any>;
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ export default {
|
|||
'menu.settings.organization.templateFieldSetting': '字段设置',
|
||||
'menu.settings.organization.templateManagementList': '模版列表',
|
||||
'menu.settings.organization.templateManagementDetail': '创建模版',
|
||||
'menu.settings.organization.templateManagementCopy': '复制模版',
|
||||
'menu.settings.organization.templateManagementEdit': '更新模板',
|
||||
'menu.settings.organization.log': '日志',
|
||||
'navbar.action.locale': '切换为中文',
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { FormItem } from '@/components/pure/ms-form-create/types';
|
||||
|
||||
export interface organizationItem {
|
||||
id?: string;
|
||||
num: number;
|
||||
|
@ -92,3 +94,11 @@ export interface DrawerReqParams {
|
|||
export interface PluginState {
|
||||
doNotShowAgain: boolean;
|
||||
}
|
||||
|
||||
// 定义统一插件下拉选项请求参数
|
||||
export interface OptionsParams {
|
||||
pluginId: string;
|
||||
organizationId: string;
|
||||
optionMethod: string;
|
||||
projectConfig: Record<string, any>[] | FormItem[];
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ export interface DefinedFieldItem {
|
|||
required?: boolean | undefined;
|
||||
fApi?: any; // 表单值
|
||||
formRules?: FormRuleItem[] | FormItem[] | FormRule[]; // 表单列表
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
// 创建自定义字段
|
||||
|
@ -67,6 +68,7 @@ export interface AddOrUpdateField {
|
|||
remark: string; // 备注
|
||||
scopeId: string; // 组织或项目ID
|
||||
options?: FieldOption[];
|
||||
enableOptionKey: boolean;
|
||||
}
|
||||
|
||||
export interface fieldIconAndNameModal {
|
||||
|
@ -98,7 +100,7 @@ export interface CustomField {
|
|||
fieldId: string;
|
||||
required: boolean; // 是否必填
|
||||
apiFieldId: string; // api字段名
|
||||
defaultValue: string; // 默认值
|
||||
defaultValue: string | string[] | null | number; // 默认值
|
||||
}
|
||||
|
||||
export interface ActionTemplateManage {
|
||||
|
@ -107,6 +109,6 @@ export interface ActionTemplateManage {
|
|||
remark: string;
|
||||
scopeId: string;
|
||||
enableThirdPart?: boolean; // 是否开启api字段名配置
|
||||
scene: SeneType;
|
||||
customFields: CustomField[];
|
||||
scene?: SeneType;
|
||||
customFields?: CustomField[];
|
||||
}
|
||||
|
|
|
@ -232,7 +232,7 @@ const Setting: AppRouteRecordRaw = {
|
|||
},
|
||||
// 模板列表-模板管理-创建&编辑模版
|
||||
{
|
||||
path: 'templateManagementDetail',
|
||||
path: 'templateManagementDetail/:mode?',
|
||||
name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT_DETAIL,
|
||||
component: () => import('@/views/setting/organization/template/components/templateDetail.vue'),
|
||||
meta: {
|
||||
|
|
|
@ -28,7 +28,7 @@ const useFormCreateStore = defineStore('form-create', {
|
|||
// 当前类型
|
||||
let fieldType;
|
||||
const currentTypeForm = Object.keys(FieldTypeFormRules).find(
|
||||
(formItemType: any) => item.type.toUpperCase() === formItemType
|
||||
(formItemType: any) => item.type?.toUpperCase() === formItemType
|
||||
);
|
||||
if (currentTypeForm) {
|
||||
fieldType = FieldTypeFormRules[currentTypeForm].type;
|
||||
|
@ -39,17 +39,18 @@ const useFormCreateStore = defineStore('form-create', {
|
|||
value: optionsItem.value,
|
||||
};
|
||||
});
|
||||
return {
|
||||
const ruleItem = {
|
||||
type: fieldType, // 表单类型
|
||||
field: item.name, // 字段
|
||||
title: item.label, // label 表单标签
|
||||
value: FieldTypeFormRules[currentTypeForm].value, // 目前的值
|
||||
value: item.value || FieldTypeFormRules[currentTypeForm].value, // 目前的值
|
||||
effect: {
|
||||
required: item.required, // 是否必填
|
||||
},
|
||||
// 级联关联到某一个form上 可能存在多个级联
|
||||
options: !item.optionMethod ? currentOptions : [],
|
||||
link: item.couplingConfig?.map((cascadeItem: any) => cascadeItem.cascade),
|
||||
// link: item.couplingConfig?.map((cascadeItem: any) => cascadeItem.cascade),
|
||||
link: item.couplingConfig?.cascade,
|
||||
rule: item.validate || [],
|
||||
// 梳理表单所需要属性
|
||||
props: {
|
||||
|
@ -67,8 +68,18 @@ const useFormCreateStore = defineStore('form-create', {
|
|||
'keyword': '',
|
||||
'modelValue': item.value,
|
||||
'options': currentOptions,
|
||||
'formKey': key,
|
||||
},
|
||||
};
|
||||
// 如果不存在关联name删除link关联属性
|
||||
if (ruleItem.link === '') {
|
||||
delete ruleItem.link;
|
||||
}
|
||||
// 如果不是等于下拉多选或者单选等
|
||||
if (ruleItem.type !== 'SearchSelect') {
|
||||
delete ruleItem.props.inputSearch;
|
||||
}
|
||||
return ruleItem;
|
||||
}
|
||||
return {};
|
||||
});
|
||||
|
|
|
@ -2,35 +2,31 @@ import { defineStore } from 'pinia';
|
|||
|
||||
import { isEnableTemplate } from '@/api/modules/setting/template';
|
||||
|
||||
import type { DefinedFieldItem } from '@/models/setting/template';
|
||||
|
||||
import useAppStore from '../app';
|
||||
|
||||
const appStore = useAppStore();
|
||||
|
||||
const useTemplateStore = defineStore('template', {
|
||||
persist: true,
|
||||
state: (): { templateStatus: Record<string, boolean>; previewList: DefinedFieldItem[] } => ({
|
||||
state: (): {
|
||||
templateStatus: Record<string, boolean>;
|
||||
} => ({
|
||||
templateStatus: {
|
||||
FUNCTIONAL: false,
|
||||
API: false,
|
||||
UI: false,
|
||||
TEST_PLAN: false,
|
||||
BUG: false,
|
||||
FUNCTIONAL: true,
|
||||
API: true,
|
||||
UI: true,
|
||||
TEST_PLAN: true,
|
||||
BUG: true,
|
||||
},
|
||||
previewList: [],
|
||||
}),
|
||||
actions: {
|
||||
// 模板列表的状态
|
||||
setStatus() {
|
||||
// 需要调整接口
|
||||
// const appStore = useAppStore();
|
||||
// Object.keys(this.templateStatus).forEach(async (item) => {
|
||||
// const sceneStatus = await isEnableTemplate(appStore.currentOrgId, item);
|
||||
// this.templateStatus[item] = sceneStatus;
|
||||
// });
|
||||
},
|
||||
// 预览存储表数据
|
||||
setPreviewHandler(filedData: DefinedFieldItem[]) {
|
||||
this.previewList = filedData;
|
||||
async getStatus() {
|
||||
try {
|
||||
this.templateStatus = await isEnableTemplate(appStore.currentOrgId);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -108,7 +108,7 @@
|
|||
} from '@/api/modules/project-management/projectMember';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useModal from '@/hooks/useModal';
|
||||
import { useTableStore, useUserStore } from '@/store';
|
||||
import { useAppStore, useTableStore } from '@/store';
|
||||
import { characterLimit } from '@/utils';
|
||||
|
||||
import type {
|
||||
|
@ -121,10 +121,10 @@
|
|||
|
||||
const { t } = useI18n();
|
||||
const { openModal } = useModal();
|
||||
const appStore = useAppStore();
|
||||
|
||||
const tableStore = useTableStore();
|
||||
const userStore = useUserStore();
|
||||
const lastProjectId = userStore?.$state?.lastProjectId;
|
||||
const lastProjectId = appStore.getCurrentProjectId;
|
||||
|
||||
const columns: MsTableColumn = [
|
||||
{
|
||||
|
@ -187,7 +187,6 @@
|
|||
|
||||
const handleTableSelect = (selectArr: (string | number)[]) => {
|
||||
tableSelected.value = selectArr;
|
||||
console.log(selectArr, 'selectArrselectArrselectArr');
|
||||
};
|
||||
|
||||
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector } = useTable(getProjectMemberList, {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div>项目版本 waiting for development </div>
|
||||
<MsFormCreate :form-rule="formRules" :form-create-key="FormCreateKeyEnum.ORGANIZE_TEMPLATE" />
|
||||
<MsFormCreate v-model:form-rule="formRules" :form-create-key="FormCreateKeyEnum.ORGANIZE_TEMPLATE" />
|
||||
<br />
|
||||
<br />
|
||||
</template>
|
||||
|
@ -15,14 +15,23 @@
|
|||
|
||||
const formRules = ref<FormItem[]>([
|
||||
{
|
||||
type: 'INPUT',
|
||||
type: 'SELECT',
|
||||
name: 'name',
|
||||
label: '姓名',
|
||||
value: '',
|
||||
subDesc: '请输入姓名',
|
||||
required: true,
|
||||
options: [
|
||||
{
|
||||
value: '1001',
|
||||
text: '单选',
|
||||
},
|
||||
{
|
||||
value: '1002',
|
||||
text: '多选',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
type: 'MULTIPLE_SELECT',
|
||||
name: 'gender',
|
||||
|
@ -32,13 +41,12 @@
|
|||
optionMethod: 'getGenderOptions',
|
||||
inputSearch: true,
|
||||
required: true,
|
||||
couplingConfig: [
|
||||
{
|
||||
type: 'initOptions',
|
||||
cascade: 'name',
|
||||
matchRule: 'includes',
|
||||
},
|
||||
],
|
||||
couplingConfig: {
|
||||
type: 'initOptions',
|
||||
cascade: 'name',
|
||||
matchRule: 'includes',
|
||||
},
|
||||
|
||||
options: [
|
||||
{
|
||||
value: '1',
|
||||
|
@ -51,7 +59,7 @@
|
|||
],
|
||||
},
|
||||
{
|
||||
type: 'INPUT',
|
||||
type: 'TEXTAREA',
|
||||
name: 'member',
|
||||
label: '成员',
|
||||
value: '',
|
||||
|
@ -76,7 +84,7 @@
|
|||
},
|
||||
{
|
||||
type: 'INT',
|
||||
name: 'birthday',
|
||||
name: 'birthday1',
|
||||
label: '出生日期',
|
||||
value: 0,
|
||||
subDesc: '请选择出生日期',
|
||||
|
@ -108,13 +116,11 @@
|
|||
text: '多选',
|
||||
},
|
||||
],
|
||||
couplingConfig: [
|
||||
{
|
||||
type: 'initOptions',
|
||||
cascade: 'member',
|
||||
matchRule: 'includes',
|
||||
},
|
||||
],
|
||||
couplingConfig: {
|
||||
type: 'initOptions',
|
||||
cascade: 'member',
|
||||
matchRule: 'includes',
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'SELECT',
|
||||
|
@ -134,13 +140,11 @@
|
|||
text: '多选',
|
||||
},
|
||||
],
|
||||
couplingConfig: [
|
||||
{
|
||||
type: 'initOptions',
|
||||
cascade: 'member',
|
||||
matchRule: 'includes',
|
||||
},
|
||||
],
|
||||
couplingConfig: {
|
||||
type: 'initOptions',
|
||||
cascade: 'member',
|
||||
matchRule: 'includes',
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
:title="t('system.orgTemplate.createField')"
|
||||
:ok-text="t('system.orgTemplate.save')"
|
||||
:ok-loading="drawerLoading"
|
||||
:width="800"
|
||||
width="65%"
|
||||
min-width="800px"
|
||||
unmount-on-close
|
||||
:show-continue="false"
|
||||
@confirm="handleDrawerConfirm"
|
||||
|
@ -15,78 +16,74 @@
|
|||
<div class="optional-field">
|
||||
<div class="optional-header">
|
||||
<div class="font-medium">{{ t('system.orgTemplate.optionalField') }}</div>
|
||||
<a-checkbox :model-value="checkedAll" :indeterminate="indeterminate" @change="handleChangeAll">
|
||||
<a-checkbox :model-value="isCheckedAll" :indeterminate="indeterminate" @change="handleChangeAll">
|
||||
<span class="font-medium text-[var(--color-text-3)]">{{ t('system.orgTemplate.selectAll') }}</span>
|
||||
</a-checkbox>
|
||||
</div>
|
||||
<div class="optional-panel p-4">
|
||||
<div class="mb-2 font-medium text-[var(--color-text-3)]">{{ t('system.orgTemplate.systemField') }}</div>
|
||||
<div>
|
||||
<a-checkbox-group v-model="selectSystemData">
|
||||
<a-grid :cols="4" :col-gap="16" :row-gap="4">
|
||||
<a-grid-item v-for="field in systemField" :key="field.id">
|
||||
<div>
|
||||
<a-checkbox-group v-model="selectSystemIds" class="checkboxContainer">
|
||||
<div v-for="field in systemField" :key="field.id" class="item checkbox">
|
||||
<a-checkbox :value="field.id" :disabled="field.internal"
|
||||
><a-tooltip :content="field.name">
|
||||
<div class="checkbox">{{ field.name }}</div></a-tooltip
|
||||
<div>{{ field.name }}</div></a-tooltip
|
||||
></a-checkbox
|
||||
>
|
||||
</a-grid-item>
|
||||
</a-grid>
|
||||
</a-checkbox-group>
|
||||
</div>
|
||||
</a-checkbox-group>
|
||||
</div>
|
||||
</div>
|
||||
<div class="my-2 mt-8 font-medium text-[var(--color-text-3)]">{{
|
||||
t('system.orgTemplate.customField')
|
||||
}}</div>
|
||||
<a-checkbox-group v-model="selectCustomField">
|
||||
<a-grid :cols="4" :col-gap="16" :row-gap="4">
|
||||
<a-grid-item v-for="field in customField" :key="field.id">
|
||||
<div>
|
||||
<a-checkbox-group v-model="selectCustomIds" class="checkboxContainer">
|
||||
<div v-for="field in customField" :key="field.id" class="item">
|
||||
<a-checkbox :value="field.id"
|
||||
><a-tooltip :content="field.name">
|
||||
<div class="checkbox">{{ field.name }}</div></a-tooltip
|
||||
></a-checkbox
|
||||
>
|
||||
</a-grid-item>
|
||||
</a-grid>
|
||||
</a-checkbox-group>
|
||||
</div>
|
||||
</a-checkbox-group>
|
||||
</div>
|
||||
<EditFieldDrawer ref="fieldDrawerRef" v-model:visible="showFieldDrawer" @success="okHandler" />
|
||||
<a-button class="mt-1 px-0" type="text" @click="createField">
|
||||
<template #icon>
|
||||
<icon-plus class="text-[14px]" />
|
||||
</template>
|
||||
{{ t('system.orgTemplate.addField') }}
|
||||
</a-button>
|
||||
<div>
|
||||
<a-button class="mt-1 px-0" type="text" :disabled="totalData.length > 20" @click="createField">
|
||||
<template #icon>
|
||||
<icon-plus class="text-[14px]" />
|
||||
</template>
|
||||
{{ t('system.orgTemplate.addField') }}
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="selected-field">
|
||||
<div class="selected-field w-[272px]">
|
||||
<div class="optional-header">
|
||||
<div class="font-medium">{{ t('system.orgTemplate.selectedField') }}</div>
|
||||
<MsButton @click="clearHandler">{{ t('system.orgTemplate.clear') }}</MsButton>
|
||||
</div>
|
||||
<div class="selected-list p-4">
|
||||
<MsList
|
||||
:data="selectedFields"
|
||||
:bordered="false"
|
||||
:split="false"
|
||||
item-border
|
||||
no-hover
|
||||
:virtual-list-props="{
|
||||
height: 'calc(100vh - 226px)',
|
||||
}"
|
||||
>
|
||||
<template #item="{ item }">
|
||||
<Draggable tag="div" :list="selectedList" ghost-class="ghost" item-key="dateIndex">
|
||||
<template #item="{ element }">
|
||||
<div class="selected-item">
|
||||
<a-tooltip :content="item.name">
|
||||
<span class="one-line-text w-[270px]">{{ item.name }}</span>
|
||||
<a-tooltip :content="element.name">
|
||||
<span>
|
||||
<MsIcon type="icon-icon_drag" class="mt-[3px] text-[16px] text-[var(--color-text-4)]"
|
||||
/></span>
|
||||
<span class="one-line-text ml-2 w-[270px]">{{ element.name }}</span>
|
||||
</a-tooltip>
|
||||
<icon-close
|
||||
v-if="!item.internal"
|
||||
v-if="!element.internal"
|
||||
:style="{ 'font-size': '14px' }"
|
||||
class="cursor-pointer text-[var(--color-text-3)]"
|
||||
@click="removeSelectedField(item.id)"
|
||||
@click="removeSelectedField(element.id)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</MsList>
|
||||
</Draggable>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -96,16 +93,18 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||
import MsDrawer from '@/components/pure/ms-drawer/index.vue';
|
||||
import MsList from '@/components/pure/ms-list/index.vue';
|
||||
import EditFieldDrawer from './editFieldDrawer.vue';
|
||||
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
|
||||
import type { DefinedFieldItem } from '@/models/setting/template';
|
||||
|
||||
import Draggable from 'vuedraggable';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const showAddDrawer = ref<boolean>(false);
|
||||
|
@ -113,78 +112,97 @@
|
|||
|
||||
const props = defineProps<{
|
||||
visible: boolean;
|
||||
selectedData: DefinedFieldItem[]; // 已选字段
|
||||
systemData: DefinedFieldItem[]; // 所有系统字段
|
||||
customData: DefinedFieldItem[]; // 所有自定义字段
|
||||
totalData: DefinedFieldItem[]; // 所有字段
|
||||
tableSelectData: DefinedFieldItem[]; // 表格选择字段
|
||||
}>();
|
||||
|
||||
const emit = defineEmits(['confirm', 'update:visible', 'update']);
|
||||
const emit = defineEmits(['confirm', 'update:visible', 'update-data']);
|
||||
|
||||
// 模板系统字段
|
||||
const systemField = ref<DefinedFieldItem[]>([]);
|
||||
// 自定义字段
|
||||
const customField = ref<DefinedFieldItem[]>([]);
|
||||
// 所有模板总字段
|
||||
const totalTemplateField = ref<DefinedFieldItem[]>([]);
|
||||
// 可选系统字段
|
||||
const selectSystemData = ref<string[]>([]);
|
||||
// 可选自定义字段
|
||||
const selectCustomField = ref<string[]>([]);
|
||||
// 半选状态
|
||||
const indeterminate = ref<boolean>(false);
|
||||
const totalList = ref<DefinedFieldItem[]>([]);
|
||||
|
||||
const checkedAll = ref<boolean>(false);
|
||||
// 计算系统字段
|
||||
const systemField = computed(() => {
|
||||
return totalList.value.filter((item: any) => item.internal);
|
||||
});
|
||||
|
||||
// 计算自定义字段
|
||||
const customField = computed(() => {
|
||||
return totalList.value.filter((item: any) => !item.internal);
|
||||
});
|
||||
|
||||
const selectSystemIds = ref<string[]>([]);
|
||||
const selectCustomIds = ref<string[]>([]);
|
||||
|
||||
// 监视回显字段
|
||||
watch(
|
||||
() => props.tableSelectData,
|
||||
(val) => {
|
||||
const sysField = props.tableSelectData.filter((item) => item.internal);
|
||||
const cusField = props.tableSelectData.filter((item) => !item.internal);
|
||||
selectSystemIds.value = sysField.map((item) => item.id);
|
||||
selectCustomIds.value = cusField.map((item) => item.id);
|
||||
}
|
||||
);
|
||||
|
||||
// 计算当前全部选择的字段id
|
||||
const totalIds = computed(() => {
|
||||
return [...new Set([...selectSystemIds.value, ...selectCustomIds.value])];
|
||||
});
|
||||
|
||||
const selectedList = ref<DefinedFieldItem[]>([]);
|
||||
|
||||
// 计算当前系统字段是否全选
|
||||
const isCheckSystemIdsAll = computed(() => {
|
||||
return systemField.value.length === selectSystemIds.value.length;
|
||||
});
|
||||
// 计算当前自定义字段是否全选
|
||||
const isCheckCustomIdsAll = computed(() => {
|
||||
return customField.value.length === selectCustomIds.value.length;
|
||||
});
|
||||
// 计算是否全选
|
||||
const isCheckedAll = computed(() => {
|
||||
return isCheckSystemIdsAll.value && isCheckCustomIdsAll.value;
|
||||
});
|
||||
// 计算是否半选
|
||||
const indeterminate = computed(() => {
|
||||
return selectSystemIds.value.length + selectCustomIds.value.length === selectCustomIds.value.length;
|
||||
});
|
||||
|
||||
// 全选
|
||||
const handleChangeAll = (value: any) => {
|
||||
indeterminate.value = false;
|
||||
if (value) {
|
||||
checkedAll.value = true;
|
||||
selectSystemData.value = systemField.value.map((item) => item.id);
|
||||
selectCustomField.value = customField.value.map((item) => item.id);
|
||||
selectSystemIds.value = systemField.value.map((item) => item.id);
|
||||
selectCustomIds.value = customField.value.map((item) => item.id);
|
||||
} else {
|
||||
checkedAll.value = false;
|
||||
selectSystemData.value = [];
|
||||
selectCustomField.value = [];
|
||||
selectCustomIds.value = [];
|
||||
}
|
||||
};
|
||||
|
||||
// 已选择列表
|
||||
const selectedFields = ref<DefinedFieldItem[]>([]);
|
||||
const getSelectedField = () => {
|
||||
const totalSelectIds = [...selectSystemData.value, ...selectCustomField.value];
|
||||
selectedFields.value = totalTemplateField.value.filter((item) => totalSelectIds.indexOf(item.id) > -1);
|
||||
};
|
||||
|
||||
// 处理全选&半选&未选
|
||||
const isCheckedAll = () => {
|
||||
totalTemplateField.value = [...props.systemData, ...props.customData];
|
||||
systemField.value = props.systemData;
|
||||
customField.value = props.customData;
|
||||
const systemAll = selectSystemData.value.length === systemField.value.length;
|
||||
const customAll = selectCustomField.value.length === customField.value.length;
|
||||
if (systemAll && customAll) {
|
||||
checkedAll.value = true;
|
||||
indeterminate.value = false;
|
||||
} else if (selectCustomField.value.length === 0 || selectCustomField.value.length === 0) {
|
||||
checkedAll.value = false;
|
||||
indeterminate.value = false;
|
||||
} else {
|
||||
checkedAll.value = false;
|
||||
indeterminate.value = true;
|
||||
// 监视选择列表顺序按照选择列表排序
|
||||
watch(
|
||||
() => totalIds.value,
|
||||
(val) => {
|
||||
const res = totalList.value.filter((item) => val.indexOf(item.id) > -1);
|
||||
const result = res.sort((a, b) => {
|
||||
return val.indexOf(a.id) - val.indexOf(b.id);
|
||||
});
|
||||
selectedList.value = result;
|
||||
}
|
||||
};
|
||||
);
|
||||
|
||||
watchEffect(() => {
|
||||
isCheckedAll();
|
||||
// 已经选择的列表
|
||||
getSelectedField();
|
||||
selectedList.value = props.tableSelectData;
|
||||
const sysField = props.tableSelectData.filter((item) => item.internal);
|
||||
const cusField = props.tableSelectData.filter((item) => !item.internal);
|
||||
selectSystemIds.value = sysField.map((item) => item.id);
|
||||
selectCustomIds.value = cusField.map((item) => item.id);
|
||||
selectedList.value = customField.value;
|
||||
});
|
||||
|
||||
// 移除已选择字段
|
||||
const removeSelectedField = (id: string) => {
|
||||
selectSystemData.value = selectSystemData.value.filter((item) => item !== id);
|
||||
selectCustomField.value = selectCustomField.value.filter((item) => item !== id);
|
||||
selectCustomIds.value = selectCustomIds.value.filter((item) => item !== id);
|
||||
selectedList.value = selectedList.value.filter((item) => item.id !== id);
|
||||
};
|
||||
|
||||
// 新增字段
|
||||
|
@ -195,32 +213,23 @@
|
|||
|
||||
// 清空
|
||||
const clearHandler = () => {
|
||||
selectSystemData.value = [];
|
||||
selectCustomField.value = [];
|
||||
selectCustomIds.value = [];
|
||||
};
|
||||
|
||||
const handleDrawerCancel = () => {
|
||||
showAddDrawer.value = false;
|
||||
selectCustomIds.value = props.tableSelectData.filter((item) => !item.internal).map((item) => item.id);
|
||||
selectSystemIds.value = props.tableSelectData.filter((item) => item.internal).map((item) => item.id);
|
||||
};
|
||||
|
||||
const handleDrawerConfirm = () => {
|
||||
emit('confirm', selectedFields.value);
|
||||
emit('confirm', selectedList.value);
|
||||
showAddDrawer.value = false;
|
||||
};
|
||||
|
||||
const okHandler = () => {
|
||||
emit('update');
|
||||
};
|
||||
|
||||
// 针对外部操作的进行回显
|
||||
const showSelectField = () => {
|
||||
const selectIds = props.selectedData.map((item) => item.id);
|
||||
// 回显系统字段
|
||||
selectSystemData.value = systemField.value.filter((item) => selectIds.indexOf(item.id) > -1).map((item) => item.id);
|
||||
// 回显自定义字段
|
||||
selectCustomField.value = customField.value
|
||||
.filter((item) => selectIds.indexOf(item.id) > -1)
|
||||
.map((item) => item.id);
|
||||
// eslint-disable-next-line vue/custom-event-name-casing
|
||||
emit('update-data');
|
||||
};
|
||||
|
||||
watch(
|
||||
|
@ -235,14 +244,15 @@
|
|||
showAddDrawer.value = val;
|
||||
}
|
||||
);
|
||||
|
||||
defineExpose({
|
||||
removeSelectedField,
|
||||
showSelectField,
|
||||
watchEffect(() => {
|
||||
totalList.value = props.totalData;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
:deep(.arco-drawer) {
|
||||
width: 65% !important;
|
||||
}
|
||||
.panel-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
@ -264,13 +274,6 @@
|
|||
background: var(--color-text-n9);
|
||||
@apply flex items-center justify-between;
|
||||
}
|
||||
.optional-panel {
|
||||
.checkbox {
|
||||
width: 74px;
|
||||
white-space: nowrap;
|
||||
@apply overflow-hidden text-ellipsis;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 已选字段
|
||||
.selected-field {
|
||||
|
@ -286,10 +289,25 @@
|
|||
.selected-item {
|
||||
height: 36px;
|
||||
background: var(--color-bg-3);
|
||||
cursor: move;
|
||||
@apply mb-2 flex items-center justify-between rounded px-2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.checkboxContainer {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(116px, 1fr));
|
||||
grid-gap: 16px;
|
||||
.checkbox {
|
||||
width: 90px;
|
||||
white-space: nowrap;
|
||||
@apply overflow-hidden text-ellipsis;
|
||||
}
|
||||
}
|
||||
.ghost {
|
||||
border: 1px dashed rgba(var(--primary-5));
|
||||
background-color: rgba(var(--primary-1));
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
:title="isEdit ? t('system.orgTemplate.update') : t('system.orgTemplate.addField')"
|
||||
:ok-text="t(isEdit ? 'system.orgTemplate.update' : 'system.orgTemplate.addField')"
|
||||
:ok-loading="drawerLoading"
|
||||
:width="680"
|
||||
:width="800"
|
||||
:show-continue="!isEdit"
|
||||
@confirm="handleDrawerConfirm"
|
||||
@continue="handleDrawerConfirm(true)"
|
||||
|
@ -36,9 +36,9 @@
|
|||
}"
|
||||
></a-textarea>
|
||||
</a-form-item>
|
||||
<a-form-item field="type" :label="t('system.orgTemplate.fieldType')" asterisk-position="end">
|
||||
<a-form-item field="type" :label="t('system.orgTemplate.fieldType')" asterisk-position="end" :required="true">
|
||||
<a-select
|
||||
v-model="fieldType"
|
||||
v-model="fieldForm.type"
|
||||
class="w-[260px]"
|
||||
:placeholder="t('system.orgTemplate.fieldTypePlaceholder')"
|
||||
allow-clear
|
||||
|
@ -53,7 +53,7 @@
|
|||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
v-if="fieldType === 'MEMBER'"
|
||||
v-if="fieldForm.type === 'MEMBER'"
|
||||
field="type"
|
||||
:label="t('system.orgTemplate.allowMultiMember')"
|
||||
asterisk-position="end"
|
||||
|
@ -63,18 +63,28 @@
|
|||
<!-- 选项选择器 -->
|
||||
<a-form-item
|
||||
v-if="showOptionsSelect"
|
||||
field="options"
|
||||
field="optionsModels"
|
||||
:label="t('system.orgTemplate.optionContent')"
|
||||
asterisk-position="end"
|
||||
:rules="[{ message: t('system.orgTemplate.optionContentRules') }]"
|
||||
class="relative"
|
||||
:class="[!fieldForm?.enableOptionKey ? 'max-w-[340px]' : 'w-full']"
|
||||
>
|
||||
<div v-if="sceneType === 'BUG'" class="optionsKey">
|
||||
<a-checkbox v-model="fieldForm.enableOptionKey"
|
||||
>选项KEY值
|
||||
<a-tooltip :content="t('system.orgTemplate.thirdPartyPlatforms')"
|
||||
><icon-question-circle
|
||||
:style="{ 'font-size': '16px' }"
|
||||
class="text-[var(--color-text-4)] hover:text-[rgb(var(--primary-5))]" /></a-tooltip></a-checkbox
|
||||
></div>
|
||||
<MsBatchForm
|
||||
ref="batchFormRef"
|
||||
:models="optionsModels"
|
||||
form-mode="create"
|
||||
add-text="system.orgTemplate.addOptions"
|
||||
:is-show-drag="true"
|
||||
form-width="340px"
|
||||
:form-width="!fieldForm?.enableOptionKey ? '340px' : ''"
|
||||
:default-vals="fieldDefaultValues"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
@ -82,7 +92,9 @@
|
|||
<a-form-item
|
||||
v-if="showDateOrNumber"
|
||||
field="selectFormat"
|
||||
:label="fieldType === 'NUMBER' ? t('system.orgTemplate.numberFormat') : t('system.orgTemplate.dateFormat')"
|
||||
:label="
|
||||
fieldForm.type === 'NUMBER' ? t('system.orgTemplate.numberFormat') : t('system.orgTemplate.dateFormat')
|
||||
"
|
||||
asterisk-position="end"
|
||||
>
|
||||
<a-select
|
||||
|
@ -106,6 +118,7 @@
|
|||
import { ref } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { FormInstance, Message, ValidatedError } from '@arco-design/web-vue';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
|
||||
import MsDrawer from '@/components/pure/ms-drawer/index.vue';
|
||||
import type { FormItemType } from '@/components/pure/ms-form-create/types';
|
||||
|
@ -124,7 +137,7 @@
|
|||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
const appStore = useAppStore();
|
||||
|
||||
const sceneType = route.query.type;
|
||||
const props = defineProps<{
|
||||
visible: boolean;
|
||||
}>();
|
||||
|
@ -136,14 +149,15 @@
|
|||
const fieldFormRef = ref<FormInstance>();
|
||||
const initFieldForm: AddOrUpdateField = {
|
||||
name: '',
|
||||
type: 'INPUT',
|
||||
type: undefined,
|
||||
remark: '',
|
||||
scopeId: '',
|
||||
scene: 'FUNCTIONAL',
|
||||
options: [],
|
||||
enableOptionKey: false,
|
||||
};
|
||||
const fieldForm = ref<AddOrUpdateField>({ ...initFieldForm });
|
||||
const isEdit = computed(() => !!fieldForm.value.id);
|
||||
const isEdit = ref<boolean>(false);
|
||||
const selectFormat = ref<FormItemType>(); // 选择格式
|
||||
const isMultipleSelectMember = ref<boolean | undefined>(false); // 成员多选
|
||||
const fieldType = ref<FormItemType>(); // 整体字段类型
|
||||
|
@ -151,12 +165,12 @@
|
|||
// 是否展示选项添加面板
|
||||
const showOptionsSelect = computed(() => {
|
||||
const showOptionsType: FormItemType[] = ['RADIO', 'CHECKBOX', 'SELECT', 'MULTIPLE_SELECT'];
|
||||
return showOptionsType.includes(fieldType.value as FormItemType);
|
||||
return showOptionsType.includes(fieldForm.value.type as FormItemType);
|
||||
});
|
||||
|
||||
// 是否展示日期或数值
|
||||
const showDateOrNumber = computed(() => {
|
||||
if (fieldType.value) return getFieldType(fieldType.value);
|
||||
if (fieldForm.value.type) return getFieldType(fieldForm.value.type);
|
||||
});
|
||||
|
||||
// 批量表单-1.仅选项情况
|
||||
|
@ -164,12 +178,43 @@
|
|||
filed: 'text',
|
||||
type: 'input',
|
||||
label: '',
|
||||
rules: [{ required: true, message: t('system.orgTemplate.optionContentRules') }],
|
||||
rules: [
|
||||
{ required: true, message: t('system.orgTemplate.optionContentRules') },
|
||||
{ notRepeat: true, message: t('system.orgTemplate.optionsContentNoRepeat') },
|
||||
],
|
||||
placeholder: t('system.orgTemplate.optionsPlaceholder'),
|
||||
hideAsterisk: true,
|
||||
hideLabel: true,
|
||||
});
|
||||
const optionsModels: Ref<FormItemModel[]> = ref([{ ...onlyOptions.value }]);
|
||||
|
||||
// 批量表单-2 缺陷情况
|
||||
const bugBatchFormRules = ref<FormItemModel[]>([
|
||||
{
|
||||
filed: 'text',
|
||||
type: 'input',
|
||||
label: '',
|
||||
rules: [
|
||||
{ required: true, message: t('system.orgTemplate.optionContentRules') },
|
||||
{ notRepeat: true, message: t('system.orgTemplate.optionsContentNoRepeat') },
|
||||
],
|
||||
placeholder: 'system.orgTemplate.optionsPlaceholder',
|
||||
hideAsterisk: true,
|
||||
hideLabel: true,
|
||||
},
|
||||
{
|
||||
filed: 'value',
|
||||
type: 'input',
|
||||
label: '',
|
||||
rules: [
|
||||
{ required: true, message: t('system.orgTemplate.optionsIdTip') },
|
||||
{ notRepeat: true, message: t('system.orgTemplate.optionsIdNoRepeat') },
|
||||
],
|
||||
placeholder: 'system.orgTemplate.optionsIdPlaceholder',
|
||||
hideAsterisk: true,
|
||||
hideLabel: true,
|
||||
},
|
||||
]);
|
||||
const optionsModels: Ref<FormItemModel[]> = ref([]);
|
||||
const batchFormRef = ref<MsBatchFormInstance | null>(null);
|
||||
|
||||
const resetForm = () => {
|
||||
|
@ -190,42 +235,49 @@
|
|||
const confirmHandler = async (isContinue: boolean) => {
|
||||
try {
|
||||
drawerLoading.value = true;
|
||||
if (fieldType.value) {
|
||||
fieldForm.value.type = fieldType.value;
|
||||
}
|
||||
|
||||
fieldForm.value.scene = route.query.type;
|
||||
fieldForm.value.scopeId = appStore.currentOrgId;
|
||||
const formCopy = cloneDeep(fieldForm.value);
|
||||
|
||||
formCopy.scene = route.query.type;
|
||||
formCopy.scopeId = appStore.currentOrgId;
|
||||
|
||||
// 如果选择是日期或者数值
|
||||
if (selectFormat.value) {
|
||||
fieldForm.value.type = selectFormat.value;
|
||||
formCopy.type = selectFormat.value;
|
||||
}
|
||||
|
||||
// 如果选择是成员(单选||多选)
|
||||
if (isMultipleSelectMember.value) {
|
||||
fieldForm.value.type = isMultipleSelectMember.value ? 'MULTIPLE_MEMBER' : 'MEMBER';
|
||||
formCopy.type = isMultipleSelectMember.value ? 'MULTIPLE_MEMBER' : 'MEMBER';
|
||||
}
|
||||
|
||||
// 如果选择是日期或者是数值
|
||||
if (selectFormat.value) {
|
||||
fieldForm.value.type = selectFormat.value;
|
||||
formCopy.type = selectFormat.value;
|
||||
}
|
||||
|
||||
// 处理参数
|
||||
const { id, name, options, scopeId, scene, type, remark } = fieldForm.value;
|
||||
const params: AddOrUpdateField = { name, options, scopeId, scene, type, remark };
|
||||
const { id, name, options, scopeId, scene, type, remark, enableOptionKey } = formCopy;
|
||||
|
||||
if (isEdit) {
|
||||
const params: AddOrUpdateField = {
|
||||
name,
|
||||
options,
|
||||
scopeId,
|
||||
scene,
|
||||
type,
|
||||
remark,
|
||||
enableOptionKey,
|
||||
};
|
||||
if (id) {
|
||||
params.id = id;
|
||||
}
|
||||
await addOrUpdateOrdField(params);
|
||||
Message.success(isEdit ? t('common.addSuccess') : t('common.updateSuccess'));
|
||||
Message.success(isEdit.value ? t('common.updateSuccess') : t('common.addSuccess'));
|
||||
if (!isContinue) {
|
||||
handleDrawerCancel();
|
||||
}
|
||||
resetForm();
|
||||
emit('success');
|
||||
emit('success', isEdit.value);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
} finally {
|
||||
|
@ -241,7 +293,7 @@
|
|||
fieldForm.value.options = (batchFormRef.value?.getFormResult() || []).map((item: any) => {
|
||||
return {
|
||||
...item,
|
||||
value: getGenerateId(),
|
||||
value: fieldForm.value.enableOptionKey ? item.value : getGenerateId(),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
@ -291,13 +343,12 @@
|
|||
const editHandler = (item: AddOrUpdateField) => {
|
||||
showDrawer.value = true;
|
||||
isMultipleSelectMember.value = item.type === 'MULTIPLE_MEMBER';
|
||||
if (isEdit && item.id) {
|
||||
if (item.id) {
|
||||
getFieldDetail(item.id);
|
||||
fieldForm.value = {
|
||||
...item,
|
||||
type: getSpecialHandler(item.type),
|
||||
};
|
||||
fieldType.value = fieldForm.value.type;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -320,6 +371,27 @@
|
|||
showDrawer.value = val;
|
||||
}
|
||||
);
|
||||
|
||||
watchEffect(() => {
|
||||
if (fieldForm.value.id) {
|
||||
isEdit.value = true;
|
||||
} else {
|
||||
isEdit.value = false;
|
||||
}
|
||||
});
|
||||
|
||||
// 监视是否显示KEY值
|
||||
watch(
|
||||
() => fieldForm.value.enableOptionKey,
|
||||
(val) => {
|
||||
if (val && sceneType === 'BUG') {
|
||||
optionsModels.value = cloneDeep(bugBatchFormRules.value);
|
||||
} else {
|
||||
optionsModels.value = [{ ...onlyOptions.value }];
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
onMounted(() => {
|
||||
const excludeOptions = ['MULTIPLE_MEMBER', 'DATETIME', 'SYSTEM', 'INT', 'FLOAT'];
|
||||
fieldOptions.value = fieldIconAndName.filter((item: any) => excludeOptions.indexOf(item.key) < 0);
|
||||
|
@ -330,4 +402,10 @@
|
|||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
<style scoped lang="less">
|
||||
.optionsKey {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
}}</a-alert>
|
||||
<div class="mb-4 flex items-center justify-between">
|
||||
<span v-if="isEnable" class="font-medium">{{ t('system.orgTemplate.fieldList') }}</span>
|
||||
<a-button v-else type="primary" :disabled="totalData.length > 20" @click="fieldHandler('add')">
|
||||
<a-button v-else type="primary" :disabled="isDisabled" @click="fieldHandler">
|
||||
{{ t('system.orgTemplate.addField') }}
|
||||
</a-button>
|
||||
<a-input-search
|
||||
|
@ -99,6 +99,7 @@
|
|||
width: 300,
|
||||
showDrag: true,
|
||||
showInTable: true,
|
||||
showTooltip: true,
|
||||
},
|
||||
{
|
||||
title: 'system.orgTemplate.columnFieldType',
|
||||
|
@ -154,15 +155,24 @@
|
|||
console.log(error);
|
||||
}
|
||||
};
|
||||
const scene = ref<SeneType>('');
|
||||
const scene = ref<SeneType>(route.query.type);
|
||||
|
||||
// 获取字段列表数据
|
||||
const fetchData = async () => {
|
||||
scene.value = route.query.type;
|
||||
setLoadListParams({ organizationId: currentOrd, scene });
|
||||
await loadList();
|
||||
totalData.value = await getFieldList({ organizationId: currentOrd, scene: route.query.type });
|
||||
};
|
||||
|
||||
const isDisabled = computed(() => {
|
||||
return totalData.value.length > 20;
|
||||
});
|
||||
|
||||
const tableRef = ref();
|
||||
const isEnable = ref<boolean>(templateStore.templateStatus[scene.value as string]); // 开始默认未启用
|
||||
const isEnable = computed(() => {
|
||||
return templateStore.templateStatus[scene.value as string];
|
||||
}); // 开始默认未启用
|
||||
|
||||
// 切换模版是否启用展示操作列
|
||||
const isEnableOperation = () => {
|
||||
|
@ -218,13 +228,12 @@
|
|||
const showDrawer = ref<boolean>(false);
|
||||
|
||||
const fieldDrawerRef = ref();
|
||||
const fieldHandler = (type: string, record?: AddOrUpdateField) => {
|
||||
const fieldHandler = () => {
|
||||
showDrawer.value = true;
|
||||
if (type === 'edit' && record) fieldDrawerRef.value.editHandler(record);
|
||||
};
|
||||
|
||||
const handleOk = (record: AddOrUpdateField) => {
|
||||
fieldHandler('edit', record);
|
||||
fieldDrawerRef.value.editHandler(record);
|
||||
};
|
||||
|
||||
const successHandler = () => {
|
||||
|
@ -242,9 +251,9 @@
|
|||
};
|
||||
|
||||
onMounted(() => {
|
||||
fetchData();
|
||||
isEnableOperation();
|
||||
updateBreadcrumbList();
|
||||
isEnableOperation();
|
||||
fetchData();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<MsCard
|
||||
:loading="loading"
|
||||
:title="title"
|
||||
:is-edit="isEdit"
|
||||
:is-edit="isEdit && route.params.mode !== 'copy'"
|
||||
has-breadcrumb
|
||||
@save="saveHandler"
|
||||
@save-and-continue="saveHandler(true)"
|
||||
|
@ -40,12 +40,21 @@
|
|||
class="max-w-[732px]"
|
||||
></a-textarea>
|
||||
</a-form-item>
|
||||
<a-form-item field="remark" label="" asterisk-position="end"
|
||||
><a-checkbox v-model="templateForm.enableThirdPart">{{ t('system.orgTemplate.thirdParty') }}</a-checkbox>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<!-- 已有字段表 -->
|
||||
<TemplateManagementTable ref="templateFieldTableRef" :custom-list="tableFiledDetailList" :is-edit="isEdit" />
|
||||
<TemplateManagementTable
|
||||
ref="templateFieldTableRef"
|
||||
v-model:select-data="selectData"
|
||||
:data="(totalTemplateField as DefinedFieldItem[])"
|
||||
:enable-third-part="templateForm.enableThirdPart"
|
||||
@update="updateHandler"
|
||||
/>
|
||||
</div>
|
||||
<!-- 预览模式 -->
|
||||
<PreviewTemplate v-else :select-field="selectFiledToTem" />
|
||||
<PreviewTemplate v-else :select-field="(selectData as DefinedFieldItem[])" />
|
||||
</MsCard>
|
||||
</template>
|
||||
|
||||
|
@ -56,54 +65,92 @@
|
|||
import { ref } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { FormInstance, Message, ValidatedError } from '@arco-design/web-vue';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
|
||||
import MsCard from '@/components/pure/ms-card/index.vue';
|
||||
import { FieldTypeFormRules } from '@/components/pure/ms-form-create/form-create';
|
||||
import TemplateManagementTable from './templateManagementTable.vue';
|
||||
import PreviewTemplate from './viewTemplate.vue';
|
||||
|
||||
import {
|
||||
createOrganizeTemplateInfo,
|
||||
getFieldList,
|
||||
getOrganizeTemplateInfo,
|
||||
updateOrganizeTemplateInfo,
|
||||
} from '@/api/modules/setting/template';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useLeaveUnSaveTip from '@/hooks/useLeaveUnSaveTip';
|
||||
import { useAppStore } from '@/store';
|
||||
import useTemplateStore from '@/store/modules/setting/template';
|
||||
import { sleep } from '@/utils';
|
||||
import { scrollIntoView } from '@/utils/dom';
|
||||
|
||||
import type { ActionTemplateManage, CustomField } from '@/models/setting/template';
|
||||
import type { ActionTemplateManage, CustomField, DefinedFieldItem } from '@/models/setting/template';
|
||||
import { SettingRouteEnum } from '@/enums/routeEnum';
|
||||
|
||||
import { cardList } from './fieldSetting';
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const appStore = useAppStore();
|
||||
const templateStore = useTemplateStore();
|
||||
useLeaveUnSaveTip();
|
||||
// useLeaveUnSaveTip();
|
||||
|
||||
const title = ref('');
|
||||
const loading = ref(false);
|
||||
|
||||
const initTemplateForm = {
|
||||
const initTemplateForm: ActionTemplateManage = {
|
||||
id: '',
|
||||
name: '',
|
||||
remark: '',
|
||||
scopeId: appStore.currentOrgId,
|
||||
enableThirdPart: false,
|
||||
};
|
||||
|
||||
const templateForm = ref({ ...initTemplateForm });
|
||||
const templateForm = ref<ActionTemplateManage>({ ...initTemplateForm });
|
||||
|
||||
const selectData = ref<DefinedFieldItem[]>([]); // 表格已选择字段
|
||||
const selectFiled = ref<DefinedFieldItem[]>([]);
|
||||
|
||||
const formRef = ref<FormInstance>();
|
||||
const totalTemplateField = ref<DefinedFieldItem[]>([]);
|
||||
const isEdit = computed(() => !!route.query.id);
|
||||
const currentOrd = appStore.currentOrgId;
|
||||
const isEditField = ref<boolean>(false);
|
||||
|
||||
const tableFiledDetailList = ref([]);
|
||||
// 获取模板详情
|
||||
const getTemplateInfo = async () => {
|
||||
try {
|
||||
loading.value = true;
|
||||
const res = await getOrganizeTemplateInfo(route.query.id as string);
|
||||
const { name, remark, customFields, scoped, enableThirdPart, scene } = res;
|
||||
templateForm.value.name = name;
|
||||
templateForm.value.remark = remark;
|
||||
// 处理 字段列表
|
||||
tableFiledDetailList.value = customFields;
|
||||
const { name, customFields } = res;
|
||||
templateForm.value = {
|
||||
...res,
|
||||
name: route.params.mode === 'copy' ? `${name}_copy` : name,
|
||||
};
|
||||
if (route.params.mode === 'copy') {
|
||||
templateForm.value.id = undefined;
|
||||
}
|
||||
// 处理字段列表
|
||||
const customFieldsIds = customFields.map((index: any) => index.fieldId);
|
||||
const result = totalTemplateField.value.filter((item) => {
|
||||
const currentCustomFieldIndex = customFieldsIds.findIndex((it: any) => it === item.id);
|
||||
if (customFieldsIds.indexOf(item.id) > -1) {
|
||||
const currentForm = item.formRules?.map((it: any) => {
|
||||
it.props.modelValue = customFields[currentCustomFieldIndex].defaultValue;
|
||||
return {
|
||||
...it,
|
||||
value: customFields[currentCustomFieldIndex].defaultValue,
|
||||
};
|
||||
});
|
||||
const formItem = item;
|
||||
formItem.formRules = cloneDeep(currentForm);
|
||||
formItem.apiFieldId = customFields[currentCustomFieldIndex].apiFieldId;
|
||||
formItem.required = customFields[currentCustomFieldIndex].required;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
selectData.value = result;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
} finally {
|
||||
|
@ -111,29 +158,88 @@
|
|||
}
|
||||
};
|
||||
|
||||
const isEdit = ref(false);
|
||||
const templateFieldTableRef = ref();
|
||||
watchEffect(() => {
|
||||
if (route.query.id) {
|
||||
// 处理表单数据格式
|
||||
const getFieldOptionList = () => {
|
||||
totalTemplateField.value = totalTemplateField.value.map((item: any) => {
|
||||
const currentFormRules = FieldTypeFormRules[item.type];
|
||||
let selectOptions: any = [];
|
||||
if (item.options && item.options.length) {
|
||||
selectOptions = item.options.map((optionItem: any) => {
|
||||
return {
|
||||
label: optionItem.text,
|
||||
value: optionItem.value,
|
||||
};
|
||||
});
|
||||
currentFormRules.options = selectOptions;
|
||||
}
|
||||
return {
|
||||
...item,
|
||||
formRules: [
|
||||
{ ...currentFormRules, value: item.value, props: { ...currentFormRules.props, options: selectOptions } },
|
||||
],
|
||||
fApi: null,
|
||||
required: item.internal,
|
||||
};
|
||||
});
|
||||
// 创建默认系统字段
|
||||
if (!isEdit.value && !isEditField.value) {
|
||||
selectData.value = totalTemplateField.value.filter((item) => item.internal);
|
||||
}
|
||||
};
|
||||
|
||||
// 获取字段列表数据
|
||||
const getClassifyField = async () => {
|
||||
try {
|
||||
totalTemplateField.value = await getFieldList({ organizationId: currentOrd, scene: route.query.type });
|
||||
getFieldOptionList();
|
||||
// 编辑字段就需要单独处理过滤
|
||||
if (isEditField.value) {
|
||||
selectData.value = totalTemplateField.value.filter(
|
||||
(item) => selectFiled.value.map((it) => it.id).indexOf(item.id) > -1
|
||||
);
|
||||
}
|
||||
if (isEdit.value) {
|
||||
getTemplateInfo();
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
watchEffect(async () => {
|
||||
if (isEdit.value && route.params.mode === 'copy') {
|
||||
title.value = t('system.orgTemplate.copyTemplate');
|
||||
getClassifyField();
|
||||
} else if (isEdit.value) {
|
||||
title.value = t('menu.settings.organization.templateManagementEdit');
|
||||
isEdit.value = true;
|
||||
getTemplateInfo();
|
||||
getClassifyField();
|
||||
} else {
|
||||
title.value = t('menu.settings.organization.templateManagementDetail');
|
||||
isEdit.value = false;
|
||||
}
|
||||
});
|
||||
|
||||
const formRef = ref<FormInstance>();
|
||||
|
||||
// 获取模板参数
|
||||
function getTemplateParams(): ActionTemplateManage {
|
||||
const result: CustomField[] = templateFieldTableRef.value.getCustomFields();
|
||||
const { name, remark } = templateForm.value;
|
||||
const result = selectData.value.map((item) => {
|
||||
if (item.formRules?.length) {
|
||||
const { value } = item.formRules[0];
|
||||
return {
|
||||
fieldId: item.id,
|
||||
required: item.required,
|
||||
apiFieldId: item.apiFieldId,
|
||||
defaultValue: value,
|
||||
};
|
||||
}
|
||||
return [];
|
||||
});
|
||||
|
||||
const { name, remark, enableThirdPart, id } = templateForm.value;
|
||||
return {
|
||||
id,
|
||||
name,
|
||||
remark,
|
||||
customFields: result,
|
||||
enableThirdPart,
|
||||
customFields: result as CustomField[],
|
||||
scopeId: appStore.currentOrgId,
|
||||
scene: route.query.type,
|
||||
};
|
||||
|
@ -145,13 +251,14 @@
|
|||
|
||||
const isContinueFlag = ref(false);
|
||||
|
||||
// 保存回调
|
||||
async function save() {
|
||||
try {
|
||||
loading.value = true;
|
||||
const params = getTemplateParams();
|
||||
if (isEdit.value) {
|
||||
if (isEdit.value && route.params.mode !== 'copy') {
|
||||
await updateOrganizeTemplateInfo(params);
|
||||
Message.success(t('system.resourcePool.updateSuccess'));
|
||||
Message.success(t('system.orgTemplate.updateSuccess'));
|
||||
} else {
|
||||
await createOrganizeTemplateInfo(params);
|
||||
Message.success(t('system.orgTemplate.addSuccess'));
|
||||
|
@ -160,7 +267,7 @@
|
|||
resetForm();
|
||||
} else {
|
||||
await sleep(300);
|
||||
router.push({ name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT_DETAIL });
|
||||
router.push({ name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT, query: route.query });
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
|
@ -170,30 +277,57 @@
|
|||
}
|
||||
|
||||
// 保存
|
||||
async function saveHandler(isContinue = false) {
|
||||
function saveHandler(isContinue = false) {
|
||||
isContinueFlag.value = isContinue;
|
||||
formRef.value?.validate(async (errors: Record<string, ValidatedError> | undefined) => {
|
||||
if (!errors) {
|
||||
save();
|
||||
} else {
|
||||
return scrollIntoView(document.querySelector('.arco-form-item-message'), { block: 'center' });
|
||||
formRef.value?.validate().then((res) => {
|
||||
if (!res) {
|
||||
return save();
|
||||
}
|
||||
return scrollIntoView(document.querySelector('.arco-form-item-message'), { block: 'center' });
|
||||
});
|
||||
}
|
||||
|
||||
const selectFiledToTem = ref([]); // 非预览模式模板已选择字段
|
||||
// 是否预览模式
|
||||
const isPreview = ref<boolean>(true); // 默认非预览模式
|
||||
function togglePreview() {
|
||||
isPreview.value = !isPreview.value;
|
||||
if (!isPreview.value) {
|
||||
selectFiledToTem.value = templateFieldTableRef.value.getSelectFiled();
|
||||
templateStore.setPreviewHandler(selectFiledToTem.value);
|
||||
}
|
||||
}
|
||||
|
||||
// 计算当前级别title
|
||||
const breadTitle = computed(() => {
|
||||
const firstBreadTitle = cardList.find((item) => item.key === route.query.type)?.name;
|
||||
const ThirdBreadTitle = title.value;
|
||||
return {
|
||||
firstBreadTitle,
|
||||
ThirdBreadTitle,
|
||||
};
|
||||
});
|
||||
|
||||
// 更新面包屑标题
|
||||
const setBreadText = () => {
|
||||
const { breadcrumbList } = appStore;
|
||||
const { firstBreadTitle, ThirdBreadTitle } = breadTitle.value;
|
||||
if (firstBreadTitle) {
|
||||
breadcrumbList[0].locale = firstBreadTitle;
|
||||
if (appStore.breadcrumbList.length > 2) {
|
||||
breadcrumbList[2].locale = ThirdBreadTitle;
|
||||
}
|
||||
appStore.setBreadcrumbList(breadcrumbList);
|
||||
}
|
||||
};
|
||||
// 字段表编辑更新表
|
||||
const updateHandler = (flag: boolean) => {
|
||||
isEditField.value = flag;
|
||||
selectFiled.value = selectData.value;
|
||||
getClassifyField();
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
templateFieldTableRef.value.setDefaultField();
|
||||
setBreadText();
|
||||
getClassifyField();
|
||||
if (!isEdit.value) {
|
||||
selectData.value = totalTemplateField.value.filter((item) => item.internal);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -17,14 +17,14 @@
|
|||
</span>
|
||||
<span class="operation hover:text-[rgb(var(--primary-5))]">
|
||||
<span @click="templateManagement">{{ t('system.orgTemplate.TemplateManagement') }}</span>
|
||||
<a-divider v-if="props.cardItem.key == 'BUG'" direction="vertical" />
|
||||
<a-divider v-if="!props.cardItem.enable || props.cardItem.key === 'BUG'" direction="vertical" />
|
||||
</span>
|
||||
<span v-if="props.cardItem.key === 'BUG'" class="operation hover:text-[rgb(var(--primary-5))]">
|
||||
<span>{{ t('system.orgTemplate.workflowSetup') }}</span>
|
||||
<a-divider v-if="!props.cardItem.enable" direction="vertical" />
|
||||
<a-divider v-if="!props.cardItem.enable && props.cardItem.key === 'BUG'" direction="vertical" />
|
||||
</span>
|
||||
<span v-if="!props.cardItem.enable" class="rounded p-[2px] hover:bg-[rgb(var(--primary-9))]">
|
||||
<MsTableMoreAction :list="moreActions" @select="handleMoreActionSelect"
|
||||
<MsTableMoreAction :list="moreActions" @select="(item) => handleMoreActionSelect"
|
||||
/></span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -36,15 +36,19 @@
|
|||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
|
||||
import MsTableMoreAction from '@/components/pure/ms-table-more-action/index.vue';
|
||||
import type { ActionsItem } from '@/components/pure/ms-table-more-action/types';
|
||||
|
||||
import { isEnableTemplate } from '@/api/modules/setting/template';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { useAppStore } from '@/store';
|
||||
|
||||
import { SettingRouteEnum } from '@/enums/routeEnum';
|
||||
|
||||
const { t } = useI18n();
|
||||
const appStore = useAppStore();
|
||||
|
||||
const props = defineProps<{
|
||||
cardItem: Record<string, any>;
|
||||
|
@ -60,7 +64,21 @@
|
|||
},
|
||||
]);
|
||||
|
||||
const handleMoreActionSelect = (item: ActionsItem) => {};
|
||||
// 启用模板
|
||||
const enableHandler = async () => {
|
||||
try {
|
||||
await isEnableTemplate(appStore.currentOrgId);
|
||||
Message.success(t('system.orgTemplate.enabledSuccessfully'));
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleMoreActionSelect = (item: ActionsItem) => {
|
||||
if (item.eventTag === 'enable') {
|
||||
enableHandler();
|
||||
}
|
||||
};
|
||||
|
||||
// 字段设置
|
||||
const fieldSetting = () => {
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
<template #operation="{ record }">
|
||||
<div class="flex flex-row flex-nowrap">
|
||||
<MsButton @click="editTemplate(record.id)">{{ t('system.orgTemplate.edit') }}</MsButton>
|
||||
<MsButton class="!mr-0">{{ t('system.orgTemplate.copy') }}</MsButton>
|
||||
<MsButton class="!mr-0" @click="copyTemplate(record.id)">{{ t('system.orgTemplate.copy') }}</MsButton>
|
||||
<a-divider v-if="!record.internal" direction="vertical" />
|
||||
<MsTableMoreAction
|
||||
v-if="!record.internal"
|
||||
|
@ -52,7 +52,7 @@
|
|||
import MsTableMoreAction from '@/components/pure/ms-table-more-action/index.vue';
|
||||
import { ActionsItem } from '@/components/pure/ms-table-more-action/types';
|
||||
|
||||
import { deleteOrdField, getOrganizeTemplateList } from '@/api/modules/setting/template';
|
||||
import { deleteOrdTemplate, getOrganizeTemplateList } from '@/api/modules/setting/template';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useModal from '@/hooks/useModal';
|
||||
import router from '@/router';
|
||||
|
@ -64,6 +64,8 @@
|
|||
import { SettingRouteEnum } from '@/enums/routeEnum';
|
||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||
|
||||
import { cardList } from './fieldSetting';
|
||||
|
||||
const route = useRoute();
|
||||
const { t } = useI18n();
|
||||
const tableStore = useTableStore();
|
||||
|
@ -71,8 +73,6 @@
|
|||
const templateStore = useTemplateStore();
|
||||
const { openModal } = useModal();
|
||||
|
||||
const isEnable = ref<boolean>(false);
|
||||
|
||||
const keyword = ref('');
|
||||
const currentOrd = appStore.currentOrgId;
|
||||
|
||||
|
@ -118,12 +118,14 @@
|
|||
showPagination: false,
|
||||
heightUsed: 380,
|
||||
});
|
||||
const scene = route.query.type;
|
||||
const isEnable = templateStore.templateStatus[scene as string];
|
||||
|
||||
const totalList = ref<OrdTemplateManagement[]>([]);
|
||||
// 查询字段
|
||||
const searchFiled = async () => {
|
||||
try {
|
||||
totalList.value = await getOrganizeTemplateList({ organizationId: currentOrd, scene: route.query.type });
|
||||
totalList.value = await getOrganizeTemplateList({ organizationId: currentOrd, scene });
|
||||
const filterData = totalList.value.filter((item: OrdTemplateManagement) => item.name.includes(keyword.value));
|
||||
setProps({ data: filterData });
|
||||
} catch (error) {
|
||||
|
@ -142,7 +144,7 @@
|
|||
const handlerDelete = (record: any) => {
|
||||
openModal({
|
||||
type: 'error',
|
||||
title: t('system.orgTemplate.deleteTitle', { name: characterLimit(record.name) }),
|
||||
title: t('system.orgTemplate.deleteTemplateTitle', { name: characterLimit(record.name) }),
|
||||
content: t('system.userGroup.beforeDeleteUserGroup'),
|
||||
okText: t('system.userGroup.confirmDelete'),
|
||||
cancelText: t('system.userGroup.cancel'),
|
||||
|
@ -151,8 +153,8 @@
|
|||
},
|
||||
onBeforeOk: async () => {
|
||||
try {
|
||||
if (record.id) await deleteOrdField(record.id);
|
||||
Message.success(t('system.user.deleteUserSuccess'));
|
||||
if (record.id) await deleteOrdTemplate(record.id);
|
||||
Message.success(t('common.deleteSuccess'));
|
||||
loadList();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
|
@ -170,19 +172,20 @@
|
|||
};
|
||||
|
||||
const fetchData = async () => {
|
||||
const scene = route.query.type;
|
||||
setLoadListParams({ organizationId: currentOrd, scene });
|
||||
setLoadListParams({ organizationId: currentOrd, scene: route.query.type });
|
||||
await loadList();
|
||||
};
|
||||
|
||||
// 创建模板
|
||||
const createTemplate = () => {
|
||||
templateStore.setPreviewHandler([]);
|
||||
router.push({
|
||||
name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT_DETAIL,
|
||||
query: {
|
||||
type: route.query.type,
|
||||
},
|
||||
params: {
|
||||
mode: 'create',
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -191,14 +194,55 @@
|
|||
router.push({
|
||||
name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT_DETAIL,
|
||||
query: {
|
||||
type: route.query.type,
|
||||
id,
|
||||
type: route.query.type,
|
||||
},
|
||||
params: {
|
||||
mode: 'edit',
|
||||
},
|
||||
});
|
||||
};
|
||||
// 复制模板
|
||||
const copyTemplate = (id: string) => {
|
||||
router.push({
|
||||
name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT_DETAIL,
|
||||
query: {
|
||||
id,
|
||||
type: route.query.type,
|
||||
},
|
||||
params: {
|
||||
mode: 'copy',
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
// 更新面包屑根据不同的模版
|
||||
const updateBreadcrumbList = () => {
|
||||
const { breadcrumbList } = appStore;
|
||||
const breadTitle = cardList.find((item) => item.key === route.query.type);
|
||||
if (breadTitle) {
|
||||
breadcrumbList[0].locale = breadTitle.name;
|
||||
appStore.setBreadcrumbList(breadcrumbList);
|
||||
}
|
||||
};
|
||||
|
||||
const tableRef = ref();
|
||||
|
||||
function updateColumns() {
|
||||
if (isEnable) {
|
||||
const result = fieldColumns.slice(0, fieldColumns.length - 1);
|
||||
tableStore.setColumns(TableKeyEnum.ORGANIZATION_TEMPLATE_MANAGEMENT, result, 'drawer');
|
||||
tableRef.value.initColumn();
|
||||
} else {
|
||||
tableStore.setColumns(TableKeyEnum.ORGANIZATION_TEMPLATE_MANAGEMENT, fieldColumns, 'drawer');
|
||||
tableRef.value.initColumn();
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
updateBreadcrumbList();
|
||||
fetchData();
|
||||
updateColumns();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -5,6 +5,14 @@
|
|||
<span class="ml-2">{{ record.name }}</span>
|
||||
<span v-if="record.internal" class="system-flag">{{ t('system.orgTemplate.isSystem') }}</span>
|
||||
</template>
|
||||
<template #apiFieldId="{ record }">
|
||||
<a-input
|
||||
v-model="record.apiFieldId"
|
||||
class="min-w-[200px] max-w-[300px]"
|
||||
:placeholder="t('system.orgTemplate.apiInputPlaceholder')"
|
||||
allow-clear
|
||||
/>
|
||||
</template>
|
||||
<template #defaultValue="{ record }">
|
||||
<div class="form-create-wrapper w-full">
|
||||
<MsFormCreate v-model:api="record.fApi" :rule="record.formRules" :option="configOptions" />
|
||||
|
@ -27,11 +35,10 @@
|
|||
<AddFieldToTemplateDrawer
|
||||
ref="fieldSelectRef"
|
||||
v-model:visible="showDrawer"
|
||||
:system-data="(systemData as DefinedFieldItem[])"
|
||||
:custom-data="(customData as DefinedFieldItem[])"
|
||||
:selected-data="(templateStore.previewList as DefinedFieldItem[])"
|
||||
:total-data="(totalData as DefinedFieldItem[])"
|
||||
:table-select-data="(selectList as DefinedFieldItem[])"
|
||||
@confirm="confirmHandler"
|
||||
@update="updateFieldHandler"
|
||||
@update-data="updateFieldHandler"
|
||||
/>
|
||||
<a-button class="mt-3 px-0" type="text" @click="addField">
|
||||
<template #icon>
|
||||
|
@ -47,7 +54,6 @@
|
|||
import { useRoute } from 'vue-router';
|
||||
|
||||
import MsButton from '@/components/pure/ms-button/index.vue';
|
||||
import { FieldTypeFormRules } from '@/components/pure/ms-form-create/form-create';
|
||||
import MsFormCreate from '@/components/pure/ms-form-create/formCreate.vue';
|
||||
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
|
||||
import { MsTableColumn } from '@/components/pure/ms-table/type';
|
||||
|
@ -55,40 +61,46 @@
|
|||
import AddFieldToTemplateDrawer from './addFieldToTemplateDrawer.vue';
|
||||
import EditFieldDrawer from './editFieldDrawer.vue';
|
||||
|
||||
import { getFieldList } from '@/api/modules/setting/template';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { useAppStore, useTableStore } from '@/store';
|
||||
import useTemplateStore from '@/store/modules/setting/template';
|
||||
import { useTableStore } from '@/store';
|
||||
|
||||
import type { CustomField, DefinedFieldItem } from '@/models/setting/template';
|
||||
import type { DefinedFieldItem } from '@/models/setting/template';
|
||||
import { TableKeyEnum } from '@/enums/tableEnum';
|
||||
|
||||
import { getIconType } from './fieldSetting';
|
||||
|
||||
const tableStore = useTableStore();
|
||||
const { t } = useI18n();
|
||||
const appStore = useAppStore();
|
||||
const templateStore = useTemplateStore();
|
||||
const route = useRoute();
|
||||
|
||||
const props = defineProps<{
|
||||
customList: CustomField[]; // 用于回显表格当前选择字段
|
||||
isEdit: boolean; // 是否编辑
|
||||
}>();
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
enableThirdPart: boolean; // 是否对接第三方平台
|
||||
data: DefinedFieldItem[]; // 总字段数据
|
||||
selectData: Record<string, any>[]; // 选择数据
|
||||
}>(),
|
||||
{
|
||||
enableThirdPart: false,
|
||||
}
|
||||
);
|
||||
|
||||
const templateFieldColumns: MsTableColumn = [
|
||||
const emit = defineEmits(['update:select-data', 'update']);
|
||||
|
||||
const columns = ref<MsTableColumn>([
|
||||
{
|
||||
title: 'system.orgTemplate.name',
|
||||
slotName: 'name',
|
||||
dataIndex: 'name',
|
||||
width: 300,
|
||||
fixed: 'left',
|
||||
showDrag: true,
|
||||
showInTable: true,
|
||||
showTooltip: true,
|
||||
},
|
||||
{
|
||||
title: 'system.orgTemplate.defaultValue',
|
||||
dataIndex: 'defaultValue',
|
||||
slotName: 'defaultValue',
|
||||
width: 300,
|
||||
showDrag: true,
|
||||
showInTable: true,
|
||||
},
|
||||
|
@ -105,6 +117,7 @@
|
|||
dataIndex: 'remark',
|
||||
showDrag: true,
|
||||
showInTable: true,
|
||||
showTooltip: true,
|
||||
},
|
||||
{
|
||||
title: 'system.orgTemplate.operation',
|
||||
|
@ -114,18 +127,28 @@
|
|||
showInTable: true,
|
||||
showDrag: false,
|
||||
},
|
||||
];
|
||||
]);
|
||||
|
||||
tableStore.initColumn(TableKeyEnum.ORGANIZATION_TEMPLATE_MANAGEMENT_FIELD, templateFieldColumns, 'drawer');
|
||||
function getApiColumns() {
|
||||
return {
|
||||
title: 'system.orgTemplate.apiFieldId',
|
||||
dataIndex: 'apiFieldId',
|
||||
slotName: 'apiFieldId',
|
||||
showDrag: true,
|
||||
showInTable: true,
|
||||
width: 300,
|
||||
};
|
||||
}
|
||||
|
||||
tableStore.initColumn(TableKeyEnum.ORGANIZATION_TEMPLATE_MANAGEMENT_FIELD, columns.value, 'drawer');
|
||||
const { propsRes, propsEvent, setProps } = useTable(undefined, {
|
||||
tableKey: TableKeyEnum.ORGANIZATION_TEMPLATE_MANAGEMENT_FIELD,
|
||||
scroll: { x: '1000px' },
|
||||
scroll: { x: '1800px' },
|
||||
selectable: false,
|
||||
noDisable: true,
|
||||
size: 'default',
|
||||
showSetting: true,
|
||||
showPagination: false,
|
||||
heightUsed: 560,
|
||||
enableDrag: true,
|
||||
});
|
||||
|
||||
|
@ -148,52 +171,17 @@
|
|||
},
|
||||
});
|
||||
const showDrawer = ref<boolean>(false);
|
||||
const totalData = ref<DefinedFieldItem[]>([]);
|
||||
|
||||
const data = ref<DefinedFieldItem[]>([]);
|
||||
const systemData = ref<DefinedFieldItem[]>([]);
|
||||
const customData = ref<DefinedFieldItem[]>([]);
|
||||
const totalTemplateField = ref<DefinedFieldItem[]>([]);
|
||||
const currentOrd = appStore.currentOrgId;
|
||||
watchEffect(() => {
|
||||
totalData.value = props.data;
|
||||
});
|
||||
|
||||
// 处理表单数据格式
|
||||
const getFieldOptionList = () => {
|
||||
totalTemplateField.value = totalTemplateField.value.map((item: any) => {
|
||||
const currentFormRules = FieldTypeFormRules[item.type];
|
||||
let selectOptions: any = [];
|
||||
if (item.options && item.options.length) {
|
||||
selectOptions = item.options.map((optionItem: any) => {
|
||||
return {
|
||||
label: optionItem.text,
|
||||
value: optionItem.value,
|
||||
};
|
||||
});
|
||||
currentFormRules.options = selectOptions;
|
||||
}
|
||||
return {
|
||||
...item,
|
||||
formRules: [{ ...currentFormRules, value: item.value, props: { options: selectOptions } }],
|
||||
fApi: null,
|
||||
required: item.internal,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
// 获取当前用例模版下所有已存在字段
|
||||
const getClassifyField = async () => {
|
||||
try {
|
||||
totalTemplateField.value = await getFieldList({ organizationId: currentOrd, scene: route.query.type });
|
||||
getFieldOptionList();
|
||||
systemData.value = totalTemplateField.value.filter((item: any) => item.internal);
|
||||
customData.value = totalTemplateField.value.filter((item: any) => !item.internal);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
const selectList = ref<DefinedFieldItem[]>([]);
|
||||
|
||||
// 确定处理字段表单数据
|
||||
const confirmHandler = (dataList: DefinedFieldItem[]) => {
|
||||
data.value = dataList;
|
||||
setProps({ data: data.value });
|
||||
selectList.value = dataList;
|
||||
};
|
||||
|
||||
const showFieldDrawer = ref<boolean>(false);
|
||||
|
@ -205,77 +193,77 @@
|
|||
fieldDrawerRef.value.editHandler(record);
|
||||
};
|
||||
|
||||
const fieldSelectRef = ref();
|
||||
// 添加字段
|
||||
const addField = async () => {
|
||||
showDrawer.value = true;
|
||||
await getClassifyField();
|
||||
fieldSelectRef.value.showSelectField();
|
||||
};
|
||||
|
||||
// 编辑更新已选择字段
|
||||
const updateFieldHandler = async () => {
|
||||
await getClassifyField();
|
||||
data.value =
|
||||
totalTemplateField.value.filter((item) => data.value.some((dataItem) => item.id === dataItem.id)) || [];
|
||||
if (data.value.length > 0) {
|
||||
setProps({ data: data.value });
|
||||
}
|
||||
const updateFieldHandler = async (isEdit: boolean) => {
|
||||
emit('update', isEdit);
|
||||
};
|
||||
|
||||
// 删除已选择字段
|
||||
const deleteSelectedField = (record: DefinedFieldItem) => {
|
||||
data.value = data.value.filter((item) => item.id !== record.id);
|
||||
setProps({ data: data.value });
|
||||
};
|
||||
|
||||
// 获取table内字段customFields
|
||||
const getCustomFields = () => {
|
||||
return data.value.map((item) => {
|
||||
return {
|
||||
fieldId: item.id,
|
||||
fieldName: item.name,
|
||||
required: item.required,
|
||||
apiFieldId: '',
|
||||
defaultValue: item.fApi.formData().fieldName,
|
||||
};
|
||||
});
|
||||
};
|
||||
// 外界获取表格字段进行存储
|
||||
const getSelectFiled = () => {
|
||||
return data.value;
|
||||
selectList.value = selectList.value.filter((item) => item.id !== record.id);
|
||||
};
|
||||
|
||||
watch(
|
||||
() => data.value,
|
||||
() => selectList.value,
|
||||
(val) => {
|
||||
templateStore.setPreviewHandler(val as DefinedFieldItem[]);
|
||||
setProps({ data: templateStore.previewList });
|
||||
if (val) {
|
||||
emit('update:select-data', val);
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
const setDefaultField = async () => {
|
||||
await getClassifyField();
|
||||
data.value = systemData.value;
|
||||
};
|
||||
watch(
|
||||
() => props.selectData,
|
||||
(val) => {
|
||||
if (val) {
|
||||
selectList.value = val as DefinedFieldItem[];
|
||||
setProps({ data: selectList.value });
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
const showDetailFields = () => {};
|
||||
|
||||
onMounted(() => {
|
||||
if (props.isEdit) {
|
||||
showDetailFields();
|
||||
} else {
|
||||
data.value = templateStore.previewList;
|
||||
setProps({ data: templateStore.previewList });
|
||||
watch(
|
||||
() => props.data,
|
||||
(val) => {
|
||||
totalData.value = props.data;
|
||||
}
|
||||
);
|
||||
const tableRef = ref();
|
||||
|
||||
// 是否开启三方API
|
||||
watch(
|
||||
() => props.enableThirdPart,
|
||||
() => {
|
||||
if (props.enableThirdPart) {
|
||||
const result = [...columns.value.slice(0, 1), getApiColumns(), ...columns.value.slice(1)];
|
||||
tableStore.setColumns(TableKeyEnum.ORGANIZATION_TEMPLATE_MANAGEMENT_FIELD, result, 'drawer');
|
||||
tableRef.value.initColumn();
|
||||
} else {
|
||||
tableStore.setColumns(TableKeyEnum.ORGANIZATION_TEMPLATE_MANAGEMENT_FIELD, columns.value, 'drawer');
|
||||
tableRef.value.initColumn();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// 获取拖拽数据
|
||||
const dragTableData = computed(() => {
|
||||
return propsRes.value.data;
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
getCustomFields,
|
||||
getSelectFiled,
|
||||
setDefaultField,
|
||||
});
|
||||
watch(
|
||||
() => dragTableData.value,
|
||||
(val) => {
|
||||
selectList.value = dragTableData.value as DefinedFieldItem[];
|
||||
emit('update:select-data', val);
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
|
@ -287,4 +275,8 @@
|
|||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
.system-flag {
|
||||
background: var(--color-text-n8);
|
||||
@apply ml-2 rounded p-1 text-xs;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -88,7 +88,11 @@
|
|||
</a-form>
|
||||
</div>
|
||||
<div class="preview-right px-4">
|
||||
<MsFormCreate :form-rule="formRules" :form-create-key="FormCreateKeyEnum.ORGANIZE_TEMPLATE_PREVIEW_TEMPLATE" />
|
||||
<MsFormCreate
|
||||
ref="formCreateRef"
|
||||
:form-rule="formRules"
|
||||
:form-create-key="FormCreateKeyEnum.ORGANIZE_TEMPLATE_PREVIEW_TEMPLATE"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -116,7 +120,7 @@
|
|||
const tableStore = useTableStore();
|
||||
|
||||
const props = defineProps<{
|
||||
selectField: DefinedFieldItem[];
|
||||
selectField: DefinedFieldItem[]; // 选择模板字段
|
||||
}>();
|
||||
|
||||
const templateFieldColumns: MsTableColumn = [
|
||||
|
@ -151,6 +155,7 @@
|
|||
showDrag: false,
|
||||
},
|
||||
];
|
||||
|
||||
tableStore.initColumn(TableKeyEnum.ORGANIZATION_TEMPLATE_MANAGEMENT_STEP, templateFieldColumns, 'drawer');
|
||||
const { propsRes, propsEvent, setProps } = useTable(undefined, {
|
||||
tableKey: TableKeyEnum.ORGANIZATION_TEMPLATE_MANAGEMENT_STEP,
|
||||
|
@ -186,8 +191,9 @@
|
|||
eventTag: 'delete',
|
||||
},
|
||||
];
|
||||
|
||||
const addStep = () => {};
|
||||
const handlerDelete = () => {};
|
||||
|
||||
// 更多操作
|
||||
const handleMoreActionSelect = (item: ActionsItem) => {
|
||||
if (item.eventTag === 'delete') {
|
||||
|
@ -195,10 +201,10 @@
|
|||
}
|
||||
};
|
||||
|
||||
const addStep = () => {};
|
||||
|
||||
const formRuleField = ref<FormItem[][]>([]);
|
||||
const formRules = ref<FormItem[]>([]);
|
||||
const formCreateRef = ref();
|
||||
|
||||
// 处理表单格式
|
||||
const getFormRules = () => {
|
||||
if (props.selectField && props.selectField.length) {
|
||||
|
@ -217,6 +223,10 @@
|
|||
value: rule.value,
|
||||
options: optionsItem,
|
||||
required: item.required,
|
||||
props: {
|
||||
modelValue: rule.value,
|
||||
options: optionsItem,
|
||||
},
|
||||
};
|
||||
});
|
||||
formRuleField.value.push(currentFormItem as FormItem[]);
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
isShowTip.value = !getIsVisited();
|
||||
};
|
||||
onBeforeMount(() => {
|
||||
templateStore.setStatus();
|
||||
templateStore.getStatus();
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
|
|
|
@ -59,6 +59,8 @@ export default {
|
|||
'system.orgTemplate.dateFormat': 'Date format',
|
||||
'system.orgTemplate.formatPlaceholder': 'Please select a format',
|
||||
'system.orgTemplate.optionsPlaceholder': 'Please enter options',
|
||||
'system.orgTemplate.optionsIdPlaceholder': 'Please enter options ID',
|
||||
'system.orgTemplate.optionsIdTip': 'The option ID cannot be empty',
|
||||
'system.orgTemplate.columnTemplateName': 'Template name',
|
||||
'system.orgTemplate.copy': 'Copy',
|
||||
'system.orgTemplate.defaultValue': 'Default value',
|
||||
|
@ -92,4 +94,13 @@ export default {
|
|||
'system.orgTemplate.expectationTip': 'Please enter expectations',
|
||||
'system.orgTemplate.addAttachment': 'Add attachment',
|
||||
'system.orgTemplate.addAttachmentTip': 'Support any type of file, the file size does not exceed 500MB',
|
||||
'system.orgTemplate.enabledSuccessfully': 'Enabled successfully',
|
||||
'system.orgTemplate.thirdPartyPlatforms': 'Used to map field values for third-party platforms such as JARA',
|
||||
'system.orgTemplate.optionsIdNoRepeat': 'The option ID must be unique',
|
||||
'system.orgTemplate.optionsContentNoRepeat': 'The options cannot be repeated',
|
||||
'system.orgTemplate.thirdParty': 'Connect to third-party platforms',
|
||||
'system.orgTemplate.deleteTemplateTitle': 'Are you sure to delete { name }?',
|
||||
'system.orgTemplate.apiInputPlaceholder': 'Please enter a third-party API',
|
||||
'system.orgTemplate.apiFieldId': 'API field',
|
||||
'system.orgTemplate.copyTemplate': 'Copy Template',
|
||||
};
|
||||
|
|
|
@ -58,6 +58,8 @@ export default {
|
|||
'system.orgTemplate.dateFormat': '日期格式',
|
||||
'system.orgTemplate.formatPlaceholder': '请选择格式',
|
||||
'system.orgTemplate.optionsPlaceholder': '请输入选项',
|
||||
'system.orgTemplate.optionsIdPlaceholder': '请输入选项ID',
|
||||
'system.orgTemplate.optionsIdTip': '选项ID不能为空',
|
||||
'system.orgTemplate.updateTip': '确认更新 `{name}` 吗?',
|
||||
'system.orgTemplate.updateDescription': '更新后,所使用该字段模版将一起修改',
|
||||
'system.orgTemplate.confirm': '确定',
|
||||
|
@ -94,4 +96,13 @@ export default {
|
|||
'system.orgTemplate.expectationTip': '请输入预期',
|
||||
'system.orgTemplate.addAttachment': '添加附件',
|
||||
'system.orgTemplate.addAttachmentTip': '支持任意类型文件,文件大小不超过 500MB',
|
||||
'system.orgTemplate.enabledSuccessfully': '启用成功',
|
||||
'system.orgTemplate.thirdPartyPlatforms': '用于映射 JARA 等第三方平台字段值',
|
||||
'system.orgTemplate.optionsIdNoRepeat': '选项 ID 不可以重复',
|
||||
'system.orgTemplate.optionsContentNoRepeat': '选项内容不可以重复',
|
||||
'system.orgTemplate.thirdParty': '对接第三方平台',
|
||||
'system.orgTemplate.deleteTemplateTitle': '确认删除 {name} 吗?',
|
||||
'system.orgTemplate.apiInputPlaceholder': '请输入第三方 API',
|
||||
'system.orgTemplate.apiFieldId': 'API 字段',
|
||||
'system.orgTemplate.copyTemplate': '复制模板',
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue