feat(用例评审): 用例评审部分接口&个人信息头像
This commit is contained in:
parent
07095ecd5a
commit
2c166fa1d7
|
@ -170,7 +170,7 @@ const transform: AxiosTransform = {
|
|||
throw new Error(e as unknown as string);
|
||||
}
|
||||
checkStatus(error?.response?.status, msg, errorMessageMode);
|
||||
return Promise.reject(error?.response?.data?.message);
|
||||
return Promise.reject(error?.response?.data?.message || error);
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
import { RouteRecordRaw, useRoute, useRouter } from 'vue-router';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
|
||||
import MsAvatar from '@/components/pure/ms-avatar/index.vue';
|
||||
import MsIcon from '@/components/pure/ms-icon-font/index.vue';
|
||||
import MsTag from '@/components/pure/ms-tag/ms-tag.vue';
|
||||
import MsPersonInfoDrawer from '@/components/business/ms-personal-drawer/index.vue';
|
||||
|
@ -288,8 +289,8 @@
|
|||
}}
|
||||
>
|
||||
<a-menu-item class="flex items-center justify-between" key="personalInfo">
|
||||
<div class="hover:!bg-transparent">
|
||||
<MsIcon type="icon-icon_that_person" />
|
||||
<div class="flex items-center gap-[8px] hover:!bg-transparent">
|
||||
<MsAvatar avatar={userStore.avatar} size={20} />
|
||||
{userStore.name}
|
||||
</div>
|
||||
<icon-caret-down class="!m-0" />
|
||||
|
|
|
@ -110,9 +110,7 @@
|
|||
</div>
|
||||
<div v-show="activeAvatarType === 'word'" class="mb-[8px] flex flex-wrap gap-[24px] pt-[14px]">
|
||||
<div class="avatar" @click="changeAvatar('word')">
|
||||
<MsAvatar avatar="word" class="mb-[4px]">
|
||||
{{ userStore.name?.substring(0, 4) }}
|
||||
</MsAvatar>
|
||||
<MsAvatar avatar="word" class="mb-[4px]" />
|
||||
<div class="text-[12px] text-[var(--color-text-1)]">{{ t('ms.personal.wordAvatar') }}</div>
|
||||
<MsIcon
|
||||
v-if="activeAvatar === 'word'"
|
||||
|
@ -157,6 +155,8 @@
|
|||
});
|
||||
const baseInfoFormRef = ref<FormInstance>();
|
||||
const orgList = ref<OrganizationProjectListItem[]>([]);
|
||||
const activeAvatarType = ref<'builtIn' | 'word'>('builtIn');
|
||||
const activeAvatar = ref('default');
|
||||
|
||||
function initBaseInfo() {
|
||||
descriptions.value = [
|
||||
|
@ -186,6 +186,8 @@
|
|||
loading.value = true;
|
||||
const res = await getBaseInfo(userStore.id || '');
|
||||
orgList.value = res.orgProjectList;
|
||||
activeAvatar.value = res.avatar;
|
||||
activeAvatarType.value = res.avatar === 'word' ? 'word' : 'builtIn';
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error);
|
||||
|
@ -251,8 +253,6 @@
|
|||
}
|
||||
|
||||
const avatarModalVisible = ref(false);
|
||||
const activeAvatarType = ref<'builtIn' | 'word'>('builtIn');
|
||||
const activeAvatar = ref('default');
|
||||
const avatarList = ref<string[]>([]);
|
||||
let i = 1;
|
||||
while (i <= 46) {
|
||||
|
|
|
@ -1,17 +1,37 @@
|
|||
<template>
|
||||
<MsIcon v-if="props.avatar === 'default'" type="icon-icon_that_person" size="40" class="text-[var(--color-text-4)]" />
|
||||
<a-avatar v-else-if="props.avatar === 'word'" class="bg-[rgb(var(--primary-1))] text-[rgb(var(--primary-6))]">
|
||||
<slot></slot>
|
||||
<MsIcon
|
||||
v-if="props.avatar === 'default'"
|
||||
type="icon-icon_that_person"
|
||||
:size="props.size"
|
||||
class="text-[var(--color-text-4)]"
|
||||
/>
|
||||
<a-avatar
|
||||
v-else-if="props.avatar === 'word'"
|
||||
:size="props.size"
|
||||
class="bg-[rgb(var(--primary-1))] text-[rgb(var(--primary-6))]"
|
||||
>
|
||||
<slot>{{ userStore.name?.substring(0, 4) }}</slot>
|
||||
</a-avatar>
|
||||
<a-avatar v-else :image-url="avatar"></a-avatar>
|
||||
<a-avatar v-else :image-url="avatar" :size="props.size"></a-avatar>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import MsIcon from '@/components/pure/ms-icon-font/index.vue';
|
||||
|
||||
const props = defineProps<{
|
||||
avatar: 'default' | 'word' | string;
|
||||
}>();
|
||||
import useUserStore from '@/store/modules/user/index';
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
avatar?: 'default' | 'word' | string;
|
||||
size?: number;
|
||||
}>(),
|
||||
{
|
||||
avatar: 'default',
|
||||
size: 40,
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
|
|
|
@ -158,9 +158,6 @@
|
|||
:deep(.arco-split-trigger-icon) {
|
||||
font-size: 14px;
|
||||
}
|
||||
.ms-split-box--top {
|
||||
height: calc(v-bind(innerSize) - 4px);
|
||||
}
|
||||
.ms-split-box--bottom {
|
||||
@apply h-full;
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
</template>
|
||||
<div class="h-full px-[24px]">
|
||||
<a-divider class="my-0" />
|
||||
<div class="flex h-[calc(100%-1px)]">
|
||||
<div class="flex h-[calc(100%-1px)] w-full">
|
||||
<div class="h-full w-[356px] border-r border-[var(--color-text-n8)] pr-[16px] pt-[16px]">
|
||||
<div class="mb-[16px] flex">
|
||||
<a-input
|
||||
|
@ -54,7 +54,7 @@
|
|||
</div>
|
||||
<MsPagination :total="total" :page-size="pageSize" :current="pageCurrent" size="mini" simple />
|
||||
</div>
|
||||
<div class="relative flex flex-1 flex-col">
|
||||
<div class="relative flex w-[calc(100%-356px)] flex-col">
|
||||
<div class="pl-[16px] pt-[16px]">
|
||||
<div class="rounded-[var(--border-radius-small)] bg-[var(--color-text-n9)] p-[16px]">
|
||||
<div class="mb-[12px] flex items-center justify-between">
|
||||
|
@ -104,16 +104,31 @@
|
|||
</div>
|
||||
</div>
|
||||
<a-tabs v-model:active-key="showTab" class="no-content">
|
||||
<a-tab-pane v-for="item of tabList" :key="item.key" :title="item.title" />
|
||||
<a-tab-pane :key="tabList[0].key" :title="tabList[0].title" />
|
||||
<a-tab-pane :key="tabList[1].key" :title="tabList[1].title" />
|
||||
<a-tab-pane :key="tabList[2].key">
|
||||
<template #title>
|
||||
<div class="flex items-center">
|
||||
{{ tabList[2].title }}
|
||||
<div
|
||||
:class="`ml-[4px] rounded-full ${
|
||||
showTab === tabList[2].key ? 'bg-[rgb(var(--primary-5))]' : 'bg-[var(--color-text-brand)]'
|
||||
} px-[4px] text-[12px] text-white`"
|
||||
>
|
||||
{{ caseDetail.demandCount > 99 ? '99+' : caseDetail.demandCount }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</div>
|
||||
<a-divider class="my-0" />
|
||||
<div class="content-center">
|
||||
<MsDescription v-if="showTab === 'baseInfo'" :descriptions="descriptions" label-width="90px" />
|
||||
<div v-if="showTab === 'detail'" class="h-full">
|
||||
<div v-else-if="showTab === 'detail'" class="h-full">
|
||||
<MsSplitBox :size="0.8" direction="vertical" min="0" :max="0.99">
|
||||
<template #top>
|
||||
<div> toptop </div>
|
||||
<caseTabDetail :form="{}" :allow-edit="false" />
|
||||
</template>
|
||||
<template #bottom>
|
||||
<div class="flex h-full flex-col overflow-hidden">
|
||||
|
@ -153,6 +168,20 @@
|
|||
</template>
|
||||
</MsSplitBox>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="flex items-center justify-between">
|
||||
{{ t('caseManagement.caseReview.demandCases') }}
|
||||
<a-input-search
|
||||
v-model="demandKeyword"
|
||||
:placeholder="t('caseManagement.caseReview.demandSearchPlaceholder')"
|
||||
allow-clear
|
||||
class="w-[300px]"
|
||||
@press-enter="searchDemand"
|
||||
@search="searchDemand"
|
||||
/>
|
||||
</div>
|
||||
<caseTabDemand ref="caseDemandRef" :fun-params="{ caseId: route.query.id, keyword: demandKeyword }" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-footer">
|
||||
<div class="mb-[16px] flex items-center">
|
||||
|
@ -232,6 +261,7 @@
|
|||
/**
|
||||
* @description 功能测试-用例评审-用例详情
|
||||
*/
|
||||
import { useRoute } from 'vue-router';
|
||||
import { FormInstance } from '@arco-design/web-vue';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
|
@ -242,13 +272,18 @@
|
|||
import MsSplitBox from '@/components/pure/ms-split-box/index.vue';
|
||||
import caseLevel from '@/components/business/ms-case-associate/caseLevel.vue';
|
||||
import type { CaseLevel } from '@/components/business/ms-case-associate/types';
|
||||
import caseTabDemand from '../caseManagementFeature/components/tabContent/tabDemand/associatedDemandTable.vue';
|
||||
import caseTabDetail from '../caseManagementFeature/components/tabContent/tabDetail.vue';
|
||||
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
|
||||
const route = useRoute();
|
||||
const { t } = useI18n();
|
||||
|
||||
const reviewName = ref('打算肯定还是觉得还是觉得还是计划的');
|
||||
const caseDetail = ref({});
|
||||
const caseDetail = ref({
|
||||
demandCount: 999,
|
||||
});
|
||||
const onlyMine = ref(false);
|
||||
const keyword = ref('');
|
||||
|
||||
|
@ -415,6 +450,12 @@
|
|||
reason: '',
|
||||
});
|
||||
const dialogFormRef = ref<FormInstance>();
|
||||
const demandKeyword = ref('');
|
||||
const caseDemandRef = ref<InstanceType<typeof caseTabDemand>>();
|
||||
|
||||
function searchDemand() {
|
||||
caseDemandRef.value?.initData();
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
|
|
@ -86,8 +86,8 @@
|
|||
<template v-if="keyword.trim() === ''" #empty>
|
||||
<div class="flex items-center justify-center p-[8px] text-[var(--color-text-4)]">
|
||||
{{ t('caseManagement.caseReview.tableNoData') }}
|
||||
<MsButton class="ml-[8px]" @click="handleAddClick">
|
||||
{{ t('caseManagement.caseReview.create') }}
|
||||
<MsButton class="ml-[8px]" @click="createCase">
|
||||
{{ t('caseManagement.caseReview.crateCase') }}
|
||||
</MsButton>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -586,10 +586,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
function handleAddClick() {
|
||||
console.log('handleAddClick');
|
||||
}
|
||||
|
||||
function openDetail(id: string) {
|
||||
router.push({
|
||||
name: CaseManagementRouteEnum.CASE_MANAGEMENT_REVIEW_DETAIL_CASE_DETAIL,
|
||||
|
@ -606,7 +602,7 @@
|
|||
|
||||
function createCase() {
|
||||
router.push({
|
||||
name: CaseManagementRouteEnum.CASE_MANAGEMENT_REVIEW_CREATE,
|
||||
name: CaseManagementRouteEnum.CASE_MANAGEMENT_CASE_DETAIL,
|
||||
query: {
|
||||
reviewId: route.query.id,
|
||||
},
|
||||
|
|
|
@ -129,4 +129,5 @@ export default {
|
|||
'caseManagement.caseReview.submitReview': 'Submit review',
|
||||
'caseManagement.caseReview.reviewHistory': 'Review history',
|
||||
'caseManagement.caseReview.noMatchReviewer': 'No matching handler, can be set in {menu}',
|
||||
'caseManagement.caseReview.crateCase': 'Create case',
|
||||
};
|
||||
|
|
|
@ -119,4 +119,7 @@ export default {
|
|||
'caseManagement.caseReview.submitReview': '提交评审',
|
||||
'caseManagement.caseReview.reviewHistory': '评审历史',
|
||||
'caseManagement.caseReview.noMatchReviewer': '无匹配处理人,可在 ',
|
||||
'caseManagement.caseReview.crateCase': '创建用例',
|
||||
'caseManagement.caseReview.demandCases': '需求关联列表',
|
||||
'caseManagement.caseReview.demandSearchPlaceholder': '通过名称搜索',
|
||||
};
|
||||
|
|
|
@ -239,6 +239,19 @@
|
|||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* 初始化模块文件数量
|
||||
*/
|
||||
watch(
|
||||
() => props.modulesCount,
|
||||
(obj) => {
|
||||
storageList.value = originStorageList.value.map((e) => ({
|
||||
...e,
|
||||
count: obj?.[e.id] || 0,
|
||||
}));
|
||||
}
|
||||
);
|
||||
|
||||
const focusItemKey = ref('');
|
||||
|
||||
function setActiveFolder(id: string) {
|
||||
|
|
|
@ -229,7 +229,13 @@
|
|||
* 右侧表格数据刷新后,若当前展示的是模块,则刷新模块树的统计数量
|
||||
*/
|
||||
function handleModuleTableInit(params: FileListQueryParams) {
|
||||
initModulesCount(params);
|
||||
initModulesCount({
|
||||
...params,
|
||||
combine: {
|
||||
...params.combine,
|
||||
storage: showType.value === 'Module' ? 'minio' : 'git', // 这里因为存在切换我的、全部文件夹时,激活的是存储库列表,所以还要区分一下当前展示的类型是啥
|
||||
},
|
||||
});
|
||||
tableFilterParams.value = { ...params };
|
||||
}
|
||||
</script>
|
||||
|
|
Loading…
Reference in New Issue