feat: 机器人库、工业设计库、公差分析库
This commit is contained in:
@@ -5,13 +5,8 @@
|
||||
ref="tableFormRef"
|
||||
:tableName="tableName"
|
||||
v-model:data="formData"
|
||||
:formAttrs="{
|
||||
originalName: {
|
||||
multiple: !isEdit,
|
||||
limit: isEdit ? 1 : undefined,
|
||||
},
|
||||
}"
|
||||
:itemNum="5"
|
||||
:formAttrs="computedFormAttrs"
|
||||
:itemNum="itemNum"
|
||||
@change="onFormChangeFun"
|
||||
>
|
||||
<template #form-simulationPoolInfoList>
|
||||
@@ -47,6 +42,8 @@ interface Props {
|
||||
folder?: any;
|
||||
tableName: string;
|
||||
confirmLoading?: boolean;
|
||||
moduleCode?: string;
|
||||
itemNum?: number;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
@@ -55,16 +52,37 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
folder: null,
|
||||
tableName: '',
|
||||
confirmLoading: false,
|
||||
moduleCode: '',
|
||||
itemNum: 5,
|
||||
});
|
||||
|
||||
const emits = defineEmits<{
|
||||
'update:modelValue': [val: boolean];
|
||||
confirm: [data: any];
|
||||
}>();
|
||||
|
||||
const visible = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (val) => emits('update:modelValue', val),
|
||||
});
|
||||
|
||||
// 根据是否有审批模块动态生成formAttrs
|
||||
const computedFormAttrs = computed(() => {
|
||||
const attrs: any = {
|
||||
originalName: {
|
||||
multiple: !isEdit.value,
|
||||
limit: isEdit.value ? 1 : undefined,
|
||||
},
|
||||
};
|
||||
// 有审批模块时添加templateId配置
|
||||
if (props.moduleCode) {
|
||||
attrs.templateId = {
|
||||
moduleCode: props.moduleCode,
|
||||
};
|
||||
}
|
||||
return attrs;
|
||||
});
|
||||
|
||||
interface RuleForm {
|
||||
originalName: any;
|
||||
projectId: string | null;
|
||||
@@ -74,6 +92,7 @@ interface RuleForm {
|
||||
templateName?: string | null;
|
||||
templateId?: string | null;
|
||||
}
|
||||
|
||||
const formData = ref<RuleForm>({
|
||||
originalName: null,
|
||||
projectId: null,
|
||||
@@ -83,11 +102,14 @@ const formData = ref<RuleForm>({
|
||||
templateName: null,
|
||||
templateId: null,
|
||||
});
|
||||
|
||||
const isEdit = computed(() => !!(props.detail && props.detail.id));
|
||||
|
||||
const { isDirty, init: initSnapshot } = useDirtyForm(formData, {
|
||||
mode: () => (isEdit.value ? 'edit' : 'add'),
|
||||
pick: (data) => ({
|
||||
originalName: data.originalName,
|
||||
originalName:
|
||||
data.originalName?.map?.(({ fileId, name }: any) => ({ fileId, name })) || data.originalName,
|
||||
projectId: data.projectId,
|
||||
analysisDirectionId: data.analysisDirectionId,
|
||||
simulationPoolInfoList: data.simulationPoolInfoList,
|
||||
@@ -119,6 +141,7 @@ const initData = () => {
|
||||
formData.value.simulationPoolInfoList = props.detail?.poolInfos;
|
||||
initSnapshot(formData.value);
|
||||
};
|
||||
|
||||
watchEffect(() => {
|
||||
nextTick(() => {
|
||||
if (props.detail && props.detail.id) {
|
||||
@@ -126,6 +149,7 @@ watchEffect(() => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const resetFun = () => {
|
||||
formData.value = {
|
||||
originalName: null,
|
||||
@@ -139,6 +163,7 @@ const resetFun = () => {
|
||||
initSnapshot();
|
||||
tableFormRef.value?.resetFun();
|
||||
};
|
||||
|
||||
const onFormChangeFun = (data: any) => {
|
||||
formData.value = tableFormRef.value.getFormDataFun();
|
||||
if (data.key === 'templateId') {
|
||||
@@ -146,10 +171,13 @@ const onFormChangeFun = (data: any) => {
|
||||
formData.value.templateName = data?.val?.label;
|
||||
}
|
||||
};
|
||||
|
||||
const tableFormRef = ref<any>();
|
||||
|
||||
const onCancelFun = () => {
|
||||
visible.value = false;
|
||||
};
|
||||
|
||||
const onConfirmFun = async () => {
|
||||
const valid = await tableFormRef.value?.validateFun();
|
||||
if (valid) {
|
||||
@@ -164,11 +192,11 @@ const onConfirmFun = async () => {
|
||||
};
|
||||
});
|
||||
}
|
||||
// return;
|
||||
emits('confirm', formResult);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.upload {
|
||||
width: 100%;
|
||||
118
src/components/common/resourceLibrary/folderModal.vue
Normal file
118
src/components/common/resourceLibrary/folderModal.vue
Normal file
@@ -0,0 +1,118 @@
|
||||
<template>
|
||||
<Dialog
|
||||
v-model="visible"
|
||||
showFooter
|
||||
showCancelButton
|
||||
showConfirmButton
|
||||
:diaTitle="mode === 'add' ? $t('知识库.新增') : $t('知识库.编辑')"
|
||||
:confirmClosable="false"
|
||||
:width="500"
|
||||
>
|
||||
<template #default>
|
||||
<el-form ref="formRef" :rules="rules" :model="form" labelWidth="80">
|
||||
<el-form-item :label="$t('知识库.名称')" prop="name">
|
||||
<el-input v-model="form.name" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
<template #footer>
|
||||
<div>
|
||||
<el-button @click="onCancelFun">{{ $t('通用.取消') }}</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
:loading="confirmLoading"
|
||||
:disabled="!isDirty"
|
||||
@click="onConfirmFun"
|
||||
>{{ $t('通用.确定') }}</el-button
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed, watch } from 'vue';
|
||||
import Dialog from '@/components/common/dialog/index.vue';
|
||||
import type { FormInstance, FormRules } from 'element-plus';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useDirtyForm } from '@/utils/useDirtyForm';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
interface Props {
|
||||
modelValue: boolean;
|
||||
detail: any;
|
||||
mode: 'add' | 'edit';
|
||||
confirmLoading?: boolean;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
modelValue: false,
|
||||
detail: null,
|
||||
mode: 'add',
|
||||
confirmLoading: false,
|
||||
});
|
||||
|
||||
const emits = defineEmits(['update:modelValue', 'confirm']);
|
||||
|
||||
const form = ref({
|
||||
name: '',
|
||||
});
|
||||
|
||||
const { isDirty, init: initSnapshot } = useDirtyForm(form, {
|
||||
mode: () => props.mode,
|
||||
});
|
||||
|
||||
const visible = computed({
|
||||
get: () => props.modelValue,
|
||||
set: (val) => emits('update:modelValue', val),
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(val) => {
|
||||
if (val) {
|
||||
resetFun();
|
||||
if (props.detail && props.mode === 'edit') {
|
||||
form.value.name = props.detail.originalName || props.detail.nodeName;
|
||||
initSnapshot(form.value);
|
||||
} else {
|
||||
form.value.name = '';
|
||||
initSnapshot();
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const resetFun = () => {
|
||||
if (!formRef.value) {
|
||||
return;
|
||||
}
|
||||
formRef.value.resetFields();
|
||||
};
|
||||
|
||||
const formRef = ref<FormInstance>();
|
||||
|
||||
interface RuleForm {
|
||||
name: string;
|
||||
}
|
||||
|
||||
const rules = reactive<FormRules<RuleForm>>({
|
||||
name: [{ required: true, message: t('知识库.请输入名称'), trigger: 'blur' }],
|
||||
});
|
||||
|
||||
const onCancelFun = () => {
|
||||
visible.value = false;
|
||||
};
|
||||
|
||||
const onConfirmFun = async () => {
|
||||
if (!formRef.value) {
|
||||
return;
|
||||
}
|
||||
await formRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
emits('confirm', form.value);
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
44
src/components/common/resourceLibrary/infoDrawer.vue
Normal file
44
src/components/common/resourceLibrary/infoDrawer.vue
Normal file
@@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<el-drawer
|
||||
v-model="visible"
|
||||
:size="400"
|
||||
:title="$t('知识库.基本信息')"
|
||||
:closeOnClickModal="false"
|
||||
@close="visible = false"
|
||||
>
|
||||
<div class="info-content">
|
||||
<el-descriptions class="info-content-descriptions" :column="1" labelWidth="100px" border>
|
||||
<el-descriptions-item :label="$t('知识库.目录名称')">
|
||||
{{ data?.originalName }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('通用.创建人')">
|
||||
{{ data?.creatorName }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('通用.创建时间')">
|
||||
{{ data?.createTime }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('通用.更新人')">
|
||||
{{ data?.updaterName }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('通用.更新时间')">
|
||||
{{ data?.updateTime }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
const visible = defineModel<boolean>({ default: false });
|
||||
defineProps<{ data?: any }>();
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.info-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.info-content-descriptions {
|
||||
margin-top: var(--margin-small);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
701
src/components/common/resourceLibrary/resourceLibraryPage.vue
Normal file
701
src/components/common/resourceLibrary/resourceLibraryPage.vue
Normal file
@@ -0,0 +1,701 @@
|
||||
<template>
|
||||
<div class="gl-page-content-grey-full">
|
||||
<div class="content">
|
||||
<FileTree
|
||||
ref="fileTreeRef"
|
||||
:api="listDirApi"
|
||||
:params="{ dirType: dirType }"
|
||||
@choseNode="choseNodeFun"
|
||||
@updateNav="updateNavFun"
|
||||
>
|
||||
<template #options>
|
||||
<el-button :icon="Plus" class="options" type="primary" @click="appendFun({})">
|
||||
{{ $t('知识库.新增') }}
|
||||
</el-button>
|
||||
</template>
|
||||
<template #treeAction="{ data }">
|
||||
<!-- 新增子目录 -->
|
||||
<el-tooltip
|
||||
v-if="parsePermission(data.permissionValue).write"
|
||||
:content="$t('知识库.新增子目录')"
|
||||
placement="top"
|
||||
>
|
||||
<el-button type="primary" link @click.stop="appendFun(data)">
|
||||
<el-icon><FolderAdd /></el-icon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<!-- 编辑目录 -->
|
||||
<el-tooltip
|
||||
v-if="parsePermission(data.permissionValue).write"
|
||||
:content="$t('通用.编辑')"
|
||||
placement="top"
|
||||
>
|
||||
<el-button type="primary" link @click.stop="updateFun(data)">
|
||||
<el-icon><EditPen /></el-icon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<!-- 删除目录 -->
|
||||
<el-tooltip
|
||||
v-if="parsePermission(data.permissionValue).delete"
|
||||
:content="$t('通用.删除')"
|
||||
placement="top"
|
||||
>
|
||||
<el-button type="danger" link @click.stop="confirmRemoveFun(data)">
|
||||
<el-icon><Delete /></el-icon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<template #table>
|
||||
<div class="right-table">
|
||||
<div class="search">
|
||||
<TableSearch
|
||||
v-if="searchItems.length > 0"
|
||||
ref="tableSearchRef"
|
||||
:searchItems="searchItems"
|
||||
@search="searchFun"
|
||||
@reset="resetFun"
|
||||
/>
|
||||
</div>
|
||||
<div class="table">
|
||||
<BaseTable
|
||||
ref="baseTableRef"
|
||||
:tableName="tableName"
|
||||
:api="apiName"
|
||||
:params="searchParams"
|
||||
showIndex
|
||||
:actionList="actionList"
|
||||
:exportApi="dataExportKnowledgeListApi"
|
||||
fullHeight
|
||||
:exportFileName="$t('知识库.知识库列表')"
|
||||
:exportParams="{
|
||||
...searchParams,
|
||||
parentDirId: currentFolder?.id || '',
|
||||
}"
|
||||
@cell-dblclick="onCellDblclickFun"
|
||||
>
|
||||
<template #leftOptions>
|
||||
<div>
|
||||
<el-button
|
||||
:icon="DArrowLeft"
|
||||
:disabled="navList.length <= 1"
|
||||
@click="backFun"
|
||||
>{{ $t('通用.返回上一级') }}</el-button
|
||||
>
|
||||
<el-button
|
||||
v-if="folderPermission.import"
|
||||
type="primary"
|
||||
:icon="Plus"
|
||||
:disabled="!currentFolder"
|
||||
@click="openModalFun"
|
||||
>
|
||||
{{ $t('知识库.上传') }}
|
||||
</el-button>
|
||||
<el-button :disabled="!currentFolder" @click="infoVisible = true">
|
||||
{{ $t('知识库.基本信息') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<template #fileSize="{ row }">
|
||||
{{ formatFileSize(row.fileSize) }}
|
||||
</template>
|
||||
<template #versionNo="{ row }">
|
||||
{{ row.versionNo ? 'V' + row.versionNo : '--' }}
|
||||
</template>
|
||||
<template #poolInfos="{ row }">
|
||||
<PoolTaskSelect :modelValue="row.poolInfos" :editable="false" />
|
||||
</template>
|
||||
<!-- 需要审批时显示审批状态 -->
|
||||
<template v-if="needApproval" #approvalStatus="{ row, column }">
|
||||
<template v-if="row.dataType === 2">
|
||||
<el-button
|
||||
v-if="row[column.field] === 'pending'"
|
||||
type="primary"
|
||||
link
|
||||
@click="openProcessFun(row)"
|
||||
>
|
||||
{{ KNOWLEDGE_APPROVE_STATUS.O[row[column.field]] }}
|
||||
</el-button>
|
||||
<el-button v-else type="primary" link @click="openProcessFun(row)">
|
||||
{{ $t('知识库.审批完成') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</template>
|
||||
<template v-if="needApproval" #approveType="{ row, column }">
|
||||
<el-button
|
||||
v-if="row.dataType === 2"
|
||||
type="primary"
|
||||
link
|
||||
@click="openProcessFun(row)"
|
||||
>
|
||||
{{ KNOWLEDGE_APPROVE_TYPE.O[row[column.field]] }}
|
||||
</el-button>
|
||||
</template>
|
||||
</BaseTable>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</FileTree>
|
||||
</div>
|
||||
<!-- 审批流程弹窗(仅需要审批时显示) -->
|
||||
<ApprovalProcess v-if="needApproval" v-model="processVisible" :flowId="currentRow?.cidFlowId" />
|
||||
<!-- 上传/编辑弹窗 -->
|
||||
<DetailModal
|
||||
v-model="visible"
|
||||
:detail="currentRow"
|
||||
:folder="currentFolder"
|
||||
:tableName="tableName"
|
||||
:moduleCode="moduleCode"
|
||||
:itemNum="needApproval ? 6 : 5"
|
||||
:confirmLoading="confirmLoading"
|
||||
@confirm="onConfirmFun"
|
||||
/>
|
||||
<!-- 文件夹弹窗 -->
|
||||
<FolderModal
|
||||
v-model="folderModalVisible"
|
||||
:detail="currentFolder"
|
||||
:mode="currentFolderMode"
|
||||
:confirmLoading="folderConfirmLoading"
|
||||
@confirm="onFolderConfirmFun"
|
||||
/>
|
||||
<!-- 文件预览 -->
|
||||
<FilePreview v-model="previewVisible" :fileId="currentRow?.id" />
|
||||
<!-- 基本信息抽屉 -->
|
||||
<InfoDrawer v-model="infoVisible" :data="currentFolder" />
|
||||
<!-- 需要审批时的删除弹窗 -->
|
||||
<ApproveDel
|
||||
v-if="needApproval"
|
||||
v-model="approveDelVisible"
|
||||
:api="dataDelFileApi"
|
||||
:params="approveDelParams"
|
||||
:moduleCode="moduleCode"
|
||||
@confirm="refreshTableFun"
|
||||
/>
|
||||
<ApproveDel
|
||||
v-if="needApproval"
|
||||
v-model="approveDelDirVisible"
|
||||
:api="dataDelDirApi"
|
||||
:params="approveDelDirParams"
|
||||
:moduleCode="moduleCode"
|
||||
@confirm="onDelDirConfirmFun"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
/**
|
||||
* 资源库页面公共组件
|
||||
* 适用于:动画库、机器人库、工业设计库、公差分析库等
|
||||
* 通过 needApproval 区分是否需要审批流程
|
||||
*/
|
||||
import {
|
||||
computed,
|
||||
onActivated,
|
||||
onBeforeUnmount,
|
||||
onDeactivated,
|
||||
onMounted,
|
||||
ref,
|
||||
watchEffect,
|
||||
type Ref,
|
||||
} from 'vue';
|
||||
import { DArrowLeft, Plus } from '@element-plus/icons-vue';
|
||||
import BaseTable from '@/components/common/table/baseTable.vue';
|
||||
import FileTree from '@/components/common/fileTree/index.vue';
|
||||
import DetailModal from './detailModal.vue';
|
||||
import FolderModal from './folderModal.vue';
|
||||
import InfoDrawer from './infoDrawer.vue';
|
||||
import {
|
||||
dataCreateDirApi,
|
||||
dataListDirApi,
|
||||
dataRenameDirApi,
|
||||
dataDelDirApi,
|
||||
dataQueryDirApi,
|
||||
dataFileSearchApi,
|
||||
dataDelFileApi,
|
||||
dataUpdateFileApi,
|
||||
batchAddFileInfoApi,
|
||||
dataExportKnowledgeListApi,
|
||||
isDirEmptyApi,
|
||||
} from '@/api/data/data';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import type { RenderContentContext } from 'element-plus';
|
||||
import { formatFileSize, downloadFileById } from '@/utils/file';
|
||||
import TableSearch from '@/components/common/table/tableSearch.vue';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { useDict } from '@/utils/useDict';
|
||||
import ApprovalProcess from '@/components/common/approvalProcess/index.vue';
|
||||
import ApproveDel from '@/components/common/approveDel/index.vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import FilePreview from '@/components/common/filePreview/index.vue';
|
||||
import emitter from '@/utils/eventBus';
|
||||
import PoolTaskSelect from '@/components/pool/poolTaskSelect.vue';
|
||||
import { parsePermission } from '@/utils/permission';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { TABLE_NAME } from '@/utils/enum/tableName';
|
||||
|
||||
interface Props {
|
||||
tableName?: string;
|
||||
dirType: number;
|
||||
needApproval?: boolean;
|
||||
moduleCode?: string;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
tableName: TABLE_NAME.ANIMATION_LIBRARY,
|
||||
needApproval: false,
|
||||
moduleCode: '',
|
||||
});
|
||||
|
||||
const route = useRoute();
|
||||
const CALLBACK_FLAG = computed(() => route.path);
|
||||
|
||||
const listDirApi = (params: any) => {
|
||||
return dataListDirApi({ ...params, dirType: props.dirType });
|
||||
};
|
||||
|
||||
const folderPermission = computed(() =>
|
||||
parsePermission(currentFolder.value?.permissionValue ?? 31)
|
||||
);
|
||||
|
||||
const { t } = useI18n();
|
||||
const { KNOWLEDGE_APPROVE_STATUS, KNOWLEDGE_APPROVE_TYPE } = useDict(
|
||||
'KNOWLEDGE_APPROVE_STATUS',
|
||||
'KNOWLEDGE_APPROVE_TYPE'
|
||||
);
|
||||
|
||||
type Data = RenderContentContext['data'];
|
||||
const fileTreeRef = ref<any>();
|
||||
const baseTableRef = ref<any>();
|
||||
const navList = ref<any>([]);
|
||||
const currentFolder = ref();
|
||||
const memoryFolder = ref();
|
||||
const currentFolderMode: Ref<'add' | 'edit'> = ref('add');
|
||||
|
||||
const choseNodeFun = (data: Data) => {
|
||||
isSearching.value = false;
|
||||
currentFolder.value = data;
|
||||
memoryFolder.value = currentFolder.value;
|
||||
};
|
||||
|
||||
const updateNavFun = (data: any) => {
|
||||
navList.value = data;
|
||||
};
|
||||
|
||||
const backFun = () => {
|
||||
fileTreeRef.value.backFun();
|
||||
};
|
||||
|
||||
const searchItems = computed(() => [
|
||||
{ title: t('通用.名称'), key: 'fileName', inputMode: 'input' },
|
||||
{ title: t('知识库.上传人'), key: 'uploadUserId', inputMode: 'userSelectMultiple' },
|
||||
]);
|
||||
|
||||
const folderModalVisible = ref(false);
|
||||
const folderConfirmLoading = ref(false);
|
||||
|
||||
const appendFun = (data: Data) => {
|
||||
currentFolder.value = data;
|
||||
currentFolderMode.value = 'add';
|
||||
folderModalVisible.value = true;
|
||||
};
|
||||
|
||||
const updateFun = (data: Data) => {
|
||||
currentFolder.value = data;
|
||||
currentFolderMode.value = 'edit';
|
||||
folderModalVisible.value = true;
|
||||
};
|
||||
|
||||
// 删除目录确认
|
||||
const confirmRemoveFun = async (data: Data) => {
|
||||
if (props.needApproval) {
|
||||
const res: any = await isDirEmptyApi({ dirId: data.id });
|
||||
if (res.code !== 200) {
|
||||
return;
|
||||
}
|
||||
if (res.data) {
|
||||
ElMessageBox.confirm(t('知识库.确认删除空目录'), t('通用.提示'), {
|
||||
confirmButtonText: t('通用.确定'),
|
||||
cancelButtonText: t('通用.取消'),
|
||||
type: 'warning',
|
||||
})
|
||||
.then(async () => {
|
||||
const delRes: any = await dataDelDirApi({ delDirId: data.id });
|
||||
if (delRes.code === 200) {
|
||||
refreshTreeAfterModifyOrRemove(data);
|
||||
ElMessage.success(delRes.message);
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
} else {
|
||||
ElMessageBox.confirm(t('知识库.目录内文件将一同被删除'), t('通用.提示'), {
|
||||
confirmButtonText: t('通用.确定'),
|
||||
cancelButtonText: t('通用.取消'),
|
||||
type: 'warning',
|
||||
})
|
||||
.then(() => {
|
||||
currentFolderToDelete.value = data;
|
||||
approveDelDirParams.value = { delDirId: data.id };
|
||||
approveDelDirVisible.value = true;
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
} else {
|
||||
// 不需要审批直接删除
|
||||
ElMessageBox.confirm(t('知识库.确认删除'), t('通用.提示'), {
|
||||
confirmButtonText: t('通用.确定'),
|
||||
cancelButtonText: t('通用.取消'),
|
||||
type: 'warning',
|
||||
})
|
||||
.then(() => removeFun(data))
|
||||
.catch(() => {});
|
||||
}
|
||||
};
|
||||
|
||||
const removeFun = async (data: Data) => {
|
||||
const res: any = await dataDelDirApi({ delDirId: data.id });
|
||||
if (res.code === 200) {
|
||||
refreshTreeAfterModifyOrRemove(data);
|
||||
ElMessage.success(res.message);
|
||||
}
|
||||
};
|
||||
|
||||
const refreshTreeRoot = () => {
|
||||
fileTreeRef.value?.reloadFun();
|
||||
baseTableRef.value?.resetFun();
|
||||
};
|
||||
|
||||
const refreshTreeOpenDir = (dirId: number) => {
|
||||
fileTreeRef.value?.openDirFun(dirId);
|
||||
baseTableRef.value?.resetFun();
|
||||
};
|
||||
|
||||
const refreshTreeAfterAdd = (parentNode?: any | null) => {
|
||||
if (parentNode && typeof parentNode.id === 'number') {
|
||||
refreshTreeOpenDir(parentNode.id);
|
||||
} else {
|
||||
refreshTreeRoot();
|
||||
}
|
||||
};
|
||||
|
||||
const isTopLevel = (node: any) => {
|
||||
if (!node || !node.objectKey) {
|
||||
return false;
|
||||
}
|
||||
const key = String(node.objectKey).replace(/\/$/, '');
|
||||
const parts = key.split('/');
|
||||
return parts.length === 2;
|
||||
};
|
||||
|
||||
const refreshTreeAfterModifyOrRemove = (node?: any | null) => {
|
||||
if (isTopLevel(node)) {
|
||||
refreshTreeRoot();
|
||||
} else {
|
||||
refreshTreeOpenDir(node.parentId);
|
||||
}
|
||||
};
|
||||
|
||||
const isSearching = ref(false);
|
||||
const searchParams = ref<any>({
|
||||
fileId: currentFolder.value?.id || '',
|
||||
dirType: props.dirType,
|
||||
});
|
||||
|
||||
// 操作按钮列表
|
||||
const actionList = computed(() => {
|
||||
const list = [
|
||||
{
|
||||
title: t('通用.预览'),
|
||||
type: 'primary',
|
||||
click: (row: any) => previewFileFun(row),
|
||||
hide: (row: any) => row.dataType !== 2 || !parsePermission(row.permissionValue).read,
|
||||
},
|
||||
{
|
||||
title: t('通用.下载'),
|
||||
type: 'primary',
|
||||
click: (row: any) => downloadFileById(row.id),
|
||||
hide: (row: any) => row.dataType !== 2 || !parsePermission(row.permissionValue).export,
|
||||
},
|
||||
{
|
||||
title: t('通用.编辑'),
|
||||
type: 'primary',
|
||||
click: (row: any) => editFileFun(row),
|
||||
hide: (row: any) =>
|
||||
row.dataType !== 2 ||
|
||||
row.approvalStatus === 'pending' ||
|
||||
!parsePermission(row.permissionValue).write,
|
||||
},
|
||||
];
|
||||
|
||||
// 删除按钮根据是否需要审批有不同逻辑
|
||||
if (props.needApproval) {
|
||||
list.push({
|
||||
title: t('通用.删除'),
|
||||
type: 'danger',
|
||||
click: (row: any) => delFileWithApprovalFun(row),
|
||||
hide: (row: any) =>
|
||||
row.dataType !== 2 ||
|
||||
row.approvalStatus === 'pending' ||
|
||||
!parsePermission(row.permissionValue).delete,
|
||||
});
|
||||
} else {
|
||||
list.push({
|
||||
title: t('通用.删除'),
|
||||
type: 'danger',
|
||||
needConfirm: true,
|
||||
confirmTip: t('通用.确认删除吗'),
|
||||
click: (row: any) => delFileFun(row),
|
||||
hide: (row: any) =>
|
||||
row.dataType !== 2 ||
|
||||
row.approvalStatus === 'pending' ||
|
||||
!parsePermission(row.permissionValue).delete,
|
||||
} as any);
|
||||
}
|
||||
|
||||
return list;
|
||||
});
|
||||
|
||||
const searchFun = (data: object) => {
|
||||
isSearching.value = true;
|
||||
if (!memoryFolder.value && currentFolder.value) {
|
||||
memoryFolder.value = currentFolder.value;
|
||||
currentFolder.value = null;
|
||||
}
|
||||
searchParams.value = cloneDeep(data);
|
||||
searchParams.value.searchType = 1;
|
||||
searchParams.value.parentDirId = memoryFolder.value?.id || '';
|
||||
searchParams.value.dirType = props.dirType;
|
||||
};
|
||||
|
||||
const resetFun = (data: object) => {
|
||||
isSearching.value = false;
|
||||
currentFolder.value = memoryFolder.value;
|
||||
searchParams.value = cloneDeep(data);
|
||||
searchParams.value.fileId = currentFolder.value?.id || '';
|
||||
searchParams.value.dirType = props.dirType;
|
||||
};
|
||||
|
||||
const refreshTableFun = async () => {
|
||||
baseTableRef.value?.resetFun();
|
||||
};
|
||||
|
||||
const onFolderConfirmFun = async (formData: any) => {
|
||||
folderConfirmLoading.value = true;
|
||||
try {
|
||||
if (currentFolderMode.value === 'add') {
|
||||
const req = {
|
||||
dirType: props.dirType,
|
||||
parDirId: currentFolder.value?.id,
|
||||
dirName: formData.name,
|
||||
type: 0,
|
||||
};
|
||||
const res: any = await dataCreateDirApi(req);
|
||||
if (res.code === 200) {
|
||||
refreshTreeAfterAdd(currentFolder.value);
|
||||
folderModalVisible.value = false;
|
||||
ElMessage.success(res.message);
|
||||
}
|
||||
} else if (currentFolderMode.value === 'edit') {
|
||||
const req = {
|
||||
dirId: currentFolder.value?.id,
|
||||
oldName: currentFolder.value?.originalName,
|
||||
newName: formData.name,
|
||||
type: 0,
|
||||
};
|
||||
const res: any = await dataRenameDirApi(req);
|
||||
if (res.code === 200) {
|
||||
refreshTreeAfterModifyOrRemove(currentFolder.value);
|
||||
folderModalVisible.value = false;
|
||||
ElMessage.success(res.message);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
folderConfirmLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const visible = ref(false);
|
||||
const confirmLoading = ref(false);
|
||||
const infoVisible = ref(false);
|
||||
const currentRow = ref();
|
||||
|
||||
const openModalFun = () => {
|
||||
visible.value = true;
|
||||
currentRow.value = null;
|
||||
};
|
||||
|
||||
const onConfirmFun = async (formData: any) => {
|
||||
let res: any;
|
||||
confirmLoading.value = true;
|
||||
try {
|
||||
if (currentRow.value && currentRow.value.id) {
|
||||
// 编辑
|
||||
const file = formData.file?.[0];
|
||||
const req = {
|
||||
...currentRow.value,
|
||||
templateId: formData.templateId,
|
||||
templateName: formData.templateName,
|
||||
file: file?.raw,
|
||||
fileName: file?.fileName,
|
||||
size: file?.size,
|
||||
projectName: formData.projectName,
|
||||
path: currentFolder.value?.objectKey,
|
||||
dirId: currentFolder.value?.id,
|
||||
chunk: 0,
|
||||
remarks: formData.remarks,
|
||||
projectId: formData.projectId,
|
||||
chunkTotal: 0,
|
||||
encryptKey: null,
|
||||
type: 0,
|
||||
analysisDirectionId: formData.analysisDirectionId,
|
||||
simulationPoolInfoListStr: JSON.stringify(formData.simulationPoolInfoList),
|
||||
};
|
||||
delete req.poolInfos;
|
||||
res = await dataUpdateFileApi(req);
|
||||
} else {
|
||||
// 新增
|
||||
const req = {
|
||||
sourceFiles: formData.file,
|
||||
uploadTaskId: new Date().getTime(),
|
||||
dirId: currentFolder.value?.id,
|
||||
projectId: formData.projectId,
|
||||
analysisDirectionId: formData.analysisDirectionId,
|
||||
templateId: formData.templateId,
|
||||
templateName: formData.templateName,
|
||||
remarks: formData.remarks,
|
||||
type: 0,
|
||||
simulationPoolInfoList: formData.simulationPoolInfoList,
|
||||
};
|
||||
res = await batchAddFileInfoApi(req);
|
||||
if (res.code === 200) {
|
||||
res.data.forEach((item: any, index: number) => {
|
||||
emitter.emit('ADD_UPLOAD_FILE', {
|
||||
file: formData.originalName[index].raw,
|
||||
data: {
|
||||
...item,
|
||||
isApprove: props.needApproval ? 1 : 0,
|
||||
taskType: 2,
|
||||
callbackFlag: CALLBACK_FLAG.value,
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
if (res.code === 200) {
|
||||
visible.value = false;
|
||||
refreshTableFun();
|
||||
ElMessage.success(res.message);
|
||||
}
|
||||
} finally {
|
||||
confirmLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const previewVisible = ref(false);
|
||||
const previewFileFun = (row: any) => {
|
||||
currentRow.value = row;
|
||||
previewVisible.value = true;
|
||||
};
|
||||
|
||||
const editFileFun = (row: any) => {
|
||||
currentRow.value = row;
|
||||
visible.value = true;
|
||||
};
|
||||
|
||||
// 不需要审批的删除
|
||||
const delFileFun = async (row: any) => {
|
||||
currentRow.value = row;
|
||||
try {
|
||||
const res: any = await dataDelFileApi({ delFileId: row.id });
|
||||
if (res.code === 200) {
|
||||
refreshTableFun();
|
||||
ElMessage.success(res.message);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
// 需要审批的删除
|
||||
const approveDelVisible = ref(false);
|
||||
const approveDelParams = ref<any>({});
|
||||
const approveDelDirVisible = ref(false);
|
||||
const approveDelDirParams = ref<any>({});
|
||||
const currentFolderToDelete = ref<any>(null);
|
||||
|
||||
const delFileWithApprovalFun = (row: any) => {
|
||||
currentRow.value = row;
|
||||
approveDelParams.value = { delFileId: row.id };
|
||||
approveDelVisible.value = true;
|
||||
};
|
||||
|
||||
const onDelDirConfirmFun = () => {
|
||||
refreshTreeAfterModifyOrRemove(currentFolderToDelete.value);
|
||||
};
|
||||
|
||||
const onCellDblclickFun = (e: any) => {
|
||||
if (e.row.dataType === 1) {
|
||||
fileTreeRef.value?.openDirFun(e.row.id);
|
||||
}
|
||||
};
|
||||
|
||||
const apiName: any = ref(null);
|
||||
watchEffect(() => {
|
||||
if (currentFolder.value && currentFolder.value?.id && !isSearching.value) {
|
||||
searchParams.value.fileId = currentFolder.value?.id || '';
|
||||
apiName.value = dataQueryDirApi;
|
||||
} else if (isSearching.value) {
|
||||
apiName.value = dataFileSearchApi;
|
||||
} else {
|
||||
apiName.value = dataFileSearchApi;
|
||||
}
|
||||
});
|
||||
|
||||
// 审批流程弹窗
|
||||
const processVisible = ref(false);
|
||||
const openProcessFun = (row: any) => {
|
||||
currentRow.value = row;
|
||||
processVisible.value = true;
|
||||
};
|
||||
|
||||
// 上传完成回调
|
||||
const uploadFinishedFun = (data: any) => {
|
||||
if (data.callbackFlag === CALLBACK_FLAG.value) {
|
||||
refreshTableFun();
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
emitter.on('UPLOAD_FINISHED', uploadFinishedFun);
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
emitter.off('UPLOAD_FINISHED', uploadFinishedFun);
|
||||
});
|
||||
|
||||
onActivated(() => {
|
||||
emitter.on('UPLOAD_FINISHED', uploadFinishedFun);
|
||||
});
|
||||
|
||||
onDeactivated(() => {
|
||||
emitter.off('UPLOAD_FINISHED', uploadFinishedFun);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.gl-page-content-grey-full {
|
||||
.content {
|
||||
height: 100%;
|
||||
.options {
|
||||
margin-bottom: var(--margin-small);
|
||||
}
|
||||
.right-table {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
.table {
|
||||
flex: 1;
|
||||
height: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -235,12 +235,6 @@ export default [
|
||||
name: 'CompetenceCenterKnowledge',
|
||||
component: () => import('@/views/competenceCenter/knowledge/index.vue'),
|
||||
},
|
||||
{
|
||||
title: '仿真动画库',
|
||||
path: '/competenceCenter/animation',
|
||||
name: 'CompetenceCenterAnimation',
|
||||
component: () => import('@/tenants/lyric/views/competenceCenter/animation/index.vue'),
|
||||
},
|
||||
{
|
||||
title: '仿真参数库',
|
||||
path: '/competenceCenter/parameter',
|
||||
@@ -259,6 +253,26 @@ export default [
|
||||
name: 'CompetenceCenterAnimation',
|
||||
component: () => import('@/tenants/lyric/views/competenceCenter/animation/index.vue'),
|
||||
},
|
||||
{
|
||||
title: '机器人库',
|
||||
path: '/competenceCenter/robot',
|
||||
name: 'CompetenceCenterRobot',
|
||||
component: () => import('@/tenants/lyric/views/competenceCenter/robot/index.vue'),
|
||||
},
|
||||
{
|
||||
title: '工业设计库',
|
||||
path: '/competenceCenter/industrialDesign',
|
||||
name: 'CompetenceCenterIndustrialDesign',
|
||||
component: () =>
|
||||
import('@/tenants/lyric/views/competenceCenter/industrialDesign/index.vue'),
|
||||
},
|
||||
{
|
||||
title: '公差分析库',
|
||||
path: '/competenceCenter/toleranceAnalysis',
|
||||
name: 'CompetenceCenterToleranceAnalysis',
|
||||
component: () =>
|
||||
import('@/tenants/lyric/views/competenceCenter/toleranceAnalysis/index.vue'),
|
||||
},
|
||||
// {
|
||||
// title: '仿真流程库',
|
||||
// path: '/simulation/process',
|
||||
|
||||
@@ -1,561 +1,8 @@
|
||||
<template>
|
||||
<div class="gl-page-content-grey-full">
|
||||
<div class="content">
|
||||
<FileTree
|
||||
ref="fileTreeRef"
|
||||
:api="dataListDirAnimationApi"
|
||||
:params="{ dirType: DIR_TYPE.ANIMATION }"
|
||||
@choseNode="choseNodeFun"
|
||||
@updateNav="updateNavFun"
|
||||
>
|
||||
<template #options>
|
||||
<el-button :icon="Plus" class="options" type="primary" @click="appendFun({})">
|
||||
{{ $t('知识库.新增') }}
|
||||
</el-button>
|
||||
</template>
|
||||
<template #treeAction="{ data }">
|
||||
<el-tooltip :content="$t('知识库.新增子目录')" placement="top">
|
||||
<el-button type="primary" link @click.stop="appendFun(data)">
|
||||
<el-icon>
|
||||
<FolderAdd />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip :content="$t('通用.编辑')" placement="top">
|
||||
<el-button type="primary" link @click.stop="updateFun(data)">
|
||||
<el-icon>
|
||||
<EditPen />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip :content="$t('通用.删除')" placement="top">
|
||||
<el-button type="danger" link @click.stop="confirmRemoveFun(data)">
|
||||
<el-icon>
|
||||
<Delete />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<template #table>
|
||||
<div class="right-table">
|
||||
<div class="search">
|
||||
<TableSearch
|
||||
v-if="searchItems.length > 0"
|
||||
ref="tableSearchRef"
|
||||
:searchItems="searchItems"
|
||||
@search="searchFun"
|
||||
@reset="resetFun"
|
||||
/>
|
||||
</div>
|
||||
<div class="table">
|
||||
<BaseTable
|
||||
ref="baseTableRef"
|
||||
:tableName="TABLE_NAME.ANIMATION_LIBRARY"
|
||||
:api="apiName"
|
||||
:params="searchParams"
|
||||
showIndex
|
||||
:actionList="actionList"
|
||||
:exportApi="dataExportKnowledgeListApi"
|
||||
fullHeight
|
||||
:exportFileName="$t('知识库.知识库列表')"
|
||||
:exportParams="{
|
||||
...searchParams,
|
||||
parentDirId: currentFolder?.id || '',
|
||||
}"
|
||||
@cell-dblclick="onCellDblclickFun"
|
||||
>
|
||||
<template #leftOptions>
|
||||
<div>
|
||||
<el-button
|
||||
:icon="DArrowLeft"
|
||||
@click="backFun"
|
||||
:disabled="navList.length <= 1"
|
||||
>{{ $t('通用.返回上一级') }}</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
:icon="Plus"
|
||||
@click="openModalFun"
|
||||
:disabled="!currentFolder"
|
||||
>
|
||||
{{ $t('知识库.上传') }}
|
||||
</el-button>
|
||||
<el-button @click="infoVisible = true" :disabled="!currentFolder">
|
||||
{{ $t('知识库.基本信息') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<template #fileSize="{ row }">
|
||||
{{ formatFileSize(row.fileSize) }}
|
||||
</template>
|
||||
<template #versionNo="{ row }">
|
||||
{{ row.versionNo ? 'V' + row.versionNo : '--' }}
|
||||
</template>
|
||||
<template #poolInfos="{ row }">
|
||||
<PoolTaskSelect :modelValue="row.poolInfos" :editable="false" />
|
||||
</template>
|
||||
<template #approvalStatus="{ row, column }">
|
||||
<template v-if="row.dataType === 2">
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
@click="openProcessFun(row)"
|
||||
v-if="row[column.field] === 'pending'"
|
||||
>
|
||||
{{ KNOWLEDGE_APPROVE_STATUS.O[row[column.field]] }}
|
||||
</el-button>
|
||||
<el-button type="primary" link @click="openProcessFun(row)" v-else>
|
||||
{{ $t('知识库.审批完成') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</template>
|
||||
<template #approveType="{ row, column }">
|
||||
<el-button
|
||||
v-if="row.dataType === 2"
|
||||
type="primary"
|
||||
link
|
||||
@click="openProcessFun(row)"
|
||||
>
|
||||
{{ KNOWLEDGE_APPROVE_TYPE.O[row[column.field]] }}</el-button
|
||||
>
|
||||
</template>
|
||||
</BaseTable>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</FileTree>
|
||||
</div>
|
||||
<ApprovalProcess v-model="processVisible" :flowId="currentRow?.cidFlowId" />
|
||||
<DetailModal
|
||||
v-model="visible"
|
||||
:detail="currentRow"
|
||||
:folder="currentFolder"
|
||||
:tableName="TABLE_NAME.ANIMATION_LIBRARY"
|
||||
:confirmLoading="confirmLoading"
|
||||
@confirm="onConfirmFun"
|
||||
/>
|
||||
<FolderModal
|
||||
v-model="folderModalVisible"
|
||||
:detail="currentFolder"
|
||||
:mode="currentFolderMode"
|
||||
:confirmLoading="folderConfirmLoading"
|
||||
@confirm="onFolderConfirmFun"
|
||||
/>
|
||||
<FilePreview v-model="previewVisible" :fileId="currentRow?.id" />
|
||||
<InfoDrawer v-model="infoVisible" :data="currentFolder" />
|
||||
</div>
|
||||
<ResourceLibraryPage :dirType="DIR_TYPE.ANIMATION" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
computed,
|
||||
onActivated,
|
||||
onBeforeUnmount,
|
||||
onDeactivated,
|
||||
onMounted,
|
||||
ref,
|
||||
watchEffect,
|
||||
type Ref,
|
||||
} from 'vue';
|
||||
import { DArrowLeft, Plus } from '@element-plus/icons-vue';
|
||||
import BaseTable from '@/components/common/table/baseTable.vue';
|
||||
import FileTree from '@/components/common/fileTree/index.vue';
|
||||
import DetailModal from './components/detailModal.vue';
|
||||
import FolderModal from '@/views/competenceCenter/knowledge/components/folderDetailModal.vue';
|
||||
import InfoDrawer from '@/views/competenceCenter/knowledge/components/infoDrawer.vue';
|
||||
import {
|
||||
dataCreateDirApi,
|
||||
dataListDirApi,
|
||||
dataRenameDirApi,
|
||||
dataDelDirApi,
|
||||
dataQueryDirApi,
|
||||
dataFileSearchApi,
|
||||
dataDelFileApi,
|
||||
dataUpdateFileApi,
|
||||
batchAddFileInfoApi,
|
||||
dataExportKnowledgeListApi,
|
||||
} from '@/api/data/data';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import type { RenderContentContext } from 'element-plus';
|
||||
import { formatFileSize } from '@/utils/file';
|
||||
import TableSearch from '@/components/common/table/tableSearch.vue';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { DIR_TYPE } from '@/utils/enum/data.ts';
|
||||
import { useDict } from '@/utils/useDict';
|
||||
import ApprovalProcess from '@/components/common/approvalProcess/index.vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import FilePreview from '@/components/common/filePreview/index.vue';
|
||||
import emitter from '@/utils/eventBus';
|
||||
import { TABLE_NAME } from '@/utils/enum/tableName';
|
||||
import { downloadFileById } from '@/utils/file';
|
||||
import PoolTaskSelect from '@/components/pool/poolTaskSelect.vue';
|
||||
|
||||
const CALLBACK_FLAG = '/competenceCenter/animation';
|
||||
|
||||
const dataListDirAnimationApi = (params: any) => {
|
||||
return dataListDirApi({ ...params, dirType: DIR_TYPE.ANIMATION });
|
||||
};
|
||||
|
||||
const { t } = useI18n();
|
||||
const { KNOWLEDGE_APPROVE_STATUS, KNOWLEDGE_APPROVE_TYPE } = useDict(
|
||||
'KNOWLEDGE_APPROVE_STATUS',
|
||||
'KNOWLEDGE_APPROVE_TYPE'
|
||||
);
|
||||
type Data = RenderContentContext['data'];
|
||||
const fileTreeRef = ref<any>();
|
||||
const baseTableRef = ref<any>();
|
||||
const navList = ref<any>([]);
|
||||
const currentFolder = ref();
|
||||
const memoryFolder = ref();
|
||||
const currentFolderMode: Ref<'add' | 'edit'> = ref('add');
|
||||
const choseNodeFun = (data: Data) => {
|
||||
isSearching.value = false;
|
||||
currentFolder.value = data;
|
||||
memoryFolder.value = currentFolder.value;
|
||||
};
|
||||
|
||||
const updateNavFun = (data: any) => {
|
||||
navList.value = data;
|
||||
};
|
||||
|
||||
const backFun = () => {
|
||||
fileTreeRef.value.backFun();
|
||||
};
|
||||
|
||||
const searchItems = computed(() => [
|
||||
{ title: t('通用.名称'), key: 'fileName', inputMode: 'input' },
|
||||
{
|
||||
title: t('知识库.上传人'),
|
||||
key: 'uploadUserId',
|
||||
inputMode: 'userSelectMultiple',
|
||||
},
|
||||
]);
|
||||
const folderModalVisible = ref(false);
|
||||
const folderConfirmLoading = ref(false);
|
||||
const appendFun = (data: Data) => {
|
||||
currentFolder.value = data;
|
||||
currentFolderMode.value = 'add';
|
||||
folderModalVisible.value = true;
|
||||
};
|
||||
const updateFun = (data: Data) => {
|
||||
currentFolder.value = data;
|
||||
currentFolderMode.value = 'edit';
|
||||
folderModalVisible.value = true;
|
||||
};
|
||||
const confirmRemoveFun = (data: Data) => {
|
||||
ElMessageBox.confirm(t('知识库.确认删除'), t('通用.提示'), {
|
||||
confirmButtonText: t('通用.确定'),
|
||||
cancelButtonText: t('通用.取消'),
|
||||
type: 'warning',
|
||||
})
|
||||
.then(() => {
|
||||
removeFun(data);
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
const removeFun = async (data: Data) => {
|
||||
const req = {
|
||||
delDirId: data.id,
|
||||
};
|
||||
const res: any = await dataDelDirApi(req);
|
||||
if (res.code === 200) {
|
||||
refreshTreeAfterModifyOrRemove(data);
|
||||
ElMessage.success(res.message);
|
||||
}
|
||||
};
|
||||
const refreshTreeRoot = () => {
|
||||
fileTreeRef.value?.reloadFun();
|
||||
baseTableRef.value?.resetFun();
|
||||
};
|
||||
const refreshTreeOpenDir = (dirId: number) => {
|
||||
fileTreeRef.value?.openDirFun(dirId);
|
||||
baseTableRef.value?.resetFun();
|
||||
};
|
||||
const refreshTreeAfterAdd = (parentNode?: any | null) => {
|
||||
if (parentNode && typeof parentNode.id === 'number') {
|
||||
refreshTreeOpenDir(parentNode.id);
|
||||
} else {
|
||||
refreshTreeRoot();
|
||||
}
|
||||
};
|
||||
const isTopLevel = (node: any) => {
|
||||
if (!node || !node.objectKey) return false;
|
||||
const key = String(node.objectKey).replace(/\/$/, '');
|
||||
const parts = key.split('/');
|
||||
return parts.length === 2;
|
||||
};
|
||||
const refreshTreeAfterModifyOrRemove = (node?: any | null) => {
|
||||
if (isTopLevel(node)) {
|
||||
refreshTreeRoot();
|
||||
} else {
|
||||
refreshTreeOpenDir(node.parentId);
|
||||
}
|
||||
};
|
||||
const isSearching = ref(false);
|
||||
const searchParams = ref<any>({
|
||||
fileId: currentFolder.value?.id || '',
|
||||
dirType: DIR_TYPE.ANIMATION,
|
||||
});
|
||||
|
||||
const actionList = computed(() => {
|
||||
return [
|
||||
{
|
||||
title: t('通用.预览'),
|
||||
type: 'primary',
|
||||
click: (row: any) => {
|
||||
previewFileFun(row);
|
||||
},
|
||||
hide: (row: any) => {
|
||||
return row.dataType !== 2;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t('通用.下载'),
|
||||
type: 'primary',
|
||||
click: (row: any) => {
|
||||
downloadFileById(row.id);
|
||||
},
|
||||
hide: (row: any) => {
|
||||
return row.dataType !== 2;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t('通用.编辑'),
|
||||
type: 'primary',
|
||||
click: (row: any) => {
|
||||
editFileFun(row);
|
||||
},
|
||||
hide: (row: any) => {
|
||||
return row.dataType !== 2 || row.approvalStatus === 'pending';
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t('通用.删除'),
|
||||
type: 'danger',
|
||||
needConfirm: true,
|
||||
confirmTip: t('通用.确认删除吗'),
|
||||
click: (row: any) => {
|
||||
delFileFun(row);
|
||||
},
|
||||
hide: (row: any) => {
|
||||
return row.dataType !== 2 || row.approvalStatus === 'pending';
|
||||
},
|
||||
},
|
||||
];
|
||||
});
|
||||
const searchFun = (data: object) => {
|
||||
isSearching.value = true;
|
||||
if (!memoryFolder.value && currentFolder.value) {
|
||||
memoryFolder.value = currentFolder.value;
|
||||
currentFolder.value = null;
|
||||
}
|
||||
searchParams.value = cloneDeep(data);
|
||||
searchParams.value.searchType = 1;
|
||||
searchParams.value.parentDirId = memoryFolder.value?.id || '';
|
||||
searchParams.value.dirType = DIR_TYPE.ANIMATION;
|
||||
};
|
||||
const resetFun = (data: object) => {
|
||||
isSearching.value = false;
|
||||
currentFolder.value = memoryFolder.value;
|
||||
searchParams.value = cloneDeep(data);
|
||||
searchParams.value.fileId = currentFolder.value?.id || '';
|
||||
searchParams.value.dirType = DIR_TYPE.ANIMATION;
|
||||
};
|
||||
const refreshTableFun = async () => {
|
||||
baseTableRef.value?.resetFun();
|
||||
};
|
||||
const onFolderConfirmFun = async (formData: any) => {
|
||||
folderConfirmLoading.value = true;
|
||||
try {
|
||||
if (currentFolderMode.value === 'add') {
|
||||
const req = {
|
||||
dirType: DIR_TYPE.ANIMATION,
|
||||
parDirId: currentFolder.value?.id,
|
||||
dirName: formData.name,
|
||||
type: 0,
|
||||
};
|
||||
const res: any = await dataCreateDirApi(req);
|
||||
if (res.code === 200) {
|
||||
refreshTreeAfterAdd(currentFolder.value);
|
||||
folderModalVisible.value = false;
|
||||
ElMessage.success(res.message);
|
||||
}
|
||||
} else if (currentFolderMode.value === 'edit') {
|
||||
const req = {
|
||||
dirId: currentFolder.value?.id,
|
||||
oldName: currentFolder.value?.originalName,
|
||||
newName: formData.name,
|
||||
type: 0,
|
||||
};
|
||||
const res: any = await dataRenameDirApi(req);
|
||||
if (res.code === 200) {
|
||||
refreshTreeAfterModifyOrRemove(currentFolder.value);
|
||||
folderModalVisible.value = false;
|
||||
ElMessage.success(res.message);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
folderConfirmLoading.value = false;
|
||||
}
|
||||
};
|
||||
const visible = ref(false);
|
||||
const confirmLoading = ref(false);
|
||||
const infoVisible = ref(false);
|
||||
const currentRow = ref();
|
||||
const openModalFun = () => {
|
||||
visible.value = true;
|
||||
currentRow.value = null;
|
||||
};
|
||||
const onConfirmFun = async (formData: any) => {
|
||||
let res: any;
|
||||
confirmLoading.value = true;
|
||||
try {
|
||||
if (currentRow.value && currentRow.value.id) {
|
||||
const file = formData.file?.[0];
|
||||
const req = {
|
||||
...currentRow.value,
|
||||
templateId: formData.templateId,
|
||||
templateName: formData.templateName,
|
||||
file: file?.raw,
|
||||
fileName: file?.fileName,
|
||||
size: file?.size,
|
||||
projectName: formData.projectName,
|
||||
path: currentFolder.value?.objectKey,
|
||||
dirId: currentFolder.value?.id,
|
||||
chunk: 0,
|
||||
remarks: formData.remarks,
|
||||
projectId: formData.projectId,
|
||||
chunkTotal: 0,
|
||||
encryptKey: null,
|
||||
type: 0,
|
||||
analysisDirectionId: formData.analysisDirectionId,
|
||||
simulationPoolInfoListStr: JSON.stringify(formData.simulationPoolInfoList),
|
||||
};
|
||||
delete req.poolInfos;
|
||||
res = await dataUpdateFileApi(req);
|
||||
} else {
|
||||
const req = {
|
||||
sourceFiles: formData.file,
|
||||
uploadTaskId: new Date().getTime(),
|
||||
dirId: currentFolder.value?.id,
|
||||
projectId: formData.projectId,
|
||||
analysisDirectionId: formData.analysisDirectionId,
|
||||
templateId: formData.templateId,
|
||||
templateName: formData.templateName,
|
||||
remarks: formData.remarks,
|
||||
type: 0,
|
||||
simulationPoolInfoList: formData.simulationPoolInfoList,
|
||||
};
|
||||
res = await batchAddFileInfoApi(req);
|
||||
if (res.code === 200) {
|
||||
res.data.forEach((item: any, index: number) => {
|
||||
emitter.emit('ADD_UPLOAD_FILE', {
|
||||
file: formData.originalName[index].raw, // 文件对象
|
||||
data: {
|
||||
// 接口返回的文件目录信息,包括配置信息
|
||||
...item,
|
||||
isApprove: 1, // 0否 1是
|
||||
taskType: 2, // 2知识库
|
||||
callbackFlag: CALLBACK_FLAG,
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
if (res.code === 200) {
|
||||
visible.value = false;
|
||||
refreshTableFun();
|
||||
ElMessage.success(res.message);
|
||||
}
|
||||
} finally {
|
||||
confirmLoading.value = false;
|
||||
}
|
||||
};
|
||||
const previewVisible = ref(false);
|
||||
const previewFileFun = (row: any) => {
|
||||
currentRow.value = row;
|
||||
previewVisible.value = true;
|
||||
};
|
||||
|
||||
const editFileFun = (row: any) => {
|
||||
currentRow.value = row;
|
||||
visible.value = true;
|
||||
};
|
||||
const delFileFun = async (row: any) => {
|
||||
currentRow.value = row;
|
||||
const req = { delFileId: row.id };
|
||||
try {
|
||||
const res: any = await dataDelFileApi(req);
|
||||
if (res.code === 200) {
|
||||
refreshTableFun();
|
||||
ElMessage.success(res.message);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
const onCellDblclickFun = (e: any) => {
|
||||
if (e.row.dataType === 1) {
|
||||
fileTreeRef.value?.openDirFun(e.row.id);
|
||||
}
|
||||
};
|
||||
const apiName: any = ref(null);
|
||||
watchEffect(() => {
|
||||
if (currentFolder.value && currentFolder.value?.id && !isSearching.value) {
|
||||
searchParams.value.fileId = currentFolder.value?.id || '';
|
||||
apiName.value = dataQueryDirApi;
|
||||
} else if (isSearching.value) {
|
||||
apiName.value = dataFileSearchApi;
|
||||
} else {
|
||||
apiName.value = dataFileSearchApi;
|
||||
}
|
||||
});
|
||||
|
||||
const processVisible = ref(false);
|
||||
const openProcessFun = (row: any) => {
|
||||
currentRow.value = row;
|
||||
processVisible.value = true;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
emitter.on('UPLOAD_FINISHED', uploadFinishedFun);
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
emitter.off('UPLOAD_FINISHED', uploadFinishedFun);
|
||||
});
|
||||
|
||||
onActivated(() => {
|
||||
emitter.on('UPLOAD_FINISHED', uploadFinishedFun);
|
||||
});
|
||||
|
||||
onDeactivated(() => {
|
||||
emitter.off('UPLOAD_FINISHED', uploadFinishedFun);
|
||||
});
|
||||
|
||||
const uploadFinishedFun = (data: any) => {
|
||||
if (data.callbackFlag === CALLBACK_FLAG) {
|
||||
refreshTableFun();
|
||||
}
|
||||
};
|
||||
import ResourceLibraryPage from '@/components/common/resourceLibrary/resourceLibraryPage.vue';
|
||||
import { DIR_TYPE } from '@/utils/enum/data';
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.gl-page-content-grey-full {
|
||||
.content {
|
||||
height: 100%;
|
||||
.options {
|
||||
margin-bottom: var(--margin-small);
|
||||
}
|
||||
.right-table {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
.table {
|
||||
flex: 1;
|
||||
height: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<template>
|
||||
<ResourceLibraryPage :dirType="DIR_TYPE.INDUSTRIAL_DESIGN" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import ResourceLibraryPage from '@/components/common/resourceLibrary/resourceLibraryPage.vue';
|
||||
import { DIR_TYPE } from '@/utils/enum/data';
|
||||
</script>
|
||||
8
src/tenants/lyric/views/competenceCenter/robot/index.vue
Normal file
8
src/tenants/lyric/views/competenceCenter/robot/index.vue
Normal file
@@ -0,0 +1,8 @@
|
||||
<template>
|
||||
<ResourceLibraryPage :dirType="DIR_TYPE.ROBOT" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import ResourceLibraryPage from '@/components/common/resourceLibrary/resourceLibraryPage.vue';
|
||||
import { DIR_TYPE } from '@/utils/enum/data';
|
||||
</script>
|
||||
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<ResourceLibraryPage
|
||||
:dirType="DIR_TYPE.TOLERANCE_ANALYSIS"
|
||||
needApproval
|
||||
moduleCode="TOLERANCE_APPROVAL"
|
||||
:tableName="TABLE_NAME.SIMULATION_KNOWLEDGE"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import ResourceLibraryPage from '@/components/common/resourceLibrary/resourceLibraryPage.vue';
|
||||
import { DIR_TYPE } from '@/utils/enum/data';
|
||||
import { TABLE_NAME } from '@/utils/enum/tableName';
|
||||
</script>
|
||||
@@ -90,7 +90,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { computed, onMounted, reactive, ref } from 'vue';
|
||||
import BaseTable from '@/components/common/table/baseTable.vue';
|
||||
import FileTree from '@/components/common/fileTree/index.vue';
|
||||
import {
|
||||
@@ -99,6 +99,10 @@ import {
|
||||
updateUserFilePermissionApi,
|
||||
} from '@/api/data/data';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { DIR_TYPE } from '@/utils/enum/data';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const fileTreeRef = ref<any>();
|
||||
const baseTableRef = ref<any>();
|
||||
@@ -108,17 +112,15 @@ const filterUserName = ref<string>('');
|
||||
const filterUserNameCopy = ref<string>('');
|
||||
const currentTreeNodeInfo = ref<any>({});
|
||||
|
||||
const dirType = ref(1);
|
||||
const dirType = ref(DIR_TYPE.KNOWLEDGE);
|
||||
|
||||
const dirTypeList = ref<any>([
|
||||
{
|
||||
label: '知识库',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '项目数据',
|
||||
value: 2,
|
||||
},
|
||||
const dirTypeList = computed(() => [
|
||||
{ label: t('菜单.仿真标准库'), value: DIR_TYPE.KNOWLEDGE },
|
||||
{ label: t('项目列表.项目数据'), value: DIR_TYPE.PROJECT_NODE },
|
||||
{ label: t('菜单.仿真动画库'), value: DIR_TYPE.ANIMATION },
|
||||
{ label: t('菜单.机器人库'), value: DIR_TYPE.ROBOT },
|
||||
{ label: t('菜单.工业设计库'), value: DIR_TYPE.INDUSTRIAL_DESIGN },
|
||||
{ label: t('菜单.公差分析库'), value: DIR_TYPE.TOLERANCE_ANALYSIS },
|
||||
]);
|
||||
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user