From 83bc7f6d33934f56fd1df80c7e8975e7c887d606 Mon Sep 17 00:00:00 2001
From: eight <641137800@qq.com>
Date: 星期三, 23 十月 2024 22:12:05 +0800
Subject: [PATCH] 检查类型 字典移除,使用 本地存储
---
src/views/ecg/appointment/index.vue | 7 +
src/api/ecg/checktype/index.ts | 6 +
src/api/ecg/room/index.ts | 1
src/views/ecg/room/RoomSetting.vue | 18 +---
src/hooks/web/useCache.ts | 1
src/views/ecg/room/RoomForm.vue | 14 +--
src/permission.ts | 5 +
src/views/ecg/appointment/AppointmentConfirm.vue | 5 +
src/views/ecg/appointment/AppointmentForm.vue | 5 +
src/utils/dict.ts | 1
src/components/RoomBedSelect/src/RoomBedSelect.vue | 13 --
src/store/modules/checkType.ts | 94 +++++++++++++++++++++++
src/views/ecg/doctor/components/QueuePanel.vue | 5 +
src/components/RoomStatus/src/RoomStatus.vue | 15 +--
src/views/ecg/queue/index.vue | 7 +
15 files changed, 145 insertions(+), 52 deletions(-)
diff --git a/src/api/ecg/checktype/index.ts b/src/api/ecg/checktype/index.ts
index b984911..829e472 100644
--- a/src/api/ecg/checktype/index.ts
+++ b/src/api/ecg/checktype/index.ts
@@ -12,6 +12,12 @@
// 妫�鏌ョ被鍨� API
export const CheckTypeApi = {
+
+ // 鏌ヨ妫�鏌ョ被鍨�.绠�鍗曞垪琛�
+ getSimpleCheckTypeList: async () => {
+ return await request.get({ url: `/ecg/check-type/list-simple-check-type` })
+ },
+
// 鏌ヨ妫�鏌ョ被鍨嬪垎椤�
getCheckTypePage: async (params: any) => {
return await request.get({ url: `/ecg/check-type/page`, params })
diff --git a/src/api/ecg/room/index.ts b/src/api/ecg/room/index.ts
index 8b3e819..870f954 100644
--- a/src/api/ecg/room/index.ts
+++ b/src/api/ecg/room/index.ts
@@ -19,6 +19,7 @@
activeQueueNum : number
priorityQueueNum : number
openingFlag : number
+ checkTypeBedInfo: object
}
// 璇婂鍜岃瘖鐤楀簥 API
diff --git a/src/components/RoomBedSelect/src/RoomBedSelect.vue b/src/components/RoomBedSelect/src/RoomBedSelect.vue
index d0b6703..79092cc 100644
--- a/src/components/RoomBedSelect/src/RoomBedSelect.vue
+++ b/src/components/RoomBedSelect/src/RoomBedSelect.vue
@@ -3,6 +3,7 @@
import {PropType} from "vue";
import {useUserStore} from "@/store/modules/user";
import {DICT_TYPE, getIntDictOptions} from "@/utils/dict";
+import {useCheckTypeStore} from "@/store/modules/checkType";
const emit = defineEmits(['event-haveseat', 'event-leaveseat'])
defineComponent({
@@ -25,6 +26,7 @@
}
})
+const checkTypeStore = useCheckTypeStore();
const userStore = useUserStore()
const curUser = userStore.getUser
@@ -35,19 +37,10 @@
emit('event-leaveseat', curItem)
}
-let mapCheckType: Map<number, string> = new Map();
-const getCheckTypeList = () => {
- const data = getIntDictOptions(DICT_TYPE.ECG_CHECK_TYPE)
- console.info( data )
- data.forEach((checkTypeItem) => {
- mapCheckType.set(checkTypeItem.value, checkTypeItem.label)
- })
-}
/** 鍒濆鍖� **/
onMounted(() => {
//console.info(props.bedList)
- getCheckTypeList()
})
</script>
@@ -59,7 +52,7 @@
<div class="deskwarp">
<div v-for="(checkType, subIndex) in bedItem.checkTypes" :key="subIndex">
- {{mapCheckType.get(checkType)}}
+ {{checkTypeStore.getCheckTypeName(checkType)}}
</div>
<div>
{{bedItem.opType === 1?"棰嗙敤":""}}
diff --git a/src/components/RoomStatus/src/RoomStatus.vue b/src/components/RoomStatus/src/RoomStatus.vue
index 417a93b..73a3f01 100644
--- a/src/components/RoomStatus/src/RoomStatus.vue
+++ b/src/components/RoomStatus/src/RoomStatus.vue
@@ -3,6 +3,7 @@
import { QueueApi } from '@/api/ecg/queue'
import {PropType} from "vue";
import {DICT_TYPE, getIntDictOptions} from "@/utils/dict";
+import {useCheckTypeStore} from "@/store/modules/checkType";
const emit = defineEmits(['refresh'])
defineComponent({
@@ -20,7 +21,7 @@
}
})
-let mapCheckType: Map<number, string> = new Map();
+const checkTypeStore = useCheckTypeStore();
const openBed = async (item) => {
await QueueApi.bedOpen(item)
@@ -32,17 +33,8 @@
emit('refresh')
}
-const getCheckTypeList = () => {
- const data = getIntDictOptions(DICT_TYPE.ECG_CHECK_TYPE)
- console.info( data )
- data.forEach((checkTypeItem) => {
- mapCheckType.set(checkTypeItem.value, checkTypeItem.label)
- })
-}
-
/** 鍒濆鍖� **/
onMounted(() => {
- getCheckTypeList()
})
</script>
@@ -72,11 +64,12 @@
/>
{{bedItem.bedNo}} {{bedItem.docName}} {{bedItem.status === 30?"-鏆傚仠":""}}
<div v-for="(checkType, subIndex) in bedItem.checkTypes" :key="subIndex">
- {{mapCheckType.get(checkType)}}
+ {{checkTypeStore.getCheckTypeName(checkType)}}
</div>
<div>
{{bedItem.opType === 1?"棰嗙敤":""}}
</div>
+ <el-divider/>
</div>
</div>
</el-card>
diff --git a/src/hooks/web/useCache.ts b/src/hooks/web/useCache.ts
index 4f39f30..990715e 100644
--- a/src/hooks/web/useCache.ts
+++ b/src/hooks/web/useCache.ts
@@ -16,6 +16,7 @@
THEME: 'theme',
LAYOUT: 'layout',
DICT_CACHE: 'dictCache',
+ CHECKTYPE_CACHE: 'checkTypeCache',
// 鐧诲綍琛ㄥ崟
LoginForm: 'loginForm',
TenantId: 'tenantId'
diff --git a/src/permission.ts b/src/permission.ts
index a4ea69d..b0f6231 100644
--- a/src/permission.ts
+++ b/src/permission.ts
@@ -6,6 +6,7 @@
import { useNProgress } from '@/hooks/web/useNProgress'
import { usePageLoading } from '@/hooks/web/usePageLoading'
import { useDictStoreWithOut } from '@/store/modules/dict'
+import { useCheckTypeStoreWithOut } from '@/store/modules/checkType'
import { useUserStoreWithOut } from '@/store/modules/user'
import { usePermissionStoreWithOut } from '@/store/modules/permission'
@@ -82,10 +83,14 @@
// 鑾峰彇鎵�鏈夊瓧鍏�
const dictStore = useDictStoreWithOut()
const userStore = useUserStoreWithOut()
+ const checkTypeStore = useCheckTypeStoreWithOut()
const permissionStore = usePermissionStoreWithOut()
if (!dictStore.getIsSetDict) {
await dictStore.setDictMap()
}
+ if (!checkTypeStore.getIsSetCheckType) {
+ await checkTypeStore.setCheckTypeMap()
+ }
if (userStore.getIsSetUser ) {
diff --git a/src/store/modules/checkType.ts b/src/store/modules/checkType.ts
new file mode 100644
index 0000000..be3ab05
--- /dev/null
+++ b/src/store/modules/checkType.ts
@@ -0,0 +1,94 @@
+import { defineStore } from 'pinia'
+import { store } from '../index'
+// @ts-ignore
+import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
+const { wsCache } = useCache('sessionStorage')
+import {CheckTypeApi} from "@/api/ecg/checktype";
+
+export interface CheckTypeSimpleVO {
+ value: number
+ name: string
+}
+export interface CheckTypeState {
+ checkTypeMap: Map<number, string>
+ isSetCheckType: boolean
+}
+
+export const useCheckTypeStore = defineStore('checktype ', {
+ state: (): CheckTypeState => ({
+ checkTypeMap: new Map<number, string>(),
+ isSetCheckType: false
+ }),
+ getters: {
+ getCheckTypeMap(): Recordable {
+ const checkTypeMap = wsCache.get(CACHE_KEY.CHECKTYPE_CACHE)
+ if (checkTypeMap) {
+ this.checkTypeMap = checkTypeMap
+ }
+ return this.checkTypeMap
+ },
+ getIsSetCheckType(): boolean {
+ return this.isSetCheckType
+ }
+ },
+ actions: {
+ async setCheckTypeMap() {
+ const checkTypeMap = wsCache.get(CACHE_KEY.CHECKTYPE_CACHE)
+ if (checkTypeMap) {
+ this.checkTypeMap = checkTypeMap
+ this.isSetCheckType = true
+ } else {
+ const res = await CheckTypeApi.getSimpleCheckTypeList()
+ // 璁剧疆鏁版嵁
+ const checkTypeMap = new Map<number, string>()
+ res.forEach((simpleVO: CheckTypeSimpleVO) => {
+ // 鑾峰緱 dictType 灞傜骇
+ const enumValueObj = checkTypeMap[simpleVO.value]
+ if (!enumValueObj) {
+ checkTypeMap[simpleVO.value] = simpleVO.name
+ }
+ })
+ this.checkTypeMap = checkTypeMap
+ this.isSetCheckType = true
+ wsCache.set(CACHE_KEY.CHECKTYPE_CACHE, checkTypeMap, { exp: 60 }) // 60 绉� 杩囨湡
+ }
+ },
+ getCheckTypeName(type: number) {
+ if (!this.isSetCheckType) {
+ this.setcheckTypeMap()
+ }
+ return this.checkTypeMap[type]
+ },
+ getCheckTypeOptions() {
+ if (!this.isSetCheckType) {
+ this.setcheckTypeMap()
+ }
+ return Object.keys(this.checkTypeMap).map((key) => {
+ return {
+ value: key,
+ label: this.checkTypeMap[key]
+ }
+ });
+ },
+ async resetCheckTypeInfo() {
+ wsCache.delete(CACHE_KEY.CHECKTYPE_CACHE)
+ const res = await CheckTypeApi.getSimpleCheckTypeList()
+ // 璁剧疆鏁版嵁
+ const checkTypeMap = new Map<number, string>()
+ res.forEach((simpleVO: CheckTypeSimpleVO) => {
+ // 鑾峰緱 dictType 灞傜骇
+ const enumValueObj = checkTypeMap[simpleVO.value]
+ if (!enumValueObj) {
+ checkTypeMap[simpleVO.value] = simpleVO.name
+ }
+ })
+ this.checkTypeMap = checkTypeMap
+ this.isSetCheckType = true
+ wsCache.set(CACHE_KEY.CHECKTYPE_CACHE, checkTypeMap, { exp: 60 }) // 60 绉� 杩囨湡
+ }
+ }
+})
+
+export const useCheckTypeStoreWithOut = () => {
+ return useCheckTypeStore(store)
+}
diff --git a/src/utils/dict.ts b/src/utils/dict.ts
index f5cf56e..4e783bb 100644
--- a/src/utils/dict.ts
+++ b/src/utils/dict.ts
@@ -144,7 +144,6 @@
// ========== ECG 妯″潡 ==========
ECG_BOOK_TIMESLOT = 'ecg_book_timeslot',
- ECG_CHECK_TYPE = 'ecg_check_type',
ECG_BOOK_SRC = 'ecg_book_src',
ECG_QUEUE_STATUS = 'ecg_queue_status',
ECG_DEV_BRAND = 'ecg_dev_brand',
diff --git a/src/views/ecg/appointment/AppointmentConfirm.vue b/src/views/ecg/appointment/AppointmentConfirm.vue
index 0e57f85..d985e7c 100644
--- a/src/views/ecg/appointment/AppointmentConfirm.vue
+++ b/src/views/ecg/appointment/AppointmentConfirm.vue
@@ -53,7 +53,7 @@
<el-form-item label="棰勭害妫�鏌ョ被鍨�" prop="bookCheckType">
<el-select v-model="formData.bookCheckType" placeholder="璇烽�夋嫨棰勭害妫�鏌ョ被鍨�">
<el-option
- v-for="dict in getIntDictOptions(DICT_TYPE.ECG_CHECK_TYPE)"
+ v-for="dict in checkTypeStore.getCheckTypeOptions()"
:key="dict.value"
:label="dict.label"
:value="dict.value"
@@ -111,10 +111,13 @@
<script setup lang="ts">
import {DICT_TYPE, getIntDictOptions} from '@/utils/dict'
import { AppointmentApi, AppointmentVO } from '@/api/ecg/appointment'
+import {useCheckTypeStore} from "@/store/modules/checkType";
/** 棰勭害纭 琛ㄥ崟 */
defineOptions({ name: 'AppointmentConfirm' })
+const checkTypeStore = useCheckTypeStore();
+
const message = useMessage() // 娑堟伅寮圭獥
const loading = ref(true) // 鍒楄〃鐨勫姞杞戒腑
diff --git a/src/views/ecg/appointment/AppointmentForm.vue b/src/views/ecg/appointment/AppointmentForm.vue
index 1d85507..9d7a19c 100644
--- a/src/views/ecg/appointment/AppointmentForm.vue
+++ b/src/views/ecg/appointment/AppointmentForm.vue
@@ -68,7 +68,7 @@
<el-form-item label="棰勭害妫�鏌ョ被鍨�" prop="bookCheckType">
<el-select v-model="formData.bookCheckType" placeholder="璇烽�夋嫨棰勭害妫�鏌ョ被鍨�">
<el-option
- v-for="dict in getIntDictOptions(DICT_TYPE.ECG_CHECK_TYPE)"
+ v-for="dict in checkTypeStore.getCheckTypeOptions()"
:key="dict.value"
:label="dict.label"
:value="dict.value"
@@ -157,10 +157,13 @@
<script setup lang="ts">
import {DICT_TYPE, getIntDictOptions} from '@/utils/dict'
import { AppointmentApi, AppointmentVO } from '@/api/ecg/appointment'
+import {useCheckTypeStore} from "@/store/modules/checkType";
/** 棰勭害 琛ㄥ崟 */
defineOptions({ name: 'AppointmentForm' })
+const checkTypeStore = useCheckTypeStore();
+
const { t } = useI18n() // 鍥介檯鍖�
const message = useMessage() // 娑堟伅寮圭獥
diff --git a/src/views/ecg/appointment/index.vue b/src/views/ecg/appointment/index.vue
index 9bc34d7..85eaf2a 100644
--- a/src/views/ecg/appointment/index.vue
+++ b/src/views/ecg/appointment/index.vue
@@ -149,7 +149,7 @@
class="!w-240px"
>
<el-option
- v-for="dict in getIntDictOptions(DICT_TYPE.ECG_CHECK_TYPE)"
+ v-for="dict in checkTypeStore.getCheckTypeOptions()"
:key="dict.value"
:label="dict.label"
:value="dict.value"
@@ -229,7 +229,7 @@
</el-table-column>
<el-table-column label="棰勭害妫�鏌ョ被鍨�" align="center" prop="bookCheckType">
<template #default="scope">
- <dict-tag :type="DICT_TYPE.ECG_CHECK_TYPE" :value="scope.row.bookCheckType" />
+ checkTypeStore.getCheckTypeName(scope.row.bookCheckType)
</template>
</el-table-column>
<el-table-column label="棰勭害鏉ユ簮" align="center" prop="bookSrc">
@@ -277,6 +277,7 @@
import download from '@/utils/download'
import { AppointmentApi, AppointmentVO } from '@/api/ecg/appointment'
import AppointmentForm from './AppointmentForm.vue'
+import {useCheckTypeStore} from "@/store/modules/checkType";
/** 棰勭害 鍒楄〃 */
defineOptions({ name: 'Appointment' })
@@ -312,6 +313,8 @@
const queryFormRef = ref() // 鎼滅储鐨勮〃鍗�
const exportLoading = ref(false) // 瀵煎嚭鐨勫姞杞戒腑
+const checkTypeStore = useCheckTypeStore();
+
/** 鏌ヨ鍒楄〃 */
const getList = async () => {
loading.value = true
diff --git a/src/views/ecg/doctor/components/QueuePanel.vue b/src/views/ecg/doctor/components/QueuePanel.vue
index 154050c..935bf90 100644
--- a/src/views/ecg/doctor/components/QueuePanel.vue
+++ b/src/views/ecg/doctor/components/QueuePanel.vue
@@ -3,12 +3,15 @@
import { QueueVO } from '@/api/ecg/queue'
import {DICT_TYPE} from "@/utils/dict";
import {PatientVO, DoctorApi} from "@/api/ecg/doctor";
+import {useCheckTypeStore} from "@/store/modules/checkType";
defineComponent({
name: 'QueuePanel'
})
const emit = defineEmits(['event_RecallFinish']) // 瀹氫箟 success 浜嬩欢锛岀敤浜庢搷浣滄垚鍔熷悗鐨勫洖璋�
+
+const checkTypeStore = useCheckTypeStore();
const message = useMessage() // 娑堟伅寮圭獥
@@ -50,7 +53,7 @@
<span style="display:inline-block; width:70px;"> {{item.seqNum}} {{item.patName}}{{item.passed === 0 ? "":"*"}} </span>
<dict-tag :type="DICT_TYPE.SYSTEM_USER_SEX" :value="item.patGender" />
<!-- {{item.roomName}} {{item.bedNo}}-->
- <dict-tag :type="DICT_TYPE.ECG_CHECK_TYPE" :value="item.bookCheckType" />
+ checkTypeStore.getCheckTypeName(item.bookCheckType)
<dict-tag :type="DICT_TYPE.ECG_QUEUE_STATUS" :value="item.status" />
<el-button v-if="item.status === 5 || item.status === 7" @click="recall(item)"> 鍙洖 </el-button>
</div>
diff --git a/src/views/ecg/queue/index.vue b/src/views/ecg/queue/index.vue
index 2ae3585..700fbc2 100644
--- a/src/views/ecg/queue/index.vue
+++ b/src/views/ecg/queue/index.vue
@@ -49,7 +49,7 @@
class="!w-240px"
>
<el-option
- v-for="dict in getIntDictOptions(DICT_TYPE.ECG_CHECK_TYPE)"
+ v-for="dict in checkTypeStore.getCheckTypeOptions()"
:key="dict.value"
:label="dict.label"
:value="dict.value"
@@ -137,7 +137,7 @@
</el-table-column>
<el-table-column label="妫�鏌ョ被鍨�" align="center" prop="bookCheckType" >
<template #default="scope">
- <dict-tag :type="DICT_TYPE.ECG_CHECK_TYPE" :value="scope.row.bookCheckType" />
+ checkTypeStore.getCheckTypeName(scope.row.bookCheckType)
</template>
</el-table-column>
<el-table-column label="鎺掗槦搴忓彿" align="center" prop="seqNum" />
@@ -217,6 +217,7 @@
import queueForm from './QueueForm.vue'
import {DICT_TYPE, getIntDictOptions} from '@/utils/dict'
import {DoctorApi, PatientVO} from "@/api/ecg/doctor";
+import {useCheckTypeStore} from "@/store/modules/checkType";
/** 鎺掗槦 鍒楄〃 */
defineOptions({ name: 'queue' })
@@ -224,6 +225,8 @@
const message = useMessage() // 娑堟伅寮圭獥
const { t } = useI18n() // 鍥介檯鍖�
+const checkTypeStore = useCheckTypeStore();
+
const loading = ref(true) // 鍒楄〃鐨勫姞杞戒腑
const list = ref<QueueVO[]>([]) // 鍒楄〃鐨勬暟鎹�
const total = ref(0) // 鍒楄〃鐨勬�婚〉鏁�
diff --git a/src/views/ecg/room/RoomForm.vue b/src/views/ecg/room/RoomForm.vue
index def39ed..1dfcfa8 100644
--- a/src/views/ecg/room/RoomForm.vue
+++ b/src/views/ecg/room/RoomForm.vue
@@ -26,7 +26,7 @@
<el-form-item label="妫�鏌ョ被鍨�" prop="checkTypes">
<el-checkbox-group v-model="formData.checkTypes">
- <el-checkbox v-for="checkType in checkTypeDict" :value="checkType.value" :key="checkType.value">{{checkType.label}}</el-checkbox>
+ <el-checkbox v-for="checkType in checkTypeStore.getCheckTypeOptions()" :value="checkType.value" :key="checkType.value">{{checkType.label}}</el-checkbox>
</el-checkbox-group>
</el-form-item>
@@ -48,12 +48,15 @@
<script setup lang="ts">
import { RoomApi, RoomVO } from '@/api/ecg/room'
import {DICT_TYPE, getIntDictOptions} from "@/utils/dict";
+import {CheckTypeApi} from "@/api/ecg/checktype";
/** 璇婂鍜岃瘖鐤楀簥 琛ㄥ崟 */
defineOptions({ name: 'RoomForm' })
const { t } = useI18n() // 鍥介檯鍖�
const message = useMessage() // 娑堟伅寮圭獥
+
+const checkTypeStore = useCheckTypeStore();
const dialogVisible = ref(false) // 寮圭獥鐨勬槸鍚﹀睍绀�
const dialogTitle = ref('') // 寮圭獥鐨勬爣棰�
@@ -74,8 +77,6 @@
})
const formRef = ref() // 琛ㄥ崟 Ref
const roomListRef = ref<RoomVO[]>([]) // 鍒楄〃鐨勬暟鎹�
-
-const checkTypeDict = ref()
/** 鎵撳紑寮圭獥 */
const open = async (type: string, id?: number) => {
@@ -141,16 +142,9 @@
return roomListRef.value.find( e => e.roomId === id)!.roomName
}
-const getCheckTypeList = () => {
- const data = getIntDictOptions(DICT_TYPE.ECG_CHECK_TYPE)
- console.info( data )
- checkTypeDict.value = data
-}
-
/** 鍒濆鍖� **/
onMounted(() => {
getSimpleRoomList()
- getCheckTypeList()
})
</script>
diff --git a/src/views/ecg/room/RoomSetting.vue b/src/views/ecg/room/RoomSetting.vue
index 72de651..7e79a0c 100644
--- a/src/views/ecg/room/RoomSetting.vue
+++ b/src/views/ecg/room/RoomSetting.vue
@@ -18,7 +18,7 @@
<div>寮�璇婃椂闂达細{{ openingPeriod }} {{ monitorInfo.openingFlag }} </div>
<div>宸ヤ綅姒傚喌锛� {{monitorInfo.queueNum}} {{monitorInfo.activeQueueNum}} {{monitorInfo.priorityQueueNum}} </div>
<div v-for="(value, key) in monitorInfo.checkTypeBedInfo" :key="key">
- {{ mapCheckType.get(Number(key)) }} {{ value }}
+ {{ checkTypeStore.getCheckTypeName(Number(key)) }} {{ value }}
</div>
</el-aside>
</el-container>
@@ -29,12 +29,11 @@
import { RoomApi, RoomVO, MonitorInfo } from '@/api/ecg/room'
import { QueueApi } from '@/api/ecg/queue'
import { getConfigKey } from '@/api/infra/config'
-import {DICT_TYPE, getIntDictOptions} from "@/utils/dict";
+import {useCheckTypeStore} from "@/store/modules/checkType";
defineOptions({ name: 'RoomSetting' })
const bedMap = ref() // 鍒楄〃鐨勬暟鎹�
-let mapCheckType: Map<number, string> = new Map();
const openingPeriod = ref<string>('')
const monitorInfo = ref<MonitorInfo>({
@@ -42,8 +41,10 @@
activeQueueNum: 0,
priorityQueueNum: 0,
openingFlag: 0,
- checkTypeBedInfo: undefined
+ checkTypeBedInfo: {}
})
+
+const checkTypeStore = useCheckTypeStore();
const getOpeningPeriod = async () => {
const data = await getConfigKey('ecg.openingtime')
@@ -86,18 +87,9 @@
getMonitorInfo()
}
-const getCheckTypeList = () => {
- const data = getIntDictOptions(DICT_TYPE.ECG_CHECK_TYPE)
- console.info( data )
- data.forEach((checkTypeItem) => {
- mapCheckType.set(checkTypeItem.value, checkTypeItem.label)
- })
-}
-
/** 鍒濆鍖� **/
onMounted(() => {
getList()
- getCheckTypeList()
getOpeningPeriod()
getMonitorInfo()
})
--
Gitblit v1.9.3