From d5dae013d54e1e74390669a88241f6b8d4c1ec18 Mon Sep 17 00:00:00 2001
From: zhengyiming <540361168@qq.com>
Date: 星期四, 21 八月 2025 10:32:52 +0800
Subject: [PATCH] fix: 签约
---
src/constants/apiEnumText.ts | 6
.eslintrc-auto-import.json | 9
src/services/api/typings.d.ts | 273 +++++++++++++++++++++
src/views/ProtocolManage/components/AddOrEditTemplateDialog.vue | 28 -
src/views/ProtocolManage/EditTemplate.vue | 142 ++++++++--
src/hooks/log.ts | 63 ++++
src/components/Dialog/OperateHistoryLogDialog.vue | 23
src/services/api/electronSign.ts | 99 +++++++
src/views/ProtocolManage/ProtocolManageList.vue | 18
auto-imports.d.ts | 20 +
src/constants/electronSign.ts | 14 +
src/constants/apiEnum.ts | 34 ++
src/constants/index.ts | 1
13 files changed, 660 insertions(+), 70 deletions(-)
diff --git a/.eslintrc-auto-import.json b/.eslintrc-auto-import.json
index b0c49f8..dde625c 100644
--- a/.eslintrc-auto-import.json
+++ b/.eslintrc-auto-import.json
@@ -25,8 +25,16 @@
"EnumBillingMethodUnitText": true,
"EnumClientType": true,
"EnumClientTypeText": true,
+ "EnumContractTemplateStatus": true,
+ "EnumContractTemplateStatusText": true,
+ "EnumContractTemplateStatusTextForEnterpriseFilter": true,
+ "EnumContractTemplateValueRecorder": true,
+ "EnumContractTemplateValueType": true,
"EnumDataSource": true,
"EnumDbAuditOperate": true,
+ "EnumDbAuditOperateText": true,
+ "EnumElectronSignAccess": true,
+ "EnumElectronSignAccessText": true,
"EnumEnterpriseRealMethod": true,
"EnumMenuType": true,
"EnumMenuVisitLevel": true,
@@ -223,6 +231,7 @@
"useModel": true,
"useOmit": true,
"useOmitProps": true,
+ "useOpenLogDialog": true,
"usePortraitTable": true,
"usePortraitTableWithAttachment": true,
"useResizeHander": true,
diff --git a/auto-imports.d.ts b/auto-imports.d.ts
index d88e9e7..b9623fd 100644
--- a/auto-imports.d.ts
+++ b/auto-imports.d.ts
@@ -33,8 +33,16 @@
const EnumBillingMethodUnitText: typeof import('./src/constants/task')['EnumBillingMethodUnitText']
const EnumClientType: typeof import('./src/constants/apiEnum')['EnumClientType']
const EnumClientTypeText: typeof import('./src/constants/apiEnumText')['EnumClientTypeText']
+ const EnumContractTemplateStatus: typeof import('./src/constants/apiEnum')['EnumContractTemplateStatus']
+ const EnumContractTemplateStatusText: typeof import('./src/constants/electronSign')['EnumContractTemplateStatusText']
+ const EnumContractTemplateStatusTextForEnterpriseFilter: typeof import('./src/constants/electronSign')['EnumContractTemplateStatusTextForEnterpriseFilter']
+ const EnumContractTemplateValueRecorder: typeof import('./src/constants/apiEnum')['EnumContractTemplateValueRecorder']
+ const EnumContractTemplateValueType: typeof import('./src/constants/apiEnum')['EnumContractTemplateValueType']
const EnumDataSource: typeof import('./src/constants/apiEnum')['EnumDataSource']
const EnumDbAuditOperate: typeof import('./src/constants/apiEnum')['EnumDbAuditOperate']
+ const EnumDbAuditOperateText: typeof import('./src/constants/apiEnumText')['EnumDbAuditOperateText']
+ const EnumElectronSignAccess: typeof import('./src/constants/apiEnum')['EnumElectronSignAccess']
+ const EnumElectronSignAccessText: typeof import('./src/constants/electronSign')['EnumElectronSignAccessText']
const EnumEnterpriseRealMethod: typeof import('./src/constants/apiEnum')['EnumEnterpriseRealMethod']
const EnumMenuType: typeof import('./src/constants/apiEnum')['EnumMenuType']
const EnumMenuVisitLevel: typeof import('./src/constants/apiEnum')['EnumMenuVisitLevel']
@@ -236,6 +244,7 @@
const useModel: typeof import('vue')['useModel']
const useOmit: typeof import('./src/hooks/help')['useOmit']
const useOmitProps: typeof import('./src/hooks/help')['useOmitProps']
+ const useOpenLogDialog: typeof import('./src/hooks/log')['useOpenLogDialog']
const usePortraitTable: typeof import('./src/hooks/portraitTable')['usePortraitTable']
const usePortraitTableWithAttachment: typeof import('./src/hooks/portraitTable')['usePortraitTableWithAttachment']
const useResizeHander: typeof import('./src/hooks/useResizeHander')['useResizeHander']
@@ -259,7 +268,7 @@
export type { Component, Slot, Slots, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
import('vue')
// @ts-ignore
- export type { EnumBillingMethod, EnumClientType, EnumDataSource, EnumDbAuditOperate, EnumEnterpriseRealMethod, EnumMenuType, EnumMenuVisitLevel, EnumOcrAccess, EnumPagedListOrder, EnumPayAccess, EnumPersonalFreeTime, EnumPersonalJobSeekingStatus, EnumPersonalRealMethod, EnumRealAccess, EnumResourceController, EnumResourceMethod, EnumRoleWebApiDataPower, EnumSettlementCycle, EnumSmsAccess, EnumTaskCheckReceiveStatus, EnumTaskRecommendStatus, EnumTaskReleaseStatus, EnumTaskSettlementStatus, EnumTaskStatus, EnumTaskUserArrangeStatus, EnumTaskUserHireStatus, EnumTaskUserSignContractStatus, EnumTaskUserSubmitCheckReceiveStatus, EnumUserGender, EnumUserRealMethod, EnumUserStatus, EnumUserType, GetPersonalApplyTaskInfosQueryStatus, GetPersonalHireTaskInfosQueryStatus, GetTaskInfoQueryResultApplyButton, GetTaskInfoQueryResultHireButton, EnumBillingMethod, EnumClientType, EnumDataSource, EnumDbAuditOperate, EnumEnterpriseRealMethod, EnumMenuType, EnumMenuVisitLevel, EnumOcrAccess, EnumPagedListOrder, EnumPayAccess, EnumPersonalFreeTime, EnumPersonalJobSeekingStatus, EnumPersonalRealMethod, EnumRealAccess, EnumResourceController, EnumResourceMethod, EnumRoleWebApiDataPower, EnumSettlementCycle, EnumSmsAccess, EnumTaskCheckReceiveStatus, EnumTaskRecommendStatus, EnumTaskReleaseStatus, EnumTaskSettlementStatus, EnumTaskStatus, EnumTaskUserArrangeStatus, EnumTaskUserHireStatus, EnumTaskUserSignContractStatus, EnumTaskUserSubmitCheckReceiveStatus, EnumUserGender, EnumUserRealMethod, EnumUserStatus, EnumUserType, GetPersonalApplyTaskInfosQueryStatus, GetPersonalHireTaskInfosQueryStatus, GetTaskInfoQueryResultApplyButton, GetTaskInfoQueryResultHireButton } from './src/constants/apiEnum'
+ export type { EnumBillingMethod, EnumClientType, EnumContractTemplateStatus, EnumContractTemplateValueRecorder, EnumContractTemplateValueType, EnumDataSource, EnumDbAuditOperate, EnumElectronSignAccess, EnumEnterpriseRealMethod, EnumMenuType, EnumMenuVisitLevel, EnumOcrAccess, EnumPagedListOrder, EnumPayAccess, EnumPersonalFreeTime, EnumPersonalJobSeekingStatus, EnumPersonalRealMethod, EnumRealAccess, EnumResourceController, EnumResourceMethod, EnumRoleWebApiDataPower, EnumSettlementCycle, EnumSmsAccess, EnumTaskCheckReceiveStatus, EnumTaskRecommendStatus, EnumTaskReleaseStatus, EnumTaskSettlementStatus, EnumTaskStatus, EnumTaskUserArrangeStatus, EnumTaskUserHireStatus, EnumTaskUserSignContractStatus, EnumTaskUserSubmitCheckReceiveStatus, EnumUserGender, EnumUserRealMethod, EnumUserStatus, EnumUserType, GetPersonalApplyTaskInfosQueryStatus, GetPersonalHireTaskInfosQueryStatus, GetTaskInfoQueryResultApplyButton, GetTaskInfoQueryResultHireButton, EnumBillingMethod, EnumClientType, EnumContractTemplateStatus, EnumContractTemplateValueRecorder, EnumContractTemplateValueType, EnumDataSource, EnumDbAuditOperate, EnumElectronSignAccess, EnumEnterpriseRealMethod, EnumMenuType, EnumMenuVisitLevel, EnumOcrAccess, EnumPagedListOrder, EnumPayAccess, EnumPersonalFreeTime, EnumPersonalJobSeekingStatus, EnumPersonalRealMethod, EnumRealAccess, EnumResourceController, EnumResourceMethod, EnumRoleWebApiDataPower, EnumSettlementCycle, EnumSmsAccess, EnumTaskCheckReceiveStatus, EnumTaskRecommendStatus, EnumTaskReleaseStatus, EnumTaskSettlementStatus, EnumTaskStatus, EnumTaskUserArrangeStatus, EnumTaskUserHireStatus, EnumTaskUserSignContractStatus, EnumTaskUserSubmitCheckReceiveStatus, EnumUserGender, EnumUserRealMethod, EnumUserStatus, EnumUserType, GetPersonalApplyTaskInfosQueryStatus, GetPersonalHireTaskInfosQueryStatus, GetTaskInfoQueryResultApplyButton, GetTaskInfoQueryResultHireButton } from './src/constants/apiEnum'
import('./src/constants/apiEnum')
// @ts-ignore
export type { FlexWorkerEleSignEnum, FlexTaskWorkerHireEnum, FlexWorkerEleSignEnum, FlexTaskWorkerHireEnum } from './src/constants/cPerson'
@@ -322,8 +331,16 @@
readonly EnumBillingMethodUnitText: UnwrapRef<typeof import('./src/constants/task')['EnumBillingMethodUnitText']>
readonly EnumClientType: UnwrapRef<typeof import('./src/constants/apiEnum')['EnumClientType']>
readonly EnumClientTypeText: UnwrapRef<typeof import('./src/constants/apiEnumText')['EnumClientTypeText']>
+ readonly EnumContractTemplateStatus: UnwrapRef<typeof import('./src/constants/apiEnum')['EnumContractTemplateStatus']>
+ readonly EnumContractTemplateStatusText: UnwrapRef<typeof import('./src/constants/electronSign')['EnumContractTemplateStatusText']>
+ readonly EnumContractTemplateStatusTextForEnterpriseFilter: UnwrapRef<typeof import('./src/constants/electronSign')['EnumContractTemplateStatusTextForEnterpriseFilter']>
+ readonly EnumContractTemplateValueRecorder: UnwrapRef<typeof import('./src/constants/apiEnum')['EnumContractTemplateValueRecorder']>
+ readonly EnumContractTemplateValueType: UnwrapRef<typeof import('./src/constants/apiEnum')['EnumContractTemplateValueType']>
readonly EnumDataSource: UnwrapRef<typeof import('./src/constants/apiEnum')['EnumDataSource']>
readonly EnumDbAuditOperate: UnwrapRef<typeof import('./src/constants/apiEnum')['EnumDbAuditOperate']>
+ readonly EnumDbAuditOperateText: UnwrapRef<typeof import('./src/constants/apiEnumText')['EnumDbAuditOperateText']>
+ readonly EnumElectronSignAccess: UnwrapRef<typeof import('./src/constants/apiEnum')['EnumElectronSignAccess']>
+ readonly EnumElectronSignAccessText: UnwrapRef<typeof import('./src/constants/electronSign')['EnumElectronSignAccessText']>
readonly EnumEnterpriseRealMethod: UnwrapRef<typeof import('./src/constants/apiEnum')['EnumEnterpriseRealMethod']>
readonly EnumMenuType: UnwrapRef<typeof import('./src/constants/apiEnum')['EnumMenuType']>
readonly EnumMenuVisitLevel: UnwrapRef<typeof import('./src/constants/apiEnum')['EnumMenuVisitLevel']>
@@ -499,6 +516,7 @@
readonly useModel: UnwrapRef<typeof import('vue')['useModel']>
readonly useOmit: UnwrapRef<typeof import('./src/hooks/help')['useOmit']>
readonly useOmitProps: UnwrapRef<typeof import('./src/hooks/help')['useOmitProps']>
+ readonly useOpenLogDialog: UnwrapRef<typeof import('./src/hooks/log')['useOpenLogDialog']>
readonly usePortraitTable: UnwrapRef<typeof import('./src/hooks/portraitTable')['usePortraitTable']>
readonly usePortraitTableWithAttachment: UnwrapRef<typeof import('./src/hooks/portraitTable')['usePortraitTableWithAttachment']>
readonly useResizeHander: UnwrapRef<typeof import('./src/hooks/useResizeHander')['useResizeHander']>
diff --git a/src/components/Dialog/OperateHistoryLogDialog.vue b/src/components/Dialog/OperateHistoryLogDialog.vue
index 0970604..d751cd0 100644
--- a/src/components/Dialog/OperateHistoryLogDialog.vue
+++ b/src/components/Dialog/OperateHistoryLogDialog.vue
@@ -24,8 +24,7 @@
</template>
<script setup lang="ts">
-import { ProDialog, ProTableV2, ProDialogTableWrapper } from '@bole-core/components';
-import { useTableLogList } from '@/hooks';
+import { ProDialog, ProTableV2, ProDialogTableWrapper, defineColumns } from '@bole-core/components';
defineOptions({
name: 'OperateHistoryLogDialog',
@@ -34,7 +33,8 @@
type Props = {
modelValue: boolean;
relationId: string;
- operateType?: number;
+ getList: (pageIndex?: number) => Promise<void>;
+ proTableProps: any;
};
const props = withDefaults(defineProps<Props>(), {
@@ -59,18 +59,17 @@
() => props.modelValue,
async (visible, oldVisible) => {
if (!oldVisible && visible) {
- await getList();
- state.loading = false;
+ await props.getList();
}
}
);
-function onDialogClose() {
- state.loading = true;
-}
+const OperateHistoryTableColumns = defineColumns([
+ { id: '1', enCode: 'createdUser', name: '鎿嶄綔浜�' },
+ { id: '2', enCode: 'createdTime', name: '鎿嶄綔鏃堕棿', width: 180 },
+ { id: '3', enCode: 'operate', name: '鎿嶄綔' },
+ { id: '4', enCode: 'content', name: '鎿嶄綔鍐呭' },
+]);
-const { getList, proTableProps, state, OperateHistoryTableColumns } = useTableLogList({
- relationId: toRef(props, 'relationId'),
- operateType: toRef(props, 'operateType'),
-});
+function onDialogClose() {}
</script>
diff --git a/src/constants/apiEnum.ts b/src/constants/apiEnum.ts
index bd24f08..b91d90e 100644
--- a/src/constants/apiEnum.ts
+++ b/src/constants/apiEnum.ts
@@ -21,6 +21,32 @@
Wxmp = 20,
}
+/** 鍚堝悓鍒剁増鐘舵�� */
+export enum EnumContractTemplateStatus {
+ /**寰呭埗鐗� */
+ Wait = 10,
+ /**宸插畬鎴� */
+ Completed = 20,
+}
+
+/** 鍚堝悓妯℃澘鍙橀噺 */
+export enum EnumContractTemplateValueRecorder {
+ /**鍙戜欢浜� */
+ Creator = 10,
+ /**绛剧讲浜� */
+ Signer = 20,
+}
+
+/** 鍚堝悓妯℃澘鍙橀噺绫诲瀷 */
+export enum EnumContractTemplateValueType {
+ /**鏂囨湰 */
+ Text = 10,
+ /**绛剧讲 */
+ Sign = 20,
+ /**鏃ユ湡 */
+ Date = 30,
+}
+
/** 鏁版嵁鏉ユ簮 */
export enum EnumDataSource {
/**818 */
@@ -37,6 +63,14 @@
Deleted = 30,
}
+/** 鐢靛瓙绛� */
+export enum EnumElectronSignAccess {
+ /**涓婁笂绛� */
+ BestSign = 10,
+ /**鏀粯瀹濅俊浠荤 */
+ AlipaySign = 20,
+}
+
/** 浼佷笟瀹炲悕鏂瑰紡 */
export enum EnumEnterpriseRealMethod {
/**浼佷笟涓夎绱� */
diff --git a/src/constants/apiEnumText.ts b/src/constants/apiEnumText.ts
index 392c27d..47bb79e 100644
--- a/src/constants/apiEnumText.ts
+++ b/src/constants/apiEnumText.ts
@@ -24,3 +24,9 @@
[EnumRoleWebApiDataPower.Creator]: '涓汉鏁版嵁',
[EnumRoleWebApiDataPower.All]: '鍏ㄩ儴鏁版嵁',
};
+
+export const EnumDbAuditOperateText = {
+ [EnumDbAuditOperate.Added]: '娣诲姞',
+ [EnumDbAuditOperate.Modified]: '淇敼',
+ [EnumDbAuditOperate.Deleted]: '鍒犻櫎',
+};
diff --git a/src/constants/electronSign.ts b/src/constants/electronSign.ts
new file mode 100644
index 0000000..7476a74
--- /dev/null
+++ b/src/constants/electronSign.ts
@@ -0,0 +1,14 @@
+export const EnumContractTemplateStatusText = {
+ [EnumContractTemplateStatus.Wait]: '寰呭埗鐗�',
+ [EnumContractTemplateStatus.Completed]: '宸插埗鐗�',
+};
+
+export const EnumContractTemplateStatusTextForEnterpriseFilter = {
+ [EnumContractTemplateStatus.Wait]: '寰呭埗鐗�',
+ [EnumContractTemplateStatus.Completed]: '宸插埗鐗�',
+};
+
+export const EnumElectronSignAccessText = {
+ [EnumElectronSignAccess.BestSign]: '涓婁笂绛�',
+ [EnumElectronSignAccess.AlipaySign]: '鏀粯瀹濅俊浠荤',
+};
diff --git a/src/constants/index.ts b/src/constants/index.ts
index 8a2ccbf..3e0e9fc 100644
--- a/src/constants/index.ts
+++ b/src/constants/index.ts
@@ -18,3 +18,4 @@
export * from './dic';
export * from './task';
export * from './enterpriseEmployee';
+export * from './electronSign';
diff --git a/src/hooks/log.ts b/src/hooks/log.ts
new file mode 100644
index 0000000..d04f147
--- /dev/null
+++ b/src/hooks/log.ts
@@ -0,0 +1,63 @@
+import { useDialog, useTable, Service, Data, ExtraParams } from '@bole-core/components';
+
+type UseOpenLogDialogOptions<TData extends Data, TExtraParams extends ExtraParams> = {
+ service: Service<TData, { id: string } & ExtraParams>;
+};
+
+export function useOpenLogDialog<TData extends Data, TExtraParams extends ExtraParams>({
+ service,
+}: UseOpenLogDialogOptions<TData, TExtraParams>) {
+ const relationId = ref('');
+
+ const { dialogProps, dialogState } = useDialog();
+
+ async function openLogDialog(_relationId: string) {
+ // relationId.value = _relationId;
+ extraParamState.id = _relationId;
+ await nextTick();
+ dialogState.dialogVisible = true;
+ }
+
+ const BaseState = {
+ loading: false,
+ };
+
+ const state = reactive({ ...BaseState });
+
+ const {
+ getDataSource: getList,
+ proTableProps,
+ extraParamState,
+ } = useTable(service, {
+ defaultExtraParams: {
+ orderInput: [{ property: 'createdTime', order: EnumPagedListOrder.Desc }],
+ id: '',
+ },
+ columnsRenderProps: {
+ createdTime: {
+ type: 'date',
+ format: 'YYYY-MM-DD HH:mm:ss',
+ },
+ content: {
+ formatter: (row) => (row.content ?? []).join(','),
+ },
+ operate: {
+ type: 'enum',
+ valueEnum: EnumDbAuditOperateText,
+ },
+ },
+ });
+
+ const logDialogProps = computed(() => {
+ return {
+ ...dialogProps.value,
+ relationId: relationId.value,
+ getList: getList,
+ proTableProps: proTableProps.value,
+ };
+ });
+ return {
+ logDialogProps,
+ openLogDialog,
+ };
+}
diff --git a/src/services/api/electronSign.ts b/src/services/api/electronSign.ts
index 77c1101..b649bcb 100644
--- a/src/services/api/electronSign.ts
+++ b/src/services/api/electronSign.ts
@@ -17,6 +17,75 @@
});
}
+/** 鏌ヨ鍚堝悓妯℃澘璇︽儏 GET /api/user/electronSign/getContractTemplate */
+export async function getContractTemplate(
+ // 鍙犲姞鐢熸垚鐨凱aram绫诲瀷 (闈瀊ody鍙傛暟swagger榛樿娌℃湁鐢熸垚瀵硅薄)
+ params: API.APIgetContractTemplateParams,
+ options?: API.RequestConfig
+) {
+ return request<API.GetContractTemplateQueryResult>('/api/user/electronSign/getContractTemplate', {
+ method: 'GET',
+ params: {
+ ...params,
+ },
+ ...(options || {}),
+ });
+}
+
+/** 鏌ヨ杩愯惀绔崗璁鐞嗗垎椤靛垪琛ㄦ暟鎹� POST /api/user/electronSign/getContractTemplateEnterprises */
+export async function getContractTemplateEnterprises(
+ body: API.GetContractTemplateEnterprisesQuery,
+ options?: API.RequestConfig
+) {
+ return request<API.GetContractTemplateEnterprisesQueryResult>(
+ '/api/user/electronSign/getContractTemplateEnterprises',
+ {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json-patch+json',
+ },
+ data: body,
+ ...(options || {}),
+ }
+ );
+}
+
+/** 鏌ヨ浼佷笟鍚堝悓妯℃澘鏃ュ織鍒嗛〉鍒楄〃鏁版嵁 POST /api/user/electronSign/getEnterpriseContractTemplateLogs */
+export async function getEnterpriseContractTemplateLogs(
+ body: API.GetEnterpriseContractTemplateLogsQuery,
+ options?: API.RequestConfig
+) {
+ return request<API.GetEnterpriseContractTemplateLogsQueryResult>(
+ '/api/user/electronSign/getEnterpriseContractTemplateLogs',
+ {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json-patch+json',
+ },
+ data: body,
+ ...(options || {}),
+ }
+ );
+}
+
+/** 鏌ヨ浼佷笟鍚堝悓妯℃澘鍒嗛〉鍒楄〃鏁版嵁 POST /api/user/electronSign/getEnterpriseContractTemplates */
+export async function getEnterpriseContractTemplates(
+ body: API.GetEnterpriseContractTemplatesQuery,
+ options?: API.RequestConfig
+) {
+ return request<API.GetEnterpriseContractTemplatesQueryResult>(
+ '/api/user/electronSign/getEnterpriseContractTemplates',
+ {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json-patch+json',
+ },
+ data: body,
+ ...(options || {}),
+ }
+ );
+}
+
/** 涓汉浜鸿劯瀹炲悕璁よ瘉 POST /api/user/electronSign/personalUserFaceReal */
export async function personalUserFaceReal(
body: API.PersonalUserFaceRealCommand,
@@ -47,6 +116,21 @@
});
}
+/** 淇濆瓨鍚堝悓妯℃澘 POST /api/user/electronSign/saveContractTemplate */
+export async function saveContractTemplate(
+ body: API.SaveContractTemplateCommand,
+ options?: API.RequestConfig
+) {
+ return request<string>('/api/user/electronSign/saveContractTemplate', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json-patch+json',
+ },
+ data: body,
+ ...(options || {}),
+ });
+}
+
/** 鍙戦�佷釜浜轰笁瑕佺礌瀹炲悕鐭俊 POST /api/user/electronSign/sendPersonalUserIdentity3RealSms */
export async function sendPersonalUserIdentity3RealSms(
body: API.SendPersonalUserIdentity3RealSmsCommand,
@@ -61,3 +145,18 @@
...(options || {}),
});
}
+
+/** 绂佺敤鍚堝悓妯℃澘 PUT /api/user/electronSign/setIsDisabledContractTemplate */
+export async function setIsDisabledContractTemplate(
+ body: API.SetIsDisabledContractTemplateCommand,
+ options?: API.RequestConfig
+) {
+ return request<number>('/api/user/electronSign/setIsDisabledContractTemplate', {
+ method: 'PUT',
+ headers: {
+ 'Content-Type': 'application/json-patch+json',
+ },
+ data: body,
+ ...(options || {}),
+ });
+}
diff --git a/src/services/api/typings.d.ts b/src/services/api/typings.d.ts
index 584f731..04356b2 100644
--- a/src/services/api/typings.d.ts
+++ b/src/services/api/typings.d.ts
@@ -29,6 +29,11 @@
date?: string;
}
+ interface APIgetContractTemplateParams {
+ /** 妯℃澘Id */
+ id?: string;
+ }
+
interface APIgetCurrentLogierMenuParams {
/** Id */
id?: string;
@@ -359,6 +364,29 @@
Wxmp = 20,
}
+ enum EnumContractTemplateStatus {
+ /**寰呭埗鐗� */
+ Wait = 10,
+ /**宸插畬鎴� */
+ Completed = 20,
+ }
+
+ enum EnumContractTemplateValueRecorder {
+ /**鍙戜欢浜� */
+ Creator = 10,
+ /**绛剧讲浜� */
+ Signer = 20,
+ }
+
+ enum EnumContractTemplateValueType {
+ /**鏂囨湰 */
+ Text = 10,
+ /**绛剧讲 */
+ Sign = 20,
+ /**鏃ユ湡 */
+ Date = 30,
+ }
+
enum EnumDataSource {
/**818 */
HumanResources = 10,
@@ -371,6 +399,13 @@
Modified = 20,
/**鍒犻櫎 */
Deleted = 30,
+ }
+
+ enum EnumElectronSignAccess {
+ /**涓婁笂绛� */
+ BestSign = 10,
+ /**鏀粯瀹濅俊浠荤 */
+ AlipaySign = 20,
}
enum EnumEnterpriseRealMethod {
@@ -775,6 +810,42 @@
timestamp?: number;
}
+ interface FriendlyResultGetContractTemplateEnterprisesQueryResult {
+ /** 璺熻釜Id */
+ traceId?: string;
+ /** 鐘舵�佺爜 */
+ code?: number;
+ /** 閿欒鐮� */
+ errorCode?: string;
+ data?: GetContractTemplateEnterprisesQueryResult;
+ /** 鎵ц鎴愬姛 */
+ success?: boolean;
+ /** 閿欒淇℃伅 */
+ msg?: any;
+ /** 闄勫姞鏁版嵁 */
+ extras?: any;
+ /** 鏃堕棿鎴� */
+ timestamp?: number;
+ }
+
+ interface FriendlyResultGetContractTemplateQueryResult {
+ /** 璺熻釜Id */
+ traceId?: string;
+ /** 鐘舵�佺爜 */
+ code?: number;
+ /** 閿欒鐮� */
+ errorCode?: string;
+ data?: GetContractTemplateQueryResult;
+ /** 鎵ц鎴愬姛 */
+ success?: boolean;
+ /** 閿欒淇℃伅 */
+ msg?: any;
+ /** 闄勫姞鏁版嵁 */
+ extras?: any;
+ /** 鏃堕棿鎴� */
+ timestamp?: number;
+ }
+
interface FriendlyResultGetDbAuditLogsQueryResult {
/** 璺熻釜Id */
traceId?: string;
@@ -783,6 +854,42 @@
/** 閿欒鐮� */
errorCode?: string;
data?: GetDbAuditLogsQueryResult;
+ /** 鎵ц鎴愬姛 */
+ success?: boolean;
+ /** 閿欒淇℃伅 */
+ msg?: any;
+ /** 闄勫姞鏁版嵁 */
+ extras?: any;
+ /** 鏃堕棿鎴� */
+ timestamp?: number;
+ }
+
+ interface FriendlyResultGetEnterpriseContractTemplateLogsQueryResult {
+ /** 璺熻釜Id */
+ traceId?: string;
+ /** 鐘舵�佺爜 */
+ code?: number;
+ /** 閿欒鐮� */
+ errorCode?: string;
+ data?: GetEnterpriseContractTemplateLogsQueryResult;
+ /** 鎵ц鎴愬姛 */
+ success?: boolean;
+ /** 閿欒淇℃伅 */
+ msg?: any;
+ /** 闄勫姞鏁版嵁 */
+ extras?: any;
+ /** 鏃堕棿鎴� */
+ timestamp?: number;
+ }
+
+ interface FriendlyResultGetEnterpriseContractTemplatesQueryResult {
+ /** 璺熻釜Id */
+ traceId?: string;
+ /** 鐘舵�佺爜 */
+ code?: number;
+ /** 閿欒鐮� */
+ errorCode?: string;
+ data?: GetEnterpriseContractTemplatesQueryResult;
/** 鎵ц鎴愬姛 */
success?: boolean;
/** 閿欒淇℃伅 */
@@ -1959,6 +2066,66 @@
addressName?: string;
}
+ interface GetContractTemplateEnterprisesQuery {
+ /** 鍏抽敭瀛� */
+ keywords?: string;
+ status?: EnumContractTemplateStatus;
+ pageModel?: PagedListQueryPageModel;
+ }
+
+ interface GetContractTemplateEnterprisesQueryResult {
+ pageModel?: PagedListQueryResultPageModel;
+ /** 鏁版嵁 */
+ data?: GetContractTemplateEnterprisesQueryResultItem[];
+ }
+
+ interface GetContractTemplateEnterprisesQueryResultItem {
+ /** 浼佷笟Id */
+ id?: string;
+ /** 浼佷笟鍏ㄧО */
+ enterpriseName?: string;
+ /** 鑱旂郴浜� */
+ contacts?: string;
+ /** 鑱旂郴鐢佃瘽 */
+ contactPhoneNumber?: string;
+ /** 鍚堝悓鏁� */
+ total?: number;
+ /** 寰呭埗鐗� */
+ waitCount?: number;
+ }
+
+ interface GetContractTemplateQueryResult {
+ /** 妯℃澘Id */
+ id?: string;
+ /** 浼佷笟Id */
+ enterpriseId?: string;
+ /** 妯℃澘鍚嶇О */
+ name?: string;
+ /** 妯℃澘 */
+ file?: string;
+ /** 涓氬姟缂栫爜 */
+ code?: string;
+ access?: EnumElectronSignAccess;
+ /** 妯℃澘Id */
+ templateId?: string;
+ /** 鍙橀噺 */
+ values?: GetContractTemplateQueryResultValue[];
+ }
+
+ interface GetContractTemplateQueryResultValue {
+ /** 鍙橀噺Id */
+ id?: string;
+ type?: EnumContractTemplateValueType;
+ recorder?: EnumContractTemplateValueRecorder;
+ userType?: EnumUserType;
+ /** 鍙橀噺鍚嶇О */
+ label?: string;
+ /** 鍙橀噺浠g爜 */
+ name?: string;
+ /** 鏄惁蹇呭~ */
+ required?: boolean;
+ }
+
type GetCurrentLogierMenusQuery = Record<string, any>;
interface GetDbAuditLogsQuery {
@@ -2102,6 +2269,74 @@
sort?: number;
/** 鏄惁绂佺敤 */
isDisabled?: boolean;
+ }
+
+ interface GetEnterpriseContractTemplateLogsQuery {
+ /** 妯℃澘Id */
+ id?: string;
+ pageModel?: PagedListQueryPageModel;
+ }
+
+ interface GetEnterpriseContractTemplateLogsQueryResult {
+ pageModel?: PagedListQueryResultPageModel;
+ /** 鏁版嵁 */
+ data?: GetEnterpriseContractTemplateLogsQueryResultItem[];
+ }
+
+ interface GetEnterpriseContractTemplateLogsQueryResultItem {
+ /** 璺熻釜Id */
+ traceId?: string;
+ /** 鎿嶄綔浜� */
+ createdUser?: string;
+ /** 鎿嶄綔鏃堕棿 */
+ createdTime?: string;
+ operate?: EnumDbAuditOperate;
+ /** 鎿嶄綔鍐呭 */
+ content?: string[];
+ }
+
+ interface GetEnterpriseContractTemplatesQuery {
+ /** 浼佷笟Id */
+ enterpriseId?: string;
+ /** 鍏抽敭瀛� */
+ keywords?: string;
+ status?: EnumContractTemplateStatus;
+ /** 瀹㈡埛涓婁紶鏃堕棿-璧峰 */
+ createdTimeBegin?: string;
+ /** 瀹㈡埛涓婁紶鏃堕棿-鎴 */
+ createdTimeEnd?: string;
+ /** 鍒剁増鏃堕棿-璧峰 */
+ completedTimeBegin?: string;
+ /** 鍒剁増鏃堕棿-鎴 */
+ completedTimeEnd?: string;
+ pageModel?: PagedListQueryPageModel;
+ }
+
+ interface GetEnterpriseContractTemplatesQueryResult {
+ pageModel?: PagedListQueryResultPageModel;
+ /** 鏁版嵁 */
+ data?: GetEnterpriseContractTemplatesQueryResultItem[];
+ }
+
+ interface GetEnterpriseContractTemplatesQueryResultItem {
+ /** 妯℃澘Id */
+ id?: string;
+ /** 妯℃澘鍚嶇О */
+ name?: string;
+ /** 瀹㈡埛涓婁紶鏃堕棿 */
+ createdTime?: string;
+ /** 妯℃澘Id */
+ templateId?: string;
+ access?: EnumElectronSignAccess;
+ /** 涓氬姟缂栫爜 */
+ code?: string;
+ /** 妯℃澘 */
+ file?: string;
+ status?: EnumContractTemplateStatus;
+ /** 鍒剁増鏃堕棿 */
+ completedTime?: string;
+ /** 鎿嶄綔浜� */
+ operator?: string;
}
interface GetEnterpriseElectronSignSettingQueryResult {
@@ -3608,6 +3843,38 @@
id?: string;
}
+ interface SaveContractTemplateCommand {
+ /** 浼佷笟Id锛堣繍钀ョ淇濆瓨鏃讹級 */
+ enterpriseId?: string;
+ /** 妯℃澘鍚嶇О */
+ name: string;
+ /** 妯℃澘 */
+ file: string;
+ /** 涓氬姟缂栫爜 */
+ code?: string;
+ access?: EnumElectronSignAccess;
+ /** 妯℃澘Id */
+ templateId?: string;
+ /** 鍙橀噺 */
+ values?: SaveContractTemplateCommandValue[];
+ /** Id */
+ id?: string;
+ }
+
+ interface SaveContractTemplateCommandValue {
+ /** Id */
+ id?: string;
+ type?: EnumContractTemplateValueType;
+ recorder?: EnumContractTemplateValueRecorder;
+ userType?: EnumUserType;
+ /** 鍙橀噺鍚嶇О */
+ label?: string;
+ /** 鍙橀噺浠g爜 */
+ name?: string;
+ /** 鏄惁蹇呭~ */
+ required?: boolean;
+ }
+
interface SaveDictionaryCategoryCommand {
/** 缂栧彿 */
code: string;
@@ -3975,6 +4242,12 @@
smsCost?: number;
}
+ interface SetIsDisabledContractTemplateCommand {
+ ids?: string[];
+ /** 鏄惁宸茬鐢� */
+ isDisabled?: boolean;
+ }
+
interface SetMenuSwitchCommand {
/** Id */
ids?: string[];
diff --git a/src/views/ProtocolManage/EditTemplate.vue b/src/views/ProtocolManage/EditTemplate.vue
index 1faf700..257d4a3 100644
--- a/src/views/ProtocolManage/EditTemplate.vue
+++ b/src/views/ProtocolManage/EditTemplate.vue
@@ -6,10 +6,7 @@
<QueryFilterItem>
<FieldRadio
v-model="extraParamState.status"
- :value-enum="[
- { value: 1, label: '寰呭埗鐗�' },
- { value: 2, label: '宸插畬鎴�' },
- ]"
+ :value-enum="EnumContractTemplateStatusText"
buttonStyle
showAllBtn
@change="getList()"
@@ -17,7 +14,7 @@
</QueryFilterItem>
<QueryFilterItem tip-content="瀹㈡埛涓婁紶鏃堕棿">
<FieldDatePicker
- v-model="extraParamState.beginDate"
+ v-model="extraParamState.createdTime"
type="daterange"
range-separator="~"
start-placeholder="寮�濮嬫棩鏈�"
@@ -28,7 +25,7 @@
</QueryFilterItem>
<QueryFilterItem tip-content="鍒剁増鏃堕棿">
<FieldDatePicker
- v-model="extraParamState.beginDate"
+ v-model="extraParamState.completedTime"
type="daterange"
range-separator="~"
start-placeholder="寮�濮嬫棩鏈�"
@@ -55,6 +52,7 @@
</ProTableV2>
</AppContainer>
<AddOrEditTemplateDialog v-bind="dialogProps" />
+ <OperateHistoryLogDialog v-bind="logDialogProps" />
</LoadingLayout>
</template>
@@ -75,9 +73,11 @@
} from '@bole-core/components';
import { useAccess } from '@/hooks';
import { ModelValueType } from 'element-plus';
-import * as enterpriseServices from '@/services/api/enterprise';
+import * as electronSignServices from '@/services/api/electronSign';
import AddOrEditTemplateDialog from './components/AddOrEditTemplateDialog.vue';
-import { Message } from '@bole-core/core';
+import { downloadFileByUrl, Message } from '@bole-core/core';
+import { convertApi2FormUrlOnlyOne, format, setOSSLink } from '@/utils';
+import { EnumContractTemplateStatus, EnumContractTemplateStatusText } from '@/constants';
defineOptions({
name: 'EditTemplate',
@@ -96,13 +96,14 @@
},
delBtn: {
emits: { onClick: (role) => handleDelete(role) },
+ props: { type: 'danger' },
extraProps: {
hide: (row) => false,
},
},
logBtn: {
- emits: { onClick: (role) => openLogDialog(role) },
+ emits: { onClick: (role) => openLogDialog(role.id) },
},
};
@@ -110,7 +111,8 @@
operationBtnMap,
});
-const router = useRouter();
+const route = useRoute();
+const enterpriseId = route.params?.id as string;
const BaseState = {
loading: true,
};
@@ -131,15 +133,21 @@
} = useTable(
async ({ pageIndex, pageSize }, extraParamState) => {
try {
- let params: API.GetEnterprisesQuery = {
+ let params: API.GetEnterpriseContractTemplatesQuery = {
pageModel: {
rows: pageSize,
page: pageIndex,
orderInput: extraParamState.orderInput,
},
- // searchKeys: extraParamState.keyword,
+ keywords: extraParamState.keyword,
+ status: extraParamState.status,
+ createdTimeBegin: format(extraParamState.createdTime?.[0] ?? '', 'YYYY-MM-DD 00:00:00'),
+ createdTimeEnd: format(extraParamState.createdTime?.[1] ?? '', 'YYYY-MM-DD 23:59:59'),
+ completedTimeBegin: format(extraParamState.completedTime?.[0] ?? '', 'YYYY-MM-DD 00:00:00'),
+ completedTimeEnd: format(extraParamState.completedTime?.[1] ?? '', 'YYYY-MM-DD 23:59:59'),
+ enterpriseId: enterpriseId,
};
- let res = await enterpriseServices.getEnterprises(params, {
+ let res = await electronSignServices.getEnterpriseContractTemplates(params, {
showLoading: !state.loading,
});
return res;
@@ -148,12 +156,22 @@
{
defaultExtraParams: {
keyword: '',
- status: '' as any as boolean,
- beginDate: [] as unknown as ModelValueType,
- endDate: [] as unknown as ModelValueType,
- orderInput: [{ property: 'id', order: EnumPagedListOrder.Asc }],
+ status: '' as any as EnumContractTemplateStatus,
+ createdTime: [] as unknown as ModelValueType,
+ completedTime: [] as unknown as ModelValueType,
+ orderInput: [{ property: 'createdTime', order: EnumPagedListOrder.Desc }],
},
- columnsRenderProps: {},
+ columnsRenderProps: {
+ createdTime: { type: 'date' },
+ completedTime: { type: 'date' },
+ status: { type: 'enum', valueEnum: EnumContractTemplateStatusText },
+ access: { type: 'enum', valueEnum: EnumElectronSignAccessText },
+ file: {
+ type: 'url',
+ showDownloadBtn: false,
+ formatter: (row: API.GetEnterpriseContractTemplatesQueryResultItem) => setOSSLink(row.file),
+ },
+ },
}
);
@@ -163,34 +181,94 @@
id: '',
templateId: '',
name: '',
- bussinessCode: '',
- templateFileUrl: [] as UploadUserFile[],
+ code: '',
+ file: [] as UploadUserFile[],
+ access: '' as any as EnumElectronSignAccess,
title: '鏂板妯℃澘',
},
});
-function openDialog(row?) {
+function openDialog(row?: API.GetEnterpriseContractTemplatesQueryResultItem) {
if (row) {
handleEdit({
- id: '',
- name: '',
- bussinessCode: '',
- templateId: '',
- templateFileUrl: [] as UploadUserFile[],
+ id: row.id,
+ templateId: row.templateId,
+ name: row.name,
+ code: row.code,
+ file: convertApi2FormUrlOnlyOne(row.file),
+ access: row.access,
});
} else {
handleAdd();
}
}
-async function handleAddOrEdit() {}
-
-function handleDownload(row) {}
-async function handleDelete(row) {
+async function handleAddOrEdit() {
try {
- await Message.deleteMessage();
+ let isEdit = !!editForm.id;
+ let params: API.SaveContractTemplateCommand = {
+ name: editForm.name,
+ file: editForm.file[0]?.path ?? '',
+ enterpriseId: enterpriseId,
+ code: editForm.code,
+ access: editForm.access,
+ templateId: editForm.templateId,
+ // values: [
+ // {
+ // id: '3fa85f64-5717-4562-b3fc-2c963f66afa6',
+ // type: 10,
+ // recorder: 10,
+ // userType: 10,
+ // label: 'string',
+ // name: 'string',
+ // required: true,
+ // },
+ // ],
+ };
+ if (isEdit) {
+ params.id = editForm.id;
+ }
+ let res = await electronSignServices.saveContractTemplate(params);
+ if (res) {
+ Message.successMessage('鎿嶄綔鎴愬姛');
+ getList();
+ }
} catch (error) {}
}
-function openLogDialog(row) {}
+function handleDownload(row: API.GetEnterpriseContractTemplatesQueryResultItem) {
+ downloadFileByUrl(setOSSLink(row.file), '妯℃澘');
+}
+async function handleDelete(row: API.GetEnterpriseContractTemplatesQueryResultItem) {
+ try {
+ await Message.deleteMessage();
+ let res = await electronSignServices.setIsDisabledContractTemplate({
+ ids: [row.id],
+ isDisabled: true,
+ });
+ if (res) {
+ Message.successMessage('鎿嶄綔鎴愬姛');
+ getList(paginationState.pageIndex);
+ }
+ } catch (error) {}
+}
+
+const { openLogDialog, logDialogProps } = useOpenLogDialog({
+ service: async ({ pageIndex, pageSize }, extraParamState) => {
+ try {
+ let params: API.GetEnterpriseContractTemplateLogsQuery = {
+ pageModel: {
+ rows: pageSize,
+ page: pageIndex,
+ orderInput: extraParamState.orderInput,
+ },
+ id: extraParamState.id,
+ };
+ let res = await electronSignServices.getEnterpriseContractTemplateLogs(params, {
+ showLoading: !state.loading,
+ });
+ return res;
+ } catch (error) {}
+ },
+});
</script>
diff --git a/src/views/ProtocolManage/ProtocolManageList.vue b/src/views/ProtocolManage/ProtocolManageList.vue
index aa1c6e0..0f9715a 100644
--- a/src/views/ProtocolManage/ProtocolManageList.vue
+++ b/src/views/ProtocolManage/ProtocolManageList.vue
@@ -6,7 +6,7 @@
<QueryFilterItem>
<FieldRadio
v-model="extraParamState.status"
- :value-enum="[{ value: 1, label: '寰呭埗鐗�' }]"
+ :value-enum="EnumContractTemplateStatusTextForEnterpriseFilter"
buttonStyle
showAllBtn
@change="getList()"
@@ -42,7 +42,8 @@
FieldRadio,
} from '@bole-core/components';
import { useAccess } from '@/hooks';
-import * as enterpriseServices from '@/services/api/enterprise';
+import * as electronSignServices from '@/services/api/electronSign';
+import { EnumContractTemplateStatusTextForEnterpriseFilter } from '@/constants';
defineOptions({
name: 'ProtocolManageList',
@@ -77,15 +78,16 @@
} = useTable(
async ({ pageIndex, pageSize }, extraParamState) => {
try {
- let params: API.GetEnterprisesQuery = {
+ let params: API.GetContractTemplateEnterprisesQuery = {
pageModel: {
rows: pageSize,
page: pageIndex,
- orderInput: extraParamState.orderInput,
+ // orderInput: extraParamState.orderInput,
},
- // searchKeys: extraParamState.keyword,
+ keywords: extraParamState.keyword,
+ status: extraParamState.status,
};
- let res = await enterpriseServices.getEnterprises(params, {
+ let res = await electronSignServices.getContractTemplateEnterprises(params, {
showLoading: !state.loading,
});
return res;
@@ -94,14 +96,14 @@
{
defaultExtraParams: {
keyword: '',
- status: '',
+ status: '' as any as EnumContractTemplateStatus,
orderInput: [{ property: 'id', order: EnumPagedListOrder.Asc }],
},
columnsRenderProps: {},
}
);
-function goEdit(row) {
+function goEdit(row: API.GetContractTemplateEnterprisesQueryResultItem) {
router.push({
name: 'EditTemplate',
params: {
diff --git a/src/views/ProtocolManage/components/AddOrEditTemplateDialog.vue b/src/views/ProtocolManage/components/AddOrEditTemplateDialog.vue
index 2bc2f6d..23ad739 100644
--- a/src/views/ProtocolManage/components/AddOrEditTemplateDialog.vue
+++ b/src/views/ProtocolManage/components/AddOrEditTemplateDialog.vue
@@ -18,25 +18,17 @@
:formatter="filterCN"
></ProFormText>
</ProFormItemV2>
- <ProFormItemV2
- label="閫氶亾锛�"
- prop="templateId"
- :check-rules="[{ message: '璇烽�夋嫨鐢靛瓙绛鹃�氶亾' }]"
- >
+ <ProFormItemV2 label="閫氶亾锛�" prop="access" :check-rules="[{ message: '璇烽�夋嫨鐢靛瓙绛鹃�氶亾' }]">
<ProFormSelect
placeholder="璇烽�夋嫨鐢靛瓙绛鹃�氶亾"
- v-model="form.templateId"
- :value-enum="[{ label: 1, value: '鏀粯瀹�' }]"
+ v-model="form.access"
+ :value-enum="EnumElectronSignAccessText"
></ProFormSelect>
</ProFormItemV2>
- <ProFormItemV2
- label="涓氬姟缂栫爜锛�"
- prop="bussinessCode"
- :check-rules="[{ message: '璇疯緭鍏ヤ笟鍔$紪鐮�' }]"
- >
+ <ProFormItemV2 label="涓氬姟缂栫爜锛�" prop="code" :check-rules="[{ message: '璇疯緭鍏ヤ笟鍔$紪鐮�' }]">
<ProFormText
placeholder="璇疯緭鍏ヤ笟鍔$紪鐮�"
- v-model.trim="form.bussinessCode"
+ v-model.trim="form.code"
:maxlength="5"
:formatter="filterNumbersFromString"
></ProFormText>
@@ -50,11 +42,11 @@
</ProFormItemV2>
<ProFormItemV2
label="涓婁紶妯℃澘锛�"
- prop="templateFileUrl"
+ prop="file"
:check-rules="[{ message: '璇蜂笂浼犳ā鏉�', type: 'upload' }]"
>
<ProFormUpload
- v-model:file-url="form.templateFileUrl"
+ v-model:file-url="form.file"
:limit="1"
:limitFileSize="10"
accept="pdf"
@@ -81,6 +73,7 @@
} from '@bole-core/components';
import { filterCN, filterNumbersFromString } from '@/utils';
import { FormInstance } from 'element-plus';
+import { EnumElectronSignAccessText } from '@/constants';
defineOptions({
name: 'AddOrEditTemplateDialog',
@@ -93,8 +86,9 @@
id: string;
templateId: string;
name: string;
- bussinessCode: string;
- templateFileUrl: UploadUserFile[];
+ code: string;
+ file: UploadUserFile[];
+ access: EnumElectronSignAccess;
};
const form = defineModel<Form>('form');
--
Gitblit v1.9.1