fix
This commit is contained in:
@@ -104,9 +104,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="!uploadedImageBase64" class="text-xs text-red-500 mt-1">
|
<div v-if="!uploadedImageBase64" class="text-xs text-red-500 mt-1">请上传参考图片</div>
|
||||||
请上传参考图片
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ onBeforeMount(() => {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
selectedKnowledgeId.value = datasetId;
|
selectedKnowledgeId.value = datasetId;
|
||||||
selectedKnowledge.value = {id: datasetId};
|
selectedKnowledge.value = { id: datasetId };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -98,10 +98,7 @@ export const parseWelcomeMessage = (welcomeMsg?: string): PrologueItem[] => {
|
|||||||
* @param {PrologueItem[]} initialPrologueList - 初始的 prologue 列表
|
* @param {PrologueItem[]} initialPrologueList - 初始的 prologue 列表
|
||||||
* @returns {Promise<PrologueItem[]>} 处理后的 prologue items
|
* @returns {Promise<PrologueItem[]>} 处理后的 prologue items
|
||||||
*/
|
*/
|
||||||
export const processPrologueItems = async (
|
export const processPrologueItems = async (selectedKnowledge: Dataset, initialPrologueList: PrologueItem[]): Promise<PrologueItem[]> => {
|
||||||
selectedKnowledge: Dataset,
|
|
||||||
initialPrologueList: PrologueItem[]
|
|
||||||
): Promise<PrologueItem[]> => {
|
|
||||||
// 如果存在 mcpId,从后端获取 MCP 元数据
|
// 如果存在 mcpId,从后端获取 MCP 元数据
|
||||||
if (selectedKnowledge?.mcpId) {
|
if (selectedKnowledge?.mcpId) {
|
||||||
const { data } = await getObj(selectedKnowledge.mcpId);
|
const { data } = await getObj(selectedKnowledge.mcpId);
|
||||||
|
|||||||
@@ -82,9 +82,16 @@
|
|||||||
v-if="!selectRow.recordId"
|
v-if="!selectRow.recordId"
|
||||||
class="flex flex-col items-center justify-center h-full p-8 bg-white border shadow-lg rounded-2xl border-slate-200/60 shadow-slate-100/50 backdrop-blur-sm"
|
class="flex flex-col items-center justify-center h-full p-8 bg-white border shadow-lg rounded-2xl border-slate-200/60 shadow-slate-100/50 backdrop-blur-sm"
|
||||||
>
|
>
|
||||||
<div class="flex items-center justify-center w-16 h-16 mb-6 border bg-gradient-to-br from-indigo-50 to-blue-50 rounded-2xl border-indigo-100/50">
|
<div
|
||||||
|
class="flex items-center justify-center w-16 h-16 mb-6 border bg-gradient-to-br from-indigo-50 to-blue-50 rounded-2xl border-indigo-100/50"
|
||||||
|
>
|
||||||
<svg class="w-8 h-8 text-indigo-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-8 h-8 text-indigo-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="1.5"
|
||||||
|
d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
|
||||||
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
@@ -95,7 +102,10 @@
|
|||||||
<template v-else>
|
<template v-else>
|
||||||
<div class="h-full overflow-hidden bg-white border shadow-lg rounded-2xl border-slate-200/60 shadow-slate-100/50 backdrop-blur-sm">
|
<div class="h-full overflow-hidden bg-white border shadow-lg rounded-2xl border-slate-200/60 shadow-slate-100/50 backdrop-blur-sm">
|
||||||
<!-- 顶部标注切换区域 -->
|
<!-- 顶部标注切换区域 -->
|
||||||
<div class="sticky top-0 z-20 flex items-center justify-between px-6 py-4 border-b bg-gradient-to-r from-blue-500/5 to-indigo-500/5 backdrop-blur-md border-blue-100/50" v-if="selectRow.llmFlag === '1'">
|
<div
|
||||||
|
class="sticky top-0 z-20 flex items-center justify-between px-6 py-4 border-b bg-gradient-to-r from-blue-500/5 to-indigo-500/5 backdrop-blur-md border-blue-100/50"
|
||||||
|
v-if="selectRow.llmFlag === '1'"
|
||||||
|
>
|
||||||
<div class="flex items-center space-x-3">
|
<div class="flex items-center space-x-3">
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<div class="w-3 h-3 rounded-full bg-gradient-to-r from-blue-500 to-indigo-500 animate-pulse"></div>
|
<div class="w-3 h-3 rounded-full bg-gradient-to-r from-blue-500 to-indigo-500 animate-pulse"></div>
|
||||||
@@ -121,20 +131,31 @@
|
|||||||
<!-- 用户提问区域 -->
|
<!-- 用户提问区域 -->
|
||||||
<div class="relative group">
|
<div class="relative group">
|
||||||
<div v-if="selectRow.llmFlag === '2'" class="relative">
|
<div v-if="selectRow.llmFlag === '2'" class="relative">
|
||||||
<div class="p-6 transition-all duration-300 border shadow-sm bg-gradient-to-br from-white to-slate-50/30 rounded-2xl border-slate-200/50 hover:shadow-md hover:border-slate-300/50">
|
<div
|
||||||
|
class="p-6 transition-all duration-300 border shadow-sm bg-gradient-to-br from-white to-slate-50/30 rounded-2xl border-slate-200/50 hover:shadow-md hover:border-slate-300/50"
|
||||||
|
>
|
||||||
<div class="leading-relaxed prose-sm prose max-w-none text-slate-700" v-html="matchResult" @click="handleChildClick" />
|
<div class="leading-relaxed prose-sm prose max-w-none text-slate-700" v-html="matchResult" @click="handleChildClick" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="relative">
|
<div v-else class="relative">
|
||||||
<div class="p-6 transition-all duration-300 border shadow-sm bg-gradient-to-br from-blue-50/30 to-indigo-50/30 rounded-2xl border-blue-200/50 hover:shadow-md hover:border-blue-300/50 hover:bg-gradient-to-br hover:from-blue-50/50 hover:to-indigo-50/50">
|
<div
|
||||||
|
class="p-6 transition-all duration-300 border shadow-sm bg-gradient-to-br from-blue-50/30 to-indigo-50/30 rounded-2xl border-blue-200/50 hover:shadow-md hover:border-blue-300/50 hover:bg-gradient-to-br hover:from-blue-50/50 hover:to-indigo-50/50"
|
||||||
|
>
|
||||||
<div class="leading-relaxed prose-sm prose max-w-none text-slate-800 font-medium">
|
<div class="leading-relaxed prose-sm prose max-w-none text-slate-800 font-medium">
|
||||||
{{ selectRow.questionText }}
|
{{ selectRow.questionText }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity duration-200">
|
<div class="absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity duration-200">
|
||||||
<div class="flex items-center px-2 py-1 text-xs font-medium text-blue-600 bg-blue-50/80 rounded-full border border-blue-200/50 backdrop-blur-sm">
|
<div
|
||||||
|
class="flex items-center px-2 py-1 text-xs font-medium text-blue-600 bg-blue-50/80 rounded-full border border-blue-200/50 backdrop-blur-sm"
|
||||||
|
>
|
||||||
<svg class="w-3 h-3 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-3 h-3 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
d="M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||||
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
问题
|
问题
|
||||||
</div>
|
</div>
|
||||||
@@ -146,9 +167,16 @@
|
|||||||
<div class="relative group">
|
<div class="relative group">
|
||||||
<div class="flex items-center mb-5 space-x-3">
|
<div class="flex items-center mb-5 space-x-3">
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<div class="flex items-center justify-center w-10 h-10 border shadow-sm bg-gradient-to-br from-blue-50 to-indigo-50 rounded-xl border-blue-100/50">
|
<div
|
||||||
|
class="flex items-center justify-center w-10 h-10 border shadow-sm bg-gradient-to-br from-blue-50 to-indigo-50 rounded-xl border-blue-100/50"
|
||||||
|
>
|
||||||
<svg class="w-5 h-5 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-5 h-5 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"></path>
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"
|
||||||
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="absolute w-3 h-3 border-2 border-white rounded-full shadow-sm -top-1 -right-1 bg-blue-400"></div>
|
<div class="absolute w-3 h-3 border-2 border-white rounded-full shadow-sm -top-1 -right-1 bg-blue-400"></div>
|
||||||
@@ -157,16 +185,25 @@
|
|||||||
<div>
|
<div>
|
||||||
<h3 class="text-lg font-bold text-slate-800">AI 智能回答</h3>
|
<h3 class="text-lg font-bold text-slate-800">AI 智能回答</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center px-3 py-1 border rounded-full bg-gradient-to-r from-blue-50 to-indigo-50 border-blue-100/50">
|
<div
|
||||||
|
class="flex items-center px-3 py-1 border rounded-full bg-gradient-to-r from-blue-50 to-indigo-50 border-blue-100/50"
|
||||||
|
>
|
||||||
<svg class="w-3 h-3 text-blue-500 mr-1.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-3 h-3 text-blue-500 mr-1.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||||
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
<span class="text-xs font-medium text-blue-600">支持Markdown</span>
|
<span class="text-xs font-medium text-blue-600">支持Markdown</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="overflow-hidden transition-all duration-300 border shadow-sm bg-gradient-to-br from-white to-slate-50/30 rounded-2xl border-slate-200/50 hover:shadow-md hover:border-slate-300/50">
|
<div
|
||||||
|
class="overflow-hidden transition-all duration-300 border shadow-sm bg-gradient-to-br from-white to-slate-50/30 rounded-2xl border-slate-200/50 hover:shadow-md hover:border-slate-300/50"
|
||||||
|
>
|
||||||
<ai-editor
|
<ai-editor
|
||||||
v-model="selectRow.answerText"
|
v-model="selectRow.answerText"
|
||||||
output="text"
|
output="text"
|
||||||
|
|||||||
@@ -235,12 +235,7 @@
|
|||||||
可见范围
|
可见范围
|
||||||
<tip content="选择可以访问此知识库的用户,如果不选择则全部的用户可访问" />
|
<tip content="选择可以访问此知识库的用户,如果不选择则全部的用户可访问" />
|
||||||
</template>
|
</template>
|
||||||
<org-selector
|
<org-selector v-model="form.visibleUsers" :type="'user'" :multiple="true" :selectSelf="true" />
|
||||||
v-model="form.visibleUsers"
|
|
||||||
:type="'user'"
|
|
||||||
:multiple="true"
|
|
||||||
:selectSelf="true"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|||||||
@@ -1,10 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog
|
<el-dialog v-model="dialogVisible" title="选择挂载方式" width="50%" :modal="false">
|
||||||
v-model="dialogVisible"
|
|
||||||
title="选择挂载方式"
|
|
||||||
width="50%"
|
|
||||||
:modal="false"
|
|
||||||
>
|
|
||||||
<div>
|
<div>
|
||||||
<el-card size="mini">
|
<el-card size="mini">
|
||||||
<el-row :gutter="10" justify="center">
|
<el-row :gutter="10" justify="center">
|
||||||
@@ -12,7 +7,7 @@
|
|||||||
<div :class="selectedMethod === 1 ? 'img-selected' : 'img-unselect'" @click="selectImg(1)">
|
<div :class="selectedMethod === 1 ? 'img-selected' : 'img-unselect'" @click="selectImg(1)">
|
||||||
<div class="css-1awpln7">
|
<div class="css-1awpln7">
|
||||||
<div class="css-0">
|
<div class="css-0">
|
||||||
<img alt="" src="/@/assets/ai/link.svg" class="chakra-image css-0">
|
<img alt="" src="/@/assets/ai/link.svg" class="chakra-image css-0" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -21,7 +16,7 @@
|
|||||||
<div :class="selectedMethod === 2 ? 'img-selected' : 'img-unselect'" @click="selectImg(2)">
|
<div :class="selectedMethod === 2 ? 'img-selected' : 'img-unselect'" @click="selectImg(2)">
|
||||||
<div class="css-1awpln7">
|
<div class="css-1awpln7">
|
||||||
<div class="css-0">
|
<div class="css-0">
|
||||||
<img alt="" src="/@/assets/ai/iframe.svg" class="chakra-image css-0">
|
<img alt="" src="/@/assets/ai/iframe.svg" class="chakra-image css-0" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -30,7 +25,7 @@
|
|||||||
<div :class="selectedMethod === 3 ? 'img-selected' : 'img-unselect'" @click="selectImg(3)">
|
<div :class="selectedMethod === 3 ? 'img-selected' : 'img-unselect'" @click="selectImg(3)">
|
||||||
<div class="css-1awpln7">
|
<div class="css-1awpln7">
|
||||||
<div class="css-0">
|
<div class="css-0">
|
||||||
<img alt="" src="/@/assets/ai/script.svg" class="chakra-image css-0">
|
<img alt="" src="/@/assets/ai/script.svg" class="chakra-image css-0" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -84,10 +79,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="AiDatasetDialog">
|
<script setup lang="ts" name="AiDatasetDialog">
|
||||||
import commonFunction from "/@/utils/commonFunction";
|
import commonFunction from '/@/utils/commonFunction';
|
||||||
|
|
||||||
const emit = defineEmits(['refresh']);
|
const emit = defineEmits(['refresh']);
|
||||||
const {copyText} = commonFunction();
|
const { copyText } = commonFunction();
|
||||||
|
|
||||||
const left_right = [
|
const left_right = [
|
||||||
{
|
{
|
||||||
@@ -97,8 +92,8 @@ const left_right = [
|
|||||||
{
|
{
|
||||||
label: '右侧',
|
label: '右侧',
|
||||||
value: 'right',
|
value: 'right',
|
||||||
}
|
},
|
||||||
]
|
];
|
||||||
|
|
||||||
const top_bottom = [
|
const top_bottom = [
|
||||||
{
|
{
|
||||||
@@ -108,31 +103,31 @@ const top_bottom = [
|
|||||||
{
|
{
|
||||||
label: '底部',
|
label: '底部',
|
||||||
value: 'bottom',
|
value: 'bottom',
|
||||||
}
|
},
|
||||||
]
|
];
|
||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false);
|
||||||
const selectedDatasetId = ref()
|
const selectedDatasetId = ref();
|
||||||
const selectedMethod = ref(1)
|
const selectedMethod = ref(1);
|
||||||
const data_btn_x = ref(16)
|
const data_btn_x = ref(16);
|
||||||
const data_btn_y = ref(16)
|
const data_btn_y = ref(16);
|
||||||
const data_stream = ref(true)
|
const data_stream = ref(true);
|
||||||
const data_direction_x = ref('right')
|
const data_direction_x = ref('right');
|
||||||
const data_direction_y = ref('bottom')
|
const data_direction_y = ref('bottom');
|
||||||
const openDialog = (datasetid: any) => {
|
const openDialog = (datasetid: any) => {
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true;
|
||||||
selectedDatasetId.value = datasetid
|
selectedDatasetId.value = datasetid;
|
||||||
}
|
};
|
||||||
|
|
||||||
const currentHostname = window.location.origin;
|
const currentHostname = window.location.origin;
|
||||||
const openImageBase64 = ref("")
|
const openImageBase64 = ref('');
|
||||||
const closeImageBase64 = ref("")
|
const closeImageBase64 = ref('');
|
||||||
|
|
||||||
function handleOpenIconBeforeUpload(file: Blob) {
|
function handleOpenIconBeforeUpload(file: Blob) {
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
reader.readAsDataURL(file);
|
reader.readAsDataURL(file);
|
||||||
reader.onload = e => {
|
reader.onload = (e) => {
|
||||||
// 在这里处理 Base64 数据
|
// 在这里处理 Base64 数据
|
||||||
openImageBase64.value = e.target.result
|
openImageBase64.value = e.target.result;
|
||||||
};
|
};
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -140,38 +135,39 @@ function handleOpenIconBeforeUpload(file: Blob) {
|
|||||||
function handleCloseIconBeforeUpload(file: Blob) {
|
function handleCloseIconBeforeUpload(file: Blob) {
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
reader.readAsDataURL(file);
|
reader.readAsDataURL(file);
|
||||||
reader.onload = e => {
|
reader.onload = (e) => {
|
||||||
// 在这里处理 Base64 数据
|
// 在这里处理 Base64 数据
|
||||||
closeImageBase64.value = e.target.result
|
closeImageBase64.value = e.target.result;
|
||||||
};
|
};
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isMicro = import.meta.env.VITE_IS_MICRO === 'true' ? 1 : 0;
|
||||||
const isMicro = import.meta.env.VITE_IS_MICRO === 'true' ? 1 : 0
|
|
||||||
|
|
||||||
const script = () => {
|
const script = () => {
|
||||||
return `<script id="chatbot-iframe" src="${currentHostname}/bot/embed.min.js?t=${Date.now()}" data-bot-src="${currentHostname}/bot/index.html#/${isMicro}/${selectedDatasetId.value}/chat" async defer><\/script>`
|
return `<script id="chatbot-iframe" src="${currentHostname}/bot/embed.min.js?t=${Date.now()}" data-bot-src="${currentHostname}/bot/index.html#/${isMicro}/${
|
||||||
}
|
selectedDatasetId.value
|
||||||
|
}/chat" async defer><\/script>`;
|
||||||
|
};
|
||||||
|
|
||||||
const iframe = () => {
|
const iframe = () => {
|
||||||
return `<iframe src="${currentHostname}/bot/bot/index.html#/${isMicro}/${selectedDatasetId.value}/chat" style="width: 100%; height: 100%;" frameborder="0" allow="microphone"/>`
|
return `<iframe src="${currentHostname}/bot/bot/index.html#/${isMicro}/${selectedDatasetId.value}/chat" style="width: 100%; height: 100%;" frameborder="0" allow="microphone"/>`;
|
||||||
}
|
};
|
||||||
|
|
||||||
const url = () => {
|
const url = () => {
|
||||||
return `${currentHostname}/bot/index.html#/${isMicro}/${selectedDatasetId.value}/chat`
|
return `${currentHostname}/bot/index.html#/${isMicro}/${selectedDatasetId.value}/chat`;
|
||||||
}
|
};
|
||||||
const selectImg = (index: number) => {
|
const selectImg = (index: number) => {
|
||||||
selectedMethod.value = index
|
selectedMethod.value = index;
|
||||||
}
|
};
|
||||||
|
|
||||||
const openText = (url: string) => {
|
const openText = (url: string) => {
|
||||||
window.open(url)
|
window.open(url);
|
||||||
}
|
};
|
||||||
|
|
||||||
// 暴露变量
|
// 暴露变量
|
||||||
defineExpose({
|
defineExpose({
|
||||||
openDialog
|
openDialog,
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -210,6 +206,6 @@ defineExpose({
|
|||||||
}
|
}
|
||||||
|
|
||||||
.card-class {
|
.card-class {
|
||||||
background-color: #F4F4F7;
|
background-color: #f4f4f7;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,5 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog :title="form.id ? '编辑' : '新增'" v-model="visible" :width="800" :close-on-click-modal="false" draggable :destroy-on-close="true" class="dark:bg-gray-800">
|
<el-dialog
|
||||||
|
:title="form.id ? '编辑' : '新增'"
|
||||||
|
v-model="visible"
|
||||||
|
:width="800"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
draggable
|
||||||
|
:destroy-on-close="true"
|
||||||
|
class="dark:bg-gray-800"
|
||||||
|
>
|
||||||
<el-form
|
<el-form
|
||||||
ref="dataFormRef"
|
ref="dataFormRef"
|
||||||
:model="form"
|
:model="form"
|
||||||
|
|||||||
@@ -129,10 +129,7 @@
|
|||||||
<form-dialog ref="formDialogRef" @refresh="getDataList(false)" />
|
<form-dialog ref="formDialogRef" @refresh="getDataList(false)" />
|
||||||
|
|
||||||
<!-- 文档查看抽屉 -->
|
<!-- 文档查看抽屉 -->
|
||||||
<document-drawer
|
<document-drawer v-model="documentDrawerVisible" :document-id="selectedDocumentId" />
|
||||||
v-model="documentDrawerVisible"
|
|
||||||
:document-id="selectedDocumentId"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const emit = defineEmits(['update:modelValue']);
|
const emit = defineEmits(['update:modelValue']);
|
||||||
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-col class="mb20">
|
<el-col class="mb20">
|
||||||
<el-form-item label="资料" prop="files">
|
<el-form-item label="资料" prop="files">
|
||||||
<upload-file
|
<upload-file :limit="1" @change="handleFileChange" :fileType="['xlsx']" />
|
||||||
:limit="1"
|
|
||||||
@change="handleFileChange"
|
|
||||||
:fileType="['xlsx']"
|
|
||||||
/>
|
|
||||||
<a class="link link-primary" @click="downloadTemplate">Q&A Excel 模板下载</a>
|
<a class="link link-primary" @click="downloadTemplate">Q&A Excel 模板下载</a>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -13,20 +9,20 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { PropType } from 'vue';
|
import { PropType } from 'vue';
|
||||||
import { downBlobFile } from "/@/utils/other";
|
import { downBlobFile } from '/@/utils/other';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: Object as PropType<any>,
|
type: Object as PropType<any>,
|
||||||
required: true
|
required: true,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['update:modelValue']);
|
const emit = defineEmits(['update:modelValue']);
|
||||||
|
|
||||||
const handleFileChange = (fileNames: string, fileList: any[]) => {
|
const handleFileChange = (fileNames: string, fileList: any[]) => {
|
||||||
emit('update:modelValue', fileList);
|
emit('update:modelValue', fileList);
|
||||||
}
|
};
|
||||||
|
|
||||||
const downloadTemplate = () => {
|
const downloadTemplate = () => {
|
||||||
downBlobFile('/admin/sys-file/local/file/qa.xlsx', {}, 'Q&A.xlsx');
|
downBlobFile('/admin/sys-file/local/file/qa.xlsx', {}, 'Q&A.xlsx');
|
||||||
|
|||||||
@@ -6,12 +6,7 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col class="mb20">
|
<el-col class="mb20">
|
||||||
<el-form-item label="内容" prop="content">
|
<el-form-item label="内容" prop="content">
|
||||||
<ai-editor
|
<ai-editor v-model="modelValue.content" output="text" placeholder="选择输入文本,即可调用 AI 辅助功能" :minHeight="400" />
|
||||||
v-model="modelValue.content"
|
|
||||||
output="text"
|
|
||||||
placeholder="选择输入文本,即可调用 AI 辅助功能"
|
|
||||||
:minHeight="400"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="visible"
|
<div
|
||||||
|
v-if="visible"
|
||||||
class="context-menu"
|
class="context-menu"
|
||||||
:style="{
|
:style="{
|
||||||
position: 'fixed',
|
position: 'fixed',
|
||||||
left: position.x + 'px',
|
left: position.x + 'px',
|
||||||
top: position.y + 'px',
|
top: position.y + 'px',
|
||||||
zIndex: 1000
|
zIndex: 1000,
|
||||||
}">
|
}"
|
||||||
|
>
|
||||||
<!-- <div class="menu-item"
|
<!-- <div class="menu-item"
|
||||||
@click="handleCommand('addNode')">
|
@click="handleCommand('addNode')">
|
||||||
<el-icon class="menu-icon">
|
<el-icon class="menu-icon">
|
||||||
@@ -14,15 +16,13 @@
|
|||||||
</el-icon>
|
</el-icon>
|
||||||
新增节点
|
新增节点
|
||||||
</div> -->
|
</div> -->
|
||||||
<div class="menu-item"
|
<div class="menu-item" @click="handleCommand('importDSL')">
|
||||||
@click="handleCommand('importDSL')">
|
|
||||||
<el-icon class="menu-icon">
|
<el-icon class="menu-icon">
|
||||||
<Upload />
|
<Upload />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
导入DSL
|
导入DSL
|
||||||
</div>
|
</div>
|
||||||
<div class="menu-item"
|
<div class="menu-item" @click="handleCommand('exportDSL')">
|
||||||
@click="handleCommand('exportDSL')">
|
|
||||||
<el-icon class="menu-icon">
|
<el-icon class="menu-icon">
|
||||||
<Download />
|
<Download />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
@@ -32,67 +32,67 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ref, defineComponent, onMounted, onBeforeUnmount } from 'vue'
|
import { ref, defineComponent, onMounted, onBeforeUnmount } from 'vue';
|
||||||
import { Plus, Upload, Download } from '@element-plus/icons-vue'
|
import { Plus, Upload, Download } from '@element-plus/icons-vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'CanvasContextMenu',
|
name: 'CanvasContextMenu',
|
||||||
components: {
|
components: {
|
||||||
Plus,
|
Plus,
|
||||||
Upload,
|
Upload,
|
||||||
Download
|
Download,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
visible: {
|
visible: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false,
|
||||||
},
|
},
|
||||||
position: {
|
position: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({ x: 0, y: 0 })
|
default: () => ({ x: 0, y: 0 }),
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
emits: ['update:visible', 'add-node', 'import-dsl', 'export-dsl'],
|
emits: ['update:visible', 'add-node', 'import-dsl', 'export-dsl'],
|
||||||
setup (props, { emit }) {
|
setup(props, { emit }) {
|
||||||
// 处理菜单命令
|
// 处理菜单命令
|
||||||
const handleCommand = (command) => {
|
const handleCommand = (command) => {
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case 'addNode':
|
case 'addNode':
|
||||||
emit('add')
|
emit('add');
|
||||||
break
|
break;
|
||||||
case 'importDSL':
|
case 'importDSL':
|
||||||
emit('import')
|
emit('import');
|
||||||
break
|
break;
|
||||||
case 'exportDSL':
|
case 'exportDSL':
|
||||||
emit('export')
|
emit('export');
|
||||||
break
|
break;
|
||||||
}
|
|
||||||
emit('update:visible', false)
|
|
||||||
}
|
}
|
||||||
|
emit('update:visible', false);
|
||||||
|
};
|
||||||
|
|
||||||
// 点击外部关闭菜单的处理函数
|
// 点击外部关闭菜单的处理函数
|
||||||
const handleClickOutside = (e) => {
|
const handleClickOutside = (e) => {
|
||||||
const contextMenu = document.querySelector('.context-menu')
|
const contextMenu = document.querySelector('.context-menu');
|
||||||
if (contextMenu && !contextMenu.contains(e.target)) {
|
if (contextMenu && !contextMenu.contains(e.target)) {
|
||||||
emit('update:visible', false)
|
emit('update:visible', false);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 组件挂载时添加点击事件监听
|
// 组件挂载时添加点击事件监听
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
document.addEventListener('click', handleClickOutside)
|
document.addEventListener('click', handleClickOutside);
|
||||||
})
|
});
|
||||||
|
|
||||||
// 组件销毁前移除事件监听
|
// 组件销毁前移除事件监听
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
document.removeEventListener('click', handleClickOutside)
|
document.removeEventListener('click', handleClickOutside);
|
||||||
})
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
handleCommand,
|
handleCommand,
|
||||||
}
|
};
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@@ -5,21 +5,14 @@
|
|||||||
<div class="header-title">
|
<div class="header-title">
|
||||||
<span>检查清单({{ validation.errors.length }})</span>
|
<span>检查清单({{ validation.errors.length }})</span>
|
||||||
</div>
|
</div>
|
||||||
<el-button
|
<el-button class="close-btn" type="primary" link @click="$emit('close')">
|
||||||
class="close-btn"
|
|
||||||
type="primary"
|
|
||||||
link
|
|
||||||
@click="$emit('close')"
|
|
||||||
>
|
|
||||||
<el-icon><Close /></el-icon>
|
<el-icon><Close /></el-icon>
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="preview-body">
|
<div class="preview-body">
|
||||||
<div class="check-list">
|
<div class="check-list">
|
||||||
<template v-if="validation.errors.length > 0">
|
<template v-if="validation.errors.length > 0">
|
||||||
<div v-for="(error, index) in validation.errors"
|
<div v-for="(error, index) in validation.errors" :key="index" class="check-item">
|
||||||
:key="index"
|
|
||||||
class="check-item">
|
|
||||||
<div class="item-icon warning">
|
<div class="item-icon warning">
|
||||||
<el-icon><Warning /></el-icon>
|
<el-icon><Warning /></el-icon>
|
||||||
</div>
|
</div>
|
||||||
@@ -29,8 +22,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div v-else
|
<div v-else class="check-item success">
|
||||||
class="check-item success">
|
|
||||||
<div class="item-icon success">
|
<div class="item-icon success">
|
||||||
<el-icon><Select /></el-icon>
|
<el-icon><Select /></el-icon>
|
||||||
</div>
|
</div>
|
||||||
@@ -46,7 +38,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { Warning, Close, Select } from '@element-plus/icons-vue'
|
import { Warning, Close, Select } from '@element-plus/icons-vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'CheckListPanel',
|
name: 'CheckListPanel',
|
||||||
@@ -54,67 +46,67 @@ export default {
|
|||||||
components: {
|
components: {
|
||||||
Warning,
|
Warning,
|
||||||
Close,
|
Close,
|
||||||
Select
|
Select,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
validation: {
|
validation: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true
|
required: true,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
emits: ['update:validation', 'close'],
|
emits: ['update:validation', 'close'],
|
||||||
data () {
|
data() {
|
||||||
return {
|
return {
|
||||||
showCheckList: false
|
showCheckList: false,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'parent.nodes': {
|
'parent.nodes': {
|
||||||
handler: 'checkChanges',
|
handler: 'checkChanges',
|
||||||
deep: true,
|
deep: true,
|
||||||
immediate: true
|
immediate: true,
|
||||||
},
|
},
|
||||||
'parent.connections': {
|
'parent.connections': {
|
||||||
handler: 'checkChanges',
|
handler: 'checkChanges',
|
||||||
deep: true,
|
deep: true,
|
||||||
immediate: true
|
immediate: true,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
checkChanges () {
|
checkChanges() {
|
||||||
const newValidation = this.validateWorkflow()
|
const newValidation = this.validateWorkflow();
|
||||||
this.$emit('update:validation', newValidation)
|
this.$emit('update:validation', newValidation);
|
||||||
},
|
},
|
||||||
validateWorkflow () {
|
validateWorkflow() {
|
||||||
const validation = {
|
const validation = {
|
||||||
isValid: true,
|
isValid: true,
|
||||||
errors: [],
|
errors: [],
|
||||||
warnings: []
|
warnings: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!this.parent.nodes || this.parent.nodes.length === 0) {
|
if (!this.parent.nodes || this.parent.nodes.length === 0) {
|
||||||
validation.errors.push({
|
validation.errors.push({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
message: '工作流中没有节点'
|
message: '工作流中没有节点',
|
||||||
});
|
});
|
||||||
validation.isValid = false;
|
validation.isValid = false;
|
||||||
return validation;
|
return validation;
|
||||||
}
|
}
|
||||||
|
|
||||||
const startNodes = this.parent.nodes.filter(node => node.type === 'start');
|
const startNodes = this.parent.nodes.filter((node) => node.type === 'start');
|
||||||
const endNodes = this.parent.nodes.filter(node => node.type === 'end');
|
const endNodes = this.parent.nodes.filter((node) => node.type === 'end');
|
||||||
|
|
||||||
if (startNodes.length === 0) {
|
if (startNodes.length === 0) {
|
||||||
validation.errors.push({
|
validation.errors.push({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
message: '工作流缺少开始节点'
|
message: '工作流缺少开始节点',
|
||||||
});
|
});
|
||||||
validation.isValid = false;
|
validation.isValid = false;
|
||||||
} else if (startNodes.length > 1) {
|
} else if (startNodes.length > 1) {
|
||||||
validation.errors.push({
|
validation.errors.push({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
message: '工作流只能有一个开始节点'
|
message: '工作流只能有一个开始节点',
|
||||||
});
|
});
|
||||||
validation.isValid = false;
|
validation.isValid = false;
|
||||||
}
|
}
|
||||||
@@ -122,20 +114,20 @@ export default {
|
|||||||
if (endNodes.length === 0) {
|
if (endNodes.length === 0) {
|
||||||
validation.errors.push({
|
validation.errors.push({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
message: '工作流缺少结束节点'
|
message: '工作流缺少结束节点',
|
||||||
});
|
});
|
||||||
validation.isValid = false;
|
validation.isValid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const nodeConnections = new Map();
|
const nodeConnections = new Map();
|
||||||
this.parent.nodes.forEach(node => {
|
this.parent.nodes.forEach((node) => {
|
||||||
nodeConnections.set(node.id, {
|
nodeConnections.set(node.id, {
|
||||||
inbound: [],
|
inbound: [],
|
||||||
outbound: []
|
outbound: [],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
this.parent.connections.forEach(conn => {
|
this.parent.connections.forEach((conn) => {
|
||||||
const sourceConn = nodeConnections.get(conn.sourceId);
|
const sourceConn = nodeConnections.get(conn.sourceId);
|
||||||
const targetConn = nodeConnections.get(conn.targetId);
|
const targetConn = nodeConnections.get(conn.targetId);
|
||||||
|
|
||||||
@@ -147,14 +139,14 @@ export default {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.parent.nodes.forEach(node => {
|
this.parent.nodes.forEach((node) => {
|
||||||
const nodeConn = nodeConnections.get(node.id);
|
const nodeConn = nodeConnections.get(node.id);
|
||||||
|
|
||||||
if (node.type === 'start' && nodeConn.inbound.length > 0) {
|
if (node.type === 'start' && nodeConn.inbound.length > 0) {
|
||||||
validation.errors.push({
|
validation.errors.push({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
message: '开始节点不能有入边连接',
|
message: '开始节点不能有入边连接',
|
||||||
nodeId: node.id
|
nodeId: node.id,
|
||||||
});
|
});
|
||||||
validation.isValid = false;
|
validation.isValid = false;
|
||||||
}
|
}
|
||||||
@@ -163,22 +155,21 @@ export default {
|
|||||||
validation.errors.push({
|
validation.errors.push({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
message: '结束节点不能有出边连接',
|
message: '结束节点不能有出边连接',
|
||||||
nodeId: node.id
|
nodeId: node.id,
|
||||||
});
|
});
|
||||||
validation.isValid = false;
|
validation.isValid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nodeConn.inbound.length === 0 && nodeConn.outbound.length === 0 &&
|
if (nodeConn.inbound.length === 0 && nodeConn.outbound.length === 0 && node.type !== 'start' && node.type !== 'end') {
|
||||||
node.type !== 'start' && node.type !== 'end') {
|
|
||||||
validation.warnings.push({
|
validation.warnings.push({
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
message: '存在孤立节点',
|
message: '存在孤立节点',
|
||||||
nodeId: node.id
|
nodeId: node.id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.parent.nodes.forEach(node => {
|
this.parent.nodes.forEach((node) => {
|
||||||
// switch (node.type) {
|
// switch (node.type) {
|
||||||
// case 'http':
|
// case 'http':
|
||||||
// this.validateHttpNode(node, validation);
|
// this.validateHttpNode(node, validation);
|
||||||
@@ -192,7 +183,7 @@ export default {
|
|||||||
if (this.hasCircularDependency()) {
|
if (this.hasCircularDependency()) {
|
||||||
validation.errors.push({
|
validation.errors.push({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
message: '工作流中存在循环依赖'
|
message: '工作流中存在循环依赖',
|
||||||
});
|
});
|
||||||
validation.isValid = false;
|
validation.isValid = false;
|
||||||
}
|
}
|
||||||
@@ -202,18 +193,18 @@ export default {
|
|||||||
console.error('验证工作流时出错:', error);
|
console.error('验证工作流时出错:', error);
|
||||||
validation.errors.push({
|
validation.errors.push({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
message: '验证工作流时出错: ' + error.message
|
message: '验证工作流时出错: ' + error.message,
|
||||||
});
|
});
|
||||||
validation.isValid = false;
|
validation.isValid = false;
|
||||||
return validation;
|
return validation;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
validateHttpNode (node, validation) {
|
validateHttpNode(node, validation) {
|
||||||
if (!node.url) {
|
if (!node.url) {
|
||||||
validation.errors.push({
|
validation.errors.push({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
message: 'HTTP节点缺少URL',
|
message: 'HTTP节点缺少URL',
|
||||||
nodeId: node.id
|
nodeId: node.id,
|
||||||
});
|
});
|
||||||
validation.isValid = false;
|
validation.isValid = false;
|
||||||
}
|
}
|
||||||
@@ -222,7 +213,7 @@ export default {
|
|||||||
validation.errors.push({
|
validation.errors.push({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
message: 'HTTP节点缺少请求方法',
|
message: 'HTTP节点缺少请求方法',
|
||||||
nodeId: node.id
|
nodeId: node.id,
|
||||||
});
|
});
|
||||||
validation.isValid = false;
|
validation.isValid = false;
|
||||||
}
|
}
|
||||||
@@ -233,7 +224,7 @@ export default {
|
|||||||
validation.errors.push({
|
validation.errors.push({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
message: `HTTP节点的第${index + 1}个请求头缺少名称`,
|
message: `HTTP节点的第${index + 1}个请求头缺少名称`,
|
||||||
nodeId: node.id
|
nodeId: node.id,
|
||||||
});
|
});
|
||||||
validation.isValid = false;
|
validation.isValid = false;
|
||||||
}
|
}
|
||||||
@@ -246,19 +237,19 @@ export default {
|
|||||||
validation.errors.push({
|
validation.errors.push({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
message: `HTTP节点的第${index + 1}个请求体参数缺少名称`,
|
message: `HTTP节点的第${index + 1}个请求体参数缺少名称`,
|
||||||
nodeId: node.id
|
nodeId: node.id,
|
||||||
});
|
});
|
||||||
validation.isValid = false;
|
validation.isValid = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
validateCodeNode (node, validation) {
|
validateCodeNode(node, validation) {
|
||||||
if (!node.code) {
|
if (!node.code) {
|
||||||
validation.errors.push({
|
validation.errors.push({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
message: '代码节点缺少执行代码',
|
message: '代码节点缺少执行代码',
|
||||||
nodeId: node.id
|
nodeId: node.id,
|
||||||
});
|
});
|
||||||
validation.isValid = false;
|
validation.isValid = false;
|
||||||
} else {
|
} else {
|
||||||
@@ -268,13 +259,13 @@ export default {
|
|||||||
validation.errors.push({
|
validation.errors.push({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
message: `代码语法错误: ${error.message}`,
|
message: `代码语法错误: ${error.message}`,
|
||||||
nodeId: node.id
|
nodeId: node.id,
|
||||||
});
|
});
|
||||||
validation.isValid = false;
|
validation.isValid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
hasCircularDependency () {
|
hasCircularDependency() {
|
||||||
const visited = new Set();
|
const visited = new Set();
|
||||||
const recursionStack = new Set();
|
const recursionStack = new Set();
|
||||||
|
|
||||||
@@ -282,7 +273,7 @@ export default {
|
|||||||
visited.add(nodeId);
|
visited.add(nodeId);
|
||||||
recursionStack.add(nodeId);
|
recursionStack.add(nodeId);
|
||||||
|
|
||||||
const connections = this.parent.connections.filter(conn => conn.sourceId === nodeId);
|
const connections = this.parent.connections.filter((conn) => conn.sourceId === nodeId);
|
||||||
for (const conn of connections) {
|
for (const conn of connections) {
|
||||||
const targetId = conn.targetId;
|
const targetId = conn.targetId;
|
||||||
|
|
||||||
@@ -309,28 +300,28 @@ export default {
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
getErrorType (error) {
|
getErrorType(error) {
|
||||||
if (error.message.includes('缺少')) return '节点缺失'
|
if (error.message.includes('缺少')) return '节点缺失';
|
||||||
if (error.message.includes('未连接')) return '连接错误'
|
if (error.message.includes('未连接')) return '连接错误';
|
||||||
if (error.message.includes('循环')) return '循环依赖'
|
if (error.message.includes('循环')) return '循环依赖';
|
||||||
return '错误'
|
return '错误';
|
||||||
},
|
},
|
||||||
getErrorMessage (error) {
|
getErrorMessage(error) {
|
||||||
let nodeName = ''
|
let nodeName = '';
|
||||||
if (error.nodeId) {
|
if (error.nodeId) {
|
||||||
const node = this.parent.nodes.find(n => n.id === error.nodeId)
|
const node = this.parent.nodes.find((n) => n.id === error.nodeId);
|
||||||
if (node) {
|
if (node) {
|
||||||
nodeName = node.name || `${node.type}节点`
|
nodeName = node.name || `${node.type}节点`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nodeName) {
|
if (nodeName) {
|
||||||
return `${nodeName}: ${error.message}`
|
return `${nodeName}: ${error.message}`;
|
||||||
}
|
}
|
||||||
return error.message
|
return error.message;
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@@ -18,10 +18,7 @@
|
|||||||
<!-- 流式调用开关 -->
|
<!-- 流式调用开关 -->
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<span class="text-sm text-gray-600 mr-2">流式:</span>
|
<span class="text-sm text-gray-600 mr-2">流式:</span>
|
||||||
<el-switch
|
<el-switch v-model="chat.isStream" class="mr-4" />
|
||||||
v-model="chat.isStream"
|
|
||||||
class="mr-4"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<el-button link type="primary" class="flex text-gray-500 hover:text-blue-500" @click="chat.showParams = !chat.showParams">
|
<el-button link type="primary" class="flex text-gray-500 hover:text-blue-500" @click="chat.showParams = !chat.showParams">
|
||||||
<i class="mr-1 text-lg i-tabler-settings"></i>
|
<i class="mr-1 text-lg i-tabler-settings"></i>
|
||||||
@@ -384,12 +381,15 @@ const scrollToBottom = (smooth = true) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 确保滚动生效的备用方案
|
// 确保滚动生效的备用方案
|
||||||
setTimeout(() => {
|
setTimeout(
|
||||||
|
() => {
|
||||||
if (wrapper.scrollTop + wrapper.clientHeight < scrollHeight - 10) {
|
if (wrapper.scrollTop + wrapper.clientHeight < scrollHeight - 10) {
|
||||||
chatScrollbarRef.value.setScrollTop(scrollHeight);
|
chatScrollbarRef.value.setScrollTop(scrollHeight);
|
||||||
}
|
}
|
||||||
isAtBottom.value = true;
|
isAtBottom.value = true;
|
||||||
}, smooth ? 100 : 10);
|
},
|
||||||
|
smooth ? 100 : 10
|
||||||
|
);
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 静默处理错误
|
// 静默处理错误
|
||||||
@@ -1049,8 +1049,6 @@ onUpdated(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@keyframes bounce {
|
@keyframes bounce {
|
||||||
0%,
|
0%,
|
||||||
80%,
|
80%,
|
||||||
|
|||||||
@@ -1,33 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
|
|
||||||
<!-- 开场白和开场问题编辑器 -->
|
<!-- 开场白和开场问题编辑器 -->
|
||||||
<el-dialog
|
<el-dialog v-model="dialogVisible" title="提示词" width="600px" :show-footer="false">
|
||||||
v-model="dialogVisible"
|
|
||||||
title="提示词"
|
|
||||||
width="600px"
|
|
||||||
:show-footer="false"
|
|
||||||
>
|
|
||||||
<div class="greeting-editor">
|
<div class="greeting-editor">
|
||||||
<!-- 开场白编辑区 -->
|
<!-- 开场白编辑区 -->
|
||||||
<div class="greeting-section">
|
<div class="greeting-section">
|
||||||
<div class="section-title">
|
<div class="section-title">
|
||||||
<div class="title-with-help">
|
<div class="title-with-help">
|
||||||
<span>聊天开场白</span>
|
<span>聊天开场白</span>
|
||||||
<el-tooltip content="开场白会在用户进入对话时首先展示,用于介绍AI助手的功能和特点。"
|
<el-tooltip content="开场白会在用户进入对话时首先展示,用于介绍AI助手的功能和特点。" placement="top">
|
||||||
placement="top">
|
|
||||||
<el-icon class="help-icon">
|
<el-icon class="help-icon">
|
||||||
<QuestionFilled />
|
<QuestionFilled />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-input
|
<el-input v-model="form.greeting" type="textarea" :rows="5" class="greeting-input" placeholder="在这里编写AI助手的开场白" />
|
||||||
v-model="form.greeting"
|
|
||||||
type="textarea"
|
|
||||||
:rows="5"
|
|
||||||
class="greeting-input"
|
|
||||||
placeholder="在这里编写AI助手的开场白"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 开场问题编辑区 -->
|
<!-- 开场问题编辑区 -->
|
||||||
@@ -36,20 +23,13 @@
|
|||||||
<div class="title-with-help">
|
<div class="title-with-help">
|
||||||
<span>开场问题</span>
|
<span>开场问题</span>
|
||||||
<div class="question-count">{{ form.questions.length }}/10</div>
|
<div class="question-count">{{ form.questions.length }}/10</div>
|
||||||
<el-tooltip content="设置常见问题示例,帮助用户快速开始对话。最多可设置10个问题。"
|
<el-tooltip content="设置常见问题示例,帮助用户快速开始对话。最多可设置10个问题。" placement="top">
|
||||||
placement="top">
|
|
||||||
<el-icon class="help-icon">
|
<el-icon class="help-icon">
|
||||||
<QuestionFilled />
|
<QuestionFilled />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<el-button
|
<el-button type="primary" class="add-question" @click="addQuestion" :disabled="form.questions.length >= 10" size="small">
|
||||||
type="primary"
|
|
||||||
class="add-question"
|
|
||||||
@click="addQuestion"
|
|
||||||
:disabled="form.questions.length >= 10"
|
|
||||||
size="small"
|
|
||||||
>
|
|
||||||
<el-icon class="icon-plus">
|
<el-icon class="icon-plus">
|
||||||
<Plus />
|
<Plus />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
@@ -57,21 +37,9 @@
|
|||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="questions-list">
|
<div class="questions-list">
|
||||||
<div v-for="(question, index) in form.questions"
|
<div v-for="(question, index) in form.questions" :key="index" class="question-item">
|
||||||
:key="index"
|
<el-input v-model="question.text" class="question-input" :placeholder="'问题 ' + (index + 1)" />
|
||||||
class="question-item">
|
<el-button @click="removeQuestion(index)" type="danger" :icon="Delete" circle size="small" />
|
||||||
<el-input
|
|
||||||
v-model="question.text"
|
|
||||||
class="question-input"
|
|
||||||
:placeholder="'问题 ' + (index + 1)"
|
|
||||||
/>
|
|
||||||
<el-button
|
|
||||||
@click="removeQuestion(index)"
|
|
||||||
type="danger"
|
|
||||||
:icon="Delete"
|
|
||||||
circle
|
|
||||||
size="small"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -80,56 +48,58 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { QuestionFilled, Plus, Delete } from '@element-plus/icons-vue'
|
import { QuestionFilled, Plus, Delete } from '@element-plus/icons-vue';
|
||||||
|
|
||||||
// 注入parent
|
// 注入parent
|
||||||
const parent = inject('parent')
|
const parent = inject('parent');
|
||||||
|
|
||||||
// 定义组件属性
|
// 定义组件属性
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false,
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
|
|
||||||
// 定义事件
|
// 定义事件
|
||||||
const emit = defineEmits(['update:modelValue'])
|
const emit = defineEmits(['update:modelValue']);
|
||||||
|
|
||||||
// 对话框显示状态
|
// 对话框显示状态
|
||||||
const dialogVisible = ref(props.modelValue)
|
const dialogVisible = ref(props.modelValue);
|
||||||
|
|
||||||
|
|
||||||
const form = ref({
|
const form = ref({
|
||||||
questions: []
|
questions: [],
|
||||||
})
|
});
|
||||||
|
|
||||||
// 监听modelValue的变化
|
// 监听modelValue的变化
|
||||||
watch(() => props.modelValue, (newVal) => {
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
(newVal) => {
|
||||||
form.value = parent.dsl;
|
form.value = parent.dsl;
|
||||||
form.value.questions=form.value.questions || []
|
form.value.questions = form.value.questions || [];
|
||||||
dialogVisible.value = newVal
|
dialogVisible.value = newVal;
|
||||||
})
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// 监听dialogVisible的变化
|
// 监听dialogVisible的变化
|
||||||
watch(() => dialogVisible.value, (newVal) => {
|
watch(
|
||||||
emit('update:modelValue', newVal)
|
() => dialogVisible.value,
|
||||||
})
|
(newVal) => {
|
||||||
|
emit('update:modelValue', newVal);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// 添加问题
|
// 添加问题
|
||||||
const addQuestion = () => {
|
const addQuestion = () => {
|
||||||
if (form.value.questions.length < 10) {
|
if (form.value.questions.length < 10) {
|
||||||
form.value.questions.push({ text: '' })
|
form.value.questions.push({ text: '' });
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// 删除问题
|
// 删除问题
|
||||||
const removeQuestion = (index) => {
|
const removeQuestion = (index) => {
|
||||||
form.value.questions.splice(index, 1)
|
form.value.questions.splice(index, 1);
|
||||||
}
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@@ -10,12 +10,7 @@
|
|||||||
<div class="preview-content">
|
<div class="preview-content">
|
||||||
<!-- 顶部标签页 -->
|
<!-- 顶部标签页 -->
|
||||||
<el-tabs v-model="activeTab" class="preview-tabs">
|
<el-tabs v-model="activeTab" class="preview-tabs">
|
||||||
<el-tab-pane
|
<el-tab-pane v-for="tab in tabs" :key="tab.key" :label="tab.label" :name="tab.key">
|
||||||
v-for="tab in tabs"
|
|
||||||
:key="tab.key"
|
|
||||||
:label="tab.label"
|
|
||||||
:name="tab.key"
|
|
||||||
>
|
|
||||||
<template #label>
|
<template #label>
|
||||||
<span>{{ tab.label }}</span>
|
<span>{{ tab.label }}</span>
|
||||||
<el-tag v-if="tab.key === 'nodes'" size="small" type="info" class="ml-2">
|
<el-tag v-if="tab.key === 'nodes'" size="small" type="info" class="ml-2">
|
||||||
@@ -27,13 +22,7 @@
|
|||||||
|
|
||||||
<!-- 代码编辑器 -->
|
<!-- 代码编辑器 -->
|
||||||
<div class="preview-body">
|
<div class="preview-body">
|
||||||
<code-editor
|
<code-editor v-model="currentTabData" :json="true" :readonly="false" theme="nord" height="400px" />
|
||||||
v-model="currentTabData"
|
|
||||||
:json="true"
|
|
||||||
:readonly="false"
|
|
||||||
theme="nord"
|
|
||||||
height="400px"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@@ -49,22 +38,22 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { Document } from '@element-plus/icons-vue'
|
import { Document } from '@element-plus/icons-vue';
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus';
|
||||||
import CodeEditor from "/@/views/knowledge/aiFlow/components/CodeEditor.vue";
|
import CodeEditor from '/@/views/knowledge/aiFlow/components/CodeEditor.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'JsonPreviewPanel',
|
name: 'JsonPreviewPanel',
|
||||||
components: {
|
components: {
|
||||||
CodeEditor,
|
CodeEditor,
|
||||||
Document
|
Document,
|
||||||
},
|
},
|
||||||
inject: ['parent'],
|
inject: ['parent'],
|
||||||
props: {
|
props: {
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -73,73 +62,74 @@ export default {
|
|||||||
{ key: 'all', label: '全部数据' },
|
{ key: 'all', label: '全部数据' },
|
||||||
{ key: 'nodes', label: '节点数据' },
|
{ key: 'nodes', label: '节点数据' },
|
||||||
{ key: 'connections', label: '连线数据' },
|
{ key: 'connections', label: '连线数据' },
|
||||||
{ key: 'execution', label: '执行顺序' }
|
{ key: 'execution', label: '执行顺序' },
|
||||||
]
|
],
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
dialogVisible: {
|
dialogVisible: {
|
||||||
get() {
|
get() {
|
||||||
return this.modelValue
|
return this.modelValue;
|
||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
this.$emit('update:modelValue', value)
|
this.$emit('update:modelValue', value);
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
nodes: this.parent.nodes,
|
nodes: this.parent.nodes,
|
||||||
connections: this.parent.connections,
|
connections: this.parent.connections,
|
||||||
executionOrder: this.parent.workflowExecutionOrder,
|
executionOrder: this.parent.workflowExecutionOrder,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
nodeCount() {
|
nodeCount() {
|
||||||
return this.data.nodes ? this.data.nodes.length : 0
|
return this.data.nodes ? this.data.nodes.length : 0;
|
||||||
},
|
},
|
||||||
currentTabData: {
|
currentTabData: {
|
||||||
get() {
|
get() {
|
||||||
let data = ''
|
let data = '';
|
||||||
switch (this.activeTab) {
|
switch (this.activeTab) {
|
||||||
case 'nodes':
|
case 'nodes':
|
||||||
data = this.data.nodes
|
data = this.data.nodes;
|
||||||
break
|
break;
|
||||||
case 'connections':
|
case 'connections':
|
||||||
data = this.data.connections
|
data = this.data.connections;
|
||||||
break
|
break;
|
||||||
case 'execution':
|
case 'execution':
|
||||||
data = this.data.executionOrder
|
data = this.data.executionOrder;
|
||||||
break
|
break;
|
||||||
default:
|
default:
|
||||||
data = this.data
|
data = this.data;
|
||||||
}
|
}
|
||||||
return JSON.stringify(data, null, 2)
|
return JSON.stringify(data, null, 2);
|
||||||
},
|
},
|
||||||
set() {
|
set() {
|
||||||
// 只读模式,不需要实现set
|
// 只读模式,不需要实现set
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
copyData() {
|
copyData() {
|
||||||
navigator.clipboard.writeText(this.currentTabData)
|
navigator.clipboard
|
||||||
|
.writeText(this.currentTabData)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
ElMessage({
|
ElMessage({
|
||||||
message: '复制成功',
|
message: '复制成功',
|
||||||
type: 'success',
|
type: 'success',
|
||||||
duration: 2000
|
duration: 2000,
|
||||||
|
});
|
||||||
})
|
})
|
||||||
})
|
.catch((err) => {
|
||||||
.catch(err => {
|
|
||||||
ElMessage({
|
ElMessage({
|
||||||
message: '复制失败',
|
message: '复制失败',
|
||||||
type: 'error',
|
type: 'error',
|
||||||
duration: 2000
|
duration: 2000,
|
||||||
})
|
});
|
||||||
console.error('复制失败:', err)
|
console.error('复制失败:', err);
|
||||||
})
|
});
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@@ -4,35 +4,33 @@
|
|||||||
<!-- 缩略图容器 -->
|
<!-- 缩略图容器 -->
|
||||||
<div class="mini-map-container" ref="container">
|
<div class="mini-map-container" ref="container">
|
||||||
<!-- 缩略图内容 -->
|
<!-- 缩略图内容 -->
|
||||||
<div class="mini-map-content"
|
<div class="mini-map-content" :style="{ transform: `translate(${contentPosition.x}px, ${contentPosition.y}px) scale(${scale})` }">
|
||||||
:style="{ transform: `translate(${contentPosition.x}px, ${contentPosition.y}px) scale(${scale})` }">
|
|
||||||
<!-- 节点缩略图 -->
|
<!-- 节点缩略图 -->
|
||||||
<div v-for="node in nodes"
|
<div
|
||||||
|
v-for="node in nodes"
|
||||||
:key="node.id"
|
:key="node.id"
|
||||||
class="mini-node"
|
class="mini-node"
|
||||||
:style="{
|
:style="{
|
||||||
left: `${node.x}px`,
|
left: `${node.x}px`,
|
||||||
top: `${node.y}px`,
|
top: `${node.y}px`,
|
||||||
backgroundColor: getNodeColor(node.type)
|
backgroundColor: getNodeColor(node.type),
|
||||||
}">
|
}"
|
||||||
</div>
|
></div>
|
||||||
<!-- 连线缩略图 -->
|
<!-- 连线缩略图 -->
|
||||||
<svg class="mini-connections" :style="{ width: `${bounds.width}px`, height: `${bounds.height}px` }">
|
<svg class="mini-connections" :style="{ width: `${bounds.width}px`, height: `${bounds.height}px` }">
|
||||||
<path v-for="(conn, index) in connections"
|
<path v-for="(conn, index) in connections" :key="index" :d="getConnectionPath(conn)" class="mini-connection-path" />
|
||||||
:key="index"
|
|
||||||
:d="getConnectionPath(conn)"
|
|
||||||
class="mini-connection-path"/>
|
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<!-- 视口指示器 -->
|
<!-- 视口指示器 -->
|
||||||
<div class="viewport-indicator"
|
<div
|
||||||
|
class="viewport-indicator"
|
||||||
:style="{
|
:style="{
|
||||||
transform: `translate(${viewportPosition.x}px, ${viewportPosition.y}px)`,
|
transform: `translate(${viewportPosition.x}px, ${viewportPosition.y}px)`,
|
||||||
width: `${viewportSize.width}px`,
|
width: `${viewportSize.width}px`,
|
||||||
height: `${viewportSize.height}px`
|
height: `${viewportSize.height}px`,
|
||||||
}"
|
}"
|
||||||
@mousedown.prevent="startDrag">
|
@mousedown.prevent="startDrag"
|
||||||
</div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -44,41 +42,41 @@ export default {
|
|||||||
// 缩略图宽度
|
// 缩略图宽度
|
||||||
width: {
|
width: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 200
|
default: 200,
|
||||||
},
|
},
|
||||||
// 缩略图高度
|
// 缩略图高度
|
||||||
height: {
|
height: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 150
|
default: 150,
|
||||||
},
|
},
|
||||||
// 节点数据
|
// 节点数据
|
||||||
nodes: {
|
nodes: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => []
|
default: () => [],
|
||||||
},
|
},
|
||||||
// 连接数据
|
// 连接数据
|
||||||
connections: {
|
connections: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => []
|
default: () => [],
|
||||||
},
|
},
|
||||||
// 画布缩放比例
|
// 画布缩放比例
|
||||||
zoom: {
|
zoom: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 1
|
default: 1,
|
||||||
},
|
},
|
||||||
// 画布位置
|
// 画布位置
|
||||||
position: {
|
position: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({ x: 0, y: 0 })
|
default: () => ({ x: 0, y: 0 }),
|
||||||
},
|
},
|
||||||
// 添加容器尺寸属性
|
// 添加容器尺寸属性
|
||||||
containerSize: {
|
containerSize: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({
|
default: () => ({
|
||||||
width: 0,
|
width: 0,
|
||||||
height: 0
|
height: 0,
|
||||||
})
|
}),
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -89,60 +87,60 @@ export default {
|
|||||||
minX: 0,
|
minX: 0,
|
||||||
minY: 0,
|
minY: 0,
|
||||||
width: 3000,
|
width: 3000,
|
||||||
height: 3000
|
height: 3000,
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
// 计算内容位置,使其居中显示
|
// 计算内容位置,使其居中显示
|
||||||
contentPosition() {
|
contentPosition() {
|
||||||
const offsetX = (this.width - this.bounds.width * this.scale) / 2
|
const offsetX = (this.width - this.bounds.width * this.scale) / 2;
|
||||||
const offsetY = (this.height - this.bounds.height * this.scale) / 2
|
const offsetY = (this.height - this.bounds.height * this.scale) / 2;
|
||||||
return {
|
return {
|
||||||
x: offsetX,
|
x: offsetX,
|
||||||
y: offsetY
|
y: offsetY,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
// 修改视口位置计算
|
// 修改视口位置计算
|
||||||
viewportPosition() {
|
viewportPosition() {
|
||||||
// 确保位置不会超出边界
|
// 确保位置不会超出边界
|
||||||
const maxX = this.width - this.viewportSize.width
|
const maxX = this.width - this.viewportSize.width;
|
||||||
const maxY = this.height - this.viewportSize.height
|
const maxY = this.height - this.viewportSize.height;
|
||||||
|
|
||||||
let x = (-this.position.x * this.scale) + this.contentPosition.x
|
let x = -this.position.x * this.scale + this.contentPosition.x;
|
||||||
let y = (-this.position.y * this.scale) + this.contentPosition.y
|
let y = -this.position.y * this.scale + this.contentPosition.y;
|
||||||
|
|
||||||
// 限制在有效范围内
|
// 限制在有效范围内
|
||||||
x = Math.max(0, Math.min(x, maxX))
|
x = Math.max(0, Math.min(x, maxX));
|
||||||
y = Math.max(0, Math.min(y, maxY))
|
y = Math.max(0, Math.min(y, maxY));
|
||||||
|
|
||||||
return { x, y }
|
return { x, y };
|
||||||
},
|
},
|
||||||
// 修改视口尺寸计算
|
// 修改视口尺寸计算
|
||||||
viewportSize() {
|
viewportSize() {
|
||||||
// 计算缩略图内容的实际显示范围
|
// 计算缩略图内容的实际显示范围
|
||||||
const contentWidth = this.bounds.width * this.scale
|
const contentWidth = this.bounds.width * this.scale;
|
||||||
const contentHeight = this.bounds.height * this.scale
|
const contentHeight = this.bounds.height * this.scale;
|
||||||
|
|
||||||
// 计算视口尺寸比例
|
// 计算视口尺寸比例
|
||||||
const viewportRatioX = this.width / (this.bounds.width / this.zoom)
|
const viewportRatioX = this.width / (this.bounds.width / this.zoom);
|
||||||
const viewportRatioY = this.height / (this.bounds.height / this.zoom)
|
const viewportRatioY = this.height / (this.bounds.height / this.zoom);
|
||||||
|
|
||||||
// 确保视口尺寸不会小于最小值或大于缩略图尺寸
|
// 确保视口尺寸不会小于最小值或大于缩略图尺寸
|
||||||
return {
|
return {
|
||||||
width: Math.min(this.width, Math.max(50, contentWidth * viewportRatioX)),
|
width: Math.min(this.width, Math.max(50, contentWidth * viewportRatioX)),
|
||||||
height: Math.min(this.height, Math.max(30, contentHeight * viewportRatioY))
|
height: Math.min(this.height, Math.max(30, contentHeight * viewportRatioY)),
|
||||||
}
|
};
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
// 监听节点变化,重新计算边界和缩放
|
// 监听节点变化,重新计算边界和缩放
|
||||||
nodes: {
|
nodes: {
|
||||||
handler() {
|
handler() {
|
||||||
this.$nextTick(this.updateBoundsAndScale)
|
this.$nextTick(this.updateBoundsAndScale);
|
||||||
|
},
|
||||||
|
deep: true,
|
||||||
},
|
},
|
||||||
deep: true
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 获取节点颜色
|
// 获取节点颜色
|
||||||
@@ -157,108 +155,108 @@ export default {
|
|||||||
llm: '#EC4899',
|
llm: '#EC4899',
|
||||||
notice: '#14B8A6',
|
notice: '#14B8A6',
|
||||||
question: '#F97316',
|
question: '#F97316',
|
||||||
default: '#6B7280'
|
default: '#6B7280',
|
||||||
}
|
};
|
||||||
return colors[type] || colors.default
|
return colors[type] || colors.default;
|
||||||
},
|
},
|
||||||
// 获取连接路径
|
// 获取连接路径
|
||||||
getConnectionPath(conn) {
|
getConnectionPath(conn) {
|
||||||
const source = this.nodes.find(n => n.id === conn.sourceId)
|
const source = this.nodes.find((n) => n.id === conn.sourceId);
|
||||||
const target = this.nodes.find(n => n.id === conn.targetId)
|
const target = this.nodes.find((n) => n.id === conn.targetId);
|
||||||
if (!source || !target) return ''
|
if (!source || !target) return '';
|
||||||
|
|
||||||
const x1 = source.x
|
const x1 = source.x;
|
||||||
const y1 = source.y
|
const y1 = source.y;
|
||||||
const x2 = target.x
|
const x2 = target.x;
|
||||||
const y2 = target.y
|
const y2 = target.y;
|
||||||
|
|
||||||
// 计算控制点
|
// 计算控制点
|
||||||
const dx = Math.abs(x2 - x1) * 0.5
|
const dx = Math.abs(x2 - x1) * 0.5;
|
||||||
const cp1x = x1 + dx
|
const cp1x = x1 + dx;
|
||||||
const cp1y = y1
|
const cp1y = y1;
|
||||||
const cp2x = x2 - dx
|
const cp2x = x2 - dx;
|
||||||
const cp2y = y2
|
const cp2y = y2;
|
||||||
|
|
||||||
return `M ${x1} ${y1} C ${cp1x} ${cp1y}, ${cp2x} ${cp2y}, ${x2} ${y2}`
|
return `M ${x1} ${y1} C ${cp1x} ${cp1y}, ${cp2x} ${cp2y}, ${x2} ${y2}`;
|
||||||
},
|
},
|
||||||
// 开始拖动视口
|
// 开始拖动视口
|
||||||
startDrag(event) {
|
startDrag(event) {
|
||||||
this.isDragging = true
|
this.isDragging = true;
|
||||||
const rect = this.$refs.container.getBoundingClientRect()
|
const rect = this.$refs.container.getBoundingClientRect();
|
||||||
this.dragStart = {
|
this.dragStart = {
|
||||||
x: event.clientX - rect.left - this.viewportPosition.x,
|
x: event.clientX - rect.left - this.viewportPosition.x,
|
||||||
y: event.clientY - rect.top - this.viewportPosition.y
|
y: event.clientY - rect.top - this.viewportPosition.y,
|
||||||
}
|
};
|
||||||
|
|
||||||
window.addEventListener('mousemove', this.onDrag)
|
window.addEventListener('mousemove', this.onDrag);
|
||||||
window.addEventListener('mouseup', this.stopDrag)
|
window.addEventListener('mouseup', this.stopDrag);
|
||||||
},
|
},
|
||||||
// 拖动中
|
// 拖动中
|
||||||
onDrag(event) {
|
onDrag(event) {
|
||||||
if (!this.isDragging) return
|
if (!this.isDragging) return;
|
||||||
|
|
||||||
const rect = this.$refs.container.getBoundingClientRect()
|
const rect = this.$refs.container.getBoundingClientRect();
|
||||||
let x = event.clientX - rect.left - this.dragStart.x
|
let x = event.clientX - rect.left - this.dragStart.x;
|
||||||
let y = event.clientY - rect.top - this.dragStart.y
|
let y = event.clientY - rect.top - this.dragStart.y;
|
||||||
|
|
||||||
// 添加边界限制
|
// 添加边界限制
|
||||||
const maxX = this.width - this.viewportSize.width
|
const maxX = this.width - this.viewportSize.width;
|
||||||
const maxY = this.height - this.viewportSize.height
|
const maxY = this.height - this.viewportSize.height;
|
||||||
x = Math.max(0, Math.min(x, maxX))
|
x = Math.max(0, Math.min(x, maxX));
|
||||||
y = Math.max(0, Math.min(y, maxY))
|
y = Math.max(0, Math.min(y, maxY));
|
||||||
|
|
||||||
// 计算相对于内容的位置
|
// 计算相对于内容的位置
|
||||||
const relativeX = (x - this.contentPosition.x) / this.scale
|
const relativeX = (x - this.contentPosition.x) / this.scale;
|
||||||
const relativeY = (y - this.contentPosition.y) / this.scale
|
const relativeY = (y - this.contentPosition.y) / this.scale;
|
||||||
|
|
||||||
this.$emit('update:position', {
|
this.$emit('update:position', {
|
||||||
x: -relativeX,
|
x: -relativeX,
|
||||||
y: -relativeY
|
y: -relativeY,
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
// 停止拖动
|
// 停止拖动
|
||||||
stopDrag() {
|
stopDrag() {
|
||||||
this.isDragging = false
|
this.isDragging = false;
|
||||||
window.removeEventListener('mousemove', this.onDrag)
|
window.removeEventListener('mousemove', this.onDrag);
|
||||||
window.removeEventListener('mouseup', this.stopDrag)
|
window.removeEventListener('mouseup', this.stopDrag);
|
||||||
},
|
},
|
||||||
// 更新边界和缩放
|
// 更新边界和缩放
|
||||||
updateBoundsAndScale() {
|
updateBoundsAndScale() {
|
||||||
if (!this.nodes.length) return
|
if (!this.nodes.length) return;
|
||||||
|
|
||||||
// 计算节点边界
|
// 计算节点边界
|
||||||
const nodePositions = this.nodes.map(node => ({
|
const nodePositions = this.nodes.map((node) => ({
|
||||||
left: node.x - 100, // 考虑节点宽度
|
left: node.x - 100, // 考虑节点宽度
|
||||||
right: node.x + 100,
|
right: node.x + 100,
|
||||||
top: node.y - 50, // 考虑节点高度
|
top: node.y - 50, // 考虑节点高度
|
||||||
bottom: node.y + 50
|
bottom: node.y + 50,
|
||||||
}))
|
}));
|
||||||
|
|
||||||
// 计算整体边界
|
// 计算整体边界
|
||||||
const minX = Math.min(...nodePositions.map(p => p.left))
|
const minX = Math.min(...nodePositions.map((p) => p.left));
|
||||||
const maxX = Math.max(...nodePositions.map(p => p.right))
|
const maxX = Math.max(...nodePositions.map((p) => p.right));
|
||||||
const minY = Math.min(...nodePositions.map(p => p.top))
|
const minY = Math.min(...nodePositions.map((p) => p.top));
|
||||||
const maxY = Math.max(...nodePositions.map(p => p.bottom))
|
const maxY = Math.max(...nodePositions.map((p) => p.bottom));
|
||||||
|
|
||||||
// 添加边距
|
// 添加边距
|
||||||
const PADDING = 100
|
const PADDING = 100;
|
||||||
this.bounds = {
|
this.bounds = {
|
||||||
minX: minX - PADDING,
|
minX: minX - PADDING,
|
||||||
minY: minY - PADDING,
|
minY: minY - PADDING,
|
||||||
width: maxX - minX + PADDING * 2,
|
width: maxX - minX + PADDING * 2,
|
||||||
height: maxY - minY + PADDING * 2
|
height: maxY - minY + PADDING * 2,
|
||||||
}
|
};
|
||||||
|
|
||||||
// 计算合适的缩放比例
|
// 计算合适的缩放比例
|
||||||
const scaleX = this.width / this.bounds.width
|
const scaleX = this.width / this.bounds.width;
|
||||||
const scaleY = this.height / this.bounds.height
|
const scaleY = this.height / this.bounds.height;
|
||||||
this.scale = Math.min(scaleX, scaleY, 0.2) // 限制最大缩放比例为0.2
|
this.scale = Math.min(scaleX, scaleY, 0.2); // 限制最大缩放比例为0.2
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.updateBoundsAndScale()
|
this.updateBoundsAndScale();
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@@ -1,167 +1,158 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div v-if="visible"
|
<div v-if="visible" class="more-menu" :style="menuStyle">
|
||||||
class="more-menu"
|
|
||||||
:style="menuStyle">
|
|
||||||
<!-- 拷贝 -->
|
<!-- 拷贝 -->
|
||||||
<div class="menu-item"
|
<div class="menu-item" @click="copyNode">
|
||||||
@click="copyNode">
|
|
||||||
<span>复制</span>
|
<span>复制</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 新增子节点 -->
|
<!-- 新增子节点 -->
|
||||||
<div class="menu-item"
|
<div class="menu-item" @click="handleShowAddChild" v-if="canAddChild">
|
||||||
@click="handleShowAddChild"
|
|
||||||
v-if="canAddChild">
|
|
||||||
<span>新增子节点</span>
|
<span>新增子节点</span>
|
||||||
<i class="el-icon-arrow-right"></i>
|
<i class="el-icon-arrow-right"></i>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 更换类型 -->
|
<!-- 更换类型 -->
|
||||||
<div class="menu-item"
|
<div class="menu-item" @click="handleShowChangeType">
|
||||||
@click="handleShowChangeType">
|
|
||||||
<span>更换类型</span>
|
<span>更换类型</span>
|
||||||
<i class="el-icon-arrow-right"></i>
|
<i class="el-icon-arrow-right"></i>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 删除 -->
|
<!-- 删除 -->
|
||||||
<div class="menu-item"
|
<div class="menu-item" @click="deleteNode" v-if="node.type !== 'start'">
|
||||||
@click="deleteNode" v-if="node.type !== 'start'">
|
|
||||||
<span>删除</span>
|
<span>删除</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 使用 NodeContextMenu 组件 - 更换类型 -->
|
<!-- 使用 NodeContextMenu 组件 - 更换类型 -->
|
||||||
<NodeContextMenu v-model:visible="showChangeType"
|
<NodeContextMenu
|
||||||
|
v-model:visible="showChangeType"
|
||||||
:position="changeTypeMenuPosition"
|
:position="changeTypeMenuPosition"
|
||||||
:node="node"
|
:node="node"
|
||||||
add-position="replace"
|
add-position="replace"
|
||||||
@add="handleChangeType" />
|
@add="handleChangeType"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- 使用 NodeContextMenu 组件 - 新增子节点 -->
|
<!-- 使用 NodeContextMenu 组件 - 新增子节点 -->
|
||||||
<NodeContextMenu v-model:visible="showAddChild"
|
<NodeContextMenu v-model:visible="showAddChild" :position="addChildMenuPosition" :node="node" add-position="right" @add="handleAddChild" />
|
||||||
:position="addChildMenuPosition"
|
|
||||||
:node="node"
|
|
||||||
add-position="right"
|
|
||||||
@add="handleAddChild" />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import NodeContextMenu from './NodeContextMenu.vue'
|
import NodeContextMenu from './NodeContextMenu.vue';
|
||||||
import { getNodeConfig } from './nodes/nodeTypes.ts'
|
import { getNodeConfig } from './nodes/nodeTypes.ts';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'NodeMoreMenu',
|
name: 'NodeMoreMenu',
|
||||||
inject: ['parent'],
|
inject: ['parent'],
|
||||||
components: {
|
components: {
|
||||||
NodeContextMenu
|
NodeContextMenu,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
visible: {
|
visible: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false,
|
||||||
},
|
},
|
||||||
position: {
|
position: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({ x: 0, y: 0 })
|
default: () => ({ x: 0, y: 0 }),
|
||||||
},
|
},
|
||||||
node: {
|
node: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: null
|
default: null,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
emits: ['update:visible'],
|
emits: ['update:visible'],
|
||||||
data () {
|
data() {
|
||||||
return {
|
return {
|
||||||
showChangeType: false,
|
showChangeType: false,
|
||||||
changeTypeMenuPosition: { x: 0, y: 0 },
|
changeTypeMenuPosition: { x: 0, y: 0 },
|
||||||
showAddChild: false,
|
showAddChild: false,
|
||||||
addChildMenuPosition: { x: 0, y: 0 }
|
addChildMenuPosition: { x: 0, y: 0 },
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
menuStyle () {
|
menuStyle() {
|
||||||
return {
|
return {
|
||||||
left: `${this.position.x}px`,
|
left: `${this.position.x}px`,
|
||||||
top: `${this.position.y}px`
|
top: `${this.position.y}px`,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
// 判断是否可以添加子节点
|
// 判断是否可以添加子节点
|
||||||
canAddChild () {
|
canAddChild() {
|
||||||
if (!this.node || !this.parent) return false
|
if (!this.node || !this.parent) return false;
|
||||||
|
|
||||||
// 结束节点不能添加子节点
|
// 结束节点不能添加子节点
|
||||||
if (this.node.type === 'end') {
|
if (this.node.type === 'end') {
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取当前节点已有的连接数量
|
// 获取当前节点已有的连接数量
|
||||||
const existingConnections = this.parent.connections?.filter((conn) => conn.sourceId === this.node.id) || []
|
const existingConnections = this.parent.connections?.filter((conn) => conn.sourceId === this.node.id) || [];
|
||||||
|
|
||||||
// 如果是分支节点(switch 或 question),可以添加子节点
|
// 如果是分支节点(switch 或 question),可以添加子节点
|
||||||
if (['switch', 'question'].includes(this.node.type)) {
|
if (['switch', 'question'].includes(this.node.type)) {
|
||||||
return true
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果不是分支节点且已经有连接,则不能添加子节点
|
// 如果不是分支节点且已经有连接,则不能添加子节点
|
||||||
if (existingConnections.length > 0) {
|
if (existingConnections.length > 0) {
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true;
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 复制节点
|
// 复制节点
|
||||||
copyNode () {
|
copyNode() {
|
||||||
if (!this.node) return
|
if (!this.node) return;
|
||||||
|
|
||||||
// 创建节点的深拷贝
|
// 创建节点的深拷贝
|
||||||
const nodeCopy = JSON.parse(JSON.stringify(this.node))
|
const nodeCopy = JSON.parse(JSON.stringify(this.node));
|
||||||
|
|
||||||
// 生成新的唯一ID
|
// 生成新的唯一ID
|
||||||
nodeCopy.id = `node_${Date.now()}`
|
nodeCopy.id = `node_${Date.now()}`;
|
||||||
|
|
||||||
// 设置新节点的位置(在原节点右下方20px处)
|
// 设置新节点的位置(在原节点右下方20px处)
|
||||||
nodeCopy.x = this.node.x + 20
|
nodeCopy.x = this.node.x + 20;
|
||||||
nodeCopy.y = this.node.y + 20
|
nodeCopy.y = this.node.y + 20;
|
||||||
|
|
||||||
// 更新节点列表
|
// 更新节点列表
|
||||||
this.parent.nodes = [...this.parent.nodes, nodeCopy]
|
this.parent.nodes = [...this.parent.nodes, nodeCopy];
|
||||||
|
|
||||||
// 关闭菜单
|
// 关闭菜单
|
||||||
this.$emit('update:visible', false)
|
this.$emit('update:visible', false);
|
||||||
},
|
},
|
||||||
|
|
||||||
// 删除节点
|
// 删除节点
|
||||||
deleteNode () {
|
deleteNode() {
|
||||||
if (!this.node) return
|
if (!this.node) return;
|
||||||
|
|
||||||
// 删除节点的所有端点
|
// 删除节点的所有端点
|
||||||
this.parent.jsPlumbInstance.removeAllEndpoints(this.node.id)
|
this.parent.jsPlumbInstance.removeAllEndpoints(this.node.id);
|
||||||
|
|
||||||
// 从节点列表中删除节点
|
// 从节点列表中删除节点
|
||||||
this.parent.nodes= this.parent.nodes.filter(n => n.id !== this.node.id)
|
this.parent.nodes = this.parent.nodes.filter((n) => n.id !== this.node.id);
|
||||||
|
|
||||||
// 关闭菜单
|
// 关闭菜单
|
||||||
this.$emit('update:visible', false)
|
this.$emit('update:visible', false);
|
||||||
},
|
},
|
||||||
|
|
||||||
// 更换节点类型
|
// 更换节点类型
|
||||||
changeNodeType (newType) {
|
changeNodeType(newType) {
|
||||||
if (!this.node || !newType) return
|
if (!this.node || !newType) return;
|
||||||
|
|
||||||
// 获取新节点类型的配置
|
// 获取新节点类型的配置
|
||||||
const nodeConfig = getNodeConfig(newType)
|
const nodeConfig = getNodeConfig(newType);
|
||||||
|
|
||||||
// 找到当前节点的索引
|
// 找到当前节点的索引
|
||||||
const nodeIndex = this.parent.nodes.findIndex(n => n.id === this.node.id)
|
const nodeIndex = this.parent.nodes.findIndex((n) => n.id === this.node.id);
|
||||||
if (nodeIndex === -1) return
|
if (nodeIndex === -1) return;
|
||||||
|
|
||||||
// 保存原节点的位置和ID
|
// 保存原节点的位置和ID
|
||||||
const { x, y, id } = this.node
|
const { x, y, id } = this.node;
|
||||||
|
|
||||||
// 创建新节点,保持原有的位置和ID
|
// 创建新节点,保持原有的位置和ID
|
||||||
const newNode = {
|
const newNode = {
|
||||||
@@ -169,113 +160,113 @@ export default {
|
|||||||
id,
|
id,
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
}
|
};
|
||||||
|
|
||||||
// 更新节点列表
|
// 更新节点列表
|
||||||
const newNodes = [...this.parent.nodes]
|
const newNodes = [...this.parent.nodes];
|
||||||
newNodes[nodeIndex] = newNode
|
newNodes[nodeIndex] = newNode;
|
||||||
this.parent.nodes = newNodes
|
this.parent.nodes = newNodes;
|
||||||
|
|
||||||
// 关闭菜单
|
// 关闭菜单
|
||||||
this.$emit('update:visible', false)
|
this.$emit('update:visible', false);
|
||||||
this.showChangeType = false
|
this.showChangeType = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
handleShowChangeType (event) {
|
handleShowChangeType(event) {
|
||||||
// 计算子菜单位置,在父菜单右侧显示
|
// 计算子菜单位置,在父菜单右侧显示
|
||||||
const menuEl = this.$el.querySelector('.more-menu')
|
const menuEl = this.$el.querySelector('.more-menu');
|
||||||
if (menuEl) {
|
if (menuEl) {
|
||||||
const rect = menuEl.getBoundingClientRect()
|
const rect = menuEl.getBoundingClientRect();
|
||||||
// 检查右侧空间是否足够
|
// 检查右侧空间是否足够
|
||||||
const rightSpace = window.innerWidth - rect.right
|
const rightSpace = window.innerWidth - rect.right;
|
||||||
const leftSpace = rect.left
|
const leftSpace = rect.left;
|
||||||
|
|
||||||
// 如果右侧空间不足,且左侧空间足够,则显示在左侧
|
// 如果右侧空间不足,且左侧空间足够,则显示在左侧
|
||||||
if (rightSpace < 200 && leftSpace > 200) {
|
if (rightSpace < 200 && leftSpace > 200) {
|
||||||
this.changeTypeMenuPosition = {
|
this.changeTypeMenuPosition = {
|
||||||
x: rect.left - 5, // 左侧偏移5px
|
x: rect.left - 5, // 左侧偏移5px
|
||||||
y: rect.top
|
y: rect.top,
|
||||||
}
|
};
|
||||||
} else {
|
} else {
|
||||||
this.changeTypeMenuPosition = {
|
this.changeTypeMenuPosition = {
|
||||||
x: rect.right + 5, // 右侧偏移5px
|
x: rect.right + 5, // 右侧偏移5px
|
||||||
y: rect.top
|
y: rect.top,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
this.showChangeType = true;
|
||||||
this.showChangeType = true
|
|
||||||
// 阻止事件冒泡,防止触发外部点击事件
|
// 阻止事件冒泡,防止触发外部点击事件
|
||||||
event?.stopPropagation()
|
event?.stopPropagation();
|
||||||
},
|
},
|
||||||
|
|
||||||
handleChangeType (type) {
|
handleChangeType(type) {
|
||||||
this.changeNodeType(type)
|
this.changeNodeType(type);
|
||||||
},
|
},
|
||||||
|
|
||||||
// 显示新增子节点菜单
|
// 显示新增子节点菜单
|
||||||
handleShowAddChild (event) {
|
handleShowAddChild(event) {
|
||||||
// 计算子菜单位置,在父菜单右侧显示
|
// 计算子菜单位置,在父菜单右侧显示
|
||||||
const menuEl = this.$el.querySelector('.more-menu')
|
const menuEl = this.$el.querySelector('.more-menu');
|
||||||
if (menuEl) {
|
if (menuEl) {
|
||||||
const rect = menuEl.getBoundingClientRect()
|
const rect = menuEl.getBoundingClientRect();
|
||||||
// 检查右侧空间是否足够
|
// 检查右侧空间是否足够
|
||||||
const rightSpace = window.innerWidth - rect.right
|
const rightSpace = window.innerWidth - rect.right;
|
||||||
const leftSpace = rect.left
|
const leftSpace = rect.left;
|
||||||
|
|
||||||
// 如果右侧空间不足,且左侧空间足够,则显示在左侧
|
// 如果右侧空间不足,且左侧空间足够,则显示在左侧
|
||||||
if (rightSpace < 200 && leftSpace > 200) {
|
if (rightSpace < 200 && leftSpace > 200) {
|
||||||
this.addChildMenuPosition = {
|
this.addChildMenuPosition = {
|
||||||
x: rect.left - 5, // 左侧偏移5px
|
x: rect.left - 5, // 左侧偏移5px
|
||||||
y: rect.top
|
y: rect.top,
|
||||||
}
|
};
|
||||||
} else {
|
} else {
|
||||||
this.addChildMenuPosition = {
|
this.addChildMenuPosition = {
|
||||||
x: rect.right + 5, // 右侧偏移5px
|
x: rect.right + 5, // 右侧偏移5px
|
||||||
y: rect.top
|
y: rect.top,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
this.showAddChild = true;
|
||||||
this.showAddChild = true
|
|
||||||
// 阻止事件冒泡,防止触发外部点击事件
|
// 阻止事件冒泡,防止触发外部点击事件
|
||||||
event?.stopPropagation()
|
event?.stopPropagation();
|
||||||
},
|
},
|
||||||
|
|
||||||
// 处理新增子节点
|
// 处理新增子节点
|
||||||
handleAddChild (type) {
|
handleAddChild(type) {
|
||||||
if (!this.node || !this.parent || typeof this.parent.addNode !== 'function') return
|
if (!this.node || !this.parent || typeof this.parent.addNode !== 'function') return;
|
||||||
|
|
||||||
// 模拟右键添加节点的流程
|
// 模拟右键添加节点的流程
|
||||||
this.parent.contextMenuNode = this.node
|
this.parent.contextMenuNode = this.node;
|
||||||
this.parent.contextMenuAddPosition = 'right'
|
this.parent.contextMenuAddPosition = 'right';
|
||||||
this.parent.contextMenuPortIndex = 0
|
this.parent.contextMenuPortIndex = 0;
|
||||||
|
|
||||||
// 调用父组件的 addNode 方法
|
// 调用父组件的 addNode 方法
|
||||||
this.parent.addNode(type)
|
this.parent.addNode(type);
|
||||||
|
|
||||||
// 关闭菜单
|
// 关闭菜单
|
||||||
this.$emit('update:visible', false)
|
this.$emit('update:visible', false);
|
||||||
this.showAddChild = false
|
this.showAddChild = false;
|
||||||
}
|
|
||||||
},
|
},
|
||||||
mounted () {
|
},
|
||||||
|
mounted() {
|
||||||
// 点击外部关闭菜单
|
// 点击外部关闭菜单
|
||||||
const handleClickOutside = (e) => {
|
const handleClickOutside = (e) => {
|
||||||
if (!this.$el.contains(e.target)) {
|
if (!this.$el.contains(e.target)) {
|
||||||
this.$emit('update:visible', false)
|
this.$emit('update:visible', false);
|
||||||
this.showChangeType = false
|
this.showChangeType = false;
|
||||||
this.showAddChild = false
|
this.showAddChild = false;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
document.addEventListener('click', handleClickOutside)
|
document.addEventListener('click', handleClickOutside);
|
||||||
|
|
||||||
// 保存引用以便在组件销毁时移除
|
// 保存引用以便在组件销毁时移除
|
||||||
this.handleClickOutside = handleClickOutside
|
this.handleClickOutside = handleClickOutside;
|
||||||
},
|
},
|
||||||
beforeUnmount () {
|
beforeUnmount() {
|
||||||
// 移除事件监听器
|
// 移除事件监听器
|
||||||
document.removeEventListener('click', this.handleClickOutside)
|
document.removeEventListener('click', this.handleClickOutside);
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -4,8 +4,7 @@
|
|||||||
<UnpublishedMask :visible="!form.enabled" />
|
<UnpublishedMask :visible="!form.enabled" />
|
||||||
|
|
||||||
<!-- 执行面板 -->
|
<!-- 执行面板 -->
|
||||||
<div class="execution-panel"
|
<div class="execution-panel" v-if="form.enabled">
|
||||||
v-if="form.enabled">
|
|
||||||
<div class="panel-header">
|
<div class="panel-header">
|
||||||
<h3>流程运行{{ id }}</h3>
|
<h3>流程运行{{ id }}</h3>
|
||||||
</div>
|
</div>
|
||||||
@@ -14,66 +13,64 @@
|
|||||||
<!-- 参数输入区域 -->
|
<!-- 参数输入区域 -->
|
||||||
<div class="left-panel">
|
<div class="left-panel">
|
||||||
<div class="variable-inputs">
|
<div class="variable-inputs">
|
||||||
<div v-for="(param, index) in startNodeParams"
|
<div v-for="(param, index) in startNodeParams" :key="index" class="input-item">
|
||||||
:key="index"
|
<div class="input-label" :class="{ required: param.required }">
|
||||||
class="input-item">
|
|
||||||
<div class="input-label"
|
|
||||||
:class="{ 'required': param.required }">
|
|
||||||
{{ param.name }}
|
{{ param.name }}
|
||||||
</div>
|
</div>
|
||||||
<div class="input-value">
|
<div class="input-value">
|
||||||
<input v-if="param.inputType === 'input'"
|
<input
|
||||||
|
v-if="param.inputType === 'input'"
|
||||||
v-model="param.value"
|
v-model="param.value"
|
||||||
class="param-input"
|
class="param-input"
|
||||||
:disabled="isRunning"
|
:disabled="isRunning"
|
||||||
:class="{ 'error': showError && param.required && !param.value }"
|
:class="{ error: showError && param.required && !param.value }"
|
||||||
:placeholder="'请输入' + param.name" />
|
:placeholder="'请输入' + param.name"
|
||||||
<input v-else-if="param.inputType === 'number'"
|
/>
|
||||||
|
<input
|
||||||
|
v-else-if="param.inputType === 'number'"
|
||||||
type="number"
|
type="number"
|
||||||
v-model.number="param.value"
|
v-model.number="param.value"
|
||||||
class="param-input"
|
class="param-input"
|
||||||
:disabled="isRunning"
|
:disabled="isRunning"
|
||||||
:class="{ 'error': showError && param.required && !param.value }"
|
:class="{ error: showError && param.required && !param.value }"
|
||||||
:placeholder="'请输入' + param.name" />
|
:placeholder="'请输入' + param.name"
|
||||||
<textarea v-else-if="param.inputType === 'textarea'"
|
/>
|
||||||
|
<textarea
|
||||||
|
v-else-if="param.inputType === 'textarea'"
|
||||||
v-model="param.value"
|
v-model="param.value"
|
||||||
class="param-textarea"
|
class="param-textarea"
|
||||||
:disabled="isRunning"
|
:disabled="isRunning"
|
||||||
:class="{ 'error': showError && param.required && !param.value }"
|
:class="{ error: showError && param.required && !param.value }"
|
||||||
:placeholder="'请输入' + param.name"
|
:placeholder="'请输入' + param.name"
|
||||||
rows="3"></textarea>
|
rows="3"
|
||||||
<select v-else-if="param.inputType === 'select'"
|
></textarea>
|
||||||
|
<select
|
||||||
|
v-else-if="param.inputType === 'select'"
|
||||||
v-model="param.value"
|
v-model="param.value"
|
||||||
class="param-select"
|
class="param-select"
|
||||||
:disabled="isRunning"
|
:disabled="isRunning"
|
||||||
:class="{ 'error': showError && param.required && !param.value }">
|
:class="{ error: showError && param.required && !param.value }"
|
||||||
|
>
|
||||||
<option value="">请选择{{ param.name }}</option>
|
<option value="">请选择{{ param.name }}</option>
|
||||||
<option v-for="option in param.options"
|
<option v-for="option in param.options" :key="option.value" :value="option.value">
|
||||||
:key="option.value"
|
|
||||||
:value="option.value">
|
|
||||||
{{ option.label }}
|
{{ option.label }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-button type="primary"
|
<el-button type="primary" class="run-btn" :disabled="isRunning" @click="handleParamRun">
|
||||||
class="run-btn"
|
|
||||||
:disabled="isRunning"
|
|
||||||
@click="handleParamRun">
|
|
||||||
{{ isRunning ? '运行中...' : '运行' }}
|
{{ isRunning ? '运行中...' : '运行' }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 执行状态和结果区域 -->
|
<!-- 执行状态和结果区域 -->
|
||||||
<div class="execution-detail"
|
<div class="execution-detail" v-if="executionNodes.length">
|
||||||
v-if="executionNodes.length">
|
|
||||||
<div class="detail-card">
|
<div class="detail-card">
|
||||||
<div class="detail-row">
|
<div class="detail-row">
|
||||||
<div class="detail-item">
|
<div class="detail-item">
|
||||||
<div class="label">状态</div>
|
<div class="label">状态</div>
|
||||||
<div class="value"
|
<div class="value" :class="executionStatus.class">
|
||||||
:class="executionStatus.class">
|
|
||||||
{{ executionStatus.text }}
|
{{ executionStatus.text }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -91,13 +88,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="right-panel">
|
<div class="right-panel">
|
||||||
<!-- 执行进度和结果区域 -->
|
<!-- 执行进度和结果区域 -->
|
||||||
<node-list :nodes="executionNodes"
|
<node-list :nodes="executionNodes" @end="handleEnd" v-if="executionNodes.length" />
|
||||||
@end="handleEnd"
|
|
||||||
v-if="executionNodes.length" />
|
|
||||||
|
|
||||||
<!-- 最终执行结果 -->
|
<!-- 最终执行结果 -->
|
||||||
<div class="execution-result"
|
<div class="execution-result" v-if="executionResult">
|
||||||
v-if="executionResult">
|
|
||||||
<h4>执行结果</h4>
|
<h4>执行结果</h4>
|
||||||
<pre>{{ JSON.stringify(executionResult, null, 2) }}</pre>
|
<pre>{{ JSON.stringify(executionResult, null, 2) }}</pre>
|
||||||
</div>
|
</div>
|
||||||
@@ -108,11 +102,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { Loading, Check, CircleClose, ArrowRight } from '@element-plus/icons-vue'
|
import { Loading, Check, CircleClose, ArrowRight } from '@element-plus/icons-vue';
|
||||||
import { getObj } from '/@/api/knowledge/aiFlow';
|
import { getObj } from '/@/api/knowledge/aiFlow';
|
||||||
import NodeList from './components/NodeList.vue'
|
import NodeList from './components/NodeList.vue';
|
||||||
import NodeCommon from './mixins/Node.ts'
|
import NodeCommon from './mixins/Node.ts';
|
||||||
import UnpublishedMask from './components/UnpublishedMask.vue'
|
import UnpublishedMask from './components/UnpublishedMask.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'WorkflowRun',
|
name: 'WorkflowRun',
|
||||||
@@ -123,15 +117,15 @@ export default {
|
|||||||
CircleClose,
|
CircleClose,
|
||||||
ArrowRight,
|
ArrowRight,
|
||||||
NodeList,
|
NodeList,
|
||||||
UnpublishedMask
|
UnpublishedMask,
|
||||||
},
|
},
|
||||||
provide () {
|
provide() {
|
||||||
return {
|
return {
|
||||||
parent: this,
|
parent: this,
|
||||||
nodes: this.nodes,
|
nodes: this.nodes,
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
data () {
|
data() {
|
||||||
return {
|
return {
|
||||||
form: { enabled: true },
|
form: { enabled: true },
|
||||||
executionNodes: [],
|
executionNodes: [],
|
||||||
@@ -140,67 +134,67 @@ export default {
|
|||||||
totalTokens: 0,
|
totalTokens: 0,
|
||||||
startNodeParams: [], // 添加开始节点参数
|
startNodeParams: [], // 添加开始节点参数
|
||||||
showError: false,
|
showError: false,
|
||||||
isRunning: false // 添加运行状态控制
|
isRunning: false, // 添加运行状态控制
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
executionStatus () {
|
executionStatus() {
|
||||||
const lastNode = this.executionNodes[this.executionNodes.length - 1]
|
const lastNode = this.executionNodes[this.executionNodes.length - 1];
|
||||||
if (!lastNode) return { text: '等待中', class: 'status-pending' }
|
if (!lastNode) return { text: '等待中', class: 'status-pending' };
|
||||||
|
|
||||||
const statusMap = {
|
const statusMap = {
|
||||||
'running': { text: '运行中', class: 'status-running' },
|
running: { text: '运行中', class: 'status-running' },
|
||||||
'success': { text: '成功', class: 'status-success' },
|
success: { text: '成功', class: 'status-success' },
|
||||||
'error': { text: '失败', class: 'status-error' },
|
error: { text: '失败', class: 'status-error' },
|
||||||
'skipped': { text: '已跳过', class: 'status-skipped' }
|
skipped: { text: '已跳过', class: 'status-skipped' },
|
||||||
}
|
};
|
||||||
|
|
||||||
return statusMap[lastNode.status] || { text: '等待中', class: 'status-pending' }
|
return statusMap[lastNode.status] || { text: '等待中', class: 'status-pending' };
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
created () {
|
created() {
|
||||||
this.loadFromStorage()
|
this.loadFromStorage();
|
||||||
},
|
},
|
||||||
unmounted() {
|
unmounted() {
|
||||||
this.resetConversation();
|
this.resetConversation();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 修改 loadFromStorage 方法
|
// 修改 loadFromStorage 方法
|
||||||
async loadFromStorage () {
|
async loadFromStorage() {
|
||||||
try {
|
try {
|
||||||
const res = await getObj(this.id)
|
const res = await getObj(this.id);
|
||||||
this.form = res.data.data;
|
this.form = res.data.data;
|
||||||
const { dsl = '{}' } = this.form
|
const { dsl = '{}' } = this.form;
|
||||||
const data = JSON.parse(dsl)
|
const data = JSON.parse(dsl);
|
||||||
this.nodes = data.nodes || []
|
this.nodes = data.nodes || [];
|
||||||
this.connections = data.connections || []
|
this.connections = data.connections || [];
|
||||||
this.env = data.env || []
|
this.env = data.env || [];
|
||||||
this.handleRunClick()
|
this.handleRunClick();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('加载工作流失败:', error)
|
console.error('加载工作流失败:', error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
formatTotalTime (time) {
|
formatTotalTime(time) {
|
||||||
if (!time) return '0ms'
|
if (!time) return '0ms';
|
||||||
return `${Number(time).toFixed(3)}ms`
|
return `${Number(time).toFixed(3)}ms`;
|
||||||
},
|
},
|
||||||
handleParamRun () {
|
handleParamRun() {
|
||||||
const hasError = this.startNodeParams.some(param => param.required && !param.value)
|
const hasError = this.startNodeParams.some((param) => param.required && !param.value);
|
||||||
this.showError = hasError
|
this.showError = hasError;
|
||||||
|
|
||||||
if (hasError) {
|
if (hasError) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.runWorkflow(this.startNodeParams)
|
this.runWorkflow(this.startNodeParams);
|
||||||
this.showError = false
|
this.showError = false;
|
||||||
},
|
},
|
||||||
handleEnd (status) {
|
handleEnd(status) {
|
||||||
this.isRunning = false
|
this.isRunning = false;
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@@ -273,7 +267,6 @@ export default {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.detail-item {
|
.detail-item {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|||||||
@@ -1,100 +1,92 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- 对话详情抽屉 -->
|
<!-- 对话详情抽屉 -->
|
||||||
<el-drawer v-model="visible"
|
<el-drawer v-model="visible" title="对话详情" size="500" :before-close="handleClose" class="chat-detail-drawer">
|
||||||
title="对话详情"
|
|
||||||
size="500"
|
|
||||||
:before-close="handleClose"
|
|
||||||
class="chat-detail-drawer">
|
|
||||||
<div v-loading="loading">
|
<div v-loading="loading">
|
||||||
<ChatMessage :messages="messages"
|
<ChatMessage :messages="messages" v-if="messages.length > 0" ref="messageContainer" />
|
||||||
v-if="messages.length > 0"
|
<el-empty v-else description="暂无对话记录"> </el-empty>
|
||||||
ref="messageContainer" />
|
|
||||||
<el-empty v-else
|
|
||||||
description="暂无对话记录">
|
|
||||||
</el-empty>
|
|
||||||
</div>
|
</div>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { marked } from 'marked'
|
import { marked } from 'marked';
|
||||||
import { Cpu } from '@element-plus/icons-vue'
|
import { Cpu } from '@element-plus/icons-vue';
|
||||||
import ChatMessage from './ChatMessage.vue'
|
import ChatMessage from './ChatMessage.vue';
|
||||||
export default {
|
export default {
|
||||||
name: 'ChatDetail',
|
name: 'ChatDetail',
|
||||||
components: {
|
components: {
|
||||||
Cpu,
|
Cpu,
|
||||||
ChatMessage
|
ChatMessage,
|
||||||
},
|
},
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
// 对话ID
|
// 对话ID
|
||||||
conversationId: {
|
conversationId: {
|
||||||
type: [String, Number],
|
type: [String, Number],
|
||||||
default: ''
|
default: '',
|
||||||
},
|
},
|
||||||
// 是否显示弹窗
|
// 是否显示弹窗
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
data () {
|
data() {
|
||||||
return {
|
return {
|
||||||
loading: false,
|
loading: false,
|
||||||
messages: []
|
messages: [],
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
visible: {
|
visible: {
|
||||||
get () {
|
get() {
|
||||||
return this.modelValue
|
return this.modelValue;
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
this.$emit('update:modelValue', val);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
set (val) {
|
|
||||||
this.$emit('update:modelValue', val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
conversationId: {
|
conversationId: {
|
||||||
handler (val) {
|
handler(val) {
|
||||||
if (val) {
|
if (val) {
|
||||||
this.loadMessages()
|
this.loadMessages();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
immediate: true
|
immediate: true,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
// 加载消息列表
|
// 加载消息列表
|
||||||
async loadMessages () {
|
async loadMessages() {
|
||||||
if (!this.conversationId) return
|
if (!this.conversationId) return;
|
||||||
|
|
||||||
this.loading = true
|
this.loading = true;
|
||||||
try {
|
try {
|
||||||
const res = null
|
const res = null;
|
||||||
this.messages = res.data.data.records || []
|
this.messages = res.data.data.records || [];
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('加载消息失败:', error)
|
console.error('加载消息失败:', error);
|
||||||
this.$message.error('加载消息失败')
|
this.$message.error('加载消息失败');
|
||||||
} finally {
|
} finally {
|
||||||
this.loading = false
|
this.loading = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 解析 Markdown
|
// 解析 Markdown
|
||||||
parseMarkdown (text) {
|
parseMarkdown(text) {
|
||||||
if (!text) return ''
|
if (!text) return '';
|
||||||
return marked(text)
|
return marked(text);
|
||||||
},
|
},
|
||||||
|
|
||||||
// 关闭弹窗
|
// 关闭弹窗
|
||||||
handleClose () {
|
handleClose() {
|
||||||
this.visible = false
|
this.visible = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -123,15 +115,14 @@ export default {
|
|||||||
// 发送更新事件给父组件
|
// 发送更新事件给父组件
|
||||||
this.$emit('message-updated', this.messages);
|
this.$emit('message-updated', this.messages);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|
||||||
.chat-detail-drawer {
|
.chat-detail-drawer {
|
||||||
.el-drawer__body{
|
.el-drawer__body {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,63 +1,44 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="messages">
|
<div class="messages">
|
||||||
<div v-for="(msg, index) in messages"
|
<div v-for="(msg, index) in messages" :key="index" class="message" :class="[msg.role]" @contextmenu.prevent="showContextMenu($event, msg, index)">
|
||||||
:key="index"
|
|
||||||
class="message"
|
|
||||||
:class="[msg.role]"
|
|
||||||
@contextmenu.prevent="showContextMenu($event, msg, index)">
|
|
||||||
<div class="avatar">
|
<div class="avatar">
|
||||||
<img :src="msg.role === 'user' ? currentUserAvatar : botAvatar"
|
<img :src="msg.role === 'user' ? currentUserAvatar : botAvatar" alt="avatar" />
|
||||||
alt="avatar" />
|
|
||||||
</div>
|
</div>
|
||||||
<div style="width: 100%;">
|
<div style="width: 100%">
|
||||||
<!-- 消息时间显示 - 移到content外面 -->
|
<!-- 消息时间显示 - 移到content外面 -->
|
||||||
<div class="time">{{ getMessageTime(msg) }}</div>
|
<div class="time">{{ getMessageTime(msg) }}</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<!-- 思考内容区域,添加可折叠功能,默认展开 -->
|
<!-- 思考内容区域,添加可折叠功能,默认展开 -->
|
||||||
<div class="collapsible_wrapper"
|
<div class="collapsible_wrapper" v-if="msg.reasoning_content">
|
||||||
v-if="msg.reasoning_content">
|
<div class="collapsible_tag" @click="toggleContent(index, 'reasoning')">
|
||||||
<div class="collapsible_tag"
|
<el-icon class="collapsible-icon" :class="{ 'is-rotate': contentVisible[index]?.reasoning !== false }">
|
||||||
@click="toggleContent(index, 'reasoning')">
|
|
||||||
<el-icon class="collapsible-icon"
|
|
||||||
:class="{ 'is-rotate': contentVisible[index]?.reasoning !== false }">
|
|
||||||
<ArrowDown />
|
<ArrowDown />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
<span>深度思考</span>
|
<span>深度思考</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="collapsible_content"
|
<div class="collapsible_content" v-show="contentVisible[index]?.reasoning !== false">
|
||||||
v-show="contentVisible[index]?.reasoning !== false">
|
|
||||||
{{ msg.reasoning_content }}
|
{{ msg.reasoning_content }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<template v-if="msg.content">
|
<template v-if="msg.content">
|
||||||
<div v-html="parseMarkdown(msg.content)"></div>
|
<div v-html="parseMarkdown(msg.content)"></div>
|
||||||
<div class="questions"
|
<div class="questions" v-if="msg.questions">
|
||||||
v-if="msg.questions">
|
<el-tag v-for="(question, qIndex) in msg.questions" :key="qIndex" type="primary" @click="handleQuestionClick(question.text)">
|
||||||
<el-tag v-for="(question, qIndex) in msg.questions"
|
|
||||||
:key="qIndex"
|
|
||||||
type="primary"
|
|
||||||
@click="handleQuestionClick(question.text)">
|
|
||||||
{{ question.text }}
|
{{ question.text }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div v-else-if="msg.nodes"
|
<div v-else-if="msg.nodes" class="collapsible_wrapper">
|
||||||
class="collapsible_wrapper">
|
<div class="collapsible_tag" @click="toggleContent(index, 'nodes')">
|
||||||
<div class="collapsible_tag"
|
<el-icon class="collapsible-icon" :class="{ 'is-rotate': contentVisible[index]?.nodes !== false }">
|
||||||
@click="toggleContent(index, 'nodes')">
|
|
||||||
<el-icon class="collapsible-icon"
|
|
||||||
:class="{ 'is-rotate': contentVisible[index]?.nodes !== false }">
|
|
||||||
<ArrowDown />
|
<ArrowDown />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
<span>执行步骤</span>
|
<span>执行步骤</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="collapsible_content"
|
<div class="collapsible_content" v-show="contentVisible[index]?.nodes !== false">
|
||||||
v-show="contentVisible[index]?.nodes !== false">
|
|
||||||
<node-list :nodes="msg.nodes" />
|
<node-list :nodes="msg.nodes" />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="msg.result"
|
<div v-if="msg.result" v-html="parseMarkdown(msg.result)"></div>
|
||||||
v-html="parseMarkdown(msg.result)">
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<template v-if="loading && messages.indexOf(msg) === messages.length - 1">
|
<template v-if="loading && messages.indexOf(msg) === messages.length - 1">
|
||||||
<div class="typing-indicator">
|
<div class="typing-indicator">
|
||||||
@@ -70,50 +51,37 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 右键菜单 -->
|
<!-- 右键菜单 -->
|
||||||
<el-dialog v-model="editDialogVisible"
|
<el-dialog v-model="editDialogVisible" title="编辑消息" width="50%" :before-close="handleEditDialogClose">
|
||||||
title="编辑消息"
|
<el-input v-model="editingContent" type="textarea" :rows="10" placeholder="请输入消息内容" />
|
||||||
width="50%"
|
|
||||||
:before-close="handleEditDialogClose">
|
|
||||||
<el-input v-model="editingContent"
|
|
||||||
type="textarea"
|
|
||||||
:rows="10"
|
|
||||||
placeholder="请输入消息内容" />
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button @click="handleEditDialogClose">取消</el-button>
|
<el-button @click="handleEditDialogClose">取消</el-button>
|
||||||
<el-button type="primary"
|
<el-button type="primary" @click="saveEditedMessage">确认</el-button>
|
||||||
@click="saveEditedMessage">确认</el-button>
|
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<!-- 自定义右键菜单 -->
|
<!-- 自定义右键菜单 -->
|
||||||
<div v-show="contextMenuVisible"
|
<div v-show="contextMenuVisible" class="context-menu" :style="{ top: contextMenuTop + 'px', left: contextMenuLeft + 'px' }">
|
||||||
class="context-menu"
|
<div class="context-menu-item" @click="copyMessage">
|
||||||
:style="{ top: contextMenuTop + 'px', left: contextMenuLeft + 'px' }">
|
|
||||||
<div class="context-menu-item"
|
|
||||||
@click="copyMessage">
|
|
||||||
<el-icon>
|
<el-icon>
|
||||||
<Document />
|
<Document />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
<span>复制</span>
|
<span>复制</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="context-menu-item"
|
<div class="context-menu-item" @click="editMessage">
|
||||||
@click="editMessage">
|
|
||||||
<el-icon>
|
<el-icon>
|
||||||
<Edit />
|
<Edit />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
<span>编辑</span>
|
<span>编辑</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="context-menu-item"
|
<div class="context-menu-item" @click="deleteMessage">
|
||||||
@click="deleteMessage">
|
|
||||||
<el-icon>
|
<el-icon>
|
||||||
<Delete />
|
<Delete />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
<span>删除</span>
|
<span>删除</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="context-menu-item"
|
<div class="context-menu-item" @click="speakMessage">
|
||||||
@click="speakMessage">
|
|
||||||
<el-icon>
|
<el-icon>
|
||||||
<Microphone />
|
<Microphone />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
@@ -121,67 +89,66 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, onMounted, onBeforeUnmount } from 'vue'
|
import { ref, reactive, onMounted, onBeforeUnmount } from 'vue';
|
||||||
import { marked } from 'marked'
|
import { marked } from 'marked';
|
||||||
import hljs from 'highlight.js/lib/core'
|
import hljs from 'highlight.js/lib/core';
|
||||||
// 按需导入常用的语言
|
// 按需导入常用的语言
|
||||||
import javascript from 'highlight.js/lib/languages/javascript'
|
import javascript from 'highlight.js/lib/languages/javascript';
|
||||||
import typescript from 'highlight.js/lib/languages/typescript'
|
import typescript from 'highlight.js/lib/languages/typescript';
|
||||||
import python from 'highlight.js/lib/languages/python'
|
import python from 'highlight.js/lib/languages/python';
|
||||||
import java from 'highlight.js/lib/languages/java'
|
import java from 'highlight.js/lib/languages/java';
|
||||||
import xml from 'highlight.js/lib/languages/xml'
|
import xml from 'highlight.js/lib/languages/xml';
|
||||||
import css from 'highlight.js/lib/languages/css'
|
import css from 'highlight.js/lib/languages/css';
|
||||||
import scss from 'highlight.js/lib/languages/scss'
|
import scss from 'highlight.js/lib/languages/scss';
|
||||||
import json from 'highlight.js/lib/languages/json'
|
import json from 'highlight.js/lib/languages/json';
|
||||||
import bash from 'highlight.js/lib/languages/bash'
|
import bash from 'highlight.js/lib/languages/bash';
|
||||||
import markdown from 'highlight.js/lib/languages/markdown'
|
import markdown from 'highlight.js/lib/languages/markdown';
|
||||||
// 导入暗色主题样式
|
// 导入暗色主题样式
|
||||||
import 'highlight.js/styles/atom-one-dark.css'
|
import 'highlight.js/styles/atom-one-dark.css';
|
||||||
// 导入Element Plus图标
|
// 导入Element Plus图标
|
||||||
import { ArrowDown, Document, Edit, Delete, Microphone } from '@element-plus/icons-vue'
|
import { ArrowDown, Document, Edit, Delete, Microphone } from '@element-plus/icons-vue';
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus';
|
||||||
|
|
||||||
import NodeList from '/@/views/knowledge/aiFlow/components/NodeList.vue'
|
import NodeList from '/@/views/knowledge/aiFlow/components/NodeList.vue';
|
||||||
import {dateTimeStr} from "/@/utils/formatTime";
|
import { dateTimeStr } from '/@/utils/formatTime';
|
||||||
|
|
||||||
// 定义组件接收的props
|
// 定义组件接收的props
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
loading: {
|
loading: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false,
|
||||||
},
|
},
|
||||||
messages: {
|
messages: {
|
||||||
type: Array,
|
type: Array,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
currentUserAvatar: {
|
currentUserAvatar: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '/img/chat/icon.png'
|
default: '/img/chat/icon.png',
|
||||||
},
|
},
|
||||||
botAvatar: {
|
botAvatar: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '/img/chat/chatgpt.png'
|
default: '/img/chat/chatgpt.png',
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
// 定义组件触发的事件
|
// 定义组件触发的事件
|
||||||
const emit = defineEmits(['item-click', 'change'])
|
const emit = defineEmits(['item-click', 'change']);
|
||||||
|
|
||||||
// 注册语言
|
// 注册语言
|
||||||
hljs.registerLanguage('javascript', javascript)
|
hljs.registerLanguage('javascript', javascript);
|
||||||
hljs.registerLanguage('typescript', typescript)
|
hljs.registerLanguage('typescript', typescript);
|
||||||
hljs.registerLanguage('python', python)
|
hljs.registerLanguage('python', python);
|
||||||
hljs.registerLanguage('java', java)
|
hljs.registerLanguage('java', java);
|
||||||
hljs.registerLanguage('xml', xml)
|
hljs.registerLanguage('xml', xml);
|
||||||
hljs.registerLanguage('css', css)
|
hljs.registerLanguage('css', css);
|
||||||
hljs.registerLanguage('scss', scss)
|
hljs.registerLanguage('scss', scss);
|
||||||
hljs.registerLanguage('json', json)
|
hljs.registerLanguage('json', json);
|
||||||
hljs.registerLanguage('bash', bash)
|
hljs.registerLanguage('bash', bash);
|
||||||
hljs.registerLanguage('markdown', markdown)
|
hljs.registerLanguage('markdown', markdown);
|
||||||
|
|
||||||
// 配置marked的代码高亮选项
|
// 配置marked的代码高亮选项
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@@ -189,34 +156,34 @@ onMounted(() => {
|
|||||||
highlight: function (code, lang) {
|
highlight: function (code, lang) {
|
||||||
if (lang && hljs.getLanguage(lang)) {
|
if (lang && hljs.getLanguage(lang)) {
|
||||||
try {
|
try {
|
||||||
return hljs.highlight(code, { language: lang }).value
|
return hljs.highlight(code, { language: lang }).value;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e);
|
||||||
return code
|
return code;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return hljs.highlightAuto(code).value
|
return hljs.highlightAuto(code).value;
|
||||||
},
|
},
|
||||||
breaks: true, // 支持换行符
|
breaks: true, // 支持换行符
|
||||||
gfm: true, // 启用GitHub风格Markdown
|
gfm: true, // 启用GitHub风格Markdown
|
||||||
sanitize: false, // 允许HTML标签以支持代码高亮
|
sanitize: false, // 允许HTML标签以支持代码高亮
|
||||||
langPrefix: 'hljs language-', // 添加代码块的class前缀
|
langPrefix: 'hljs language-', // 添加代码块的class前缀
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
// 使用reactive创建响应式对象,用于跟踪内容的显示状态
|
// 使用reactive创建响应式对象,用于跟踪内容的显示状态
|
||||||
const contentVisible = reactive({})
|
const contentVisible = reactive({});
|
||||||
|
|
||||||
// 右键菜单相关状态
|
// 右键菜单相关状态
|
||||||
const contextMenuVisible = ref(false)
|
const contextMenuVisible = ref(false);
|
||||||
const contextMenuTop = ref(0)
|
const contextMenuTop = ref(0);
|
||||||
const contextMenuLeft = ref(0)
|
const contextMenuLeft = ref(0);
|
||||||
const currentMessage = ref(null)
|
const currentMessage = ref(null);
|
||||||
const currentMessageIndex = ref(-1)
|
const currentMessageIndex = ref(-1);
|
||||||
|
|
||||||
// 编辑对话框相关状态
|
// 编辑对话框相关状态
|
||||||
const editDialogVisible = ref(false)
|
const editDialogVisible = ref(false);
|
||||||
const editingContent = ref('')
|
const editingContent = ref('');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 切换内容的显示/隐藏状态
|
* 切换内容的显示/隐藏状态
|
||||||
@@ -225,10 +192,10 @@ const editingContent = ref('')
|
|||||||
*/
|
*/
|
||||||
const toggleContent = (index, type) => {
|
const toggleContent = (index, type) => {
|
||||||
if (!contentVisible[index]) {
|
if (!contentVisible[index]) {
|
||||||
contentVisible[index] = {}
|
contentVisible[index] = {};
|
||||||
}
|
}
|
||||||
contentVisible[index][type] = contentVisible[index][type] === false ? true : false
|
contentVisible[index][type] = contentVisible[index][type] === false ? true : false;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取消息的时间
|
* 获取消息的时间
|
||||||
@@ -238,15 +205,14 @@ const toggleContent = (index, type) => {
|
|||||||
const getMessageTime = (msg) => {
|
const getMessageTime = (msg) => {
|
||||||
// 如果消息对象中已有时间属性,则直接使用
|
// 如果消息对象中已有时间属性,则直接使用
|
||||||
if (msg.time) {
|
if (msg.time) {
|
||||||
|
return parseDate(msg.time, dateTimeStr);
|
||||||
return parseDate(msg.time,dateTimeStr)
|
|
||||||
}
|
}
|
||||||
// 否则生成当前时间并赋值给消息对象
|
// 否则生成当前时间并赋值给消息对象
|
||||||
const currentTime = parseDate(new Date(),dateTimeStr)
|
const currentTime = parseDate(new Date(), dateTimeStr);
|
||||||
// 为消息对象添加时间属性
|
// 为消息对象添加时间属性
|
||||||
msg.time = new Date().toISOString()
|
msg.time = new Date().toISOString();
|
||||||
return currentTime
|
return currentTime;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 显示右键菜单
|
* 显示右键菜单
|
||||||
@@ -256,152 +222,147 @@ const getMessageTime = (msg) => {
|
|||||||
*/
|
*/
|
||||||
const showContextMenu = (event, msg, index) => {
|
const showContextMenu = (event, msg, index) => {
|
||||||
// 阻止默认右键菜单
|
// 阻止默认右键菜单
|
||||||
event.preventDefault()
|
event.preventDefault();
|
||||||
// 设置菜单位置
|
// 设置菜单位置
|
||||||
contextMenuTop.value = event.clientY
|
contextMenuTop.value = event.clientY;
|
||||||
contextMenuLeft.value = event.clientX
|
contextMenuLeft.value = event.clientX;
|
||||||
// 保存当前消息和索引
|
// 保存当前消息和索引
|
||||||
currentMessage.value = msg
|
currentMessage.value = msg;
|
||||||
currentMessageIndex.value = index
|
currentMessageIndex.value = index;
|
||||||
// 显示菜单
|
// 显示菜单
|
||||||
contextMenuVisible.value = true
|
contextMenuVisible.value = true;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 隐藏右键菜单
|
* 隐藏右键菜单
|
||||||
*/
|
*/
|
||||||
const hideContextMenu = () => {
|
const hideContextMenu = () => {
|
||||||
contextMenuVisible.value = false
|
contextMenuVisible.value = false;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 复制消息内容到剪贴板
|
* 复制消息内容到剪贴板
|
||||||
*/
|
*/
|
||||||
const copyMessage = () => {
|
const copyMessage = () => {
|
||||||
if (!currentMessage.value) return
|
if (!currentMessage.value) return;
|
||||||
|
|
||||||
// 获取要复制的文本内容
|
// 获取要复制的文本内容
|
||||||
const textToCopy = currentMessage.value.content ||
|
const textToCopy = currentMessage.value.content || currentMessage.value.reasoning_content || currentMessage.value.result || '';
|
||||||
currentMessage.value.reasoning_content ||
|
|
||||||
(currentMessage.value.result || '')
|
|
||||||
|
|
||||||
// 使用Clipboard API复制文本
|
// 使用Clipboard API复制文本
|
||||||
navigator.clipboard.writeText(textToCopy)
|
navigator.clipboard
|
||||||
|
.writeText(textToCopy)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
ElMessage.success('复制成功')
|
ElMessage.success('复制成功');
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
ElMessage.error('复制失败: ' + err)
|
|
||||||
})
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
ElMessage.error('复制失败: ' + err);
|
||||||
|
});
|
||||||
|
|
||||||
// 隐藏菜单
|
// 隐藏菜单
|
||||||
hideContextMenu()
|
hideContextMenu();
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 打开编辑对话框
|
* 打开编辑对话框
|
||||||
*/
|
*/
|
||||||
const editMessage = () => {
|
const editMessage = () => {
|
||||||
if (!currentMessage.value) return
|
if (!currentMessage.value) return;
|
||||||
|
|
||||||
// 设置编辑内容
|
// 设置编辑内容
|
||||||
editingContent.value = currentMessage.value.content ||
|
editingContent.value = currentMessage.value.content || currentMessage.value.reasoning_content || currentMessage.value.result || '';
|
||||||
currentMessage.value.reasoning_content ||
|
|
||||||
(currentMessage.value.result || '')
|
|
||||||
|
|
||||||
// 显示编辑对话框
|
// 显示编辑对话框
|
||||||
editDialogVisible.value = true
|
editDialogVisible.value = true;
|
||||||
|
|
||||||
// 隐藏菜单
|
// 隐藏菜单
|
||||||
hideContextMenu()
|
hideContextMenu();
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 关闭编辑对话框
|
* 关闭编辑对话框
|
||||||
*/
|
*/
|
||||||
const handleEditDialogClose = () => {
|
const handleEditDialogClose = () => {
|
||||||
editDialogVisible.value = false
|
editDialogVisible.value = false;
|
||||||
editingContent.value = ''
|
editingContent.value = '';
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存编辑后的消息
|
* 保存编辑后的消息
|
||||||
*/
|
*/
|
||||||
const saveEditedMessage = () => {
|
const saveEditedMessage = () => {
|
||||||
if (currentMessageIndex.value === -1 || !currentMessage.value) return
|
if (currentMessageIndex.value === -1 || !currentMessage.value) return;
|
||||||
|
|
||||||
// 更新时间
|
// 更新时间
|
||||||
currentMessage.value.time = dayjs().toISOString()
|
currentMessage.value.time = dayjs().toISOString();
|
||||||
// 更新消息内容
|
// 更新消息内容
|
||||||
currentMessage.value.content = editingContent.value
|
currentMessage.value.content = editingContent.value;
|
||||||
|
|
||||||
// 发送编辑消息事件
|
// 发送编辑消息事件
|
||||||
emit('change')
|
emit('change');
|
||||||
|
|
||||||
// 关闭对话框
|
// 关闭对话框
|
||||||
handleEditDialogClose()
|
handleEditDialogClose();
|
||||||
|
|
||||||
ElMessage.success('消息已更新')
|
ElMessage.success('消息已更新');
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除消息
|
* 删除消息
|
||||||
*/
|
*/
|
||||||
const deleteMessage = () => {
|
const deleteMessage = () => {
|
||||||
if (currentMessageIndex.value === -1) return
|
if (currentMessageIndex.value === -1) return;
|
||||||
|
|
||||||
// 从消息数组中删除当前消息
|
// 从消息数组中删除当前消息
|
||||||
props.messages.splice(currentMessageIndex.value, 1)
|
props.messages.splice(currentMessageIndex.value, 1);
|
||||||
|
|
||||||
// 发送删除消息事件
|
// 发送删除消息事件
|
||||||
emit('change')
|
emit('change');
|
||||||
|
|
||||||
// 隐藏菜单
|
// 隐藏菜单
|
||||||
hideContextMenu()
|
hideContextMenu();
|
||||||
|
|
||||||
ElMessage.success('消息已删除')
|
ElMessage.success('消息已删除');
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 使用浏览器API朗读消息
|
* 使用浏览器API朗读消息
|
||||||
*/
|
*/
|
||||||
const speakMessage = () => {
|
const speakMessage = () => {
|
||||||
if (!currentMessage.value) return
|
if (!currentMessage.value) return;
|
||||||
|
|
||||||
// 获取要朗读的文本
|
// 获取要朗读的文本
|
||||||
const textToSpeak = currentMessage.value.content ||
|
const textToSpeak = currentMessage.value.content || currentMessage.value.reasoning_content || currentMessage.value.result || '';
|
||||||
currentMessage.value.reasoning_content ||
|
|
||||||
(currentMessage.value.result || '')
|
|
||||||
|
|
||||||
// 检查浏览器是否支持语音合成
|
// 检查浏览器是否支持语音合成
|
||||||
if ('speechSynthesis' in window) {
|
if ('speechSynthesis' in window) {
|
||||||
// 创建语音合成实例
|
// 创建语音合成实例
|
||||||
const utterance = new SpeechSynthesisUtterance(textToSpeak)
|
const utterance = new SpeechSynthesisUtterance(textToSpeak);
|
||||||
|
|
||||||
// 设置语音属性
|
// 设置语音属性
|
||||||
utterance.lang = 'zh-CN' // 设置语言为中文
|
utterance.lang = 'zh-CN'; // 设置语言为中文
|
||||||
utterance.rate = 1.0 // 设置语速
|
utterance.rate = 1.0; // 设置语速
|
||||||
utterance.pitch = 1.0 // 设置音调
|
utterance.pitch = 1.0; // 设置音调
|
||||||
|
|
||||||
// 开始朗读
|
// 开始朗读
|
||||||
window.speechSynthesis.speak(utterance)
|
window.speechSynthesis.speak(utterance);
|
||||||
|
|
||||||
ElMessage.success('正在朗读消息')
|
ElMessage.success('正在朗读消息');
|
||||||
} else {
|
} else {
|
||||||
ElMessage.error('您的浏览器不支持语音合成')
|
ElMessage.error('您的浏览器不支持语音合成');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 隐藏菜单
|
// 隐藏菜单
|
||||||
hideContextMenu()
|
hideContextMenu();
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理问题点击事件
|
* 处理问题点击事件
|
||||||
* @param {string} text - 问题文本
|
* @param {string} text - 问题文本
|
||||||
*/
|
*/
|
||||||
const handleQuestionClick = (text) => {
|
const handleQuestionClick = (text) => {
|
||||||
emit('item-click', text)
|
emit('item-click', text);
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析Markdown内容并支持代码高亮
|
* 解析Markdown内容并支持代码高亮
|
||||||
@@ -409,28 +370,27 @@ const handleQuestionClick = (text) => {
|
|||||||
* @returns {string} - 解析后的HTML字符串
|
* @returns {string} - 解析后的HTML字符串
|
||||||
*/
|
*/
|
||||||
const parseMarkdown = (content) => {
|
const parseMarkdown = (content) => {
|
||||||
if (!content) return ''
|
if (!content) return '';
|
||||||
return marked(content)
|
return marked(content);
|
||||||
}
|
};
|
||||||
|
|
||||||
// 点击页面其他区域时隐藏右键菜单
|
// 点击页面其他区域时隐藏右键菜单
|
||||||
const handleDocumentClick = () => {
|
const handleDocumentClick = () => {
|
||||||
hideContextMenu()
|
hideContextMenu();
|
||||||
}
|
};
|
||||||
|
|
||||||
// 组件挂载时添加全局点击事件监听
|
// 组件挂载时添加全局点击事件监听
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
document.addEventListener('click', handleDocumentClick)
|
document.addEventListener('click', handleDocumentClick);
|
||||||
})
|
});
|
||||||
|
|
||||||
// 组件卸载前移除全局点击事件监听
|
// 组件卸载前移除全局点击事件监听
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
document.removeEventListener('click', handleDocumentClick)
|
document.removeEventListener('click', handleDocumentClick);
|
||||||
})
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|
||||||
// 可折叠内容区域通用样式
|
// 可折叠内容区域通用样式
|
||||||
.collapsible_wrapper {
|
.collapsible_wrapper {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
:start-params="startNodeParams"
|
:start-params="startNodeParams"
|
||||||
:conversation-id="conversationId"
|
:conversation-id="conversationId"
|
||||||
@run="runWorkflow"
|
@run="runWorkflow"
|
||||||
@update:stream="(value) => isStream = value"
|
@update:stream="(value) => (isStream = value)"
|
||||||
@close="showExecutionPanel = false"
|
@close="showExecutionPanel = false"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -74,7 +74,6 @@
|
|||||||
|
|
||||||
<div class="w-px h-4 mx-2 bg-gray-200 dark:bg-gray-700"></div>
|
<div class="w-px h-4 mx-2 bg-gray-200 dark:bg-gray-700"></div>
|
||||||
|
|
||||||
|
|
||||||
<el-button
|
<el-button
|
||||||
class="!p-2 text-gray-600 rounded-full transition-colors dark:text-gray-300 hover:text-primary hover:bg-gray-100 dark:hover:bg-gray-700"
|
class="!p-2 text-gray-600 rounded-full transition-colors dark:text-gray-300 hover:text-primary hover:bg-gray-100 dark:hover:bg-gray-700"
|
||||||
text
|
text
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ export default {
|
|||||||
this.executionNodes[nodeIndex] = {
|
this.executionNodes[nodeIndex] = {
|
||||||
...this.executionNodes[nodeIndex],
|
...this.executionNodes[nodeIndex],
|
||||||
status: 'running',
|
status: 'running',
|
||||||
...event.data
|
...event.data,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -289,7 +289,7 @@ export default {
|
|||||||
this.executionResult = {
|
this.executionResult = {
|
||||||
...this.executionResult,
|
...this.executionResult,
|
||||||
chatMessage: chatMessageContent,
|
chatMessage: chatMessageContent,
|
||||||
isStreaming: !isComplete
|
isStreaming: !isComplete,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -303,7 +303,7 @@ export default {
|
|||||||
this.executionResult = {
|
this.executionResult = {
|
||||||
...result.result,
|
...result.result,
|
||||||
chatMessage: chatMessageContent,
|
chatMessage: chatMessageContent,
|
||||||
isStreaming: false
|
isStreaming: false,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
this.executionResult = result.result;
|
this.executionResult = result.result;
|
||||||
@@ -339,7 +339,7 @@ export default {
|
|||||||
this.executionResult = {
|
this.executionResult = {
|
||||||
chatMessage: chatResult.chatMessage,
|
chatMessage: chatResult.chatMessage,
|
||||||
result: chatResult.result,
|
result: chatResult.result,
|
||||||
isStreaming: false
|
isStreaming: false,
|
||||||
};
|
};
|
||||||
this.isRunning = false;
|
this.isRunning = false;
|
||||||
});
|
});
|
||||||
@@ -354,7 +354,7 @@ export default {
|
|||||||
id: this.id,
|
id: this.id,
|
||||||
params: context.params,
|
params: context.params,
|
||||||
envs: context.envs,
|
envs: context.envs,
|
||||||
stream: false
|
stream: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 处理普通JSON响应
|
// 处理普通JSON响应
|
||||||
@@ -389,7 +389,7 @@ export default {
|
|||||||
this.executionResult = {
|
this.executionResult = {
|
||||||
...this.executionResult,
|
...this.executionResult,
|
||||||
chatMessage: chatMessage,
|
chatMessage: chatMessage,
|
||||||
isStreaming: false
|
isStreaming: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="output-params"
|
<div class="output-params" v-if="node.method || node.httpParams.url">
|
||||||
v-if="node.method || node.httpParams.url">
|
|
||||||
<div class="param-item">
|
<div class="param-item">
|
||||||
<span class="param-name">{{ node.httpParams.method }}</span>
|
<span class="param-name">{{ node.httpParams.method }}</span>
|
||||||
<span class="param-value">{{ node.httpParams.url }}</span>
|
<span class="param-value">{{ node.httpParams.url }}</span>
|
||||||
@@ -9,11 +8,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import common from './common.ts'
|
import common from './common.ts';
|
||||||
export default {
|
export default {
|
||||||
name: 'HttpNode',
|
name: 'HttpNode',
|
||||||
mixins: [common]
|
mixins: [common],
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ export default {
|
|||||||
props: {
|
props: {
|
||||||
node: {
|
node: {
|
||||||
type: Object as PropType<Node>,
|
type: Object as PropType<Node>,
|
||||||
required: true
|
required: true,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
inputParams: this.node.inputParams || [],
|
inputParams: this.node.inputParams || [],
|
||||||
outputParams: this.node.outputParams || []
|
outputParams: this.node.outputParams || [],
|
||||||
}
|
};
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ export const nodeTypes: NodeType[] = [
|
|||||||
{
|
{
|
||||||
name: '分支2',
|
name: '分支2',
|
||||||
value: 1,
|
value: 1,
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
outputParams: [
|
outputParams: [
|
||||||
@@ -151,7 +151,7 @@ export const nodeTypes: NodeType[] = [
|
|||||||
{
|
{
|
||||||
name: 'result',
|
name: 'result',
|
||||||
type: 'String',
|
type: 'String',
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -245,7 +245,8 @@ export const nodeTypes: NodeType[] = [
|
|||||||
messages: [
|
messages: [
|
||||||
{
|
{
|
||||||
role: 'user',
|
role: 'user',
|
||||||
content: '你是一个问题总结助手。\n任务:根据用户提问 ${arg1} 和系统答案 ${arg2},生成一个标准的问题答案。\n要求:基于系统答案内容回答,回答准确、简洁、有用。',
|
content:
|
||||||
|
'你是一个问题总结助手。\n任务:根据用户提问 ${arg1} 和系统答案 ${arg2},生成一个标准的问题答案。\n要求:基于系统答案内容回答,回答准确、简洁、有用。',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
modelConfig: {
|
modelConfig: {
|
||||||
|
|||||||
@@ -85,11 +85,10 @@
|
|||||||
import { Plus, Delete } from '@element-plus/icons-vue';
|
import { Plus, Delete } from '@element-plus/icons-vue';
|
||||||
import common from './common.ts';
|
import common from './common.ts';
|
||||||
import './panel.css';
|
import './panel.css';
|
||||||
import {list} from "/@/api/gen/datasource";
|
import { list } from '/@/api/gen/datasource';
|
||||||
import CodeEditor from '/@/views/knowledge/aiFlow/components/CodeEditor.vue';
|
import CodeEditor from '/@/views/knowledge/aiFlow/components/CodeEditor.vue';
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'DbPanel',
|
name: 'DbPanel',
|
||||||
components: {
|
components: {
|
||||||
@@ -100,8 +99,7 @@ export default {
|
|||||||
mixins: [common],
|
mixins: [common],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
dbList: [
|
dbList: [],
|
||||||
],
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
@@ -109,8 +107,8 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async loadDbList() {
|
async loadDbList() {
|
||||||
const {data} = await list()
|
const { data } = await list();
|
||||||
this.dbList = data
|
this.dbList = data;
|
||||||
},
|
},
|
||||||
handleDbChange() {
|
handleDbChange() {
|
||||||
if (!this.node.dbParams.dbId) {
|
if (!this.node.dbParams.dbId) {
|
||||||
@@ -126,7 +124,7 @@ export default {
|
|||||||
setup() {
|
setup() {
|
||||||
const result = ref(null);
|
const result = ref(null);
|
||||||
return {
|
return {
|
||||||
result
|
result,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
selectedMcp() {
|
selectedMcp() {
|
||||||
return this.mcpList.find(mcp => mcp.mcpId === this.node.mcpParams?.mcpId);
|
return this.mcpList.find((mcp) => mcp.mcpId === this.node.mcpParams?.mcpId);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<span>变量列表</span>
|
<span>变量列表</span>
|
||||||
<el-button type="primary" size="small" @click="addOutput">
|
<el-button type="primary" size="small" @click="addOutput">
|
||||||
<el-icon>
|
<el-icon>
|
||||||
<Plus/>
|
<Plus />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
添加
|
添加
|
||||||
</el-button>
|
</el-button>
|
||||||
@@ -21,29 +21,23 @@
|
|||||||
<el-tag type="primary" size="small">
|
<el-tag type="primary" size="small">
|
||||||
{{ getInputTypeLabel(param.inputType) }}
|
{{ getInputTypeLabel(param.inputType) }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
<el-text>
|
<el-text> | </el-text>
|
||||||
|
|
|
||||||
</el-text>
|
|
||||||
<el-tag :type="param.required ? 'danger' : 'info'" size="small">
|
<el-tag :type="param.required ? 'danger' : 'info'" size="small">
|
||||||
{{ param.required ? '必填' : '选填' }}
|
{{ param.required ? '必填' : '选填' }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
<el-text>
|
<el-text> | </el-text>
|
||||||
|
|
<el-text> {{ param.name }} ({{ param.type }}) </el-text>
|
||||||
</el-text>
|
|
||||||
<el-text>
|
|
||||||
{{ param.name }} ({{ param.type }})
|
|
||||||
</el-text>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="!param.disabled" class="flex gap-2">
|
<div v-if="!param.disabled" class="flex gap-2">
|
||||||
<el-button type="primary" size="small" @click="editParam(index)">
|
<el-button type="primary" size="small" @click="editParam(index)">
|
||||||
<el-icon>
|
<el-icon>
|
||||||
<Edit/>
|
<Edit />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button size="small" @click="removeOutput(index)">
|
<el-button size="small" @click="removeOutput(index)">
|
||||||
<el-icon>
|
<el-icon>
|
||||||
<Delete/>
|
<Delete />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
@@ -54,74 +48,49 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 变量编辑对话框 -->
|
<!-- 变量编辑对话框 -->
|
||||||
<el-dialog
|
<el-dialog v-model="editDialogVisible" :title="isEdit ? '编辑变量' : '添加变量'" width="600px" destroy-on-close>
|
||||||
v-model="editDialogVisible"
|
<el-form ref="paramForm" :model="editingParam" :rules="rules" label-position="top">
|
||||||
:title="isEdit ? '编辑变量' : '添加变量'"
|
|
||||||
width="600px"
|
|
||||||
destroy-on-close
|
|
||||||
>
|
|
||||||
<el-form
|
|
||||||
ref="paramForm"
|
|
||||||
:model="editingParam"
|
|
||||||
:rules="rules"
|
|
||||||
label-position="top"
|
|
||||||
>
|
|
||||||
<el-form-item label="显示名称" prop="name">
|
<el-form-item label="显示名称" prop="name">
|
||||||
<el-input v-model="editingParam.name" placeholder="请输入显示名称"/>
|
<el-input v-model="editingParam.name" placeholder="请输入显示名称" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="变量名" prop="type">
|
<el-form-item label="变量名" prop="type">
|
||||||
<el-input v-model="editingParam.type" placeholder="请输入变量名"/>
|
<el-input v-model="editingParam.type" placeholder="请输入变量名" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="输入类型" prop="inputType">
|
<el-form-item label="输入类型" prop="inputType">
|
||||||
<el-select
|
<el-select v-model="editingParam.inputType" class="w-full" @change="handleEditInputTypeChange">
|
||||||
v-model="editingParam.inputType"
|
<el-option v-for="item in inputTypeDict" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
class="w-full"
|
|
||||||
@change="handleEditInputTypeChange"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in inputTypeDict"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="是否必填" prop="required">
|
<el-form-item label="是否必填" prop="required">
|
||||||
<el-select v-model="editingParam.required" class="w-full">
|
<el-select v-model="editingParam.required" class="w-full">
|
||||||
<el-option :value="false" label="否"/>
|
<el-option :value="false" label="否" />
|
||||||
<el-option :value="true" label="是"/>
|
<el-option :value="true" label="是" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<!-- 选项编辑表单 -->
|
<!-- 选项编辑表单 -->
|
||||||
<template v-if="editingParam.inputType==='select'">
|
<template v-if="editingParam.inputType === 'select'">
|
||||||
<el-divider content-position="left">选项配置</el-divider>
|
<el-divider content-position="left">选项配置</el-divider>
|
||||||
<div class="options-list">
|
<div class="options-list">
|
||||||
<div v-for="(option, index) in editingParam.editingOptions" :key="index" class="mb-2">
|
<div v-for="(option, index) in editingParam.editingOptions" :key="index" class="mb-2">
|
||||||
<el-row :gutter="12">
|
<el-row :gutter="12">
|
||||||
<el-col :span="9">
|
<el-col :span="9">
|
||||||
<el-form-item
|
<el-form-item :prop="'editingOptions.' + index + '.label'" :rules="{ required: true, message: '请输入选项名称', trigger: 'blur' }">
|
||||||
:prop="'editingOptions.' + index + '.label'"
|
<el-input v-model="option.label" placeholder="请输入选项名称" />
|
||||||
:rules="{ required: true, message: '请输入选项名称', trigger: 'blur' }"
|
|
||||||
>
|
|
||||||
<el-input v-model="option.label" placeholder="请输入选项名称"/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item
|
<el-form-item :prop="'editingOptions.' + index + '.value'" :rules="{ required: true, message: '请输入选项值', trigger: 'blur' }">
|
||||||
:prop="'editingOptions.' + index + '.value'"
|
<el-input v-model="option.value" placeholder="请输入选项值" />
|
||||||
:rules="{ required: true, message: '请输入选项值', trigger: 'blur' }"
|
|
||||||
>
|
|
||||||
<el-input v-model="option.value" placeholder="请输入选项值"/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="3">
|
<el-col :span="3">
|
||||||
<el-button @click="removeOption(index)">
|
<el-button @click="removeOption(index)">
|
||||||
<el-icon>
|
<el-icon>
|
||||||
<Delete/>
|
<Delete />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -129,7 +98,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<el-button type="primary" @click="addOption">
|
<el-button type="primary" @click="addOption">
|
||||||
<el-icon>
|
<el-icon>
|
||||||
<Plus/>
|
<Plus />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
添加选项
|
添加选项
|
||||||
</el-button>
|
</el-button>
|
||||||
@@ -148,25 +117,25 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {Plus, Delete, Edit} from '@element-plus/icons-vue'
|
import { Plus, Delete, Edit } from '@element-plus/icons-vue';
|
||||||
import common from './common.ts'
|
import common from './common.ts';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'StartPanel',
|
name: 'StartPanel',
|
||||||
components: {
|
components: {
|
||||||
Plus,
|
Plus,
|
||||||
Delete,
|
Delete,
|
||||||
Edit
|
Edit,
|
||||||
},
|
},
|
||||||
mixins: [common],
|
mixins: [common],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
inputTypeDict: [
|
inputTypeDict: [
|
||||||
{label: '输入框', value: 'input'},
|
{ label: '输入框', value: 'input' },
|
||||||
{label: '下拉框', value: 'select'},
|
{ label: '下拉框', value: 'select' },
|
||||||
{label: '数字框', value: 'number'},
|
{ label: '数字框', value: 'number' },
|
||||||
{label: '文本框', value: 'textarea'},
|
{ label: '文本框', value: 'textarea' },
|
||||||
{label: '图片', value: 'image'},
|
{ label: '图片', value: 'image' },
|
||||||
],
|
],
|
||||||
editDialogVisible: false,
|
editDialogVisible: false,
|
||||||
editingParam: {
|
editingParam: {
|
||||||
@@ -176,37 +145,33 @@ export default {
|
|||||||
required: false,
|
required: false,
|
||||||
inputType: 'input',
|
inputType: 'input',
|
||||||
options: [],
|
options: [],
|
||||||
editingOptions: []
|
editingOptions: [],
|
||||||
},
|
},
|
||||||
isEdit: false,
|
isEdit: false,
|
||||||
rules: {
|
rules: {
|
||||||
name: [
|
name: [
|
||||||
{required: true, message: '请输入显示名称', trigger: 'blur'},
|
{ required: true, message: '请输入显示名称', trigger: 'blur' },
|
||||||
{min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur'}
|
{ min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' },
|
||||||
],
|
],
|
||||||
type: [
|
type: [
|
||||||
{required: true, message: '请输入变量名', trigger: 'blur'},
|
{ required: true, message: '请输入变量名', trigger: 'blur' },
|
||||||
{
|
{
|
||||||
pattern: /^[a-zA-Z][a-zA-Z0-9_]*$/,
|
pattern: /^[a-zA-Z][a-zA-Z0-9_]*$/,
|
||||||
message: '变量名只能包含字母、数字和下划线,且必须以字母开头',
|
message: '变量名只能包含字母、数字和下划线,且必须以字母开头',
|
||||||
trigger: 'blur'
|
trigger: 'blur',
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
inputType: [
|
inputType: [{ required: true, message: '请选择输入类型', trigger: 'change' }],
|
||||||
{required: true, message: '请选择输入类型', trigger: 'change'}
|
required: [{ required: true, message: '请选择是否必填', trigger: 'change' }],
|
||||||
],
|
},
|
||||||
required: [
|
};
|
||||||
{required: true, message: '请选择是否必填', trigger: 'change'}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.updateOutputParams()
|
this.updateOutputParams();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
addOutput() {
|
addOutput() {
|
||||||
this.isEdit = false
|
this.isEdit = false;
|
||||||
this.editingParam = {
|
this.editingParam = {
|
||||||
name: '',
|
name: '',
|
||||||
type: '',
|
type: '',
|
||||||
@@ -214,89 +179,89 @@ export default {
|
|||||||
required: false,
|
required: false,
|
||||||
inputType: 'input',
|
inputType: 'input',
|
||||||
options: [],
|
options: [],
|
||||||
editingOptions: []
|
editingOptions: [],
|
||||||
}
|
};
|
||||||
this.editDialogVisible = true
|
this.editDialogVisible = true;
|
||||||
},
|
},
|
||||||
editParam(index) {
|
editParam(index) {
|
||||||
this.isEdit = true
|
this.isEdit = true;
|
||||||
this.editingParamIndex = index
|
this.editingParamIndex = index;
|
||||||
const param = {...this.inputParams[index]}
|
const param = { ...this.inputParams[index] };
|
||||||
param.editingOptions = [...(param.options || [])].map(opt => ({...opt}))
|
param.editingOptions = [...(param.options || [])].map((opt) => ({ ...opt }));
|
||||||
this.editingParam = param
|
this.editingParam = param;
|
||||||
this.editDialogVisible = true
|
this.editDialogVisible = true;
|
||||||
},
|
},
|
||||||
saveParam() {
|
saveParam() {
|
||||||
if (this.isEdit) {
|
if (this.isEdit) {
|
||||||
this.inputParams[this.editingParamIndex] = {...this.editingParam}
|
this.inputParams[this.editingParamIndex] = { ...this.editingParam };
|
||||||
} else {
|
} else {
|
||||||
this.inputParams.push({...this.editingParam})
|
this.inputParams.push({ ...this.editingParam });
|
||||||
}
|
}
|
||||||
this.editDialogVisible = false
|
this.editDialogVisible = false;
|
||||||
},
|
},
|
||||||
handleEditInputTypeChange() {
|
handleEditInputTypeChange() {
|
||||||
if (this.editingParam.inputType === 'select' && (!this.editingParam.options || this.editingParam.options.length === 0)) {
|
if (this.editingParam.inputType === 'select' && (!this.editingParam.options || this.editingParam.options.length === 0)) {
|
||||||
this.editingParam.options = []
|
this.editingParam.options = [];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
removeOutput(index) {
|
removeOutput(index) {
|
||||||
this.inputParams.splice(index, 1)
|
this.inputParams.splice(index, 1);
|
||||||
},
|
},
|
||||||
updateOutputParams() {
|
updateOutputParams() {
|
||||||
const outputParams = this.inputParams.map(param => ({
|
const outputParams = this.inputParams.map((param) => ({
|
||||||
name: param.type || '',
|
name: param.type || '',
|
||||||
type: param.type || '',
|
type: param.type || '',
|
||||||
value: '',
|
value: '',
|
||||||
required: param.required || false,
|
required: param.required || false,
|
||||||
inputType: param.inputType || 'input',
|
inputType: param.inputType || 'input',
|
||||||
options: param.options || []
|
options: param.options || [],
|
||||||
}))
|
}));
|
||||||
|
|
||||||
if (this.node) {
|
if (this.node) {
|
||||||
this.node.outputParams = outputParams
|
this.node.outputParams = outputParams;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleSave() {
|
handleSave() {
|
||||||
this.$refs.paramForm.validate(async (valid) => {
|
this.$refs.paramForm.validate(async (valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
if (this.editingParam.inputType === 'select') {
|
if (this.editingParam.inputType === 'select') {
|
||||||
this.editingParam.options = [...this.editingParam.editingOptions]
|
this.editingParam.options = [...this.editingParam.editingOptions];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isEdit) {
|
if (this.isEdit) {
|
||||||
this.inputParams[this.editingParamIndex] = {...this.editingParam}
|
this.inputParams[this.editingParamIndex] = { ...this.editingParam };
|
||||||
} else {
|
} else {
|
||||||
this.inputParams.push({...this.editingParam})
|
this.inputParams.push({ ...this.editingParam });
|
||||||
}
|
}
|
||||||
this.editDialogVisible = false
|
this.editDialogVisible = false;
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
addOption() {
|
addOption() {
|
||||||
this.editingParam.editingOptions.push({
|
this.editingParam.editingOptions.push({
|
||||||
label: '',
|
label: '',
|
||||||
value: ''
|
value: '',
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
removeOption(index) {
|
removeOption(index) {
|
||||||
this.editingParam.editingOptions.splice(index, 1)
|
this.editingParam.editingOptions.splice(index, 1);
|
||||||
},
|
},
|
||||||
getInputTypeLabel(type) {
|
getInputTypeLabel(type) {
|
||||||
const found = this.inputTypeDict.find(item => item.value === type)
|
const found = this.inputTypeDict.find((item) => item.value === type);
|
||||||
return found ? found.label : '输入框'
|
return found ? found.label : '输入框';
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
inputParams: {
|
inputParams: {
|
||||||
handler() {
|
handler() {
|
||||||
this.updateOutputParams()
|
this.updateOutputParams();
|
||||||
},
|
},
|
||||||
deep: true
|
deep: true,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@@ -55,12 +55,7 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-tips">
|
<div class="text-tips">
|
||||||
<el-alert
|
<el-alert title="提示:此节点将返回您设置的固定文本内容,可用于流程中的固定消息、说明文字等场景。" type="info" :closable="false" show-icon />
|
||||||
title="提示:此节点将返回您设置的固定文本内容,可用于流程中的固定消息、说明文字等场景。"
|
|
||||||
type="info"
|
|
||||||
:closable="false"
|
|
||||||
show-icon
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ const formatSchema = (schema: any) => {
|
|||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
visible.value = false;
|
visible.value = false;
|
||||||
toolsList.value = [];
|
toolsList.value = [];
|
||||||
Object.keys(mcpInfo).forEach(key => delete mcpInfo[key]);
|
Object.keys(mcpInfo).forEach((key) => delete mcpInfo[key]);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 暴露方法
|
// 暴露方法
|
||||||
|
|||||||
@@ -11,7 +11,9 @@
|
|||||||
rows="2"
|
rows="2"
|
||||||
/>
|
/>
|
||||||
<div class="absolute -bottom-5 right-2 text-xs z-10 bg-white/90 px-2 py-1 rounded">
|
<div class="absolute -bottom-5 right-2 text-xs z-10 bg-white/90 px-2 py-1 rounded">
|
||||||
<a href="https://cloud.siliconflow.cn/i/YKcJJTYP" target="_blank" class="text-blue-500 hover:text-blue-700 no-underline text-xs">获取【硅基流动】 免费 ApiKey</a>
|
<a href="https://cloud.siliconflow.cn/i/YKcJJTYP" target="_blank" class="text-blue-500 hover:text-blue-700 no-underline text-xs"
|
||||||
|
>获取【硅基流动】 免费 ApiKey</a
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
@@ -52,7 +54,7 @@ const loading = ref(false);
|
|||||||
|
|
||||||
// 提交表单数据
|
// 提交表单数据
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
apiKey: ''
|
apiKey: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
// 定义校验规则
|
// 定义校验规则
|
||||||
@@ -75,9 +77,9 @@ const dataRules = ref({
|
|||||||
}
|
}
|
||||||
callback();
|
callback();
|
||||||
},
|
},
|
||||||
trigger: 'blur'
|
trigger: 'blur',
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
// 预览要创建的模型
|
// 预览要创建的模型
|
||||||
@@ -88,7 +90,7 @@ const previewModels = ref([
|
|||||||
modelName: 'moonshotai/Kimi-K2-Instruct',
|
modelName: 'moonshotai/Kimi-K2-Instruct',
|
||||||
name: 'kimi-k2',
|
name: 'kimi-k2',
|
||||||
provider: 'Siliconflow',
|
provider: 'Siliconflow',
|
||||||
baseUrl: 'https://api.siliconflow.cn/v1'
|
baseUrl: 'https://api.siliconflow.cn/v1',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'Chat',
|
type: 'Chat',
|
||||||
@@ -96,7 +98,7 @@ const previewModels = ref([
|
|||||||
modelName: 'deepseek-ai/DeepSeek-V3',
|
modelName: 'deepseek-ai/DeepSeek-V3',
|
||||||
name: 'deepseek-chat',
|
name: 'deepseek-chat',
|
||||||
provider: 'Siliconflow',
|
provider: 'Siliconflow',
|
||||||
baseUrl: 'https://api.siliconflow.cn/v1'
|
baseUrl: 'https://api.siliconflow.cn/v1',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'Embedding',
|
type: 'Embedding',
|
||||||
@@ -104,7 +106,7 @@ const previewModels = ref([
|
|||||||
modelName: 'Qwen/Qwen3-Embedding-8B',
|
modelName: 'Qwen/Qwen3-Embedding-8B',
|
||||||
name: 'qwen-embedding',
|
name: 'qwen-embedding',
|
||||||
provider: 'Siliconflow',
|
provider: 'Siliconflow',
|
||||||
baseUrl: 'https://api.siliconflow.cn/v1'
|
baseUrl: 'https://api.siliconflow.cn/v1',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'Reranker',
|
type: 'Reranker',
|
||||||
@@ -112,7 +114,7 @@ const previewModels = ref([
|
|||||||
modelName: 'Qwen/Qwen3-Reranker-8B',
|
modelName: 'Qwen/Qwen3-Reranker-8B',
|
||||||
name: 'qwen-reranker',
|
name: 'qwen-reranker',
|
||||||
provider: 'Siliconflow',
|
provider: 'Siliconflow',
|
||||||
baseUrl: 'https://api.siliconflow.cn/v1'
|
baseUrl: 'https://api.siliconflow.cn/v1',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'Image',
|
type: 'Image',
|
||||||
@@ -120,7 +122,7 @@ const previewModels = ref([
|
|||||||
modelName: 'Kwai-Kolors/Kolors',
|
modelName: 'Kwai-Kolors/Kolors',
|
||||||
name: 'kolors-image',
|
name: 'kolors-image',
|
||||||
provider: 'Siliconflow',
|
provider: 'Siliconflow',
|
||||||
baseUrl: 'https://api.siliconflow.cn/v1'
|
baseUrl: 'https://api.siliconflow.cn/v1',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'Reason',
|
type: 'Reason',
|
||||||
@@ -128,7 +130,7 @@ const previewModels = ref([
|
|||||||
modelName: 'MiniMaxAI/MiniMax-M1-80k',
|
modelName: 'MiniMaxAI/MiniMax-M1-80k',
|
||||||
name: 'minimax-reason',
|
name: 'minimax-reason',
|
||||||
provider: 'Siliconflow',
|
provider: 'Siliconflow',
|
||||||
baseUrl: 'https://api.siliconflow.cn/v1'
|
baseUrl: 'https://api.siliconflow.cn/v1',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'Vision',
|
type: 'Vision',
|
||||||
@@ -136,7 +138,7 @@ const previewModels = ref([
|
|||||||
modelName: 'Qwen/Qwen2.5-VL-72B-Instruct',
|
modelName: 'Qwen/Qwen2.5-VL-72B-Instruct',
|
||||||
name: 'qwen-vision',
|
name: 'qwen-vision',
|
||||||
provider: 'Siliconflow',
|
provider: 'Siliconflow',
|
||||||
baseUrl: 'https://api.siliconflow.cn/v1'
|
baseUrl: 'https://api.siliconflow.cn/v1',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'Video',
|
type: 'Video',
|
||||||
@@ -144,7 +146,7 @@ const previewModels = ref([
|
|||||||
modelName: 'Wan-AI/Wan2.1-I2V-14B-720P',
|
modelName: 'Wan-AI/Wan2.1-I2V-14B-720P',
|
||||||
name: 'wan-video',
|
name: 'wan-video',
|
||||||
provider: 'Siliconflow',
|
provider: 'Siliconflow',
|
||||||
baseUrl: 'https://api.siliconflow.cn/v1'
|
baseUrl: 'https://api.siliconflow.cn/v1',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'Voice',
|
type: 'Voice',
|
||||||
@@ -152,8 +154,8 @@ const previewModels = ref([
|
|||||||
modelName: 'RVC-Boss/GPT-SoVITS',
|
modelName: 'RVC-Boss/GPT-SoVITS',
|
||||||
name: 'gpt-sovits',
|
name: 'gpt-sovits',
|
||||||
provider: 'Siliconflow',
|
provider: 'Siliconflow',
|
||||||
baseUrl: 'https://api.siliconflow.cn/v1'
|
baseUrl: 'https://api.siliconflow.cn/v1',
|
||||||
}
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// 检查模型名称是否存在
|
// 检查模型名称是否存在
|
||||||
@@ -215,14 +217,14 @@ const onSubmit = async () => {
|
|||||||
...(model.type === 'Chat' && {
|
...(model.type === 'Chat' && {
|
||||||
responseLimit: 2048,
|
responseLimit: 2048,
|
||||||
temperature: 0.4,
|
temperature: 0.4,
|
||||||
topP: 0.7
|
topP: 0.7,
|
||||||
}),
|
}),
|
||||||
// 为Image类型设置默认参数
|
// 为Image类型设置默认参数
|
||||||
...(model.type === 'Image' && {
|
...(model.type === 'Image' && {
|
||||||
imageSize: '1024x1024',
|
imageSize: '1024x1024',
|
||||||
imageQuality: 'standard',
|
imageQuality: 'standard',
|
||||||
imageStyle: 'natural'
|
imageStyle: 'natural',
|
||||||
})
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
await addObj(modelData);
|
await addObj(modelData);
|
||||||
@@ -251,14 +253,14 @@ const onSubmit = async () => {
|
|||||||
|
|
||||||
// 显示跳过的模型信息
|
// 显示跳过的模型信息
|
||||||
if (skipped.length > 0 && skipped.length <= 3) {
|
if (skipped.length > 0 && skipped.length <= 3) {
|
||||||
skipped.forEach(msg => useMessage().warning(msg));
|
skipped.forEach((msg) => useMessage().warning(msg));
|
||||||
} else if (skipped.length > 3) {
|
} else if (skipped.length > 3) {
|
||||||
useMessage().warning(`共跳过${skipCount}个已存在的模型`);
|
useMessage().warning(`共跳过${skipCount}个已存在的模型`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 显示错误信息
|
// 显示错误信息
|
||||||
if (errors.length > 0 && errors.length <= 3) {
|
if (errors.length > 0 && errors.length <= 3) {
|
||||||
errors.forEach(error => useMessage().error(error));
|
errors.forEach((error) => useMessage().error(error));
|
||||||
} else if (errors.length > 3) {
|
} else if (errors.length > 3) {
|
||||||
useMessage().error(`批量创建完成,有${failedCount}个模型创建失败`);
|
useMessage().error(`批量创建完成,有${failedCount}个模型创建失败`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -205,9 +205,7 @@ const availableDimensions = computed(() => {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentModel = availableModels.value.find(model =>
|
const currentModel = availableModels.value.find((model) => model.model === form.modelName && model.type === 'Embedding');
|
||||||
model.model === form.modelName && model.type === 'Embedding'
|
|
||||||
);
|
|
||||||
|
|
||||||
return currentModel?.dimensions || [];
|
return currentModel?.dimensions || [];
|
||||||
});
|
});
|
||||||
@@ -270,8 +268,8 @@ const dataRules = ref({
|
|||||||
}
|
}
|
||||||
callback();
|
callback();
|
||||||
},
|
},
|
||||||
trigger: 'change'
|
trigger: 'change',
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
extData: [{ validator: rule.json, trigger: 'blur' }],
|
extData: [{ validator: rule.json, trigger: 'blur' }],
|
||||||
// ... 其他字段的验证规则 ...
|
// ... 其他字段的验证规则 ...
|
||||||
@@ -374,9 +372,7 @@ watch(
|
|||||||
() => form.modelName,
|
() => form.modelName,
|
||||||
() => {
|
() => {
|
||||||
if (form.modelType === 'Embedding') {
|
if (form.modelType === 'Embedding') {
|
||||||
const currentModel = availableModels.value.find(model =>
|
const currentModel = availableModels.value.find((model) => model.model === form.modelName && model.type === 'Embedding');
|
||||||
model.model === form.modelName && model.type === 'Embedding'
|
|
||||||
);
|
|
||||||
if (currentModel?.dimensions && currentModel.dimensions.length > 0) {
|
if (currentModel?.dimensions && currentModel.dimensions.length > 0) {
|
||||||
form.dimensions = currentModel.dimensions[0].toString();
|
form.dimensions = currentModel.dimensions[0].toString();
|
||||||
} else {
|
} else {
|
||||||
@@ -387,6 +383,4 @@ watch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ const dataRules = {
|
|||||||
prompt: [{ required: true, message: '请输入提示词', trigger: 'blur' }],
|
prompt: [{ required: true, message: '请输入提示词', trigger: 'blur' }],
|
||||||
promptSort: [
|
promptSort: [
|
||||||
{ required: true, message: '请输入列表排序', trigger: 'blur' },
|
{ required: true, message: '请输入列表排序', trigger: 'blur' },
|
||||||
{ type: 'number', message: '列表排序必须为数字', trigger: 'blur' }
|
{ type: 'number', message: '列表排序必须为数字', trigger: 'blur' },
|
||||||
],
|
],
|
||||||
promptStatus: [{ required: true, message: '请选择是否有效', trigger: 'change' }],
|
promptStatus: [{ required: true, message: '请选择是否有效', trigger: 'change' }],
|
||||||
};
|
};
|
||||||
@@ -109,7 +109,7 @@ function getAiPromptData(id: string) {
|
|||||||
const data = res.data;
|
const data = res.data;
|
||||||
Object.assign(form, {
|
Object.assign(form, {
|
||||||
...data,
|
...data,
|
||||||
promptSort: Number(data.promptSort)
|
promptSort: Number(data.promptSort),
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
|
|||||||
@@ -1,12 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-drawer
|
<el-drawer v-model="visible" :close-on-click-modal="true" size="50%" :destroy-on-close="true" direction="rtl" class="document-drawer">
|
||||||
v-model="visible"
|
|
||||||
:close-on-click-modal="true"
|
|
||||||
size="50%"
|
|
||||||
:destroy-on-close="true"
|
|
||||||
direction="rtl"
|
|
||||||
class="document-drawer"
|
|
||||||
>
|
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="flex gap-3 items-center py-1">
|
<div class="flex gap-3 items-center py-1">
|
||||||
<h2 class="max-w-md text-lg font-semibold text-gray-800 truncate">{{ documentTitle }}</h2>
|
<h2 class="max-w-md text-lg font-semibold text-gray-800 truncate">{{ documentTitle }}</h2>
|
||||||
@@ -40,12 +33,7 @@
|
|||||||
已训练
|
已训练
|
||||||
</span>
|
</span>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<svg
|
<svg class="w-4 h-4 mr-1 text-gray-500" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||||
class="w-4 h-4 mr-1 text-gray-500"
|
|
||||||
viewBox="0 0 1024 1024"
|
|
||||||
version="1.1"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
<path
|
||||||
d="M639.2 282.6l80.2-80.6c5.9-5.6 15.3-5.6 20.7 0 2.3 2.3 3.3 4.3 4 6.6V209.2l15 55.7 55.7 15 0.3 0.2h0.2c2.3 0.7 4.7 1.6 6.4 3.8 5.7 5.6 5.7 14.8 0 20.7l-80 80.2c-3.8 3.7-9 5.2-14.4 3.8l-45.1-12-23 23.3c25.1 32 39.8 72.9 39.8 117.2 0 52.5-21.4 100.7-56.2 135.5l-0.7 0.5c-35 34.8-82.4 56-135 56-52.9 0-101.1-21.6-135.7-56.5-34.8-34.8-56.4-83-56.4-135.5 0-53.1 21.6-100.9 56.4-135.9C406 346.4 454.2 325 507.1 325c44.2 0 84.9 14.8 117.3 39.8l23.1-22.8-12.2-45.4c-1.5-4.9 0.2-10.5 3.9-14z"
|
d="M639.2 282.6l80.2-80.6c5.9-5.6 15.3-5.6 20.7 0 2.3 2.3 3.3 4.3 4 6.6V209.2l15 55.7 55.7 15 0.3 0.2h0.2c2.3 0.7 4.7 1.6 6.4 3.8 5.7 5.6 5.7 14.8 0 20.7l-80 80.2c-3.8 3.7-9 5.2-14.4 3.8l-45.1-12-23 23.3c25.1 32 39.8 72.9 39.8 117.2 0 52.5-21.4 100.7-56.2 135.5l-0.7 0.5c-35 34.8-82.4 56-135 56-52.9 0-101.1-21.6-135.7-56.5-34.8-34.8-56.4-83-56.4-135.5 0-53.1 21.6-100.9 56.4-135.9C406 346.4 454.2 325 507.1 325c44.2 0 84.9 14.8 117.3 39.8l23.1-22.8-12.2-45.4c-1.5-4.9 0.2-10.5 3.9-14z"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
@@ -54,12 +42,7 @@
|
|||||||
<span>命中: {{ selectedSlice?.hitCount || 0 }}</span>
|
<span>命中: {{ selectedSlice?.hitCount || 0 }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<svg
|
<svg class="mr-1 w-5 h-5" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||||
class="mr-1 w-5 h-5"
|
|
||||||
viewBox="0 0 1024 1024"
|
|
||||||
version="1.1"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
<path
|
||||||
d="M109.568 99.328s-17.408 15.36 0 38.912 295.936 392.192 295.936 392.192 17.408 15.36 0 35.84-288.768 323.584-288.768 323.584-20.48 32.768 3.072 32.768h733.184s27.648 0 33.792-29.696c7.168-29.696 33.792-154.624 33.792-154.624s0-12.288-10.24-17.408c-10.24-6.144-30.72 0-33.792 9.216-3.072 9.216-92.16 98.304-125.952 104.448h-471.04l237.568-273.408s17.408-12.288 17.408-29.696-23.552-45.056-23.552-45.056L276.48 169.984h458.752s88.064 47.104 146.432 136.192c7.168 9.216 40.96 9.216 40.96 0s-51.2-201.728-51.2-201.728l-761.856-5.12z"
|
d="M109.568 99.328s-17.408 15.36 0 38.912 295.936 392.192 295.936 392.192 17.408 15.36 0 35.84-288.768 323.584-288.768 323.584-20.48 32.768 3.072 32.768h733.184s27.648 0 33.792-29.696c7.168-29.696 33.792-154.624 33.792-154.624s0-12.288-10.24-17.408c-10.24-6.144-30.72 0-33.792 9.216-3.072 9.216-92.16 98.304-125.952 104.448h-471.04l237.568-273.408s17.408-12.288 17.408-29.696-23.552-45.056-23.552-45.056L276.48 169.984h458.752s88.064 47.104 146.432 136.192c7.168 9.216 40.96 9.216 40.96 0s-51.2-201.728-51.2-201.728l-761.856-5.12z"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
@@ -73,7 +56,14 @@
|
|||||||
<el-button size="small" class="flex items-center" type="primary" @click="startEditing(slice)" text>
|
<el-button size="small" class="flex items-center" type="primary" @click="startEditing(slice)" text>
|
||||||
<el-icon class="mr-1"><Edit /></el-icon>编辑
|
<el-icon class="mr-1"><Edit /></el-icon>编辑
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button size="small" class="flex items-center" type="warning" @click="handleRetrain(slice)" text v-if="slice.sliceStatus === '1'">
|
<el-button
|
||||||
|
size="small"
|
||||||
|
class="flex items-center"
|
||||||
|
type="warning"
|
||||||
|
@click="handleRetrain(slice)"
|
||||||
|
text
|
||||||
|
v-if="slice.sliceStatus === '1'"
|
||||||
|
>
|
||||||
<el-icon class="mr-1"><Refresh /></el-icon>重新训练
|
<el-icon class="mr-1"><Refresh /></el-icon>重新训练
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
@@ -94,18 +84,14 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="slices.length === 0" class="text-center py-10 text-gray-500">
|
<div v-if="slices.length === 0" class="text-center py-10 text-gray-500">当前文档暂无切片内容</div>
|
||||||
当前文档暂无切片内容
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-if="loading" class="text-center py-4">
|
<div v-if="loading" class="text-center py-4">
|
||||||
<el-icon class="is-loading"><Loading /></el-icon>
|
<el-icon class="is-loading"><Loading /></el-icon>
|
||||||
<span class="ml-2">加载中...</span>
|
<span class="ml-2">加载中...</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="noMoreData && slices.length > 0" class="text-center py-4 text-gray-400 text-sm">
|
<div v-if="noMoreData && slices.length > 0" class="text-center py-4 text-gray-400 text-sm">没有更多数据了</div>
|
||||||
没有更多数据了
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Add a loading trigger element at the bottom -->
|
<!-- Add a loading trigger element at the bottom -->
|
||||||
<div v-if="!noMoreData && !loading" class="loading-trigger h-10" ref="loadTriggerRef"></div>
|
<div v-if="!noMoreData && !loading" class="loading-trigger h-10" ref="loadTriggerRef"></div>
|
||||||
@@ -126,7 +112,7 @@
|
|||||||
:src="`${baseURL}${other.adaptationUrl('/knowledge/aiDocument/wordcloud')}?documentId=${props.documentId}`"
|
:src="`${baseURL}${other.adaptationUrl('/knowledge/aiDocument/wordcloud')}?documentId=${props.documentId}`"
|
||||||
alt="关键词云图"
|
alt="关键词云图"
|
||||||
class="max-w-full max-h-full object-contain"
|
class="max-w-full max-h-full object-contain"
|
||||||
style="max-height: calc(100vh - 200px);"
|
style="max-height: calc(100vh - 200px)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -149,23 +135,23 @@ import other from '/@/utils/other';
|
|||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
documentId: {
|
documentId: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: '',
|
||||||
},
|
},
|
||||||
sliceId: {
|
sliceId: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: '',
|
||||||
},
|
},
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['update:modelValue']);
|
const emit = defineEmits(['update:modelValue']);
|
||||||
|
|
||||||
const visible = computed({
|
const visible = computed({
|
||||||
get: () => props.modelValue,
|
get: () => props.modelValue,
|
||||||
set: (val) => emit('update:modelValue', val)
|
set: (val) => emit('update:modelValue', val),
|
||||||
});
|
});
|
||||||
|
|
||||||
const documentTitle = ref('文档查看');
|
const documentTitle = ref('文档查看');
|
||||||
@@ -253,7 +239,7 @@ const loadMoreSlices = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 滚动事件处理
|
// 滚动事件处理
|
||||||
const onScroll = ({ scrollTop, scrollHeight, clientHeight }: { scrollTop: number, scrollHeight: number, clientHeight: number }) => {
|
const onScroll = ({ scrollTop, scrollHeight, clientHeight }: { scrollTop: number; scrollHeight: number; clientHeight: number }) => {
|
||||||
// 当滚动到底部附近时加载更多数据
|
// 当滚动到底部附近时加载更多数据
|
||||||
if (scrollHeight - scrollTop - clientHeight < 200 && !loading.value && !noMoreData.value) {
|
if (scrollHeight - scrollTop - clientHeight < 200 && !loading.value && !noMoreData.value) {
|
||||||
loadMoreSlices();
|
loadMoreSlices();
|
||||||
@@ -269,7 +255,7 @@ const { stop: stopObserver } = useIntersectionObserver(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
threshold: 0.1
|
threshold: 0.1,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -323,12 +309,12 @@ const saveContent = async (slice: any) => {
|
|||||||
try {
|
try {
|
||||||
await putObj({
|
await putObj({
|
||||||
...slice,
|
...slice,
|
||||||
content: editingContent.value
|
content: editingContent.value,
|
||||||
});
|
});
|
||||||
useMessage().success('修改成功');
|
useMessage().success('修改成功');
|
||||||
|
|
||||||
// 更新本地数据
|
// 更新本地数据
|
||||||
const index = slices.value.findIndex(s => s.id === slice.id);
|
const index = slices.value.findIndex((s) => s.id === slice.id);
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
slices.value[index].content = editingContent.value;
|
slices.value[index].content = editingContent.value;
|
||||||
}
|
}
|
||||||
@@ -357,7 +343,7 @@ const handleRetrain = async (slice: any) => {
|
|||||||
useMessage().success('已提交重新训练');
|
useMessage().success('已提交重新训练');
|
||||||
|
|
||||||
// 更新本地数据
|
// 更新本地数据
|
||||||
const index = slices.value.findIndex(s => s.id === slice.id);
|
const index = slices.value.findIndex((s) => s.id === slice.id);
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
slices.value[index].sliceStatus = '0';
|
slices.value[index].sliceStatus = '0';
|
||||||
}
|
}
|
||||||
@@ -374,7 +360,7 @@ const handleRetrain = async (slice: any) => {
|
|||||||
// 滚动到指定切片的位置
|
// 滚动到指定切片的位置
|
||||||
const scrollToSlice = async (sliceId: string) => {
|
const scrollToSlice = async (sliceId: string) => {
|
||||||
// 如果没有找到切片,可能需要加载更多数据
|
// 如果没有找到切片,可能需要加载更多数据
|
||||||
if (!slices.value.some(s => s.id === sliceId) && !allSlicesLoaded.value) {
|
if (!slices.value.some((s) => s.id === sliceId) && !allSlicesLoaded.value) {
|
||||||
// 重置并加载所有数据
|
// 重置并加载所有数据
|
||||||
currentPage.value = 1;
|
currentPage.value = 1;
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
@@ -417,7 +403,9 @@ const resetPagination = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 监听 visible 变化
|
// 监听 visible 变化
|
||||||
watch(() => visible.value, (newVal) => {
|
watch(
|
||||||
|
() => visible.value,
|
||||||
|
(newVal) => {
|
||||||
if (newVal && props.documentId) {
|
if (newVal && props.documentId) {
|
||||||
resetPagination();
|
resetPagination();
|
||||||
getDocumentSlices();
|
getDocumentSlices();
|
||||||
@@ -431,32 +419,41 @@ watch(() => visible.value, (newVal) => {
|
|||||||
activeTab.value = 'document';
|
activeTab.value = 'document';
|
||||||
imageError.value = '';
|
imageError.value = '';
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
watch(() => props.documentId, (newVal) => {
|
watch(
|
||||||
|
() => props.documentId,
|
||||||
|
(newVal) => {
|
||||||
if (newVal && visible.value) {
|
if (newVal && visible.value) {
|
||||||
resetPagination();
|
resetPagination();
|
||||||
getDocumentSlices();
|
getDocumentSlices();
|
||||||
// 重置图片错误状态
|
// 重置图片错误状态
|
||||||
imageError.value = '';
|
imageError.value = '';
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
watch(() => props.sliceId, (newVal) => {
|
watch(
|
||||||
|
() => props.sliceId,
|
||||||
|
(newVal) => {
|
||||||
if (newVal && visible.value) {
|
if (newVal && visible.value) {
|
||||||
selectedSliceId.value = newVal;
|
selectedSliceId.value = newVal;
|
||||||
scrollToSlice(newVal);
|
scrollToSlice(newVal);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// Watch slices to update selectedSlice when data is loaded
|
// Watch slices to update selectedSlice when data is loaded
|
||||||
watch(() => slices.value, (newSlices) => {
|
watch(
|
||||||
|
() => slices.value,
|
||||||
|
(newSlices) => {
|
||||||
if (selectedSliceId.value && newSlices.length > 0) {
|
if (selectedSliceId.value && newSlices.length > 0) {
|
||||||
const slice = newSlices.find(s => s.id === selectedSliceId.value);
|
const slice = newSlices.find((s) => s.id === selectedSliceId.value);
|
||||||
if (slice) {
|
if (slice) {
|
||||||
selectedSlice.value = slice;
|
selectedSlice.value = slice;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
@@ -1,14 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog :title="form.id ? '编辑' : '新增'" v-model="visible"
|
<el-dialog :title="form.id ? '编辑' : '新增'" v-model="visible" :close-on-click-modal="false" draggable>
|
||||||
:close-on-click-modal="false" draggable>
|
|
||||||
<el-form ref="dataFormRef" :model="form" :rules="dataRules" formDialogRef label-width="90px" v-loading="loading">
|
<el-form ref="dataFormRef" :model="form" :rules="dataRules" formDialogRef label-width="90px" v-loading="loading">
|
||||||
|
|
||||||
|
|
||||||
<el-form-item label="内容" prop="content">
|
<el-form-item label="内容" prop="content">
|
||||||
<editor v-model:get-html="form.content" height="500" width="600"/>
|
<editor v-model:get-html="form.content" height="500" width="600" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
@@ -20,17 +15,17 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="AiSliceDialog">
|
<script setup lang="ts" name="AiSliceDialog">
|
||||||
import {useDict} from '/@/hooks/dict';
|
import { useDict } from '/@/hooks/dict';
|
||||||
import {useMessage} from "/@/hooks/message";
|
import { useMessage } from '/@/hooks/message';
|
||||||
import {getObj, addObj, putObj} from '/@/api/knowledge/aiSlice'
|
import { getObj, addObj, putObj } from '/@/api/knowledge/aiSlice';
|
||||||
import {rule} from '/@/utils/validate';
|
import { rule } from '/@/utils/validate';
|
||||||
|
|
||||||
const emit = defineEmits(['refresh']);
|
const emit = defineEmits(['refresh']);
|
||||||
|
|
||||||
// 定义变量内容
|
// 定义变量内容
|
||||||
const dataFormRef = ref();
|
const dataFormRef = ref();
|
||||||
const visible = ref(false)
|
const visible = ref(false);
|
||||||
const loading = ref(false)
|
const loading = ref(false);
|
||||||
// 定义字典
|
// 定义字典
|
||||||
|
|
||||||
// 提交表单数据
|
// 提交表单数据
|
||||||
@@ -46,18 +41,21 @@ const form = reactive({
|
|||||||
|
|
||||||
// 定义校验规则
|
// 定义校验规则
|
||||||
const dataRules = ref({
|
const dataRules = ref({
|
||||||
content: [{required: true, message: '内容不能为空', trigger: 'blur'}, {
|
content: [
|
||||||
|
{ required: true, message: '内容不能为空', trigger: 'blur' },
|
||||||
|
{
|
||||||
min: 100,
|
min: 100,
|
||||||
max: 1500,
|
max: 1500,
|
||||||
message: '文本长度在 100 - 1500 之间',
|
message: '文本长度在 100 - 1500 之间',
|
||||||
trigger: 'blur',
|
trigger: 'blur',
|
||||||
}]
|
},
|
||||||
})
|
],
|
||||||
|
});
|
||||||
|
|
||||||
// 打开弹窗
|
// 打开弹窗
|
||||||
const openDialog = (id: string) => {
|
const openDialog = (id: string) => {
|
||||||
visible.value = true
|
visible.value = true;
|
||||||
form.id = ''
|
form.id = '';
|
||||||
|
|
||||||
// 重置表单数据
|
// 重置表单数据
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
@@ -66,15 +64,14 @@ const openDialog = (id: string) => {
|
|||||||
|
|
||||||
// 获取aiSlice信息
|
// 获取aiSlice信息
|
||||||
if (id) {
|
if (id) {
|
||||||
form.id = id
|
form.id = id;
|
||||||
getaiSliceData(id)
|
getaiSliceData(id);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 提交
|
// 提交
|
||||||
const onSubmit = async () => {
|
const onSubmit = async () => {
|
||||||
const valid = await dataFormRef.value.validate().catch(() => {
|
const valid = await dataFormRef.value.validate().catch(() => {});
|
||||||
});
|
|
||||||
if (!valid) return false;
|
if (!valid) return false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -90,20 +87,21 @@ const onSubmit = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// 初始化表单数据
|
// 初始化表单数据
|
||||||
const getaiSliceData = (id: string) => {
|
const getaiSliceData = (id: string) => {
|
||||||
// 获取数据
|
// 获取数据
|
||||||
loading.value = true
|
loading.value = true;
|
||||||
getObj(id).then((res: any) => {
|
getObj(id)
|
||||||
Object.assign(form, res.data)
|
.then((res: any) => {
|
||||||
}).finally(() => {
|
Object.assign(form, res.data);
|
||||||
loading.value = false
|
|
||||||
})
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 暴露变量
|
// 暴露变量
|
||||||
defineExpose({
|
defineExpose({
|
||||||
openDialog
|
openDialog,
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -269,7 +269,7 @@ const saveContent = async (slice: any) => {
|
|||||||
try {
|
try {
|
||||||
await putObj({
|
await putObj({
|
||||||
...slice,
|
...slice,
|
||||||
content: editingContent.value
|
content: editingContent.value,
|
||||||
});
|
});
|
||||||
useMessage().success('修改成功');
|
useMessage().success('修改成功');
|
||||||
getDataList();
|
getDataList();
|
||||||
|
|||||||
@@ -1,17 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<transition name="el-zoom-in-center">
|
<transition name="el-zoom-in-center">
|
||||||
<div
|
<div v-show="isShow" class="el-dropdown__popper el-popper is-light is-pure custom-contextmenu" :style="`top: ${y}px; left: ${x}px;`">
|
||||||
v-show="isShow"
|
|
||||||
class="el-dropdown__popper el-popper is-light is-pure custom-contextmenu"
|
|
||||||
:style="`top: ${y}px; left: ${x}px;`"
|
|
||||||
>
|
|
||||||
<ul class="el-dropdown-menu">
|
<ul class="el-dropdown-menu">
|
||||||
<li
|
<li v-for="item in menuItems" :key="item.text" class="el-dropdown-menu__item" @click="handleItemClick(item)">
|
||||||
v-for="item in menuItems"
|
|
||||||
:key="item.text"
|
|
||||||
class="el-dropdown-menu__item"
|
|
||||||
@click="handleItemClick(item)"
|
|
||||||
>
|
|
||||||
<el-icon><component :is="item.icon" /></el-icon>
|
<el-icon><component :is="item.icon" /></el-icon>
|
||||||
<span>{{ item.text }}</span>
|
<span>{{ item.text }}</span>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -1,21 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog
|
<el-dialog v-model="dialogVisible" title="标记信息" width="30%" :close-on-click-modal="false">
|
||||||
v-model="dialogVisible"
|
|
||||||
title="标记信息"
|
|
||||||
width="30%"
|
|
||||||
:close-on-click-modal="false"
|
|
||||||
>
|
|
||||||
<el-form :model="form" :rules="rules" ref="formRef">
|
<el-form :model="form" :rules="rules" ref="formRef">
|
||||||
<el-form-item prop="name" label="字段名" :label-width="formLabelWidth">
|
<el-form-item prop="name" label="字段名" :label-width="formLabelWidth">
|
||||||
<el-input v-model="form.name" autocomplete="off"></el-input>
|
<el-input v-model="form.name" autocomplete="off"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="description" label="字段描述" :label-width="formLabelWidth">
|
<el-form-item prop="description" label="字段描述" :label-width="formLabelWidth">
|
||||||
<el-input
|
<el-input v-model="form.description" type="textarea" :rows="4" placeholder="请输入描述"></el-input>
|
||||||
v-model="form.description"
|
|
||||||
type="textarea"
|
|
||||||
:rows="4"
|
|
||||||
placeholder="请输入描述"
|
|
||||||
></el-input>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@@ -28,7 +18,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {rule} from "/@/utils/validate";
|
import { rule } from '/@/utils/validate';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
initialName: String,
|
initialName: String,
|
||||||
@@ -41,19 +31,19 @@ const dialogVisible = ref(false);
|
|||||||
const formRef = ref(null);
|
const formRef = ref(null);
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
name: props.initialName || '',
|
name: props.initialName || '',
|
||||||
description: props.initialDescription || ''
|
description: props.initialDescription || '',
|
||||||
});
|
});
|
||||||
|
|
||||||
const rules = {
|
const rules = {
|
||||||
name: [
|
name: [
|
||||||
{required: true, message: '请输入属性名', trigger: 'blur'},
|
{ required: true, message: '请输入属性名', trigger: 'blur' },
|
||||||
{validator: rule.overLength, trigger: 'blur'},
|
{ validator: rule.overLength, trigger: 'blur' },
|
||||||
{validator: rule.validatorLowercase, trigger: 'blur'}
|
{ validator: rule.validatorLowercase, trigger: 'blur' },
|
||||||
],
|
],
|
||||||
description: [
|
description: [
|
||||||
{required: true, message: '请输入描述', trigger: 'blur'},
|
{ required: true, message: '请输入描述', trigger: 'blur' },
|
||||||
{validator: rule.overLength, trigger: 'blur'},
|
{ validator: rule.overLength, trigger: 'blur' },
|
||||||
]
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
const formLabelWidth = '80px';
|
const formLabelWidth = '80px';
|
||||||
@@ -61,7 +51,7 @@ const formLabelWidth = '80px';
|
|||||||
const submitForm = () => {
|
const submitForm = () => {
|
||||||
formRef.value.validate((valid) => {
|
formRef.value.validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
emit('submit', {name: form.name, description: form.description});
|
emit('submit', { name: form.name, description: form.description });
|
||||||
closeDialog();
|
closeDialog();
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@@ -80,5 +70,5 @@ const showDialog = (name, description) => {
|
|||||||
dialogVisible.value = true;
|
dialogVisible.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
defineExpose({showDialog});
|
defineExpose({ showDialog });
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog :title="form.id ? '编辑' : '新增'" v-model="visible"
|
<el-dialog :title="form.id ? '编辑' : '新增'" v-model="visible" :close-on-click-modal="false" draggable>
|
||||||
:close-on-click-modal="false" draggable>
|
|
||||||
<el-form ref="dataFormRef" :model="form" :rules="dataRules" formDialogRef label-width="90px" v-loading="loading">
|
<el-form ref="dataFormRef" :model="form" :rules="dataRules" formDialogRef label-width="90px" v-loading="loading">
|
||||||
<el-form-item label="标题" prop="ocrTitle">
|
<el-form-item label="标题" prop="ocrTitle">
|
||||||
<el-input v-model="form.ocrTitle" placeholder="请输入标题"/>
|
<el-input v-model="form.ocrTitle" placeholder="请输入标题" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="描述" prop="ocrPrompt">
|
<el-form-item label="描述" prop="ocrPrompt">
|
||||||
<el-input type="textarea" :rows="5" v-model="form.ocrPrompt" placeholder="请输入描述提示词"/>
|
<el-input type="textarea" :rows="5" v-model="form.ocrPrompt" placeholder="请输入描述提示词" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
@@ -21,17 +19,17 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="AiOcrConfDialog">
|
<script setup lang="ts" name="AiOcrConfDialog">
|
||||||
import {useDict} from '/@/hooks/dict';
|
import { useDict } from '/@/hooks/dict';
|
||||||
import {useMessage} from "/@/hooks/message";
|
import { useMessage } from '/@/hooks/message';
|
||||||
import {getObj, addObj, putObj, validateExist} from '/@/api/knowledge/ocr'
|
import { getObj, addObj, putObj, validateExist } from '/@/api/knowledge/ocr';
|
||||||
import {rule} from '/@/utils/validate';
|
import { rule } from '/@/utils/validate';
|
||||||
|
|
||||||
const emit = defineEmits(['refresh']);
|
const emit = defineEmits(['refresh']);
|
||||||
|
|
||||||
// 定义变量内容
|
// 定义变量内容
|
||||||
const dataFormRef = ref();
|
const dataFormRef = ref();
|
||||||
const visible = ref(false)
|
const visible = ref(false);
|
||||||
const loading = ref(false)
|
const loading = ref(false);
|
||||||
// 定义字典
|
// 定义字典
|
||||||
|
|
||||||
// 提交表单数据
|
// 提交表单数据
|
||||||
@@ -46,19 +44,19 @@ const form = reactive({
|
|||||||
// 定义校验规则
|
// 定义校验规则
|
||||||
const dataRules = {
|
const dataRules = {
|
||||||
ocrTitle: [
|
ocrTitle: [
|
||||||
{required: true, message: '请输入功能名称', trigger: 'blur'},
|
{ required: true, message: '请输入功能名称', trigger: 'blur' },
|
||||||
{validator: rule.overLength, trigger: 'blur'}
|
{ validator: rule.overLength, trigger: 'blur' },
|
||||||
],
|
],
|
||||||
ocrPrompt: [
|
ocrPrompt: [
|
||||||
{required: true, message: '请输入提示词描述', trigger: 'blur'},
|
{ required: true, message: '请输入提示词描述', trigger: 'blur' },
|
||||||
{validator: rule.overLength, trigger: 'blur'},
|
{ validator: rule.overLength, trigger: 'blur' },
|
||||||
]
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开弹窗
|
// 打开弹窗
|
||||||
const openDialog = (id: string) => {
|
const openDialog = (id: string) => {
|
||||||
visible.value = true
|
visible.value = true;
|
||||||
form.id = ''
|
form.id = '';
|
||||||
|
|
||||||
// 重置表单数据
|
// 重置表单数据
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
@@ -67,15 +65,14 @@ const openDialog = (id: string) => {
|
|||||||
|
|
||||||
// 获取aiOcrConf信息
|
// 获取aiOcrConf信息
|
||||||
if (id) {
|
if (id) {
|
||||||
form.id = id
|
form.id = id;
|
||||||
getAiOcrConfData(id)
|
getAiOcrConfData(id);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 提交
|
// 提交
|
||||||
const onSubmit = async () => {
|
const onSubmit = async () => {
|
||||||
const valid = await dataFormRef.value.validate().catch(() => {
|
const valid = await dataFormRef.value.validate().catch(() => {});
|
||||||
});
|
|
||||||
if (!valid) return false;
|
if (!valid) return false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -91,20 +88,21 @@ const onSubmit = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// 初始化表单数据
|
// 初始化表单数据
|
||||||
const getAiOcrConfData = (id: string) => {
|
const getAiOcrConfData = (id: string) => {
|
||||||
// 获取数据
|
// 获取数据
|
||||||
loading.value = true
|
loading.value = true;
|
||||||
getObj({id: id}).then((res: any) => {
|
getObj({ id: id })
|
||||||
Object.assign(form, res.data[0])
|
.then((res: any) => {
|
||||||
}).finally(() => {
|
Object.assign(form, res.data[0]);
|
||||||
loading.value = false
|
|
||||||
})
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 暴露变量
|
// 暴露变量
|
||||||
defineExpose({
|
defineExpose({
|
||||||
openDialog
|
openDialog,
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
<script setup lang="ts" name="authredirect">
|
<script setup lang="ts" name="authredirect">
|
||||||
import request from '/@/utils/request';
|
import request from '/@/utils/request';
|
||||||
import other from '/@/utils/other';
|
import other from '/@/utils/other';
|
||||||
import {validateNull} from '/@/utils/validate';
|
import { validateNull } from '/@/utils/validate';
|
||||||
import {Session} from '/@/utils/storage';
|
import { Session } from '/@/utils/storage';
|
||||||
import {useUserInfo} from '/@/stores/userInfo';
|
import { useUserInfo } from '/@/stores/userInfo';
|
||||||
import {useMessageBox} from '/@/hooks/message';
|
import { useMessageBox } from '/@/hooks/message';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载完成后执行的函数,用于处理授权回调。
|
* 加载完成后执行的函数,用于处理授权回调。
|
||||||
|
|||||||
@@ -1,23 +1,26 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-form size="large" class="login-content-form" :rules="dataRules" ref="dataFormRef" :model="passwordFormData">
|
<el-form size="large" class="login-content-form" :rules="dataRules" ref="dataFormRef" :model="passwordFormData">
|
||||||
<el-form-item class="login-animation1" prop="username">
|
<el-form-item class="login-animation1" prop="username">
|
||||||
<el-input text :placeholder="$t('password.accountPlaceholder1')" disabled v-model="passwordFormData.username"
|
<el-input text :placeholder="$t('password.accountPlaceholder1')" disabled v-model="passwordFormData.username" clearable autocomplete="off">
|
||||||
clearable
|
|
||||||
autocomplete="off">
|
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<el-icon class="el-input__icon">
|
<el-icon class="el-input__icon">
|
||||||
<ele-User/>
|
<ele-User />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item class="login-animation1" prop="password">
|
<el-form-item class="login-animation1" prop="password">
|
||||||
<el-input text :placeholder="$t('expire.oldPassword')" v-model="passwordFormData.password" clearable
|
<el-input
|
||||||
|
text
|
||||||
|
:placeholder="$t('expire.oldPassword')"
|
||||||
|
v-model="passwordFormData.password"
|
||||||
|
clearable
|
||||||
:type="showPassword ? 'text' : 'password'"
|
:type="showPassword ? 'text' : 'password'"
|
||||||
autocomplete="off">
|
autocomplete="off"
|
||||||
|
>
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<el-icon class="el-input__icon">
|
<el-icon class="el-input__icon">
|
||||||
<ele-Unlock/>
|
<ele-Unlock />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
</template>
|
</template>
|
||||||
<template #suffix>
|
<template #suffix>
|
||||||
@@ -41,7 +44,7 @@
|
|||||||
>
|
>
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<el-icon class="el-input__icon">
|
<el-icon class="el-input__icon">
|
||||||
<ele-Unlock/>
|
<ele-Unlock />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
</template>
|
</template>
|
||||||
</strength-meter>
|
</strength-meter>
|
||||||
@@ -58,32 +61,25 @@
|
|||||||
>
|
>
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<el-icon class="el-input__icon">
|
<el-icon class="el-input__icon">
|
||||||
<ele-Unlock/>
|
<ele-Unlock />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
</template>
|
</template>
|
||||||
</strength-meter>
|
</strength-meter>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item class="login-animation4">
|
<el-form-item class="login-animation4">
|
||||||
<el-button
|
<el-button type="primary" class="rounded-lg login-content-submit" v-waves @click="handleResetPassword" :loading="loading">
|
||||||
type="primary"
|
|
||||||
class="rounded-lg login-content-submit"
|
|
||||||
v-waves
|
|
||||||
@click="handleResetPassword"
|
|
||||||
:loading="loading"
|
|
||||||
>
|
|
||||||
<span class="font-semibold tracking-wide">{{ $t('password.resetBtnText') }}</span>
|
<span class="font-semibold tracking-wide">{{ $t('password.resetBtnText') }}</span>
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
</el-form>
|
</el-form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="expire">
|
<script setup lang="ts" name="expire">
|
||||||
import {resetUserPassword} from '/@/api/admin/user';
|
import { resetUserPassword } from '/@/api/admin/user';
|
||||||
import {useMessage} from '/@/hooks/message';
|
import { useMessage } from '/@/hooks/message';
|
||||||
import {useI18n} from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import {LoginTypeEnum} from "/@/api/login";
|
import { LoginTypeEnum } from '/@/api/login';
|
||||||
import type { FormInstance } from 'element-plus';
|
import type { FormInstance } from 'element-plus';
|
||||||
|
|
||||||
// 注册生命周期事件
|
// 注册生命周期事件
|
||||||
@@ -93,7 +89,7 @@ const emit = defineEmits(['afterSuccess', 'change']);
|
|||||||
const StrengthMeter = defineAsyncComponent(() => import('/@/components/StrengthMeter/index.vue'));
|
const StrengthMeter = defineAsyncComponent(() => import('/@/components/StrengthMeter/index.vue'));
|
||||||
|
|
||||||
// 使用i18n
|
// 使用i18n
|
||||||
const {t} = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
// 表单引用
|
// 表单引用
|
||||||
const dataFormRef = ref<FormInstance | null>(null);
|
const dataFormRef = ref<FormInstance | null>(null);
|
||||||
@@ -134,7 +130,7 @@ const validatorScore = (rule: any, value: any, callback: any) => {
|
|||||||
|
|
||||||
// 表单验证规则
|
// 表单验证规则
|
||||||
const dataRules = reactive({
|
const dataRules = reactive({
|
||||||
password: [{required: true, message: t('expire.oldPassword'), trigger: 'blur'}],
|
password: [{ required: true, message: t('expire.oldPassword'), trigger: 'blur' }],
|
||||||
newpassword1: [
|
newpassword1: [
|
||||||
{
|
{
|
||||||
min: 6,
|
min: 6,
|
||||||
@@ -142,7 +138,7 @@ const dataRules = reactive({
|
|||||||
message: t('register.passwordLength'),
|
message: t('register.passwordLength'),
|
||||||
trigger: 'blur',
|
trigger: 'blur',
|
||||||
},
|
},
|
||||||
{validator: validatorScore, trigger: 'blur'},
|
{ validator: validatorScore, trigger: 'blur' },
|
||||||
],
|
],
|
||||||
newpassword2: [
|
newpassword2: [
|
||||||
{
|
{
|
||||||
@@ -151,8 +147,8 @@ const dataRules = reactive({
|
|||||||
message: t('register.passwordLength'),
|
message: t('register.passwordLength'),
|
||||||
trigger: 'blur',
|
trigger: 'blur',
|
||||||
},
|
},
|
||||||
{validator: validatorPassword2, trigger: 'blur'},
|
{ validator: validatorPassword2, trigger: 'blur' },
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
// 处理密码强度得分变化事件
|
// 处理密码强度得分变化事件
|
||||||
|
|||||||
@@ -64,14 +64,14 @@
|
|||||||
>
|
>
|
||||||
{{ $t('mobile.backToLogin') }}
|
{{ $t('mobile.backToLogin') }}
|
||||||
</a>
|
</a>
|
||||||
<!-- <a-->
|
<!-- <a-->
|
||||||
<!-- href="#"-->
|
<!-- href="#"-->
|
||||||
<!-- v-if="autoRegisterEnable"-->
|
<!-- v-if="autoRegisterEnable"-->
|
||||||
<!-- class="ml-2 text-blue-500 hover:text-blue-400 dark:text-blue-400 dark:hover:text-blue-300"-->
|
<!-- class="ml-2 text-blue-500 hover:text-blue-400 dark:text-blue-400 dark:hover:text-blue-300"-->
|
||||||
<!-- @click="emit('change', LoginTypeEnum.REGISTER)"-->
|
<!-- @click="emit('change', LoginTypeEnum.REGISTER)"-->
|
||||||
<!-- >-->
|
<!-- >-->
|
||||||
<!-- {{ $t('mobile.createAccount') }}-->
|
<!-- {{ $t('mobile.createAccount') }}-->
|
||||||
<!-- </a>-->
|
<!-- </a>-->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -67,9 +67,9 @@
|
|||||||
<a href="#" class="text-blue-500" @click="emit('change', LoginTypeEnum.MOBILE)">
|
<a href="#" class="text-blue-500" @click="emit('change', LoginTypeEnum.MOBILE)">
|
||||||
{{ $t('password.mobileLogin') }}
|
{{ $t('password.mobileLogin') }}
|
||||||
</a>
|
</a>
|
||||||
<!-- <a href="#" v-if="autoRegisterEnable" class="ml-2 text-blue-500" @click="emit('change', LoginTypeEnum.REGISTER)">-->
|
<!-- <a href="#" v-if="autoRegisterEnable" class="ml-2 text-blue-500" @click="emit('change', LoginTypeEnum.REGISTER)">-->
|
||||||
<!-- {{ $t('password.createAccount') }}-->
|
<!-- {{ $t('password.createAccount') }}-->
|
||||||
<!-- </a>-->
|
<!-- </a>-->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="fixed bottom-0 right-0 z-10 flex flex-col items-center mb-16 w-[160px]">
|
<div class="fixed bottom-0 right-0 z-10 flex flex-col items-center mb-16 w-[160px]">
|
||||||
<!-- <div class="group">-->
|
<!-- <div class="group">-->
|
||||||
<!-- <div class="relative transition-transform duration-300 transform group-hover:scale-110 group-hover:-translate-y-1">-->
|
<!-- <div class="relative transition-transform duration-300 transform group-hover:scale-110 group-hover:-translate-y-1">-->
|
||||||
<!-- <img-->
|
<!-- <img-->
|
||||||
<!-- class="w-24 h-24 rounded-lg ring-gray-200 dark:ring-slate-700 dark:bg-slate-800"-->
|
<!-- class="w-24 h-24 rounded-lg ring-gray-200 dark:ring-slate-700 dark:bg-slate-800"-->
|
||||||
<!-- :src="!themeConfig.miniQr ? miniQr : baseURL + themeConfig.miniQr"-->
|
<!-- :src="!themeConfig.miniQr ? miniQr : baseURL + themeConfig.miniQr"-->
|
||||||
<!-- :alt="t('scan.wechatApp')"-->
|
<!-- :alt="t('scan.wechatApp')"-->
|
||||||
<!-- />-->
|
<!-- />-->
|
||||||
<!-- </div>-->
|
<!-- </div>-->
|
||||||
<!-- <!– 底部文字 –>-->
|
<!-- <!– 底部文字 –>-->
|
||||||
<!-- <div class="mt-2">-->
|
<!-- <div class="mt-2">-->
|
||||||
<!-- <p class="text-xs text-gray-400 dark:text-slate-500">{{ t('scan.wechatApp') }}</p>-->
|
<!-- <p class="text-xs text-gray-400 dark:text-slate-500">{{ t('scan.wechatApp') }}</p>-->
|
||||||
<!-- </div>-->
|
<!-- </div>-->
|
||||||
<!-- </div>-->
|
<!-- </div>-->
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ onMounted(async () => {
|
|||||||
|
|
||||||
// 获取当前租户名称
|
// 获取当前租户名称
|
||||||
const getCurrentTenantName = computed(() => {
|
const getCurrentTenantName = computed(() => {
|
||||||
const current = tenantList.value.find(item => item.id === tenant.value);
|
const current = tenantList.value.find((item) => item.id === tenant.value);
|
||||||
return current?.name || t('tenantSelect.select');
|
return current?.name || t('tenantSelect.select');
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -37,14 +37,14 @@
|
|||||||
<expire v-if="loginType === LoginTypeEnum.EXPIRE" :username="username" @change="changeLoginType" />
|
<expire v-if="loginType === LoginTypeEnum.EXPIRE" :username="username" @change="changeLoginType" />
|
||||||
|
|
||||||
<!-- 分割线 -->
|
<!-- 分割线 -->
|
||||||
<!-- <div class="flex justify-center items-center my-6 space-x-3">-->
|
<!-- <div class="flex justify-center items-center my-6 space-x-3">-->
|
||||||
<!-- <span class="w-20 h-[1.5px] bg-gray-200 dark:bg-slate-600"></span>-->
|
<!-- <span class="w-20 h-[1.5px] bg-gray-200 dark:bg-slate-600"></span>-->
|
||||||
<!-- <span class="text-gray-600 dark:text-slate-400">{{ $t('divider.or') }}</span>-->
|
<!-- <span class="text-gray-600 dark:text-slate-400">{{ $t('divider.or') }}</span>-->
|
||||||
<!-- <span class="w-20 h-[1.5px] bg-gray-200 dark:bg-slate-600"></span>-->
|
<!-- <span class="w-20 h-[1.5px] bg-gray-200 dark:bg-slate-600"></span>-->
|
||||||
<!-- </div>-->
|
<!-- </div>-->
|
||||||
|
|
||||||
<!-- 社交登录 -->
|
<!-- 社交登录 -->
|
||||||
<!-- <social @signInSuccess="signInSuccess" />-->
|
<!-- <social @signInSuccess="signInSuccess" />-->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,44 +1,58 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-form ref="dataFormRef" :model="form" :rules="dataRules" label-width="90px" v-loading="loading"
|
<el-form ref="dataFormRef" :model="form" :rules="dataRules" label-width="90px" v-loading="loading" :disabled="operType === 'view'">
|
||||||
:disabled="operType === 'view'">
|
|
||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<el-col :span="12" class="mb20" v-if="!hiddenFields.type">
|
<el-col :span="12" class="mb20" v-if="!hiddenFields.type">
|
||||||
<el-form-item :label="t('askLeave.type')" prop="type">
|
<el-form-item :label="t('askLeave.type')" prop="type">
|
||||||
<el-input v-model="form.type" :placeholder="t('askLeave.inputTypeTip')" :disabled="disabledFields.type"/>
|
<el-input v-model="form.type" :placeholder="t('askLeave.inputTypeTip')" :disabled="disabledFields.type" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20" v-if="!hiddenFields.startTime">
|
<el-col :span="12" class="mb20" v-if="!hiddenFields.startTime">
|
||||||
<el-form-item :label="t('askLeave.startTime')" prop="startTime">
|
<el-form-item :label="t('askLeave.startTime')" prop="startTime">
|
||||||
<el-date-picker type="datetime" :placeholder="t('askLeave.inputStartTimeTip')" :disabled="disabledFields.startTime"
|
<el-date-picker
|
||||||
v-model="form.startTime" :value-format="dateTimeStr"></el-date-picker>
|
type="datetime"
|
||||||
|
:placeholder="t('askLeave.inputStartTimeTip')"
|
||||||
|
:disabled="disabledFields.startTime"
|
||||||
|
v-model="form.startTime"
|
||||||
|
:value-format="dateTimeStr"
|
||||||
|
></el-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20" v-if="!hiddenFields.endTime">
|
<el-col :span="12" class="mb20" v-if="!hiddenFields.endTime">
|
||||||
<el-form-item :label="t('askLeave.endTime')" prop="endTime">
|
<el-form-item :label="t('askLeave.endTime')" prop="endTime">
|
||||||
<el-date-picker type="datetime" :placeholder="t('askLeave.inputEndTimeTip')" :disabled="disabledFields.endTime"
|
<el-date-picker
|
||||||
v-model="form.endTime" :value-format="dateTimeStr"></el-date-picker>
|
type="datetime"
|
||||||
|
:placeholder="t('askLeave.inputEndTimeTip')"
|
||||||
|
:disabled="disabledFields.endTime"
|
||||||
|
v-model="form.endTime"
|
||||||
|
:value-format="dateTimeStr"
|
||||||
|
></el-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20" v-if="!hiddenFields.days">
|
<el-col :span="12" class="mb20" v-if="!hiddenFields.days">
|
||||||
<el-form-item :label="t('askLeave.days')" prop="days">
|
<el-form-item :label="t('askLeave.days')" prop="days">
|
||||||
<el-input v-model="form.days" :placeholder="t('askLeave.inputDaysTip')" :disabled="disabledFields.days"/>
|
<el-input v-model="form.days" :placeholder="t('askLeave.inputDaysTip')" :disabled="disabledFields.days" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20" v-if="!hiddenFields.carbonCopyPerson">
|
<el-col :span="12" class="mb20" v-if="!hiddenFields.carbonCopyPerson">
|
||||||
<el-form-item :label="t('askLeave.carbonCopyPerson')" prop="carbonCopyPerson">
|
<el-form-item :label="t('askLeave.carbonCopyPerson')" prop="carbonCopyPerson">
|
||||||
<el-tooltip content="请输入用户名称进行模糊搜索" placement="top">
|
<el-tooltip content="请输入用户名称进行模糊搜索" placement="top">
|
||||||
<el-select v-model="form.carbonCopyPerson" :placeholder="t('askLeave.inputCarbonCopyPersonTip')" :disabled="disabledFields.carbonCopyPerson"
|
<el-select
|
||||||
remote :remote-method="remoteMethod" :reserve-keyword="false"
|
v-model="form.carbonCopyPerson"
|
||||||
clearable filterable multiple>
|
:placeholder="t('askLeave.inputCarbonCopyPersonTip')"
|
||||||
<el-option v-for="(item, index) in dicData.carbonCopyPerson" :key="index" :label="item.name"
|
:disabled="disabledFields.carbonCopyPerson"
|
||||||
:value="item.userId">
|
remote
|
||||||
|
:remote-method="remoteMethod"
|
||||||
</el-option>
|
:reserve-keyword="false"
|
||||||
|
clearable
|
||||||
|
filterable
|
||||||
|
multiple
|
||||||
|
>
|
||||||
|
<el-option v-for="(item, index) in dicData.carbonCopyPerson" :key="index" :label="item.name" :value="item.userId"> </el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -46,25 +60,21 @@
|
|||||||
|
|
||||||
<el-col :span="12" class="mb20" v-if="!hiddenFields.remark">
|
<el-col :span="12" class="mb20" v-if="!hiddenFields.remark">
|
||||||
<el-form-item :label="t('askLeave.remark')" prop="remark">
|
<el-form-item :label="t('askLeave.remark')" prop="remark">
|
||||||
<el-input v-model="form.remark" type="textarea" :placeholder="t('askLeave.inputRemarkTip')" :disabled="disabledFields.remark"/>
|
<el-input v-model="form.remark" type="textarea" :placeholder="t('askLeave.inputRemarkTip')" :disabled="disabledFields.remark" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20" v-if="!hiddenFields.imgUrls">
|
<el-col :span="12" class="mb20" v-if="!hiddenFields.imgUrls">
|
||||||
<el-form-item :label="t('askLeave.imgUrls')" prop="imgUrls">
|
<el-form-item :label="t('askLeave.imgUrls')" prop="imgUrls">
|
||||||
<el-input v-model="form.imgUrls" :placeholder="t('askLeave.inputImgUrlsTip')" :disabled="disabledFields.imgUrls"/>
|
<el-input v-model="form.imgUrls" :placeholder="t('askLeave.inputImgUrlsTip')" :disabled="disabledFields.imgUrls" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template v-if="data.submitBtn">
|
<template v-if="data.submitBtn">
|
||||||
<footer class="el-dialog__footer">
|
<footer class="el-dialog__footer">
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button type="primary" @click="printForm" v-if="form.printInfo">{{
|
<el-button type="primary" @click="printForm" v-if="form.printInfo">{{ t('jfI18n.print') }} </el-button>
|
||||||
t('jfI18n.print')
|
|
||||||
}}
|
|
||||||
</el-button>
|
|
||||||
<el-button type="primary" @click="submitForm" :disabled="loading">{{ t('jfI18n.submit') }}</el-button>
|
<el-button type="primary" @click="submitForm" :disabled="loading">{{ t('jfI18n.submit') }}</el-button>
|
||||||
</span>
|
</span>
|
||||||
</footer>
|
</footer>
|
||||||
@@ -72,56 +82,50 @@
|
|||||||
<template v-else>
|
<template v-else>
|
||||||
<footer class="el-dialog__footer">
|
<footer class="el-dialog__footer">
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button type="primary" @click="printForm" v-if="form.printInfo">{{
|
<el-button type="primary" @click="printForm" v-if="form.printInfo">{{ t('jfI18n.print') }} </el-button>
|
||||||
t('jfI18n.print')
|
|
||||||
}}
|
|
||||||
</el-button>
|
|
||||||
</span>
|
</span>
|
||||||
</footer>
|
</footer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 打印表单 -->
|
<!-- 打印表单 -->
|
||||||
<el-dialog v-model="data.showTinymceView" top="20px" width="700px"
|
<el-dialog v-model="data.showTinymceView" top="20px" width="700px" :title="data.tinymceTitle" append-to-body @close="closePrint">
|
||||||
:title="data.tinymceTitle" append-to-body
|
|
||||||
@close="closePrint">
|
|
||||||
<tinymce-view v-if="data.showTinymceView" :currFlowForm="form" :elTab="data.elTab"></tinymce-view>
|
<tinymce-view v-if="data.showTinymceView" :currFlowForm="form" :elTab="data.elTab"></tinymce-view>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="AskLeaveForm">
|
<script setup lang="ts" name="AskLeaveForm">
|
||||||
|
import { useMessage } from '/@/hooks/message';
|
||||||
|
import * as askLeave from '/@/api/order/ask-leave';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { onFormLoadedUrl, onLoadDicUrl, remoteMethodByKey } from '/@/flow/components/convert-name/convert.ts';
|
||||||
|
import * as orderVue from '/@/api/order/order-key-vue';
|
||||||
|
import { handleCustomFormPerm, handleFormPrint } from '/@/flow/utils/form-perm';
|
||||||
|
import { deepClone } from '/@/utils/other';
|
||||||
|
import { initCustomFormMethods } from '../index';
|
||||||
|
|
||||||
import {useMessage} from "/@/hooks/message";
|
const { t } = useI18n();
|
||||||
import * as askLeave from '/@/api/order/ask-leave'
|
const emits = defineEmits(['handleJob']);
|
||||||
import {useI18n} from "vue-i18n"
|
// 引入组件
|
||||||
import {onFormLoadedUrl, onLoadDicUrl, remoteMethodByKey} from "/@/flow/components/convert-name/convert.ts";
|
const TinymceView = defineAsyncComponent(() => import('/@/flow/components/tinymce/TinymceView.vue'));
|
||||||
import * as orderVue from "/@/api/order/order-key-vue";
|
|
||||||
import {handleCustomFormPerm, handleFormPrint} from "/@/flow/utils/form-perm";
|
|
||||||
import {deepClone} from "/@/utils/other";
|
|
||||||
import {initCustomFormMethods} from "../index";
|
|
||||||
|
|
||||||
const {t} = useI18n();
|
// 定义变量内容
|
||||||
const emits = defineEmits(["handleJob"]);
|
const dataFormRef = ref();
|
||||||
// 引入组件
|
const loading = ref(false);
|
||||||
const TinymceView = defineAsyncComponent(() => import('/@/flow/components/tinymce/TinymceView.vue'));
|
const operType = ref(false);
|
||||||
|
// 定义字典
|
||||||
// 定义变量内容
|
const dicData = reactive({});
|
||||||
const dataFormRef = ref();
|
const onLoad = onLoadDicUrl();
|
||||||
const loading = ref(false);
|
const onFormLoaded = onFormLoadedUrl({ key: 'carbonCopyPerson' });
|
||||||
const operType = ref(false);
|
onMounted(async () => {
|
||||||
// 定义字典
|
|
||||||
const dicData = reactive({});
|
|
||||||
const onLoad = onLoadDicUrl();
|
|
||||||
const onFormLoaded = onFormLoadedUrl({key: "carbonCopyPerson"});
|
|
||||||
onMounted(async () => {
|
|
||||||
// await onLoad(dicData);
|
// await onLoad(dicData);
|
||||||
});
|
});
|
||||||
|
|
||||||
function remoteMethod(query: string) {
|
function remoteMethod(query: string) {
|
||||||
remoteMethodByKey(query, onLoad, dicData, 'userName', "carbonCopyPerson")
|
remoteMethodByKey(query, onLoad, dicData, 'userName', 'carbonCopyPerson');
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
currJob: {
|
currJob: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: null,
|
default: null,
|
||||||
@@ -130,10 +134,10 @@
|
|||||||
type: Object,
|
type: Object,
|
||||||
default: {},
|
default: {},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// 提交表单数据
|
// 提交表单数据
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
type: '',
|
type: '',
|
||||||
startTime: '',
|
startTime: '',
|
||||||
endTime: '',
|
endTime: '',
|
||||||
@@ -141,20 +145,20 @@
|
|||||||
carbonCopyPerson: [],
|
carbonCopyPerson: [],
|
||||||
remark: '',
|
remark: '',
|
||||||
imgUrls: '',
|
imgUrls: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
// 定义校验规则
|
// 定义校验规则
|
||||||
const dataRules = ref({
|
const dataRules = ref({
|
||||||
startTime: [{required: true, message: '开始时间不能为空', trigger: 'blur'}],
|
startTime: [{ required: true, message: '开始时间不能为空', trigger: 'blur' }],
|
||||||
days: [{required: true, message: '请假天数不能为空', trigger: 'blur'}],
|
days: [{ required: true, message: '请假天数不能为空', trigger: 'blur' }],
|
||||||
remark: [{required: true, message: '请假事由不能为空', trigger: 'blur'}],
|
remark: [{ required: true, message: '请假事由不能为空', trigger: 'blur' }],
|
||||||
})
|
});
|
||||||
|
|
||||||
function initJobData() {
|
function initJobData() {
|
||||||
handleGetObj(props.currJob.orderId)
|
handleGetObj(props.currJob.orderId);
|
||||||
}
|
}
|
||||||
|
|
||||||
const fieldsPerm = {
|
const fieldsPerm = {
|
||||||
type: false,
|
type: false,
|
||||||
startTime: false,
|
startTime: false,
|
||||||
endTime: false,
|
endTime: false,
|
||||||
@@ -162,97 +166,96 @@
|
|||||||
carbonCopyPerson: false,
|
carbonCopyPerson: false,
|
||||||
remark: false,
|
remark: false,
|
||||||
imgUrls: false,
|
imgUrls: false,
|
||||||
}
|
};
|
||||||
// 定义字段显隐
|
// 定义字段显隐
|
||||||
const hiddenFields = reactive(fieldsPerm);
|
const hiddenFields = reactive(fieldsPerm);
|
||||||
// 定义字段是否可编辑
|
// 定义字段是否可编辑
|
||||||
const disabledFields = reactive(deepClone(fieldsPerm));
|
const disabledFields = reactive(deepClone(fieldsPerm));
|
||||||
|
|
||||||
function handleGetObj(id) {
|
function handleGetObj(id) {
|
||||||
askLeave.getObj(id).then(async resp => {
|
askLeave.getObj(id).then(async (resp) => {
|
||||||
let formData = resp.data ? resp.data : {}
|
let formData = resp.data ? resp.data : {};
|
||||||
Object.assign(form, formData)
|
Object.assign(form, formData);
|
||||||
await onFormLoaded(dicData, form);
|
await onFormLoaded(dicData, form);
|
||||||
form.runJobId = props.currJob.id
|
form.runJobId = props.currJob.id;
|
||||||
await initFormPermPrint()
|
await initFormPermPrint();
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
showTinymceView: false,
|
showTinymceView: false,
|
||||||
tinymceTitle: '',
|
tinymceTitle: '',
|
||||||
submitBtn: true,
|
submitBtn: true,
|
||||||
elTab: null
|
elTab: null,
|
||||||
})
|
});
|
||||||
|
|
||||||
const methods = initCustomFormMethods(data, disabledFields, operType)
|
const methods = initCustomFormMethods(data, disabledFields, operType);
|
||||||
|
|
||||||
async function initFormPermPrint() {
|
async function initFormPermPrint() {
|
||||||
let elTab = orderVue.currElTabIsExist(props.currJob, props.currElTab.id);
|
let elTab = orderVue.currElTabIsExist(props.currJob, props.currElTab.id);
|
||||||
// 处理表单权限
|
// 处理表单权限
|
||||||
let res = await handleCustomFormPerm(props, hiddenFields, disabledFields, elTab)
|
let res = await handleCustomFormPerm(props, hiddenFields, disabledFields, elTab);
|
||||||
// 判断是否仅查看
|
// 判断是否仅查看
|
||||||
await orderVue.currElTabIsView(methods, props.currJob, props.currElTab.id, submitForm, res.callback)
|
await orderVue.currElTabIsView(methods, props.currJob, props.currElTab.id, submitForm, res.callback);
|
||||||
// 采用elTab配置的模板
|
// 采用elTab配置的模板
|
||||||
await handleFormPrint(form, elTab.type, elTab.id, '1')
|
await handleFormPrint(form, elTab.type, elTab.id, '1');
|
||||||
data.elTab = elTab
|
data.elTab = elTab;
|
||||||
}
|
}
|
||||||
|
|
||||||
function printForm() {
|
function printForm() {
|
||||||
closePrint(true, false)
|
closePrint(true, false);
|
||||||
data.tinymceTitle = '请假工单'
|
data.tinymceTitle = '请假工单';
|
||||||
data.showTinymceView = true
|
data.showTinymceView = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function closePrint(isInit, isSave){
|
function closePrint(isInit, isSave) {
|
||||||
if (isInit) {
|
if (isInit) {
|
||||||
form.formData = form
|
form.formData = form;
|
||||||
form.dicData = {carbonCopyPerson: dicData.carbonCopyPerson}
|
form.dicData = { carbonCopyPerson: dicData.carbonCopyPerson };
|
||||||
form['carbonCopyPerson.valueKey'] = 'userId'
|
form['carbonCopyPerson.valueKey'] = 'userId';
|
||||||
form['carbonCopyPerson.showKey'] = 'name'
|
form['carbonCopyPerson.showKey'] = 'name';
|
||||||
} else {
|
} else {
|
||||||
delete form.formData
|
delete form.formData;
|
||||||
delete form.dicData
|
delete form.dicData;
|
||||||
delete form['carbonCopyPerson.valueKey']
|
delete form['carbonCopyPerson.valueKey'];
|
||||||
delete form['carbonCopyPerson.showKey']
|
delete form['carbonCopyPerson.showKey'];
|
||||||
}
|
|
||||||
if (isSave) delete form.printInfo
|
|
||||||
}
|
}
|
||||||
|
if (isSave) delete form.printInfo;
|
||||||
|
}
|
||||||
|
|
||||||
async function submitForm() {
|
async function submitForm() {
|
||||||
closePrint(false, true)
|
closePrint(false, true);
|
||||||
try {
|
try {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
await askLeave.putObj(form)
|
await askLeave.putObj(form);
|
||||||
orderVue.currElTabIsSave(props.currJob, props.currElTab.id, true, emits)
|
orderVue.currElTabIsSave(props.currJob, props.currElTab.id, true, emits);
|
||||||
useMessage().success(t(form.id ? 'common.editSuccessText' : 'common.addSuccessText'));
|
useMessage().success(t(form.id ? 'common.editSuccessText' : 'common.addSuccessText'));
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
useMessage().error(err.msg);
|
useMessage().error(err.msg);
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 监听双向绑定
|
// 监听双向绑定
|
||||||
watch(
|
watch(
|
||||||
() => props.currJob.id,
|
() => props.currJob.id,
|
||||||
() => {
|
() => {
|
||||||
initJobData();
|
initJobData();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
initJobData()
|
initJobData();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.el-dialog__footer {
|
.el-dialog__footer {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
.dialog-footer {
|
.dialog-footer {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -4,36 +4,54 @@
|
|||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<el-col :span="12" class="mb20" v-if="!hiddenFields.type">
|
<el-col :span="12" class="mb20" v-if="!hiddenFields.type">
|
||||||
<el-form-item :label="t('askLeave.type')" prop="type">
|
<el-form-item :label="t('askLeave.type')" prop="type">
|
||||||
<el-input v-model="form.type" :placeholder="t('askLeave.inputTypeTip')" :disabled="disabledFields.type"/>
|
<el-input v-model="form.type" :placeholder="t('askLeave.inputTypeTip')" :disabled="disabledFields.type" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20" v-if="!hiddenFields.startTime">
|
<el-col :span="12" class="mb20" v-if="!hiddenFields.startTime">
|
||||||
<el-form-item :label="t('askLeave.startTime')" prop="startTime">
|
<el-form-item :label="t('askLeave.startTime')" prop="startTime">
|
||||||
<el-date-picker type="datetime" :placeholder="t('askLeave.inputStartTimeTip')" :disabled="disabledFields.startTime"
|
<el-date-picker
|
||||||
v-model="form.startTime" :value-format="dateTimeStr"></el-date-picker>
|
type="datetime"
|
||||||
|
:placeholder="t('askLeave.inputStartTimeTip')"
|
||||||
|
:disabled="disabledFields.startTime"
|
||||||
|
v-model="form.startTime"
|
||||||
|
:value-format="dateTimeStr"
|
||||||
|
></el-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20" v-if="!hiddenFields.endTime">
|
<el-col :span="12" class="mb20" v-if="!hiddenFields.endTime">
|
||||||
<el-form-item :label="t('askLeave.endTime')" prop="endTime">
|
<el-form-item :label="t('askLeave.endTime')" prop="endTime">
|
||||||
<el-date-picker type="datetime" :placeholder="t('askLeave.inputEndTimeTip')" :disabled="disabledFields.endTime"
|
<el-date-picker
|
||||||
v-model="form.endTime" :value-format="dateTimeStr"></el-date-picker>
|
type="datetime"
|
||||||
|
:placeholder="t('askLeave.inputEndTimeTip')"
|
||||||
|
:disabled="disabledFields.endTime"
|
||||||
|
v-model="form.endTime"
|
||||||
|
:value-format="dateTimeStr"
|
||||||
|
></el-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20" v-if="!hiddenFields.days">
|
<el-col :span="12" class="mb20" v-if="!hiddenFields.days">
|
||||||
<el-form-item :label="t('askLeave.days')" prop="days">
|
<el-form-item :label="t('askLeave.days')" prop="days">
|
||||||
<el-input v-model="form.days" :placeholder="t('askLeave.inputDaysTip')" :disabled="disabledFields.days"/>
|
<el-input v-model="form.days" :placeholder="t('askLeave.inputDaysTip')" :disabled="disabledFields.days" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20" v-if="!hiddenFields.carbonCopyPerson">
|
<el-col :span="12" class="mb20" v-if="!hiddenFields.carbonCopyPerson">
|
||||||
<el-form-item :label="t('askLeave.carbonCopyPerson')" prop="carbonCopyPerson">
|
<el-form-item :label="t('askLeave.carbonCopyPerson')" prop="carbonCopyPerson">
|
||||||
<el-tooltip content="请输入用户名称进行模糊搜索" placement="top">
|
<el-tooltip content="请输入用户名称进行模糊搜索" placement="top">
|
||||||
<el-select v-model="form.carbonCopyPerson" :placeholder="t('askLeave.inputCarbonCopyPersonTip')" clearable filterable multiple
|
<el-select
|
||||||
remote :remote-method="remoteMethod" :reserve-keyword="false"
|
v-model="form.carbonCopyPerson"
|
||||||
:disabled="disabledFields.carbonCopyPerson">
|
:placeholder="t('askLeave.inputCarbonCopyPersonTip')"
|
||||||
|
clearable
|
||||||
|
filterable
|
||||||
|
multiple
|
||||||
|
remote
|
||||||
|
:remote-method="remoteMethod"
|
||||||
|
:reserve-keyword="false"
|
||||||
|
:disabled="disabledFields.carbonCopyPerson"
|
||||||
|
>
|
||||||
<el-option v-for="(item, index) in dicData.carbonCopyPerson" :key="index" :label="item.name" :value="item.userId"></el-option>
|
<el-option v-for="(item, index) in dicData.carbonCopyPerson" :key="index" :label="item.name" :value="item.userId"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
@@ -42,16 +60,15 @@
|
|||||||
|
|
||||||
<el-col :span="12" class="mb20" v-if="!hiddenFields.remark">
|
<el-col :span="12" class="mb20" v-if="!hiddenFields.remark">
|
||||||
<el-form-item :label="t('askLeave.remark')" prop="remark">
|
<el-form-item :label="t('askLeave.remark')" prop="remark">
|
||||||
<el-input v-model="form.remark" type="textarea" :placeholder="t('askLeave.inputRemarkTip')" :disabled="disabledFields.remark"/>
|
<el-input v-model="form.remark" type="textarea" :placeholder="t('askLeave.inputRemarkTip')" :disabled="disabledFields.remark" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20" v-if="!hiddenFields.imgUrls">
|
<el-col :span="12" class="mb20" v-if="!hiddenFields.imgUrls">
|
||||||
<el-form-item :label="t('askLeave.imgUrls')" prop="imgUrls">
|
<el-form-item :label="t('askLeave.imgUrls')" prop="imgUrls">
|
||||||
<el-input v-model="form.imgUrls" :placeholder="t('askLeave.inputImgUrlsTip')" :disabled="disabledFields.imgUrls"/>
|
<el-input v-model="form.imgUrls" :placeholder="t('askLeave.inputImgUrlsTip')" :disabled="disabledFields.imgUrls" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template v-if="operType !== 'view'">
|
<template v-if="operType !== 'view'">
|
||||||
@@ -63,10 +80,7 @@
|
|||||||
<el-button type="primary" @click="onTemp" :disabled="loading">{{ $t('jfI18n.temp') }}</el-button>
|
<el-button type="primary" @click="onTemp" :disabled="loading">{{ $t('jfI18n.temp') }}</el-button>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<el-button type="primary" @click="printForm" v-if="form.printInfo">{{
|
<el-button type="primary" @click="printForm" v-if="form.printInfo">{{ t('jfI18n.print') }} </el-button>
|
||||||
t('jfI18n.print')
|
|
||||||
}}
|
|
||||||
</el-button>
|
|
||||||
<el-button type="primary" @click="onSubmit" :disabled="loading">{{ $t('common.editBtn') }}</el-button>
|
<el-button type="primary" @click="onSubmit" :disabled="loading">{{ $t('common.editBtn') }}</el-button>
|
||||||
</template>
|
</template>
|
||||||
</span>
|
</span>
|
||||||
@@ -76,66 +90,60 @@
|
|||||||
<footer class="el-dialog__footer">
|
<footer class="el-dialog__footer">
|
||||||
<div style="text-align: center">
|
<div style="text-align: center">
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button type="primary" @click="printForm" v-if="form.printInfo">{{
|
<el-button type="primary" @click="printForm" v-if="form.printInfo">{{ t('jfI18n.print') }} </el-button>
|
||||||
t('jfI18n.print')
|
|
||||||
}}
|
|
||||||
</el-button>
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</template>
|
</template>
|
||||||
<!-- 打印表单 -->
|
<!-- 打印表单 -->
|
||||||
<el-dialog v-model="data.showTinymceView" top="20px" width="700px"
|
<el-dialog v-model="data.showTinymceView" top="20px" width="700px" :title="data.tinymceTitle" append-to-body @close="closePrint">
|
||||||
:title="data.tinymceTitle" append-to-body
|
|
||||||
@close="closePrint">
|
|
||||||
<tinymce-view v-if="data.showTinymceView" :currFlowForm="form" :elTab="data.elTab"></tinymce-view>
|
<tinymce-view v-if="data.showTinymceView" :currFlowForm="form" :elTab="data.elTab"></tinymce-view>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="AskLeaveDialog">
|
<script setup lang="ts" name="AskLeaveDialog">
|
||||||
|
import { useMessage } from '/@/hooks/message';
|
||||||
|
import { getObj, addObj, putObj, tempStore } from '/@/api/order/ask-leave';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { rule, validateNull } from '/@/utils/validate';
|
||||||
|
import { onFormLoadedUrl, onLoadDicUrl, remoteMethodByKey } from '/@/flow/components/convert-name/convert.ts';
|
||||||
|
import * as common from '/@/flow/support/common';
|
||||||
|
import { handleFormPrint, handleFormStartPerm } from '/@/flow/utils/form-perm';
|
||||||
|
import { currFormIsView, orderKeyMap } from '/@/api/order/order-key-vue';
|
||||||
|
import { deepClone } from '/@/utils/other';
|
||||||
|
import { DIC_PROP } from '/@/flow/support/dict-prop';
|
||||||
|
import { initCustomFormMethods } from '../index';
|
||||||
|
|
||||||
import { useMessage } from "/@/hooks/message";
|
const emit = defineEmits(['refresh']);
|
||||||
import {getObj, addObj, putObj, tempStore} from '/@/api/order/ask-leave'
|
const { t } = useI18n();
|
||||||
import { useI18n } from "vue-i18n"
|
// 引入组件
|
||||||
import {rule, validateNull} from '/@/utils/validate';
|
const TinymceView = defineAsyncComponent(() => import('/@/flow/components/tinymce/TinymceView.vue'));
|
||||||
import {onFormLoadedUrl, onLoadDicUrl, remoteMethodByKey} from "/@/flow/components/convert-name/convert.ts";
|
|
||||||
import * as common from '/@/flow/support/common'
|
|
||||||
import {handleFormPrint, handleFormStartPerm} from "/@/flow/utils/form-perm";
|
|
||||||
import {currFormIsView, orderKeyMap} from "/@/api/order/order-key-vue";
|
|
||||||
import {deepClone} from "/@/utils/other";
|
|
||||||
import {DIC_PROP} from "/@/flow/support/dict-prop";
|
|
||||||
import {initCustomFormMethods} from "../index";
|
|
||||||
|
|
||||||
const emit = defineEmits(['refresh']);
|
// 定义变量内容
|
||||||
const { t } = useI18n();
|
const dataFormRef = ref();
|
||||||
// 引入组件
|
const visible = ref(false);
|
||||||
const TinymceView = defineAsyncComponent(() => import('/@/flow/components/tinymce/TinymceView.vue'));
|
const loading = ref(false);
|
||||||
|
const operType = ref(false);
|
||||||
// 定义变量内容
|
const title = ref('');
|
||||||
const dataFormRef = ref();
|
// 定义字典
|
||||||
const visible = ref(false);
|
const dicData = reactive({});
|
||||||
const loading = ref(false);
|
const onLoad = onLoadDicUrl();
|
||||||
const operType = ref(false);
|
const onFormLoaded = onFormLoadedUrl({ key: 'carbonCopyPerson' });
|
||||||
const title = ref('');
|
onMounted(async () => {
|
||||||
// 定义字典
|
|
||||||
const dicData = reactive({});
|
|
||||||
const onLoad = onLoadDicUrl();
|
|
||||||
const onFormLoaded = onFormLoadedUrl({key: "carbonCopyPerson"});
|
|
||||||
onMounted(async () => {
|
|
||||||
// await onLoad(dicData);
|
// await onLoad(dicData);
|
||||||
await openDialog(props.formData.type, props.formData.id)
|
await openDialog(props.formData.type, props.formData.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
formData: {
|
formData: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: null,
|
default: null,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// 提交表单数据
|
// 提交表单数据
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
type: '',
|
type: '',
|
||||||
startTime: '',
|
startTime: '',
|
||||||
endTime: '',
|
endTime: '',
|
||||||
@@ -143,16 +151,16 @@
|
|||||||
carbonCopyPerson: [],
|
carbonCopyPerson: [],
|
||||||
remark: '',
|
remark: '',
|
||||||
imgUrls: '',
|
imgUrls: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
// 定义校验规则
|
// 定义校验规则
|
||||||
const dataRules = ref({
|
const dataRules = ref({
|
||||||
startTime: [{required: true, message: '开始时间不能为空', trigger: 'blur'}],
|
startTime: [{ required: true, message: '开始时间不能为空', trigger: 'blur' }],
|
||||||
days: [{required: true, message: '请假天数不能为空', trigger: 'blur'}],
|
days: [{ required: true, message: '请假天数不能为空', trigger: 'blur' }],
|
||||||
remark: [{required: true, message: '请假事由不能为空', trigger: 'blur'}],
|
remark: [{ required: true, message: '请假事由不能为空', trigger: 'blur' }],
|
||||||
})
|
});
|
||||||
|
|
||||||
const fieldsPerm = {
|
const fieldsPerm = {
|
||||||
type: false,
|
type: false,
|
||||||
startTime: false,
|
startTime: false,
|
||||||
endTime: false,
|
endTime: false,
|
||||||
@@ -160,17 +168,17 @@
|
|||||||
carbonCopyPerson: false,
|
carbonCopyPerson: false,
|
||||||
remark: false,
|
remark: false,
|
||||||
imgUrls: false,
|
imgUrls: false,
|
||||||
}
|
};
|
||||||
// 定义字段显隐
|
// 定义字段显隐
|
||||||
const hiddenFields = reactive(fieldsPerm);
|
const hiddenFields = reactive(fieldsPerm);
|
||||||
// 定义字段是否可编辑
|
// 定义字段是否可编辑
|
||||||
const disabledFields = reactive(deepClone(fieldsPerm));
|
const disabledFields = reactive(deepClone(fieldsPerm));
|
||||||
|
|
||||||
// 打开弹窗
|
// 打开弹窗
|
||||||
const openDialog = async (type: string, id: string) => {
|
const openDialog = async (type: string, id: string) => {
|
||||||
visible.value = true
|
visible.value = true;
|
||||||
operType.value = type;
|
operType.value = type;
|
||||||
form.id = ''
|
form.id = '';
|
||||||
|
|
||||||
if (type === 'add') {
|
if (type === 'add') {
|
||||||
title.value = t('common.addBtn');
|
title.value = t('common.addBtn');
|
||||||
@@ -187,57 +195,56 @@
|
|||||||
dataFormRef.value?.resetFields();
|
dataFormRef.value?.resetFields();
|
||||||
// 获取AskLeave信息
|
// 获取AskLeave信息
|
||||||
if (id) {
|
if (id) {
|
||||||
form.id = id
|
form.id = id;
|
||||||
await getAskLeaveData(id)
|
await getAskLeaveData(id);
|
||||||
}
|
}
|
||||||
await initFormPermPrint()
|
await initFormPermPrint();
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
};
|
const data = reactive({
|
||||||
|
|
||||||
const data = reactive({
|
|
||||||
showTinymceView: false,
|
showTinymceView: false,
|
||||||
tinymceTitle: '',
|
tinymceTitle: '',
|
||||||
elTab: null
|
elTab: null,
|
||||||
})
|
});
|
||||||
|
|
||||||
const methods = initCustomFormMethods(data, disabledFields)
|
const methods = initCustomFormMethods(data, disabledFields);
|
||||||
|
|
||||||
async function initFormPermPrint() {
|
async function initFormPermPrint() {
|
||||||
// 处理表单权限 开始节点必须配置表单
|
// 处理表单权限 开始节点必须配置表单
|
||||||
let res = await handleFormStartPerm(hiddenFields, disabledFields, null, null, orderKeyMap.AskLeave, null);
|
let res = await handleFormStartPerm(hiddenFields, disabledFields, null, null, orderKeyMap.AskLeave, null);
|
||||||
await currFormIsView(methods, res.elTab, true, res.callback)
|
await currFormIsView(methods, res.elTab, true, res.callback);
|
||||||
// 采用elTab配置的模板
|
// 采用elTab配置的模板
|
||||||
await handleFormPrint(form, res.elTab.type, res.elTab.id, '1')
|
await handleFormPrint(form, res.elTab.type, res.elTab.id, '1');
|
||||||
data.elTab = res.elTab
|
data.elTab = res.elTab;
|
||||||
}
|
}
|
||||||
|
|
||||||
function printForm() {
|
function printForm() {
|
||||||
closePrint(true, false)
|
closePrint(true, false);
|
||||||
data.tinymceTitle = '请假工单'
|
data.tinymceTitle = '请假工单';
|
||||||
data.showTinymceView = true
|
data.showTinymceView = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function closePrint(isInit, isSave){
|
function closePrint(isInit, isSave) {
|
||||||
if (isInit) {
|
if (isInit) {
|
||||||
form.formData = form
|
form.formData = form;
|
||||||
form.dicData = {carbonCopyPerson: dicData.carbonCopyPerson}
|
form.dicData = { carbonCopyPerson: dicData.carbonCopyPerson };
|
||||||
form['carbonCopyPerson.valueKey'] = 'userId'
|
form['carbonCopyPerson.valueKey'] = 'userId';
|
||||||
form['carbonCopyPerson.showKey'] = 'name'
|
form['carbonCopyPerson.showKey'] = 'name';
|
||||||
} else {
|
} else {
|
||||||
delete form.formData
|
delete form.formData;
|
||||||
delete form.dicData
|
delete form.dicData;
|
||||||
delete form['carbonCopyPerson.valueKey']
|
delete form['carbonCopyPerson.valueKey'];
|
||||||
delete form['carbonCopyPerson.showKey']
|
delete form['carbonCopyPerson.showKey'];
|
||||||
}
|
|
||||||
if (isSave) delete form.printInfo
|
|
||||||
}
|
}
|
||||||
|
if (isSave) delete form.printInfo;
|
||||||
|
}
|
||||||
|
|
||||||
// 暂存
|
// 暂存
|
||||||
const onTemp = async () => {
|
const onTemp = async () => {
|
||||||
closePrint(false, true)
|
closePrint(false, true);
|
||||||
|
|
||||||
let clone = {operType: operType.value, form: form};
|
let clone = { operType: operType.value, form: form };
|
||||||
common.handleCloneSubmit(clone);
|
common.handleCloneSubmit(clone);
|
||||||
try {
|
try {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
@@ -250,20 +257,20 @@
|
|||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function remoteMethod(query: string) {
|
function remoteMethod(query: string) {
|
||||||
remoteMethodByKey(query, onLoad, dicData, 'userName', "carbonCopyPerson")
|
remoteMethodByKey(query, onLoad, dicData, 'userName', 'carbonCopyPerson');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 提交
|
// 提交
|
||||||
const onSubmit = async () => {
|
const onSubmit = async () => {
|
||||||
const valid = await dataFormRef.value.validate().catch(() => {});
|
const valid = await dataFormRef.value.validate().catch(() => {});
|
||||||
if (!valid) return false;
|
if (!valid) return false;
|
||||||
closePrint(false, true)
|
closePrint(false, true);
|
||||||
|
|
||||||
let clone = {operType: operType.value, form: form};
|
let clone = { operType: operType.value, form: form };
|
||||||
common.handleCloneSubmit(clone)
|
common.handleCloneSubmit(clone);
|
||||||
try {
|
try {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
form.status !== DIC_PROP.ORDER_STATUS[0].value ? await addObj(form) : await putObj(form);
|
form.status !== DIC_PROP.ORDER_STATUS[0].value ? await addObj(form) : await putObj(form);
|
||||||
@@ -275,33 +282,33 @@
|
|||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onRefresh = () => {
|
const onRefresh = () => {
|
||||||
emit('refresh');
|
emit('refresh');
|
||||||
}
|
};
|
||||||
|
|
||||||
// 初始化表单数据
|
// 初始化表单数据
|
||||||
const getAskLeaveData = async (id: string) => {
|
const getAskLeaveData = async (id: string) => {
|
||||||
// 获取数据
|
// 获取数据
|
||||||
loading.value = true
|
loading.value = true;
|
||||||
let res = await getObj(id)
|
let res = await getObj(id);
|
||||||
loading.value = false
|
loading.value = false;
|
||||||
Object.assign(form, res.data)
|
Object.assign(form, res.data);
|
||||||
await onFormLoaded(dicData, form);
|
await onFormLoaded(dicData, form);
|
||||||
let clone = {operType: operType.value, form: form};
|
let clone = { operType: operType.value, form: form };
|
||||||
common.handleClone(clone);
|
common.handleClone(clone);
|
||||||
};
|
};
|
||||||
|
|
||||||
async function getFormData() {
|
async function getFormData() {
|
||||||
const valid = await dataFormRef.value.validate().catch(() => {});
|
const valid = await dataFormRef.value.validate().catch(() => {});
|
||||||
if (!valid) return false;
|
if (!valid) return false;
|
||||||
return form
|
return form;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 暴露变量
|
// 暴露变量
|
||||||
defineExpose({
|
defineExpose({
|
||||||
openDialog,
|
openDialog,
|
||||||
getFormData
|
getFormData,
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -39,6 +39,5 @@ export default {
|
|||||||
inputUpdateUserTip: 'input updateUser',
|
inputUpdateUserTip: 'input updateUser',
|
||||||
inputUpdateTimeTip: 'input updateTime',
|
inputUpdateTimeTip: 'input updateTime',
|
||||||
inputDelFlagTip: 'input delFlag',
|
inputDelFlagTip: 'input delFlag',
|
||||||
|
},
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
|||||||
@@ -39,6 +39,5 @@ export default {
|
|||||||
inputUpdateUserTip: '请输入修改人',
|
inputUpdateUserTip: '请输入修改人',
|
||||||
inputUpdateTimeTip: '请输入修改时间',
|
inputUpdateTimeTip: '请输入修改时间',
|
||||||
inputDelFlagTip: '请输入删除标',
|
inputDelFlagTip: '请输入删除标',
|
||||||
|
},
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
|||||||
@@ -3,9 +3,8 @@
|
|||||||
<div class="layout-padding-auto layout-padding-view">
|
<div class="layout-padding-auto layout-padding-view">
|
||||||
<el-row v-show="showSearch">
|
<el-row v-show="showSearch">
|
||||||
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
|
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
|
||||||
<el-form-item :label="$t('askLeave.code')" prop="code" >
|
<el-form-item :label="$t('askLeave.code')" prop="code">
|
||||||
<el-input :placeholder="t('askLeave.inputCodeTip')" v-model="state.queryForm.code" clearable
|
<el-input :placeholder="t('askLeave.inputCodeTip')" v-model="state.queryForm.code" clearable style="max-width: 180px" />
|
||||||
style="max-width: 180px" />
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('askLeave.status')" prop="status">
|
<el-form-item :label="$t('askLeave.status')" prop="status">
|
||||||
<el-select v-model="state.queryForm.status" :placeholder="t('askLeave.inputStatusTip')" clearable filterable style="max-width: 180px">
|
<el-select v-model="state.queryForm.status" :placeholder="t('askLeave.inputStatusTip')" clearable filterable style="max-width: 180px">
|
||||||
@@ -16,107 +15,114 @@
|
|||||||
<el-button icon="search" type="primary" @click="getDataList">
|
<el-button icon="search" type="primary" @click="getDataList">
|
||||||
{{ $t('common.queryBtn') }}
|
{{ $t('common.queryBtn') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button icon="Refresh" @click="resetQuery">{{
|
<el-button icon="Refresh" @click="resetQuery">{{ $t('common.resetBtn') }} </el-button>
|
||||||
$t('common.resetBtn')
|
|
||||||
}}
|
|
||||||
</el-button>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
<div class="mb8" style="width: 100%">
|
<div class="mb8" style="width: 100%">
|
||||||
|
|
||||||
<el-tooltip placement="top">
|
<el-tooltip placement="top">
|
||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('common.addBtn') }}
|
{{ $t('common.addBtn') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button icon="Plus" type="primary" class="ml10" @click="openDialog('add')"
|
<el-button icon="Plus" type="primary" class="ml10" @click="openDialog('add')" v-auth="'order_askleave_add'"> </el-button>
|
||||||
v-auth="'order_askleave_add'">
|
|
||||||
</el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip placement="top">
|
<el-tooltip placement="top">
|
||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('common.delBtn') }}
|
{{ $t('common.delBtn') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button plain :disabled="multiple" icon="Delete" type="primary" class="ml10"
|
<el-button
|
||||||
v-auth="'order_askleave_del'" @click="handleDelete(selectObjs)">
|
plain
|
||||||
|
:disabled="multiple"
|
||||||
|
icon="Delete"
|
||||||
|
type="primary"
|
||||||
|
class="ml10"
|
||||||
|
v-auth="'order_askleave_del'"
|
||||||
|
@click="handleDelete(selectObjs)"
|
||||||
|
>
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
<right-toolbar v-model:showSearch="showSearch" :export="'order_askleave_export'"
|
<right-toolbar
|
||||||
@exportExcel="exportExcel" class="ml10" style="float: right;margin-right: 20px"
|
v-model:showSearch="showSearch"
|
||||||
@queryTable="getDataList"></right-toolbar>
|
:export="'order_askleave_export'"
|
||||||
|
@exportExcel="exportExcel"
|
||||||
|
class="ml10"
|
||||||
|
style="float: right; margin-right: 20px"
|
||||||
|
@queryTable="getDataList"
|
||||||
|
></right-toolbar>
|
||||||
</div>
|
</div>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-table :data="state.dataList" v-loading="state.loading" style="width: 100%"
|
<el-table
|
||||||
@selection-change="handleSelectionChange" @sort-change="sortChangeHandle">
|
:data="state.dataList"
|
||||||
<el-table-column type="selection" width="40" align="center"/>
|
v-loading="state.loading"
|
||||||
<el-table-column type="index" :label="t('askLeave.index')" width="40"/>
|
style="width: 100%"
|
||||||
<el-table-column prop="code" :label="t('askLeave.code')" show-overflow-tooltip/>
|
@selection-change="handleSelectionChange"
|
||||||
<el-table-column prop="flowKey" :label="t('askLeave.flowKey')" show-overflow-tooltip/>
|
@sort-change="sortChangeHandle"
|
||||||
<el-table-column prop="type" :label="t('askLeave.type')" show-overflow-tooltip/>
|
>
|
||||||
<el-table-column prop="startTime" :label="t('askLeave.startTime')" show-overflow-tooltip/>
|
<el-table-column type="selection" width="40" align="center" />
|
||||||
<el-table-column prop="endTime" :label="t('askLeave.endTime')" show-overflow-tooltip/>
|
<el-table-column type="index" :label="t('askLeave.index')" width="40" />
|
||||||
<el-table-column prop="days" :label="t('askLeave.days')" show-overflow-tooltip/>
|
<el-table-column prop="code" :label="t('askLeave.code')" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="flowKey" :label="t('askLeave.flowKey')" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="type" :label="t('askLeave.type')" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="startTime" :label="t('askLeave.startTime')" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="endTime" :label="t('askLeave.endTime')" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="days" :label="t('askLeave.days')" show-overflow-tooltip />
|
||||||
<el-table-column prop="carbonCopyPerson" :label="t('askLeave.carbonCopyPerson')" show-overflow-tooltip>
|
<el-table-column prop="carbonCopyPerson" :label="t('askLeave.carbonCopyPerson')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<convert-name :options="state.dicData.carbonCopyPerson" :value="scope.row.carbonCopyPerson"
|
<convert-name
|
||||||
:valueKey="'userId'" :showKey="'name'"></convert-name>
|
:options="state.dicData.carbonCopyPerson"
|
||||||
|
:value="scope.row.carbonCopyPerson"
|
||||||
|
:valueKey="'userId'"
|
||||||
|
:showKey="'name'"
|
||||||
|
></convert-name>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="remark" :label="t('askLeave.remark')" show-overflow-tooltip/>
|
<el-table-column prop="remark" :label="t('askLeave.remark')" show-overflow-tooltip />
|
||||||
<el-table-column prop="status" :label="t('askLeave.status')" show-overflow-tooltip>
|
<el-table-column prop="status" :label="t('askLeave.status')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :options="DIC_PROP.ORDER_STATUS" :value="scope.row.status"></dict-tag>
|
<dict-tag :options="DIC_PROP.ORDER_STATUS" :value="scope.row.status"></dict-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="finishTime" :label="t('askLeave.finishTime')" show-overflow-tooltip/>
|
<el-table-column prop="finishTime" :label="t('askLeave.finishTime')" show-overflow-tooltip />
|
||||||
<el-table-column prop="createUser" :label="t('askLeave.createUser')" show-overflow-tooltip>
|
<el-table-column prop="createUser" :label="t('askLeave.createUser')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<convert-name :options="state.dicData.createUser" :value="scope.row.createUser"
|
<convert-name :options="state.dicData.createUser" :value="scope.row.createUser" :valueKey="'userId'" :showKey="'name'"></convert-name>
|
||||||
:valueKey="'userId'" :showKey="'name'"></convert-name>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="createTime" :label="t('askLeave.createTime')" show-overflow-tooltip/>
|
<el-table-column prop="createTime" :label="t('askLeave.createTime')" show-overflow-tooltip />
|
||||||
<el-table-column :label="$t('common.action')" width="150">
|
<el-table-column :label="$t('common.action')" width="150">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tooltip placement="top">
|
<el-tooltip placement="top">
|
||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('common.viewBtn') }}
|
{{ $t('common.viewBtn') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button text type="primary" icon="view" @click="openDialog('view', scope.row.id)">
|
<el-button text type="primary" icon="view" @click="openDialog('view', scope.row.id)"> </el-button>
|
||||||
</el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
<el-tooltip placement="top">
|
<el-tooltip placement="top">
|
||||||
<template #content>
|
<template #content> 打印表单 </template>
|
||||||
打印表单
|
<el-button icon="Document" text type="primary" @click="openDialog('view', scope.row.id)"> </el-button>
|
||||||
</template>
|
|
||||||
<el-button icon="Document" text type="primary" @click="openDialog('view', scope.row.id)">
|
|
||||||
</el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
<el-tooltip placement="top">
|
<el-tooltip placement="top">
|
||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('common.copyBtn') }}
|
{{ $t('common.copyBtn') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button icon="DocumentCopy" text type="primary" @click="openDialog('copy', scope.row.id, scope.row)">
|
<el-button icon="DocumentCopy" text type="primary" @click="openDialog('copy', scope.row.id, scope.row)"> </el-button>
|
||||||
</el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
<el-tooltip placement="top" v-if="scope.row.status===DIC_PROP.ORDER_STATUS[2].value">
|
<el-tooltip placement="top" v-if="scope.row.status === DIC_PROP.ORDER_STATUS[2].value">
|
||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('jfI18n.recallBtn') }}
|
{{ $t('jfI18n.recallBtn') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button icon="RefreshLeft" text type="primary" @click="handleRecallReset(scope.row)">
|
<el-button icon="RefreshLeft" text type="primary" @click="handleRecallReset(scope.row)"> </el-button>
|
||||||
</el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip placement="top" v-if="scope.row.status===DIC_PROP.ORDER_STATUS[0].value">
|
<el-tooltip placement="top" v-if="scope.row.status === DIC_PROP.ORDER_STATUS[0].value">
|
||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('jfI18n.resetBtn') }}
|
{{ $t('jfI18n.resetBtn') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button icon="RefreshRight" text type="primary" @click="handleRecallReset(scope.row)">
|
<el-button icon="RefreshRight" text type="primary" @click="handleRecallReset(scope.row)"> </el-button>
|
||||||
</el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
<el-tooltip placement="top" v-if="scope.row.flowInstId">
|
<el-tooltip placement="top" v-if="scope.row.flowInstId">
|
||||||
@@ -126,117 +132,109 @@
|
|||||||
<el-button text type="primary" icon="Share" @click="openPreview(scope.row)"></el-button>
|
<el-button text type="primary" icon="Share" @click="openPreview(scope.row)"></el-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
<el-tooltip placement="top" v-if="scope.row.status===DIC_PROP.ORDER_STATUS[1].value || scope.row.status===DIC_PROP.ORDER_STATUS[0].value">
|
<el-tooltip
|
||||||
|
placement="top"
|
||||||
|
v-if="scope.row.status === DIC_PROP.ORDER_STATUS[1].value || scope.row.status === DIC_PROP.ORDER_STATUS[0].value"
|
||||||
|
>
|
||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('common.editBtn') }}
|
{{ $t('common.editBtn') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button icon="edit-pen" text type="primary" @click="openDialog('edit', scope.row.id, scope.row)">
|
<el-button icon="edit-pen" text type="primary" @click="openDialog('edit', scope.row.id, scope.row)"> </el-button>
|
||||||
</el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip placement="top" v-if="scope.row.status===DIC_PROP.ORDER_STATUS[1].value">
|
<el-tooltip placement="top" v-if="scope.row.status === DIC_PROP.ORDER_STATUS[1].value">
|
||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('common.delBtn') }}
|
{{ $t('common.delBtn') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button icon="delete" text type="primary" @click="handleDelete([scope.row.id])">
|
<el-button icon="delete" text type="primary" @click="handleDelete([scope.row.id])"> </el-button>
|
||||||
</el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle"
|
<pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle" v-bind="state.pagination" />
|
||||||
v-bind="state.pagination"/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 发起工单 -->
|
<!-- 发起工单 -->
|
||||||
<json-flow-predict ref="predict" :proxy="proxy" @handleInitiateOrder="refresh">
|
<json-flow-predict ref="predict" :proxy="proxy" @handleInitiateOrder="refresh">
|
||||||
<template v-slot="slotProps" v-if="showInitiateOrder">
|
<template v-slot="slotProps" v-if="showInitiateOrder">
|
||||||
<form-dialog ref="form" v-show="slotProps.currActive === 'form'" :formData="formData" @refresh="refresh"/>
|
<form-dialog ref="form" v-show="slotProps.currActive === 'form'" :formData="formData" @refresh="refresh" />
|
||||||
</template>
|
</template>
|
||||||
</json-flow-predict>
|
</json-flow-predict>
|
||||||
|
|
||||||
<!-- 编辑、新增 -->
|
<!-- 编辑、新增 -->
|
||||||
<el-dialog title="请假工单" v-model="showFormDialog" width="60%"
|
<el-dialog title="请假工单" v-model="showFormDialog" width="60%" :close-on-click-modal="false" draggable>
|
||||||
:close-on-click-modal="false" draggable>
|
<form-dialog v-if="showFormDialog" ref="formDialogRef" :formData="formData" @refresh="refresh" />
|
||||||
<form-dialog v-if="showFormDialog" ref="formDialogRef" :formData="formData" @refresh="refresh"/>
|
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="systemAskLeave">
|
<script setup lang="ts" name="systemAskLeave">
|
||||||
import {BasicTableProps, useTable} from "/@/hooks/table";
|
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||||
import {fetchList, delObjs} from "/@/api/order/ask-leave";
|
import { fetchList, delObjs } from '/@/api/order/ask-leave';
|
||||||
import {useMessage, useMessageBox} from "/@/hooks/message";
|
import { useMessage, useMessageBox } from '/@/hooks/message';
|
||||||
|
|
||||||
import {useI18n} from "vue-i18n";
|
import { useI18n } from 'vue-i18n';
|
||||||
import {onCascadeChange, onLoadDicUrl, onLoaded} from "/@/flow/components/convert-name/convert";
|
import { onCascadeChange, onLoadDicUrl, onLoaded } from '/@/flow/components/convert-name/convert';
|
||||||
import {recallReset} from "/@/api/jsonflow/run-flow";
|
import { recallReset } from '/@/api/jsonflow/run-flow';
|
||||||
import {openFlowPreview} from "/@/flow/support/extend";
|
import { openFlowPreview } from '/@/flow/support/extend';
|
||||||
import {DIC_PROP} from "/@/flow/support/dict-prop";
|
import { DIC_PROP } from '/@/flow/support/dict-prop';
|
||||||
import {orderKeyMap} from "/@/api/order/order-key-vue";
|
import { orderKeyMap } from '/@/api/order/order-key-vue';
|
||||||
|
|
||||||
// 引入组件
|
// 引入组件
|
||||||
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
|
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
|
||||||
const JsonFlowPredict = defineAsyncComponent(() => import('/@/views/jsonflow/flow-design/predict.vue'));
|
const JsonFlowPredict = defineAsyncComponent(() => import('/@/views/jsonflow/flow-design/predict.vue'));
|
||||||
|
|
||||||
const {t} = useI18n()
|
const { t } = useI18n();
|
||||||
const {proxy} = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
// 定义查询字典
|
// 定义查询字典
|
||||||
const dicData = reactive({});
|
const dicData = reactive({});
|
||||||
// const onLoad = onLoadDicUrl();
|
// const onLoad = onLoadDicUrl();
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// onLoad(dicData);
|
// onLoad(dicData);
|
||||||
});
|
});
|
||||||
// 定义变量内容
|
// 定义变量内容
|
||||||
const formDialogRef = ref()
|
const formDialogRef = ref();
|
||||||
const showFormDialog = ref(false)
|
const showFormDialog = ref(false);
|
||||||
const showInitiateOrder = ref(false)
|
const showInitiateOrder = ref(false);
|
||||||
const formData = ref({})
|
const formData = ref({});
|
||||||
// 搜索变量
|
// 搜索变量
|
||||||
const queryRef = ref()
|
const queryRef = ref();
|
||||||
const showSearch = ref(true)
|
const showSearch = ref(true);
|
||||||
// 多选变量
|
// 多选变量
|
||||||
const selectObjs = ref([]) as any
|
const selectObjs = ref([]) as any;
|
||||||
const multiple = ref(true)
|
const multiple = ref(true);
|
||||||
|
|
||||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||||
queryForm: {},
|
queryForm: {},
|
||||||
pageList: fetchList,
|
pageList: fetchList,
|
||||||
onLoaded: onLoaded({key: "createUser"}, {key: "carbonCopyPerson"}),
|
onLoaded: onLoaded({ key: 'createUser' }, { key: 'carbonCopyPerson' }),
|
||||||
descs: ["create_time"]
|
descs: ['create_time'],
|
||||||
})
|
});
|
||||||
|
|
||||||
// table hook
|
// table hook
|
||||||
const {
|
const { getDataList, currentChangeHandle, sizeChangeHandle, sortChangeHandle, downBlobFile } = useTable(state);
|
||||||
getDataList,
|
|
||||||
currentChangeHandle,
|
|
||||||
sizeChangeHandle,
|
|
||||||
sortChangeHandle,
|
|
||||||
downBlobFile
|
|
||||||
} = useTable(state)
|
|
||||||
|
|
||||||
|
// 清空搜索条件
|
||||||
|
const resetQuery = () => {
|
||||||
// 清空搜索条件
|
// 清空搜索条件
|
||||||
const resetQuery = () => {
|
queryRef.value?.resetFields();
|
||||||
// 清空搜索条件
|
|
||||||
queryRef.value?.resetFields()
|
|
||||||
// 清空多选
|
// 清空多选
|
||||||
selectObjs.value = []
|
selectObjs.value = [];
|
||||||
getDataList()
|
getDataList();
|
||||||
}
|
};
|
||||||
|
|
||||||
// 导出excel
|
// 导出excel
|
||||||
const exportExcel = () => {
|
const exportExcel = () => {
|
||||||
downBlobFile('/order/ask-leave/export', state.queryForm, 'ask-leave.xlsx')
|
downBlobFile('/order/ask-leave/export', state.queryForm, 'ask-leave.xlsx');
|
||||||
}
|
};
|
||||||
|
|
||||||
// 多选事件
|
// 多选事件
|
||||||
const handleSelectionChange = (objs: any) => {
|
const handleSelectionChange = (objs: any) => {
|
||||||
selectObjs.value = objs.map(({ id }) => id);
|
selectObjs.value = objs.map(({ id }) => id);
|
||||||
multiple.value = !objs.length;
|
multiple.value = !objs.length;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 删除操作
|
// 删除操作
|
||||||
const handleDelete = async (ids: string[]) => {
|
const handleDelete = async (ids: string[]) => {
|
||||||
try {
|
try {
|
||||||
await useMessageBox().confirm(t('common.delConfirmText'));
|
await useMessageBox().confirm(t('common.delConfirmText'));
|
||||||
} catch {
|
} catch {
|
||||||
@@ -250,55 +248,56 @@
|
|||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
useMessage().error(err.msg);
|
useMessage().error(err.msg);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function handleRecallReset(row) {
|
function handleRecallReset(row) {
|
||||||
let params = {id: row.flowInstId, flowKey: row.flowKey, status: row.status}
|
let params = { id: row.flowInstId, flowKey: row.flowKey, status: row.status };
|
||||||
if (row.status === DIC_PROP.ORDER_STATUS[0].value) {
|
if (row.status === DIC_PROP.ORDER_STATUS[0].value) {
|
||||||
recallReset(params).then(() => {
|
recallReset(params).then(() => {
|
||||||
useMessage().success('重发成功');
|
useMessage().success('重发成功');
|
||||||
getDataList();
|
getDataList();
|
||||||
})
|
});
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
useMessageBox().confirm('是否确认要撤回该工单?')
|
useMessageBox()
|
||||||
|
.confirm('是否确认要撤回该工单?')
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return recallReset(params)
|
return recallReset(params);
|
||||||
}).then(() => {
|
|
||||||
useMessage().success('撤回成功')
|
|
||||||
getDataList();
|
|
||||||
})
|
})
|
||||||
}
|
.then(() => {
|
||||||
|
useMessage().success('撤回成功');
|
||||||
|
getDataList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const $router = useRouter();
|
const $router = useRouter();
|
||||||
function openPreview(row) {
|
function openPreview(row) {
|
||||||
openFlowPreview($router, {flowInstId: row.flowInstId}, '1')
|
openFlowPreview($router, { flowInstId: row.flowInstId }, '1');
|
||||||
}
|
}
|
||||||
|
|
||||||
function openPredict(row, bool) {
|
function openPredict(row, bool) {
|
||||||
proxy.$refs.predict.open(row, bool)
|
proxy.$refs.predict.open(row, bool);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 打开弹窗
|
// 打开弹窗
|
||||||
const openDialog = (type?: string, id?: string, row?) => {
|
const openDialog = (type?: string, id?: string, row?) => {
|
||||||
formData.value = {type, id}
|
formData.value = { type, id };
|
||||||
if (type === 'add' || type === 'edit' || type === 'copy') {
|
if (type === 'add' || type === 'edit' || type === 'copy') {
|
||||||
showInitiateOrder.value = true
|
showInitiateOrder.value = true;
|
||||||
if (type === 'add') {
|
if (type === 'add') {
|
||||||
openPredict({flowKey: orderKeyMap.AskLeave}, true)
|
openPredict({ flowKey: orderKeyMap.AskLeave }, true);
|
||||||
} else {
|
} else {
|
||||||
openPredict(row, true)
|
openPredict(row, true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
showFormDialog.value = true
|
showFormDialog.value = true;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function refresh() {
|
|
||||||
getDataList(false)
|
|
||||||
openPredict({}, false)
|
|
||||||
showInitiateOrder.value = false
|
|
||||||
showFormDialog.value = false
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function refresh() {
|
||||||
|
getDataList(false);
|
||||||
|
openPredict({}, false);
|
||||||
|
showInitiateOrder.value = false;
|
||||||
|
showFormDialog.value = false;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog :title="title" v-model="visible" width="80%" append-to-body
|
<el-dialog :title="title" v-model="visible" width="80%" append-to-body :close-on-click-modal="false" draggable @closed="onCancel">
|
||||||
:close-on-click-modal="false" draggable @closed="onCancel">
|
|
||||||
<el-form ref="dataFormRef" :model="form" :rules="dataRules" label-width="100px" v-loading="loading" :disabled="operType === 'view'">
|
<el-form ref="dataFormRef" :model="form" :rules="dataRules" label-width="100px" v-loading="loading" :disabled="operType === 'view'">
|
||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<el-col :span="12" class="mb20">
|
<el-col :span="12" class="mb20">
|
||||||
<el-form-item :label="t('createTable.tableName')" prop="tableName">
|
<el-form-item :label="t('createTable.tableName')" prop="tableName">
|
||||||
<el-input v-model="form.tableName" :placeholder="t('createTable.inputTableNameTip')"/>
|
<el-input v-model="form.tableName" :placeholder="t('createTable.inputTableNameTip')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
<el-col :span="12" class="mb20">
|
||||||
<el-form-item :label="t('createTable.comments')" prop="comments">
|
<el-form-item :label="t('createTable.comments')" prop="comments">
|
||||||
<el-input v-model="form.comments" :placeholder="t('createTable.inputCommentsTip')"/>
|
<el-input v-model="form.comments" :placeholder="t('createTable.inputCommentsTip')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
@@ -52,12 +51,12 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="name" :label="t('createTable.name')" show-overflow-tooltip>
|
<el-table-column prop="name" :label="t('createTable.name')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-input v-model="scope.row.name" :placeholder="t('createTable.name')"/>
|
<el-input v-model="scope.row.name" :placeholder="t('createTable.name')" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="comment" :label="t('createTable.comment')" show-overflow-tooltip>
|
<el-table-column prop="comment" :label="t('createTable.comment')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-input v-model="scope.row.comment" :placeholder="t('createTable.comment')"/>
|
<el-input v-model="scope.row.comment" :placeholder="t('createTable.comment')" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="typeName" :label="t('createTable.typeName')" show-overflow-tooltip>
|
<el-table-column prop="typeName" :label="t('createTable.typeName')" show-overflow-tooltip>
|
||||||
@@ -79,10 +78,10 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="defaultValue" :label="t('createTable.defaultValue')" show-overflow-tooltip>
|
<el-table-column prop="defaultValue" :label="t('createTable.defaultValue')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-input v-model="scope.row.defaultValue" :placeholder="t('createTable.defaultValue')"/>
|
<el-input v-model="scope.row.defaultValue" :placeholder="t('createTable.defaultValue')" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<!-- <el-table-column prop="primary" :label="t('createTable.primaryKey')" show-overflow-tooltip>
|
<!-- <el-table-column prop="primary" :label="t('createTable.primaryKey')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-radio-group v-model="scope.row.primary">
|
<el-radio-group v-model="scope.row.primary">
|
||||||
<el-radio v-for="(item, index) in DIC_PROP.YES_OR_NO_NUM" :key="index" :label="item.value" >
|
<el-radio v-for="(item, index) in DIC_PROP.YES_OR_NO_NUM" :key="index" :label="item.value" >
|
||||||
@@ -94,7 +93,7 @@
|
|||||||
<el-table-column prop="nullable" :label="t('createTable.nullable')" show-overflow-tooltip>
|
<el-table-column prop="nullable" :label="t('createTable.nullable')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-radio-group v-model="scope.row.nullable">
|
<el-radio-group v-model="scope.row.nullable">
|
||||||
<el-radio v-for="(item, index) in DIC_PROP.YES_OR_NO_NUM" :key="index" :label="item.value" >
|
<el-radio v-for="(item, index) in DIC_PROP.YES_OR_NO_NUM" :key="index" :label="item.value">
|
||||||
{{ getLabelByLanguage(item) }}
|
{{ getLabelByLanguage(item) }}
|
||||||
</el-radio>
|
</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
@@ -103,7 +102,6 @@
|
|||||||
</el-table>
|
</el-table>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer v-if="operType !== 'view'">
|
<template #footer v-if="operType !== 'view'">
|
||||||
@@ -116,67 +114,66 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="CreateTableDialog">
|
<script setup lang="ts" name="CreateTableDialog">
|
||||||
|
import { useMessage, useMessageBox } from '/@/hooks/message';
|
||||||
|
import { getObj, addObj, putObj } from '/@/api/order/create-table';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { rule, validateNull } from '/@/utils/validate';
|
||||||
|
import { utils } from '/@/flow/designer/utils/common';
|
||||||
|
const emit = defineEmits(['refreshDone', 'refresh']);
|
||||||
|
|
||||||
import {useMessage, useMessageBox} from "/@/hooks/message";
|
const { t } = useI18n();
|
||||||
import { getObj, addObj, putObj } from '/@/api/order/create-table'
|
|
||||||
import { useI18n } from "vue-i18n"
|
|
||||||
import {rule, validateNull} from '/@/utils/validate';
|
|
||||||
import {utils} from "/@/flow/designer/utils/common";
|
|
||||||
const emit = defineEmits(['refreshDone', 'refresh']);
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
// 定义变量内容
|
||||||
|
const dataFormRef = ref();
|
||||||
|
const visible = ref(false);
|
||||||
|
const loading = ref(false);
|
||||||
|
const operType = ref(false);
|
||||||
|
const title = ref('');
|
||||||
|
// 定义字典
|
||||||
|
|
||||||
// 定义变量内容
|
// 提交表单数据
|
||||||
const dataFormRef = ref();
|
const form = reactive({
|
||||||
const visible = ref(false);
|
|
||||||
const loading = ref(false);
|
|
||||||
const operType = ref(false);
|
|
||||||
const title = ref('');
|
|
||||||
// 定义字典
|
|
||||||
|
|
||||||
// 提交表单数据
|
|
||||||
const form = reactive({
|
|
||||||
tableName: '',
|
tableName: '',
|
||||||
comments: '',
|
comments: '',
|
||||||
databaseType: 'MySQL',
|
databaseType: 'MySQL',
|
||||||
pkPolicy: 'ID_WORKER',
|
pkPolicy: 'ID_WORKER',
|
||||||
columns: [],
|
columns: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验数据源名
|
* 校验数据源名
|
||||||
* @param {校验数据源名} rule
|
* @param {校验数据源名} rule
|
||||||
* @param {*} value
|
* @param {*} value
|
||||||
* @param {*} callback
|
* @param {*} callback
|
||||||
*/
|
*/
|
||||||
let validateDsName = (rule, value, callback) => {
|
let validateDsName = (rule, value, callback) => {
|
||||||
let re = /(?=.*[a-z]|[A-Z])(?=.*_)/;
|
let re = /(?=.*[a-z]|[A-Z])(?=.*_)/;
|
||||||
if (value && (!(re).test(value))) {
|
if (value && !re.test(value)) {
|
||||||
callback(new Error('数据源名称不合法, 组名_数据源名形式'))
|
callback(new Error('数据源名称不合法, 组名_数据源名形式'));
|
||||||
} else {
|
} else {
|
||||||
callback()
|
callback();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 定义校验规则
|
// 定义校验规则
|
||||||
const dataRules = ref({
|
const dataRules = ref({
|
||||||
tableName: [
|
tableName: [
|
||||||
{required: true, message: '表名称不能为空', trigger: 'blur'},
|
{ required: true, message: '表名称不能为空', trigger: 'blur' },
|
||||||
{max: 32, message: '长度在 32 个字符', trigger: 'blur'},
|
{ max: 32, message: '长度在 32 个字符', trigger: 'blur' },
|
||||||
{validator: validateDsName, trigger: 'blur'}
|
{ validator: validateDsName, trigger: 'blur' },
|
||||||
],
|
],
|
||||||
comments: [{required: true, message: '表注释不能为空', trigger: 'blur'}],
|
comments: [{ required: true, message: '表注释不能为空', trigger: 'blur' }],
|
||||||
databaseType: [{required: true, message: '数据库类型不能为空', trigger: 'blur'}],
|
databaseType: [{ required: true, message: '数据库类型不能为空', trigger: 'blur' }],
|
||||||
pkPolicy: [{required: true, message: '主键策略不能为空', trigger: 'blur'}],
|
pkPolicy: [{ required: true, message: '主键策略不能为空', trigger: 'blur' }],
|
||||||
primaryKey: [{required: true, message: '主键字段不能为空', trigger: 'blur'}],
|
primaryKey: [{ required: true, message: '主键字段不能为空', trigger: 'blur' }],
|
||||||
columns: [{required: true, message: '字段信息不能为空', trigger: 'blur'}],
|
columns: [{ required: true, message: '字段信息不能为空', trigger: 'blur' }],
|
||||||
})
|
});
|
||||||
|
|
||||||
// 打开弹窗
|
// 打开弹窗
|
||||||
const openDialog = (type: string, id: string) => {
|
const openDialog = (type: string, id: string) => {
|
||||||
visible.value = true
|
visible.value = true;
|
||||||
operType.value = type;
|
operType.value = type;
|
||||||
form.id = ''
|
form.id = '';
|
||||||
|
|
||||||
if (type === 'add') {
|
if (type === 'add') {
|
||||||
title.value = t('common.addBtn');
|
title.value = t('common.addBtn');
|
||||||
@@ -189,29 +186,29 @@
|
|||||||
// 重置表单数据
|
// 重置表单数据
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
dataFormRef.value?.resetFields();
|
dataFormRef.value?.resetFields();
|
||||||
if (!id) onAddItem()
|
if (!id) onAddItem();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 获取CreateTable信息
|
// 获取CreateTable信息
|
||||||
if (id) {
|
if (id) {
|
||||||
form.id = id
|
form.id = id;
|
||||||
getCreateTableData(id)
|
getCreateTableData(id);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const isOnSubmitRef = ref(false);
|
const isOnSubmitRef = ref(false);
|
||||||
const onCancel = async () => {
|
const onCancel = async () => {
|
||||||
emit('refreshDone', form.tableName, operType.value, isOnSubmitRef.value);
|
emit('refreshDone', form.tableName, operType.value, isOnSubmitRef.value);
|
||||||
}
|
};
|
||||||
|
|
||||||
// 提交
|
// 提交
|
||||||
const onSubmit = async () => {
|
const onSubmit = async () => {
|
||||||
const valid = await dataFormRef.value.validate().catch(() => {});
|
const valid = await dataFormRef.value.validate().catch(() => {});
|
||||||
if (!valid) return false;
|
if (!valid) return false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (form.id) {
|
if (form.id) {
|
||||||
await useMessageBox().confirm("注意若已有表中存在数据时,修改字段类型可能会报错。请确保数据值可自由转换");
|
await useMessageBox().confirm('注意若已有表中存在数据时,修改字段类型可能会报错。请确保数据值可自由转换');
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
return;
|
return;
|
||||||
@@ -219,13 +216,13 @@
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
form.columnInfo = JSON.stringify(form.columns)
|
form.columnInfo = JSON.stringify(form.columns);
|
||||||
let columns = {}
|
let columns = {};
|
||||||
form.columns.forEach(each => {
|
form.columns.forEach((each) => {
|
||||||
if (validateNull(each.defaultValue)) each.defaultValue = null
|
if (validateNull(each.defaultValue)) each.defaultValue = null;
|
||||||
columns[each.name] = each
|
columns[each.name] = each;
|
||||||
})
|
});
|
||||||
form.columnsInfo = JSON.stringify(columns)
|
form.columnsInfo = JSON.stringify(columns);
|
||||||
await addObj(form);
|
await addObj(form);
|
||||||
useMessage().success(t(form.id ? 'common.editSuccessText' : 'common.addSuccessText'));
|
useMessage().success(t(form.id ? 'common.editSuccessText' : 'common.addSuccessText'));
|
||||||
visible.value = false;
|
visible.value = false;
|
||||||
@@ -236,48 +233,68 @@
|
|||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 初始化表单数据
|
// 初始化表单数据
|
||||||
const getCreateTableData = (id: string) => {
|
const getCreateTableData = (id: string) => {
|
||||||
// 获取数据
|
// 获取数据
|
||||||
loading.value = true
|
loading.value = true;
|
||||||
getObj(id).then((res: any) => {
|
getObj(id)
|
||||||
|
.then((res: any) => {
|
||||||
let columnInfo = res.data.columnInfo;
|
let columnInfo = res.data.columnInfo;
|
||||||
res.data.columns = validateNull(columnInfo) ? [] : JSON.parse(columnInfo);
|
res.data.columns = validateNull(columnInfo) ? [] : JSON.parse(columnInfo);
|
||||||
Object.assign(form, res.data)
|
Object.assign(form, res.data);
|
||||||
}).finally(() => {
|
|
||||||
loading.value = false
|
|
||||||
})
|
})
|
||||||
};
|
.finally(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const onAddItem = () => {
|
const onAddItem = () => {
|
||||||
let find = form.columns.find(f => f.name === 'id');
|
let find = form.columns.find((f) => f.name === 'id');
|
||||||
if (find) {
|
if (find) {
|
||||||
let obj = {name: '', comment: '', typeName: '', precision: 0, scale: 0, defaultValue: null, nullable: 1, uniId: utils.getId()};
|
let obj = { name: '', comment: '', typeName: '', precision: 0, scale: 0, defaultValue: null, nullable: 1, uniId: utils.getId() };
|
||||||
form.columns.push(obj);
|
form.columns.push(obj);
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
// primary 1是0否,默认-1
|
// primary 1是0否,默认-1
|
||||||
let id = {name: 'id', comment: '主键', typeName: 'bigint', precision: 20, scale: 0, defaultValue: null, nullable: 0, uniId: utils.getId()};
|
let id = { name: 'id', comment: '主键', typeName: 'bigint', precision: 20, scale: 0, defaultValue: null, nullable: 0, uniId: utils.getId() };
|
||||||
let create_user = {name: 'create_user', comment: '创建人', typeName: 'bigint', precision: 20, scale: 0, defaultValue: null, nullable: 0, uniId: utils.getId()};
|
let create_user = {
|
||||||
let create_time = {name: 'create_time', comment: '创建时间', typeName: 'date', precision: 0, scale: 0, defaultValue: null, nullable: 1, uniId: utils.getId()};
|
name: 'create_user',
|
||||||
|
comment: '创建人',
|
||||||
|
typeName: 'bigint',
|
||||||
|
precision: 20,
|
||||||
|
scale: 0,
|
||||||
|
defaultValue: null,
|
||||||
|
nullable: 0,
|
||||||
|
uniId: utils.getId(),
|
||||||
|
};
|
||||||
|
let create_time = {
|
||||||
|
name: 'create_time',
|
||||||
|
comment: '创建时间',
|
||||||
|
typeName: 'date',
|
||||||
|
precision: 0,
|
||||||
|
scale: 0,
|
||||||
|
defaultValue: null,
|
||||||
|
nullable: 1,
|
||||||
|
uniId: utils.getId(),
|
||||||
|
};
|
||||||
form.columns.push(id);
|
form.columns.push(id);
|
||||||
form.columns.push(create_user);
|
form.columns.push(create_user);
|
||||||
form.columns.push(create_time);
|
form.columns.push(create_time);
|
||||||
form.primaryKey = id.name
|
form.primaryKey = id.name;
|
||||||
}
|
};
|
||||||
|
|
||||||
const handleDelete = (index: number, row: any) => {
|
const handleDelete = (index: number, row: any) => {
|
||||||
if (row.name === 'id' || row.name === 'create_user' || row.name === 'create_time') {
|
if (row.name === 'id' || row.name === 'create_user' || row.name === 'create_time') {
|
||||||
useMessage().warning("不能删除【主键】、【创建人】、【创建时间】");
|
useMessage().warning('不能删除【主键】、【创建人】、【创建时间】');
|
||||||
return
|
return;
|
||||||
}
|
|
||||||
form.columns.splice(index, 1)
|
|
||||||
}
|
}
|
||||||
|
form.columns.splice(index, 1);
|
||||||
|
};
|
||||||
|
|
||||||
// 暴露变量
|
// 暴露变量
|
||||||
defineExpose({
|
defineExpose({
|
||||||
openDialog
|
openDialog,
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -30,5 +30,5 @@ export default {
|
|||||||
scale: 'scale',
|
scale: 'scale',
|
||||||
defaultValue: 'defaultValue',
|
defaultValue: 'defaultValue',
|
||||||
nullable: 'nullable',
|
nullable: 'nullable',
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -30,5 +30,5 @@ export default {
|
|||||||
scale: '小数位数',
|
scale: '小数位数',
|
||||||
defaultValue: '默认值',
|
defaultValue: '默认值',
|
||||||
nullable: '允许NULL',
|
nullable: '允许NULL',
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -3,9 +3,8 @@
|
|||||||
<div class="layout-padding-auto layout-padding-view">
|
<div class="layout-padding-auto layout-padding-view">
|
||||||
<el-row v-show="showSearch">
|
<el-row v-show="showSearch">
|
||||||
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
|
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
|
||||||
<el-form-item :label="$t('createTable.tableName')" prop="tableName" >
|
<el-form-item :label="$t('createTable.tableName')" prop="tableName">
|
||||||
<el-input :placeholder="t('createTable.inputTableNameTip')" v-model="state.queryForm.tableName"
|
<el-input :placeholder="t('createTable.inputTableNameTip')" v-model="state.queryForm.tableName" style="max-width: 180px" />
|
||||||
style="max-width: 180px" />
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button icon="search" type="primary" @click="getDataList">
|
<el-button icon="search" type="primary" @click="getDataList">
|
||||||
@@ -21,66 +20,77 @@
|
|||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('common.addBtn') }}
|
{{ $t('common.addBtn') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button icon="Plus" type="primary" class="ml10" @click="formDialogRef.openDialog('add')"
|
<el-button icon="Plus" type="primary" class="ml10" @click="formDialogRef.openDialog('add')" v-auth="'order_createtable_add'"> </el-button>
|
||||||
v-auth="'order_createtable_add'">
|
|
||||||
</el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
<el-tooltip placement="top">
|
<el-tooltip placement="top">
|
||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('common.delBtn') }}
|
{{ $t('common.delBtn') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button plain :disabled="multiple" icon="Delete" type="primary" class="ml10"
|
<el-button
|
||||||
v-auth="'order_createtable_del'" @click="handleDelete(selectObjs)">
|
plain
|
||||||
|
:disabled="multiple"
|
||||||
|
icon="Delete"
|
||||||
|
type="primary"
|
||||||
|
class="ml10"
|
||||||
|
v-auth="'order_createtable_del'"
|
||||||
|
@click="handleDelete(selectObjs)"
|
||||||
|
>
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
<right-toolbar v-model:showSearch="showSearch" :export="'order_createtable_export'"
|
<right-toolbar
|
||||||
@exportExcel="exportExcel" class="ml10" style="float: right;margin-right: 20px"
|
v-model:showSearch="showSearch"
|
||||||
@queryTable="getDataList"></right-toolbar>
|
:export="'order_createtable_export'"
|
||||||
|
@exportExcel="exportExcel"
|
||||||
|
class="ml10"
|
||||||
|
style="float: right; margin-right: 20px"
|
||||||
|
@queryTable="getDataList"
|
||||||
|
></right-toolbar>
|
||||||
</div>
|
</div>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-table :data="state.dataList" v-loading="state.loading" style="width: 100%"
|
<el-table
|
||||||
@selection-change="handleSelectionChange" @sort-change="sortChangeHandle">
|
:data="state.dataList"
|
||||||
|
v-loading="state.loading"
|
||||||
|
style="width: 100%"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
|
@sort-change="sortChangeHandle"
|
||||||
|
>
|
||||||
<el-table-column type="selection" width="40" align="center" />
|
<el-table-column type="selection" width="40" align="center" />
|
||||||
<el-table-column type="index" :label="t('createTable.index')" width="40" />
|
<el-table-column type="index" :label="t('createTable.index')" width="40" />
|
||||||
<el-table-column prop="tableName" :label="t('createTable.tableName')" show-overflow-tooltip/>
|
<el-table-column prop="tableName" :label="t('createTable.tableName')" show-overflow-tooltip />
|
||||||
<el-table-column prop="comments" :label="t('createTable.comments')" show-overflow-tooltip/>
|
<el-table-column prop="comments" :label="t('createTable.comments')" show-overflow-tooltip />
|
||||||
<el-table-column prop="databaseType" :label="t('createTable.databaseType')" show-overflow-tooltip>
|
<el-table-column prop="databaseType" :label="t('createTable.databaseType')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :options="DIC_PROP.DATABASE_TYPE" :value="scope.row.databaseType"></dict-tag>
|
<dict-tag :options="DIC_PROP.DATABASE_TYPE" :value="scope.row.databaseType"></dict-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="pkPolicy" :label="t('createTable.pkPolicy')" show-overflow-tooltip/>
|
<el-table-column prop="pkPolicy" :label="t('createTable.pkPolicy')" show-overflow-tooltip />
|
||||||
<el-table-column prop="createUser" :label="t('createTable.createUser')" show-overflow-tooltip>
|
<el-table-column prop="createUser" :label="t('createTable.createUser')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<convert-name :options="state.dicData.createUser" :value="scope.row.createUser"
|
<convert-name :options="state.dicData.createUser" :value="scope.row.createUser" :valueKey="'userId'" :showKey="'name'"></convert-name>
|
||||||
:valueKey="'userId'" :showKey="'name'"></convert-name>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="createTime" :label="t('createTable.createTime')" show-overflow-tooltip/>
|
<el-table-column prop="createTime" :label="t('createTable.createTime')" show-overflow-tooltip />
|
||||||
<el-table-column :label="$t('common.action')" width="100">
|
<el-table-column :label="$t('common.action')" width="100">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tooltip placement="top">
|
<el-tooltip placement="top">
|
||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('common.viewBtn') }}
|
{{ $t('common.viewBtn') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button text type="primary" icon="view" @click="formDialogRef.openDialog('view', scope.row.id)">
|
<el-button text type="primary" icon="view" @click="formDialogRef.openDialog('view', scope.row.id)"> </el-button>
|
||||||
</el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip placement="top">
|
<el-tooltip placement="top">
|
||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('common.editBtn') }}
|
{{ $t('common.editBtn') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button icon="edit-pen" text type="primary" @click="formDialogRef.openDialog('edit', scope.row.id)">
|
<el-button icon="edit-pen" text type="primary" @click="formDialogRef.openDialog('edit', scope.row.id)"> </el-button>
|
||||||
</el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip placement="top">
|
<el-tooltip placement="top">
|
||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('common.delBtn') }}
|
{{ $t('common.delBtn') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button icon="delete" text type="primary" @click="handleDelete([scope.row.id])">
|
<el-button icon="delete" text type="primary" @click="handleDelete([scope.row.id])"> </el-button>
|
||||||
</el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -94,65 +104,59 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="systemCreateTable">
|
<script setup lang="ts" name="systemCreateTable">
|
||||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||||
import { fetchList, delObjs } from "/@/api/order/create-table";
|
import { fetchList, delObjs } from '/@/api/order/create-table';
|
||||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
import { useMessage, useMessageBox } from '/@/hooks/message';
|
||||||
|
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from 'vue-i18n';
|
||||||
import { onLoaded } from "/@/flow/components/convert-name/convert";
|
import { onLoaded } from '/@/flow/components/convert-name/convert';
|
||||||
|
|
||||||
// 引入组件
|
// 引入组件
|
||||||
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
|
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
|
||||||
const { t } = useI18n()
|
const { t } = useI18n();
|
||||||
// 定义查询字典
|
// 定义查询字典
|
||||||
|
|
||||||
// 定义变量内容
|
// 定义变量内容
|
||||||
const formDialogRef = ref()
|
const formDialogRef = ref();
|
||||||
// 搜索变量
|
// 搜索变量
|
||||||
const queryRef = ref()
|
const queryRef = ref();
|
||||||
const showSearch = ref(true)
|
const showSearch = ref(true);
|
||||||
// 多选变量
|
// 多选变量
|
||||||
const selectObjs = ref([]) as any
|
const selectObjs = ref([]) as any;
|
||||||
const multiple = ref(true)
|
const multiple = ref(true);
|
||||||
|
|
||||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||||
queryForm: {},
|
queryForm: {},
|
||||||
pageList: fetchList,
|
pageList: fetchList,
|
||||||
onLoaded: onLoaded({key: "createUser"}),
|
onLoaded: onLoaded({ key: 'createUser' }),
|
||||||
descs: ["create_time"]
|
descs: ['create_time'],
|
||||||
})
|
});
|
||||||
|
|
||||||
// table hook
|
// table hook
|
||||||
const {
|
const { getDataList, currentChangeHandle, sizeChangeHandle, sortChangeHandle, downBlobFile } = useTable(state);
|
||||||
getDataList,
|
|
||||||
currentChangeHandle,
|
|
||||||
sizeChangeHandle,
|
|
||||||
sortChangeHandle,
|
|
||||||
downBlobFile
|
|
||||||
} = useTable(state)
|
|
||||||
|
|
||||||
|
// 清空搜索条件
|
||||||
|
const resetQuery = () => {
|
||||||
// 清空搜索条件
|
// 清空搜索条件
|
||||||
const resetQuery = () => {
|
queryRef.value?.resetFields();
|
||||||
// 清空搜索条件
|
|
||||||
queryRef.value?.resetFields()
|
|
||||||
// 清空多选
|
// 清空多选
|
||||||
selectObjs.value = []
|
selectObjs.value = [];
|
||||||
getDataList()
|
getDataList();
|
||||||
}
|
};
|
||||||
|
|
||||||
// 导出excel
|
// 导出excel
|
||||||
const exportExcel = () => {
|
const exportExcel = () => {
|
||||||
downBlobFile('/order/create-table/export', state.queryForm, 'create-table.xlsx')
|
downBlobFile('/order/create-table/export', state.queryForm, 'create-table.xlsx');
|
||||||
}
|
};
|
||||||
|
|
||||||
// 多选事件
|
// 多选事件
|
||||||
const handleSelectionChange = (objs: any) => {
|
const handleSelectionChange = (objs: any) => {
|
||||||
selectObjs.value = objs.map(({ id }) => id);
|
selectObjs.value = objs.map(({ id }) => id);
|
||||||
multiple.value = !objs.length;
|
multiple.value = !objs.length;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 删除操作
|
// 删除操作
|
||||||
const handleDelete = async (ids: string[]) => {
|
const handleDelete = async (ids: string[]) => {
|
||||||
try {
|
try {
|
||||||
await useMessageBox().confirm(t('common.delConfirmText'));
|
await useMessageBox().confirm(t('common.delConfirmText'));
|
||||||
} catch {
|
} catch {
|
||||||
@@ -166,5 +170,5 @@
|
|||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
useMessage().error(err.msg);
|
useMessage().error(err.msg);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,44 +1,58 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-form ref="dataFormRef" :model="form" :rules="dataRules" label-width="90px" v-loading="loading"
|
<el-form ref="dataFormRef" :model="form" :rules="dataRules" label-width="90px" v-loading="loading" :disabled="operType === 'view'">
|
||||||
:disabled="operType === 'view'">
|
|
||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<el-col :span="12" class="mb20" v-if="!hiddenFields.type">
|
<el-col :span="12" class="mb20" v-if="!hiddenFields.type">
|
||||||
<el-form-item :label="t('askLeave.type')" prop="type">
|
<el-form-item :label="t('askLeave.type')" prop="type">
|
||||||
<el-input v-model="form.type" :placeholder="t('askLeave.inputTypeTip')" :disabled="disabledFields.type"/>
|
<el-input v-model="form.type" :placeholder="t('askLeave.inputTypeTip')" :disabled="disabledFields.type" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20" v-if="!hiddenFields.startTime">
|
<el-col :span="12" class="mb20" v-if="!hiddenFields.startTime">
|
||||||
<el-form-item :label="t('askLeave.startTime')" prop="startTime">
|
<el-form-item :label="t('askLeave.startTime')" prop="startTime">
|
||||||
<el-date-picker type="datetime" :placeholder="t('askLeave.inputStartTimeTip')" :disabled="disabledFields.startTime"
|
<el-date-picker
|
||||||
v-model="form.startTime" :value-format="dateTimeStr"></el-date-picker>
|
type="datetime"
|
||||||
|
:placeholder="t('askLeave.inputStartTimeTip')"
|
||||||
|
:disabled="disabledFields.startTime"
|
||||||
|
v-model="form.startTime"
|
||||||
|
:value-format="dateTimeStr"
|
||||||
|
></el-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20" v-if="!hiddenFields.endTime">
|
<el-col :span="12" class="mb20" v-if="!hiddenFields.endTime">
|
||||||
<el-form-item :label="t('askLeave.endTime')" prop="endTime">
|
<el-form-item :label="t('askLeave.endTime')" prop="endTime">
|
||||||
<el-date-picker type="datetime" :placeholder="t('askLeave.inputEndTimeTip')" :disabled="disabledFields.endTime"
|
<el-date-picker
|
||||||
v-model="form.endTime" :value-format="dateTimeStr"></el-date-picker>
|
type="datetime"
|
||||||
|
:placeholder="t('askLeave.inputEndTimeTip')"
|
||||||
|
:disabled="disabledFields.endTime"
|
||||||
|
v-model="form.endTime"
|
||||||
|
:value-format="dateTimeStr"
|
||||||
|
></el-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20" v-if="!hiddenFields.days">
|
<el-col :span="12" class="mb20" v-if="!hiddenFields.days">
|
||||||
<el-form-item :label="t('askLeave.days')" prop="days">
|
<el-form-item :label="t('askLeave.days')" prop="days">
|
||||||
<el-input v-model="form.days" :placeholder="t('askLeave.inputDaysTip')" :disabled="disabledFields.days"/>
|
<el-input v-model="form.days" :placeholder="t('askLeave.inputDaysTip')" :disabled="disabledFields.days" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20" v-if="!hiddenFields.carbonCopyPerson">
|
<el-col :span="12" class="mb20" v-if="!hiddenFields.carbonCopyPerson">
|
||||||
<el-form-item :label="t('askLeave.carbonCopyPerson')" prop="carbonCopyPerson">
|
<el-form-item :label="t('askLeave.carbonCopyPerson')" prop="carbonCopyPerson">
|
||||||
<el-tooltip content="请输入用户名称进行模糊搜索" placement="top">
|
<el-tooltip content="请输入用户名称进行模糊搜索" placement="top">
|
||||||
<el-select v-model="form.carbonCopyPerson" :placeholder="t('askLeave.inputCarbonCopyPersonTip')" :disabled="disabledFields.carbonCopyPerson"
|
<el-select
|
||||||
remote :remote-method="remoteMethod" :reserve-keyword="false"
|
v-model="form.carbonCopyPerson"
|
||||||
clearable filterable multiple>
|
:placeholder="t('askLeave.inputCarbonCopyPersonTip')"
|
||||||
<el-option v-for="(item, index) in dicData.carbonCopyPerson" :key="index" :label="item.name"
|
:disabled="disabledFields.carbonCopyPerson"
|
||||||
:value="item.userId">
|
remote
|
||||||
|
:remote-method="remoteMethod"
|
||||||
</el-option>
|
:reserve-keyword="false"
|
||||||
|
clearable
|
||||||
|
filterable
|
||||||
|
multiple
|
||||||
|
>
|
||||||
|
<el-option v-for="(item, index) in dicData.carbonCopyPerson" :key="index" :label="item.name" :value="item.userId"> </el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -46,25 +60,21 @@
|
|||||||
|
|
||||||
<el-col :span="12" class="mb20" v-if="!hiddenFields.remark">
|
<el-col :span="12" class="mb20" v-if="!hiddenFields.remark">
|
||||||
<el-form-item :label="t('askLeave.remark')" prop="remark">
|
<el-form-item :label="t('askLeave.remark')" prop="remark">
|
||||||
<el-input v-model="form.remark" type="textarea" :placeholder="t('askLeave.inputRemarkTip')" :disabled="disabledFields.remark"/>
|
<el-input v-model="form.remark" type="textarea" :placeholder="t('askLeave.inputRemarkTip')" :disabled="disabledFields.remark" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20" v-if="!hiddenFields.imgUrls">
|
<el-col :span="12" class="mb20" v-if="!hiddenFields.imgUrls">
|
||||||
<el-form-item :label="t('askLeave.imgUrls')" prop="imgUrls">
|
<el-form-item :label="t('askLeave.imgUrls')" prop="imgUrls">
|
||||||
<el-input v-model="form.imgUrls" :placeholder="t('askLeave.inputImgUrlsTip')" :disabled="disabledFields.imgUrls"/>
|
<el-input v-model="form.imgUrls" :placeholder="t('askLeave.inputImgUrlsTip')" :disabled="disabledFields.imgUrls" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template v-if="data.submitBtn">
|
<template v-if="data.submitBtn">
|
||||||
<footer class="el-dialog__footer">
|
<footer class="el-dialog__footer">
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button type="primary" @click="printForm" v-if="data.currFlowForm.printInfo">{{
|
<el-button type="primary" @click="printForm" v-if="data.currFlowForm.printInfo">{{ t('jfI18n.print') }} </el-button>
|
||||||
t('jfI18n.print')
|
|
||||||
}}
|
|
||||||
</el-button>
|
|
||||||
<el-button type="primary" @click="submitForm" :disabled="loading">{{ t('jfI18n.submit') }}</el-button>
|
<el-button type="primary" @click="submitForm" :disabled="loading">{{ t('jfI18n.submit') }}</el-button>
|
||||||
</span>
|
</span>
|
||||||
</footer>
|
</footer>
|
||||||
@@ -72,59 +82,53 @@
|
|||||||
<template v-else>
|
<template v-else>
|
||||||
<footer class="el-dialog__footer">
|
<footer class="el-dialog__footer">
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button type="primary" @click="printForm" v-if="data.currFlowForm.printInfo">{{
|
<el-button type="primary" @click="printForm" v-if="data.currFlowForm.printInfo">{{ t('jfI18n.print') }} </el-button>
|
||||||
t('jfI18n.print')
|
|
||||||
}}
|
|
||||||
</el-button>
|
|
||||||
</span>
|
</span>
|
||||||
</footer>
|
</footer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 打印表单 -->
|
<!-- 打印表单 -->
|
||||||
<el-dialog v-model="data.showTinymceView" top="20px" width="700px"
|
<el-dialog v-model="data.showTinymceView" top="20px" width="700px" :title="data.tinymceTitle" append-to-body @close="closePrint">
|
||||||
:title="data.tinymceTitle" append-to-body
|
|
||||||
@close="closePrint">
|
|
||||||
<tinymce-view v-if="data.showTinymceView" :currFlowForm="data.currFlowForm" :elTab="data.elTab"></tinymce-view>
|
<tinymce-view v-if="data.showTinymceView" :currFlowForm="data.currFlowForm" :elTab="data.elTab"></tinymce-view>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="CustomLeaveFlow">
|
<script setup lang="ts" name="CustomLeaveFlow">
|
||||||
|
import { useMessage } from '/@/hooks/message';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { rule, validateNull } from '/@/utils/validate';
|
||||||
|
import { onFormLoadedUrl, onLoadDicUrl, remoteMethodByKey } from '/@/flow/components/convert-name/convert.ts';
|
||||||
|
import * as orderVue from '/@/api/order/order-key-vue';
|
||||||
|
import * as runApplication from '/@/api/order/run-application';
|
||||||
|
import { parseWithFunctions } from '/@/flow';
|
||||||
|
import { deepClone } from '/@/utils/other';
|
||||||
|
import { handleCustomFormPerm, handleFormPrint } from '/@/flow/utils/form-perm';
|
||||||
|
import { initCustomFormMethods } from '../index';
|
||||||
|
|
||||||
import {useMessage} from "/@/hooks/message";
|
const { t } = useI18n();
|
||||||
import {useI18n} from "vue-i18n"
|
const emits = defineEmits(['handleJob']);
|
||||||
import {rule, validateNull} from '/@/utils/validate';
|
// 引入组件
|
||||||
import {onFormLoadedUrl, onLoadDicUrl, remoteMethodByKey} from "/@/flow/components/convert-name/convert.ts";
|
const TinymceView = defineAsyncComponent(() => import('/@/flow/components/tinymce/TinymceView.vue'));
|
||||||
import * as orderVue from "/@/api/order/order-key-vue";
|
|
||||||
import * as runApplication from "/@/api/order/run-application";
|
|
||||||
import {parseWithFunctions} from "/@/flow";
|
|
||||||
import {deepClone} from "/@/utils/other";
|
|
||||||
import {handleCustomFormPerm, handleFormPrint} from "/@/flow/utils/form-perm";
|
|
||||||
import {initCustomFormMethods} from "../index";
|
|
||||||
|
|
||||||
const {t} = useI18n();
|
// 定义变量内容
|
||||||
const emits = defineEmits(["handleJob"]);
|
const dataFormRef = ref();
|
||||||
// 引入组件
|
const loading = ref(false);
|
||||||
const TinymceView = defineAsyncComponent(() => import('/@/flow/components/tinymce/TinymceView.vue'));
|
const operType = ref(false);
|
||||||
|
// 定义字典
|
||||||
// 定义变量内容
|
const dicData = reactive({});
|
||||||
const dataFormRef = ref();
|
const onLoad = onLoadDicUrl();
|
||||||
const loading = ref(false);
|
const onFormLoaded = onFormLoadedUrl({ key: 'carbonCopyPerson' });
|
||||||
const operType = ref(false);
|
onMounted(async () => {
|
||||||
// 定义字典
|
|
||||||
const dicData = reactive({});
|
|
||||||
const onLoad = onLoadDicUrl();
|
|
||||||
const onFormLoaded = onFormLoadedUrl({key: "carbonCopyPerson"});
|
|
||||||
onMounted(async () => {
|
|
||||||
// await onLoad(dicData);
|
// await onLoad(dicData);
|
||||||
});
|
});
|
||||||
|
|
||||||
function remoteMethod(query: string) {
|
function remoteMethod(query: string) {
|
||||||
remoteMethodByKey(query, onLoad, dicData, 'userName', "carbonCopyPerson")
|
remoteMethodByKey(query, onLoad, dicData, 'userName', 'carbonCopyPerson');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 提交表单数据
|
// 提交表单数据
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
type: '',
|
type: '',
|
||||||
startTime: '',
|
startTime: '',
|
||||||
endTime: '',
|
endTime: '',
|
||||||
@@ -132,16 +136,16 @@
|
|||||||
carbonCopyPerson: [],
|
carbonCopyPerson: [],
|
||||||
remark: '',
|
remark: '',
|
||||||
imgUrls: '',
|
imgUrls: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
// 定义校验规则
|
// 定义校验规则
|
||||||
const dataRules = ref({
|
const dataRules = ref({
|
||||||
startTime: [{required: true, message: '开始时间不能为空', trigger: 'blur'}],
|
startTime: [{ required: true, message: '开始时间不能为空', trigger: 'blur' }],
|
||||||
days: [{required: true, message: '请假天数不能为空', trigger: 'blur'}],
|
days: [{ required: true, message: '请假天数不能为空', trigger: 'blur' }],
|
||||||
remark: [{required: true, message: '请假事由不能为空', trigger: 'blur'}],
|
remark: [{ required: true, message: '请假事由不能为空', trigger: 'blur' }],
|
||||||
})
|
});
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
currJob: {
|
currJob: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: null,
|
default: null,
|
||||||
@@ -150,22 +154,22 @@
|
|||||||
type: Object,
|
type: Object,
|
||||||
default: {},
|
default: {},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
currFlowForm: {},
|
currFlowForm: {},
|
||||||
formData: {},
|
formData: {},
|
||||||
showTinymceView: false,
|
showTinymceView: false,
|
||||||
tinymceTitle: null,
|
tinymceTitle: null,
|
||||||
submitBtn: true,
|
submitBtn: true,
|
||||||
elTab: null
|
elTab: null,
|
||||||
})
|
});
|
||||||
|
|
||||||
function initJobData() {
|
function initJobData() {
|
||||||
handleGetObj(props.currJob.orderId)
|
handleGetObj(props.currJob.orderId);
|
||||||
}
|
}
|
||||||
|
|
||||||
const fieldsPerm = {
|
const fieldsPerm = {
|
||||||
type: false,
|
type: false,
|
||||||
startTime: false,
|
startTime: false,
|
||||||
endTime: false,
|
endTime: false,
|
||||||
@@ -173,103 +177,102 @@
|
|||||||
carbonCopyPerson: false,
|
carbonCopyPerson: false,
|
||||||
remark: false,
|
remark: false,
|
||||||
imgUrls: false,
|
imgUrls: false,
|
||||||
}
|
};
|
||||||
// 定义字段显隐
|
// 定义字段显隐
|
||||||
const hiddenFields = reactive(fieldsPerm);
|
const hiddenFields = reactive(fieldsPerm);
|
||||||
// 定义字段是否可编辑
|
// 定义字段是否可编辑
|
||||||
const disabledFields = reactive(deepClone(fieldsPerm));
|
const disabledFields = reactive(deepClone(fieldsPerm));
|
||||||
|
|
||||||
function handleGetObj(id) {
|
function handleGetObj(id) {
|
||||||
runApplication.getObj(id).then(async resp => {
|
runApplication.getObj(id).then(async (resp) => {
|
||||||
let res = resp.data ? resp.data : {}
|
let res = resp.data ? resp.data : {};
|
||||||
data.currFlowForm = res
|
data.currFlowForm = res;
|
||||||
let data2 = parseWithFunctions(res.formData)
|
let data2 = parseWithFunctions(res.formData);
|
||||||
Object.assign(form, data2)
|
Object.assign(form, data2);
|
||||||
await onFormLoaded(dicData, form);
|
await onFormLoaded(dicData, form);
|
||||||
data.currFlowForm.runJobId = props.currJob.id
|
data.currFlowForm.runJobId = props.currJob.id;
|
||||||
data.formData = data2
|
data.formData = data2;
|
||||||
await initFormPermPrint()
|
await initFormPermPrint();
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const methods = initCustomFormMethods(data, disabledFields, operType)
|
const methods = initCustomFormMethods(data, disabledFields, operType);
|
||||||
|
|
||||||
async function initFormPermPrint() {
|
async function initFormPermPrint() {
|
||||||
let elTab = orderVue.currElTabIsExist(props.currJob, props.currElTab.id)
|
let elTab = orderVue.currElTabIsExist(props.currJob, props.currElTab.id);
|
||||||
// 处理表单权限
|
// 处理表单权限
|
||||||
let res = await handleCustomFormPerm(props, hiddenFields, disabledFields, elTab)
|
let res = await handleCustomFormPerm(props, hiddenFields, disabledFields, elTab);
|
||||||
// 判断是否仅查看
|
// 判断是否仅查看
|
||||||
await orderVue.currElTabIsView(methods, props.currJob, props.currElTab.id, submitForm, res.callback)
|
await orderVue.currElTabIsView(methods, props.currJob, props.currElTab.id, submitForm, res.callback);
|
||||||
// 采用elTab配置的模板
|
// 采用elTab配置的模板
|
||||||
await handleFormPrint(data.currFlowForm, elTab.type, elTab.id, '1')
|
await handleFormPrint(data.currFlowForm, elTab.type, elTab.id, '1');
|
||||||
data.elTab = elTab
|
data.elTab = elTab;
|
||||||
}
|
}
|
||||||
|
|
||||||
function printForm() {
|
function printForm() {
|
||||||
closePrint(true, false)
|
closePrint(true, false);
|
||||||
data.tinymceTitle = data.currFlowForm.formName
|
data.tinymceTitle = data.currFlowForm.formName;
|
||||||
data.showTinymceView = true
|
data.showTinymceView = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function closePrint(isInit, isSave){
|
function closePrint(isInit, isSave) {
|
||||||
if (isInit) {
|
if (isInit) {
|
||||||
data.currFlowForm.formData = form
|
data.currFlowForm.formData = form;
|
||||||
data.currFlowForm.dicData = {carbonCopyPerson: dicData.carbonCopyPerson}
|
data.currFlowForm.dicData = { carbonCopyPerson: dicData.carbonCopyPerson };
|
||||||
data.currFlowForm['carbonCopyPerson.valueKey'] = 'userId'
|
data.currFlowForm['carbonCopyPerson.valueKey'] = 'userId';
|
||||||
data.currFlowForm['carbonCopyPerson.showKey'] = 'name'
|
data.currFlowForm['carbonCopyPerson.showKey'] = 'name';
|
||||||
} else {
|
} else {
|
||||||
delete data.currFlowForm.dicData
|
delete data.currFlowForm.dicData;
|
||||||
delete data.currFlowForm['carbonCopyPerson.valueKey']
|
delete data.currFlowForm['carbonCopyPerson.valueKey'];
|
||||||
delete data.currFlowForm['carbonCopyPerson.showKey']
|
delete data.currFlowForm['carbonCopyPerson.showKey'];
|
||||||
}
|
|
||||||
if (isSave) delete data.currFlowForm.printInfo
|
|
||||||
}
|
}
|
||||||
|
if (isSave) delete data.currFlowForm.printInfo;
|
||||||
|
}
|
||||||
|
|
||||||
async function submitForm() {
|
async function submitForm() {
|
||||||
try {
|
try {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
let formJson = saveInitData(form);
|
let formJson = saveInitData(form);
|
||||||
await runApplication.putObj(formJson)
|
await runApplication.putObj(formJson);
|
||||||
orderVue.currElTabIsSave(props.currJob, props.currElTab.id, true, emits)
|
orderVue.currElTabIsSave(props.currJob, props.currElTab.id, true, emits);
|
||||||
useMessage().success(t(formJson.id ? 'common.editSuccessText' : 'common.addSuccessText'));
|
useMessage().success(t(formJson.id ? 'common.editSuccessText' : 'common.addSuccessText'));
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
useMessage().error(err.msg);
|
useMessage().error(err.msg);
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveInitData(form) {
|
function saveInitData(form) {
|
||||||
closePrint(false, true)
|
closePrint(false, true);
|
||||||
data.currFlowForm.formData = validateNull(form) ? null : form
|
data.currFlowForm.formData = validateNull(form) ? null : form;
|
||||||
let formJson = deepClone(data.currFlowForm)
|
let formJson = deepClone(data.currFlowForm);
|
||||||
if (!validateNull(form)) {
|
if (!validateNull(form)) {
|
||||||
formJson.formData = Object.assign({}, data.formData, formJson.formData);
|
formJson.formData = Object.assign({}, data.formData, formJson.formData);
|
||||||
}
|
}
|
||||||
formJson.formData = JSON.stringify(formJson.formData)
|
formJson.formData = JSON.stringify(formJson.formData);
|
||||||
return formJson;
|
return formJson;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 监听双向绑定
|
// 监听双向绑定
|
||||||
watch(
|
watch(
|
||||||
() => props.currJob.id,
|
() => props.currJob.id,
|
||||||
() => {
|
() => {
|
||||||
initJobData();
|
initJobData();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
initJobData()
|
initJobData();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.el-dialog__footer {
|
.el-dialog__footer {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
.dialog-footer {
|
.dialog-footer {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -3,36 +3,54 @@
|
|||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<el-col :span="12" class="mb20" v-if="!hiddenFields.type">
|
<el-col :span="12" class="mb20" v-if="!hiddenFields.type">
|
||||||
<el-form-item :label="t('askLeave.type')" prop="type">
|
<el-form-item :label="t('askLeave.type')" prop="type">
|
||||||
<el-input v-model="form.type" :placeholder="t('askLeave.inputTypeTip')" :disabled="disabledFields.type"/>
|
<el-input v-model="form.type" :placeholder="t('askLeave.inputTypeTip')" :disabled="disabledFields.type" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20" v-if="!hiddenFields.startTime">
|
<el-col :span="12" class="mb20" v-if="!hiddenFields.startTime">
|
||||||
<el-form-item :label="t('askLeave.startTime')" prop="startTime">
|
<el-form-item :label="t('askLeave.startTime')" prop="startTime">
|
||||||
<el-date-picker type="datetime" :placeholder="t('askLeave.inputStartTimeTip')" :disabled="disabledFields.startTime"
|
<el-date-picker
|
||||||
v-model="form.startTime" :value-format="dateTimeStr"></el-date-picker>
|
type="datetime"
|
||||||
|
:placeholder="t('askLeave.inputStartTimeTip')"
|
||||||
|
:disabled="disabledFields.startTime"
|
||||||
|
v-model="form.startTime"
|
||||||
|
:value-format="dateTimeStr"
|
||||||
|
></el-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20" v-if="!hiddenFields.endTime">
|
<el-col :span="12" class="mb20" v-if="!hiddenFields.endTime">
|
||||||
<el-form-item :label="t('askLeave.endTime')" prop="endTime">
|
<el-form-item :label="t('askLeave.endTime')" prop="endTime">
|
||||||
<el-date-picker type="datetime" :placeholder="t('askLeave.inputEndTimeTip')" :disabled="disabledFields.endTime"
|
<el-date-picker
|
||||||
v-model="form.endTime" :value-format="dateTimeStr"></el-date-picker>
|
type="datetime"
|
||||||
|
:placeholder="t('askLeave.inputEndTimeTip')"
|
||||||
|
:disabled="disabledFields.endTime"
|
||||||
|
v-model="form.endTime"
|
||||||
|
:value-format="dateTimeStr"
|
||||||
|
></el-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20" v-if="!hiddenFields.days">
|
<el-col :span="12" class="mb20" v-if="!hiddenFields.days">
|
||||||
<el-form-item :label="t('askLeave.days')" prop="days">
|
<el-form-item :label="t('askLeave.days')" prop="days">
|
||||||
<el-input v-model="form.days" :placeholder="t('askLeave.inputDaysTip')" :disabled="disabledFields.days"/>
|
<el-input v-model="form.days" :placeholder="t('askLeave.inputDaysTip')" :disabled="disabledFields.days" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20" v-if="!hiddenFields.carbonCopyPerson">
|
<el-col :span="12" class="mb20" v-if="!hiddenFields.carbonCopyPerson">
|
||||||
<el-form-item :label="t('askLeave.carbonCopyPerson')" prop="carbonCopyPerson">
|
<el-form-item :label="t('askLeave.carbonCopyPerson')" prop="carbonCopyPerson">
|
||||||
<el-tooltip content="请输入用户名称进行模糊搜索" placement="top">
|
<el-tooltip content="请输入用户名称进行模糊搜索" placement="top">
|
||||||
<el-select v-model="form.carbonCopyPerson" :placeholder="t('askLeave.inputCarbonCopyPersonTip')" clearable filterable multiple
|
<el-select
|
||||||
remote :remote-method="remoteMethod" :reserve-keyword="false"
|
v-model="form.carbonCopyPerson"
|
||||||
:disabled="disabledFields.carbonCopyPerson">
|
:placeholder="t('askLeave.inputCarbonCopyPersonTip')"
|
||||||
|
clearable
|
||||||
|
filterable
|
||||||
|
multiple
|
||||||
|
remote
|
||||||
|
:remote-method="remoteMethod"
|
||||||
|
:reserve-keyword="false"
|
||||||
|
:disabled="disabledFields.carbonCopyPerson"
|
||||||
|
>
|
||||||
<el-option v-for="(item, index) in dicData.carbonCopyPerson" :key="index" :label="item.name" :value="item.userId"></el-option>
|
<el-option v-for="(item, index) in dicData.carbonCopyPerson" :key="index" :label="item.name" :value="item.userId"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
@@ -41,66 +59,64 @@
|
|||||||
|
|
||||||
<el-col :span="12" class="mb20" v-if="!hiddenFields.remark">
|
<el-col :span="12" class="mb20" v-if="!hiddenFields.remark">
|
||||||
<el-form-item :label="t('askLeave.remark')" prop="remark">
|
<el-form-item :label="t('askLeave.remark')" prop="remark">
|
||||||
<el-input v-model="form.remark" type="textarea" :placeholder="t('askLeave.inputRemarkTip')" :disabled="disabledFields.remark"/>
|
<el-input v-model="form.remark" type="textarea" :placeholder="t('askLeave.inputRemarkTip')" :disabled="disabledFields.remark" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20" v-if="!hiddenFields.imgUrls">
|
<el-col :span="12" class="mb20" v-if="!hiddenFields.imgUrls">
|
||||||
<el-form-item :label="t('askLeave.imgUrls')" prop="imgUrls">
|
<el-form-item :label="t('askLeave.imgUrls')" prop="imgUrls">
|
||||||
<el-input v-model="form.imgUrls" :placeholder="t('askLeave.inputImgUrlsTip')" :disabled="disabledFields.imgUrls"/>
|
<el-input v-model="form.imgUrls" :placeholder="t('askLeave.inputImgUrlsTip')" :disabled="disabledFields.imgUrls" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="CustomLeaveForm">
|
<script setup lang="ts" name="CustomLeaveForm">
|
||||||
|
import { useMessage } from '/@/hooks/message';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { rule, validateNull } from '/@/utils/validate';
|
||||||
|
import { onFormLoadedUrl, onLoadDicUrl, remoteMethodByKey } from '/@/flow/components/convert-name/convert.ts';
|
||||||
|
import * as common from '/@/flow/support/common';
|
||||||
|
import { paramsFilter, parseWithFunctions } from '/@/flow';
|
||||||
|
import { deepClone } from '/@/utils/other';
|
||||||
|
import * as runApplication from '/@/api/order/run-application';
|
||||||
|
import { handleFormPrint, handleFormStartPerm } from '/@/flow/utils/form-perm';
|
||||||
|
import { DIC_PROP } from '/@/flow/support/dict-prop';
|
||||||
|
import { initCustomFormMethods } from '../index';
|
||||||
|
import { currFormIsView } from '/@/api/order/order-key-vue';
|
||||||
|
|
||||||
import { useMessage } from "/@/hooks/message";
|
const { t } = useI18n();
|
||||||
import { useI18n } from "vue-i18n"
|
|
||||||
import {rule, validateNull} from '/@/utils/validate';
|
|
||||||
import {onFormLoadedUrl, onLoadDicUrl, remoteMethodByKey} from "/@/flow/components/convert-name/convert.ts";
|
|
||||||
import * as common from '/@/flow/support/common'
|
|
||||||
import {paramsFilter, parseWithFunctions} from "/@/flow";
|
|
||||||
import {deepClone} from "/@/utils/other";
|
|
||||||
import * as runApplication from "/@/api/order/run-application";
|
|
||||||
import {handleFormPrint, handleFormStartPerm} from "/@/flow/utils/form-perm";
|
|
||||||
import {DIC_PROP} from "/@/flow/support/dict-prop";
|
|
||||||
import {initCustomFormMethods} from "../index";
|
|
||||||
import {currFormIsView} from "/@/api/order/order-key-vue";
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
const props = defineProps({
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
currJob: {
|
currJob: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: null,
|
default: null,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// 定义变量内容
|
// 定义变量内容
|
||||||
const dataFormRef = ref();
|
const dataFormRef = ref();
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const operType = ref(false);
|
const operType = ref(false);
|
||||||
// 定义字典
|
// 定义字典
|
||||||
const dicData = reactive({});
|
const dicData = reactive({});
|
||||||
const onLoad = onLoadDicUrl();
|
const onLoad = onLoadDicUrl();
|
||||||
const onFormLoaded = onFormLoadedUrl({key: "carbonCopyPerson"});
|
const onFormLoaded = onFormLoadedUrl({ key: 'carbonCopyPerson' });
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
// await onLoad(dicData);
|
// await onLoad(dicData);
|
||||||
openForm(props.currJob.operType, props.currJob.id)
|
openForm(props.currJob.operType, props.currJob.id);
|
||||||
props.currJob.onSubmit = onSubmit
|
props.currJob.onSubmit = onSubmit;
|
||||||
props.currJob.onTemp = onTemp
|
props.currJob.onTemp = onTemp;
|
||||||
props.currJob.getFormData = getFormData
|
props.currJob.getFormData = getFormData;
|
||||||
});
|
});
|
||||||
|
|
||||||
function remoteMethod(query: string) {
|
function remoteMethod(query: string) {
|
||||||
remoteMethodByKey(query, onLoad, dicData, 'userName', "carbonCopyPerson")
|
remoteMethodByKey(query, onLoad, dicData, 'userName', 'carbonCopyPerson');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 提交表单数据
|
// 提交表单数据
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
type: '',
|
type: '',
|
||||||
startTime: '',
|
startTime: '',
|
||||||
endTime: '',
|
endTime: '',
|
||||||
@@ -108,17 +124,17 @@
|
|||||||
carbonCopyPerson: [],
|
carbonCopyPerson: [],
|
||||||
remark: '',
|
remark: '',
|
||||||
imgUrls: '',
|
imgUrls: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
// 定义校验规则
|
// 定义校验规则
|
||||||
const dataRules = ref({
|
const dataRules = ref({
|
||||||
startTime: [{required: true, message: '开始时间不能为空', trigger: 'blur'}],
|
startTime: [{ required: true, message: '开始时间不能为空', trigger: 'blur' }],
|
||||||
days: [{required: true, message: '请假天数不能为空', trigger: 'blur'}],
|
days: [{ required: true, message: '请假天数不能为空', trigger: 'blur' }],
|
||||||
remark: [{required: true, message: '请假事由不能为空', trigger: 'blur'}],
|
remark: [{ required: true, message: '请假事由不能为空', trigger: 'blur' }],
|
||||||
})
|
});
|
||||||
|
|
||||||
// 打开表单
|
// 打开表单
|
||||||
const openForm = (type: string, id: string) => {
|
const openForm = (type: string, id: string) => {
|
||||||
operType.value = type;
|
operType.value = type;
|
||||||
|
|
||||||
// 重置表单数据
|
// 重置表单数据
|
||||||
@@ -126,12 +142,12 @@
|
|||||||
dataFormRef.value?.resetFields();
|
dataFormRef.value?.resetFields();
|
||||||
// 获取表单信息
|
// 获取表单信息
|
||||||
if (id) {
|
if (id) {
|
||||||
rowEditInitData(type, id)
|
rowEditInitData(type, id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const fieldsPerm = {
|
const fieldsPerm = {
|
||||||
type: false,
|
type: false,
|
||||||
startTime: false,
|
startTime: false,
|
||||||
endTime: false,
|
endTime: false,
|
||||||
@@ -139,78 +155,78 @@
|
|||||||
carbonCopyPerson: false,
|
carbonCopyPerson: false,
|
||||||
remark: false,
|
remark: false,
|
||||||
imgUrls: false,
|
imgUrls: false,
|
||||||
}
|
};
|
||||||
// 定义字段显隐
|
// 定义字段显隐
|
||||||
const hiddenFields = reactive(fieldsPerm);
|
const hiddenFields = reactive(fieldsPerm);
|
||||||
// 定义字段是否可编辑
|
// 定义字段是否可编辑
|
||||||
const disabledFields = reactive(deepClone(fieldsPerm));
|
const disabledFields = reactive(deepClone(fieldsPerm));
|
||||||
|
|
||||||
const methods = initCustomFormMethods({}, disabledFields)
|
const methods = initCustomFormMethods({}, disabledFields);
|
||||||
|
|
||||||
async function rowEditInitData(type, id) {
|
async function rowEditInitData(type, id) {
|
||||||
// 处理表单权限 开始节点必须配置表单
|
// 处理表单权限 开始节点必须配置表单
|
||||||
let res = await handleFormStartPerm(hiddenFields, disabledFields, null, props.currJob.defFlowId, null, null)
|
let res = await handleFormStartPerm(hiddenFields, disabledFields, null, props.currJob.defFlowId, null, null);
|
||||||
await currFormIsView(methods, res.elTab, true, res.callback)
|
await currFormIsView(methods, res.elTab, true, res.callback);
|
||||||
if (type === 'add') {
|
if (type === 'add') {
|
||||||
props.currJob.formId = id
|
props.currJob.formId = id;
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
if (validateNull(props.currJob.formData)) return
|
if (validateNull(props.currJob.formData)) return;
|
||||||
let data = parseWithFunctions(props.currJob.formData)
|
let data = parseWithFunctions(props.currJob.formData);
|
||||||
Object.assign(form, data)
|
Object.assign(form, data);
|
||||||
await onFormLoaded(dicData, form);
|
await onFormLoaded(dicData, form);
|
||||||
await initFormPermPrint()
|
await initFormPermPrint();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function initFormPermPrint() {
|
async function initFormPermPrint() {
|
||||||
// 处理表单权限
|
// 处理表单权限
|
||||||
await handleFormPrint(props.currJob, props.currJob.type, props.currJob.formId, '1')
|
await handleFormPrint(props.currJob, props.currJob.type, props.currJob.formId, '1');
|
||||||
props.currJob.resolvePrintForm = printForm
|
props.currJob.resolvePrintForm = printForm;
|
||||||
props.currJob.resolveClosePrint = closePrint
|
props.currJob.resolveClosePrint = closePrint;
|
||||||
}
|
}
|
||||||
|
|
||||||
function printForm() {
|
function printForm() {
|
||||||
closePrint(true, false)
|
closePrint(true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
function closePrint(isInit, isSave){
|
function closePrint(isInit, isSave) {
|
||||||
if (isInit) {
|
if (isInit) {
|
||||||
props.currJob.formData = form
|
props.currJob.formData = form;
|
||||||
props.currJob.dicData = {carbonCopyPerson: dicData.carbonCopyPerson}
|
props.currJob.dicData = { carbonCopyPerson: dicData.carbonCopyPerson };
|
||||||
props.currJob['carbonCopyPerson.valueKey'] = 'userId'
|
props.currJob['carbonCopyPerson.valueKey'] = 'userId';
|
||||||
props.currJob['carbonCopyPerson.showKey'] = 'name'
|
props.currJob['carbonCopyPerson.showKey'] = 'name';
|
||||||
} else {
|
} else {
|
||||||
delete props.currJob.dicData
|
delete props.currJob.dicData;
|
||||||
delete props.currJob['carbonCopyPerson.valueKey']
|
delete props.currJob['carbonCopyPerson.valueKey'];
|
||||||
delete props.currJob['carbonCopyPerson.showKey']
|
delete props.currJob['carbonCopyPerson.showKey'];
|
||||||
}
|
|
||||||
if (isSave) delete props.currJob.printInfo
|
|
||||||
}
|
}
|
||||||
|
if (isSave) delete props.currJob.printInfo;
|
||||||
|
}
|
||||||
|
|
||||||
// 暂存
|
// 暂存
|
||||||
const onTemp = async () => {
|
const onTemp = async () => {
|
||||||
let clone = {operType: operType.value, form: form};
|
let clone = { operType: operType.value, form: form };
|
||||||
common.handleCloneSubmit(clone);
|
common.handleCloneSubmit(clone);
|
||||||
try {
|
try {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
let formJson = saveInitData(form);
|
let formJson = saveInitData(form);
|
||||||
await runApplication.tempStore(formJson)
|
await runApplication.tempStore(formJson);
|
||||||
useMessage().success("暂存成功,请在【我的申请】查看");
|
useMessage().success('暂存成功,请在【我的申请】查看');
|
||||||
return true;
|
return true;
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
useMessage().error(err.msg);
|
useMessage().error(err.msg);
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// 提交
|
// 提交
|
||||||
const onSubmit = async () => {
|
const onSubmit = async () => {
|
||||||
const valid = await dataFormRef.value.validate().catch(() => {});
|
const valid = await dataFormRef.value.validate().catch(() => {});
|
||||||
if (!valid) return false;
|
if (!valid) return false;
|
||||||
|
|
||||||
let clone = {operType: operType.value, form: form};
|
let clone = { operType: operType.value, form: form };
|
||||||
common.handleCloneSubmit(clone)
|
common.handleCloneSubmit(clone);
|
||||||
try {
|
try {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
let formJson = saveInitData(form);
|
let formJson = saveInitData(form);
|
||||||
@@ -222,21 +238,20 @@
|
|||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function saveInitData(form) {
|
function saveInitData(form) {
|
||||||
closePrint(false, true)
|
closePrint(false, true);
|
||||||
form = paramsFilter(form)
|
form = paramsFilter(form);
|
||||||
props.currJob.formData = validateNull(form) ? undefined : form
|
props.currJob.formData = validateNull(form) ? undefined : form;
|
||||||
let formJson = deepClone(props.currJob)
|
let formJson = deepClone(props.currJob);
|
||||||
let clone = {operType: props.currJob.operType, form: formJson};
|
let clone = { operType: props.currJob.operType, form: formJson };
|
||||||
common.handleCloneSubmit(clone)
|
common.handleCloneSubmit(clone);
|
||||||
formJson.formData = JSON.stringify(formJson.formData)
|
formJson.formData = JSON.stringify(formJson.formData);
|
||||||
return formJson;
|
return formJson;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getFormData() {
|
async function getFormData() {
|
||||||
return saveInitData(form);
|
return saveInitData(form);
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -3,25 +3,35 @@
|
|||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<el-col :span="12" class="mb20">
|
<el-col :span="12" class="mb20">
|
||||||
<el-form-item :label="t('askLeave.type')" prop="type">
|
<el-form-item :label="t('askLeave.type')" prop="type">
|
||||||
<el-input v-model="form.type" :placeholder="t('askLeave.inputTypeTip')"/>
|
<el-input v-model="form.type" :placeholder="t('askLeave.inputTypeTip')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
<el-col :span="12" class="mb20">
|
||||||
<el-form-item :label="t('askLeave.startTime')" prop="startTime">
|
<el-form-item :label="t('askLeave.startTime')" prop="startTime">
|
||||||
<el-date-picker type="datetime" :placeholder="t('askLeave.inputStartTimeTip')" v-model="form.startTime" :value-format="dateTimeStr"></el-date-picker>
|
<el-date-picker
|
||||||
|
type="datetime"
|
||||||
|
:placeholder="t('askLeave.inputStartTimeTip')"
|
||||||
|
v-model="form.startTime"
|
||||||
|
:value-format="dateTimeStr"
|
||||||
|
></el-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
<el-col :span="12" class="mb20">
|
||||||
<el-form-item :label="t('askLeave.endTime')" prop="endTime">
|
<el-form-item :label="t('askLeave.endTime')" prop="endTime">
|
||||||
<el-date-picker type="datetime" :placeholder="t('askLeave.inputEndTimeTip')" v-model="form.endTime" :value-format="dateTimeStr"></el-date-picker>
|
<el-date-picker
|
||||||
|
type="datetime"
|
||||||
|
:placeholder="t('askLeave.inputEndTimeTip')"
|
||||||
|
v-model="form.endTime"
|
||||||
|
:value-format="dateTimeStr"
|
||||||
|
></el-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
<el-col :span="12" class="mb20">
|
||||||
<el-form-item :label="t('askLeave.days')" prop="days">
|
<el-form-item :label="t('askLeave.days')" prop="days">
|
||||||
<el-input v-model="form.days" :placeholder="t('askLeave.inputDaysTip')"/>
|
<el-input v-model="form.days" :placeholder="t('askLeave.inputDaysTip')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
@@ -35,55 +45,53 @@
|
|||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
<el-col :span="12" class="mb20">
|
||||||
<el-form-item :label="t('askLeave.remark')" prop="remark">
|
<el-form-item :label="t('askLeave.remark')" prop="remark">
|
||||||
<el-input v-model="form.remark" type="textarea" :placeholder="t('askLeave.inputRemarkTip')"/>
|
<el-input v-model="form.remark" type="textarea" :placeholder="t('askLeave.inputRemarkTip')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
<el-col :span="12" class="mb20">
|
||||||
<el-form-item :label="t('askLeave.imgUrls')" prop="imgUrls">
|
<el-form-item :label="t('askLeave.imgUrls')" prop="imgUrls">
|
||||||
<el-input v-model="form.imgUrls" :placeholder="t('askLeave.inputImgUrlsTip')"/>
|
<el-input v-model="form.imgUrls" :placeholder="t('askLeave.inputImgUrlsTip')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="CustomAskLeave">
|
<script setup lang="ts" name="CustomAskLeave">
|
||||||
|
import { useMessage } from '/@/hooks/message';
|
||||||
|
import { getObj, addObj, putObj, tempStore } from '/@/api/order/ask-leave';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { rule } from '/@/utils/validate';
|
||||||
|
import { onLoadDicUrl } from '/@/flow/components/convert-name/convert.ts';
|
||||||
|
import * as common from '/@/flow/support/common';
|
||||||
|
import { DIC_PROP } from '/@/flow/support/dict-prop';
|
||||||
|
|
||||||
import { useMessage } from "/@/hooks/message";
|
const { t } = useI18n();
|
||||||
import {getObj, addObj, putObj, tempStore} from '/@/api/order/ask-leave'
|
|
||||||
import { useI18n } from "vue-i18n"
|
|
||||||
import { rule } from '/@/utils/validate';
|
|
||||||
import {onLoadDicUrl} from "/@/flow/components/convert-name/convert.ts";
|
|
||||||
import * as common from '/@/flow/support/common'
|
|
||||||
import {DIC_PROP} from "/@/flow/support/dict-prop";
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
const props = defineProps({
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
currJob: {
|
currJob: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: null,
|
default: null,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// 定义变量内容
|
// 定义变量内容
|
||||||
const dataFormRef = ref();
|
const dataFormRef = ref();
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const operType = ref(false);
|
const operType = ref(false);
|
||||||
// 定义字典
|
// 定义字典
|
||||||
const dicData = reactive({});
|
const dicData = reactive({});
|
||||||
const onLoad = onLoadDicUrl({key: "carbonCopyPerson"});
|
const onLoad = onLoadDicUrl({ key: 'carbonCopyPerson' });
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
onLoad(dicData);
|
onLoad(dicData);
|
||||||
openForm(props.currJob.operType, props.currJob.id)
|
openForm(props.currJob.operType, props.currJob.id);
|
||||||
props.currJob.onSubmit = onSubmit
|
props.currJob.onSubmit = onSubmit;
|
||||||
props.currJob.onTemp = onTemp
|
props.currJob.onTemp = onTemp;
|
||||||
});
|
});
|
||||||
|
|
||||||
// 提交表单数据
|
// 提交表单数据
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
type: '',
|
type: '',
|
||||||
startTime: '',
|
startTime: '',
|
||||||
endTime: '',
|
endTime: '',
|
||||||
@@ -91,19 +99,19 @@
|
|||||||
carbonCopyPerson: [],
|
carbonCopyPerson: [],
|
||||||
remark: '',
|
remark: '',
|
||||||
imgUrls: '',
|
imgUrls: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
// 定义校验规则
|
// 定义校验规则
|
||||||
const dataRules = ref({
|
const dataRules = ref({
|
||||||
startTime: [{required: true, message: '开始时间不能为空', trigger: 'blur'}],
|
startTime: [{ required: true, message: '开始时间不能为空', trigger: 'blur' }],
|
||||||
days: [{required: true, message: '请假天数不能为空', trigger: 'blur'}],
|
days: [{ required: true, message: '请假天数不能为空', trigger: 'blur' }],
|
||||||
remark: [{required: true, message: '请假事由不能为空', trigger: 'blur'}],
|
remark: [{ required: true, message: '请假事由不能为空', trigger: 'blur' }],
|
||||||
})
|
});
|
||||||
|
|
||||||
// 打开表单
|
// 打开表单
|
||||||
const openForm = (type: string, id: string) => {
|
const openForm = (type: string, id: string) => {
|
||||||
operType.value = type;
|
operType.value = type;
|
||||||
form.id = ''
|
form.id = '';
|
||||||
|
|
||||||
// 重置表单数据
|
// 重置表单数据
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
@@ -112,14 +120,14 @@
|
|||||||
|
|
||||||
// 获取AskLeave信息
|
// 获取AskLeave信息
|
||||||
if (id) {
|
if (id) {
|
||||||
form.id = id
|
form.id = id;
|
||||||
getAskLeaveData(id)
|
getAskLeaveData(id);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 暂存
|
// 暂存
|
||||||
const onTemp = async () => {
|
const onTemp = async () => {
|
||||||
let clone = {operType: operType.value, form: form};
|
let clone = { operType: operType.value, form: form };
|
||||||
common.handleCloneSubmit(clone);
|
common.handleCloneSubmit(clone);
|
||||||
try {
|
try {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
@@ -131,15 +139,15 @@
|
|||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// 提交
|
// 提交
|
||||||
const onSubmit = async () => {
|
const onSubmit = async () => {
|
||||||
const valid = await dataFormRef.value.validate().catch(() => {});
|
const valid = await dataFormRef.value.validate().catch(() => {});
|
||||||
if (!valid) return false;
|
if (!valid) return false;
|
||||||
|
|
||||||
let clone = {operType: operType.value, form: form};
|
let clone = { operType: operType.value, form: form };
|
||||||
common.handleCloneSubmit(clone)
|
common.handleCloneSubmit(clone);
|
||||||
try {
|
try {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
form.status !== DIC_PROP.ORDER_STATUS[0].value ? await addObj(form) : await putObj(form);
|
form.status !== DIC_PROP.ORDER_STATUS[0].value ? await addObj(form) : await putObj(form);
|
||||||
@@ -150,19 +158,20 @@
|
|||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 初始化表单数据
|
// 初始化表单数据
|
||||||
const getAskLeaveData = (id: string) => {
|
const getAskLeaveData = (id: string) => {
|
||||||
// 获取数据
|
// 获取数据
|
||||||
loading.value = true
|
loading.value = true;
|
||||||
getObj(id).then((res: any) => {
|
getObj(id)
|
||||||
Object.assign(form, res.data)
|
.then((res: any) => {
|
||||||
let clone = {operType: operType.value, form: form};
|
Object.assign(form, res.data);
|
||||||
|
let clone = { operType: operType.value, form: form };
|
||||||
common.handleClone(clone);
|
common.handleClone(clone);
|
||||||
}).finally(() => {
|
|
||||||
loading.value = false
|
|
||||||
})
|
})
|
||||||
};
|
.finally(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -47,6 +47,5 @@ export default {
|
|||||||
inputUpdateUserTip: 'input updateUser',
|
inputUpdateUserTip: 'input updateUser',
|
||||||
inputUpdateTimeTip: 'input updateTime',
|
inputUpdateTimeTip: 'input updateTime',
|
||||||
inputDelFlagTip: 'input delFlag',
|
inputDelFlagTip: 'input delFlag',
|
||||||
|
},
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
|||||||
@@ -47,6 +47,5 @@ export default {
|
|||||||
inputUpdateUserTip: '请输入修改人',
|
inputUpdateUserTip: '请输入修改人',
|
||||||
inputUpdateTimeTip: '请输入修改时间',
|
inputUpdateTimeTip: '请输入修改时间',
|
||||||
inputDelFlagTip: '请输入删除标',
|
inputDelFlagTip: '请输入删除标',
|
||||||
|
},
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,79 +1,70 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="layout-padding">
|
<div class="layout-padding">
|
||||||
|
|
||||||
<div style="background: #f4f4f5; margin-bottom: 10px" class="el_result_layout">
|
<div style="background: #f4f4f5; margin-bottom: 10px" class="el_result_layout">
|
||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-space class="el-space_container" @click="handleClickHref('TodoJobHash')">
|
<el-space class="el-space_container" @click="handleClickHref('TodoJobHash')">
|
||||||
<el-result style="width: 100px; padding: 0;">
|
<el-result style="width: 100px; padding: 0">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<el-icon :size="50" style="color: #409EFF;"><BellFilled /></el-icon>
|
<el-icon :size="50" style="color: #409eff"><BellFilled /></el-icon>
|
||||||
</template>
|
</template>
|
||||||
</el-result>
|
</el-result>
|
||||||
<el-card shadow="never" class="el-card__title__" style="width: 220px; border: none">
|
<el-card shadow="never" class="el-card__title__" style="width: 220px; border: none">
|
||||||
<template #header> 待我审批 </template>
|
<template #header> 待我审批 </template>
|
||||||
<div style="height: 23px; font-size: 30px; font-weight: bold;"> {{ useFlowJob().jobLen }} </div>
|
<div style="height: 23px; font-size: 30px; font-weight: bold">{{ useFlowJob().jobLen }}</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-space>
|
</el-space>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="4" style="padding: 0;">
|
<el-col :span="4" style="padding: 0">
|
||||||
<el-result class="el-result__style__" @click="handleClickHref('RunApplicationHash')"
|
<el-result class="el-result__style__" @click="handleClickHref('RunApplicationHash')" title="我的申请">
|
||||||
title="我的申请">
|
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<el-icon :size="40" style="color: #409EFF;"><Promotion /></el-icon>
|
<el-icon :size="40" style="color: #409eff"><Promotion /></el-icon>
|
||||||
</template>
|
</template>
|
||||||
</el-result>
|
</el-result>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="4" style="padding: 0;">
|
<el-col :span="4" style="padding: 0">
|
||||||
<el-result class="el-result__style__" @click="handleClickHref('TodoJobHash', '?belongType=1')"
|
<el-result class="el-result__style__" @click="handleClickHref('TodoJobHash', '?belongType=1')" title="抄送我的">
|
||||||
title="抄送我的">
|
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<el-icon :size="40" style="color: #409EFF;"><Avatar /></el-icon>
|
<el-icon :size="40" style="color: #409eff"><Avatar /></el-icon>
|
||||||
</template>
|
</template>
|
||||||
</el-result>
|
</el-result>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="4" style="padding: 0;">
|
<el-col :span="4" style="padding: 0">
|
||||||
<el-result class="el-result__style__" @click="handleClickHref('SignJobHash')"
|
<el-result class="el-result__style__" @click="handleClickHref('SignJobHash')" title="待认领的">
|
||||||
title="待认领的">
|
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<el-icon :size="40" style="color: #409EFF;"><Opportunity /></el-icon>
|
<el-icon :size="40" style="color: #409eff"><Opportunity /></el-icon>
|
||||||
</template>
|
</template>
|
||||||
</el-result>
|
</el-result>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="4" style="padding: 0 10px 0 0;">
|
<el-col :span="4" style="padding: 0 10px 0 0">
|
||||||
<el-result class="el-result__style__" @click="handleClickHref('HiJobHash')"
|
<el-result class="el-result__style__" @click="handleClickHref('HiJobHash')" title="我审批的">
|
||||||
title="我审批的">
|
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<el-icon :size="40" style="color: #409EFF;"><Stamp /></el-icon>
|
<el-icon :size="40" style="color: #409eff"><Stamp /></el-icon>
|
||||||
</template>
|
</template>
|
||||||
</el-result>
|
</el-result>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="layout-padding-auto layout-padding-view" style="overflow-y: auto;">
|
<div class="layout-padding-auto layout-padding-view" style="overflow-y: auto">
|
||||||
<template v-for="(tabs, index) in data.tabsData" :key="index">
|
<template v-for="(tabs, index) in data.tabsData" :key="index">
|
||||||
<el-collapse v-model="data.collapse">
|
<el-collapse v-model="data.collapse">
|
||||||
<el-collapse-item :name="index">
|
<el-collapse-item :name="index">
|
||||||
<template #title>
|
<template #title>
|
||||||
<el-icon :size="24" style="margin-right: 8px; color: #409EFF;">
|
<el-icon :size="24" style="margin-right: 8px; color: #409eff">
|
||||||
<CaretRight v-if="!data.collapse.includes(index)" />
|
<CaretRight v-if="!data.collapse.includes(index)" />
|
||||||
<CaretBottom v-else />
|
<CaretBottom v-else />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
<div style="font-size: 14px;"> {{ tabs.groupName }} </div>
|
<div style="font-size: 14px">{{ tabs.groupName }}</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div class="avue-view__avue-card">
|
<div class="avue-view__avue-card">
|
||||||
<el-row
|
<el-row :span="24" :gutter="20">
|
||||||
:span="24"
|
<el-col v-for="(item, index) in data.tableData.filter((f) => f.groupName === tabs.groupName)" :key="index" :span="6">
|
||||||
:gutter="20">
|
|
||||||
<el-col v-for="(item,index) in data.tableData.filter(f => f.groupName === tabs.groupName)"
|
|
||||||
:key="index"
|
|
||||||
:span="6">
|
|
||||||
<div class="avue-card__item">
|
<div class="avue-card__item">
|
||||||
<div class="avue-card__body">
|
<div class="avue-card__body">
|
||||||
<div class="avue-card__avatar2">
|
<div class="avue-card__avatar2">
|
||||||
<i :class="item.icon" alt="" style="font-size: 38px!important;color: #409EFF;"/>
|
<i :class="item.icon" alt="" style="font-size: 38px !important; color: #409eff" />
|
||||||
</div>
|
</div>
|
||||||
<div class="avue-card__detail">
|
<div class="avue-card__detail">
|
||||||
<div class="avue-card__title">{{ item.formName }} V{{ item.version }}</div>
|
<div class="avue-card__title">{{ item.formName }} V{{ item.version }}</div>
|
||||||
@@ -81,19 +72,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="avue-card__menu">
|
<div class="avue-card__menu">
|
||||||
<span
|
<span v-if="item.status === '1'" v-auth="'order_flowapplication_edit'" @click.stop="handleInitiateOrder(item, index)"
|
||||||
v-if="item.status === '1'" v-auth="'order_flowapplication_edit'"
|
>发起工单
|
||||||
@click.stop="handleInitiateOrder(item,index)">发起工单
|
|
||||||
</span>
|
|
||||||
<span v-auth="'order_flowapplication_edit'"
|
|
||||||
@click.stop="openPreview(item.defFlowId)">查看流程图
|
|
||||||
</span>
|
</span>
|
||||||
|
<span v-auth="'order_flowapplication_edit'" @click.stop="openPreview(item.defFlowId)">查看流程图 </span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</el-collapse-item>
|
</el-collapse-item>
|
||||||
</el-collapse>
|
</el-collapse>
|
||||||
</template>
|
</template>
|
||||||
@@ -101,21 +88,25 @@
|
|||||||
<!-- 发起工单 -->
|
<!-- 发起工单 -->
|
||||||
<json-flow-predict ref="predict" :proxy="proxy" @handleInitiateOrder="handleInitiateOrder">
|
<json-flow-predict ref="predict" :proxy="proxy" @handleInitiateOrder="handleInitiateOrder">
|
||||||
<template v-slot="slotProps" v-if="data.showInitiateOrder">
|
<template v-slot="slotProps" v-if="data.showInitiateOrder">
|
||||||
<flow-initiate ref="form" v-show="slotProps.currActive === 'form'" :curr-flow-form="data.currFlowForm"
|
<flow-initiate
|
||||||
@handleInitiateOrder="handleInitiateOrder"></flow-initiate>
|
ref="form"
|
||||||
|
v-show="slotProps.currActive === 'form'"
|
||||||
|
:curr-flow-form="data.currFlowForm"
|
||||||
|
@handleInitiateOrder="handleInitiateOrder"
|
||||||
|
></flow-initiate>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot="slotProps" v-if="data.showHandleForm">
|
<template v-slot="slotProps" v-if="data.showHandleForm">
|
||||||
<custom-form ref="form" v-show="slotProps.currActive === 'form'" :curr-job="data.currFlowForm"
|
<custom-form
|
||||||
@onHandleForm="handleInitiateOrder"></custom-form>
|
ref="form"
|
||||||
|
v-show="slotProps.currActive === 'form'"
|
||||||
|
:curr-job="data.currFlowForm"
|
||||||
|
@onHandleForm="handleInitiateOrder"
|
||||||
|
></custom-form>
|
||||||
</template>
|
</template>
|
||||||
</json-flow-predict>
|
</json-flow-predict>
|
||||||
|
|
||||||
<!-- 查看流程图 -->
|
<!-- 查看流程图 -->
|
||||||
<el-drawer
|
<el-drawer class="flow-overflow-drawer" direction="rtl" append-to-body size="90%" v-model="data.showFlowPic">
|
||||||
class="flow-overflow-drawer" direction="rtl"
|
|
||||||
append-to-body size="90%"
|
|
||||||
v-model="data.showFlowPic"
|
|
||||||
>
|
|
||||||
<flow-photo v-if="data.showFlowPic" :curr-job="data.currFlowForm"></flow-photo>
|
<flow-photo v-if="data.showFlowPic" :curr-job="data.currFlowForm"></flow-photo>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
</div>
|
</div>
|
||||||
@@ -123,91 +114,89 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="systemFlowApplication">
|
<script setup lang="ts" name="systemFlowApplication">
|
||||||
import * as flowApplication from "/@/api/order/flow-application";
|
import * as flowApplication from '/@/api/order/flow-application';
|
||||||
import {useI18n} from "vue-i18n";
|
import { useI18n } from 'vue-i18n';
|
||||||
import other, {deepClone} from "/@/utils/other";
|
import other, { deepClone } from '/@/utils/other';
|
||||||
import {useFlowJob} from "/@/flow/stores/flowJob";
|
import { useFlowJob } from '/@/flow/stores/flowJob';
|
||||||
import {windowLocationHrefParam} from "/@/flow/support/extend";
|
import { windowLocationHrefParam } from '/@/flow/support/extend';
|
||||||
import {handleCustomForm, vueKey} from "/@/api/order/order-key-vue";
|
import { handleCustomForm, vueKey } from '/@/api/order/order-key-vue';
|
||||||
|
|
||||||
// 引入组件
|
// 引入组件
|
||||||
const FlowPhoto = defineAsyncComponent(() => import('/@/views/jsonflow/flow-design/view.vue'));
|
const FlowPhoto = defineAsyncComponent(() => import('/@/views/jsonflow/flow-design/view.vue'));
|
||||||
const FlowInitiate = defineAsyncComponent(() => import('./initiate.vue'));
|
const FlowInitiate = defineAsyncComponent(() => import('./initiate.vue'));
|
||||||
const CustomForm = defineAsyncComponent(() => import('/@/flow/components/custom-form/handle.vue'));
|
const CustomForm = defineAsyncComponent(() => import('/@/flow/components/custom-form/handle.vue'));
|
||||||
const JsonFlowPredict = defineAsyncComponent(() => import('/@/views/jsonflow/flow-design/predict.vue'));
|
const JsonFlowPredict = defineAsyncComponent(() => import('/@/views/jsonflow/flow-design/predict.vue'));
|
||||||
|
|
||||||
const {t} = useI18n()
|
const { t } = useI18n();
|
||||||
const {proxy} = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
tableData: [],
|
tableData: [],
|
||||||
tabsData: [],
|
tabsData: [],
|
||||||
showInitiateOrder: false,
|
showInitiateOrder: false,
|
||||||
showFlowPic: false,
|
showFlowPic: false,
|
||||||
currFlowForm: {},
|
currFlowForm: {},
|
||||||
showHandleForm: false,
|
showHandleForm: false,
|
||||||
collapse: [0]
|
collapse: [0],
|
||||||
})
|
});
|
||||||
|
|
||||||
// 列表查询
|
// 列表查询
|
||||||
function getList() {
|
function getList() {
|
||||||
flowApplication.listByPerms({}).then(response => {
|
flowApplication.listByPerms({}).then((response) => {
|
||||||
data.tableData = response.data
|
data.tableData = response.data;
|
||||||
data.tabsData = data.tableData.filter((value, i, arr) =>
|
data.tabsData = data.tableData.filter((value, i, arr) => arr.findIndex((x) => x.groupName === value.groupName) === i);
|
||||||
arr.findIndex(x => x.groupName === value.groupName) === i
|
});
|
||||||
);
|
}
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleInitiateOrder(row, index) {
|
function handleInitiateOrder(row, index) {
|
||||||
if (row === false) {
|
if (row === false) {
|
||||||
openPredict({}, false)
|
openPredict({}, false);
|
||||||
data.showInitiateOrder = false
|
data.showInitiateOrder = false;
|
||||||
data.showHandleForm = false
|
data.showHandleForm = false;
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
data.currFlowForm = deepClone(row)
|
data.currFlowForm = deepClone(row);
|
||||||
// 判断是否自定义首页
|
// 判断是否自定义首页
|
||||||
if (row.path !== vueKey.RunApplicationForm) {
|
if (row.path !== vueKey.RunApplicationForm) {
|
||||||
handleCustomForm(data, row)
|
handleCustomForm(data, row);
|
||||||
data.currFlowForm.operType = 'add'
|
data.currFlowForm.operType = 'add';
|
||||||
data.showHandleForm = true
|
data.showHandleForm = true;
|
||||||
} else {
|
} else {
|
||||||
data.showInitiateOrder = true
|
data.showInitiateOrder = true;
|
||||||
}
|
|
||||||
openPredict(row, true)
|
|
||||||
}
|
}
|
||||||
|
openPredict(row, true);
|
||||||
|
}
|
||||||
|
|
||||||
function openPredict(row, bool) {
|
function openPredict(row, bool) {
|
||||||
proxy.$refs.predict.open(row, bool)
|
proxy.$refs.predict.open(row, bool);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleClickHref(hash, param = '') {
|
function handleClickHref(hash, param = '') {
|
||||||
windowLocationHrefParam(hash, param)
|
windowLocationHrefParam(hash, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
function openPreview(defFlowId) {
|
function openPreview(defFlowId) {
|
||||||
data.currFlowForm = {defFlowId: defFlowId}
|
data.currFlowForm = { defFlowId: defFlowId };
|
||||||
data.showFlowPic = true
|
data.showFlowPic = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getList()
|
getList();
|
||||||
})
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import "../../../flow/components/style/flow-drawer.scss";
|
@import '../../../flow/components/style/flow-drawer.scss';
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.avue-view__avue-card {
|
.avue-view__avue-card {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
.avue-card__item:hover {
|
.avue-card__item:hover {
|
||||||
border-color: #409EFF;
|
border-color: #409eff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.avue-card__item {
|
.avue-card__item {
|
||||||
@@ -217,13 +206,13 @@
|
|||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
color: rgba(0, 0, 0, .65);
|
color: rgba(0, 0, 0, 0.65);
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-variant: tabular-nums;
|
font-variant: tabular-nums;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
-webkit-font-feature-settings: "tnum";
|
-webkit-font-feature-settings: 'tnum';
|
||||||
font-feature-settings: "tnum";
|
font-feature-settings: 'tnum';
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
.avue-card__body {
|
.avue-card__body {
|
||||||
@@ -246,7 +235,7 @@
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
||||||
.avue-card__title {
|
.avue-card__title {
|
||||||
color: rgba(0, 0, 0, .85);
|
color: rgba(0, 0, 0, 0.85);
|
||||||
margin-top: 6px;
|
margin-top: 6px;
|
||||||
margin-bottom: 6px;
|
margin-bottom: 6px;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
@@ -273,9 +262,9 @@
|
|||||||
line-height: 50px;
|
line-height: 50px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.el_result_layout {
|
.el_result_layout {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
.el-space_container {
|
.el-space_container {
|
||||||
@@ -303,7 +292,5 @@
|
|||||||
background: white;
|
background: white;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,125 +1,118 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="layout-padding">
|
<div class="layout-padding">
|
||||||
<div class="layout-padding-auto layout-padding-view">
|
<div class="layout-padding-auto layout-padding-view">
|
||||||
<form-render ref="formCreateRef" :currFlowForm="data.currFlowForm" :initFormPermPrint="initFormPermPrint">
|
<form-render ref="formCreateRef" :currFlowForm="data.currFlowForm" :initFormPermPrint="initFormPermPrint"> </form-render>
|
||||||
</form-render>
|
|
||||||
</div>
|
</div>
|
||||||
<footer class="el-dialog__footer" v-if="data.submitBtn">
|
<footer class="el-dialog__footer" v-if="data.submitBtn">
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button type="primary" @click="submitForm" :disabled="loading">{{
|
<el-button type="primary" @click="submitForm" :disabled="loading">{{ t('jfI18n.submit') }} </el-button>
|
||||||
t('jfI18n.submit')
|
<el-button type="primary" @click="handleTempStore" :disabled="loading">{{ t('jfI18n.temp') }} </el-button>
|
||||||
}}
|
|
||||||
</el-button>
|
|
||||||
<el-button type="primary" @click="handleTempStore" :disabled="loading">{{
|
|
||||||
t('jfI18n.temp')
|
|
||||||
}}
|
|
||||||
</el-button>
|
|
||||||
</span>
|
</span>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="FlowApplicationInitiate">
|
<script setup lang="ts" name="FlowApplicationInitiate">
|
||||||
import * as flowApplication from '/@/api/order/flow-application'
|
import * as flowApplication from '/@/api/order/flow-application';
|
||||||
import {useI18n} from "vue-i18n";
|
import { useI18n } from 'vue-i18n';
|
||||||
import {validateNull} from "/@/utils/validate";
|
import { validateNull } from '/@/utils/validate';
|
||||||
import {deepClone} from "/@/utils/other";
|
import { deepClone } from '/@/utils/other';
|
||||||
import {setPropsNull} from "/@/flow/support/common";
|
import { setPropsNull } from '/@/flow/support/common';
|
||||||
import {doInitData, doInitiateForm, doTempStore, initFormMethods, initJobDataByApp} from "../index";
|
import { doInitData, doInitiateForm, doTempStore, initFormMethods, initJobDataByApp } from '../index';
|
||||||
import {handleFormStartPerm} from "/@/flow/utils/form-perm";
|
import { handleFormStartPerm } from '/@/flow/utils/form-perm';
|
||||||
import {currFormIsView} from "/@/api/order/order-key-vue";
|
import { currFormIsView } from '/@/api/order/order-key-vue';
|
||||||
|
|
||||||
const FormRender = defineAsyncComponent(() => import('/@/flow/components/form-create/render.vue'));
|
const FormRender = defineAsyncComponent(() => import('/@/flow/components/form-create/render.vue'));
|
||||||
const formCreateRef = ref(null)
|
const formCreateRef = ref(null);
|
||||||
|
|
||||||
const {t} = useI18n();
|
const { t } = useI18n();
|
||||||
const $emit = defineEmits(['handleInitiateOrder']);
|
const $emit = defineEmits(['handleInitiateOrder']);
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
currFlowForm: {
|
currFlowForm: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: {},
|
default: {},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
// 兼容app端监听currFlowForm
|
// 兼容app端监听currFlowForm
|
||||||
currFlowForm: {
|
currFlowForm: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: {},
|
default: {},
|
||||||
},
|
},
|
||||||
submitBtn: true
|
submitBtn: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const $route = useRoute();
|
const $route = useRoute();
|
||||||
function initJobData() {
|
function initJobData() {
|
||||||
initJobDataByApp($route, handleGetObj, () => {
|
initJobDataByApp($route, handleGetObj, () => {
|
||||||
data.currFlowForm = props.currFlowForm
|
data.currFlowForm = props.currFlowForm;
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleGetObj(id) {
|
function handleGetObj(id) {
|
||||||
flowApplication.getObj(id).then(resp => {
|
flowApplication.getObj(id).then((resp) => {
|
||||||
let form = resp.data ? resp.data : {}
|
let form = resp.data ? resp.data : {};
|
||||||
Object.assign(data.currFlowForm, form);
|
Object.assign(data.currFlowForm, form);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function submitForm() {
|
async function submitForm() {
|
||||||
await doInitiateForm(loading, props, data, $route, formCreateRef, $emit, saveInitData, t)
|
await doInitiateForm(loading, props, data, $route, formCreateRef, $emit, saveInitData, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleTempStore() {
|
function handleTempStore() {
|
||||||
doTempStore(loading, data, $route, formCreateRef, $emit, saveInitData)
|
doTempStore(loading, data, $route, formCreateRef, $emit, saveInitData);
|
||||||
}
|
}
|
||||||
|
|
||||||
const methods = initFormMethods(formCreateRef, data)
|
const methods = initFormMethods(formCreateRef, data);
|
||||||
|
|
||||||
async function initFormPermPrint(formInfo) {
|
async function initFormPermPrint(formInfo) {
|
||||||
// 处理表单权限
|
// 处理表单权限
|
||||||
let res = await handleFormStartPerm(null, null, formInfo, data.currFlowForm.defFlowId, null, data.currFlowForm.type)
|
let res = await handleFormStartPerm(null, null, formInfo, data.currFlowForm.defFlowId, null, data.currFlowForm.type);
|
||||||
await currFormIsView(methods, res.elTab, true, res.callback, res.widgetList)
|
await currFormIsView(methods, res.elTab, true, res.callback, res.widgetList);
|
||||||
return res.elTab
|
return res.elTab;
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveInitData(form) {
|
function saveInitData(form) {
|
||||||
data.currFlowForm.formData = validateNull(form) ? undefined : form
|
data.currFlowForm.formData = validateNull(form) ? undefined : form;
|
||||||
let formJson = deepClone(data.currFlowForm)
|
let formJson = deepClone(data.currFlowForm);
|
||||||
formJson.formData = JSON.stringify(formJson.formData)
|
formJson.formData = JSON.stringify(formJson.formData);
|
||||||
formJson.formId = formJson.id
|
formJson.formId = formJson.id;
|
||||||
setPropsNull(formJson, 'id', 'status')
|
setPropsNull(formJson, 'id', 'status');
|
||||||
return formJson;
|
return formJson;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getFormData() {
|
async function getFormData() {
|
||||||
return await doInitData(formCreateRef, saveInitData)
|
return await doInitData(formCreateRef, saveInitData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 暴露变量
|
// 暴露变量
|
||||||
defineExpose({
|
defineExpose({
|
||||||
getFormData,
|
getFormData,
|
||||||
})
|
});
|
||||||
|
|
||||||
// 监听双向绑定
|
// 监听双向绑定
|
||||||
watch(
|
watch(
|
||||||
() => props.currFlowForm.id,
|
() => props.currFlowForm.id,
|
||||||
() => {
|
() => {
|
||||||
initJobData();
|
initJobData();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
initJobData()
|
initJobData();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.el-dialog__footer {
|
.el-dialog__footer {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
|
||||||
.dialog-footer {
|
.dialog-footer {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-form ref="dataFormRef" :model="form" :rules="dataRules" label-width="90px" v-loading="loading"
|
<el-form ref="dataFormRef" :model="form" :rules="dataRules" label-width="90px" v-loading="loading" :disabled="operType === 'view'">
|
||||||
:disabled="operType === 'view'">
|
|
||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<el-col :span="12" class="mb20">
|
<el-col :span="12" class="mb20">
|
||||||
<el-form-item :label="t('handoverFlow.type')" prop="type">
|
<el-form-item :label="t('handoverFlow.type')" prop="type">
|
||||||
<el-select v-model="form.type" :placeholder="t('handoverFlow.inputTypeTip')" clearable
|
<el-select v-model="form.type" :placeholder="t('handoverFlow.inputTypeTip')" clearable filterable disabled>
|
||||||
filterable disabled>
|
<el-option v-for="(item, index) in DIC_PROP.HANDOVER_TYPE" :key="index" :label="item.label" :value="item.value"></el-option>
|
||||||
<el-option v-for="(item, index) in DIC_PROP.HANDOVER_TYPE" :key="index" :label="item.label"
|
|
||||||
:value="item.value"></el-option>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -16,11 +13,17 @@
|
|||||||
<el-col :span="12" class="mb20">
|
<el-col :span="12" class="mb20">
|
||||||
<el-form-item :label="t('handoverFlow.receiveDept')" prop="receiveDept">
|
<el-form-item :label="t('handoverFlow.receiveDept')" prop="receiveDept">
|
||||||
<el-tooltip content="请输入部门名称进行模糊搜索" placement="top">
|
<el-tooltip content="请输入部门名称进行模糊搜索" placement="top">
|
||||||
<el-select v-model="form.receiveDept" :placeholder="t('handoverFlow.inputReceiveDeptTip')"
|
<el-select
|
||||||
remote :remote-method="remoteMethodDept" :reserve-keyword="false"
|
v-model="form.receiveDept"
|
||||||
clearable filterable disabled>
|
:placeholder="t('handoverFlow.inputReceiveDeptTip')"
|
||||||
<el-option v-for="(item, index) in dicData.receiveDept" :key="index" :label="item.name"
|
remote
|
||||||
:value="item.deptId"></el-option>
|
:remote-method="remoteMethodDept"
|
||||||
|
:reserve-keyword="false"
|
||||||
|
clearable
|
||||||
|
filterable
|
||||||
|
disabled
|
||||||
|
>
|
||||||
|
<el-option v-for="(item, index) in dicData.receiveDept" :key="index" :label="item.name" :value="item.deptId"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -29,24 +32,27 @@
|
|||||||
<el-col :span="12" class="mb20">
|
<el-col :span="12" class="mb20">
|
||||||
<el-form-item :label="t('handoverFlow.receiveUser')" prop="receiveUser">
|
<el-form-item :label="t('handoverFlow.receiveUser')" prop="receiveUser">
|
||||||
<el-tooltip content="请输入用户名称进行模糊搜索" placement="top">
|
<el-tooltip content="请输入用户名称进行模糊搜索" placement="top">
|
||||||
<el-select v-model="form.receiveUser" :placeholder="t('handoverFlow.inputReceiveUserTip')"
|
<el-select
|
||||||
remote :remote-method="remoteMethodUser" :reserve-keyword="false"
|
v-model="form.receiveUser"
|
||||||
clearable filterable disabled>
|
:placeholder="t('handoverFlow.inputReceiveUserTip')"
|
||||||
<el-option v-for="(item, index) in dicData.receiveUser" :key="index" :label="item.name"
|
remote
|
||||||
:value="item.userId"></el-option>
|
:remote-method="remoteMethodUser"
|
||||||
|
:reserve-keyword="false"
|
||||||
|
clearable
|
||||||
|
filterable
|
||||||
|
disabled
|
||||||
|
>
|
||||||
|
<el-option v-for="(item, index) in dicData.receiveUser" :key="index" :label="item.name" :value="item.userId"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template v-if="operType !== 'view'">
|
<template v-if="operType !== 'view'">
|
||||||
<footer class="el-dialog__footer">
|
<footer class="el-dialog__footer">
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button type="primary" @click="methods.handleUpdate" :disabled="loading">{{
|
<el-button type="primary" @click="methods.handleUpdate" :disabled="loading">{{ $t('common.confirmButtonText') }}</el-button>
|
||||||
$t('common.confirmButtonText')
|
|
||||||
}}</el-button>
|
|
||||||
</span>
|
</span>
|
||||||
</footer>
|
</footer>
|
||||||
</template>
|
</template>
|
||||||
@@ -54,50 +60,50 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="HandoverDistributionForm">
|
<script setup lang="ts" name="HandoverDistributionForm">
|
||||||
import {useMessage} from "/@/hooks/message";
|
import { useMessage } from '/@/hooks/message';
|
||||||
import {distributePerson, getObj} from '/@/api/order/handover-flow'
|
import { distributePerson, getObj } from '/@/api/order/handover-flow';
|
||||||
import {useI18n} from "vue-i18n"
|
import { useI18n } from 'vue-i18n';
|
||||||
import {rule} from '/@/utils/validate';
|
import { rule } from '/@/utils/validate';
|
||||||
import {onFormLoadedUrl, onLoadDicUrl, remoteMethodByKey} from "/@/flow/components/convert-name/convert";
|
import { onFormLoadedUrl, onLoadDicUrl, remoteMethodByKey } from '/@/flow/components/convert-name/convert';
|
||||||
import * as orderVue from "/@/api/order/order-key-vue";
|
import * as orderVue from '/@/api/order/order-key-vue';
|
||||||
|
|
||||||
const {t} = useI18n();
|
const { t } = useI18n();
|
||||||
const emits = defineEmits(["handleJob"]);
|
const emits = defineEmits(['handleJob']);
|
||||||
// 定义变量内容
|
// 定义变量内容
|
||||||
const dataFormRef = ref();
|
const dataFormRef = ref();
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const operType = ref(false);
|
const operType = ref(false);
|
||||||
// 定义字典
|
// 定义字典
|
||||||
const dicData = reactive({});
|
const dicData = reactive({});
|
||||||
const onLoad = onLoadDicUrl();
|
const onLoad = onLoadDicUrl();
|
||||||
const onFormLoaded = onFormLoadedUrl({key: "receiveDept"}, {key: "receiveUser"});
|
const onFormLoaded = onFormLoadedUrl({ key: 'receiveDept' }, { key: 'receiveUser' });
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// onLoad(dicData);
|
// onLoad(dicData);
|
||||||
});
|
});
|
||||||
|
|
||||||
function remoteMethodDept(query: string) {
|
function remoteMethodDept(query: string) {
|
||||||
remoteMethodByKey(query, onLoad, dicData, 'deptName', "receiveDept")
|
remoteMethodByKey(query, onLoad, dicData, 'deptName', 'receiveDept');
|
||||||
}
|
}
|
||||||
|
|
||||||
function remoteMethodUser(query: string) {
|
function remoteMethodUser(query: string) {
|
||||||
remoteMethodByKey(query, onLoad, dicData, 'userName', "receiveUser")
|
remoteMethodByKey(query, onLoad, dicData, 'userName', 'receiveUser');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 提交表单数据
|
// 提交表单数据
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
type: '',
|
type: '',
|
||||||
receiveDept: '',
|
receiveDept: '',
|
||||||
receiveUser: '',
|
receiveUser: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
// 定义校验规则
|
// 定义校验规则
|
||||||
const dataRules = ref({
|
const dataRules = ref({
|
||||||
type: [{required: true, message: '交接类型不能为空', trigger: 'blur'}],
|
type: [{ required: true, message: '交接类型不能为空', trigger: 'blur' }],
|
||||||
receiveDept: [{required: true, message: '接收部门不能为空', trigger: 'blur'}],
|
receiveDept: [{ required: true, message: '接收部门不能为空', trigger: 'blur' }],
|
||||||
receiveUser: [{required: true, message: '接收人不能为空', trigger: 'blur'}],
|
receiveUser: [{ required: true, message: '接收人不能为空', trigger: 'blur' }],
|
||||||
})
|
});
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
currJob: {
|
currJob: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: null,
|
default: null,
|
||||||
@@ -106,25 +112,25 @@
|
|||||||
type: Object,
|
type: Object,
|
||||||
default: {},
|
default: {},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const methods = {
|
const methods = {
|
||||||
disableForm() {
|
disableForm() {
|
||||||
operType.value = "view"
|
operType.value = 'view';
|
||||||
},
|
},
|
||||||
enableForm() {
|
enableForm() {
|
||||||
operType.value = "flow"
|
operType.value = 'flow';
|
||||||
},
|
},
|
||||||
async initJobData() {
|
async initJobData() {
|
||||||
await orderVue.currElTabIsView(methods, props.currJob, props.currElTab.id, methods.handleUpdate)
|
await orderVue.currElTabIsView(methods, props.currJob, props.currElTab.id, methods.handleUpdate);
|
||||||
methods.handleGetObj(props.currJob.orderId)
|
methods.handleGetObj(props.currJob.orderId);
|
||||||
},
|
},
|
||||||
handleGetObj(id) {
|
handleGetObj(id) {
|
||||||
getObj(id).then(response => {
|
getObj(id).then((response) => {
|
||||||
Object.assign(form, response.data)
|
Object.assign(form, response.data);
|
||||||
onFormLoaded(dicData, form);
|
onFormLoaded(dicData, form);
|
||||||
form.runJobId = props.currJob.id
|
form.runJobId = props.currJob.id;
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
async handleUpdate() {
|
async handleUpdate() {
|
||||||
try {
|
try {
|
||||||
@@ -132,39 +138,39 @@
|
|||||||
// 转岗或离职交接时需要分配接收人来接收未来任务
|
// 转岗或离职交接时需要分配接收人来接收未来任务
|
||||||
let handoverReason = props.currJob.order.handoverReason;
|
let handoverReason = props.currJob.order.handoverReason;
|
||||||
if (form.isNeedReceive && (handoverReason === '1' || handoverReason === '2') && !form.receiveUser) {
|
if (form.isNeedReceive && (handoverReason === '1' || handoverReason === '2') && !form.receiveUser) {
|
||||||
useMessage().error('转岗或离职交接时需要分配接收人来接收未来任务')
|
useMessage().error('转岗或离职交接时需要分配接收人来接收未来任务');
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
await distributePerson(form)
|
await distributePerson(form);
|
||||||
orderVue.currElTabIsSave(props.currJob, props.currElTab.id, true, emits)
|
orderVue.currElTabIsSave(props.currJob, props.currElTab.id, true, emits);
|
||||||
useMessage().success('操作成功')
|
useMessage().success('操作成功');
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
useMessage().error(err.msg);
|
useMessage().error(err.msg);
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
// 监听双向绑定
|
// 监听双向绑定
|
||||||
watch(
|
watch(
|
||||||
() => props.currJob.id,
|
() => props.currJob.id,
|
||||||
() => {
|
() => {
|
||||||
methods.initJobData();
|
methods.initJobData();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
methods.initJobData()
|
methods.initJobData();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.el-dialog__footer {
|
.el-dialog__footer {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
.dialog-footer {
|
.dialog-footer {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog :title="title" v-model="visible" width="60%"
|
<el-dialog :title="title" v-model="visible" width="60%" :close-on-click-modal="false" draggable>
|
||||||
:close-on-click-modal="false" draggable>
|
|
||||||
<el-form ref="dataFormRef" :model="form" :rules="dataRules" label-width="90px" v-loading="loading" :disabled="operType === 'view'">
|
<el-form ref="dataFormRef" :model="form" :rules="dataRules" label-width="90px" v-loading="loading" :disabled="operType === 'view'">
|
||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<el-col :span="12" class="mb20">
|
<el-col :span="12" class="mb20">
|
||||||
<el-form-item :label="t('handoverFlow.code')" prop="code">
|
<el-form-item :label="t('handoverFlow.code')" prop="code">
|
||||||
<el-input v-model="form.code" :placeholder="t('handoverFlow.inputCodeTip')" disabled/>
|
<el-input v-model="form.code" :placeholder="t('handoverFlow.inputCodeTip')" disabled />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
@@ -60,8 +59,15 @@
|
|||||||
<el-col :span="12" class="mb20">
|
<el-col :span="12" class="mb20">
|
||||||
<el-form-item :label="t('handoverFlow.receiveDept')" prop="receiveDept">
|
<el-form-item :label="t('handoverFlow.receiveDept')" prop="receiveDept">
|
||||||
<el-tooltip content="请输入部门名称进行模糊搜索" placement="top">
|
<el-tooltip content="请输入部门名称进行模糊搜索" placement="top">
|
||||||
<el-select v-model="form.receiveDept" :placeholder="t('handoverFlow.inputReceiveDeptTip')" clearable filterable
|
<el-select
|
||||||
remote :remote-method="remoteMethodDept" :reserve-keyword="false">
|
v-model="form.receiveDept"
|
||||||
|
:placeholder="t('handoverFlow.inputReceiveDeptTip')"
|
||||||
|
clearable
|
||||||
|
filterable
|
||||||
|
remote
|
||||||
|
:remote-method="remoteMethodDept"
|
||||||
|
:reserve-keyword="false"
|
||||||
|
>
|
||||||
<el-option v-for="(item, index) in dicData.receiveDept" :key="index" :label="item.name" :value="item.deptId"></el-option>
|
<el-option v-for="(item, index) in dicData.receiveDept" :key="index" :label="item.name" :value="item.deptId"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
@@ -71,8 +77,15 @@
|
|||||||
<el-col :span="12" class="mb20">
|
<el-col :span="12" class="mb20">
|
||||||
<el-form-item :label="t('handoverFlow.receiveUser')" prop="receiveUser">
|
<el-form-item :label="t('handoverFlow.receiveUser')" prop="receiveUser">
|
||||||
<el-tooltip content="请输入用户名称进行模糊搜索" placement="top">
|
<el-tooltip content="请输入用户名称进行模糊搜索" placement="top">
|
||||||
<el-select v-model="form.receiveUser" :placeholder="t('handoverFlow.inputReceiveUserTip')" clearable filterable
|
<el-select
|
||||||
remote :remote-method="remoteMethodUser" :reserve-keyword="false">
|
v-model="form.receiveUser"
|
||||||
|
:placeholder="t('handoverFlow.inputReceiveUserTip')"
|
||||||
|
clearable
|
||||||
|
filterable
|
||||||
|
remote
|
||||||
|
:remote-method="remoteMethodUser"
|
||||||
|
:reserve-keyword="false"
|
||||||
|
>
|
||||||
<el-option v-for="(item, index) in dicData.receiveUser" :key="index" :label="item.name" :value="item.userId"></el-option>
|
<el-option v-for="(item, index) in dicData.receiveUser" :key="index" :label="item.name" :value="item.userId"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
@@ -81,10 +94,14 @@
|
|||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
<el-col :span="12" class="mb20">
|
||||||
<el-form-item :label="t('handoverFlow.finishTime')" prop="finishTime">
|
<el-form-item :label="t('handoverFlow.finishTime')" prop="finishTime">
|
||||||
<el-date-picker type="datetime" :placeholder="t('handoverFlow.inputFinishTimeTip')" v-model="form.finishTime" :value-format="dateTimeStr"></el-date-picker>
|
<el-date-picker
|
||||||
|
type="datetime"
|
||||||
|
:placeholder="t('handoverFlow.inputFinishTimeTip')"
|
||||||
|
v-model="form.finishTime"
|
||||||
|
:value-format="dateTimeStr"
|
||||||
|
></el-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer v-if="operType !== 'view'">
|
<template #footer v-if="operType !== 'view'">
|
||||||
@@ -97,47 +114,41 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="HandoverFlowDialog">
|
<script setup lang="ts" name="HandoverFlowDialog">
|
||||||
|
import { useMessage } from '/@/hooks/message';
|
||||||
|
import { getObj, addObj, putObj } from '/@/api/order/handover-flow';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { rule } from '/@/utils/validate';
|
||||||
|
import { onCascadeChange, onFormLoadedUrl, onLoadDicUrl, remoteMethodByKey } from '/@/flow/components/convert-name/convert';
|
||||||
|
const emit = defineEmits(['refresh']);
|
||||||
|
|
||||||
import { useMessage } from "/@/hooks/message";
|
const { t } = useI18n();
|
||||||
import { getObj, addObj, putObj } from '/@/api/order/handover-flow'
|
|
||||||
import { useI18n } from "vue-i18n"
|
|
||||||
import { rule } from '/@/utils/validate';
|
|
||||||
import {
|
|
||||||
onCascadeChange,
|
|
||||||
onFormLoadedUrl,
|
|
||||||
onLoadDicUrl,
|
|
||||||
remoteMethodByKey
|
|
||||||
} from "/@/flow/components/convert-name/convert";
|
|
||||||
const emit = defineEmits(['refresh']);
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
// 定义变量内容
|
||||||
|
const dataFormRef = ref();
|
||||||
// 定义变量内容
|
const visible = ref(false);
|
||||||
const dataFormRef = ref();
|
const loading = ref(false);
|
||||||
const visible = ref(false);
|
const operType = ref(false);
|
||||||
const loading = ref(false);
|
const title = ref('');
|
||||||
const operType = ref(false);
|
// 定义字典
|
||||||
const title = ref('');
|
const dicData = reactive({});
|
||||||
// 定义字典
|
const cascadeDic = reactive({});
|
||||||
const dicData = reactive({});
|
const onLoad = onLoadDicUrl();
|
||||||
const cascadeDic = reactive({});
|
const onFormLoaded = onFormLoadedUrl({ key: 'receiveDept' }, { key: 'receiveUser' }, { key: 'handoverUserDept' }, { key: 'handoverUser' });
|
||||||
const onLoad = onLoadDicUrl();
|
const onCascade = onCascadeChange(cascadeDic, { key: 'flowInstId', cascades: ['flowKey'] });
|
||||||
const onFormLoaded = onFormLoadedUrl({key: "receiveDept"}, {key: "receiveUser"}, {key: "handoverUserDept"}, {key: "handoverUser"});
|
onMounted(() => {
|
||||||
const onCascade = onCascadeChange(cascadeDic, {key: "flowInstId", cascades: ["flowKey"]});
|
|
||||||
onMounted(() => {
|
|
||||||
// onLoad(dicData);
|
// onLoad(dicData);
|
||||||
});
|
});
|
||||||
|
|
||||||
function remoteMethodDept(query: string) {
|
function remoteMethodDept(query: string) {
|
||||||
remoteMethodByKey(query, onLoad, dicData, 'deptName', "receiveDept")
|
remoteMethodByKey(query, onLoad, dicData, 'deptName', 'receiveDept');
|
||||||
}
|
}
|
||||||
|
|
||||||
function remoteMethodUser(query: string) {
|
function remoteMethodUser(query: string) {
|
||||||
remoteMethodByKey(query, onLoad, dicData, 'userName', "receiveUser")
|
remoteMethodByKey(query, onLoad, dicData, 'userName', 'receiveUser');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 提交表单数据
|
// 提交表单数据
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
code: '',
|
code: '',
|
||||||
flowKey: '',
|
flowKey: '',
|
||||||
type: '',
|
type: '',
|
||||||
@@ -149,24 +160,24 @@
|
|||||||
receiveUser: '',
|
receiveUser: '',
|
||||||
flowInstId: '',
|
flowInstId: '',
|
||||||
finishTime: '',
|
finishTime: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
// 定义校验规则
|
// 定义校验规则
|
||||||
const dataRules = ref({
|
const dataRules = ref({
|
||||||
code: [{required: true, message: '编号不能为空', trigger: 'blur'}],
|
code: [{ required: true, message: '编号不能为空', trigger: 'blur' }],
|
||||||
flowKey: [{required: true, message: '业务类型不能为空', trigger: 'blur'}],
|
flowKey: [{ required: true, message: '业务类型不能为空', trigger: 'blur' }],
|
||||||
type: [{required: true, message: '交接类型不能为空', trigger: 'blur'}],
|
type: [{ required: true, message: '交接类型不能为空', trigger: 'blur' }],
|
||||||
status: [{required: true, message: '状态不能为空', trigger: 'blur'}],
|
status: [{ required: true, message: '状态不能为空', trigger: 'blur' }],
|
||||||
handoverReason: [{required: true, message: '交接原因不能为空', trigger: 'blur'}],
|
handoverReason: [{ required: true, message: '交接原因不能为空', trigger: 'blur' }],
|
||||||
receiveDept: [{required: true, message: '接收部门不能为空', trigger: 'blur'}],
|
receiveDept: [{ required: true, message: '接收部门不能为空', trigger: 'blur' }],
|
||||||
receiveUser: [{required: true, message: '接收人不能为空', trigger: 'blur'}],
|
receiveUser: [{ required: true, message: '接收人不能为空', trigger: 'blur' }],
|
||||||
})
|
});
|
||||||
|
|
||||||
// 打开弹窗
|
// 打开弹窗
|
||||||
const openDialog = (type: string, id: string) => {
|
const openDialog = (type: string, id: string) => {
|
||||||
visible.value = true
|
visible.value = true;
|
||||||
operType.value = type;
|
operType.value = type;
|
||||||
form.id = ''
|
form.id = '';
|
||||||
|
|
||||||
if (type === 'add') {
|
if (type === 'add') {
|
||||||
title.value = t('common.addBtn');
|
title.value = t('common.addBtn');
|
||||||
@@ -183,13 +194,13 @@
|
|||||||
|
|
||||||
// 获取HandoverFlow信息
|
// 获取HandoverFlow信息
|
||||||
if (id) {
|
if (id) {
|
||||||
form.id = id
|
form.id = id;
|
||||||
getHandoverFlowData(id)
|
getHandoverFlowData(id);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 提交
|
// 提交
|
||||||
const onSubmit = async () => {
|
const onSubmit = async () => {
|
||||||
const valid = await dataFormRef.value.validate().catch(() => {});
|
const valid = await dataFormRef.value.validate().catch(() => {});
|
||||||
if (!valid) return false;
|
if (!valid) return false;
|
||||||
|
|
||||||
@@ -204,23 +215,25 @@
|
|||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 初始化表单数据
|
// 初始化表单数据
|
||||||
const getHandoverFlowData = (id: string) => {
|
const getHandoverFlowData = (id: string) => {
|
||||||
// 获取数据
|
// 获取数据
|
||||||
loading.value = true
|
loading.value = true;
|
||||||
getObj(id).then((res: any) => {
|
getObj(id)
|
||||||
Object.assign(form, res.data)
|
.then((res: any) => {
|
||||||
|
Object.assign(form, res.data);
|
||||||
onFormLoaded(dicData, form);
|
onFormLoaded(dicData, form);
|
||||||
onCascade(form);
|
onCascade(form);
|
||||||
}).finally(() => {
|
|
||||||
loading.value = false
|
|
||||||
})
|
})
|
||||||
};
|
.finally(() => {
|
||||||
|
loading.value = false;
|
||||||
// 暴露变量
|
|
||||||
defineExpose({
|
|
||||||
openDialog
|
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 暴露变量
|
||||||
|
defineExpose({
|
||||||
|
openDialog,
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -37,6 +37,5 @@ export default {
|
|||||||
inputUpdateUserTip: 'input updateUser',
|
inputUpdateUserTip: 'input updateUser',
|
||||||
inputUpdateTimeTip: 'input updateTime',
|
inputUpdateTimeTip: 'input updateTime',
|
||||||
inputDelFlagTip: 'input delFlag',
|
inputDelFlagTip: 'input delFlag',
|
||||||
|
},
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
|||||||
@@ -37,6 +37,5 @@ export default {
|
|||||||
inputUpdateUserTip: '请输入修改人',
|
inputUpdateUserTip: '请输入修改人',
|
||||||
inputUpdateTimeTip: '请输入修改时间',
|
inputUpdateTimeTip: '请输入修改时间',
|
||||||
inputDelFlagTip: '请输入删除标识',
|
inputDelFlagTip: '请输入删除标识',
|
||||||
|
},
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
|||||||
@@ -4,39 +4,69 @@
|
|||||||
<el-row v-show="showSearch">
|
<el-row v-show="showSearch">
|
||||||
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
|
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
|
||||||
<el-form-item :label="$t('handoverFlow.code')" prop="code">
|
<el-form-item :label="$t('handoverFlow.code')" prop="code">
|
||||||
<el-input :placeholder="t('handoverFlow.inputCodeTip')" v-model="state.queryForm.code" clearable
|
<el-input :placeholder="t('handoverFlow.inputCodeTip')" v-model="state.queryForm.code" clearable style="max-width: 180px" />
|
||||||
style="max-width: 180px" />
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('handoverFlow.handoverReason')" prop="handoverReason" >
|
<el-form-item :label="$t('handoverFlow.handoverReason')" prop="handoverReason">
|
||||||
<el-tooltip content="离职 或 转岗 会默认交接全部任务。故可随意选择1条任务发起即可" placement="top">
|
<el-tooltip content="离职 或 转岗 会默认交接全部任务。故可随意选择1条任务发起即可" placement="top">
|
||||||
<el-select v-model="state.queryForm.handoverReason" :placeholder="t('handoverFlow.inputHandoverReasonTip')" clearable filterable style="max-width: 180px">
|
<el-select
|
||||||
|
v-model="state.queryForm.handoverReason"
|
||||||
|
:placeholder="t('handoverFlow.inputHandoverReasonTip')"
|
||||||
|
clearable
|
||||||
|
filterable
|
||||||
|
style="max-width: 180px"
|
||||||
|
>
|
||||||
<el-option v-for="(item, index) in DIC_PROP.HANDOVER_REASON" :key="index" :label="item.label" :value="item.value"></el-option>
|
<el-option v-for="(item, index) in DIC_PROP.HANDOVER_REASON" :key="index" :label="item.label" :value="item.value"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('handoverFlow.receiveDept')" prop="receiveDept" >
|
<el-form-item :label="$t('handoverFlow.receiveDept')" prop="receiveDept">
|
||||||
<el-tooltip content="请输入部门名称进行模糊搜索" placement="top">
|
<el-tooltip content="请输入部门名称进行模糊搜索" placement="top">
|
||||||
<el-select v-model="state.queryForm.receiveDept" :placeholder="t('handoverFlow.inputReceiveDeptTip')" clearable filterable
|
<el-select
|
||||||
remote :remote-method="remoteMethodDept" :reserve-keyword="false"
|
v-model="state.queryForm.receiveDept"
|
||||||
style="max-width: 180px">
|
:placeholder="t('handoverFlow.inputReceiveDeptTip')"
|
||||||
|
clearable
|
||||||
|
filterable
|
||||||
|
remote
|
||||||
|
:remote-method="remoteMethodDept"
|
||||||
|
:reserve-keyword="false"
|
||||||
|
style="max-width: 180px"
|
||||||
|
>
|
||||||
<el-option v-for="(item, index) in dicData.receiveDept" :key="index" :label="item.name" :value="item.deptId"></el-option>
|
<el-option v-for="(item, index) in dicData.receiveDept" :key="index" :label="item.name" :value="item.deptId"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('handoverFlow.receiveUser')" prop="receiveUser" >
|
<el-form-item :label="$t('handoverFlow.receiveUser')" prop="receiveUser">
|
||||||
<el-tooltip content="请输入用户名称进行模糊搜索" placement="top">
|
<el-tooltip content="请输入用户名称进行模糊搜索" placement="top">
|
||||||
<el-select v-model="state.queryForm.receiveUser" :placeholder="t('handoverFlow.inputReceiveUserTip')" clearable filterable
|
<el-select
|
||||||
remote :remote-method="remoteMethodUser" :reserve-keyword="false"
|
v-model="state.queryForm.receiveUser"
|
||||||
style="max-width: 180px">
|
:placeholder="t('handoverFlow.inputReceiveUserTip')"
|
||||||
|
clearable
|
||||||
|
filterable
|
||||||
|
remote
|
||||||
|
:remote-method="remoteMethodUser"
|
||||||
|
:reserve-keyword="false"
|
||||||
|
style="max-width: 180px"
|
||||||
|
>
|
||||||
<el-option v-for="(item, index) in dicData.receiveUser" :key="index" :label="item.name" :value="item.userId"></el-option>
|
<el-option v-for="(item, index) in dicData.receiveUser" :key="index" :label="item.name" :value="item.userId"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('handoverFlow.type')" prop="type" >
|
<el-form-item :label="$t('handoverFlow.type')" prop="type">
|
||||||
<el-select v-model="state.queryForm.type" :placeholder="t('handoverFlow.inputTypeTip')" clearable filterable style="max-width: 180px"
|
<el-select
|
||||||
@change="typeChange">
|
v-model="state.queryForm.type"
|
||||||
<el-option v-for="(item, index) in DIC_PROP.HANDOVER_TYPE" :disabled="DIC_PROP.HANDOVER_TYPE[1].value === item.value"
|
:placeholder="t('handoverFlow.inputTypeTip')"
|
||||||
:key="index" :label="item.label" :value="item.value"></el-option>
|
clearable
|
||||||
|
filterable
|
||||||
|
style="max-width: 180px"
|
||||||
|
@change="typeChange"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="(item, index) in DIC_PROP.HANDOVER_TYPE"
|
||||||
|
:disabled="DIC_PROP.HANDOVER_TYPE[1].value === item.value"
|
||||||
|
:key="index"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
@@ -49,31 +79,37 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
<div class="mb8" style="width: 100%">
|
<div class="mb8" style="width: 100%">
|
||||||
<el-button icon="Promotion" type="primary" class="ml10" @click="handleInitiate"
|
<el-button icon="Promotion" type="primary" class="ml10" @click="handleInitiate" :loading="state.loading" v-auth="'order_handoverflow_add'">
|
||||||
:loading="state.loading"
|
|
||||||
v-auth="'order_handoverflow_add'">
|
|
||||||
{{ $t('jfI18n.initHandover') }}
|
{{ $t('jfI18n.initHandover') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<right-toolbar v-model:showSearch="showSearch" :export="'order_handoverflow_export'"
|
<right-toolbar
|
||||||
@exportExcel="exportExcel" class="ml10" style="float: right;margin-right: 20px"
|
v-model:showSearch="showSearch"
|
||||||
@queryTable="getDataList"></right-toolbar>
|
:export="'order_handoverflow_export'"
|
||||||
|
@exportExcel="exportExcel"
|
||||||
|
class="ml10"
|
||||||
|
style="float: right; margin-right: 20px"
|
||||||
|
@queryTable="getDataList"
|
||||||
|
></right-toolbar>
|
||||||
</div>
|
</div>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-table :data="state.dataList" v-loading="state.loading" style="width: 100%"
|
<el-table
|
||||||
@selection-change="handleSelectionChange" @sort-change="sortChangeHandle">
|
:data="state.dataList"
|
||||||
|
v-loading="state.loading"
|
||||||
|
style="width: 100%"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
|
@sort-change="sortChangeHandle"
|
||||||
|
>
|
||||||
<el-table-column type="selection" width="40" align="center" />
|
<el-table-column type="selection" width="40" align="center" />
|
||||||
<el-table-column type="index" :label="t('handoverFlow.index')" width="40" />
|
<el-table-column type="index" :label="t('handoverFlow.index')" width="40" />
|
||||||
<el-table-column prop="code" :label="t('handoverFlow.code')" show-overflow-tooltip/>
|
<el-table-column prop="code" :label="t('handoverFlow.code')" show-overflow-tooltip />
|
||||||
<el-table-column prop="flowKey" :label="t('handoverFlow.flowKey')" show-overflow-tooltip>
|
<el-table-column prop="flowKey" :label="t('handoverFlow.flowKey')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<convert-name :options="state.dicData.flowInstId" :value="scope.row.flowKey"
|
<convert-name :options="state.dicData.flowInstId" :value="scope.row.flowKey" :valueKey="'flowKey'" :showKey="'flowName'"></convert-name>
|
||||||
:valueKey="'flowKey'" :showKey="'flowName'"></convert-name>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="runJobId" :label="t('handoverNodeRecord.runJobId')" show-overflow-tooltip>
|
<el-table-column prop="runJobId" :label="t('handoverNodeRecord.runJobId')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<convert-name :options="state.dicData.runJobId" :value="scope.row.runJobId"
|
<convert-name :options="state.dicData.runJobId" :value="scope.row.runJobId" :valueKey="'id'" :showKey="'jobName'"></convert-name>
|
||||||
:valueKey="'id'" :showKey="'jobName'"></convert-name>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="type" :label="t('handoverFlow.type')" show-overflow-tooltip>
|
<el-table-column prop="type" :label="t('handoverFlow.type')" show-overflow-tooltip>
|
||||||
@@ -88,109 +124,97 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="createUser" :label="t('handoverFlow.createUser')" show-overflow-tooltip>
|
<el-table-column prop="createUser" :label="t('handoverFlow.createUser')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<convert-name :options="state.dicData.createUser" :value="scope.row.createUser"
|
<convert-name :options="state.dicData.createUser" :value="scope.row.createUser" :valueKey="'userId'" :showKey="'name'"></convert-name>
|
||||||
:valueKey="'userId'" :showKey="'name'"></convert-name>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="createTime" :label="t('handoverFlow.createTime')" show-overflow-tooltip/>
|
<el-table-column prop="createTime" :label="t('handoverFlow.createTime')" show-overflow-tooltip />
|
||||||
</el-table>
|
</el-table>
|
||||||
<pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle" v-bind="state.pagination" />
|
<pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle" v-bind="state.pagination" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-dialog
|
<el-dialog v-if="data.showNodeHandover" append-to-body v-model="data.showNodeHandover" top="20px" width="80%" :title="data.handoverTitle">
|
||||||
v-if="data.showNodeHandover"
|
|
||||||
append-to-body
|
|
||||||
v-model="data.showNodeHandover"
|
|
||||||
top="20px"
|
|
||||||
width="80%"
|
|
||||||
:title="data.handoverTitle">
|
|
||||||
<handover-node-record
|
<handover-node-record
|
||||||
ref="node"
|
ref="node"
|
||||||
:selections="data.selections"
|
:selections="data.selections"
|
||||||
:handover-form="data.handoverForm"
|
:handover-form="data.handoverForm"
|
||||||
@onHandoverFlow="onHandoverFlow"></handover-node-record>
|
@onHandoverFlow="onHandoverFlow"
|
||||||
|
></handover-node-record>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="systemHandoverFlow">
|
<script setup lang="ts" name="systemHandoverFlow">
|
||||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
import { useMessage, useMessageBox } from '/@/hooks/message';
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from 'vue-i18n';
|
||||||
import {onLoadDicUrl, onLoaded, remoteMethodByKey} from "/@/flow/components/convert-name/convert";
|
import { onLoadDicUrl, onLoaded, remoteMethodByKey } from '/@/flow/components/convert-name/convert';
|
||||||
import {validateNull} from "/@/utils/validate";
|
import { validateNull } from '/@/utils/validate';
|
||||||
import {DIC_PROP} from "/@/flow/support/dict-prop";
|
import { DIC_PROP } from '/@/flow/support/dict-prop';
|
||||||
import * as handoverFlow from "/@/api/order/handover-flow";
|
import * as handoverFlow from '/@/api/order/handover-flow';
|
||||||
import * as runJob from "/@/api/jsonflow/run-job";
|
import * as runJob from '/@/api/jsonflow/run-job';
|
||||||
|
|
||||||
// 引入组件
|
// 引入组件
|
||||||
const HandoverNodeRecord = defineAsyncComponent(() => import('/@/views/order/handover-node-record/initiate.vue'));
|
const HandoverNodeRecord = defineAsyncComponent(() => import('/@/views/order/handover-node-record/initiate.vue'));
|
||||||
const { t } = useI18n()
|
const { t } = useI18n();
|
||||||
// 定义查询字典
|
// 定义查询字典
|
||||||
const dicData = reactive({});
|
const dicData = reactive({});
|
||||||
const onLoad = onLoadDicUrl();
|
const onLoad = onLoadDicUrl();
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// onLoad(dicData);
|
// onLoad(dicData);
|
||||||
});
|
});
|
||||||
|
|
||||||
function remoteMethodDept(query: string) {
|
function remoteMethodDept(query: string) {
|
||||||
remoteMethodByKey(query, onLoad, dicData, 'deptName', "receiveDept")
|
remoteMethodByKey(query, onLoad, dicData, 'deptName', 'receiveDept');
|
||||||
}
|
}
|
||||||
|
|
||||||
function remoteMethodUser(query: string) {
|
function remoteMethodUser(query: string) {
|
||||||
remoteMethodByKey(query, onLoad, dicData, 'userName', "receiveUser")
|
remoteMethodByKey(query, onLoad, dicData, 'userName', 'receiveUser');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 搜索变量
|
// 搜索变量
|
||||||
const queryRef = ref()
|
const queryRef = ref();
|
||||||
const showSearch = ref(true)
|
const showSearch = ref(true);
|
||||||
// 多选变量
|
// 多选变量
|
||||||
const selectObjs = ref([]) as any
|
const selectObjs = ref([]) as any;
|
||||||
const multiple = ref(true)
|
const multiple = ref(true);
|
||||||
|
|
||||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||||
queryForm: {
|
queryForm: {
|
||||||
type: DIC_PROP.HANDOVER_TYPE[0].value,
|
type: DIC_PROP.HANDOVER_TYPE[0].value,
|
||||||
status: DIC_PROP.HANDOVER_STATUS[1].value
|
status: DIC_PROP.HANDOVER_STATUS[1].value,
|
||||||
},
|
},
|
||||||
pageList: runJob.fetchNodeHandover,
|
pageList: runJob.fetchNodeHandover,
|
||||||
onLoaded: onLoaded({key: "createUser"}, {key: "flowInstId"}, {key: "runJobId"}),
|
onLoaded: onLoaded({ key: 'createUser' }, { key: 'flowInstId' }, { key: 'runJobId' }),
|
||||||
descs: ["create_time"]
|
descs: ['create_time'],
|
||||||
})
|
});
|
||||||
|
|
||||||
// table hook
|
// table hook
|
||||||
const {
|
const { getDataList, currentChangeHandle, sizeChangeHandle, sortChangeHandle, downBlobFile } = useTable(state);
|
||||||
getDataList,
|
|
||||||
currentChangeHandle,
|
|
||||||
sizeChangeHandle,
|
|
||||||
sortChangeHandle,
|
|
||||||
downBlobFile
|
|
||||||
} = useTable(state)
|
|
||||||
|
|
||||||
|
// 清空搜索条件
|
||||||
|
const resetQuery = () => {
|
||||||
// 清空搜索条件
|
// 清空搜索条件
|
||||||
const resetQuery = () => {
|
queryRef.value?.resetFields();
|
||||||
// 清空搜索条件
|
|
||||||
queryRef.value?.resetFields()
|
|
||||||
// 清空多选
|
// 清空多选
|
||||||
selectObjs.value = []
|
selectObjs.value = [];
|
||||||
data.selections = []
|
data.selections = [];
|
||||||
getDataList()
|
getDataList();
|
||||||
}
|
};
|
||||||
|
|
||||||
// 导出excel
|
// 导出excel
|
||||||
const exportExcel = () => {
|
const exportExcel = () => {
|
||||||
downBlobFile('/order/handover-flow/export', state.queryForm, 'handover-flow.xlsx')
|
downBlobFile('/order/handover-flow/export', state.queryForm, 'handover-flow.xlsx');
|
||||||
}
|
};
|
||||||
|
|
||||||
// 多选事件
|
// 多选事件
|
||||||
const handleSelectionChange = (objs: any) => {
|
const handleSelectionChange = (objs: any) => {
|
||||||
data.selections = objs
|
data.selections = objs;
|
||||||
selectObjs.value = objs.map(({ id }) => id);
|
selectObjs.value = objs.map(({ id }) => id);
|
||||||
multiple.value = !objs.length;
|
multiple.value = !objs.length;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 删除操作
|
// 删除操作
|
||||||
const handleDelete = async (ids: string[]) => {
|
const handleDelete = async (ids: string[]) => {
|
||||||
try {
|
try {
|
||||||
await useMessageBox().confirm(t('common.delConfirmText'));
|
await useMessageBox().confirm(t('common.delConfirmText'));
|
||||||
} catch {
|
} catch {
|
||||||
@@ -203,84 +227,84 @@
|
|||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
useMessage().error(err.msg);
|
useMessage().error(err.msg);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
selections: [],
|
selections: [],
|
||||||
showNodeHandover: false,
|
showNodeHandover: false,
|
||||||
handoverTitle: null,
|
handoverTitle: null,
|
||||||
handoverForm: null,
|
handoverForm: null,
|
||||||
})
|
});
|
||||||
|
|
||||||
function fetchListFun(fetchList, params) {
|
function fetchListFun(fetchList, params) {
|
||||||
if (!params.status || !params.type) {
|
if (!params.status || !params.type) {
|
||||||
useMessage().info('请选择必填交接条件')
|
useMessage().info('请选择必填交接条件');
|
||||||
return
|
return;
|
||||||
}
|
|
||||||
state.pageList = fetchList
|
|
||||||
getDataList()
|
|
||||||
}
|
}
|
||||||
|
state.pageList = fetchList;
|
||||||
|
getDataList();
|
||||||
|
}
|
||||||
|
|
||||||
function typeChange() {
|
function typeChange() {
|
||||||
let type = state.queryForm.type
|
let type = state.queryForm.type;
|
||||||
let handoverType = DIC_PROP.HANDOVER_TYPE
|
let handoverType = DIC_PROP.HANDOVER_TYPE;
|
||||||
if (type === handoverType[0].value) {
|
if (type === handoverType[0].value) {
|
||||||
// 任务交接
|
// 任务交接
|
||||||
fetchListFun(runJob.fetchNodeHandover, state.queryForm)
|
fetchListFun(runJob.fetchNodeHandover, state.queryForm);
|
||||||
} else {
|
} else {
|
||||||
// 公共交接 TODO 需自行扩展自身业务,参考任务交接
|
// 公共交接 TODO 需自行扩展自身业务,参考任务交接
|
||||||
// fetchListFun(company.fetchCommonHandover, state.queryForm)
|
// fetchListFun(company.fetchCommonHandover, state.queryForm)
|
||||||
}
|
}
|
||||||
handleSelectionChange([])
|
handleSelectionChange([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleInitiate() {
|
function handleInitiate() {
|
||||||
const type = state.queryForm.type
|
const type = state.queryForm.type;
|
||||||
if (validateFormInfo(type)) {
|
if (validateFormInfo(type)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
data.handoverTitle = DIC_PROP.HANDOVER_TYPE.filter(f => f.value === type)[0].label
|
data.handoverTitle = DIC_PROP.HANDOVER_TYPE.filter((f) => f.value === type)[0].label;
|
||||||
// 转岗或离职,则全部交接
|
// 转岗或离职,则全部交接
|
||||||
if (validateNull(data.selections)) {
|
if (validateNull(data.selections)) {
|
||||||
useMessage().info('请选择交接项')
|
useMessage().info('请选择交接项');
|
||||||
return
|
return;
|
||||||
}
|
|
||||||
data.handoverForm = Object.assign({}, state.queryForm)
|
|
||||||
data.handoverForm.code = null
|
|
||||||
data.showNodeHandover = true
|
|
||||||
}
|
}
|
||||||
|
data.handoverForm = Object.assign({}, state.queryForm);
|
||||||
|
data.handoverForm.code = null;
|
||||||
|
data.showNodeHandover = true;
|
||||||
|
}
|
||||||
|
|
||||||
function validateFormInfo(type) {
|
function validateFormInfo(type) {
|
||||||
const handoverReason = state.queryForm.handoverReason
|
const handoverReason = state.queryForm.handoverReason;
|
||||||
if (!handoverReason) {
|
if (!handoverReason) {
|
||||||
useMessage().info('请选择交接原因')
|
useMessage().info('请选择交接原因');
|
||||||
return true
|
return true;
|
||||||
}
|
}
|
||||||
if (!type) {
|
if (!type) {
|
||||||
useMessage().info('请选择交接类型')
|
useMessage().info('请选择交接类型');
|
||||||
return true
|
return true;
|
||||||
}
|
}
|
||||||
if (!state.queryForm.status) {
|
if (!state.queryForm.status) {
|
||||||
useMessage().info('请选择交接状态')
|
useMessage().info('请选择交接状态');
|
||||||
return true
|
return true;
|
||||||
}
|
}
|
||||||
if (!state.queryForm.receiveDept) {
|
if (!state.queryForm.receiveDept) {
|
||||||
useMessage().info('请选择接收部门')
|
useMessage().info('请选择接收部门');
|
||||||
return true
|
return true;
|
||||||
}
|
}
|
||||||
if (!state.queryForm.receiveUser) {
|
if (!state.queryForm.receiveUser) {
|
||||||
useMessage().info('请选择接收人')
|
useMessage().info('请选择接收人');
|
||||||
return true
|
return true;
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
function onHandoverFlow(type) {
|
function onHandoverFlow(type) {
|
||||||
getDataList()
|
getDataList();
|
||||||
data.showNodeHandover = false
|
data.showNodeHandover = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
state.loading = false
|
state.loading = false;
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -3,40 +3,64 @@
|
|||||||
<div class="layout-padding-auto layout-padding-view">
|
<div class="layout-padding-auto layout-padding-view">
|
||||||
<el-row v-show="showSearch">
|
<el-row v-show="showSearch">
|
||||||
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
|
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
|
||||||
<el-form-item :label="$t('handoverFlow.code')" prop="code" >
|
<el-form-item :label="$t('handoverFlow.code')" prop="code">
|
||||||
<el-input :placeholder="t('handoverFlow.inputCodeTip')" v-model="state.queryForm.code" clearable
|
<el-input :placeholder="t('handoverFlow.inputCodeTip')" v-model="state.queryForm.code" clearable style="max-width: 180px" />
|
||||||
style="max-width: 180px" />
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('handoverFlow.handoverReason')" prop="handoverReason" >
|
<el-form-item :label="$t('handoverFlow.handoverReason')" prop="handoverReason">
|
||||||
<el-select v-model="state.queryForm.handoverReason" :placeholder="t('handoverFlow.inputHandoverReasonTip')" clearable filterable style="max-width: 180px">
|
<el-select
|
||||||
|
v-model="state.queryForm.handoverReason"
|
||||||
|
:placeholder="t('handoverFlow.inputHandoverReasonTip')"
|
||||||
|
clearable
|
||||||
|
filterable
|
||||||
|
style="max-width: 180px"
|
||||||
|
>
|
||||||
<el-option v-for="(item, index) in DIC_PROP.HANDOVER_REASON" :key="index" :label="item.label" :value="item.value"></el-option>
|
<el-option v-for="(item, index) in DIC_PROP.HANDOVER_REASON" :key="index" :label="item.label" :value="item.value"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('handoverFlow.receiveDept')" prop="receiveDept" >
|
<el-form-item :label="$t('handoverFlow.receiveDept')" prop="receiveDept">
|
||||||
<el-tooltip content="请输入部门名称进行模糊搜索" placement="top">
|
<el-tooltip content="请输入部门名称进行模糊搜索" placement="top">
|
||||||
<el-select v-model="state.queryForm.receiveDept" :placeholder="t('handoverFlow.inputReceiveDeptTip')" clearable filterable
|
<el-select
|
||||||
remote :remote-method="remoteMethodDept" :reserve-keyword="false"
|
v-model="state.queryForm.receiveDept"
|
||||||
style="max-width: 180px">
|
:placeholder="t('handoverFlow.inputReceiveDeptTip')"
|
||||||
|
clearable
|
||||||
|
filterable
|
||||||
|
remote
|
||||||
|
:remote-method="remoteMethodDept"
|
||||||
|
:reserve-keyword="false"
|
||||||
|
style="max-width: 180px"
|
||||||
|
>
|
||||||
<el-option v-for="(item, index) in dicData.receiveDept" :key="index" :label="item.name" :value="item.deptId"></el-option>
|
<el-option v-for="(item, index) in dicData.receiveDept" :key="index" :label="item.name" :value="item.deptId"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('handoverFlow.receiveUser')" prop="receiveUser" >
|
<el-form-item :label="$t('handoverFlow.receiveUser')" prop="receiveUser">
|
||||||
<el-tooltip content="请输入用户名称进行模糊搜索" placement="top">
|
<el-tooltip content="请输入用户名称进行模糊搜索" placement="top">
|
||||||
<el-select v-model="state.queryForm.receiveUser" :placeholder="t('handoverFlow.inputReceiveUserTip')" clearable filterable
|
<el-select
|
||||||
remote :remote-method="remoteMethodUser" :reserve-keyword="false"
|
v-model="state.queryForm.receiveUser"
|
||||||
style="max-width: 180px">
|
:placeholder="t('handoverFlow.inputReceiveUserTip')"
|
||||||
|
clearable
|
||||||
|
filterable
|
||||||
|
remote
|
||||||
|
:remote-method="remoteMethodUser"
|
||||||
|
:reserve-keyword="false"
|
||||||
|
style="max-width: 180px"
|
||||||
|
>
|
||||||
<el-option v-for="(item, index) in dicData.receiveUser" :key="index" :label="item.name" :value="item.userId"></el-option>
|
<el-option v-for="(item, index) in dicData.receiveUser" :key="index" :label="item.name" :value="item.userId"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('handoverFlow.type')" prop="type" >
|
<el-form-item :label="$t('handoverFlow.type')" prop="type">
|
||||||
<el-select v-model="state.queryForm.type" :placeholder="t('handoverFlow.inputTypeTip')" clearable filterable style="max-width: 180px">
|
<el-select v-model="state.queryForm.type" :placeholder="t('handoverFlow.inputTypeTip')" clearable filterable style="max-width: 180px">
|
||||||
<el-option v-for="(item, index) in DIC_PROP.HANDOVER_TYPE" :disabled="DIC_PROP.HANDOVER_TYPE[1].value === item.value"
|
<el-option
|
||||||
:key="index" :label="item.label" :value="item.value"></el-option>
|
v-for="(item, index) in DIC_PROP.HANDOVER_TYPE"
|
||||||
|
:disabled="DIC_PROP.HANDOVER_TYPE[1].value === item.value"
|
||||||
|
:key="index"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('handoverFlow.status')" prop="status" >
|
<el-form-item :label="$t('handoverFlow.status')" prop="status">
|
||||||
<el-select v-model="state.queryForm.status" :placeholder="t('handoverFlow.inputStatusTip')" clearable filterable style="max-width: 180px">
|
<el-select v-model="state.queryForm.status" :placeholder="t('handoverFlow.inputStatusTip')" clearable filterable style="max-width: 180px">
|
||||||
<el-option v-for="(item, index) in DIC_PROP.HANDOVER_STATUS" :key="index" :label="item.label" :value="item.value"></el-option>
|
<el-option v-for="(item, index) in DIC_PROP.HANDOVER_STATUS" :key="index" :label="item.label" :value="item.value"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
@@ -51,42 +75,55 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
<div class="mb8" style="width: 100%">
|
<div class="mb8" style="width: 100%">
|
||||||
|
|
||||||
<el-tooltip placement="top">
|
<el-tooltip placement="top">
|
||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('common.delBtn') }}
|
{{ $t('common.delBtn') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button plain :disabled="multiple" icon="Delete" type="primary" class="ml10"
|
<el-button
|
||||||
v-auth="'order_handoverflow_del'" @click="handleDelete(selectObjs)">
|
plain
|
||||||
|
:disabled="multiple"
|
||||||
|
icon="Delete"
|
||||||
|
type="primary"
|
||||||
|
class="ml10"
|
||||||
|
v-auth="'order_handoverflow_del'"
|
||||||
|
@click="handleDelete(selectObjs)"
|
||||||
|
>
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
<right-toolbar v-model:showSearch="showSearch" :export="'order_handoverflow_export'"
|
<right-toolbar
|
||||||
@exportExcel="exportExcel" class="ml10" style="float: right;margin-right: 20px"
|
v-model:showSearch="showSearch"
|
||||||
@queryTable="getDataList"></right-toolbar>
|
:export="'order_handoverflow_export'"
|
||||||
|
@exportExcel="exportExcel"
|
||||||
|
class="ml10"
|
||||||
|
style="float: right; margin-right: 20px"
|
||||||
|
@queryTable="getDataList"
|
||||||
|
></right-toolbar>
|
||||||
</div>
|
</div>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-table :data="state.dataList" v-loading="state.loading" style="width: 100%"
|
<el-table
|
||||||
@selection-change="handleSelectionChange" @sort-change="sortChangeHandle">
|
:data="state.dataList"
|
||||||
|
v-loading="state.loading"
|
||||||
|
style="width: 100%"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
|
@sort-change="sortChangeHandle"
|
||||||
|
>
|
||||||
<el-table-column type="selection" width="40" align="center" />
|
<el-table-column type="selection" width="40" align="center" />
|
||||||
<el-table-column type="index" :label="t('handoverFlow.index')" width="40" />
|
<el-table-column type="index" :label="t('handoverFlow.index')" width="40" />
|
||||||
<el-table-column prop="code" :label="t('handoverFlow.code')" show-overflow-tooltip/>
|
<el-table-column prop="code" :label="t('handoverFlow.code')" show-overflow-tooltip />
|
||||||
<el-table-column prop="flowKey" :label="t('handoverFlow.flowKey')" show-overflow-tooltip>
|
<el-table-column prop="flowKey" :label="t('handoverFlow.flowKey')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<convert-name :options="state.dicData.flowInstId" :value="scope.row.flowKey"
|
<convert-name :options="state.dicData.flowInstId" :value="scope.row.flowKey" :valueKey="'flowKey'" :showKey="'flowName'"></convert-name>
|
||||||
:valueKey="'flowKey'" :showKey="'flowName'"></convert-name>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="receiveDept" :label="t('handoverFlow.receiveDept')" show-overflow-tooltip>
|
<el-table-column prop="receiveDept" :label="t('handoverFlow.receiveDept')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<convert-name :options="state.dicData.receiveDept" :value="scope.row.receiveDept"
|
<convert-name :options="state.dicData.receiveDept" :value="scope.row.receiveDept" :valueKey="'deptId'" :showKey="'name'"></convert-name>
|
||||||
:valueKey="'deptId'" :showKey="'name'"></convert-name>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="receiveUser" :label="t('handoverFlow.receiveUser')" show-overflow-tooltip>
|
<el-table-column prop="receiveUser" :label="t('handoverFlow.receiveUser')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<convert-name :options="state.dicData.receiveUser" :value="scope.row.receiveUser"
|
<convert-name :options="state.dicData.receiveUser" :value="scope.row.receiveUser" :valueKey="'userId'" :showKey="'name'"></convert-name>
|
||||||
:valueKey="'userId'" :showKey="'name'"></convert-name>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="type" :label="t('handoverFlow.type')" show-overflow-tooltip>
|
<el-table-column prop="type" :label="t('handoverFlow.type')" show-overflow-tooltip>
|
||||||
@@ -101,51 +138,47 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="createUser" :label="t('handoverFlow.createUser')" show-overflow-tooltip>
|
<el-table-column prop="createUser" :label="t('handoverFlow.createUser')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<convert-name :options="state.dicData.createUser" :value="scope.row.createUser"
|
<convert-name :options="state.dicData.createUser" :value="scope.row.createUser" :valueKey="'userId'" :showKey="'name'"></convert-name>
|
||||||
:valueKey="'userId'" :showKey="'name'"></convert-name>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="createTime" :label="t('handoverFlow.createTime')" show-overflow-tooltip/>
|
<el-table-column prop="createTime" :label="t('handoverFlow.createTime')" show-overflow-tooltip />
|
||||||
<el-table-column :label="$t('common.action')" width="120">
|
<el-table-column :label="$t('common.action')" width="120">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tooltip placement="top">
|
<el-tooltip placement="top">
|
||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('common.viewBtn') }}
|
{{ $t('common.viewBtn') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button text type="primary" icon="view" @click="formDialogRef.openDialog('view', scope.row.id)">
|
<el-button text type="primary" icon="view" @click="formDialogRef.openDialog('view', scope.row.id)"> </el-button>
|
||||||
</el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
<el-tooltip placement="top" v-if="scope.row.status===DIC_PROP.ORDER_STATUS[2].value">
|
<el-tooltip placement="top" v-if="scope.row.status === DIC_PROP.ORDER_STATUS[2].value">
|
||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('jfI18n.recallBtn') }}
|
{{ $t('jfI18n.recallBtn') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button icon="RefreshLeft" text type="primary" @click="handleRecallReset(scope.row)">
|
<el-button icon="RefreshLeft" text type="primary" @click="handleRecallReset(scope.row)"> </el-button>
|
||||||
</el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip placement="top" v-if="scope.row.status===DIC_PROP.ORDER_STATUS[0].value">
|
<el-tooltip placement="top" v-if="scope.row.status === DIC_PROP.ORDER_STATUS[0].value">
|
||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('jfI18n.resetBtn') }}
|
{{ $t('jfI18n.resetBtn') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button icon="RefreshRight" text type="primary" @click="handleRecallReset(scope.row)">
|
<el-button icon="RefreshRight" text type="primary" @click="handleRecallReset(scope.row)"> </el-button>
|
||||||
</el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
<el-tooltip placement="top" v-if="scope.row.status===DIC_PROP.ORDER_STATUS[1].value || scope.row.status===DIC_PROP.ORDER_STATUS[0].value">
|
<el-tooltip
|
||||||
|
placement="top"
|
||||||
|
v-if="scope.row.status === DIC_PROP.ORDER_STATUS[1].value || scope.row.status === DIC_PROP.ORDER_STATUS[0].value"
|
||||||
|
>
|
||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('common.editBtn') }}
|
{{ $t('common.editBtn') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button icon="edit-pen" text type="primary" @click="formDialogRef.openDialog('edit', scope.row.id)">
|
<el-button icon="edit-pen" text type="primary" @click="formDialogRef.openDialog('edit', scope.row.id)"> </el-button>
|
||||||
</el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip placement="top" v-if="scope.row.status===DIC_PROP.ORDER_STATUS[1].value">
|
<el-tooltip placement="top" v-if="scope.row.status === DIC_PROP.ORDER_STATUS[1].value">
|
||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('common.delBtn') }}
|
{{ $t('common.delBtn') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button icon="delete" text type="primary" @click="handleDelete([scope.row.id])">
|
<el-button icon="delete" text type="primary" @click="handleDelete([scope.row.id])"> </el-button>
|
||||||
</el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@@ -158,98 +191,94 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="systemHandoverFlowView">
|
<script setup lang="ts" name="systemHandoverFlowView">
|
||||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||||
import { fetchList, delObjs } from "/@/api/order/handover-flow";
|
import { fetchList, delObjs } from '/@/api/order/handover-flow';
|
||||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
import { useMessage, useMessageBox } from '/@/hooks/message';
|
||||||
|
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from 'vue-i18n';
|
||||||
import {onLoadDicUrl, onLoaded, remoteMethodByKey} from "/@/flow/components/convert-name/convert";
|
import { onLoadDicUrl, onLoaded, remoteMethodByKey } from '/@/flow/components/convert-name/convert';
|
||||||
import {recallReset} from "/@/api/jsonflow/run-flow";
|
import { recallReset } from '/@/api/jsonflow/run-flow';
|
||||||
import {DIC_PROP} from "/@/flow/support/dict-prop";
|
import { DIC_PROP } from '/@/flow/support/dict-prop';
|
||||||
|
|
||||||
// 引入组件
|
// 引入组件
|
||||||
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
|
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
|
||||||
const { t } = useI18n()
|
const { t } = useI18n();
|
||||||
// 定义查询字典
|
// 定义查询字典
|
||||||
const dicData = reactive({});
|
const dicData = reactive({});
|
||||||
const onLoad = onLoadDicUrl();
|
const onLoad = onLoadDicUrl();
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// onLoad(dicData);
|
// onLoad(dicData);
|
||||||
});
|
});
|
||||||
|
|
||||||
function remoteMethodDept(query: string) {
|
function remoteMethodDept(query: string) {
|
||||||
remoteMethodByKey(query, onLoad, dicData, 'deptName', "receiveDept")
|
remoteMethodByKey(query, onLoad, dicData, 'deptName', 'receiveDept');
|
||||||
}
|
}
|
||||||
|
|
||||||
function remoteMethodUser(query: string) {
|
function remoteMethodUser(query: string) {
|
||||||
remoteMethodByKey(query, onLoad, dicData, 'userName', "receiveUser")
|
remoteMethodByKey(query, onLoad, dicData, 'userName', 'receiveUser');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 定义变量内容
|
// 定义变量内容
|
||||||
const formDialogRef = ref()
|
const formDialogRef = ref();
|
||||||
// 搜索变量
|
// 搜索变量
|
||||||
const queryRef = ref()
|
const queryRef = ref();
|
||||||
const showSearch = ref(true)
|
const showSearch = ref(true);
|
||||||
// 多选变量
|
// 多选变量
|
||||||
const selectObjs = ref([]) as any
|
const selectObjs = ref([]) as any;
|
||||||
const multiple = ref(true)
|
const multiple = ref(true);
|
||||||
|
|
||||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||||
queryForm: {},
|
queryForm: {},
|
||||||
pageList: fetchList,
|
pageList: fetchList,
|
||||||
onLoaded: onLoaded({key: "createUser"}, {key: "receiveUser"}, {key: "flowInstId"}, {key: "receiveDept"}),
|
onLoaded: onLoaded({ key: 'createUser' }, { key: 'receiveUser' }, { key: 'flowInstId' }, { key: 'receiveDept' }),
|
||||||
descs: ["create_time"]
|
descs: ['create_time'],
|
||||||
})
|
});
|
||||||
|
|
||||||
// table hook
|
// table hook
|
||||||
const {
|
const { getDataList, currentChangeHandle, sizeChangeHandle, sortChangeHandle, downBlobFile } = useTable(state);
|
||||||
getDataList,
|
|
||||||
currentChangeHandle,
|
|
||||||
sizeChangeHandle,
|
|
||||||
sortChangeHandle,
|
|
||||||
downBlobFile
|
|
||||||
} = useTable(state)
|
|
||||||
|
|
||||||
|
// 清空搜索条件
|
||||||
|
const resetQuery = () => {
|
||||||
// 清空搜索条件
|
// 清空搜索条件
|
||||||
const resetQuery = () => {
|
queryRef.value?.resetFields();
|
||||||
// 清空搜索条件
|
|
||||||
queryRef.value?.resetFields()
|
|
||||||
// 清空多选
|
// 清空多选
|
||||||
selectObjs.value = []
|
selectObjs.value = [];
|
||||||
getDataList()
|
getDataList();
|
||||||
}
|
};
|
||||||
|
|
||||||
// 导出excel
|
// 导出excel
|
||||||
const exportExcel = () => {
|
const exportExcel = () => {
|
||||||
downBlobFile('/order/handover-flow/export', state.queryForm, 'handover-flow.xlsx')
|
downBlobFile('/order/handover-flow/export', state.queryForm, 'handover-flow.xlsx');
|
||||||
}
|
};
|
||||||
|
|
||||||
// 多选事件
|
// 多选事件
|
||||||
const handleSelectionChange = (objs: any) => {
|
const handleSelectionChange = (objs: any) => {
|
||||||
selectObjs.value = objs.map(({ id }) => id);
|
selectObjs.value = objs.map(({ id }) => id);
|
||||||
multiple.value = !objs.length;
|
multiple.value = !objs.length;
|
||||||
};
|
};
|
||||||
|
|
||||||
function handleRecallReset(row) {
|
function handleRecallReset(row) {
|
||||||
let params = {id: row.flowInstId, flowKey: row.flowKey, status: row.status}
|
let params = { id: row.flowInstId, flowKey: row.flowKey, status: row.status };
|
||||||
if (row.status === DIC_PROP.ORDER_STATUS[0].value) {
|
if (row.status === DIC_PROP.ORDER_STATUS[0].value) {
|
||||||
recallReset(params).then(() => {
|
recallReset(params).then(() => {
|
||||||
useMessage().success('重发成功');
|
useMessage().success('重发成功');
|
||||||
getDataList();
|
getDataList();
|
||||||
})
|
});
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
useMessageBox().confirm('是否确认要撤回该工单?')
|
useMessageBox()
|
||||||
|
.confirm('是否确认要撤回该工单?')
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return recallReset(params)
|
return recallReset(params);
|
||||||
}).then(() => {
|
|
||||||
useMessage().success('撤回成功')
|
|
||||||
getDataList();
|
|
||||||
})
|
})
|
||||||
}
|
.then(() => {
|
||||||
|
useMessage().success('撤回成功');
|
||||||
|
getDataList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 删除操作
|
// 删除操作
|
||||||
const handleDelete = async (ids: string[]) => {
|
const handleDelete = async (ids: string[]) => {
|
||||||
try {
|
try {
|
||||||
await useMessageBox().confirm(t('common.delConfirmText'));
|
await useMessageBox().confirm(t('common.delConfirmText'));
|
||||||
} catch {
|
} catch {
|
||||||
@@ -263,5 +292,5 @@
|
|||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
useMessage().error(err.msg);
|
useMessage().error(err.msg);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -4,98 +4,136 @@
|
|||||||
<el-row v-show="showSearch">
|
<el-row v-show="showSearch">
|
||||||
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
|
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
|
||||||
<el-form-item :label="$t('handoverFlow.handoverReason')" prop="handoverReason">
|
<el-form-item :label="$t('handoverFlow.handoverReason')" prop="handoverReason">
|
||||||
<el-select v-model="state.queryForm.handoverReason"
|
<el-select
|
||||||
:placeholder="t('handoverFlow.inputHandoverReasonTip')" clearable filterable
|
v-model="state.queryForm.handoverReason"
|
||||||
style="max-width: 180px">
|
:placeholder="t('handoverFlow.inputHandoverReasonTip')"
|
||||||
<el-option v-for="(item, index) in DIC_PROP.HANDOVER_REASON" :key="index"
|
clearable
|
||||||
:label="item.label" :value="item.value"></el-option>
|
filterable
|
||||||
|
style="max-width: 180px"
|
||||||
|
>
|
||||||
|
<el-option v-for="(item, index) in DIC_PROP.HANDOVER_REASON" :key="index" :label="item.label" :value="item.value"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('handoverFlow.receiveDept')" prop="receiveDept">
|
<el-form-item :label="$t('handoverFlow.receiveDept')" prop="receiveDept">
|
||||||
<el-tooltip content="请输入部门名称进行模糊搜索" placement="top">
|
<el-tooltip content="请输入部门名称进行模糊搜索" placement="top">
|
||||||
<el-select v-model="state.queryForm.receiveDept"
|
<el-select
|
||||||
:placeholder="t('handoverFlow.inputReceiveDeptTip')" clearable filterable
|
v-model="state.queryForm.receiveDept"
|
||||||
remote :remote-method="remoteMethodDept" :reserve-keyword="false"
|
:placeholder="t('handoverFlow.inputReceiveDeptTip')"
|
||||||
style="max-width: 180px">
|
clearable
|
||||||
<el-option v-for="(item, index) in dicData.receiveDept" :key="index" :label="item.name"
|
filterable
|
||||||
:value="item.deptId"></el-option>
|
remote
|
||||||
|
:remote-method="remoteMethodDept"
|
||||||
|
:reserve-keyword="false"
|
||||||
|
style="max-width: 180px"
|
||||||
|
>
|
||||||
|
<el-option v-for="(item, index) in dicData.receiveDept" :key="index" :label="item.name" :value="item.deptId"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('handoverFlow.receiveUser')" prop="receiveUser">
|
<el-form-item :label="$t('handoverFlow.receiveUser')" prop="receiveUser">
|
||||||
<el-tooltip content="请输入用户名称进行模糊搜索" placement="top">
|
<el-tooltip content="请输入用户名称进行模糊搜索" placement="top">
|
||||||
<el-select v-model="state.queryForm.receiveUser"
|
<el-select
|
||||||
:placeholder="t('handoverFlow.inputReceiveUserTip')" clearable filterable
|
v-model="state.queryForm.receiveUser"
|
||||||
remote :remote-method="remoteMethodUser" :reserve-keyword="false"
|
:placeholder="t('handoverFlow.inputReceiveUserTip')"
|
||||||
style="max-width: 180px">
|
clearable
|
||||||
<el-option v-for="(item, index) in dicData.receiveUser" :key="index" :label="item.name"
|
filterable
|
||||||
:value="item.userId"></el-option>
|
remote
|
||||||
|
:remote-method="remoteMethodUser"
|
||||||
|
:reserve-keyword="false"
|
||||||
|
style="max-width: 180px"
|
||||||
|
>
|
||||||
|
<el-option v-for="(item, index) in dicData.receiveUser" :key="index" :label="item.name" :value="item.userId"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('handoverFlow.type')" prop="type">
|
<el-form-item :label="$t('handoverFlow.type')" prop="type">
|
||||||
<el-select v-model="state.queryForm.type" :placeholder="t('handoverFlow.inputTypeTip')"
|
<el-select v-model="state.queryForm.type" :placeholder="t('handoverFlow.inputTypeTip')" clearable filterable style="max-width: 180px">
|
||||||
clearable filterable style="max-width: 180px">
|
<el-option v-for="(item, index) in DIC_PROP.HANDOVER_TYPE" :key="index" :label="item.label" :value="item.value"></el-option>
|
||||||
<el-option v-for="(item, index) in DIC_PROP.HANDOVER_TYPE" :key="index" :label="item.label"
|
|
||||||
:value="item.value"></el-option>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('handoverNodeRecord.status')" prop="status">
|
<el-form-item :label="$t('handoverNodeRecord.status')" prop="status">
|
||||||
<el-select v-model="state.queryForm.status"
|
<el-select
|
||||||
:placeholder="t('handoverNodeRecord.inputStatusTip')" clearable filterable
|
v-model="state.queryForm.status"
|
||||||
style="max-width: 180px">
|
:placeholder="t('handoverNodeRecord.inputStatusTip')"
|
||||||
<el-option v-for="(item, index) in DIC_PROP.HANDOVER_STATUS" :key="index"
|
clearable
|
||||||
:label="item.label" :value="item.value"></el-option>
|
filterable
|
||||||
|
style="max-width: 180px"
|
||||||
|
>
|
||||||
|
<el-option v-for="(item, index) in DIC_PROP.HANDOVER_STATUS" :key="index" :label="item.label" :value="item.value"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
<div class="mb8" style="width: 100%">
|
<div class="mb8" style="width: 100%">
|
||||||
<el-button icon="edit-pen" type="primary" class="ml10" @click="methods.handleUpdateFlow"
|
<el-button
|
||||||
:loading="state.loading" v-if="state.queryForm.retStatus === '1'"
|
icon="edit-pen"
|
||||||
v-auth="'order_handovernoderecord_edit'">
|
type="primary"
|
||||||
|
class="ml10"
|
||||||
|
@click="methods.handleUpdateFlow"
|
||||||
|
:loading="state.loading"
|
||||||
|
v-if="state.queryForm.retStatus === '1'"
|
||||||
|
v-auth="'order_handovernoderecord_edit'"
|
||||||
|
>
|
||||||
{{ $t('jfI18n.updateFlow') }}
|
{{ $t('jfI18n.updateFlow') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button icon="RefreshLeft" type="primary" class="ml10" @click="methods.handleCheckToReject"
|
<el-button
|
||||||
:loading="state.loading" v-if="data.isCheckToReject"
|
icon="RefreshLeft"
|
||||||
v-auth="'order_handovernoderecord_edit'">
|
type="primary"
|
||||||
|
class="ml10"
|
||||||
|
@click="methods.handleCheckToReject"
|
||||||
|
:loading="state.loading"
|
||||||
|
v-if="data.isCheckToReject"
|
||||||
|
v-auth="'order_handovernoderecord_edit'"
|
||||||
|
>
|
||||||
{{ $t('jfI18n.rejectBtn') }}
|
{{ $t('jfI18n.rejectBtn') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button icon="CircleCheck" type="primary" class="ml10" @click="methods.handleConfirmReceive"
|
<el-button
|
||||||
:loading="state.loading" v-if="data.isConfirmReceive"
|
icon="CircleCheck"
|
||||||
v-auth="'order_handovernoderecord_edit'">
|
type="primary"
|
||||||
|
class="ml10"
|
||||||
|
@click="methods.handleConfirmReceive"
|
||||||
|
:loading="state.loading"
|
||||||
|
v-if="data.isConfirmReceive"
|
||||||
|
v-auth="'order_handovernoderecord_edit'"
|
||||||
|
>
|
||||||
{{ $t('jfI18n.receiveBtn') }}
|
{{ $t('jfI18n.receiveBtn') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-table :data="state.dataList" v-loading="state.loading" style="width: 100%"
|
<el-table
|
||||||
@selection-change="handleSelectionChange" @sort-change="sortChangeHandle">
|
:data="state.dataList"
|
||||||
<el-table-column type="selection" width="40" align="center" v-if="data.selection"/>
|
v-loading="state.loading"
|
||||||
<el-table-column type="index" :label="t('handoverNodeRecord.index')" width="40"/>
|
style="width: 100%"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
|
@sort-change="sortChangeHandle"
|
||||||
|
>
|
||||||
|
<el-table-column type="selection" width="40" align="center" v-if="data.selection" />
|
||||||
|
<el-table-column type="index" :label="t('handoverNodeRecord.index')" width="40" />
|
||||||
<el-table-column prop="flowKey" :label="t('handoverNodeRecord.flowKey')" show-overflow-tooltip>
|
<el-table-column prop="flowKey" :label="t('handoverNodeRecord.flowKey')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<convert-name :options="state.dicData.flowInstId" :value="scope.row.flowKey"
|
<convert-name :options="state.dicData.flowInstId" :value="scope.row.flowKey" :valueKey="'flowKey'" :showKey="'flowName'"></convert-name>
|
||||||
:valueKey="'flowKey'" :showKey="'flowName'"></convert-name>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="initiatorId" :label="t('handoverNodeRecord.initiatorId')" show-overflow-tooltip>
|
<el-table-column prop="initiatorId" :label="t('handoverNodeRecord.initiatorId')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<convert-name :options="state.dicData.initiatorId" :value="scope.row.initiatorId"
|
<convert-name :options="state.dicData.initiatorId" :value="scope.row.initiatorId" :valueKey="'userId'" :showKey="'name'"></convert-name>
|
||||||
:valueKey="'userId'" :showKey="'name'"></convert-name>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="runJobId" :label="t('handoverNodeRecord.runJobId')" show-overflow-tooltip>
|
<el-table-column prop="runJobId" :label="t('handoverNodeRecord.runJobId')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<convert-name :options="state.dicData.runJobId" :value="scope.row.runJobId"
|
<convert-name :options="state.dicData.runJobId" :value="scope.row.runJobId" :valueKey="'id'" :showKey="'jobName'"></convert-name>
|
||||||
:valueKey="'id'" :showKey="'jobName'"></convert-name>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="startTime" :label="t('handoverNodeRecord.startTime')" show-overflow-tooltip/>
|
<el-table-column prop="startTime" :label="t('handoverNodeRecord.startTime')" show-overflow-tooltip />
|
||||||
<el-table-column prop="todoList" :label="t('handoverNodeRecord.todoList')" show-overflow-tooltip>
|
<el-table-column prop="todoList" :label="t('handoverNodeRecord.todoList')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-input :disabled="!scope.row.$cellEdit" v-model="scope.row.todoList" type="textarea"
|
<el-input
|
||||||
:placeholder="t('handoverNodeRecord.inputTodoListTip')"/>
|
:disabled="!scope.row.$cellEdit"
|
||||||
|
v-model="scope.row.todoList"
|
||||||
|
type="textarea"
|
||||||
|
:placeholder="t('handoverNodeRecord.inputTodoListTip')"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="status" :label="t('handoverNodeRecord.status')" show-overflow-tooltip>
|
<el-table-column prop="status" :label="t('handoverNodeRecord.status')" show-overflow-tooltip>
|
||||||
@@ -105,145 +143,158 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="createUser" :label="t('handoverNodeRecord.createUser')" show-overflow-tooltip>
|
<el-table-column prop="createUser" :label="t('handoverNodeRecord.createUser')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<convert-name :options="state.dicData.createUser" :value="scope.row.createUser"
|
<convert-name :options="state.dicData.createUser" :value="scope.row.createUser" :valueKey="'userId'" :showKey="'name'"></convert-name>
|
||||||
:valueKey="'userId'" :showKey="'name'"></convert-name>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="createTime" :label="t('handoverNodeRecord.createTime')" show-overflow-tooltip/>
|
<el-table-column prop="createTime" :label="t('handoverNodeRecord.createTime')" show-overflow-tooltip />
|
||||||
<el-table-column :label="$t('common.action')" width="200" v-if="data.menu">
|
<el-table-column :label="$t('common.action')" width="200" v-if="data.menu">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button text type="primary" icon="view" v-if="!scope.row.$cellEdit"
|
<el-button
|
||||||
|
text
|
||||||
|
type="primary"
|
||||||
|
icon="view"
|
||||||
|
v-if="!scope.row.$cellEdit"
|
||||||
@click="formDialogRef.openDialog('view', scope.row.id)"
|
@click="formDialogRef.openDialog('view', scope.row.id)"
|
||||||
v-auth="'order_handovernoderecord_view'">
|
v-auth="'order_handovernoderecord_view'"
|
||||||
|
>
|
||||||
{{ $t('common.viewBtn') }}
|
{{ $t('common.viewBtn') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button icon="edit-pen" text type="primary" v-auth="'order_handovernoderecord_edit'" v-if="!scope.row.$cellEdit"
|
<el-button
|
||||||
@click="methods.handleEdit(scope.row, scope.$index, true)">{{ $t('common.editBtn') }}
|
icon="edit-pen"
|
||||||
|
text
|
||||||
|
type="primary"
|
||||||
|
v-auth="'order_handovernoderecord_edit'"
|
||||||
|
v-if="!scope.row.$cellEdit"
|
||||||
|
@click="methods.handleEdit(scope.row, scope.$index, true)"
|
||||||
|
>{{ $t('common.editBtn') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button icon="Check" text type="primary" v-auth="'order_handovernoderecord_add'" v-if="scope.row.$cellEdit"
|
<el-button
|
||||||
@click="methods.handleUpdate(scope.row, scope.$index)">{{ $t('jfI18n.saveBtn') }}
|
icon="Check"
|
||||||
|
text
|
||||||
|
type="primary"
|
||||||
|
v-auth="'order_handovernoderecord_add'"
|
||||||
|
v-if="scope.row.$cellEdit"
|
||||||
|
@click="methods.handleUpdate(scope.row, scope.$index)"
|
||||||
|
>{{ $t('jfI18n.saveBtn') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button icon="Close" text type="primary" v-auth="'order_handovernoderecord_edit'" v-if="scope.row.$cellEdit"
|
<el-button
|
||||||
@click="methods.handleEdit(scope.row, scope.$index, false)">{{ $t('jfI18n.cancelBtn') }}
|
icon="Close"
|
||||||
|
text
|
||||||
|
type="primary"
|
||||||
|
v-auth="'order_handovernoderecord_edit'"
|
||||||
|
v-if="scope.row.$cellEdit"
|
||||||
|
@click="methods.handleEdit(scope.row, scope.$index, false)"
|
||||||
|
>{{ $t('jfI18n.cancelBtn') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button icon="delete" text type="primary" v-auth="'order_handovernoderecord_del'"
|
<el-button icon="delete" text type="primary" v-auth="'order_handovernoderecord_del'" @click="handleDelete(scope.row.id, scope.$index)"
|
||||||
@click="handleDelete(scope.row.id, scope.$index)">{{
|
>{{ $t('common.delBtn') }}
|
||||||
$t('common.delBtn')
|
|
||||||
}}
|
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle"
|
<pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle" v-bind="state.pagination" />
|
||||||
v-bind="state.pagination"/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 编辑、新增 -->
|
<!-- 编辑、新增 -->
|
||||||
<form-dialog ref="formDialogRef" @refresh="getDataList(false)"/>
|
<form-dialog ref="formDialogRef" @refresh="getDataList(false)" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="HandoverNodeRecordFlow">
|
<script setup lang="ts" name="HandoverNodeRecordFlow">
|
||||||
import {BasicTableProps, useTable} from "/@/hooks/table";
|
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||||
import * as handoverNodeRecord from '/@/api/order/handover-node-record'
|
import * as handoverNodeRecord from '/@/api/order/handover-node-record';
|
||||||
import {useMessage, useMessageBox} from "/@/hooks/message";
|
import { useMessage, useMessageBox } from '/@/hooks/message';
|
||||||
|
|
||||||
import {useI18n} from "vue-i18n";
|
import { useI18n } from 'vue-i18n';
|
||||||
import {onFormLoadedUrl, onLoadDicUrl, onLoaded, remoteMethodByKey} from "/@/flow/components/convert-name/convert";
|
import { onFormLoadedUrl, onLoadDicUrl, onLoaded, remoteMethodByKey } from '/@/flow/components/convert-name/convert';
|
||||||
import {validateNull} from "/@/utils/validate";
|
import { validateNull } from '/@/utils/validate';
|
||||||
import * as handoverFlow from '/@/api/order/handover-flow'
|
import * as handoverFlow from '/@/api/order/handover-flow';
|
||||||
import * as orderVue from "/@/api/order/order-key-vue";
|
import * as orderVue from '/@/api/order/order-key-vue';
|
||||||
import {PROP_CONST} from '/@/flow/support/prop-const'
|
import { PROP_CONST } from '/@/flow/support/prop-const';
|
||||||
import {useUserInfo} from "/@/stores/userInfo";
|
import { useUserInfo } from '/@/stores/userInfo';
|
||||||
import {setCrudQueryForm} from "/@/flow/support/common";
|
import { setCrudQueryForm } from '/@/flow/support/common';
|
||||||
|
|
||||||
// 引入组件
|
// 引入组件
|
||||||
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
|
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
|
||||||
const {t} = useI18n()
|
const { t } = useI18n();
|
||||||
const userInfo = useUserInfo();
|
const userInfo = useUserInfo();
|
||||||
// 定义查询字典
|
// 定义查询字典
|
||||||
const dicData = reactive({});
|
const dicData = reactive({});
|
||||||
const onLoad = onLoadDicUrl();
|
const onLoad = onLoadDicUrl();
|
||||||
const onFormLoaded = onFormLoadedUrl({key: "receiveDept"}, {key: "receiveUser"});
|
const onFormLoaded = onFormLoadedUrl({ key: 'receiveDept' }, { key: 'receiveUser' });
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// onLoad(dicData);
|
// onLoad(dicData);
|
||||||
});
|
});
|
||||||
|
|
||||||
function remoteMethodDept(query: string) {
|
function remoteMethodDept(query: string) {
|
||||||
remoteMethodByKey(query, onLoad, dicData, 'deptName', "receiveDept")
|
remoteMethodByKey(query, onLoad, dicData, 'deptName', 'receiveDept');
|
||||||
}
|
}
|
||||||
|
|
||||||
function remoteMethodUser(query: string) {
|
function remoteMethodUser(query: string) {
|
||||||
remoteMethodByKey(query, onLoad, dicData, 'userName', "receiveUser")
|
remoteMethodByKey(query, onLoad, dicData, 'userName', 'receiveUser');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 定义变量内容
|
// 定义变量内容
|
||||||
const formDialogRef = ref()
|
const formDialogRef = ref();
|
||||||
// 搜索变量
|
// 搜索变量
|
||||||
const queryRef = ref()
|
const queryRef = ref();
|
||||||
const showSearch = ref(true)
|
const showSearch = ref(true);
|
||||||
// 多选变量
|
// 多选变量
|
||||||
const selectObjs = ref([]) as any
|
const selectObjs = ref([]) as any;
|
||||||
const multiple = ref(true)
|
const multiple = ref(true);
|
||||||
|
|
||||||
const onTableLoaded = async (state) => {
|
const onTableLoaded = async (state) => {
|
||||||
let onLoadedInit = onLoaded({key: "createUser"}, {key: "initiatorId"}, {key: "flowInstId"}, {key: "runJobId"});
|
let onLoadedInit = onLoaded({ key: 'createUser' }, { key: 'initiatorId' }, { key: 'flowInstId' }, { key: 'runJobId' });
|
||||||
await onLoadedInit(state)
|
await onLoadedInit(state);
|
||||||
await onFormLoaded(dicData, state.queryForm)
|
await onFormLoaded(dicData, state.queryForm);
|
||||||
}
|
};
|
||||||
|
|
||||||
const validate = async () => {
|
const validate = async () => {
|
||||||
// 防止被手动修改
|
// 防止被手动修改
|
||||||
methods.setCrudQueryForm()
|
methods.setCrudQueryForm();
|
||||||
if (!state.queryForm.status || !state.queryForm.type) {
|
if (!state.queryForm.status || !state.queryForm.type) {
|
||||||
useMessage().info('请选择交接条件')
|
useMessage().info('请选择交接条件');
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
// 被驳回时查询
|
// 被驳回时查询
|
||||||
state.queryForm.createUser = props.currJob.createUser
|
state.queryForm.createUser = props.currJob.createUser;
|
||||||
return true
|
return true;
|
||||||
}
|
};
|
||||||
|
|
||||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||||
queryForm: {},
|
queryForm: {},
|
||||||
pageList: handoverNodeRecord.fetchFlowList,
|
pageList: handoverNodeRecord.fetchFlowList,
|
||||||
validate: validate,
|
validate: validate,
|
||||||
onLoaded: onTableLoaded,
|
onLoaded: onTableLoaded,
|
||||||
descs: ["create_time"],
|
descs: ['create_time'],
|
||||||
createdIsNeed: false
|
createdIsNeed: false,
|
||||||
})
|
});
|
||||||
|
|
||||||
// table hook
|
// table hook
|
||||||
const {
|
const { getDataList, currentChangeHandle, sizeChangeHandle, sortChangeHandle, downBlobFile } = useTable(state);
|
||||||
getDataList,
|
|
||||||
currentChangeHandle,
|
|
||||||
sizeChangeHandle,
|
|
||||||
sortChangeHandle,
|
|
||||||
downBlobFile
|
|
||||||
} = useTable(state)
|
|
||||||
|
|
||||||
|
// 清空搜索条件
|
||||||
|
const resetQuery = () => {
|
||||||
// 清空搜索条件
|
// 清空搜索条件
|
||||||
const resetQuery = () => {
|
queryRef.value?.resetFields();
|
||||||
// 清空搜索条件
|
|
||||||
queryRef.value?.resetFields()
|
|
||||||
// 清空多选
|
// 清空多选
|
||||||
selectObjs.value = []
|
selectObjs.value = [];
|
||||||
data.selections = []
|
data.selections = [];
|
||||||
getDataList()
|
getDataList();
|
||||||
}
|
};
|
||||||
|
|
||||||
// 多选事件
|
// 多选事件
|
||||||
const handleSelectionChange = (objs: any) => {
|
const handleSelectionChange = (objs: any) => {
|
||||||
data.selections = objs
|
data.selections = objs;
|
||||||
selectObjs.value = objs.map(({ id }) => id);
|
selectObjs.value = objs.map(({ id }) => id);
|
||||||
multiple.value = !objs.length;
|
multiple.value = !objs.length;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 删除操作
|
// 删除操作
|
||||||
const handleDelete = async (id: string, index) => {
|
const handleDelete = async (id: string, index) => {
|
||||||
if (validateNull(id)) {
|
if (validateNull(id)) {
|
||||||
useMessage().info('还未保存')
|
useMessage().info('还未保存');
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await useMessageBox().confirm(t('common.delConfirmText'));
|
await useMessageBox().confirm(t('common.delConfirmText'));
|
||||||
@@ -252,15 +303,15 @@
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await handoverNodeRecord.delObjs(id);
|
await handoverNodeRecord.delObjs(id);
|
||||||
state.dataList.splice(index, 1)
|
state.dataList.splice(index, 1);
|
||||||
state.pagination!.total = state.dataList.length
|
state.pagination!.total = state.dataList.length;
|
||||||
useMessage().success(t('common.delSuccessText'));
|
useMessage().success(t('common.delSuccessText'));
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
useMessage().error(err.msg);
|
useMessage().error(err.msg);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
currJob: {
|
currJob: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: null,
|
default: null,
|
||||||
@@ -269,84 +320,85 @@
|
|||||||
type: Object,
|
type: Object,
|
||||||
default: {},
|
default: {},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
selections: [],
|
selections: [],
|
||||||
isCheckToReject: false,
|
isCheckToReject: false,
|
||||||
isConfirmReceive: false,
|
isConfirmReceive: false,
|
||||||
menu: false,
|
menu: false,
|
||||||
selection: false
|
selection: false,
|
||||||
})
|
});
|
||||||
|
|
||||||
const methods = {
|
const methods = {
|
||||||
initJobData() {
|
initJobData() {
|
||||||
state.loading = false
|
state.loading = false;
|
||||||
data.menu = false;
|
data.menu = false;
|
||||||
data.selection = false;
|
data.selection = false;
|
||||||
data.isConfirmReceive = false
|
data.isConfirmReceive = false;
|
||||||
data.isCheckToReject = false
|
data.isCheckToReject = false;
|
||||||
methods.initSelections()
|
methods.initSelections();
|
||||||
},
|
},
|
||||||
async resolveMethod() {
|
async resolveMethod() {
|
||||||
let index = state.dataList.findIndex(f => f.retStatus === '1') + 1
|
let index = state.dataList.findIndex((f) => f.retStatus === '1') + 1;
|
||||||
if (index !== 0) {
|
if (index !== 0) {
|
||||||
useMessage().info('第 ' + index + ' 行交接项未修改,请先修改并保存')
|
useMessage().info('第 ' + index + ' 行交接项未修改,请先修改并保存');
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
orderVue.currElTabIsSave(props.currJob, props.currElTab.id, true)
|
orderVue.currElTabIsSave(props.currJob, props.currElTab.id, true);
|
||||||
return true
|
return true;
|
||||||
},
|
},
|
||||||
async initSelections() {
|
async initSelections() {
|
||||||
let hiJob = props.currJob.hiJob
|
let hiJob = props.currJob.hiJob;
|
||||||
// 判断是否仅查看
|
// 判断是否仅查看
|
||||||
await orderVue.currElTabIsView(null, props.currJob, props.currElTab.id)
|
await orderVue.currElTabIsView(null, props.currJob, props.currElTab.id);
|
||||||
let find = orderVue.currElTabIsExist(props.currJob, props.currElTab.id)
|
let find = orderVue.currElTabIsExist(props.currJob, props.currElTab.id);
|
||||||
if (find.isFormEdit === '0') hiJob = true
|
if (find.isFormEdit === '0') hiJob = true;
|
||||||
let userKey = props.currJob.userKey
|
let userKey = props.currJob.userKey;
|
||||||
let currJob = PROP_CONST.HANDOVER_FLOW.userKey
|
let currJob = PROP_CONST.HANDOVER_FLOW.userKey;
|
||||||
if (userKey === currJob.create_user) {
|
if (userKey === currJob.create_user) {
|
||||||
// 判断修改工单
|
// 判断修改工单
|
||||||
if (!hiJob) {// 为0后带入参数查询不出1的数据
|
if (!hiJob) {
|
||||||
state.queryForm.retStatus = '1'
|
// 为0后带入参数查询不出1的数据
|
||||||
|
state.queryForm.retStatus = '1';
|
||||||
data.menu = true;
|
data.menu = true;
|
||||||
} else data.menu = false;
|
} else data.menu = false;
|
||||||
// 被驳回需全部保存
|
// 被驳回需全部保存
|
||||||
props.currJob.resolveMethods.push(methods.resolveMethod)
|
props.currJob.resolveMethods.push(methods.resolveMethod);
|
||||||
} else if (userKey === currJob.receive_user || userKey === currJob.curr_dept_manager) {
|
} else if (userKey === currJob.receive_user || userKey === currJob.curr_dept_manager) {
|
||||||
data.menu = false;
|
data.menu = false;
|
||||||
state.queryForm.retStatus = '0'
|
state.queryForm.retStatus = '0';
|
||||||
// 判断驳回工单
|
// 判断驳回工单
|
||||||
if (!hiJob) {
|
if (!hiJob) {
|
||||||
data.isCheckToReject = true
|
data.isCheckToReject = true;
|
||||||
data.selection = true;
|
data.selection = true;
|
||||||
if (userKey === currJob.curr_dept_manager) orderVue.currElTabIsSave(props.currJob, props.currElTab.id, true)
|
if (userKey === currJob.curr_dept_manager) orderVue.currElTabIsSave(props.currJob, props.currElTab.id, true);
|
||||||
}
|
}
|
||||||
// 判断接收工单
|
// 判断接收工单
|
||||||
if (userKey === currJob.receive_user && !hiJob) {
|
if (userKey === currJob.receive_user && !hiJob) {
|
||||||
props.currJob.resolveSaves.push(methods.handleConfirmReceive)
|
props.currJob.resolveSaves.push(methods.handleConfirmReceive);
|
||||||
data.isConfirmReceive = true
|
data.isConfirmReceive = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 其他节点自动完成
|
// 其他节点自动完成
|
||||||
orderVue.currElTabIsSave(props.currJob, props.currElTab.id, true)
|
orderVue.currElTabIsSave(props.currJob, props.currElTab.id, true);
|
||||||
}
|
}
|
||||||
// 初始化
|
// 初始化
|
||||||
getDataList()
|
getDataList();
|
||||||
},
|
},
|
||||||
async handleUpdate(row, index) {
|
async handleUpdate(row, index) {
|
||||||
try {
|
try {
|
||||||
state.loading = true;
|
state.loading = true;
|
||||||
// 防止被手动修改
|
// 防止被手动修改
|
||||||
methods.setCrudQueryForm()
|
methods.setCrudQueryForm();
|
||||||
// 驳回后修改为正常状态
|
// 驳回后修改为正常状态
|
||||||
if (state.queryForm.retStatus === '1') row.retStatus = '0'
|
if (state.queryForm.retStatus === '1') row.retStatus = '0';
|
||||||
let resp = await handoverNodeRecord.putObj(Object.assign({}, state.queryForm, row));
|
let resp = await handoverNodeRecord.putObj(Object.assign({}, state.queryForm, row));
|
||||||
// 延迟赋值
|
// 延迟赋值
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
state.dataList[index].id = resp.data.id
|
state.dataList[index].id = resp.data.id;
|
||||||
state.dataList[index].$cellEdit = false
|
state.dataList[index].$cellEdit = false;
|
||||||
}, 0)
|
}, 0);
|
||||||
useMessage().success('操作成功')
|
useMessage().success('操作成功');
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
useMessage().error(err.msg);
|
useMessage().error(err.msg);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -357,83 +409,90 @@
|
|||||||
// 可手动修改的交接参数
|
// 可手动修改的交接参数
|
||||||
// common.setPropsDataValue(order, state.queryForm, 'handoverReason', 'receiveDept')
|
// common.setPropsDataValue(order, state.queryForm, 'handoverReason', 'receiveDept')
|
||||||
if (!state.queryForm.status || !state.queryForm.type || !state.queryForm.handoverReason || !state.queryForm.receiveDept) {
|
if (!state.queryForm.status || !state.queryForm.type || !state.queryForm.handoverReason || !state.queryForm.receiveDept) {
|
||||||
useMessage().info('请选择交接条件:交接状态、交接类型、交接原因、接受部门')
|
useMessage().info('请选择交接条件:交接状态、交接类型、交接原因、接受部门');
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
methods.timeoutLoading(3)
|
methods.timeoutLoading(3);
|
||||||
let queryForm = {
|
let queryForm = {
|
||||||
id: props.currJob.orderId,
|
id: props.currJob.orderId,
|
||||||
code: props.currJob.code,
|
code: props.currJob.code,
|
||||||
flowKey: props.currJob.flowKey,
|
flowKey: props.currJob.flowKey,
|
||||||
flowInstId: props.currJob.flowInstId,
|
flowInstId: props.currJob.flowInstId,
|
||||||
runJobId: props.currJob.id
|
runJobId: props.currJob.id,
|
||||||
}
|
};
|
||||||
// 修改工单信息时,任务交接不允许修改类型、状态
|
// 修改工单信息时,任务交接不允许修改类型、状态
|
||||||
let order = props.currJob.order
|
let order = props.currJob.order;
|
||||||
let assign = Object.assign({}, state.queryForm, queryForm, {type: order.type, status: order.status});
|
let assign = Object.assign({}, state.queryForm, queryForm, { type: order.type, status: order.status });
|
||||||
handoverFlow.putObj(assign).then(data => {
|
handoverFlow.putObj(assign).then((data) => {
|
||||||
orderVue.currElTabIsSave(props.currJob, props.currElTab.id, true)
|
orderVue.currElTabIsSave(props.currJob, props.currElTab.id, true);
|
||||||
useMessage().success('修改成功')
|
useMessage().success('修改成功');
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
// 防止被手动修改
|
// 防止被手动修改
|
||||||
setCrudQueryForm() {
|
setCrudQueryForm() {
|
||||||
let order = props.currJob.order
|
let order = props.currJob.order;
|
||||||
setCrudQueryForm(state, {prop: 'receiveDept', value: order.receiveDept}, {prop: 'type', value: order.type}
|
setCrudQueryForm(
|
||||||
, {prop: 'status', value: order.status}, {prop: 'receiveUser', value: order.receiveUser},
|
state,
|
||||||
{prop: 'handoverReason', value: order.handoverReason},{prop: 'orderId', value: props.currJob.orderId} )
|
{ prop: 'receiveDept', value: order.receiveDept },
|
||||||
|
{ prop: 'type', value: order.type },
|
||||||
|
{ prop: 'status', value: order.status },
|
||||||
|
{ prop: 'receiveUser', value: order.receiveUser },
|
||||||
|
{ prop: 'handoverReason', value: order.handoverReason },
|
||||||
|
{ prop: 'orderId', value: props.currJob.orderId }
|
||||||
|
);
|
||||||
},
|
},
|
||||||
handleCheckToReject() {
|
handleCheckToReject() {
|
||||||
// 防止被手动修改
|
// 防止被手动修改
|
||||||
methods.setCrudQueryForm()
|
methods.setCrudQueryForm();
|
||||||
// 驳回
|
// 驳回
|
||||||
if (validateNull(data.selections)) {
|
if (validateNull(data.selections)) {
|
||||||
useMessage().info('请选择需驳回的交接项')
|
useMessage().info('请选择需驳回的交接项');
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
methods.timeoutLoading(3)
|
methods.timeoutLoading(3);
|
||||||
state.queryForm.id = data.selections[0].orderId
|
state.queryForm.id = data.selections[0].orderId;
|
||||||
state.queryForm.rejectIds = data.selections.map(m => m.id)
|
state.queryForm.rejectIds = data.selections.map((m) => m.id);
|
||||||
handoverFlow.checkToReject(state.queryForm).then(data => {
|
handoverFlow.checkToReject(state.queryForm).then((data) => {
|
||||||
state.queryForm.id = null
|
state.queryForm.id = null;
|
||||||
getDataList()
|
getDataList();
|
||||||
useMessage().success('驳回成功')
|
useMessage().success('驳回成功');
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
async handleConfirmReceive() {
|
async handleConfirmReceive() {
|
||||||
// 防止被手动修改
|
// 防止被手动修改
|
||||||
methods.setCrudQueryForm()
|
methods.setCrudQueryForm();
|
||||||
// 接收
|
// 接收
|
||||||
if (validateNull(state.dataList)) {
|
if (validateNull(state.dataList)) {
|
||||||
useMessage().info('请选择交接项')
|
useMessage().info('请选择交接项');
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
methods.timeoutLoading(3)
|
methods.timeoutLoading(3);
|
||||||
state.queryForm.id = state.dataList[0].orderId
|
state.queryForm.id = state.dataList[0].orderId;
|
||||||
await handoverFlow.confirmReceive(state.queryForm)
|
await handoverFlow.confirmReceive(state.queryForm);
|
||||||
orderVue.currElTabIsSave(props.currJob, props.currElTab.id, true, null)
|
orderVue.currElTabIsSave(props.currJob, props.currElTab.id, true, null);
|
||||||
useMessage().success('接收成功')
|
useMessage().success('接收成功');
|
||||||
},
|
},
|
||||||
timeoutLoading(t) {
|
timeoutLoading(t) {
|
||||||
state.loading = true
|
state.loading = true;
|
||||||
setTimeout(() => {// 防重复提交
|
setTimeout(() => {
|
||||||
state.loading = false
|
// 防重复提交
|
||||||
}, t * 1000)
|
state.loading = false;
|
||||||
|
}, t * 1000);
|
||||||
},
|
},
|
||||||
handleEdit(row, index, bool) {
|
handleEdit(row, index, bool) {
|
||||||
row.$cellEdit = bool
|
row.$cellEdit = bool;
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
// 监听双向绑定
|
// 监听双向绑定
|
||||||
watch(
|
watch(
|
||||||
() => props.currJob.id,
|
() => props.currJob.id,
|
||||||
() => {
|
() => {
|
||||||
methods.initJobData();
|
methods.initJobData();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
methods.initJobData()
|
methods.initJobData();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog :title="title" v-model="visible" width="60%"
|
<el-dialog :title="title" v-model="visible" width="60%" :close-on-click-modal="false" draggable>
|
||||||
:close-on-click-modal="false" draggable>
|
|
||||||
<el-form ref="dataFormRef" :model="form" :rules="dataRules" label-width="90px" v-loading="loading" :disabled="operType === 'view'">
|
<el-form ref="dataFormRef" :model="form" :rules="dataRules" label-width="90px" v-loading="loading" :disabled="operType === 'view'">
|
||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<el-col :span="12" class="mb20">
|
<el-col :span="12" class="mb20">
|
||||||
@@ -29,13 +28,19 @@
|
|||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
<el-col :span="12" class="mb20">
|
||||||
<el-form-item :label="t('handoverNodeRecord.startTime')" prop="startTime">
|
<el-form-item :label="t('handoverNodeRecord.startTime')" prop="startTime">
|
||||||
<el-date-picker disabled type="datetime" :placeholder="t('handoverNodeRecord.inputStartTimeTip')" v-model="form.startTime" :value-format="dateTimeStr"></el-date-picker>
|
<el-date-picker
|
||||||
|
disabled
|
||||||
|
type="datetime"
|
||||||
|
:placeholder="t('handoverNodeRecord.inputStartTimeTip')"
|
||||||
|
v-model="form.startTime"
|
||||||
|
:value-format="dateTimeStr"
|
||||||
|
></el-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12" class="mb20">
|
<el-col :span="12" class="mb20">
|
||||||
<el-form-item :label="t('handoverNodeRecord.todoList')" prop="todoList">
|
<el-form-item :label="t('handoverNodeRecord.todoList')" prop="todoList">
|
||||||
<el-input v-model="form.todoList" type="textarea" :placeholder="t('handoverNodeRecord.inputTodoListTip')"/>
|
<el-input v-model="form.todoList" type="textarea" :placeholder="t('handoverNodeRecord.inputTodoListTip')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
@@ -46,7 +51,6 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer v-if="operType !== 'view'">
|
<template #footer v-if="operType !== 'view'">
|
||||||
@@ -59,54 +63,57 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="HandoverNodeRecordDialog">
|
<script setup lang="ts" name="HandoverNodeRecordDialog">
|
||||||
|
import { useMessage } from '/@/hooks/message';
|
||||||
|
import { getObj, addObj, putObj } from '/@/api/order/handover-node-record';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { rule } from '/@/utils/validate';
|
||||||
|
import { onCascadeChange, onFormLoadedUrl, onLoadDicUrl } from '/@/flow/components/convert-name/convert';
|
||||||
|
const emit = defineEmits(['refresh']);
|
||||||
|
|
||||||
import { useMessage } from "/@/hooks/message";
|
const { t } = useI18n();
|
||||||
import { getObj, addObj, putObj } from '/@/api/order/handover-node-record'
|
|
||||||
import { useI18n } from "vue-i18n"
|
|
||||||
import { rule } from '/@/utils/validate';
|
|
||||||
import {onCascadeChange, onFormLoadedUrl, onLoadDicUrl} from "/@/flow/components/convert-name/convert";
|
|
||||||
const emit = defineEmits(['refresh']);
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
// 定义变量内容
|
||||||
|
const dataFormRef = ref();
|
||||||
// 定义变量内容
|
const visible = ref(false);
|
||||||
const dataFormRef = ref();
|
const loading = ref(false);
|
||||||
const visible = ref(false);
|
const operType = ref(false);
|
||||||
const loading = ref(false);
|
const title = ref('');
|
||||||
const operType = ref(false);
|
// 定义字典
|
||||||
const title = ref('');
|
const dicData = reactive({});
|
||||||
// 定义字典
|
const cascadeDic = reactive({});
|
||||||
const dicData = reactive({});
|
const onLoad = onLoadDicUrl();
|
||||||
const cascadeDic = reactive({});
|
const onFormLoaded = onFormLoadedUrl({ key: 'initiatorId' });
|
||||||
const onLoad = onLoadDicUrl();
|
const onCascade = onCascadeChange(
|
||||||
const onFormLoaded = onFormLoadedUrl({key: "initiatorId"});
|
cascadeDic,
|
||||||
const onCascade = onCascadeChange(cascadeDic, {key: "flowInstId", cascades: ["flowKey", "runNodeId"]}, {key: "runNodeId", cascades: ["runJobId"]});
|
{ key: 'flowInstId', cascades: ['flowKey', 'runNodeId'] },
|
||||||
onMounted(() => {
|
{ key: 'runNodeId', cascades: ['runJobId'] }
|
||||||
|
);
|
||||||
|
onMounted(() => {
|
||||||
// onLoad(dicData);
|
// onLoad(dicData);
|
||||||
});
|
});
|
||||||
// 提交表单数据
|
// 提交表单数据
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
flowKey: '',
|
flowKey: '',
|
||||||
initiatorId: '',
|
initiatorId: '',
|
||||||
nodeJobId: '',
|
nodeJobId: '',
|
||||||
startTime: '',
|
startTime: '',
|
||||||
todoList: '',
|
todoList: '',
|
||||||
status: '',
|
status: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
// 定义校验规则
|
// 定义校验规则
|
||||||
const dataRules = ref({
|
const dataRules = ref({
|
||||||
flowKey: [{required: true, message: '业务类型不能为空', trigger: 'blur'}],
|
flowKey: [{ required: true, message: '业务类型不能为空', trigger: 'blur' }],
|
||||||
initiatorId: [{required: true, message: '交接申请人不能为空', trigger: 'blur'}],
|
initiatorId: [{ required: true, message: '交接申请人不能为空', trigger: 'blur' }],
|
||||||
nodeJobId: [{required: true, message: '任务名称不能为空', trigger: 'blur'}],
|
nodeJobId: [{ required: true, message: '任务名称不能为空', trigger: 'blur' }],
|
||||||
status: [{required: true, message: '交接状态不能为空', trigger: 'blur'}],
|
status: [{ required: true, message: '交接状态不能为空', trigger: 'blur' }],
|
||||||
})
|
});
|
||||||
|
|
||||||
// 打开弹窗
|
// 打开弹窗
|
||||||
const openDialog = (type: string, id: string) => {
|
const openDialog = (type: string, id: string) => {
|
||||||
visible.value = true
|
visible.value = true;
|
||||||
operType.value = type;
|
operType.value = type;
|
||||||
form.id = ''
|
form.id = '';
|
||||||
|
|
||||||
if (type === 'add') {
|
if (type === 'add') {
|
||||||
title.value = t('common.addBtn');
|
title.value = t('common.addBtn');
|
||||||
@@ -123,13 +130,13 @@
|
|||||||
|
|
||||||
// 获取HandoverNodeRecord信息
|
// 获取HandoverNodeRecord信息
|
||||||
if (id) {
|
if (id) {
|
||||||
form.id = id
|
form.id = id;
|
||||||
getHandoverNodeRecordData(id)
|
getHandoverNodeRecordData(id);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 提交
|
// 提交
|
||||||
const onSubmit = async () => {
|
const onSubmit = async () => {
|
||||||
const valid = await dataFormRef.value.validate().catch(() => {});
|
const valid = await dataFormRef.value.validate().catch(() => {});
|
||||||
if (!valid) return false;
|
if (!valid) return false;
|
||||||
|
|
||||||
@@ -144,23 +151,25 @@
|
|||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 初始化表单数据
|
// 初始化表单数据
|
||||||
const getHandoverNodeRecordData = (id: string) => {
|
const getHandoverNodeRecordData = (id: string) => {
|
||||||
// 获取数据
|
// 获取数据
|
||||||
loading.value = true
|
loading.value = true;
|
||||||
getObj(id).then((res: any) => {
|
getObj(id)
|
||||||
Object.assign(form, res.data)
|
.then((res: any) => {
|
||||||
|
Object.assign(form, res.data);
|
||||||
onFormLoaded(dicData, form);
|
onFormLoaded(dicData, form);
|
||||||
onCascade(form);
|
onCascade(form);
|
||||||
}).finally(() => {
|
|
||||||
loading.value = false
|
|
||||||
})
|
})
|
||||||
};
|
.finally(() => {
|
||||||
|
loading.value = false;
|
||||||
// 暴露变量
|
|
||||||
defineExpose({
|
|
||||||
openDialog
|
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 暴露变量
|
||||||
|
defineExpose({
|
||||||
|
openDialog,
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -35,6 +35,5 @@ export default {
|
|||||||
inputRunNodeIdTip: 'input runNodeId',
|
inputRunNodeIdTip: 'input runNodeId',
|
||||||
inputUpdateUserTip: 'input updateUser',
|
inputUpdateUserTip: 'input updateUser',
|
||||||
inputUpdateTimeTip: 'input updateTime',
|
inputUpdateTimeTip: 'input updateTime',
|
||||||
|
},
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
|||||||
@@ -35,6 +35,5 @@ export default {
|
|||||||
inputRunNodeIdTip: '请输入运行节点ID',
|
inputRunNodeIdTip: '请输入运行节点ID',
|
||||||
inputUpdateUserTip: '请输入修改人',
|
inputUpdateUserTip: '请输入修改人',
|
||||||
inputUpdateTimeTip: '请输入修改时间',
|
inputUpdateTimeTip: '请输入修改时间',
|
||||||
|
},
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
|||||||
@@ -3,16 +3,25 @@
|
|||||||
<div class="layout-padding-auto layout-padding-view">
|
<div class="layout-padding-auto layout-padding-view">
|
||||||
<el-row v-show="showSearch">
|
<el-row v-show="showSearch">
|
||||||
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
|
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
|
||||||
<el-form-item :label="$t('handoverNodeRecord.flowInstId')" prop="flowInstId" >
|
<el-form-item :label="$t('handoverNodeRecord.flowInstId')" prop="flowInstId">
|
||||||
<el-input :placeholder="t('handoverNodeRecord.inputFlowInstIdTip')" v-model="state.queryForm.flowInstId" clearable
|
<el-input
|
||||||
style="max-width: 180px" />
|
:placeholder="t('handoverNodeRecord.inputFlowInstIdTip')"
|
||||||
|
v-model="state.queryForm.flowInstId"
|
||||||
|
clearable
|
||||||
|
style="max-width: 180px"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('runFlow.flowKey')" prop="flowKey" >
|
<el-form-item :label="$t('runFlow.flowKey')" prop="flowKey">
|
||||||
<el-input :placeholder="t('runFlow.inputFlowKeyTip')" v-model="state.queryForm.flowKey" clearable
|
<el-input :placeholder="t('runFlow.inputFlowKeyTip')" v-model="state.queryForm.flowKey" clearable style="max-width: 180px" />
|
||||||
style="max-width: 180px" />
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('handoverNodeRecord.status')" prop="status" >
|
<el-form-item :label="$t('handoverNodeRecord.status')" prop="status">
|
||||||
<el-select v-model="state.queryForm.status" :placeholder="t('handoverNodeRecord.inputStatusTip')" clearable filterable style="max-width: 180px">
|
<el-select
|
||||||
|
v-model="state.queryForm.status"
|
||||||
|
:placeholder="t('handoverNodeRecord.inputStatusTip')"
|
||||||
|
clearable
|
||||||
|
filterable
|
||||||
|
style="max-width: 180px"
|
||||||
|
>
|
||||||
<el-option v-for="(item, index) in DIC_PROP.HANDOVER_STATUS" :key="index" :label="item.label" :value="item.value"></el-option>
|
<el-option v-for="(item, index) in DIC_PROP.HANDOVER_STATUS" :key="index" :label="item.label" :value="item.value"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -30,41 +39,55 @@
|
|||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('common.delBtn') }}
|
{{ $t('common.delBtn') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button plain :disabled="multiple" icon="Delete" type="primary" class="ml10"
|
<el-button
|
||||||
v-auth="'order_handovernoderecord_del'" @click="handleDelete(selectObjs)">
|
plain
|
||||||
|
:disabled="multiple"
|
||||||
|
icon="Delete"
|
||||||
|
type="primary"
|
||||||
|
class="ml10"
|
||||||
|
v-auth="'order_handovernoderecord_del'"
|
||||||
|
@click="handleDelete(selectObjs)"
|
||||||
|
>
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
<right-toolbar v-model:showSearch="showSearch" :export="'order_handovernoderecord_export'"
|
<right-toolbar
|
||||||
@exportExcel="exportExcel" class="ml10" style="float: right;margin-right: 20px"
|
v-model:showSearch="showSearch"
|
||||||
@queryTable="getDataList"></right-toolbar>
|
:export="'order_handovernoderecord_export'"
|
||||||
|
@exportExcel="exportExcel"
|
||||||
|
class="ml10"
|
||||||
|
style="float: right; margin-right: 20px"
|
||||||
|
@queryTable="getDataList"
|
||||||
|
></right-toolbar>
|
||||||
</div>
|
</div>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-table :data="state.dataList" v-loading="state.loading" style="width: 100%"
|
<el-table
|
||||||
@selection-change="handleSelectionChange" @sort-change="sortChangeHandle">
|
:data="state.dataList"
|
||||||
|
v-loading="state.loading"
|
||||||
|
style="width: 100%"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
|
@sort-change="sortChangeHandle"
|
||||||
|
>
|
||||||
<el-table-column type="selection" width="40" align="center" />
|
<el-table-column type="selection" width="40" align="center" />
|
||||||
<el-table-column type="index" :label="t('handoverNodeRecord.index')" width="40" />
|
<el-table-column type="index" :label="t('handoverNodeRecord.index')" width="40" />
|
||||||
<el-table-column prop="flowInstId" :label="t('runReject.flowInstId')" show-overflow-tooltip/>
|
<el-table-column prop="flowInstId" :label="t('runReject.flowInstId')" show-overflow-tooltip />
|
||||||
<el-table-column prop="flowKey" :label="t('handoverNodeRecord.flowKey')" show-overflow-tooltip>
|
<el-table-column prop="flowKey" :label="t('handoverNodeRecord.flowKey')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<convert-name :options="state.dicData.flowInstId" :value="scope.row.flowKey"
|
<convert-name :options="state.dicData.flowInstId" :value="scope.row.flowKey" :valueKey="'flowKey'" :showKey="'flowName'"></convert-name>
|
||||||
:valueKey="'flowKey'" :showKey="'flowName'"></convert-name>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="initiatorId" :label="t('handoverNodeRecord.initiatorId')" show-overflow-tooltip>
|
<el-table-column prop="initiatorId" :label="t('handoverNodeRecord.initiatorId')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<convert-name :options="state.dicData.initiatorId" :value="scope.row.initiatorId"
|
<convert-name :options="state.dicData.initiatorId" :value="scope.row.initiatorId" :valueKey="'userId'" :showKey="'name'"></convert-name>
|
||||||
:valueKey="'userId'" :showKey="'name'"></convert-name>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="runJobId" :label="t('handoverNodeRecord.runJobId')" show-overflow-tooltip>
|
<el-table-column prop="runJobId" :label="t('handoverNodeRecord.runJobId')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<convert-name :options="state.dicData.runJobId" :value="scope.row.runJobId"
|
<convert-name :options="state.dicData.runJobId" :value="scope.row.runJobId" :valueKey="'id'" :showKey="'jobName'"></convert-name>
|
||||||
:valueKey="'id'" :showKey="'jobName'"></convert-name>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="startTime" :label="t('handoverNodeRecord.startTime')" show-overflow-tooltip/>
|
<el-table-column prop="startTime" :label="t('handoverNodeRecord.startTime')" show-overflow-tooltip />
|
||||||
<el-table-column prop="todoList" :label="t('handoverNodeRecord.todoList')" show-overflow-tooltip/>
|
<el-table-column prop="todoList" :label="t('handoverNodeRecord.todoList')" show-overflow-tooltip />
|
||||||
<el-table-column prop="status" :label="t('handoverNodeRecord.status')" show-overflow-tooltip>
|
<el-table-column prop="status" :label="t('handoverNodeRecord.status')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :options="DIC_PROP.HANDOVER_STATUS" :value="scope.row.status"></dict-tag>
|
<dict-tag :options="DIC_PROP.HANDOVER_STATUS" :value="scope.row.status"></dict-tag>
|
||||||
@@ -77,33 +100,29 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="createUser" :label="t('handoverNodeRecord.createUser')" show-overflow-tooltip>
|
<el-table-column prop="createUser" :label="t('handoverNodeRecord.createUser')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<convert-name :options="state.dicData.createUser" :value="scope.row.createUser"
|
<convert-name :options="state.dicData.createUser" :value="scope.row.createUser" :valueKey="'userId'" :showKey="'name'"></convert-name>
|
||||||
:valueKey="'userId'" :showKey="'name'"></convert-name>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="createTime" :label="t('handoverNodeRecord.createTime')" show-overflow-tooltip/>
|
<el-table-column prop="createTime" :label="t('handoverNodeRecord.createTime')" show-overflow-tooltip />
|
||||||
<el-table-column :label="$t('common.action')" width="100">
|
<el-table-column :label="$t('common.action')" width="100">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tooltip placement="top">
|
<el-tooltip placement="top">
|
||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('common.viewBtn') }}
|
{{ $t('common.viewBtn') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button text type="primary" icon="view" @click="formDialogRef.openDialog('view', scope.row.id)">
|
<el-button text type="primary" icon="view" @click="formDialogRef.openDialog('view', scope.row.id)"> </el-button>
|
||||||
</el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip placement="top">
|
<el-tooltip placement="top">
|
||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('common.editBtn') }}
|
{{ $t('common.editBtn') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button icon="edit-pen" text type="primary" @click="formDialogRef.openDialog('edit', scope.row.id)">
|
<el-button icon="edit-pen" text type="primary" @click="formDialogRef.openDialog('edit', scope.row.id)"> </el-button>
|
||||||
</el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip placement="top">
|
<el-tooltip placement="top">
|
||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('common.delBtn') }}
|
{{ $t('common.delBtn') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button icon="delete" text type="primary" @click="handleDelete([scope.row.id])">
|
<el-button icon="delete" text type="primary" @click="handleDelete([scope.row.id])"> </el-button>
|
||||||
</el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -117,64 +136,58 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="systemHandoverNodeRecord">
|
<script setup lang="ts" name="systemHandoverNodeRecord">
|
||||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||||
import { fetchList, delObjs } from "/@/api/order/handover-node-record";
|
import { fetchList, delObjs } from '/@/api/order/handover-node-record';
|
||||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
import { useMessage, useMessageBox } from '/@/hooks/message';
|
||||||
|
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from 'vue-i18n';
|
||||||
import {onLoaded} from "/@/flow/components/convert-name/convert";
|
import { onLoaded } from '/@/flow/components/convert-name/convert';
|
||||||
|
|
||||||
// 引入组件
|
// 引入组件
|
||||||
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
|
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
|
||||||
const { t } = useI18n()
|
const { t } = useI18n();
|
||||||
|
|
||||||
// 定义变量内容
|
// 定义变量内容
|
||||||
const formDialogRef = ref()
|
const formDialogRef = ref();
|
||||||
// 搜索变量
|
// 搜索变量
|
||||||
const queryRef = ref()
|
const queryRef = ref();
|
||||||
const showSearch = ref(true)
|
const showSearch = ref(true);
|
||||||
// 多选变量
|
// 多选变量
|
||||||
const selectObjs = ref([]) as any
|
const selectObjs = ref([]) as any;
|
||||||
const multiple = ref(true)
|
const multiple = ref(true);
|
||||||
|
|
||||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||||
queryForm: {},
|
queryForm: {},
|
||||||
pageList: fetchList,
|
pageList: fetchList,
|
||||||
onLoaded: onLoaded({key: "createUser"}, {key: "initiatorId"}, {key: "flowInstId"}, {key: "runJobId"}),
|
onLoaded: onLoaded({ key: 'createUser' }, { key: 'initiatorId' }, { key: 'flowInstId' }, { key: 'runJobId' }),
|
||||||
descs: ["create_time"]
|
descs: ['create_time'],
|
||||||
})
|
});
|
||||||
|
|
||||||
// table hook
|
// table hook
|
||||||
const {
|
const { getDataList, currentChangeHandle, sizeChangeHandle, sortChangeHandle, downBlobFile } = useTable(state);
|
||||||
getDataList,
|
|
||||||
currentChangeHandle,
|
|
||||||
sizeChangeHandle,
|
|
||||||
sortChangeHandle,
|
|
||||||
downBlobFile
|
|
||||||
} = useTable(state)
|
|
||||||
|
|
||||||
|
// 清空搜索条件
|
||||||
|
const resetQuery = () => {
|
||||||
// 清空搜索条件
|
// 清空搜索条件
|
||||||
const resetQuery = () => {
|
queryRef.value?.resetFields();
|
||||||
// 清空搜索条件
|
|
||||||
queryRef.value?.resetFields()
|
|
||||||
// 清空多选
|
// 清空多选
|
||||||
selectObjs.value = []
|
selectObjs.value = [];
|
||||||
getDataList()
|
getDataList();
|
||||||
}
|
};
|
||||||
|
|
||||||
// 导出excel
|
// 导出excel
|
||||||
const exportExcel = () => {
|
const exportExcel = () => {
|
||||||
downBlobFile('/order/handover-node-record/export', state.queryForm, 'handover-node-record.xlsx')
|
downBlobFile('/order/handover-node-record/export', state.queryForm, 'handover-node-record.xlsx');
|
||||||
}
|
};
|
||||||
|
|
||||||
// 多选事件
|
// 多选事件
|
||||||
const handleSelectionChange = (objs: any) => {
|
const handleSelectionChange = (objs: any) => {
|
||||||
selectObjs.value = objs.map(({ id }) => id);
|
selectObjs.value = objs.map(({ id }) => id);
|
||||||
multiple.value = !objs.length;
|
multiple.value = !objs.length;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 删除操作
|
// 删除操作
|
||||||
const handleDelete = async (ids: string[]) => {
|
const handleDelete = async (ids: string[]) => {
|
||||||
try {
|
try {
|
||||||
await useMessageBox().confirm(t('common.delConfirmText'));
|
await useMessageBox().confirm(t('common.delConfirmText'));
|
||||||
} catch {
|
} catch {
|
||||||
@@ -188,5 +201,5 @@
|
|||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
useMessage().error(err.msg);
|
useMessage().error(err.msg);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -3,43 +3,56 @@
|
|||||||
<div class="layout-padding-auto layout-padding-view">
|
<div class="layout-padding-auto layout-padding-view">
|
||||||
<el-row>
|
<el-row>
|
||||||
<div class="mb8" style="width: 100%">
|
<div class="mb8" style="width: 100%">
|
||||||
<el-button icon="Promotion" type="primary" class="ml10" @click="methods.handleInitiate"
|
<el-button
|
||||||
:loading="state.loading" v-if="!validateNull(props.selections)"
|
icon="Promotion"
|
||||||
v-auth="'order_handovernoderecord_add'">
|
type="primary"
|
||||||
|
class="ml10"
|
||||||
|
@click="methods.handleInitiate"
|
||||||
|
:loading="state.loading"
|
||||||
|
v-if="!validateNull(props.selections)"
|
||||||
|
v-auth="'order_handovernoderecord_add'"
|
||||||
|
>
|
||||||
{{ $t('jfI18n.initialBtn') }}
|
{{ $t('jfI18n.initialBtn') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button icon="Check" type="primary" class="ml10" @click="methods.batchSaveOrUpdate"
|
<el-button
|
||||||
:loading="state.loading" v-if="!validateNull(props.selections)"
|
icon="Check"
|
||||||
v-auth="'order_handovernoderecord_add'">
|
type="primary"
|
||||||
|
class="ml10"
|
||||||
|
@click="methods.batchSaveOrUpdate"
|
||||||
|
:loading="state.loading"
|
||||||
|
v-if="!validateNull(props.selections)"
|
||||||
|
v-auth="'order_handovernoderecord_add'"
|
||||||
|
>
|
||||||
{{ $t('jfI18n.batchBtn') }}
|
{{ $t('jfI18n.batchBtn') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-table :data="state.dataList" v-loading="state.loading" style="width: 100%"
|
<el-table :data="state.dataList" v-loading="state.loading" style="width: 100%" @sort-change="sortChangeHandle">
|
||||||
@sort-change="sortChangeHandle">
|
<el-table-column type="index" :label="t('handoverNodeRecord.index')" width="40" />
|
||||||
<el-table-column type="index" :label="t('handoverNodeRecord.index')" width="40"/>
|
|
||||||
<el-table-column prop="flowKey" :label="t('handoverNodeRecord.flowKey')" show-overflow-tooltip>
|
<el-table-column prop="flowKey" :label="t('handoverNodeRecord.flowKey')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<convert-name :options="state.dicData.flowInstId" :value="scope.row.flowKey"
|
<convert-name :options="state.dicData.flowInstId" :value="scope.row.flowKey" :valueKey="'flowKey'" :showKey="'flowName'"></convert-name>
|
||||||
:valueKey="'flowKey'" :showKey="'flowName'"></convert-name>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="initiatorId" :label="t('handoverNodeRecord.initiatorId')" show-overflow-tooltip>
|
<el-table-column prop="initiatorId" :label="t('handoverNodeRecord.initiatorId')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<convert-name :options="state.dicData.initiatorId" :value="scope.row.initiatorId"
|
<convert-name :options="state.dicData.initiatorId" :value="scope.row.initiatorId" :valueKey="'userId'" :showKey="'name'"></convert-name>
|
||||||
:valueKey="'userId'" :showKey="'name'"></convert-name>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="runJobId" :label="t('handoverNodeRecord.runJobId')" show-overflow-tooltip>
|
<el-table-column prop="runJobId" :label="t('handoverNodeRecord.runJobId')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<convert-name :options="state.dicData.runJobId" :value="scope.row.runJobId"
|
<convert-name :options="state.dicData.runJobId" :value="scope.row.runJobId" :valueKey="'id'" :showKey="'jobName'"></convert-name>
|
||||||
:valueKey="'id'" :showKey="'jobName'"></convert-name>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="startTime" :label="t('handoverNodeRecord.startTime')" show-overflow-tooltip/>
|
<el-table-column prop="startTime" :label="t('handoverNodeRecord.startTime')" show-overflow-tooltip />
|
||||||
<el-table-column prop="todoList" :label="t('handoverNodeRecord.todoList')" show-overflow-tooltip>
|
<el-table-column prop="todoList" :label="t('handoverNodeRecord.todoList')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-input :disabled="!scope.row.$cellEdit" v-model="scope.row.todoList" type="textarea" :placeholder="t('handoverNodeRecord.inputTodoListTip')"/>
|
<el-input
|
||||||
|
:disabled="!scope.row.$cellEdit"
|
||||||
|
v-model="scope.row.todoList"
|
||||||
|
type="textarea"
|
||||||
|
:placeholder="t('handoverNodeRecord.inputTodoListTip')"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="status" :label="t('handoverNodeRecord.status')" show-overflow-tooltip>
|
<el-table-column prop="status" :label="t('handoverNodeRecord.status')" show-overflow-tooltip>
|
||||||
@@ -49,57 +62,77 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="createUser" :label="t('handoverNodeRecord.createUser')" show-overflow-tooltip>
|
<el-table-column prop="createUser" :label="t('handoverNodeRecord.createUser')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<convert-name :options="state.dicData.createUser" :value="scope.row.createUser"
|
<convert-name :options="state.dicData.createUser" :value="scope.row.createUser" :valueKey="'userId'" :showKey="'name'"></convert-name>
|
||||||
:valueKey="'userId'" :showKey="'name'"></convert-name>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="createTime" :label="t('handoverNodeRecord.createTime')" show-overflow-tooltip/>
|
<el-table-column prop="createTime" :label="t('handoverNodeRecord.createTime')" show-overflow-tooltip />
|
||||||
<el-table-column :label="$t('common.action')" width="200">
|
<el-table-column :label="$t('common.action')" width="200">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button text type="primary" icon="view" v-if="!scope.row.$cellEdit && scope.row.id"
|
<el-button
|
||||||
@click="formDialogRef.openDialog('view', scope.row.id)" v-auth="'order_handovernoderecord_edit'">
|
text
|
||||||
|
type="primary"
|
||||||
|
icon="view"
|
||||||
|
v-if="!scope.row.$cellEdit && scope.row.id"
|
||||||
|
@click="formDialogRef.openDialog('view', scope.row.id)"
|
||||||
|
v-auth="'order_handovernoderecord_edit'"
|
||||||
|
>
|
||||||
{{ $t('common.viewBtn') }}
|
{{ $t('common.viewBtn') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button icon="edit-pen" text type="primary" v-auth="'order_handovernoderecord_edit'" v-if="!scope.row.$cellEdit"
|
<el-button
|
||||||
@click="methods.handleEdit(scope.row, scope.$index, true)">{{ $t('common.editBtn') }}
|
icon="edit-pen"
|
||||||
|
text
|
||||||
|
type="primary"
|
||||||
|
v-auth="'order_handovernoderecord_edit'"
|
||||||
|
v-if="!scope.row.$cellEdit"
|
||||||
|
@click="methods.handleEdit(scope.row, scope.$index, true)"
|
||||||
|
>{{ $t('common.editBtn') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button icon="Check" text type="primary" v-auth="'order_handovernoderecord_add'" v-if="scope.row.$cellEdit"
|
<el-button
|
||||||
@click="methods.handleUpdate(scope.row, scope.$index)">{{ $t('jfI18n.saveBtn') }}
|
icon="Check"
|
||||||
|
text
|
||||||
|
type="primary"
|
||||||
|
v-auth="'order_handovernoderecord_add'"
|
||||||
|
v-if="scope.row.$cellEdit"
|
||||||
|
@click="methods.handleUpdate(scope.row, scope.$index)"
|
||||||
|
>{{ $t('jfI18n.saveBtn') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button icon="Close" text type="primary" v-auth="'order_handovernoderecord_edit'" v-if="scope.row.$cellEdit && scope.row.id"
|
<el-button
|
||||||
@click="methods.handleEdit(scope.row, scope.$index, false)">{{ $t('jfI18n.cancelBtn') }}
|
icon="Close"
|
||||||
|
text
|
||||||
|
type="primary"
|
||||||
|
v-auth="'order_handovernoderecord_edit'"
|
||||||
|
v-if="scope.row.$cellEdit && scope.row.id"
|
||||||
|
@click="methods.handleEdit(scope.row, scope.$index, false)"
|
||||||
|
>{{ $t('jfI18n.cancelBtn') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button icon="delete" text type="primary" v-auth="'order_handovernoderecord_del'"
|
<el-button icon="delete" text type="primary" v-auth="'order_handovernoderecord_del'" @click="handleDelete(scope.row.id, scope.$index)"
|
||||||
@click="handleDelete(scope.row.id, scope.$index)">{{
|
>{{ $t('common.delBtn') }}
|
||||||
$t('common.delBtn')
|
|
||||||
}}
|
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle"
|
<pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle" v-bind="state.pagination" />
|
||||||
v-bind="state.pagination"/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 编辑、新增 -->
|
<!-- 编辑、新增 -->
|
||||||
<form-dialog ref="formDialogRef" @refresh="getDataList(false)"/>
|
<form-dialog ref="formDialogRef" @refresh="getDataList(false)" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="HandoverNodeRecordInitiate">
|
<script setup lang="ts" name="HandoverNodeRecordInitiate">
|
||||||
import {BasicTableProps, useTable} from "/@/hooks/table";
|
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||||
import * as handoverNodeRecord from '/@/api/order/handover-node-record'
|
import * as handoverNodeRecord from '/@/api/order/handover-node-record';
|
||||||
import {useMessage, useMessageBox} from "/@/hooks/message";
|
import { useMessage, useMessageBox } from '/@/hooks/message';
|
||||||
|
|
||||||
import {useI18n} from "vue-i18n";
|
import { useI18n } from 'vue-i18n';
|
||||||
import {onLoaded} from "/@/flow/components/convert-name/convert";
|
import { onLoaded } from '/@/flow/components/convert-name/convert';
|
||||||
import {validateNull} from "/@/utils/validate";
|
import { validateNull } from '/@/utils/validate';
|
||||||
import * as handoverFlow from '/@/api/order/handover-flow'
|
import * as handoverFlow from '/@/api/order/handover-flow';
|
||||||
import {deepClone} from "/@/utils/other";
|
import { deepClone } from '/@/utils/other';
|
||||||
import {paramsFilter} from "/@/flow";
|
import { paramsFilter } from '/@/flow';
|
||||||
|
|
||||||
const $emit = defineEmits(['onHandoverFlow']);
|
const $emit = defineEmits(['onHandoverFlow']);
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
selections: {
|
selections: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: null,
|
default: null,
|
||||||
@@ -107,34 +140,29 @@
|
|||||||
handoverForm: {
|
handoverForm: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: null,
|
default: null,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// 引入组件
|
// 引入组件
|
||||||
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
|
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
|
||||||
const {t} = useI18n()
|
const { t } = useI18n();
|
||||||
|
|
||||||
// 定义变量内容
|
// 定义变量内容
|
||||||
const formDialogRef = ref()
|
const formDialogRef = ref();
|
||||||
|
|
||||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||||
createdIsNeed: false,
|
createdIsNeed: false,
|
||||||
isPage: false
|
isPage: false,
|
||||||
})
|
});
|
||||||
|
|
||||||
// table hook
|
// table hook
|
||||||
const {
|
const { getDataList, currentChangeHandle, sizeChangeHandle, sortChangeHandle } = useTable(state);
|
||||||
getDataList,
|
|
||||||
currentChangeHandle,
|
|
||||||
sizeChangeHandle,
|
|
||||||
sortChangeHandle,
|
|
||||||
} = useTable(state)
|
|
||||||
|
|
||||||
// 删除操作
|
// 删除操作
|
||||||
const handleDelete = async (id: string, index) => {
|
const handleDelete = async (id: string, index) => {
|
||||||
if (validateNull(id)) {
|
if (validateNull(id)) {
|
||||||
useMessage().info('还未保存')
|
useMessage().info('还未保存');
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await useMessageBox().confirm(t('common.delConfirmText'));
|
await useMessageBox().confirm(t('common.delConfirmText'));
|
||||||
@@ -143,36 +171,36 @@
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await handoverNodeRecord.delObj(id);
|
await handoverNodeRecord.delObj(id);
|
||||||
state.dataList.splice(index, 1)
|
state.dataList.splice(index, 1);
|
||||||
state.pagination!.total = state.dataList.length
|
state.pagination!.total = state.dataList.length;
|
||||||
useMessage().success(t('common.delSuccessText'));
|
useMessage().success(t('common.delSuccessText'));
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
useMessage().error(err.msg);
|
useMessage().error(err.msg);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const initLoaded = onLoaded({key: "flowInstId"}, {key: "runJobId"}, {key: "createUser"}, {key: "initiatorId"})
|
const initLoaded = onLoaded({ key: 'flowInstId' }, { key: 'runJobId' }, { key: 'createUser' }, { key: 'initiatorId' });
|
||||||
|
|
||||||
const methods = {
|
const methods = {
|
||||||
async initSelections() {
|
async initSelections() {
|
||||||
state.loading = true
|
state.loading = true;
|
||||||
// 搜索条件
|
// 搜索条件
|
||||||
state.queryForm = paramsFilter(Object.assign(state.queryForm, props.handoverForm))
|
state.queryForm = paramsFilter(Object.assign(state.queryForm, props.handoverForm));
|
||||||
// 任务交接交接数据一定不能为空
|
// 任务交接交接数据一定不能为空
|
||||||
if (validateNull(props.selections)) {
|
if (validateNull(props.selections)) {
|
||||||
useMessage().info('请选择交接项')
|
useMessage().info('请选择交接项');
|
||||||
state.loading = false
|
state.loading = false;
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
let selections = deepClone(props.selections)
|
let selections = deepClone(props.selections);
|
||||||
for (let i = 0; i < selections.length; i++) {
|
for (let i = 0; i < selections.length; i++) {
|
||||||
selections[i].$cellEdit = true
|
selections[i].$cellEdit = true;
|
||||||
selections[i].id = null// 防止复用
|
selections[i].id = null; // 防止复用
|
||||||
}
|
}
|
||||||
Object.assign(state.dataList, selections)
|
Object.assign(state.dataList, selections);
|
||||||
await initLoaded(state);
|
await initLoaded(state);
|
||||||
state.pagination!.total = state.dataList.length
|
state.pagination!.total = state.dataList.length;
|
||||||
state.loading = false
|
state.loading = false;
|
||||||
},
|
},
|
||||||
async handleUpdate(row, index) {
|
async handleUpdate(row, index) {
|
||||||
try {
|
try {
|
||||||
@@ -180,10 +208,10 @@
|
|||||||
let resp = await handoverNodeRecord.putObj(Object.assign(row, state.queryForm));
|
let resp = await handoverNodeRecord.putObj(Object.assign(row, state.queryForm));
|
||||||
// 延迟赋值
|
// 延迟赋值
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
state.dataList[index].id = resp.data.id
|
state.dataList[index].id = resp.data.id;
|
||||||
state.dataList[index].$cellEdit = false
|
state.dataList[index].$cellEdit = false;
|
||||||
}, 0)
|
}, 0);
|
||||||
useMessage().success('操作成功')
|
useMessage().success('操作成功');
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
useMessage().error(err.msg);
|
useMessage().error(err.msg);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -193,62 +221,66 @@
|
|||||||
handleInitiate() {
|
handleInitiate() {
|
||||||
// 发起
|
// 发起
|
||||||
if (validateNull(state.dataList)) {
|
if (validateNull(state.dataList)) {
|
||||||
useMessage().info('请选择交接项')
|
useMessage().info('请选择交接项');
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
let index = state.dataList.findIndex(f => !f.id) + 1
|
let index = state.dataList.findIndex((f) => !f.id) + 1;
|
||||||
if (index !== 0) {
|
if (index !== 0) {
|
||||||
useMessage().info('第 ' + index + ' 行交接项未保存,请先保存')
|
useMessage().info('第 ' + index + ' 行交接项未保存,请先保存');
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
methods.timeoutLoading()
|
methods.timeoutLoading();
|
||||||
// 防止再次发起复用
|
// 防止再次发起复用
|
||||||
let assign = Object.assign({}, state.queryForm, {id: state.dataList[0].orderId});
|
let assign = Object.assign({}, state.queryForm, { id: state.dataList[0].orderId });
|
||||||
handoverFlow.addObj(assign).then(data => {
|
handoverFlow.addObj(assign).then((data) => {
|
||||||
useMessage().success('发起成功')
|
useMessage().success('发起成功');
|
||||||
$emit('onHandoverFlow', state.queryForm.type)
|
$emit('onHandoverFlow', state.queryForm.type);
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
batchSaveOrUpdate() {
|
batchSaveOrUpdate() {
|
||||||
state.loading = true
|
state.loading = true;
|
||||||
state.dataList[0] = Object.assign({}, state.queryForm, state.dataList[0]);
|
state.dataList[0] = Object.assign({}, state.queryForm, state.dataList[0]);
|
||||||
handoverNodeRecord.batchSaveOrUpdate(state.dataList).then(resp => {
|
handoverNodeRecord
|
||||||
|
.batchSaveOrUpdate(state.dataList)
|
||||||
|
.then((resp) => {
|
||||||
// 延迟赋值
|
// 延迟赋值
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
resp.data.forEach(data => {
|
resp.data.forEach((data) => {
|
||||||
let find = state.dataList.find(f => f.flowInstId === data.flowInstId && f.runJobId === data.runJobId)
|
let find = state.dataList.find((f) => f.flowInstId === data.flowInstId && f.runJobId === data.runJobId);
|
||||||
find.id = data.id
|
find.id = data.id;
|
||||||
find.type = state.queryForm.type
|
find.type = state.queryForm.type;
|
||||||
find.$cellEdit = false
|
find.$cellEdit = false;
|
||||||
})
|
});
|
||||||
useMessage().success('保存成功')
|
useMessage().success('保存成功');
|
||||||
state.loading = false
|
state.loading = false;
|
||||||
}, 0)
|
}, 0);
|
||||||
}).catch((e) => {
|
|
||||||
state.loading= false
|
|
||||||
})
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
state.loading = false;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
timeoutLoading() {
|
timeoutLoading() {
|
||||||
state.loading = true
|
state.loading = true;
|
||||||
setTimeout(() => {// 防重复提交
|
setTimeout(() => {
|
||||||
state.loading = false
|
// 防重复提交
|
||||||
}, 3 * 1000)
|
state.loading = false;
|
||||||
|
}, 3 * 1000);
|
||||||
},
|
},
|
||||||
handleEdit(row, index, bool) {
|
handleEdit(row, index, bool) {
|
||||||
row.$cellEdit = bool
|
row.$cellEdit = bool;
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
// 监听双向绑定
|
// 监听双向绑定
|
||||||
watch(
|
watch(
|
||||||
() => props.selections.length,
|
() => props.selections.length,
|
||||||
() => {
|
() => {
|
||||||
methods.initSelections();
|
methods.initSelections();
|
||||||
},
|
},
|
||||||
{deep: true}
|
{ deep: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
methods.initSelections()
|
methods.initSelections();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,25 +1,25 @@
|
|||||||
import {flowConfig} from "/@/flow/designer/config/flow-config";
|
import { flowConfig } from '/@/flow/designer/config/flow-config';
|
||||||
import {validateNull} from "/@/utils/validate";
|
import { validateNull } from '/@/utils/validate';
|
||||||
import {useMessage} from "/@/hooks/message";
|
import { useMessage } from '/@/hooks/message';
|
||||||
import {DIC_PROP} from "/@/flow/support/dict-prop";
|
import { DIC_PROP } from '/@/flow/support/dict-prop';
|
||||||
import * as runApplication from "/@/api/order/run-application";
|
import * as runApplication from '/@/api/order/run-application';
|
||||||
import {disabledAllFormFields} from "/@/flow/utils/form-perm";
|
import { disabledAllFormFields } from '/@/flow/utils/form-perm';
|
||||||
|
|
||||||
export function validateApp($route) {
|
export function validateApp($route) {
|
||||||
let appdata = flowConfig.mobileConfig.mobilePrefix
|
let appdata = flowConfig.mobileConfig.mobilePrefix;
|
||||||
return !validateNull($route.query[appdata]);
|
return !validateNull($route.query[appdata]);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initJobDataByApp($route, handleGetObj, rowEditInitData) {
|
export function initJobDataByApp($route, handleGetObj, rowEditInitData) {
|
||||||
// 兼容移动端
|
// 兼容移动端
|
||||||
let appdata = flowConfig.mobileConfig.mobilePrefix
|
let appdata = flowConfig.mobileConfig.mobilePrefix;
|
||||||
let app = !validateNull($route.query[appdata]);
|
let app = !validateNull($route.query[appdata]);
|
||||||
if (app) {
|
if (app) {
|
||||||
let split = $route.query[appdata].split('-');
|
let split = $route.query[appdata].split('-');
|
||||||
let query = {id: split[1]}
|
let query = { id: split[1] };
|
||||||
handleGetObj(query.id)
|
handleGetObj(query.id);
|
||||||
} else {
|
} else {
|
||||||
if (rowEditInitData) rowEditInitData()
|
if (rowEditInitData) rowEditInitData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,8 +27,8 @@ export async function doInitData(formCreateRef, saveInitData) {
|
|||||||
let state = await formCreateRef.value.design.fApi.validate();
|
let state = await formCreateRef.value.design.fApi.validate();
|
||||||
let formData = formCreateRef.value.design.formData;
|
let formData = formCreateRef.value.design.formData;
|
||||||
if (!state || validateNull(formData)) {
|
if (!state || validateNull(formData)) {
|
||||||
useMessage().warning("请输入表单信息");
|
useMessage().warning('请输入表单信息');
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
return saveInitData(formData);
|
return saveInitData(formData);
|
||||||
}
|
}
|
||||||
@@ -36,20 +36,20 @@ export async function doInitData(formCreateRef, saveInitData) {
|
|||||||
export async function doInitiateForm(loading, props, data, $route, formCreateRef, $emit, saveInitData, t) {
|
export async function doInitiateForm(loading, props, data, $route, formCreateRef, $emit, saveInitData, t) {
|
||||||
try {
|
try {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
let formJson = await doInitData(formCreateRef, saveInitData)
|
let formJson = await doInitData(formCreateRef, saveInitData);
|
||||||
props.currFlowForm.status !== DIC_PROP.ORDER_STATUS[0].value ? await runApplication.addObj(formJson) : await runApplication.putObj(formJson);
|
props.currFlowForm.status !== DIC_PROP.ORDER_STATUS[0].value ? await runApplication.addObj(formJson) : await runApplication.putObj(formJson);
|
||||||
// 兼容移动端
|
// 兼容移动端
|
||||||
let app = validateApp($route);
|
let app = validateApp($route);
|
||||||
if (app) {
|
if (app) {
|
||||||
useMessage().success("发起成功,请在【我的申请】查看");
|
useMessage().success('发起成功,请在【我的申请】查看');
|
||||||
formCreateRef.value.design.fApi.disabled(true)
|
formCreateRef.value.design.fApi.disabled(true);
|
||||||
data.submitBtn = false
|
data.submitBtn = false;
|
||||||
} else {
|
} else {
|
||||||
useMessage().success(t(formJson.id ? 'common.editSuccessText' : 'common.addSuccessText'));
|
useMessage().success(t(formJson.id ? 'common.editSuccessText' : 'common.addSuccessText'));
|
||||||
$emit('handleInitiateOrder', false)
|
$emit('handleInitiateOrder', false);
|
||||||
}
|
}
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
console.log(err)
|
console.log(err);
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
@@ -60,21 +60,21 @@ export function doTempStore(loading, data, $route, formCreateRef, $emit, saveIni
|
|||||||
loading.value = true;
|
loading.value = true;
|
||||||
let formData = formCreateRef.value.design.formData;
|
let formData = formCreateRef.value.design.formData;
|
||||||
if (validateNull(formData)) {
|
if (validateNull(formData)) {
|
||||||
useMessage().warning("请输入表单信息");
|
useMessage().warning('请输入表单信息');
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
let formJson = saveInitData(formData);
|
let formJson = saveInitData(formData);
|
||||||
runApplication.tempStore(formJson).then(resp => {
|
runApplication.tempStore(formJson).then((resp) => {
|
||||||
useMessage().success("暂存成功,请在【我的申请】查看");
|
useMessage().success('暂存成功,请在【我的申请】查看');
|
||||||
// 兼容移动端
|
// 兼容移动端
|
||||||
let app = validateApp($route);
|
let app = validateApp($route);
|
||||||
if (app) {
|
if (app) {
|
||||||
formCreateRef.value.design.fApi.disabled(true)
|
formCreateRef.value.design.fApi.disabled(true);
|
||||||
data.submitBtn = false
|
data.submitBtn = false;
|
||||||
} else {
|
} else {
|
||||||
$emit('handleInitiateOrder', false)
|
$emit('handleInitiateOrder', false);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
useMessage().error(err);
|
useMessage().error(err);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -82,11 +82,10 @@ export function doTempStore(loading, data, $route, formCreateRef, $emit, saveIni
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function handleDisabledFields(disabledFields, disabled) {
|
function handleDisabledFields(disabledFields, disabled) {
|
||||||
if (disabledFields) {
|
if (disabledFields) {
|
||||||
Object.keys(disabledFields).forEach(key => {
|
Object.keys(disabledFields).forEach((key) => {
|
||||||
disabledFields[key] = disabled
|
disabledFields[key] = disabled;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -95,20 +94,20 @@ export function initCustomFormMethods(data, disabledFields, operType?) {
|
|||||||
return {
|
return {
|
||||||
disableForm(isAll) {
|
disableForm(isAll) {
|
||||||
// 流程中页面,因发起页面可copy
|
// 流程中页面,因发起页面可copy
|
||||||
if (isAll) operType.value = "view"
|
if (isAll) operType.value = 'view';
|
||||||
else handleDisabledFields(disabledFields, true)
|
else handleDisabledFields(disabledFields, true);
|
||||||
},
|
},
|
||||||
enableForm(isAll) {
|
enableForm(isAll) {
|
||||||
if (isAll) operType.value = "flow"
|
if (isAll) operType.value = 'flow';
|
||||||
else handleDisabledFields(disabledFields, false)
|
else handleDisabledFields(disabledFields, false);
|
||||||
},
|
},
|
||||||
disableSubmit() {
|
disableSubmit() {
|
||||||
data.submitBtn = false
|
data.submitBtn = false;
|
||||||
},
|
},
|
||||||
enableSubmit() {
|
enableSubmit() {
|
||||||
data.submitBtn = true
|
data.submitBtn = true;
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initFormMethods(formCreateRef, data) {
|
export function initFormMethods(formCreateRef, data) {
|
||||||
@@ -116,36 +115,36 @@ export function initFormMethods(formCreateRef, data) {
|
|||||||
hiddenForm(isAll, widgetList) {
|
hiddenForm(isAll, widgetList) {
|
||||||
if (isAll) {
|
if (isAll) {
|
||||||
nextTick(async () => {
|
nextTick(async () => {
|
||||||
formCreateRef.value.design.fApi.hidden(true)
|
formCreateRef.value.design.fApi.hidden(true);
|
||||||
})
|
});
|
||||||
} else {
|
} else {
|
||||||
disabledAllFormFields(widgetList, '-1')
|
disabledAllFormFields(widgetList, '-1');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
disableForm(isAll, widgetList) {
|
disableForm(isAll, widgetList) {
|
||||||
if (isAll) {
|
if (isAll) {
|
||||||
// TODO 目前调用会早于规则赋值无效
|
// TODO 目前调用会早于规则赋值无效
|
||||||
nextTick(async () => {
|
nextTick(async () => {
|
||||||
formCreateRef.value.design.fApi.disabled(true)
|
formCreateRef.value.design.fApi.disabled(true);
|
||||||
})
|
});
|
||||||
} else {
|
} else {
|
||||||
disabledAllFormFields(widgetList, '0')
|
disabledAllFormFields(widgetList, '0');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
enableForm(isAll, widgetList) {
|
enableForm(isAll, widgetList) {
|
||||||
if (isAll) {
|
if (isAll) {
|
||||||
nextTick(async () => {
|
nextTick(async () => {
|
||||||
formCreateRef.value.design.fApi.disabled(false)
|
formCreateRef.value.design.fApi.disabled(false);
|
||||||
})
|
});
|
||||||
} else {
|
} else {
|
||||||
disabledAllFormFields(widgetList, '1')
|
disabledAllFormFields(widgetList, '1');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
disableSubmit() {
|
disableSubmit() {
|
||||||
data.submitBtn = false
|
data.submitBtn = false;
|
||||||
},
|
},
|
||||||
enableSubmit() {
|
enableSubmit() {
|
||||||
data.submitBtn = true
|
data.submitBtn = true;
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,62 +1,55 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="layout-padding-auto layout-padding-view">
|
<div class="layout-padding-auto layout-padding-view">
|
||||||
<form-render ref="formCreateRef" :currFlowForm="data.currFlowFormClone" v-if="!validateNull(data.currFlowFormClone)"
|
<form-render
|
||||||
:initFormPermPrint="initFormPermPrint">
|
ref="formCreateRef"
|
||||||
|
:currFlowForm="data.currFlowFormClone"
|
||||||
|
v-if="!validateNull(data.currFlowFormClone)"
|
||||||
|
:initFormPermPrint="initFormPermPrint"
|
||||||
|
>
|
||||||
</form-render>
|
</form-render>
|
||||||
|
|
||||||
<footer class="el-dialog__footer" v-if="data.submitBtn">
|
<footer class="el-dialog__footer" v-if="data.submitBtn">
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button type="primary" @click="printForm" v-if="data.currFlowForm.printInfo">{{
|
<el-button type="primary" @click="printForm" v-if="data.currFlowForm.printInfo">{{ t('jfI18n.print') }} </el-button>
|
||||||
t('jfI18n.print')
|
<el-button type="primary" @click="submitForm" :disabled="loading">{{ t('jfI18n.submit') }} </el-button>
|
||||||
}}
|
|
||||||
</el-button>
|
|
||||||
<el-button type="primary" @click="submitForm" :disabled="loading">{{
|
|
||||||
t('jfI18n.submit')
|
|
||||||
}}
|
|
||||||
</el-button>
|
|
||||||
</span>
|
</span>
|
||||||
</footer>
|
</footer>
|
||||||
<footer class="el-dialog__footer" v-else>
|
<footer class="el-dialog__footer" v-else>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button type="primary" @click="printForm" v-if="data.currFlowForm.printInfo">{{
|
<el-button type="primary" @click="printForm" v-if="data.currFlowForm.printInfo">{{ t('jfI18n.print') }} </el-button>
|
||||||
t('jfI18n.print')
|
|
||||||
}}
|
|
||||||
</el-button>
|
|
||||||
</span>
|
</span>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 打印表单 -->
|
<!-- 打印表单 -->
|
||||||
<el-dialog v-model="data.showTinymceView" top="20px" width="700px"
|
<el-dialog v-model="data.showTinymceView" top="20px" width="700px" :title="data.tinymceTitle" append-to-body @close="closePrint">
|
||||||
:title="data.tinymceTitle" append-to-body
|
|
||||||
@close="closePrint">
|
|
||||||
<tinymce-view v-if="data.showTinymceView" :currFlowForm="data.currFlowForm"></tinymce-view>
|
<tinymce-view v-if="data.showTinymceView" :currFlowForm="data.currFlowForm"></tinymce-view>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="RunApplicationForm">
|
<script setup lang="ts" name="RunApplicationForm">
|
||||||
import * as runApplication from '/@/api/order/run-application'
|
import * as runApplication from '/@/api/order/run-application';
|
||||||
import * as orderVue from "/@/api/order/order-key-vue";
|
import * as orderVue from '/@/api/order/order-key-vue';
|
||||||
import {parseWithFunctions} from "/@/flow";
|
import { parseWithFunctions } from '/@/flow';
|
||||||
import {handleDesignFormPerm, handleFormPrint} from "/@/flow/utils/form-perm";
|
import { handleDesignFormPerm, handleFormPrint } from '/@/flow/utils/form-perm';
|
||||||
import {useI18n} from "vue-i18n";
|
import { useI18n } from 'vue-i18n';
|
||||||
import {useMessage} from "/@/hooks/message";
|
import { useMessage } from '/@/hooks/message';
|
||||||
import {validateNull} from "/@/utils/validate";
|
import { validateNull } from '/@/utils/validate';
|
||||||
import {deepClone} from "/@/utils/other";
|
import { deepClone } from '/@/utils/other';
|
||||||
import {initJobDataByApp} from "/@/flow/support/extend";
|
import { initJobDataByApp } from '/@/flow/support/extend';
|
||||||
import {initFormMethods} from "../index";
|
import { initFormMethods } from '../index';
|
||||||
|
|
||||||
const emits = defineEmits(["handleJob"]);
|
const emits = defineEmits(['handleJob']);
|
||||||
const FormRender = defineAsyncComponent(() => import('/@/flow/components/form-create/render.vue'));
|
const FormRender = defineAsyncComponent(() => import('/@/flow/components/form-create/render.vue'));
|
||||||
const formCreateRef = ref(null)
|
const formCreateRef = ref(null);
|
||||||
// 引入组件
|
// 引入组件
|
||||||
const TinymceView = defineAsyncComponent(() => import('/@/flow/components/tinymce/TinymceView.vue'));
|
const TinymceView = defineAsyncComponent(() => import('/@/flow/components/tinymce/TinymceView.vue'));
|
||||||
|
|
||||||
const {t} = useI18n();
|
const { t } = useI18n();
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
currJob: {
|
currJob: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: {},
|
default: {},
|
||||||
@@ -65,8 +58,8 @@
|
|||||||
type: Object,
|
type: Object,
|
||||||
default: {},
|
default: {},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
// 兼容app端监听printInfo
|
// 兼容app端监听printInfo
|
||||||
currFlowForm: {
|
currFlowForm: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@@ -78,125 +71,126 @@
|
|||||||
initFormData: {},
|
initFormData: {},
|
||||||
showTinymceView: false,
|
showTinymceView: false,
|
||||||
tinymceTitle: null,
|
tinymceTitle: null,
|
||||||
submitBtn: true
|
submitBtn: true,
|
||||||
})
|
});
|
||||||
|
|
||||||
const methods = initFormMethods(formCreateRef, data)
|
const methods = initFormMethods(formCreateRef, data);
|
||||||
|
|
||||||
const $route = useRoute();
|
const $route = useRoute();
|
||||||
async function initJobData() {
|
async function initJobData() {
|
||||||
// 兼容移动端
|
// 兼容移动端
|
||||||
await initJobDataByApp($route, props);
|
await initJobDataByApp($route, props);
|
||||||
// 判断是否存在该表单
|
// 判断是否存在该表单
|
||||||
data.elTab = orderVue.currElTabIsExist(props.currJob, props.currElTab.id);
|
data.elTab = orderVue.currElTabIsExist(props.currJob, props.currElTab.id);
|
||||||
handleGetObj(props.currJob.orderId)
|
handleGetObj(props.currJob.orderId);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleGetObj(id) {
|
function handleGetObj(id) {
|
||||||
runApplication.getObj(id).then(async resp => {
|
runApplication.getObj(id).then(async (resp) => {
|
||||||
let form = resp.data ? resp.data : {}
|
let form = resp.data ? resp.data : {};
|
||||||
data.currFlowForm = form
|
data.currFlowForm = form;
|
||||||
data.currFlowForm.runJobId = props.currJob.id
|
data.currFlowForm.runJobId = props.currJob.id;
|
||||||
rowEditInitData(form)
|
rowEditInitData(form);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function rowEditInitData(form: Object) {
|
function rowEditInitData(form: Object) {
|
||||||
let formInfoStr = form.formInfo
|
let formInfoStr = form.formInfo;
|
||||||
// 判断是否为可选表单
|
// 判断是否为可选表单
|
||||||
if (data.elTab.id !== form.formId) formInfoStr = data.elTab.formInfo
|
if (data.elTab.id !== form.formId) formInfoStr = data.elTab.formInfo;
|
||||||
data.currFlowFormClone = deepClone(form)
|
data.currFlowFormClone = deepClone(form);
|
||||||
data.currFlowFormClone.formInfo = formInfoStr
|
data.currFlowFormClone.formInfo = formInfoStr;
|
||||||
// 记录原始值
|
// 记录原始值
|
||||||
let formData = parseWithFunctions(form.formData)
|
let formData = parseWithFunctions(form.formData);
|
||||||
Object.assign(data.initFormData, formData)
|
Object.assign(data.initFormData, formData);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function initFormPermPrint(cloneFormInfo) {
|
async function initFormPermPrint(cloneFormInfo) {
|
||||||
let form = data.currFlowForm
|
let form = data.currFlowForm;
|
||||||
// 判断是否为可选表单
|
// 判断是否为可选表单
|
||||||
let formType = form.type, formId = form.formId
|
let formType = form.type,
|
||||||
|
formId = form.formId;
|
||||||
if (data.elTab.id !== form.formId) {
|
if (data.elTab.id !== form.formId) {
|
||||||
formType = data.elTab.type
|
formType = data.elTab.type;
|
||||||
formId = data.elTab.id
|
formId = data.elTab.id;
|
||||||
}
|
}
|
||||||
let res = await handleDesignFormPerm(props, cloneFormInfo, data.elTab, formType, formId);
|
let res = await handleDesignFormPerm(props, cloneFormInfo, data.elTab, formType, formId);
|
||||||
// 判断是否仅查看
|
// 判断是否仅查看
|
||||||
await orderVue.currElTabIsView(methods, props.currJob, props.currElTab.id, submitForm, res.callback, res.widgetList)
|
await orderVue.currElTabIsView(methods, props.currJob, props.currElTab.id, submitForm, res.callback, res.widgetList);
|
||||||
await handleFormPrint(form, formType, formId, '1')
|
await handleFormPrint(form, formType, formId, '1');
|
||||||
return data.elTab;
|
return data.elTab;
|
||||||
}
|
}
|
||||||
|
|
||||||
function printForm() {
|
function printForm() {
|
||||||
data.currFlowForm.formData = formCreateRef.value.design.formData
|
data.currFlowForm.formData = formCreateRef.value.design.formData;
|
||||||
data.currFlowForm.modelRefList = []
|
data.currFlowForm.modelRefList = [];
|
||||||
let children = formCreateRef.value.design.fApi.children;
|
let children = formCreateRef.value.design.fApi.children;
|
||||||
if (children && children.length > 0) {
|
if (children && children.length > 0) {
|
||||||
children.forEach(each => data.currFlowForm.modelRefList.push({model: each.model}))
|
children.forEach((each) => data.currFlowForm.modelRefList.push({ model: each.model }));
|
||||||
}
|
|
||||||
data.currFlowForm.rule = formCreateRef.value.design.rule
|
|
||||||
data.tinymceTitle = data.currFlowForm.formName
|
|
||||||
data.showTinymceView = true
|
|
||||||
}
|
}
|
||||||
|
data.currFlowForm.rule = formCreateRef.value.design.rule;
|
||||||
|
data.tinymceTitle = data.currFlowForm.formName;
|
||||||
|
data.showTinymceView = true;
|
||||||
|
}
|
||||||
|
|
||||||
function closePrint(isSave){
|
function closePrint(isSave) {
|
||||||
delete data.currFlowForm.modelRefList
|
delete data.currFlowForm.modelRefList;
|
||||||
delete data.currFlowForm.rule
|
delete data.currFlowForm.rule;
|
||||||
if (isSave) delete data.currFlowForm.printInfo
|
if (isSave) delete data.currFlowForm.printInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function submitForm() {
|
async function submitForm() {
|
||||||
try {
|
try {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
let state = await formCreateRef.value.design.fApi.validate();
|
let state = await formCreateRef.value.design.fApi.validate();
|
||||||
let formData = formCreateRef.value.design.formData
|
let formData = formCreateRef.value.design.formData;
|
||||||
if (!state || validateNull(formData)) {
|
if (!state || validateNull(formData)) {
|
||||||
useMessage().warning("请输入表单信息");
|
useMessage().warning('请输入表单信息');
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
let formJson = saveInitData(formData);
|
let formJson = saveInitData(formData);
|
||||||
await runApplication.putObj(formJson)
|
await runApplication.putObj(formJson);
|
||||||
orderVue.currElTabIsSave(props.currJob, props.currElTab.id, true, emits)
|
orderVue.currElTabIsSave(props.currJob, props.currElTab.id, true, emits);
|
||||||
useMessage().success(t(formJson.id ? 'common.editSuccessText' : 'common.addSuccessText'));
|
useMessage().success(t(formJson.id ? 'common.editSuccessText' : 'common.addSuccessText'));
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
useMessage().warning("请输入表单信息");
|
useMessage().warning('请输入表单信息');
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveInitData(form) {
|
function saveInitData(form) {
|
||||||
closePrint(true)
|
closePrint(true);
|
||||||
data.currFlowForm.formData = validateNull(form) ? null : form
|
data.currFlowForm.formData = validateNull(form) ? null : form;
|
||||||
let formJson = deepClone(data.currFlowForm)
|
let formJson = deepClone(data.currFlowForm);
|
||||||
if (!validateNull(form)) {
|
if (!validateNull(form)) {
|
||||||
// 合并不同页面不同字段
|
// 合并不同页面不同字段
|
||||||
formJson.formData = Object.assign({}, data.initFormData, formJson.formData);
|
formJson.formData = Object.assign({}, data.initFormData, formJson.formData);
|
||||||
}
|
}
|
||||||
formJson.formData = JSON.stringify(formJson.formData)
|
formJson.formData = JSON.stringify(formJson.formData);
|
||||||
return formJson;
|
return formJson;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 监听双向绑定
|
// 监听双向绑定
|
||||||
watch(
|
watch(
|
||||||
() => props.currJob.id,
|
() => props.currJob.id,
|
||||||
async () => {
|
async () => {
|
||||||
await initJobData();
|
await initJobData();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await initJobData()
|
await initJobData();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.el-dialog__footer {
|
.el-dialog__footer {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
|
||||||
.dialog-footer {
|
.dialog-footer {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -47,6 +47,5 @@ export default {
|
|||||||
inputUpdateUserTip: 'input updateUser',
|
inputUpdateUserTip: 'input updateUser',
|
||||||
inputUpdateTimeTip: 'input updateTime',
|
inputUpdateTimeTip: 'input updateTime',
|
||||||
inputDelFlagTip: 'input delFlag',
|
inputDelFlagTip: 'input delFlag',
|
||||||
|
},
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
|||||||
@@ -47,6 +47,5 @@ export default {
|
|||||||
inputUpdateUserTip: '请输入修改人',
|
inputUpdateUserTip: '请输入修改人',
|
||||||
inputUpdateTimeTip: '请输入修改时间',
|
inputUpdateTimeTip: '请输入修改时间',
|
||||||
inputDelFlagTip: '请输入删除标',
|
inputDelFlagTip: '请输入删除标',
|
||||||
|
},
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
|||||||
@@ -3,19 +3,16 @@
|
|||||||
<div class="layout-padding-auto layout-padding-view">
|
<div class="layout-padding-auto layout-padding-view">
|
||||||
<el-row v-show="showSearch">
|
<el-row v-show="showSearch">
|
||||||
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
|
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
|
||||||
<el-form-item :label="$t('runApplication.code')" prop="code" >
|
<el-form-item :label="$t('runApplication.code')" prop="code">
|
||||||
<el-input :placeholder="t('runApplication.inputCodeTip')" v-model="state.queryForm.code" clearable
|
<el-input :placeholder="t('runApplication.inputCodeTip')" v-model="state.queryForm.code" clearable style="max-width: 180px" />
|
||||||
style="max-width: 180px" />
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('runApplication.flowKey')" prop="flowKey" >
|
<el-form-item :label="$t('runApplication.flowKey')" prop="flowKey">
|
||||||
<el-input :placeholder="t('runApplication.inputFlowKeyTip')" v-model="state.queryForm.flowKey" clearable
|
<el-input :placeholder="t('runApplication.inputFlowKeyTip')" v-model="state.queryForm.flowKey" clearable style="max-width: 180px" />
|
||||||
style="max-width: 180px" />
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('runApplication.formName')" prop="formName" >
|
<el-form-item :label="$t('runApplication.formName')" prop="formName">
|
||||||
<el-input :placeholder="t('runApplication.inputFormNameTip')" v-model="state.queryForm.formName" clearable
|
<el-input :placeholder="t('runApplication.inputFormNameTip')" v-model="state.queryForm.formName" clearable style="max-width: 180px" />
|
||||||
style="max-width: 180px" />
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('runApplication.status')" prop="status" >
|
<el-form-item :label="$t('runApplication.status')" prop="status">
|
||||||
<el-select v-model="state.queryForm.status" :placeholder="t('runApplication.inputStatusTip')" clearable style="max-width: 180px">
|
<el-select v-model="state.queryForm.status" :placeholder="t('runApplication.inputStatusTip')" clearable style="max-width: 180px">
|
||||||
<el-option v-for="(item, index) in DIC_PROP.ORDER_STATUS" :key="index" :label="item.label" :value="item.value"></el-option>
|
<el-option v-for="(item, index) in DIC_PROP.ORDER_STATUS" :key="index" :label="item.label" :value="item.value"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
@@ -34,43 +31,59 @@
|
|||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('common.delBtn') }}
|
{{ $t('common.delBtn') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button plain :disabled="multiple" icon="Delete" type="primary" class="ml10"
|
<el-button
|
||||||
v-auth="'order_runapplication_del'" @click="handleDelete(selectObjs)">
|
plain
|
||||||
|
:disabled="multiple"
|
||||||
|
icon="Delete"
|
||||||
|
type="primary"
|
||||||
|
class="ml10"
|
||||||
|
v-auth="'order_runapplication_del'"
|
||||||
|
@click="handleDelete(selectObjs)"
|
||||||
|
>
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
<right-toolbar v-model:showSearch="showSearch" :export="'order_runapplication_export'"
|
<right-toolbar
|
||||||
@exportExcel="exportExcel" class="ml10" style="float: right;margin-right: 20px"
|
v-model:showSearch="showSearch"
|
||||||
@queryTable="getDataList"></right-toolbar>
|
:export="'order_runapplication_export'"
|
||||||
|
@exportExcel="exportExcel"
|
||||||
|
class="ml10"
|
||||||
|
style="float: right; margin-right: 20px"
|
||||||
|
@queryTable="getDataList"
|
||||||
|
></right-toolbar>
|
||||||
</div>
|
</div>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-table :data="state.dataList" v-loading="state.loading" style="width: 100%"
|
<el-table
|
||||||
@selection-change="handleSelectionChange" @sort-change="sortChangeHandle">
|
:data="state.dataList"
|
||||||
<el-table-column type="selection" width="40" align="center"/>
|
v-loading="state.loading"
|
||||||
<el-table-column type="index" :label="t('runApplication.index')" width="40"/>
|
style="width: 100%"
|
||||||
<el-table-column prop="code" :label="t('runApplication.code')" show-overflow-tooltip/>
|
@selection-change="handleSelectionChange"
|
||||||
|
@sort-change="sortChangeHandle"
|
||||||
|
>
|
||||||
|
<el-table-column type="selection" width="40" align="center" />
|
||||||
|
<el-table-column type="index" :label="t('runApplication.index')" width="40" />
|
||||||
|
<el-table-column prop="code" :label="t('runApplication.code')" show-overflow-tooltip />
|
||||||
<el-table-column prop="flowKey" :label="t('runApplication.flowKey')" show-overflow-tooltip>
|
<el-table-column prop="flowKey" :label="t('runApplication.flowKey')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<convert-name :options="dicData.flowKey" :value="scope.row.flowKey"
|
<convert-name :options="dicData.flowKey" :value="scope.row.flowKey" :valueKey="'flowKey'" :showKey="'flowName'"></convert-name>
|
||||||
:valueKey="'flowKey'" :showKey="'flowName'"></convert-name>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="icon" :label="t('runApplication.icon')" show-overflow-tooltip>
|
<el-table-column prop="icon" :label="t('runApplication.icon')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<SvgIcon :name="scope.row.icon" :size="20" color="#409EFF"/>
|
<SvgIcon :name="scope.row.icon" :size="20" color="#409EFF" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="formName" :label="t('runApplication.formName')" show-overflow-tooltip/>
|
<el-table-column prop="formName" :label="t('runApplication.formName')" show-overflow-tooltip />
|
||||||
<el-table-column prop="groupName" :label="t('runApplication.groupName')" show-overflow-tooltip/>
|
<el-table-column prop="groupName" :label="t('runApplication.groupName')" show-overflow-tooltip />
|
||||||
<el-table-column prop="finishTime" :label="t('runApplication.finishTime')" show-overflow-tooltip/>
|
<el-table-column prop="finishTime" :label="t('runApplication.finishTime')" show-overflow-tooltip />
|
||||||
<el-table-column prop="status" :label="t('runApplication.status')" show-overflow-tooltip>
|
<el-table-column prop="status" :label="t('runApplication.status')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :options="DIC_PROP.ORDER_STATUS" :value="scope.row.status"></dict-tag>
|
<dict-tag :options="DIC_PROP.ORDER_STATUS" :value="scope.row.status"></dict-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="remark" :label="t('runApplication.remark')" width="200" show-overflow-tooltip/>
|
<el-table-column prop="remark" :label="t('runApplication.remark')" width="200" show-overflow-tooltip />
|
||||||
<el-table-column prop="version" :label="t('runApplication.version')" show-overflow-tooltip/>
|
<el-table-column prop="version" :label="t('runApplication.version')" show-overflow-tooltip />
|
||||||
<!-- <el-table-column prop="createUser" :label="t('runApplication.createUser')" show-overflow-tooltip>
|
<!-- <el-table-column prop="createUser" :label="t('runApplication.createUser')" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<convert-name :options="state.dicData.createUser" :value="scope.row.createUser"
|
<convert-name :options="state.dicData.createUser" :value="scope.row.createUser"
|
||||||
:valueKey="'userId'" :showKey="'name'"></convert-name>
|
:valueKey="'userId'" :showKey="'name'"></convert-name>
|
||||||
@@ -79,67 +92,59 @@
|
|||||||
<el-table-column prop="createTime" :label="t('runApplication.createTime')" show-overflow-tooltip/>-->
|
<el-table-column prop="createTime" :label="t('runApplication.createTime')" show-overflow-tooltip/>-->
|
||||||
<el-table-column :label="$t('common.action')" width="170">
|
<el-table-column :label="$t('common.action')" width="170">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
|
|
||||||
<el-tooltip placement="top">
|
<el-tooltip placement="top">
|
||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('common.viewBtn') }}
|
{{ $t('common.viewBtn') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button text type="primary" icon="view" @click="handleViewOrder(scope.row)">
|
<el-button text type="primary" icon="view" @click="handleViewOrder(scope.row)"> </el-button>
|
||||||
</el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
<el-tooltip placement="top">
|
<el-tooltip placement="top">
|
||||||
<template #content>
|
<template #content> 打印表单 </template>
|
||||||
打印表单
|
<el-button icon="Document" text type="primary" @click="handleViewOrder(scope.row)"> </el-button>
|
||||||
</template>
|
|
||||||
<el-button icon="Document" text type="primary" @click="handleViewOrder(scope.row)">
|
|
||||||
</el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
<el-tooltip placement="top">
|
<el-tooltip placement="top">
|
||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('common.copyBtn') }}
|
{{ $t('common.copyBtn') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button icon="DocumentCopy" text type="primary" @click="handleInitiateOrder(scope.row,'copy')">
|
<el-button icon="DocumentCopy" text type="primary" @click="handleInitiateOrder(scope.row, 'copy')"> </el-button>
|
||||||
</el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
<el-tooltip placement="top" v-if="scope.row.status===DIC_PROP.ORDER_STATUS[2].value">
|
<el-tooltip placement="top" v-if="scope.row.status === DIC_PROP.ORDER_STATUS[2].value">
|
||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('jfI18n.recallBtn') }}
|
{{ $t('jfI18n.recallBtn') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button icon="RefreshLeft" text type="primary" @click="handleRecallReset(scope.row)">
|
<el-button icon="RefreshLeft" text type="primary" @click="handleRecallReset(scope.row)"> </el-button>
|
||||||
</el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip placement="top" v-if="scope.row.status===DIC_PROP.ORDER_STATUS[0].value">
|
<el-tooltip placement="top" v-if="scope.row.status === DIC_PROP.ORDER_STATUS[0].value">
|
||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('jfI18n.resetBtn') }}
|
{{ $t('jfI18n.resetBtn') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button icon="RefreshRight" text type="primary" @click="handleRecallReset(scope.row)">
|
<el-button icon="RefreshRight" text type="primary" @click="handleRecallReset(scope.row)"> </el-button>
|
||||||
</el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
<el-tooltip placement="top">
|
<el-tooltip placement="top">
|
||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('jfI18n.viewFlow') }}
|
{{ $t('jfI18n.viewFlow') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button icon="Share" text type="primary" @click="openPreview(scope.row)">
|
<el-button icon="Share" text type="primary" @click="openPreview(scope.row)"> </el-button>
|
||||||
</el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
<el-tooltip placement="top" v-if="scope.row.status===DIC_PROP.ORDER_STATUS[1].value || scope.row.status===DIC_PROP.ORDER_STATUS[0].value">
|
<el-tooltip
|
||||||
|
placement="top"
|
||||||
|
v-if="scope.row.status === DIC_PROP.ORDER_STATUS[1].value || scope.row.status === DIC_PROP.ORDER_STATUS[0].value"
|
||||||
|
>
|
||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('common.editBtn') }}
|
{{ $t('common.editBtn') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button icon="edit-pen" text type="primary" @click="handleInitiateOrder(scope.row,'edit')">
|
<el-button icon="edit-pen" text type="primary" @click="handleInitiateOrder(scope.row, 'edit')"> </el-button>
|
||||||
</el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-tooltip placement="top" v-if="scope.row.status===DIC_PROP.ORDER_STATUS[1].value">
|
<el-tooltip placement="top" v-if="scope.row.status === DIC_PROP.ORDER_STATUS[1].value">
|
||||||
<template #content>
|
<template #content>
|
||||||
{{ $t('common.delBtn') }}
|
{{ $t('common.delBtn') }}
|
||||||
</template>
|
</template>
|
||||||
<el-button icon="delete" text type="primary" @click="handleDelete([scope.row.id])">
|
<el-button icon="delete" text type="primary" @click="handleDelete([scope.row.id])"> </el-button>
|
||||||
</el-button>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -149,122 +154,110 @@
|
|||||||
|
|
||||||
<json-flow-predict ref="predict" :proxy="proxy" @handleInitiateOrder="handleInitiateOrder">
|
<json-flow-predict ref="predict" :proxy="proxy" @handleInitiateOrder="handleInitiateOrder">
|
||||||
<template v-slot="slotProps" v-if="data.showInitiateOrder">
|
<template v-slot="slotProps" v-if="data.showInitiateOrder">
|
||||||
<run-initiate ref="form" v-show="slotProps.currActive === 'form'" :curr-flow-form="data.currFlowForm"
|
<run-initiate
|
||||||
@handleInitiateOrder="handleInitiateOrder"></run-initiate>
|
ref="form"
|
||||||
|
v-show="slotProps.currActive === 'form'"
|
||||||
|
:curr-flow-form="data.currFlowForm"
|
||||||
|
@handleInitiateOrder="handleInitiateOrder"
|
||||||
|
></run-initiate>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot="slotProps" v-if="data.showHandleForm">
|
<template v-slot="slotProps" v-if="data.showHandleForm">
|
||||||
<custom-form ref="form" v-show="slotProps.currActive === 'form'" :curr-job="data.currFlowForm"
|
<custom-form
|
||||||
@onHandleForm="handleInitiateOrder"></custom-form>
|
ref="form"
|
||||||
|
v-show="slotProps.currActive === 'form'"
|
||||||
|
:curr-job="data.currFlowForm"
|
||||||
|
@onHandleForm="handleInitiateOrder"
|
||||||
|
></custom-form>
|
||||||
</template>
|
</template>
|
||||||
</json-flow-predict>
|
</json-flow-predict>
|
||||||
|
|
||||||
<!-- 查看工单 -->
|
<!-- 查看工单 -->
|
||||||
<el-dialog
|
<el-dialog v-model="data.showHandleFormView" top="20px" width="90%" title="查看工单" append-to-body>
|
||||||
v-model="data.showHandleFormView"
|
|
||||||
top="20px"
|
|
||||||
width="90%"
|
|
||||||
title="查看工单"
|
|
||||||
append-to-body>
|
|
||||||
<custom-form v-if="data.showHandleFormView" :curr-job="data.currFlowForm"></custom-form>
|
<custom-form v-if="data.showHandleFormView" :curr-job="data.currFlowForm"></custom-form>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<!-- 查看工单 -->
|
<!-- 查看工单 -->
|
||||||
<el-dialog
|
<el-dialog v-model="data.showViewOrder" top="20px" width="90%" title="查看工单" append-to-body>
|
||||||
v-model="data.showViewOrder"
|
|
||||||
top="20px"
|
|
||||||
width="90%"
|
|
||||||
title="查看工单"
|
|
||||||
append-to-body>
|
|
||||||
<run-view v-if="data.showViewOrder" :curr-flow-form="data.currFlowForm"></run-view>
|
<run-view v-if="data.showViewOrder" :curr-flow-form="data.currFlowForm"></run-view>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<!-- 查看流程图 -->
|
<!-- 查看流程图 -->
|
||||||
<el-drawer
|
<el-drawer class="flow-overflow-drawer" direction="rtl" append-to-body size="90%" v-model="data.showFlowPic">
|
||||||
class="flow-overflow-drawer" direction="rtl"
|
|
||||||
append-to-body size="90%"
|
|
||||||
v-model="data.showFlowPic"
|
|
||||||
>
|
|
||||||
<flow-photo v-if="data.showFlowPic" :curr-job="data.currFlowForm"></flow-photo>
|
<flow-photo v-if="data.showFlowPic" :curr-job="data.currFlowForm"></flow-photo>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="systemRunApplication">
|
<script setup lang="ts" name="systemRunApplication">
|
||||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||||
import * as runApplication from '/@/api/order/run-application'
|
import * as runApplication from '/@/api/order/run-application';
|
||||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
import { useMessage, useMessageBox } from '/@/hooks/message';
|
||||||
|
|
||||||
import {useI18n} from "vue-i18n";
|
import { useI18n } from 'vue-i18n';
|
||||||
import {onLoadDicUrl, onLoaded} from "/@/flow/components/convert-name/convert";
|
import { onLoadDicUrl, onLoaded } from '/@/flow/components/convert-name/convert';
|
||||||
import * as common from '/@/flow/support/common'
|
import * as common from '/@/flow/support/common';
|
||||||
import other, {deepClone} from "/@/utils/other";
|
import other, { deepClone } from '/@/utils/other';
|
||||||
import {recallReset} from "/@/api/jsonflow/run-flow";
|
import { recallReset } from '/@/api/jsonflow/run-flow';
|
||||||
import {DIC_PROP} from "/@/flow/support/dict-prop";
|
import { DIC_PROP } from '/@/flow/support/dict-prop';
|
||||||
import {openFlowPreview} from "/@/flow/support/extend";
|
import { openFlowPreview } from '/@/flow/support/extend';
|
||||||
import {handleCustomForm, vueKey} from "/@/api/order/order-key-vue";
|
import { handleCustomForm, vueKey } from '/@/api/order/order-key-vue';
|
||||||
|
|
||||||
// 引入组件
|
// 引入组件
|
||||||
const FlowPhoto = defineAsyncComponent(() => import('/@/views/jsonflow/flow-design/view.vue'));
|
const FlowPhoto = defineAsyncComponent(() => import('/@/views/jsonflow/flow-design/view.vue'));
|
||||||
const RunInitiate = defineAsyncComponent(() => import('./initiate.vue'));
|
const RunInitiate = defineAsyncComponent(() => import('./initiate.vue'));
|
||||||
const RunView = defineAsyncComponent(() => import('./view.vue'));
|
const RunView = defineAsyncComponent(() => import('./view.vue'));
|
||||||
const CustomForm = defineAsyncComponent(() => import('/@/flow/components/custom-form/handle.vue'));
|
const CustomForm = defineAsyncComponent(() => import('/@/flow/components/custom-form/handle.vue'));
|
||||||
const JsonFlowPredict = defineAsyncComponent(() => import('/@/views/jsonflow/flow-design/predict.vue'));
|
const JsonFlowPredict = defineAsyncComponent(() => import('/@/views/jsonflow/flow-design/predict.vue'));
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n();
|
||||||
const {proxy} = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
// 搜索变量
|
// 搜索变量
|
||||||
const queryRef = ref()
|
const queryRef = ref();
|
||||||
const showSearch = ref(true)
|
const showSearch = ref(true);
|
||||||
// 多选变量
|
// 多选变量
|
||||||
const selectObjs = ref([]) as any
|
const selectObjs = ref([]) as any;
|
||||||
const multiple = ref(true)
|
const multiple = ref(true);
|
||||||
|
|
||||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||||
queryForm: {},
|
queryForm: {},
|
||||||
pageList: runApplication.fetchList,
|
pageList: runApplication.fetchList,
|
||||||
onLoaded: onLoaded({key: "createUser"}),
|
onLoaded: onLoaded({ key: 'createUser' }),
|
||||||
descs: ["create_time"]
|
descs: ['create_time'],
|
||||||
})
|
});
|
||||||
|
|
||||||
// 定义字典
|
// 定义字典
|
||||||
const dicData = reactive({});
|
const dicData = reactive({});
|
||||||
const onLoad = onLoadDicUrl({key: "flowKey"});
|
const onLoad = onLoadDicUrl({ key: 'flowKey' });
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
onLoad(dicData);
|
onLoad(dicData);
|
||||||
});
|
});
|
||||||
|
|
||||||
// table hook
|
// table hook
|
||||||
const {
|
const { getDataList, currentChangeHandle, sizeChangeHandle, sortChangeHandle, downBlobFile } = useTable(state);
|
||||||
getDataList,
|
|
||||||
currentChangeHandle,
|
|
||||||
sizeChangeHandle,
|
|
||||||
sortChangeHandle,
|
|
||||||
downBlobFile
|
|
||||||
} = useTable(state)
|
|
||||||
|
|
||||||
|
// 清空搜索条件
|
||||||
|
const resetQuery = () => {
|
||||||
// 清空搜索条件
|
// 清空搜索条件
|
||||||
const resetQuery = () => {
|
queryRef.value?.resetFields();
|
||||||
// 清空搜索条件
|
|
||||||
queryRef.value?.resetFields()
|
|
||||||
// 清空多选
|
// 清空多选
|
||||||
selectObjs.value = []
|
selectObjs.value = [];
|
||||||
getDataList()
|
getDataList();
|
||||||
}
|
};
|
||||||
|
|
||||||
// 导出excel
|
// 导出excel
|
||||||
const exportExcel = () => {
|
const exportExcel = () => {
|
||||||
downBlobFile('/order/run-application/export', state.queryForm, 'run-application.xlsx')
|
downBlobFile('/order/run-application/export', state.queryForm, 'run-application.xlsx');
|
||||||
}
|
};
|
||||||
|
|
||||||
// 多选事件
|
// 多选事件
|
||||||
const handleSelectionChange = (objs: any) => {
|
const handleSelectionChange = (objs: any) => {
|
||||||
selectObjs.value = objs.map(({ id }) => id);
|
selectObjs.value = objs.map(({ id }) => id);
|
||||||
multiple.value = !objs.length;
|
multiple.value = !objs.length;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 删除操作
|
// 删除操作
|
||||||
const handleDelete = async (ids: string[]) => {
|
const handleDelete = async (ids: string[]) => {
|
||||||
try {
|
try {
|
||||||
await useMessageBox().confirm(t('common.delConfirmText'));
|
await useMessageBox().confirm(t('common.delConfirmText'));
|
||||||
} catch {
|
} catch {
|
||||||
@@ -278,85 +271,86 @@
|
|||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
useMessage().error(err.msg);
|
useMessage().error(err.msg);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
showViewOrder: false,
|
showViewOrder: false,
|
||||||
showInitiateOrder: false,
|
showInitiateOrder: false,
|
||||||
showFlowPic: false,
|
showFlowPic: false,
|
||||||
currFlowForm: {},
|
currFlowForm: {},
|
||||||
showHandleFormView: false,
|
showHandleFormView: false,
|
||||||
showHandleForm: false,
|
showHandleForm: false,
|
||||||
})
|
});
|
||||||
|
|
||||||
function handleViewOrder(row) {
|
function handleViewOrder(row) {
|
||||||
data.currFlowForm = row
|
data.currFlowForm = row;
|
||||||
// 判断是否自定义首页
|
// 判断是否自定义首页
|
||||||
if (row.path !== vueKey.RunApplicationForm) {
|
if (row.path !== vueKey.RunApplicationForm) {
|
||||||
handleCustomForm(data, row)
|
handleCustomForm(data, row);
|
||||||
data.currFlowForm.operType = 'view'
|
data.currFlowForm.operType = 'view';
|
||||||
data.showHandleFormView = true
|
data.showHandleFormView = true;
|
||||||
} else {
|
} else {
|
||||||
data.showViewOrder = true
|
data.showViewOrder = true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function handleInitiateOrder(row, operType) {
|
function handleInitiateOrder(row, operType) {
|
||||||
if (row === false) {
|
if (row === false) {
|
||||||
getDataList();
|
getDataList();
|
||||||
openPredict({}, false)
|
openPredict({}, false);
|
||||||
data.showInitiateOrder = false
|
data.showInitiateOrder = false;
|
||||||
data.showHandleForm = false
|
data.showHandleForm = false;
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
data.currFlowForm = deepClone(row)
|
data.currFlowForm = deepClone(row);
|
||||||
data.currFlowForm.operType = operType
|
data.currFlowForm.operType = operType;
|
||||||
let clone = {operType: data.currFlowForm.operType};
|
let clone = { operType: data.currFlowForm.operType };
|
||||||
common.handleClone(clone, data.currFlowForm)
|
common.handleClone(clone, data.currFlowForm);
|
||||||
// 判断是否自定义首页
|
// 判断是否自定义首页
|
||||||
if (row.path !== vueKey.RunApplicationForm) {
|
if (row.path !== vueKey.RunApplicationForm) {
|
||||||
handleCustomForm(data, row)
|
handleCustomForm(data, row);
|
||||||
data.showHandleForm = true
|
data.showHandleForm = true;
|
||||||
} else {
|
} else {
|
||||||
data.showInitiateOrder = true
|
data.showInitiateOrder = true;
|
||||||
}
|
|
||||||
openPredict(row, true)
|
|
||||||
}
|
}
|
||||||
|
openPredict(row, true);
|
||||||
|
}
|
||||||
|
|
||||||
function openPredict(row, bool) {
|
function openPredict(row, bool) {
|
||||||
proxy.$refs.predict.open(row, bool)
|
proxy.$refs.predict.open(row, bool);
|
||||||
}
|
}
|
||||||
|
|
||||||
const $router = useRouter();
|
const $router = useRouter();
|
||||||
function openPreview(row) {
|
function openPreview(row) {
|
||||||
if (row.status === DIC_PROP.ORDER_STATUS[1].value) {
|
if (row.status === DIC_PROP.ORDER_STATUS[1].value) {
|
||||||
data.currFlowForm = {defFlowId: row.defFlowId}
|
data.currFlowForm = { defFlowId: row.defFlowId };
|
||||||
data.showFlowPic = true
|
data.showFlowPic = true;
|
||||||
} else {
|
} else {
|
||||||
openFlowPreview($router, {flowInstId: row.flowInstId}, '1')
|
openFlowPreview($router, { flowInstId: row.flowInstId }, '1');
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function handleRecallReset(row) {
|
function handleRecallReset(row) {
|
||||||
let params = {id: row.flowInstId, flowKey: row.flowKey, status: row.status}
|
let params = { id: row.flowInstId, flowKey: row.flowKey, status: row.status };
|
||||||
if (row.status === DIC_PROP.ORDER_STATUS[0].value) {
|
if (row.status === DIC_PROP.ORDER_STATUS[0].value) {
|
||||||
recallReset(params).then(() => {
|
recallReset(params).then(() => {
|
||||||
useMessage().success('重发成功');
|
useMessage().success('重发成功');
|
||||||
getDataList();
|
getDataList();
|
||||||
})
|
});
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
useMessageBox().confirm('是否确认要撤回该工单?')
|
useMessageBox()
|
||||||
|
.confirm('是否确认要撤回该工单?')
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return recallReset(params)
|
return recallReset(params);
|
||||||
}).then(() => {
|
|
||||||
useMessage().success('撤回成功')
|
|
||||||
getDataList();
|
|
||||||
})
|
})
|
||||||
}
|
.then(() => {
|
||||||
|
useMessage().success('撤回成功');
|
||||||
|
getDataList();
|
||||||
|
});
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import "../../../flow/components/style/flow-drawer.scss";
|
@import '../../../flow/components/style/flow-drawer.scss';
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,25 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="layout-padding">
|
<div class="layout-padding">
|
||||||
<div class="layout-padding-auto layout-padding-view">
|
<div class="layout-padding-auto layout-padding-view">
|
||||||
<form-render ref="formCreateRef" :currFlowForm="props.currFlowForm" :initFormPermPrint="initFormPermPrint">
|
<form-render ref="formCreateRef" :currFlowForm="props.currFlowForm" :initFormPermPrint="initFormPermPrint"> </form-render>
|
||||||
</form-render>
|
|
||||||
</div>
|
</div>
|
||||||
<footer class="el-dialog__footer" v-if="data.submitBtn">
|
<footer class="el-dialog__footer" v-if="data.submitBtn">
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<template v-if="props.currFlowForm.status !== DIC_PROP.ORDER_STATUS[0].value">
|
<template v-if="props.currFlowForm.status !== DIC_PROP.ORDER_STATUS[0].value">
|
||||||
<el-button type="primary" @click="submitForm" :disabled="loading">{{
|
<el-button type="primary" @click="submitForm" :disabled="loading">{{ t('jfI18n.submit') }} </el-button>
|
||||||
t('jfI18n.submit')
|
<el-button type="primary" @click="handleTempStore" :disabled="loading">{{ t('jfI18n.temp') }} </el-button>
|
||||||
}}
|
|
||||||
</el-button>
|
|
||||||
<el-button type="primary" @click="handleTempStore" :disabled="loading">{{
|
|
||||||
t('jfI18n.temp')
|
|
||||||
}}
|
|
||||||
</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<el-button type="primary" @click="submitForm" :disabled="loading">{{
|
<el-button type="primary" @click="submitForm" :disabled="loading">{{ $t('common.editBtn') }}</el-button>
|
||||||
$t('common.editBtn')
|
|
||||||
}}</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
</span>
|
</span>
|
||||||
</footer>
|
</footer>
|
||||||
@@ -27,99 +18,99 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="RunApplicationInitiate">
|
<script setup lang="ts" name="RunApplicationInitiate">
|
||||||
import * as runApplication from '/@/api/order/run-application'
|
import * as runApplication from '/@/api/order/run-application';
|
||||||
import {useI18n} from "vue-i18n";
|
import { useI18n } from 'vue-i18n';
|
||||||
import {validateNull} from "/@/utils/validate";
|
import { validateNull } from '/@/utils/validate';
|
||||||
import {deepClone} from "/@/utils/other";
|
import { deepClone } from '/@/utils/other';
|
||||||
import * as common from "/@/flow/support/common";
|
import * as common from '/@/flow/support/common';
|
||||||
import {doInitData, doInitiateForm, doTempStore, initFormMethods, initJobDataByApp} from "../index";
|
import { doInitData, doInitiateForm, doTempStore, initFormMethods, initJobDataByApp } from '../index';
|
||||||
import {handleFormStartPerm} from "/@/flow/utils/form-perm";
|
import { handleFormStartPerm } from '/@/flow/utils/form-perm';
|
||||||
import {currFormIsView} from "/@/api/order/order-key-vue";
|
import { currFormIsView } from '/@/api/order/order-key-vue';
|
||||||
|
|
||||||
const FormRender = defineAsyncComponent(() => import('/@/flow/components/form-create/render.vue'));
|
const FormRender = defineAsyncComponent(() => import('/@/flow/components/form-create/render.vue'));
|
||||||
const formCreateRef = ref(null)
|
const formCreateRef = ref(null);
|
||||||
|
|
||||||
const {t} = useI18n();
|
const { t } = useI18n();
|
||||||
const $emit = defineEmits(['handleInitiateOrder']);
|
const $emit = defineEmits(['handleInitiateOrder']);
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
currFlowForm: {
|
currFlowForm: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: {},
|
default: {},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
submitBtn: true
|
submitBtn: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const $route = useRoute();
|
const $route = useRoute();
|
||||||
function initJobData() {
|
function initJobData() {
|
||||||
initJobDataByApp($route, handleGetObj, null)
|
initJobDataByApp($route, handleGetObj, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleGetObj(id) {
|
function handleGetObj(id) {
|
||||||
runApplication.getObj(id).then(resp => {
|
runApplication.getObj(id).then((resp) => {
|
||||||
let form = resp.data ? resp.data : {}
|
let form = resp.data ? resp.data : {};
|
||||||
Object.assign(props.currFlowForm, form);
|
Object.assign(props.currFlowForm, form);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function submitForm() {
|
async function submitForm() {
|
||||||
await doInitiateForm(loading, props, data, $route, formCreateRef, $emit, saveInitData, t)
|
await doInitiateForm(loading, props, data, $route, formCreateRef, $emit, saveInitData, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleTempStore() {
|
function handleTempStore() {
|
||||||
doTempStore(loading, data, $route, formCreateRef, $emit, saveInitData)
|
doTempStore(loading, data, $route, formCreateRef, $emit, saveInitData);
|
||||||
}
|
}
|
||||||
|
|
||||||
const methods = initFormMethods(formCreateRef, data)
|
const methods = initFormMethods(formCreateRef, data);
|
||||||
|
|
||||||
async function initFormPermPrint(formInfo) {
|
async function initFormPermPrint(formInfo) {
|
||||||
// 处理表单权限
|
// 处理表单权限
|
||||||
let res = await handleFormStartPerm(null, null, formInfo, props.currFlowForm.defFlowId, null, props.currFlowForm.type)
|
let res = await handleFormStartPerm(null, null, formInfo, props.currFlowForm.defFlowId, null, props.currFlowForm.type);
|
||||||
await currFormIsView(methods, res.elTab, true, res.callback, res.widgetList)
|
await currFormIsView(methods, res.elTab, true, res.callback, res.widgetList);
|
||||||
return res.elTab
|
return res.elTab;
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveInitData(form) {
|
function saveInitData(form) {
|
||||||
props.currFlowForm.formData = validateNull(form) ? undefined : form
|
props.currFlowForm.formData = validateNull(form) ? undefined : form;
|
||||||
let formJson = deepClone(props.currFlowForm)
|
let formJson = deepClone(props.currFlowForm);
|
||||||
let clone = {operType: props.currFlowForm.operType, form: formJson};
|
let clone = { operType: props.currFlowForm.operType, form: formJson };
|
||||||
common.handleCloneSubmit(clone)
|
common.handleCloneSubmit(clone);
|
||||||
formJson.formData = JSON.stringify(formJson.formData)
|
formJson.formData = JSON.stringify(formJson.formData);
|
||||||
return formJson;
|
return formJson;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getFormData() {
|
async function getFormData() {
|
||||||
return await doInitData(formCreateRef, saveInitData)
|
return await doInitData(formCreateRef, saveInitData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 暴露变量
|
// 暴露变量
|
||||||
defineExpose({
|
defineExpose({
|
||||||
getFormData,
|
getFormData,
|
||||||
})
|
});
|
||||||
|
|
||||||
// 监听双向绑定
|
// 监听双向绑定
|
||||||
watch(
|
watch(
|
||||||
() => props.currFlowForm.id,
|
() => props.currFlowForm.id,
|
||||||
() => {
|
() => {
|
||||||
initJobData();
|
initJobData();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
initJobData()
|
initJobData();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.el-dialog__footer {
|
.el-dialog__footer {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
|
||||||
.dialog-footer {
|
.dialog-footer {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,49 +1,49 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="layout-padding">
|
<div class="layout-padding">
|
||||||
<div class="layout-padding-auto layout-padding-view">
|
<div class="layout-padding-auto layout-padding-view">
|
||||||
<form-render ref="formCreateRef" :currFlowForm="form.currFlowForm" v-if="!validateNull(form.currFlowForm)" :renderType="'-1'"
|
<form-render
|
||||||
:initFormPermPrint="initFormPermPrint">
|
ref="formCreateRef"
|
||||||
|
:currFlowForm="form.currFlowForm"
|
||||||
|
v-if="!validateNull(form.currFlowForm)"
|
||||||
|
:renderType="'-1'"
|
||||||
|
:initFormPermPrint="initFormPermPrint"
|
||||||
|
>
|
||||||
</form-render>
|
</form-render>
|
||||||
</div>
|
</div>
|
||||||
<footer class="el-dialog__footer">
|
<footer class="el-dialog__footer">
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button type="primary" @click="printForm" v-if="form.currFlowForm.printInfo">{{
|
<el-button type="primary" @click="printForm" v-if="form.currFlowForm.printInfo">{{ t('jfI18n.print') }} </el-button>
|
||||||
t('jfI18n.print')
|
|
||||||
}}
|
|
||||||
</el-button>
|
|
||||||
</span>
|
</span>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<!-- 打印表单 -->
|
<!-- 打印表单 -->
|
||||||
<el-dialog v-model="form.showTinymceView" top="20px" width="700px"
|
<el-dialog v-model="form.showTinymceView" top="20px" width="700px" :title="form.tinymceTitle" append-to-body @close="closePrint">
|
||||||
:title="form.tinymceTitle" append-to-body
|
|
||||||
@close="closePrint">
|
|
||||||
<tinymce-view v-if="form.showTinymceView" :currFlowForm="form.currFlowForm"></tinymce-view>
|
<tinymce-view v-if="form.showTinymceView" :currFlowForm="form.currFlowForm"></tinymce-view>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="RunApplicationView">
|
<script setup lang="ts" name="RunApplicationView">
|
||||||
import * as runApplication from "/@/api/order/run-application";
|
import * as runApplication from '/@/api/order/run-application';
|
||||||
import {useI18n} from "vue-i18n";
|
import { useI18n } from 'vue-i18n';
|
||||||
import {initJobDataByApp} from "../index";
|
import { initJobDataByApp } from '../index';
|
||||||
import {deepClone} from "/@/utils/other";
|
import { deepClone } from '/@/utils/other';
|
||||||
import {handleFormPrint} from "/@/flow/utils/form-perm";
|
import { handleFormPrint } from '/@/flow/utils/form-perm';
|
||||||
|
|
||||||
const {t} = useI18n();
|
const { t } = useI18n();
|
||||||
const FormRender = defineAsyncComponent(() => import('/@/flow/components/form-create/render.vue'));
|
const FormRender = defineAsyncComponent(() => import('/@/flow/components/form-create/render.vue'));
|
||||||
const formCreateRef = ref(null)
|
const formCreateRef = ref(null);
|
||||||
// 引入组件
|
// 引入组件
|
||||||
const TinymceView = defineAsyncComponent(() => import('/@/flow/components/tinymce/TinymceView.vue'));
|
const TinymceView = defineAsyncComponent(() => import('/@/flow/components/tinymce/TinymceView.vue'));
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
currFlowForm: {
|
currFlowForm: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: {},
|
default: {},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
// 兼容app端监听printInfo
|
// 兼容app端监听printInfo
|
||||||
currFlowForm: {
|
currFlowForm: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@@ -51,65 +51,64 @@
|
|||||||
},
|
},
|
||||||
showTinymceView: false,
|
showTinymceView: false,
|
||||||
tinymceTitle: null,
|
tinymceTitle: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
const $route = useRoute();
|
const $route = useRoute();
|
||||||
function initJobData() {
|
function initJobData() {
|
||||||
initJobDataByApp($route, handleGetObj, () => {
|
initJobDataByApp($route, handleGetObj, () => {
|
||||||
form.currFlowForm = props.currFlowForm
|
form.currFlowForm = props.currFlowForm;
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleGetObj(id) {
|
function handleGetObj(id) {
|
||||||
runApplication.getObj(id).then(resp => {
|
runApplication.getObj(id).then((resp) => {
|
||||||
let formData = resp.data ? resp.data : {}
|
let formData = resp.data ? resp.data : {};
|
||||||
Object.assign(form.currFlowForm, formData);
|
Object.assign(form.currFlowForm, formData);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function initFormPermPrint() {
|
async function initFormPermPrint() {
|
||||||
await handleFormPrint(form.currFlowForm, form.currFlowForm.type, form.currFlowForm.formId, '1')
|
await handleFormPrint(form.currFlowForm, form.currFlowForm.type, form.currFlowForm.formId, '1');
|
||||||
}
|
}
|
||||||
|
|
||||||
function printForm() {
|
function printForm() {
|
||||||
form.currFlowForm.formData = formCreateRef.value.design.formData
|
form.currFlowForm.formData = formCreateRef.value.design.formData;
|
||||||
form.currFlowForm.modelRefList = []
|
form.currFlowForm.modelRefList = [];
|
||||||
let children = formCreateRef.value.design.fApi.children;
|
let children = formCreateRef.value.design.fApi.children;
|
||||||
if (children && children.length > 0) {
|
if (children && children.length > 0) {
|
||||||
// 防止!validateNull(form.currFlowForm)引用循环
|
// 防止!validateNull(form.currFlowForm)引用循环
|
||||||
children.forEach(each => form.currFlowForm.modelRefList.push({model: each.model}))
|
children.forEach((each) => form.currFlowForm.modelRefList.push({ model: each.model }));
|
||||||
}
|
|
||||||
form.currFlowForm.rule = formCreateRef.value.design.rule
|
|
||||||
form.tinymceTitle = form.currFlowForm.formName
|
|
||||||
form.showTinymceView = true
|
|
||||||
}
|
}
|
||||||
|
form.currFlowForm.rule = formCreateRef.value.design.rule;
|
||||||
|
form.tinymceTitle = form.currFlowForm.formName;
|
||||||
|
form.showTinymceView = true;
|
||||||
|
}
|
||||||
|
|
||||||
function closePrint(){
|
function closePrint() {
|
||||||
delete form.currFlowForm.modelRefList
|
delete form.currFlowForm.modelRefList;
|
||||||
delete form.currFlowForm.rule
|
delete form.currFlowForm.rule;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 监听双向绑定
|
// 监听双向绑定
|
||||||
watch(
|
watch(
|
||||||
() => props.currFlowForm.id,
|
() => props.currFlowForm.id,
|
||||||
() => {
|
() => {
|
||||||
initJobData();
|
initJobData();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
initJobData()
|
initJobData();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.el-dialog__footer {
|
.el-dialog__footer {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
|
||||||
.dialog-footer {
|
.dialog-footer {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -3,12 +3,9 @@
|
|||||||
<div class="layout-padding-auto layout-padding-view">
|
<div class="layout-padding-auto layout-padding-view">
|
||||||
<!-- 操作按钮 -->
|
<!-- 操作按钮 -->
|
||||||
<el-row>
|
<el-row>
|
||||||
<div class="mb15" style="width: 100%;">
|
<div class="mb15" style="width: 100%">
|
||||||
<el-button
|
<el-button v-if="hasAuth('professional_professionalacademicqualificationsconfig_add')" type="primary" icon="FolderAdd" @click="handleAdd"
|
||||||
v-if="hasAuth('professional_professionalacademicqualificationsconfig_add')"
|
>新 增
|
||||||
type="primary"
|
|
||||||
icon="FolderAdd"
|
|
||||||
@click="handleAdd">新 增
|
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-row>
|
</el-row>
|
||||||
@@ -39,7 +36,8 @@
|
|||||||
icon="edit-pen"
|
icon="edit-pen"
|
||||||
link
|
link
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="handleEdit(scope.row)">修改
|
@click="handleEdit(scope.row)"
|
||||||
|
>修改
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
v-if="hasAuth('professional_professionalacademicqualificationsconfig_del')"
|
v-if="hasAuth('professional_professionalacademicqualificationsconfig_del')"
|
||||||
@@ -47,58 +45,29 @@
|
|||||||
link
|
link
|
||||||
type="danger"
|
type="danger"
|
||||||
style="margin-left: 12px"
|
style="margin-left: 12px"
|
||||||
@click="handleDel(scope.row)">删除
|
@click="handleDel(scope.row)"
|
||||||
|
>删除
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
<pagination
|
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||||
v-bind="state.pagination"
|
|
||||||
@current-change="currentChangeHandle"
|
|
||||||
@size-change="sizeChangeHandle"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 新增/编辑弹窗 -->
|
<!-- 新增/编辑弹窗 -->
|
||||||
<el-dialog
|
<el-dialog v-model="dialogVisible" :title="form.id ? '修改' : '新增'" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||||
v-model="dialogVisible"
|
<el-form ref="formRef" :model="form" :rules="formRules" label-width="120px">
|
||||||
:title="form.id ? '修改' : '新增'"
|
|
||||||
width="600px"
|
|
||||||
:close-on-click-modal="false"
|
|
||||||
destroy-on-close
|
|
||||||
>
|
|
||||||
<el-form
|
|
||||||
ref="formRef"
|
|
||||||
:model="form"
|
|
||||||
:rules="formRules"
|
|
||||||
label-width="120px"
|
|
||||||
>
|
|
||||||
<el-form-item label="学历名称" prop="qualificationName">
|
<el-form-item label="学历名称" prop="qualificationName">
|
||||||
<el-input
|
<el-input v-model="form.qualificationName" placeholder="请输入学历名称" clearable />
|
||||||
v-model="form.qualificationName"
|
|
||||||
placeholder="请输入学历名称"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="排序" prop="sort">
|
<el-form-item label="排序" prop="sort">
|
||||||
<el-input-number
|
<el-input-number v-model="form.sort" :min="0" placeholder="请输入排序" style="width: 100%" />
|
||||||
v-model="form.sort"
|
|
||||||
:min="0"
|
|
||||||
placeholder="请输入排序"
|
|
||||||
style="width: 100%"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="备注" prop="remarks">
|
<el-form-item label="备注" prop="remarks">
|
||||||
<el-input
|
<el-input v-model="form.remarks" type="textarea" :rows="3" placeholder="请输入备注" clearable />
|
||||||
v-model="form.remarks"
|
|
||||||
type="textarea"
|
|
||||||
:rows="3"
|
|
||||||
placeholder="请输入备注"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
@@ -114,59 +83,55 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive } from 'vue'
|
import { ref, reactive } from 'vue';
|
||||||
import { useAuth } from '/@/hooks/auth'
|
import { useAuth } from '/@/hooks/auth';
|
||||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||||
import { useMessage } from '/@/hooks/message'
|
import { useMessage } from '/@/hooks/message';
|
||||||
import { useMessageBox } from '/@/hooks/message'
|
import { useMessageBox } from '/@/hooks/message';
|
||||||
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/academicqualificationsconfig'
|
import { fetchList, addObj, putObj, delObj } from '/@/api/professional/rsbase/academicqualificationsconfig';
|
||||||
|
|
||||||
const { hasAuth } = useAuth()
|
const { hasAuth } = useAuth();
|
||||||
// 消息提示 hooks
|
// 消息提示 hooks
|
||||||
const message = useMessage()
|
const message = useMessage();
|
||||||
const messageBox = useMessageBox()
|
const messageBox = useMessageBox();
|
||||||
|
|
||||||
// 表格引用
|
// 表格引用
|
||||||
const tableRef = ref()
|
const tableRef = ref();
|
||||||
const formRef = ref()
|
const formRef = ref();
|
||||||
|
|
||||||
// 弹窗状态
|
// 弹窗状态
|
||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false);
|
||||||
const submitLoading = ref(false)
|
const submitLoading = ref(false);
|
||||||
|
|
||||||
// 表单数据
|
// 表单数据
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
id: '',
|
id: '',
|
||||||
qualificationName: '',
|
qualificationName: '',
|
||||||
sort: 0,
|
sort: 0,
|
||||||
remarks: ''
|
remarks: '',
|
||||||
})
|
});
|
||||||
|
|
||||||
// 表单验证规则
|
// 表单验证规则
|
||||||
const formRules = {
|
const formRules = {
|
||||||
qualificationName: [
|
qualificationName: [{ required: true, message: '请输入学历名称', trigger: 'blur' }],
|
||||||
{ required: true, message: '请输入学历名称', trigger: 'blur' }
|
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }],
|
||||||
],
|
};
|
||||||
sort: [
|
|
||||||
{ required: true, message: '请输入排序', trigger: 'blur' }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
// 配置 useTable
|
// 配置 useTable
|
||||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||||
pageList: async (params: any) => {
|
pageList: async (params: any) => {
|
||||||
const response = await fetchList(params)
|
const response = await fetchList(params);
|
||||||
return {
|
return {
|
||||||
data: {
|
data: {
|
||||||
records: response.data.records || [],
|
records: response.data.records || [],
|
||||||
total: response.data.total || 0
|
total: response.data.total || 0,
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
queryForm: {}
|
};
|
||||||
})
|
},
|
||||||
|
queryForm: {},
|
||||||
|
});
|
||||||
|
|
||||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||||
|
|
||||||
// 打开新增窗口
|
// 打开新增窗口
|
||||||
const handleAdd = () => {
|
const handleAdd = () => {
|
||||||
@@ -174,10 +139,10 @@ const handleAdd = () => {
|
|||||||
id: '',
|
id: '',
|
||||||
qualificationName: '',
|
qualificationName: '',
|
||||||
sort: 0,
|
sort: 0,
|
||||||
remarks: ''
|
remarks: '',
|
||||||
})
|
});
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 打开编辑窗口
|
// 打开编辑窗口
|
||||||
const handleEdit = async (row: any) => {
|
const handleEdit = async (row: any) => {
|
||||||
@@ -185,52 +150,53 @@ const handleEdit = async (row: any) => {
|
|||||||
id: row.id,
|
id: row.id,
|
||||||
qualificationName: row.qualificationName || '',
|
qualificationName: row.qualificationName || '',
|
||||||
sort: row.sort || 0,
|
sort: row.sort || 0,
|
||||||
remarks: row.remarks || ''
|
remarks: row.remarks || '',
|
||||||
})
|
});
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 删除
|
// 删除
|
||||||
const handleDel = (row: any) => {
|
const handleDel = (row: any) => {
|
||||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
messageBox
|
||||||
await delObj(row.id)
|
.confirm('是否确认删除该条记录')
|
||||||
message.success('删除成功')
|
.then(async () => {
|
||||||
|
await delObj(row.id);
|
||||||
|
message.success('删除成功');
|
||||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||||
state.pagination.current = state.pagination.current - 1
|
state.pagination.current = state.pagination.current - 1;
|
||||||
}
|
}
|
||||||
getDataList()
|
getDataList();
|
||||||
}).catch(() => {})
|
})
|
||||||
}
|
.catch(() => {});
|
||||||
|
};
|
||||||
|
|
||||||
// 提交表单
|
// 提交表单
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
if (!formRef.value) return
|
if (!formRef.value) return;
|
||||||
|
|
||||||
await formRef.value.validate(async (valid: boolean) => {
|
await formRef.value.validate(async (valid: boolean) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
submitLoading.value = true
|
submitLoading.value = true;
|
||||||
try {
|
try {
|
||||||
if (form.id) {
|
if (form.id) {
|
||||||
await putObj(form)
|
await putObj(form);
|
||||||
message.success('修改成功')
|
message.success('修改成功');
|
||||||
} else {
|
} else {
|
||||||
await addObj(form)
|
await addObj(form);
|
||||||
message.success('添加成功')
|
message.success('添加成功');
|
||||||
}
|
}
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false;
|
||||||
getDataList()
|
getDataList();
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
// 处理业务错误
|
// 处理业务错误
|
||||||
message.error(error.msg)
|
message.error(error.msg);
|
||||||
} finally {
|
} finally {
|
||||||
submitLoading.value = false
|
submitLoading.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped></style>
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -14,38 +14,37 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, defineAsyncComponent } from 'vue';
|
import { ref, defineAsyncComponent } from 'vue';
|
||||||
const multiUpload = defineAsyncComponent(() => import('./multiUpload.vue'))
|
const multiUpload = defineAsyncComponent(() => import('./multiUpload.vue'));
|
||||||
|
|
||||||
// Props
|
// Props
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
fileList: any[]
|
fileList: any[];
|
||||||
type?: string
|
type?: string;
|
||||||
params?: any
|
params?: any;
|
||||||
limitNums?: number
|
limitNums?: number;
|
||||||
acceptFile?: string
|
acceptFile?: string;
|
||||||
}>()
|
}>();
|
||||||
|
|
||||||
// 组件引用
|
// 组件引用
|
||||||
const commonUploadPicRef = ref()
|
const commonUploadPicRef = ref();
|
||||||
|
|
||||||
// 推送列表数据
|
// 推送列表数据
|
||||||
const pushListData = (data: { name: string; url: string }) => {
|
const pushListData = (data: { name: string; url: string }) => {
|
||||||
props.fileList.push(data)
|
props.fileList.push(data);
|
||||||
}
|
};
|
||||||
|
|
||||||
// 删除列表数据
|
// 删除列表数据
|
||||||
const delListData = (file: string) => {
|
const delListData = (file: string) => {
|
||||||
const index = props.fileList.findIndex((item: any) => item.url === file)
|
const index = props.fileList.findIndex((item: any) => item.url === file);
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
props.fileList.splice(index, 1)
|
props.fileList.splice(index, 1);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// 暴露方法
|
// 暴露方法
|
||||||
defineExpose({
|
defineExpose({
|
||||||
commonUploadPic: commonUploadPicRef
|
commonUploadPic: commonUploadPicRef,
|
||||||
})
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped></style>
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -49,36 +49,36 @@ const visible = ref(false);
|
|||||||
const headers = computed(() => {
|
const headers = computed(() => {
|
||||||
return {
|
return {
|
||||||
Authorization: 'Bearer ' + Session.getToken(),
|
Authorization: 'Bearer ' + Session.getToken(),
|
||||||
TENANT_ID: Session.getTenant()
|
TENANT_ID: Session.getTenant(),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
const uploadUrl = ref('')
|
const uploadUrl = ref('');
|
||||||
const currentType = ref('')
|
const currentType = ref('');
|
||||||
const uploadRef = ref<{ clearFiles?: () => void }>()
|
const uploadRef = ref<{ clearFiles?: () => void }>();
|
||||||
const titleMap: Record<string, string> = {
|
const titleMap: Record<string, string> = {
|
||||||
titleRelation: '职称信息导入',
|
titleRelation: '职称信息导入',
|
||||||
quaRelation: '职业资格信息导入',
|
quaRelation: '职业资格信息导入',
|
||||||
cerRelation: '教师资格证信息导入',
|
cerRelation: '教师资格证信息导入',
|
||||||
eduDegree: '学历学位信息导入',
|
eduDegree: '学历学位信息导入',
|
||||||
partyChange: '党组织变动信息导入',
|
partyChange: '党组织变动信息导入',
|
||||||
honor: '综合表彰信息导入'
|
honor: '综合表彰信息导入',
|
||||||
}
|
};
|
||||||
// 方法
|
// 方法
|
||||||
const init = (type: any) => {
|
const init = (type: any) => {
|
||||||
currentType.value = type
|
currentType.value = type;
|
||||||
uploadUrl.value = '/professional/file/importTeacherOtherInfo?type=' + type
|
uploadUrl.value = '/professional/file/importTeacherOtherInfo?type=' + type;
|
||||||
title.value = titleMap[type] || '信息导入'
|
title.value = titleMap[type] || '信息导入';
|
||||||
visible.value = true
|
visible.value = true;
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
uploadRef.value?.clearFiles()
|
uploadRef.value?.clearFiles();
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
// Emits
|
// Emits
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'refreshData'): void
|
(e: 'refreshData'): void;
|
||||||
}>()
|
}>();
|
||||||
|
|
||||||
const handleUploadSuccess = () => {
|
const handleUploadSuccess = () => {
|
||||||
visible.value = false;
|
visible.value = false;
|
||||||
@@ -88,7 +88,7 @@ const handleUploadSuccess = () => {
|
|||||||
type: 'success',
|
type: 'success',
|
||||||
});
|
});
|
||||||
|
|
||||||
emit('refreshData')
|
emit('refreshData');
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleAvatarError = (err: any) => {
|
const handleAvatarError = (err: any) => {
|
||||||
@@ -103,8 +103,8 @@ const handleAvatarError = (err: any) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleDownloadTemplate = () => {
|
const handleDownloadTemplate = () => {
|
||||||
downBlobFile('/professional/file/exportTeacherInfoTemplate', { type: currentType.value || 'titleRelation' }, title.value+'模板.xlsx')
|
downBlobFile('/professional/file/exportTeacherInfoTemplate', { type: currentType.value || 'titleRelation' }, title.value + '模板.xlsx');
|
||||||
}
|
};
|
||||||
|
|
||||||
// 暴露方法给父组件
|
// 暴露方法给父组件
|
||||||
defineExpose({
|
defineExpose({
|
||||||
|
|||||||
@@ -2,28 +2,27 @@
|
|||||||
<div>
|
<div>
|
||||||
<el-button type="success" icon="view" size="small" @click="handlePdfPreview">预览</el-button>
|
<el-button type="success" icon="view" size="small" @click="handlePdfPreview">预览</el-button>
|
||||||
<el-dialog v-model="visible" width="90%" append-to-body destroy-on-close>
|
<el-dialog v-model="visible" width="90%" append-to-body destroy-on-close>
|
||||||
<auth-img :authSrc="url" style="height:1000px;" v-if="visible" />
|
<auth-img :authSrc="url" style="height: 1000px" v-if="visible" />
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, defineAsyncComponent } from 'vue'
|
import { ref, defineAsyncComponent } from 'vue';
|
||||||
const authImg = defineAsyncComponent(() => import('/@/components/tools/auth-img.vue'))
|
const authImg = defineAsyncComponent(() => import('/@/components/tools/auth-img.vue'));
|
||||||
|
|
||||||
// Props
|
// Props
|
||||||
defineProps<{
|
defineProps<{
|
||||||
url: string
|
url: string;
|
||||||
}>()
|
}>();
|
||||||
|
|
||||||
// 对话框显示状态
|
// 对话框显示状态
|
||||||
const visible = ref(false)
|
const visible = ref(false);
|
||||||
|
|
||||||
// 预览PDF
|
// 预览PDF
|
||||||
const handlePdfPreview = () => {
|
const handlePdfPreview = () => {
|
||||||
visible.value = true
|
visible.value = true;
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -11,105 +11,104 @@
|
|||||||
:file-list="fileList"
|
:file-list="fileList"
|
||||||
:accept="realAcceptFile"
|
:accept="realAcceptFile"
|
||||||
:limit="realLimitNums"
|
:limit="realLimitNums"
|
||||||
list-type="picture">
|
list-type="picture"
|
||||||
|
>
|
||||||
<el-button size="small" type="primary">点击上传</el-button>
|
<el-button size="small" type="primary">点击上传</el-button>
|
||||||
<el-tag>仅支持{{realAcceptFile}}后缀的文件上传,且文件大小不能超过5M!最大上传数量限制为{{realLimitNums}}.</el-tag>
|
<el-tag>仅支持{{ realAcceptFile }}后缀的文件上传,且文件大小不能超过5M!最大上传数量限制为{{ realLimitNums }}.</el-tag>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, onMounted } from 'vue'
|
import { ref, computed, onMounted } from 'vue';
|
||||||
import { useMessage } from '/@/hooks/message'
|
import { useMessage } from '/@/hooks/message';
|
||||||
import { Session } from '/@/utils/storage'
|
import { Session } from '/@/utils/storage';
|
||||||
|
|
||||||
// Props
|
// Props
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
params?: any
|
params?: any;
|
||||||
fileList?: any[]
|
fileList?: any[];
|
||||||
limitNums?: number
|
limitNums?: number;
|
||||||
acceptFile?: string
|
acceptFile?: string;
|
||||||
}>()
|
}>();
|
||||||
|
|
||||||
// Emits
|
// Emits
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
delListData: [url: string]
|
delListData: [url: string];
|
||||||
pushListData: [obj: { name: string; url: string }]
|
pushListData: [obj: { name: string; url: string }];
|
||||||
}>()
|
}>();
|
||||||
|
|
||||||
// 消息提示 hooks
|
// 消息提示 hooks
|
||||||
const message = useMessage()
|
const message = useMessage();
|
||||||
|
|
||||||
// 响应式数据
|
// 响应式数据
|
||||||
const realLimitNums = ref(0)
|
const realLimitNums = ref(0);
|
||||||
const realAcceptFile = ref('.jpg,.jpeg,.png,.pdf')
|
const realAcceptFile = ref('.jpg,.jpeg,.png,.pdf');
|
||||||
const fileName = ref('')
|
const fileName = ref('');
|
||||||
|
|
||||||
// Computed
|
// Computed
|
||||||
const headers = computed(() => {
|
const headers = computed(() => {
|
||||||
return {
|
return {
|
||||||
"Authorization": 'Bearer ' + Session.getToken()
|
Authorization: 'Bearer ' + Session.getToken(),
|
||||||
}
|
};
|
||||||
})
|
});
|
||||||
|
|
||||||
// 生命周期
|
// 生命周期
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (props.limitNums) {
|
if (props.limitNums) {
|
||||||
realLimitNums.value = props.limitNums
|
realLimitNums.value = props.limitNums;
|
||||||
} else {
|
} else {
|
||||||
realLimitNums.value = 5
|
realLimitNums.value = 5;
|
||||||
}
|
}
|
||||||
if (props.acceptFile) {
|
if (props.acceptFile) {
|
||||||
realAcceptFile.value = props.acceptFile
|
realAcceptFile.value = props.acceptFile;
|
||||||
} else {
|
} else {
|
||||||
realAcceptFile.value = ".jpg,.jpeg,.png,.pdf"
|
realAcceptFile.value = '.jpg,.jpeg,.png,.pdf';
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
// 方法
|
// 方法
|
||||||
// const handleUploadLimit = () => {
|
// const handleUploadLimit = () => {
|
||||||
// message.error('最多只能上传1张图片')
|
// message.error('最多只能上传1张图片')
|
||||||
// }
|
// }
|
||||||
|
|
||||||
const beforeUpload = (file: any) => {
|
const beforeUpload = (file: any) => {
|
||||||
let fileNameStr = file.name
|
let fileNameStr = file.name;
|
||||||
const pos = fileNameStr.lastIndexOf(".")
|
const pos = fileNameStr.lastIndexOf('.');
|
||||||
fileNameStr = fileNameStr.substring(pos + 1, fileNameStr.length)
|
fileNameStr = fileNameStr.substring(pos + 1, fileNameStr.length);
|
||||||
fileNameStr = fileNameStr.toLowerCase()
|
fileNameStr = fileNameStr.toLowerCase();
|
||||||
const extension = fileNameStr === 'jpg'
|
const extension = fileNameStr === 'jpg';
|
||||||
const extension2 = fileNameStr === 'png'
|
const extension2 = fileNameStr === 'png';
|
||||||
const extension3 = fileNameStr === 'jpeg'
|
const extension3 = fileNameStr === 'jpeg';
|
||||||
const extension4 = fileNameStr === 'bmp'
|
const extension4 = fileNameStr === 'bmp';
|
||||||
const extension5 = fileNameStr === 'gif'
|
const extension5 = fileNameStr === 'gif';
|
||||||
const extension6 = fileNameStr === 'pdf'
|
const extension6 = fileNameStr === 'pdf';
|
||||||
const isLt2M = file.size / 1024 / 1024 < 5
|
const isLt2M = file.size / 1024 / 1024 < 5;
|
||||||
if (!extension && !extension2 && !extension3 && !extension4 && !extension5 && !extension6) {
|
if (!extension && !extension2 && !extension3 && !extension4 && !extension5 && !extension6) {
|
||||||
message.warning('请检查文件上传格式!')
|
message.warning('请检查文件上传格式!');
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
if (!isLt2M) {
|
if (!isLt2M) {
|
||||||
message.warning('上传图片大小不能超过 5MB!')
|
message.warning('上传图片大小不能超过 5MB!');
|
||||||
return false
|
return false;
|
||||||
}
|
|
||||||
fileName.value = file.name
|
|
||||||
return true // 返回false不会自动上传
|
|
||||||
}
|
}
|
||||||
|
fileName.value = file.name;
|
||||||
|
return true; // 返回false不会自动上传
|
||||||
|
};
|
||||||
|
|
||||||
const handleRemove = (file: any) => {
|
const handleRemove = (file: any) => {
|
||||||
emit("delListData", file.url)
|
emit('delListData', file.url);
|
||||||
}
|
};
|
||||||
|
|
||||||
// const handleUploadError = () => {
|
// const handleUploadError = () => {
|
||||||
// message.error('文件上传失败,请检查文件上传格式与大小')
|
// message.error('文件上传失败,请检查文件上传格式与大小')
|
||||||
// }
|
// }
|
||||||
|
|
||||||
const handleUploadSuccess = (res: any) => {
|
const handleUploadSuccess = (res: any) => {
|
||||||
message.success('文件上传成功')
|
message.success('文件上传成功');
|
||||||
const obj = { name: res.data.name, url: res.data.url }
|
const obj = { name: res.data.name, url: res.data.url };
|
||||||
emit("pushListData", obj)
|
emit('pushListData', obj);
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped></style>
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -8,14 +8,7 @@
|
|||||||
<el-input v-model="typeName" disabled />
|
<el-input v-model="typeName" disabled />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="驳回理由">
|
<el-form-item label="驳回理由">
|
||||||
<el-input
|
<el-input type="textarea" v-model="dataForm.backReason" :rows="3" placeholder="请输入驳回理由" maxlength="500" show-word-limit />
|
||||||
type="textarea"
|
|
||||||
v-model="dataForm.backReason"
|
|
||||||
:rows="3"
|
|
||||||
placeholder="请输入驳回理由"
|
|
||||||
maxlength="500"
|
|
||||||
show-word-limit
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
@@ -29,45 +22,45 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive } from 'vue'
|
import { ref, reactive } from 'vue';
|
||||||
import { useMessage, useMessageBox } from '/@/hooks/message'
|
import { useMessage, useMessageBox } from '/@/hooks/message';
|
||||||
import { examObj as editTitle } from '/@/api/professional/professionaluser/professionaltitlerelation'
|
import { examObj as editTitle } from '/@/api/professional/professionaluser/professionaltitlerelation';
|
||||||
import { examObj as editQua } from '/@/api/professional/professionaluser/professionalqualificationrelation'
|
import { examObj as editQua } from '/@/api/professional/professionaluser/professionalqualificationrelation';
|
||||||
import { examObj as editCer } from '/@/api/professional/professionaluser/professionalteachercertificaterelation'
|
import { examObj as editCer } from '/@/api/professional/professionaluser/professionalteachercertificaterelation';
|
||||||
import { examObj as editEducation } from '/@/api/professional/professionaluser/professionalteacheracademicrelation'
|
import { examObj as editEducation } from '/@/api/professional/professionaluser/professionalteacheracademicrelation';
|
||||||
import { examObj as editHonor } from '/@/api/professional/professionaluser/professionalteacherhonor'
|
import { examObj as editHonor } from '/@/api/professional/professionaluser/professionalteacherhonor';
|
||||||
import { examObj as editPaper } from '/@/api/professional/professionalteacherpaper'
|
import { examObj as editPaper } from '/@/api/professional/professionalteacherpaper';
|
||||||
import { examObj as editMaterial } from '/@/api/professional/professionalteachingmaterial'
|
import { examObj as editMaterial } from '/@/api/professional/professionalteachingmaterial';
|
||||||
import { examObj as editTopic } from '/@/api/professional/professionaltopiclist'
|
import { examObj as editTopic } from '/@/api/professional/professionaltopiclist';
|
||||||
|
|
||||||
// Emits
|
// Emits
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'refreshData'): void
|
(e: 'refreshData'): void;
|
||||||
}>()
|
}>();
|
||||||
|
|
||||||
// 消息提示
|
// 消息提示
|
||||||
const message = useMessage()
|
const message = useMessage();
|
||||||
const messageBox = useMessageBox()
|
const messageBox = useMessageBox();
|
||||||
|
|
||||||
// 对话框显示状态
|
// 对话框显示状态
|
||||||
const visible = ref(false)
|
const visible = ref(false);
|
||||||
|
|
||||||
// 加载状态
|
// 加载状态
|
||||||
const loading = ref(false)
|
const loading = ref(false);
|
||||||
|
|
||||||
// 表单数据
|
// 表单数据
|
||||||
const dataForm = reactive({
|
const dataForm = reactive({
|
||||||
name: '',
|
name: '',
|
||||||
id: null as string | number | null,
|
id: null as string | number | null,
|
||||||
backReason: '',
|
backReason: '',
|
||||||
teacherNo: ''
|
teacherNo: '',
|
||||||
})
|
});
|
||||||
|
|
||||||
// 类型名称
|
// 类型名称
|
||||||
const typeName = ref('')
|
const typeName = ref('');
|
||||||
|
|
||||||
// 类型
|
// 类型
|
||||||
const type = ref('')
|
const type = ref('');
|
||||||
|
|
||||||
// 类型映射
|
// 类型映射
|
||||||
const typeMap: Record<string, string> = {
|
const typeMap: Record<string, string> = {
|
||||||
@@ -78,8 +71,8 @@ const typeMap: Record<string, string> = {
|
|||||||
honor: '综合表彰',
|
honor: '综合表彰',
|
||||||
paper: '教师论文',
|
paper: '教师论文',
|
||||||
material: '教材',
|
material: '教材',
|
||||||
topic: '课题'
|
topic: '课题',
|
||||||
}
|
};
|
||||||
|
|
||||||
// API 方法映射
|
// API 方法映射
|
||||||
const apiMethodMap: Record<string, any> = {
|
const apiMethodMap: Record<string, any> = {
|
||||||
@@ -90,65 +83,65 @@ const apiMethodMap: Record<string, any> = {
|
|||||||
honor: editHonor,
|
honor: editHonor,
|
||||||
paper: editPaper,
|
paper: editPaper,
|
||||||
material: editMaterial,
|
material: editMaterial,
|
||||||
topic: editTopic
|
topic: editTopic,
|
||||||
}
|
};
|
||||||
|
|
||||||
// 初始化
|
// 初始化
|
||||||
const init = (row: any, typeValue: string) => {
|
const init = (row: any, typeValue: string) => {
|
||||||
type.value = typeValue
|
type.value = typeValue;
|
||||||
typeName.value = typeMap[typeValue] || ''
|
typeName.value = typeMap[typeValue] || '';
|
||||||
dataForm.name = row.realName || ''
|
dataForm.name = row.realName || '';
|
||||||
dataForm.teacherNo = row.teacherNo || ''
|
dataForm.teacherNo = row.teacherNo || '';
|
||||||
dataForm.id = row.id || null
|
dataForm.id = row.id || null;
|
||||||
dataForm.backReason = ''
|
dataForm.backReason = '';
|
||||||
visible.value = true
|
visible.value = true;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 保存数据
|
// 保存数据
|
||||||
const saveData = async () => {
|
const saveData = async () => {
|
||||||
if (!dataForm.backReason.trim()) {
|
if (!dataForm.backReason.trim()) {
|
||||||
message.warning('请填写驳回理由')
|
message.warning('请填写驳回理由');
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const apiMethod = apiMethodMap[type.value]
|
const apiMethod = apiMethodMap[type.value];
|
||||||
if (!apiMethod) {
|
if (!apiMethod) {
|
||||||
message.error('未知的类型')
|
message.error('未知的类型');
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await saveDataMethod(apiMethod)
|
await saveDataMethod(apiMethod);
|
||||||
}
|
};
|
||||||
|
|
||||||
// 保存数据方法
|
// 保存数据方法
|
||||||
const saveDataMethod = async (method: any) => {
|
const saveDataMethod = async (method: any) => {
|
||||||
const data = {
|
const data = {
|
||||||
id: dataForm.id,
|
id: dataForm.id,
|
||||||
state: '-2',
|
state: '-2',
|
||||||
backReason: dataForm.backReason
|
backReason: dataForm.backReason,
|
||||||
}
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await messageBox.confirm(`确认驳回, ${dataForm.name}的${typeName.value}申请?`)
|
await messageBox.confirm(`确认驳回, ${dataForm.name}的${typeName.value}申请?`);
|
||||||
loading.value = true
|
loading.value = true;
|
||||||
await method(data)
|
await method(data);
|
||||||
message.success('操作成功')
|
message.success('操作成功');
|
||||||
visible.value = false
|
visible.value = false;
|
||||||
emit('refreshData')
|
emit('refreshData');
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
// 用户取消或请求失败
|
// 用户取消或请求失败
|
||||||
if (error !== 'cancel') {
|
if (error !== 'cancel') {
|
||||||
message.error(error?.msg || '操作失败')
|
message.error(error?.msg || '操作失败');
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// 暴露方法
|
// 暴露方法
|
||||||
defineExpose({
|
defineExpose({
|
||||||
init
|
init,
|
||||||
})
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@@ -2,45 +2,45 @@
|
|||||||
<el-dialog append-to-body v-model="visible" width="90%" height="700px" :title="title">
|
<el-dialog append-to-body v-model="visible" width="90%" height="700px" :title="title">
|
||||||
<el-tabs v-model="activeName" type="border-card" tab-position="left">
|
<el-tabs v-model="activeName" type="border-card" tab-position="left">
|
||||||
<el-tab-pane label="获奖证书" name="awardImg" v-if="imageData.awardImg">
|
<el-tab-pane label="获奖证书" name="awardImg" v-if="imageData.awardImg">
|
||||||
<auth-img v-for="src in imageData.awardImg" :authSrc="src.url" :key="src.url" style="height:1000px;"></auth-img>
|
<auth-img v-for="src in imageData.awardImg" :authSrc="src.url" :key="src.url" style="height: 1000px"></auth-img>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="知网截图" name="knowdgeImg" v-if="imageData.knowdgeImg">
|
<el-tab-pane label="知网截图" name="knowdgeImg" v-if="imageData.knowdgeImg">
|
||||||
<auth-img v-for="src in imageData.knowdgeImg" :authSrc="src.url" :key="src.url" style="height:1000px;"></auth-img>
|
<auth-img v-for="src in imageData.knowdgeImg" :authSrc="src.url" :key="src.url" style="height: 1000px"></auth-img>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="刊物封面" name="pubCover" v-if="imageData.pubCover">
|
<el-tab-pane label="刊物封面" name="pubCover" v-if="imageData.pubCover">
|
||||||
<auth-img v-for="src in imageData.pubCover" :authSrc="src.url" :key="src.url" style="height:1000px;"></auth-img>
|
<auth-img v-for="src in imageData.pubCover" :authSrc="src.url" :key="src.url" style="height: 1000px"></auth-img>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
<el-tab-pane label="目录页" name="cateImg" v-if="imageData.cateImg">
|
<el-tab-pane label="目录页" name="cateImg" v-if="imageData.cateImg">
|
||||||
<auth-img v-for="src in imageData.cateImg" :authSrc="src.url" :key="src.url" style="height:1000px;"></auth-img>
|
<auth-img v-for="src in imageData.cateImg" :authSrc="src.url" :key="src.url" style="height: 1000px"></auth-img>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
<el-tab-pane label="内容页" name="contentImg" v-if="imageData.contentImg">
|
<el-tab-pane label="内容页" name="contentImg" v-if="imageData.contentImg">
|
||||||
<auth-img v-for="src in imageData.contentImg" :authSrc="src.url" :key="src.url" style="height:1000px;"></auth-img>
|
<auth-img v-for="src in imageData.contentImg" :authSrc="src.url" :key="src.url" style="height: 1000px"></auth-img>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
<el-tab-pane label="教材封面" name="mateCover" v-if="imageData.mateCover">
|
<el-tab-pane label="教材封面" name="mateCover" v-if="imageData.mateCover">
|
||||||
<auth-img v-for="src in imageData.mateCover" :authSrc="src.url" :key="src.url" style="height:1000px;"></auth-img>
|
<auth-img v-for="src in imageData.mateCover" :authSrc="src.url" :key="src.url" style="height: 1000px"></auth-img>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
<el-tab-pane label="出版页" name="pubImg" v-if="imageData.pubImg">
|
<el-tab-pane label="出版页" name="pubImg" v-if="imageData.pubImg">
|
||||||
<auth-img v-for="src in imageData.pubImg" :authSrc="src.url" :key="src.url" style="height:1000px;"></auth-img>
|
<auth-img v-for="src in imageData.pubImg" :authSrc="src.url" :key="src.url" style="height: 1000px"></auth-img>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
<el-tab-pane label="立项申报书" name="projectApp" v-if="imageData.projectApp">
|
<el-tab-pane label="立项申报书" name="projectApp" v-if="imageData.projectApp">
|
||||||
<auth-img v-for="src in imageData.projectApp" :authSrc="src.url" :key="src.url" style="height:1000px;"></auth-img>
|
<auth-img v-for="src in imageData.projectApp" :authSrc="src.url" :key="src.url" style="height: 1000px"></auth-img>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
<el-tab-pane label="结题证书" name="conclusionBook" v-if="imageData.conclusionBook">
|
<el-tab-pane label="结题证书" name="conclusionBook" v-if="imageData.conclusionBook">
|
||||||
<auth-img v-for="src in imageData.conclusionBook" :authSrc="src.url" :key="src.url" style="height:1000px;"></auth-img>
|
<auth-img v-for="src in imageData.conclusionBook" :authSrc="src.url" :key="src.url" style="height: 1000px"></auth-img>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
<el-tab-pane label="结题报告" name="conclusionReport" v-if="imageData.conclusionReport">
|
<el-tab-pane label="结题报告" name="conclusionReport" v-if="imageData.conclusionReport">
|
||||||
<auth-img v-for="src in imageData.conclusionReport" :authSrc="src.url" :key="src.url" style="height:1000px;"></auth-img>
|
<auth-img v-for="src in imageData.conclusionReport" :authSrc="src.url" :key="src.url" style="height: 1000px"></auth-img>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
<el-tab-pane label="其他材料" name="otherImg" v-if="imageData.otherImg">
|
<el-tab-pane label="其他材料" name="otherImg" v-if="imageData.otherImg">
|
||||||
<auth-img v-for="src in imageData.otherImg" :authSrc="src.url" :key="src.url" style="height:1000px;"></auth-img>
|
<auth-img v-for="src in imageData.otherImg" :authSrc="src.url" :key="src.url" style="height: 1000px"></auth-img>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts" name="showEvidence">
|
<script setup lang="ts" name="showEvidence">
|
||||||
import { ref, reactive, nextTick, defineAsyncComponent } from 'vue';
|
import { ref, reactive, nextTick, defineAsyncComponent } from 'vue';
|
||||||
const authImg = defineAsyncComponent(() => import('/@/components/tools/auth-img.vue'))
|
const authImg = defineAsyncComponent(() => import('/@/components/tools/auth-img.vue'));
|
||||||
|
|
||||||
interface ImageItem {
|
interface ImageItem {
|
||||||
url: string;
|
url: string;
|
||||||
@@ -150,6 +150,4 @@ defineExpose({
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped></style>
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -1,55 +1,55 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog v-model="visible" width="90%" append-to-body title="综合表彰材料">
|
<el-dialog v-model="visible" width="90%" append-to-body title="综合表彰材料">
|
||||||
<auth-img v-for="src in imgUrl" :key="src.title" :authSrc="src.url" style="height:1000px;"></auth-img>
|
<auth-img v-for="src in imgUrl" :key="src.title" :authSrc="src.url" style="height: 1000px"></auth-img>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, nextTick, defineAsyncComponent } from 'vue';
|
import { ref, nextTick, defineAsyncComponent } from 'vue';
|
||||||
const authImg = defineAsyncComponent(() => import('/@/components/tools/auth-img.vue'))
|
const authImg = defineAsyncComponent(() => import('/@/components/tools/auth-img.vue'));
|
||||||
|
|
||||||
interface ImageItem {
|
interface ImageItem {
|
||||||
title: string
|
title: string;
|
||||||
url: string
|
url: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 响应式数据
|
// 响应式数据
|
||||||
const visible = ref(false)
|
const visible = ref(false);
|
||||||
const row = ref<any>({})
|
const row = ref<any>({});
|
||||||
const pdfSrc = ref('')
|
const pdfSrc = ref('');
|
||||||
const imgUrl = ref<ImageItem[]>([])
|
const imgUrl = ref<ImageItem[]>([]);
|
||||||
|
|
||||||
// 方法(保留以备将来使用)
|
// 方法(保留以备将来使用)
|
||||||
// const checkIsImg = (url: string) => {
|
// const checkIsImg = (url: string) => {
|
||||||
// if ((url.indexOf('.jpg') == -1)
|
// if ((url.indexOf('.jpg') == -1)
|
||||||
// && (url.indexOf('.jpeg') == -1)
|
// && (url.indexOf('.jpeg') == -1)
|
||||||
// && (url.indexOf('.png') == -1)
|
// && (url.indexOf('.png') == -1)
|
||||||
// && (url.indexOf('.JPG') == -1)
|
// && (url.indexOf('.JPG') == -1)
|
||||||
// && (url.indexOf('.JPEG') == -1)
|
// && (url.indexOf('.JPEG') == -1)
|
||||||
// && (url.indexOf('.PNG') == -1)) {
|
// && (url.indexOf('.PNG') == -1)) {
|
||||||
// return false
|
// return false
|
||||||
// }
|
// }
|
||||||
// return true
|
// return true
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// const downLoadFileForLook = (fileUrl: string, teacherNo: string) => {
|
// const downLoadFileForLook = (fileUrl: string, teacherNo: string) => {
|
||||||
// const index = fileUrl.indexOf('fileName')
|
// const index = fileUrl.indexOf('fileName')
|
||||||
// const firstIndex = index + 'fileName'.length + 1
|
// const firstIndex = index + 'fileName'.length + 1
|
||||||
// const lastIndex = fileUrl.indexOf('&')
|
// const lastIndex = fileUrl.indexOf('&')
|
||||||
// const fileName = fileUrl.substr(firstIndex, lastIndex - firstIndex)
|
// const fileName = fileUrl.substr(firstIndex, lastIndex - firstIndex)
|
||||||
// pdfSrc.value = "/professional/file/showPdf?fileName=" + fileName + "&type=attachment&teacherNo=" + teacherNo
|
// pdfSrc.value = "/professional/file/showPdf?fileName=" + fileName + "&type=attachment&teacherNo=" + teacherNo
|
||||||
// }
|
// }
|
||||||
|
|
||||||
const init = (rowData: any) => {
|
const init = (rowData: any) => {
|
||||||
row.value = rowData
|
row.value = rowData;
|
||||||
pdfSrc.value = ''
|
pdfSrc.value = '';
|
||||||
imgUrl.value = []
|
imgUrl.value = [];
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
const obj: ImageItem = {
|
const obj: ImageItem = {
|
||||||
title: "",
|
title: '',
|
||||||
url: row.value.attachment
|
url: row.value.attachment,
|
||||||
}
|
};
|
||||||
imgUrl.value.push(obj)
|
imgUrl.value.push(obj);
|
||||||
// if(checkIsImg(rowData.attachment)){
|
// if(checkIsImg(rowData.attachment)){
|
||||||
// const obj: ImageItem = {
|
// const obj: ImageItem = {
|
||||||
// title: "",
|
// title: "",
|
||||||
@@ -59,16 +59,14 @@
|
|||||||
// }else{
|
// }else{
|
||||||
// downLoadFileForLook(rowData.attachment, rowData.teacherNo)
|
// downLoadFileForLook(rowData.attachment, rowData.teacherNo)
|
||||||
// }
|
// }
|
||||||
visible.value = true
|
visible.value = true;
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
// 暴露方法给父组件
|
// 暴露方法给父组件
|
||||||
defineExpose({
|
defineExpose({
|
||||||
init
|
init,
|
||||||
})
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped></style>
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -23,5 +23,4 @@
|
|||||||
// 空组件,保留用于未来扩展
|
// 空组件,保留用于未来扩展
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped></style>
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -5,16 +5,10 @@
|
|||||||
<el-row shadow="hover" v-show="showSearch">
|
<el-row shadow="hover" v-show="showSearch">
|
||||||
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
|
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
|
||||||
<el-form-item label="单位名称" prop="companyName">
|
<el-form-item label="单位名称" prop="companyName">
|
||||||
<el-input
|
<el-input v-model="state.queryForm.companyName" placeholder="请输入单位名称" clearable />
|
||||||
v-model="state.queryForm.companyName"
|
|
||||||
placeholder="请输入单位名称"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button icon="search" type="primary" @click="getDataList">
|
<el-button icon="search" type="primary" @click="getDataList"> 查询 </el-button>
|
||||||
查询
|
|
||||||
</el-button>
|
|
||||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
@@ -22,13 +16,8 @@
|
|||||||
|
|
||||||
<!-- 操作按钮 -->
|
<!-- 操作按钮 -->
|
||||||
<el-row>
|
<el-row>
|
||||||
<div class="mb15" style="width: 100%;">
|
<div class="mb15" style="width: 100%">
|
||||||
<el-button
|
<el-button v-if="hasAuth('professional_outercompany_add')" type="primary" icon="FolderAdd" @click="handleAdd">新 增 </el-button>
|
||||||
v-if="hasAuth('professional_outercompany_add')"
|
|
||||||
type="primary"
|
|
||||||
icon="FolderAdd"
|
|
||||||
@click="handleAdd">新 增
|
|
||||||
</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
@@ -48,9 +37,7 @@
|
|||||||
|
|
||||||
<el-table-column label="允许时段" min-width="250" align="center">
|
<el-table-column label="允许时段" min-width="250" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<span v-if="scope.row.allowStartTime && scope.row.allowEndTime">
|
<span v-if="scope.row.allowStartTime && scope.row.allowEndTime"> {{ scope.row.allowStartTime }} - {{ scope.row.allowEndTime }} </span>
|
||||||
{{ scope.row.allowStartTime }} - {{ scope.row.allowEndTime }}
|
|
||||||
</span>
|
|
||||||
<span v-else>-</span>
|
<span v-else>-</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -59,51 +46,24 @@
|
|||||||
|
|
||||||
<el-table-column label="操作" min-width="150" align="center" fixed="right">
|
<el-table-column label="操作" min-width="150" align="center" fixed="right">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button v-if="hasAuth('professional_outercompany_edit')" icon="edit-pen" link type="primary" @click="handleEdit(scope.row)"
|
||||||
v-if="hasAuth('professional_outercompany_edit')"
|
>修改
|
||||||
icon="edit-pen"
|
|
||||||
link
|
|
||||||
type="primary"
|
|
||||||
@click="handleEdit(scope.row)">修改
|
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button v-if="hasAuth('professional_outercompany_del')" icon="delete" link type="danger" @click="handleDel(scope.row)"
|
||||||
v-if="hasAuth('professional_outercompany_del')"
|
>删除
|
||||||
icon="delete"
|
|
||||||
link
|
|
||||||
type="danger"
|
|
||||||
@click="handleDel(scope.row)">删除
|
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
<pagination
|
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||||
v-bind="state.pagination"
|
|
||||||
@current-change="currentChangeHandle"
|
|
||||||
@size-change="sizeChangeHandle"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 新增/编辑弹窗 -->
|
<!-- 新增/编辑弹窗 -->
|
||||||
<el-dialog
|
<el-dialog v-model="dialogVisible" :title="form.id ? '修改' : '新增'" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||||
v-model="dialogVisible"
|
<el-form ref="formRef" :model="form" :rules="formRules" label-width="120px">
|
||||||
:title="form.id ? '修改' : '新增'"
|
|
||||||
width="600px"
|
|
||||||
:close-on-click-modal="false"
|
|
||||||
destroy-on-close
|
|
||||||
>
|
|
||||||
<el-form
|
|
||||||
ref="formRef"
|
|
||||||
:model="form"
|
|
||||||
:rules="formRules"
|
|
||||||
label-width="120px"
|
|
||||||
>
|
|
||||||
<el-form-item label="单位名称" prop="companyName">
|
<el-form-item label="单位名称" prop="companyName">
|
||||||
<el-input
|
<el-input v-model="form.companyName" placeholder="请输入单位名称" clearable />
|
||||||
v-model="form.companyName"
|
|
||||||
placeholder="请输入单位名称"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="开始时段" prop="allowStartTime">
|
<el-form-item label="开始时段" prop="allowStartTime">
|
||||||
@@ -141,29 +101,29 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive } from 'vue'
|
import { ref, reactive } from 'vue';
|
||||||
import { useAuth } from '/@/hooks/auth'
|
import { useAuth } from '/@/hooks/auth';
|
||||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||||
import { useMessage } from '/@/hooks/message'
|
import { useMessage } from '/@/hooks/message';
|
||||||
import { useMessageBox } from '/@/hooks/message'
|
import { useMessageBox } from '/@/hooks/message';
|
||||||
import { fetchList, addObj, putObj, delObj, getObj } from '/@/api/professional/stayschool/outercompany'
|
import { fetchList, addObj, putObj, delObj, getObj } from '/@/api/professional/stayschool/outercompany';
|
||||||
|
|
||||||
const { hasAuth } = useAuth()
|
const { hasAuth } = useAuth();
|
||||||
// 消息提示 hooks
|
// 消息提示 hooks
|
||||||
const message = useMessage()
|
const message = useMessage();
|
||||||
const messageBox = useMessageBox()
|
const messageBox = useMessageBox();
|
||||||
|
|
||||||
// 表格引用
|
// 表格引用
|
||||||
const tableRef = ref()
|
const tableRef = ref();
|
||||||
const formRef = ref()
|
const formRef = ref();
|
||||||
const queryRef = ref()
|
const queryRef = ref();
|
||||||
|
|
||||||
// 搜索显示
|
// 搜索显示
|
||||||
const showSearch = ref(true)
|
const showSearch = ref(true);
|
||||||
|
|
||||||
// 弹窗状态
|
// 弹窗状态
|
||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false);
|
||||||
const submitLoading = ref(false)
|
const submitLoading = ref(false);
|
||||||
|
|
||||||
// 表单数据
|
// 表单数据
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
@@ -171,42 +131,40 @@ const form = reactive({
|
|||||||
companyName: '',
|
companyName: '',
|
||||||
allowStartTime: '',
|
allowStartTime: '',
|
||||||
allowEndTime: '',
|
allowEndTime: '',
|
||||||
companyType: '0'
|
companyType: '0',
|
||||||
})
|
});
|
||||||
|
|
||||||
// 表单验证规则
|
// 表单验证规则
|
||||||
const formRules = {
|
const formRules = {
|
||||||
companyName: [
|
companyName: [{ required: true, message: '请输入单位名称', trigger: 'blur' }],
|
||||||
{ required: true, message: '请输入单位名称', trigger: 'blur' }
|
};
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
// 配置 useTable
|
// 配置 useTable
|
||||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||||
pageList: async (params: any) => {
|
pageList: async (params: any) => {
|
||||||
const response = await fetchList({
|
const response = await fetchList({
|
||||||
...params,
|
...params,
|
||||||
companyType: '0'
|
companyType: '0',
|
||||||
})
|
});
|
||||||
return {
|
return {
|
||||||
data: {
|
data: {
|
||||||
records: response.data.records || [],
|
records: response.data.records || [],
|
||||||
total: response.data.total || 0
|
total: response.data.total || 0,
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
queryForm: {
|
queryForm: {
|
||||||
companyName: ''
|
companyName: '',
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||||
|
|
||||||
// 重置查询
|
// 重置查询
|
||||||
const resetQuery = () => {
|
const resetQuery = () => {
|
||||||
queryRef.value?.resetFields()
|
queryRef.value?.resetFields();
|
||||||
getDataList()
|
getDataList();
|
||||||
}
|
};
|
||||||
|
|
||||||
// 打开新增窗口
|
// 打开新增窗口
|
||||||
const handleAdd = () => {
|
const handleAdd = () => {
|
||||||
@@ -215,68 +173,70 @@ const handleAdd = () => {
|
|||||||
companyName: '',
|
companyName: '',
|
||||||
allowStartTime: '',
|
allowStartTime: '',
|
||||||
allowEndTime: '',
|
allowEndTime: '',
|
||||||
companyType: '0'
|
companyType: '0',
|
||||||
})
|
});
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 打开编辑窗口
|
// 打开编辑窗口
|
||||||
const handleEdit = async (row: any) => {
|
const handleEdit = async (row: any) => {
|
||||||
try {
|
try {
|
||||||
const response = await getObj(row.id)
|
const response = await getObj(row.id);
|
||||||
Object.assign(form, {
|
Object.assign(form, {
|
||||||
id: response.data.id,
|
id: response.data.id,
|
||||||
companyName: response.data.companyName || '',
|
companyName: response.data.companyName || '',
|
||||||
allowStartTime: response.data.allowStartTime || '',
|
allowStartTime: response.data.allowStartTime || '',
|
||||||
allowEndTime: response.data.allowEndTime || '',
|
allowEndTime: response.data.allowEndTime || '',
|
||||||
companyType: response.data.companyType || '0'
|
companyType: response.data.companyType || '0',
|
||||||
})
|
});
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 获取详情失败
|
// 获取详情失败
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// 删除
|
// 删除
|
||||||
const handleDel = (row: any) => {
|
const handleDel = (row: any) => {
|
||||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
messageBox
|
||||||
await delObj(row.id)
|
.confirm('是否确认删除该条记录')
|
||||||
message.success('删除成功')
|
.then(async () => {
|
||||||
|
await delObj(row.id);
|
||||||
|
message.success('删除成功');
|
||||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||||
state.pagination.current = state.pagination.current - 1
|
state.pagination.current = state.pagination.current - 1;
|
||||||
}
|
}
|
||||||
getDataList()
|
getDataList();
|
||||||
}).catch(() => {})
|
})
|
||||||
}
|
.catch(() => {});
|
||||||
|
};
|
||||||
|
|
||||||
// 提交表单
|
// 提交表单
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
if (!formRef.value) return
|
if (!formRef.value) return;
|
||||||
|
|
||||||
await formRef.value.validate(async (valid: boolean) => {
|
await formRef.value.validate(async (valid: boolean) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
submitLoading.value = true
|
submitLoading.value = true;
|
||||||
try {
|
try {
|
||||||
if (form.id) {
|
if (form.id) {
|
||||||
await putObj(form)
|
await putObj(form);
|
||||||
message.success('修改成功')
|
message.success('修改成功');
|
||||||
} else {
|
} else {
|
||||||
await addObj(form)
|
await addObj(form);
|
||||||
message.success('添加成功')
|
message.success('添加成功');
|
||||||
}
|
}
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false;
|
||||||
getDataList()
|
getDataList();
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
// 处理业务错误
|
// 处理业务错误
|
||||||
message.error(error.msg)
|
message.error(error.msg);
|
||||||
} finally {
|
} finally {
|
||||||
submitLoading.value = false
|
submitLoading.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped></style>
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -5,16 +5,10 @@
|
|||||||
<el-row shadow="hover" v-show="showSearch">
|
<el-row shadow="hover" v-show="showSearch">
|
||||||
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
|
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
|
||||||
<el-form-item label="单位名称" prop="companyName">
|
<el-form-item label="单位名称" prop="companyName">
|
||||||
<el-input
|
<el-input v-model="state.queryForm.companyName" placeholder="请输入单位名称" clearable />
|
||||||
v-model="state.queryForm.companyName"
|
|
||||||
placeholder="请输入单位名称"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button icon="search" type="primary" @click="getDataList">
|
<el-button icon="search" type="primary" @click="getDataList"> 查询 </el-button>
|
||||||
查询
|
|
||||||
</el-button>
|
|
||||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
@@ -22,13 +16,8 @@
|
|||||||
|
|
||||||
<!-- 操作按钮 -->
|
<!-- 操作按钮 -->
|
||||||
<el-row>
|
<el-row>
|
||||||
<div class="mb15" style="width: 100%;">
|
<div class="mb15" style="width: 100%">
|
||||||
<el-button
|
<el-button v-if="hasAuth('professional_outercompany_add')" type="primary" icon="FolderAdd" @click="handleAdd">新 增 </el-button>
|
||||||
v-if="hasAuth('professional_outercompany_add')"
|
|
||||||
type="primary"
|
|
||||||
icon="FolderAdd"
|
|
||||||
@click="handleAdd">新 增
|
|
||||||
</el-button>
|
|
||||||
<!-- <right-toolbar
|
<!-- <right-toolbar
|
||||||
v-model:showSearch="showSearch"
|
v-model:showSearch="showSearch"
|
||||||
class="ml10"
|
class="ml10"
|
||||||
@@ -54,9 +43,7 @@
|
|||||||
|
|
||||||
<el-table-column label="允许时段" min-width="250" align="center">
|
<el-table-column label="允许时段" min-width="250" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<span v-if="scope.row.allowStartTime && scope.row.allowEndTime">
|
<span v-if="scope.row.allowStartTime && scope.row.allowEndTime"> {{ scope.row.allowStartTime }} - {{ scope.row.allowEndTime }} </span>
|
||||||
{{ scope.row.allowStartTime }} - {{ scope.row.allowEndTime }}
|
|
||||||
</span>
|
|
||||||
<span v-else>-</span>
|
<span v-else>-</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -65,51 +52,24 @@
|
|||||||
|
|
||||||
<el-table-column label="操作" min-width="150" align="center" fixed="right">
|
<el-table-column label="操作" min-width="150" align="center" fixed="right">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button v-if="hasAuth('professional_outercompany_edit')" icon="edit-pen" link type="primary" @click="handleEdit(scope.row)"
|
||||||
v-if="hasAuth('professional_outercompany_edit')"
|
>修改
|
||||||
icon="edit-pen"
|
|
||||||
link
|
|
||||||
type="primary"
|
|
||||||
@click="handleEdit(scope.row)">修改
|
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button v-if="hasAuth('professional_outercompany_del')" icon="delete" link type="danger" @click="handleDel(scope.row)"
|
||||||
v-if="hasAuth('professional_outercompany_del')"
|
>删除
|
||||||
icon="delete"
|
|
||||||
link
|
|
||||||
type="danger"
|
|
||||||
@click="handleDel(scope.row)">删除
|
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
<pagination
|
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||||
v-bind="state.pagination"
|
|
||||||
@current-change="currentChangeHandle"
|
|
||||||
@size-change="sizeChangeHandle"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 新增/编辑弹窗 -->
|
<!-- 新增/编辑弹窗 -->
|
||||||
<el-dialog
|
<el-dialog v-model="dialogVisible" :title="form.id ? '修改' : '新增'" width="600px" :close-on-click-modal="false" destroy-on-close>
|
||||||
v-model="dialogVisible"
|
<el-form ref="formRef" :model="form" :rules="formRules" label-width="120px">
|
||||||
:title="form.id ? '修改' : '新增'"
|
|
||||||
width="600px"
|
|
||||||
:close-on-click-modal="false"
|
|
||||||
destroy-on-close
|
|
||||||
>
|
|
||||||
<el-form
|
|
||||||
ref="formRef"
|
|
||||||
:model="form"
|
|
||||||
:rules="formRules"
|
|
||||||
label-width="120px"
|
|
||||||
>
|
|
||||||
<el-form-item label="单位名称" prop="companyName">
|
<el-form-item label="单位名称" prop="companyName">
|
||||||
<el-input
|
<el-input v-model="form.companyName" placeholder="请输入单位名称" clearable />
|
||||||
v-model="form.companyName"
|
|
||||||
placeholder="请输入单位名称"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="开始时段" prop="allowStartTime">
|
<el-form-item label="开始时段" prop="allowStartTime">
|
||||||
@@ -147,29 +107,29 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive } from 'vue'
|
import { ref, reactive } from 'vue';
|
||||||
import { useAuth } from '/@/hooks/auth'
|
import { useAuth } from '/@/hooks/auth';
|
||||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||||
import { useMessage } from '/@/hooks/message'
|
import { useMessage } from '/@/hooks/message';
|
||||||
import { useMessageBox } from '/@/hooks/message'
|
import { useMessageBox } from '/@/hooks/message';
|
||||||
import { fetchList, addObj, putObj, delObj, getObj } from '/@/api/professional/stayschool/outercompany'
|
import { fetchList, addObj, putObj, delObj, getObj } from '/@/api/professional/stayschool/outercompany';
|
||||||
|
|
||||||
const { hasAuth } = useAuth()
|
const { hasAuth } = useAuth();
|
||||||
// 消息提示 hooks
|
// 消息提示 hooks
|
||||||
const message = useMessage()
|
const message = useMessage();
|
||||||
const messageBox = useMessageBox()
|
const messageBox = useMessageBox();
|
||||||
|
|
||||||
// 表格引用
|
// 表格引用
|
||||||
const tableRef = ref()
|
const tableRef = ref();
|
||||||
const formRef = ref()
|
const formRef = ref();
|
||||||
const queryRef = ref()
|
const queryRef = ref();
|
||||||
|
|
||||||
// 搜索显示
|
// 搜索显示
|
||||||
const showSearch = ref(true)
|
const showSearch = ref(true);
|
||||||
|
|
||||||
// 弹窗状态
|
// 弹窗状态
|
||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false);
|
||||||
const submitLoading = ref(false)
|
const submitLoading = ref(false);
|
||||||
|
|
||||||
// 表单数据
|
// 表单数据
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
@@ -177,42 +137,40 @@ const form = reactive({
|
|||||||
companyName: '',
|
companyName: '',
|
||||||
allowStartTime: '',
|
allowStartTime: '',
|
||||||
allowEndTime: '',
|
allowEndTime: '',
|
||||||
companyType: '2'
|
companyType: '2',
|
||||||
})
|
});
|
||||||
|
|
||||||
// 表单验证规则
|
// 表单验证规则
|
||||||
const formRules = {
|
const formRules = {
|
||||||
companyName: [
|
companyName: [{ required: true, message: '请输入单位名称', trigger: 'blur' }],
|
||||||
{ required: true, message: '请输入单位名称', trigger: 'blur' }
|
};
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
// 配置 useTable
|
// 配置 useTable
|
||||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||||
pageList: async (params: any) => {
|
pageList: async (params: any) => {
|
||||||
const response = await fetchList({
|
const response = await fetchList({
|
||||||
...params,
|
...params,
|
||||||
companyType: '2'
|
companyType: '2',
|
||||||
})
|
});
|
||||||
return {
|
return {
|
||||||
data: {
|
data: {
|
||||||
records: response.data.records || [],
|
records: response.data.records || [],
|
||||||
total: response.data.total || 0
|
total: response.data.total || 0,
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
queryForm: {
|
queryForm: {
|
||||||
companyName: ''
|
companyName: '',
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||||
|
|
||||||
// 重置查询
|
// 重置查询
|
||||||
const resetQuery = () => {
|
const resetQuery = () => {
|
||||||
queryRef.value?.resetFields()
|
queryRef.value?.resetFields();
|
||||||
getDataList()
|
getDataList();
|
||||||
}
|
};
|
||||||
|
|
||||||
// 打开新增窗口
|
// 打开新增窗口
|
||||||
const handleAdd = () => {
|
const handleAdd = () => {
|
||||||
@@ -221,68 +179,70 @@ const handleAdd = () => {
|
|||||||
companyName: '',
|
companyName: '',
|
||||||
allowStartTime: '',
|
allowStartTime: '',
|
||||||
allowEndTime: '',
|
allowEndTime: '',
|
||||||
companyType: '2'
|
companyType: '2',
|
||||||
})
|
});
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 打开编辑窗口
|
// 打开编辑窗口
|
||||||
const handleEdit = async (row: any) => {
|
const handleEdit = async (row: any) => {
|
||||||
try {
|
try {
|
||||||
const response = await getObj(row.id)
|
const response = await getObj(row.id);
|
||||||
Object.assign(form, {
|
Object.assign(form, {
|
||||||
id: response.data.id,
|
id: response.data.id,
|
||||||
companyName: response.data.companyName || '',
|
companyName: response.data.companyName || '',
|
||||||
allowStartTime: response.data.allowStartTime || '',
|
allowStartTime: response.data.allowStartTime || '',
|
||||||
allowEndTime: response.data.allowEndTime || '',
|
allowEndTime: response.data.allowEndTime || '',
|
||||||
companyType: response.data.companyType || '2'
|
companyType: response.data.companyType || '2',
|
||||||
})
|
});
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 获取详情失败
|
// 获取详情失败
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// 删除
|
// 删除
|
||||||
const handleDel = (row: any) => {
|
const handleDel = (row: any) => {
|
||||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
messageBox
|
||||||
await delObj(row.id)
|
.confirm('是否确认删除该条记录')
|
||||||
message.success('删除成功')
|
.then(async () => {
|
||||||
|
await delObj(row.id);
|
||||||
|
message.success('删除成功');
|
||||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||||
state.pagination.current = state.pagination.current - 1
|
state.pagination.current = state.pagination.current - 1;
|
||||||
}
|
}
|
||||||
getDataList()
|
getDataList();
|
||||||
}).catch(() => {})
|
})
|
||||||
}
|
.catch(() => {});
|
||||||
|
};
|
||||||
|
|
||||||
// 提交表单
|
// 提交表单
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
if (!formRef.value) return
|
if (!formRef.value) return;
|
||||||
|
|
||||||
await formRef.value.validate(async (valid: boolean) => {
|
await formRef.value.validate(async (valid: boolean) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
submitLoading.value = true
|
submitLoading.value = true;
|
||||||
try {
|
try {
|
||||||
if (form.id) {
|
if (form.id) {
|
||||||
await putObj(form)
|
await putObj(form);
|
||||||
message.success('修改成功')
|
message.success('修改成功');
|
||||||
} else {
|
} else {
|
||||||
await addObj(form)
|
await addObj(form);
|
||||||
message.success('添加成功')
|
message.success('添加成功');
|
||||||
}
|
}
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false;
|
||||||
getDataList()
|
getDataList();
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
// 处理业务错误
|
// 处理业务错误
|
||||||
message.error(error.msg)
|
message.error(error.msg);
|
||||||
} finally {
|
} finally {
|
||||||
submitLoading.value = false
|
submitLoading.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped></style>
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -5,16 +5,10 @@
|
|||||||
<el-row shadow="hover" v-show="showSearch">
|
<el-row shadow="hover" v-show="showSearch">
|
||||||
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
|
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList">
|
||||||
<el-form-item label="单位名称" prop="companyName">
|
<el-form-item label="单位名称" prop="companyName">
|
||||||
<el-input
|
<el-input v-model="state.queryForm.companyName" placeholder="请输入单位名称" clearable />
|
||||||
v-model="state.queryForm.companyName"
|
|
||||||
placeholder="请输入单位名称"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button icon="search" type="primary" @click="getDataList">
|
<el-button icon="search" type="primary" @click="getDataList"> 查询 </el-button>
|
||||||
查询
|
|
||||||
</el-button>
|
|
||||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
@@ -36,9 +30,7 @@
|
|||||||
|
|
||||||
<el-table-column label="允许时段" min-width="250" align="center">
|
<el-table-column label="允许时段" min-width="250" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<span v-if="scope.row.allowStartTime && scope.row.allowEndTime">
|
<span v-if="scope.row.allowStartTime && scope.row.allowEndTime"> {{ scope.row.allowStartTime }} - {{ scope.row.allowEndTime }} </span>
|
||||||
{{ scope.row.allowStartTime }} - {{ scope.row.allowEndTime }}
|
|
||||||
</span>
|
|
||||||
<span v-else>-</span>
|
<span v-else>-</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -68,55 +60,49 @@
|
|||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
<pagination
|
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||||
v-bind="state.pagination"
|
|
||||||
@current-change="currentChangeHandle"
|
|
||||||
@size-change="sizeChangeHandle"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive } from 'vue'
|
import { ref, reactive } from 'vue';
|
||||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||||
import { fetchList } from '/@/api/professional/stayschool/outercompany'
|
import { fetchList } from '/@/api/professional/stayschool/outercompany';
|
||||||
|
|
||||||
|
|
||||||
// 表格引用
|
// 表格引用
|
||||||
const tableRef = ref()
|
const tableRef = ref();
|
||||||
const queryRef = ref()
|
const queryRef = ref();
|
||||||
|
|
||||||
// 搜索显示
|
// 搜索显示
|
||||||
const showSearch = ref(true)
|
const showSearch = ref(true);
|
||||||
|
|
||||||
// 配置 useTable
|
// 配置 useTable
|
||||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||||
pageList: async (params: any) => {
|
pageList: async (params: any) => {
|
||||||
const response = await fetchList({
|
const response = await fetchList({
|
||||||
...params,
|
...params,
|
||||||
companyType: '1'
|
companyType: '1',
|
||||||
})
|
});
|
||||||
return {
|
return {
|
||||||
data: {
|
data: {
|
||||||
records: response.data.records || [],
|
records: response.data.records || [],
|
||||||
total: response.data.total || 0
|
total: response.data.total || 0,
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
queryForm: {
|
queryForm: {
|
||||||
companyName: ''
|
companyName: '',
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||||
|
|
||||||
// 重置查询
|
// 重置查询
|
||||||
const resetQuery = () => {
|
const resetQuery = () => {
|
||||||
queryRef.value?.resetFields()
|
queryRef.value?.resetFields();
|
||||||
getDataList()
|
getDataList();
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped></style>
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -7,39 +7,18 @@
|
|||||||
destroy-on-close
|
destroy-on-close
|
||||||
@close="handleClose"
|
@close="handleClose"
|
||||||
>
|
>
|
||||||
<el-form
|
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px" class="form-content">
|
||||||
ref="formRef"
|
|
||||||
:model="formData"
|
|
||||||
:rules="formRules"
|
|
||||||
label-width="100px"
|
|
||||||
class="form-content"
|
|
||||||
>
|
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="单位名称" prop="companyId">
|
<el-form-item label="单位名称" prop="companyId">
|
||||||
<el-select
|
<el-select v-model="formData.companyId" filterable clearable placeholder="请选择单位">
|
||||||
v-model="formData.companyId"
|
<el-option v-for="item in companyList" :key="item.id" :label="item.companyName" :value="item.id" />
|
||||||
filterable
|
|
||||||
clearable
|
|
||||||
placeholder="请选择单位"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in companyList"
|
|
||||||
:key="item.id"
|
|
||||||
:label="item.companyName"
|
|
||||||
:value="item.id"
|
|
||||||
/>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="职员编号" prop="employeeNo">
|
<el-form-item label="职员编号" prop="employeeNo">
|
||||||
<el-input
|
<el-input v-model="formData.employeeNo" placeholder="系统自动生成" disabled clearable />
|
||||||
v-model="formData.employeeNo"
|
|
||||||
placeholder="系统自动生成"
|
|
||||||
disabled
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@@ -47,22 +26,12 @@
|
|||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="姓名" prop="realName">
|
<el-form-item label="姓名" prop="realName">
|
||||||
<el-input
|
<el-input v-model="formData.realName" placeholder="请输入姓名" clearable />
|
||||||
v-model="formData.realName"
|
|
||||||
placeholder="请输入姓名"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="身份证" prop="idCard">
|
<el-form-item label="身份证" prop="idCard">
|
||||||
<el-input
|
<el-input v-model="formData.idCard" placeholder="请输入身份证号" clearable maxlength="18" @input="handleIdCardInput" />
|
||||||
v-model="formData.idCard"
|
|
||||||
placeholder="请输入身份证号"
|
|
||||||
clearable
|
|
||||||
maxlength="18"
|
|
||||||
@input="handleIdCardInput"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@@ -70,22 +39,12 @@
|
|||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="手机" prop="mobile">
|
<el-form-item label="手机" prop="mobile">
|
||||||
<el-input
|
<el-input v-model="formData.mobile" type="number" placeholder="请输入手机号" clearable maxlength="11" />
|
||||||
v-model="formData.mobile"
|
|
||||||
type="number"
|
|
||||||
placeholder="请输入手机号"
|
|
||||||
clearable
|
|
||||||
maxlength="11"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="职位" prop="position">
|
<el-form-item label="职位" prop="position">
|
||||||
<el-input
|
<el-input v-model="formData.position" placeholder="请输入职位" clearable />
|
||||||
v-model="formData.position"
|
|
||||||
placeholder="请输入职位"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@@ -93,39 +52,20 @@
|
|||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="家庭地址" prop="address">
|
<el-form-item label="家庭地址" prop="address">
|
||||||
<el-input
|
<el-input v-model="formData.address" placeholder="请输入家庭地址" clearable />
|
||||||
v-model="formData.address"
|
|
||||||
placeholder="请输入家庭地址"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="允许进出" prop="inoutFlag">
|
<el-form-item label="允许进出" prop="inoutFlag">
|
||||||
<el-select
|
<el-select v-model="formData.inoutFlag" clearable placeholder="请选择">
|
||||||
v-model="formData.inoutFlag"
|
<el-option v-for="item in yesNoDict" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
clearable
|
|
||||||
placeholder="请选择"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in yesNoDict"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-form-item label="备注" prop="remarks">
|
<el-form-item label="备注" prop="remarks">
|
||||||
<el-input
|
<el-input v-model="formData.remarks" type="textarea" :rows="3" placeholder="请输入备注" clearable />
|
||||||
v-model="formData.remarks"
|
|
||||||
type="textarea"
|
|
||||||
:rows="3"
|
|
||||||
placeholder="请输入备注"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
@@ -139,29 +79,29 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, watch } from 'vue'
|
import { ref, watch } from 'vue';
|
||||||
import { useDict } from '/@/hooks/dict'
|
import { useDict } from '/@/hooks/dict';
|
||||||
import { useMessage } from '/@/hooks/message'
|
import { useMessage } from '/@/hooks/message';
|
||||||
import { addObj, putObj } from '/@/api/professional/stayschool/outercompanyemployee'
|
import { addObj, putObj } from '/@/api/professional/stayschool/outercompanyemployee';
|
||||||
|
|
||||||
// Props
|
// Props
|
||||||
interface Props {
|
interface Props {
|
||||||
modelValue: boolean
|
modelValue: boolean;
|
||||||
formData: {
|
formData: {
|
||||||
id?: string
|
id?: string;
|
||||||
companyId?: string
|
companyId?: string;
|
||||||
companyName?: string
|
companyName?: string;
|
||||||
employeeNo?: string
|
employeeNo?: string;
|
||||||
realName?: string
|
realName?: string;
|
||||||
idCard?: string
|
idCard?: string;
|
||||||
mobile?: string
|
mobile?: string;
|
||||||
position?: string
|
position?: string;
|
||||||
address?: string
|
address?: string;
|
||||||
inoutFlag?: string
|
inoutFlag?: string;
|
||||||
remarks?: string
|
remarks?: string;
|
||||||
}
|
};
|
||||||
companyList: any[]
|
companyList: any[];
|
||||||
saveApi?: (data: any) => Promise<any> // 自定义保存 API 函数(用于培训单位、二期单位等)
|
saveApi?: (data: any) => Promise<any>; // 自定义保存 API 函数(用于培训单位、二期单位等)
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
@@ -177,118 +117,113 @@ const props = withDefaults(defineProps<Props>(), {
|
|||||||
position: '',
|
position: '',
|
||||||
address: '',
|
address: '',
|
||||||
inoutFlag: '',
|
inoutFlag: '',
|
||||||
remarks: ''
|
remarks: '',
|
||||||
}),
|
}),
|
||||||
companyList: () => [],
|
companyList: () => [],
|
||||||
saveApi: undefined
|
saveApi: undefined,
|
||||||
})
|
});
|
||||||
|
|
||||||
// Emits
|
// Emits
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'update:modelValue', value: boolean): void
|
(e: 'update:modelValue', value: boolean): void;
|
||||||
(e: 'success'): void
|
(e: 'success'): void;
|
||||||
}>()
|
}>();
|
||||||
|
|
||||||
// 字典数据
|
// 字典数据
|
||||||
const { yes_no_type: yesNoDict } = useDict('yes_no_type')
|
const { yes_no_type: yesNoDict } = useDict('yes_no_type');
|
||||||
|
|
||||||
// 消息提示
|
// 消息提示
|
||||||
const message = useMessage()
|
const message = useMessage();
|
||||||
|
|
||||||
// 表单引用
|
// 表单引用
|
||||||
const formRef = ref()
|
const formRef = ref();
|
||||||
|
|
||||||
// 提交加载状态
|
// 提交加载状态
|
||||||
const submitLoading = ref(false)
|
const submitLoading = ref(false);
|
||||||
|
|
||||||
// 弹窗显示状态
|
// 弹窗显示状态
|
||||||
const visible = ref(false)
|
const visible = ref(false);
|
||||||
|
|
||||||
watch(() => props.modelValue, (val) => {
|
watch(
|
||||||
visible.value = val
|
() => props.modelValue,
|
||||||
})
|
(val) => {
|
||||||
|
visible.value = val;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
watch(visible, (val) => {
|
watch(visible, (val) => {
|
||||||
emit('update:modelValue', val)
|
emit('update:modelValue', val);
|
||||||
})
|
});
|
||||||
|
|
||||||
// 表单验证规则
|
// 表单验证规则
|
||||||
const formRules = {
|
const formRules = {
|
||||||
companyId: [
|
companyId: [{ required: true, message: '请选择单位', trigger: 'change' }],
|
||||||
{ required: true, message: '请选择单位', trigger: 'change' }
|
realName: [{ required: true, message: '请填写姓名', trigger: 'blur' }],
|
||||||
],
|
|
||||||
realName: [
|
|
||||||
{ required: true, message: '请填写姓名', trigger: 'blur' }
|
|
||||||
],
|
|
||||||
idCard: [
|
idCard: [
|
||||||
{ required: true, message: '请输入正确身份证', trigger: 'blur' },
|
{ required: true, message: '请输入正确身份证', trigger: 'blur' },
|
||||||
{ min: 15, max: 18, message: '长度在 15 到 18 个字符', trigger: 'blur' },
|
{ min: 15, max: 18, message: '长度在 15 到 18 个字符', trigger: 'blur' },
|
||||||
{ pattern: /^(\d{15}|\d{17}[\dXx])$/, message: '身份证号格式不正确', trigger: 'blur' }
|
{ pattern: /^(\d{15}|\d{17}[\dXx])$/, message: '身份证号格式不正确', trigger: 'blur' },
|
||||||
],
|
],
|
||||||
mobile: [
|
mobile: [
|
||||||
{ required: true, message: '请填写手机号', trigger: 'blur' },
|
{ required: true, message: '请填写手机号', trigger: 'blur' },
|
||||||
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' }
|
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' },
|
||||||
],
|
],
|
||||||
address: [
|
address: [{ required: true, message: '请填写家庭住址', trigger: 'blur' }],
|
||||||
{ required: true, message: '请填写家庭住址', trigger: 'blur' }
|
inoutFlag: [{ required: true, message: '请选择是否允许进出', trigger: 'change' }],
|
||||||
],
|
};
|
||||||
inoutFlag: [
|
|
||||||
{ required: true, message: '请选择是否允许进出', trigger: 'change' }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
// 关闭弹窗
|
// 关闭弹窗
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
visible.value = false
|
visible.value = false;
|
||||||
formRef.value?.resetFields()
|
formRef.value?.resetFields();
|
||||||
}
|
};
|
||||||
|
|
||||||
// 身份证号输入限制:只允许数字和X/x,最大长度18
|
// 身份证号输入限制:只允许数字和X/x,最大长度18
|
||||||
const handleIdCardInput = (value: string) => {
|
const handleIdCardInput = (value: string) => {
|
||||||
// 只保留数字和X/x
|
// 只保留数字和X/x
|
||||||
const filtered = value.replace(/[^\dXx]/g, '')
|
const filtered = value.replace(/[^\dXx]/g, '');
|
||||||
if (filtered !== value) {
|
if (filtered !== value) {
|
||||||
props.formData.idCard = filtered
|
props.formData.idCard = filtered;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// 提交表单
|
// 提交表单
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
if (!formRef.value) return
|
if (!formRef.value) return;
|
||||||
|
|
||||||
await formRef.value.validate(async (valid: boolean) => {
|
await formRef.value.validate(async (valid: boolean) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
submitLoading.value = true
|
submitLoading.value = true;
|
||||||
try {
|
try {
|
||||||
// 设置单位名称
|
// 设置单位名称
|
||||||
const selectedCompany = props.companyList.find(item => item.id === props.formData.companyId)
|
const selectedCompany = props.companyList.find((item) => item.id === props.formData.companyId);
|
||||||
const submitData = {
|
const submitData = {
|
||||||
...props.formData,
|
...props.formData,
|
||||||
companyName: selectedCompany?.companyName || ''
|
companyName: selectedCompany?.companyName || '',
|
||||||
}
|
};
|
||||||
|
|
||||||
if (props.formData.id) {
|
if (props.formData.id) {
|
||||||
await putObj(submitData)
|
await putObj(submitData);
|
||||||
message.success('修改成功')
|
message.success('修改成功');
|
||||||
} else {
|
} else {
|
||||||
// 如果提供了自定义保存函数,使用它;否则使用默认的 addObj
|
// 如果提供了自定义保存函数,使用它;否则使用默认的 addObj
|
||||||
if (props.saveApi) {
|
if (props.saveApi) {
|
||||||
await props.saveApi(submitData)
|
await props.saveApi(submitData);
|
||||||
} else {
|
} else {
|
||||||
await addObj(submitData)
|
await addObj(submitData);
|
||||||
}
|
}
|
||||||
message.success('添加成功')
|
message.success('添加成功');
|
||||||
}
|
}
|
||||||
handleClose()
|
handleClose();
|
||||||
emit('success')
|
emit('success');
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
message.error(error?.msg || '操作失败')
|
message.error(error?.msg || '操作失败');
|
||||||
} finally {
|
} finally {
|
||||||
submitLoading.value = false
|
submitLoading.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@@ -306,4 +241,3 @@ const handleSubmit = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -7,39 +7,18 @@
|
|||||||
destroy-on-close
|
destroy-on-close
|
||||||
@close="handleClose"
|
@close="handleClose"
|
||||||
>
|
>
|
||||||
<el-form
|
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px" class="form-content">
|
||||||
ref="formRef"
|
|
||||||
:model="formData"
|
|
||||||
:rules="formRules"
|
|
||||||
label-width="100px"
|
|
||||||
class="form-content"
|
|
||||||
>
|
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="班级名称" prop="companyId">
|
<el-form-item label="班级名称" prop="companyId">
|
||||||
<el-select
|
<el-select v-model="formData.companyId" filterable clearable placeholder="请选择班级">
|
||||||
v-model="formData.companyId"
|
<el-option v-for="item in companyList" :key="item.id" :label="item.companyName" :value="item.id" />
|
||||||
filterable
|
|
||||||
clearable
|
|
||||||
placeholder="请选择班级"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in companyList"
|
|
||||||
:key="item.id"
|
|
||||||
:label="item.companyName"
|
|
||||||
:value="item.id"
|
|
||||||
/>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="学员编号" prop="employeeNo">
|
<el-form-item label="学员编号" prop="employeeNo">
|
||||||
<el-input
|
<el-input v-model="formData.employeeNo" placeholder="系统自动生成" disabled clearable />
|
||||||
v-model="formData.employeeNo"
|
|
||||||
placeholder="系统自动生成"
|
|
||||||
disabled
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@@ -47,22 +26,12 @@
|
|||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="姓名" prop="realName">
|
<el-form-item label="姓名" prop="realName">
|
||||||
<el-input
|
<el-input v-model="formData.realName" placeholder="请输入姓名" clearable />
|
||||||
v-model="formData.realName"
|
|
||||||
placeholder="请输入姓名"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="身份证" prop="idCard">
|
<el-form-item label="身份证" prop="idCard">
|
||||||
<el-input
|
<el-input v-model="formData.idCard" placeholder="请输入身份证号" clearable maxlength="18" @input="handleIdCardInput" />
|
||||||
v-model="formData.idCard"
|
|
||||||
placeholder="请输入身份证号"
|
|
||||||
clearable
|
|
||||||
maxlength="18"
|
|
||||||
@input="handleIdCardInput"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@@ -70,41 +39,20 @@
|
|||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="手机" prop="mobile">
|
<el-form-item label="手机" prop="mobile">
|
||||||
<el-input
|
<el-input v-model="formData.mobile" type="number" placeholder="请输入手机号" clearable maxlength="11" />
|
||||||
v-model="formData.mobile"
|
|
||||||
type="number"
|
|
||||||
placeholder="请输入手机号"
|
|
||||||
clearable
|
|
||||||
maxlength="11"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="允许进出" prop="inoutFlag">
|
<el-form-item label="允许进出" prop="inoutFlag">
|
||||||
<el-select
|
<el-select v-model="formData.inoutFlag" clearable placeholder="请选择">
|
||||||
v-model="formData.inoutFlag"
|
<el-option v-for="item in yesNoDict" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
clearable
|
|
||||||
placeholder="请选择"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in yesNoDict"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-form-item label="备注" prop="remarks">
|
<el-form-item label="备注" prop="remarks">
|
||||||
<el-input
|
<el-input v-model="formData.remarks" type="textarea" :rows="3" placeholder="请输入备注" clearable />
|
||||||
v-model="formData.remarks"
|
|
||||||
type="textarea"
|
|
||||||
:rows="3"
|
|
||||||
placeholder="请输入备注"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
@@ -118,27 +66,27 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, watch } from 'vue'
|
import { ref, watch } from 'vue';
|
||||||
import { useDict } from '/@/hooks/dict'
|
import { useDict } from '/@/hooks/dict';
|
||||||
import { useMessage } from '/@/hooks/message'
|
import { useMessage } from '/@/hooks/message';
|
||||||
import { putObj } from '/@/api/professional/stayschool/outercompanyemployee'
|
import { putObj } from '/@/api/professional/stayschool/outercompanyemployee';
|
||||||
|
|
||||||
// Props
|
// Props
|
||||||
interface Props {
|
interface Props {
|
||||||
modelValue: boolean
|
modelValue: boolean;
|
||||||
formData: {
|
formData: {
|
||||||
id?: string
|
id?: string;
|
||||||
companyId?: string
|
companyId?: string;
|
||||||
companyName?: string
|
companyName?: string;
|
||||||
employeeNo?: string
|
employeeNo?: string;
|
||||||
realName?: string
|
realName?: string;
|
||||||
idCard?: string
|
idCard?: string;
|
||||||
mobile?: string
|
mobile?: string;
|
||||||
inoutFlag?: string
|
inoutFlag?: string;
|
||||||
remarks?: string
|
remarks?: string;
|
||||||
}
|
};
|
||||||
companyList: any[]
|
companyList: any[];
|
||||||
saveApi?: (data: any) => Promise<any> // 自定义保存 API 函数
|
saveApi?: (data: any) => Promise<any>; // 自定义保存 API 函数
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
@@ -152,116 +100,113 @@ const props = withDefaults(defineProps<Props>(), {
|
|||||||
idCard: '',
|
idCard: '',
|
||||||
mobile: '',
|
mobile: '',
|
||||||
inoutFlag: '',
|
inoutFlag: '',
|
||||||
remarks: ''
|
remarks: '',
|
||||||
}),
|
}),
|
||||||
companyList: () => [],
|
companyList: () => [],
|
||||||
saveApi: undefined
|
saveApi: undefined,
|
||||||
})
|
});
|
||||||
|
|
||||||
// Emits
|
// Emits
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'update:modelValue', value: boolean): void
|
(e: 'update:modelValue', value: boolean): void;
|
||||||
(e: 'success'): void
|
(e: 'success'): void;
|
||||||
}>()
|
}>();
|
||||||
|
|
||||||
// 字典数据
|
// 字典数据
|
||||||
const { yes_no_type: yesNoDict } = useDict('yes_no_type')
|
const { yes_no_type: yesNoDict } = useDict('yes_no_type');
|
||||||
|
|
||||||
// 消息提示
|
// 消息提示
|
||||||
const message = useMessage()
|
const message = useMessage();
|
||||||
|
|
||||||
// 表单引用
|
// 表单引用
|
||||||
const formRef = ref()
|
const formRef = ref();
|
||||||
|
|
||||||
// 提交加载状态
|
// 提交加载状态
|
||||||
const submitLoading = ref(false)
|
const submitLoading = ref(false);
|
||||||
|
|
||||||
// 弹窗显示状态
|
// 弹窗显示状态
|
||||||
const visible = ref(false)
|
const visible = ref(false);
|
||||||
|
|
||||||
watch(() => props.modelValue, (val) => {
|
watch(
|
||||||
visible.value = val
|
() => props.modelValue,
|
||||||
})
|
(val) => {
|
||||||
|
visible.value = val;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
watch(visible, (val) => {
|
watch(visible, (val) => {
|
||||||
emit('update:modelValue', val)
|
emit('update:modelValue', val);
|
||||||
})
|
});
|
||||||
|
|
||||||
// 表单验证规则
|
// 表单验证规则
|
||||||
const formRules = {
|
const formRules = {
|
||||||
companyId: [
|
companyId: [{ required: true, message: '请选择班级', trigger: 'change' }],
|
||||||
{ required: true, message: '请选择班级', trigger: 'change' }
|
realName: [{ required: true, message: '请填写姓名', trigger: 'blur' }],
|
||||||
],
|
|
||||||
realName: [
|
|
||||||
{ required: true, message: '请填写姓名', trigger: 'blur' }
|
|
||||||
],
|
|
||||||
idCard: [
|
idCard: [
|
||||||
{ required: true, message: '请输入正确身份证', trigger: 'blur' },
|
{ required: true, message: '请输入正确身份证', trigger: 'blur' },
|
||||||
{ min: 15, max: 18, message: '长度在 15 到 18 个字符', trigger: 'blur' },
|
{ min: 15, max: 18, message: '长度在 15 到 18 个字符', trigger: 'blur' },
|
||||||
{ pattern: /^(\d{15}|\d{17}[\dXx])$/, message: '身份证号格式不正确', trigger: 'blur' }
|
{ pattern: /^(\d{15}|\d{17}[\dXx])$/, message: '身份证号格式不正确', trigger: 'blur' },
|
||||||
],
|
],
|
||||||
mobile: [
|
mobile: [
|
||||||
{ required: true, message: '请填写手机号', trigger: 'blur' },
|
{ required: true, message: '请填写手机号', trigger: 'blur' },
|
||||||
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' }
|
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' },
|
||||||
],
|
],
|
||||||
inoutFlag: [
|
inoutFlag: [{ required: true, message: '请选择是否允许进出', trigger: 'change' }],
|
||||||
{ required: true, message: '请选择是否允许进出', trigger: 'change' }
|
};
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
// 关闭弹窗
|
// 关闭弹窗
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
visible.value = false
|
visible.value = false;
|
||||||
formRef.value?.resetFields()
|
formRef.value?.resetFields();
|
||||||
}
|
};
|
||||||
|
|
||||||
// 身份证号输入限制:只允许数字和X/x,最大长度18
|
// 身份证号输入限制:只允许数字和X/x,最大长度18
|
||||||
const handleIdCardInput = (value: string) => {
|
const handleIdCardInput = (value: string) => {
|
||||||
// 只保留数字和X/x
|
// 只保留数字和X/x
|
||||||
const filtered = value.replace(/[^\dXx]/g, '')
|
const filtered = value.replace(/[^\dXx]/g, '');
|
||||||
if (filtered !== value) {
|
if (filtered !== value) {
|
||||||
props.formData.idCard = filtered
|
props.formData.idCard = filtered;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// 提交表单
|
// 提交表单
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
if (!formRef.value) return
|
if (!formRef.value) return;
|
||||||
|
|
||||||
await formRef.value.validate(async (valid: boolean) => {
|
await formRef.value.validate(async (valid: boolean) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
submitLoading.value = true
|
submitLoading.value = true;
|
||||||
try {
|
try {
|
||||||
// 设置班级名称
|
// 设置班级名称
|
||||||
const selectedCompany = props.companyList.find(item => item.id === props.formData.companyId)
|
const selectedCompany = props.companyList.find((item) => item.id === props.formData.companyId);
|
||||||
const submitData = {
|
const submitData = {
|
||||||
...props.formData,
|
...props.formData,
|
||||||
companyName: selectedCompany?.companyName || ''
|
companyName: selectedCompany?.companyName || '',
|
||||||
}
|
};
|
||||||
|
|
||||||
if (props.formData.id) {
|
if (props.formData.id) {
|
||||||
await putObj(submitData)
|
await putObj(submitData);
|
||||||
message.success('修改成功')
|
message.success('修改成功');
|
||||||
} else {
|
} else {
|
||||||
// 使用自定义保存函数
|
// 使用自定义保存函数
|
||||||
if (props.saveApi) {
|
if (props.saveApi) {
|
||||||
await props.saveApi(submitData)
|
await props.saveApi(submitData);
|
||||||
} else {
|
} else {
|
||||||
message.error('请提供保存 API 函数')
|
message.error('请提供保存 API 函数');
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
message.success('添加成功')
|
message.success('添加成功');
|
||||||
}
|
}
|
||||||
handleClose()
|
handleClose();
|
||||||
emit('success')
|
emit('success');
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
message.error(error?.msg || '操作失败')
|
message.error(error?.msg || '操作失败');
|
||||||
} finally {
|
} finally {
|
||||||
submitLoading.value = false
|
submitLoading.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@@ -279,4 +224,3 @@ const handleSubmit = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -5,60 +5,25 @@
|
|||||||
<el-row shadow="hover" v-show="showSearch">
|
<el-row shadow="hover" v-show="showSearch">
|
||||||
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="handleFilter">
|
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="handleFilter">
|
||||||
<el-form-item label="单位名称" prop="companyId">
|
<el-form-item label="单位名称" prop="companyId">
|
||||||
<el-select
|
<el-select v-model="state.queryForm.companyId" filterable clearable placeholder="请选择单位">
|
||||||
v-model="state.queryForm.companyId"
|
<el-option v-for="item in companyList" :key="item.id" :label="item.companyName" :value="item.id" />
|
||||||
filterable
|
|
||||||
clearable
|
|
||||||
placeholder="请选择单位"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in companyList"
|
|
||||||
:key="item.id"
|
|
||||||
:label="item.companyName"
|
|
||||||
:value="item.id"
|
|
||||||
/>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="职员编号" prop="employeeNo">
|
<el-form-item label="职员编号" prop="employeeNo">
|
||||||
<el-input
|
<el-input v-model="state.queryForm.employeeNo" placeholder="请输入职员编号" clearable />
|
||||||
v-model="state.queryForm.employeeNo"
|
|
||||||
placeholder="请输入职员编号"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="姓名" prop="realName">
|
<el-form-item label="姓名" prop="realName">
|
||||||
<el-input
|
<el-input v-model="state.queryForm.realName" placeholder="请输入姓名" clearable />
|
||||||
v-model="state.queryForm.realName"
|
|
||||||
placeholder="请输入姓名"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="身份证" prop="idCard">
|
<el-form-item label="身份证" prop="idCard">
|
||||||
<el-input
|
<el-input v-model="state.queryForm.idCard" placeholder="请输入身份证" clearable />
|
||||||
v-model="state.queryForm.idCard"
|
|
||||||
placeholder="请输入身份证"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="手机" prop="mobile">
|
<el-form-item label="手机" prop="mobile">
|
||||||
<el-input
|
<el-input v-model="state.queryForm.mobile" placeholder="请输入手机" clearable />
|
||||||
v-model="state.queryForm.mobile"
|
|
||||||
placeholder="请输入手机"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="允许进出" prop="inoutFlag">
|
<el-form-item label="允许进出" prop="inoutFlag">
|
||||||
<el-select
|
<el-select v-model="state.queryForm.inoutFlag" clearable placeholder="请选择">
|
||||||
v-model="state.queryForm.inoutFlag"
|
<el-option v-for="item in yesNoDict" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
clearable
|
|
||||||
placeholder="请选择"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in yesNoDict"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
@@ -71,21 +36,8 @@
|
|||||||
<!-- 操作按钮 -->
|
<!-- 操作按钮 -->
|
||||||
<el-row>
|
<el-row>
|
||||||
<div class="mb15">
|
<div class="mb15">
|
||||||
<el-button
|
<el-button v-if="hasAuth('professional_outercompanyemployee_add')" type="primary" icon="FolderAdd" @click="handleAdd">新 增 </el-button>
|
||||||
v-if="hasAuth('professional_outercompanyemployee_add')"
|
<el-button type="primary" plain icon="UploadFilled" class="ml10" @click="handleExportIn" v-if="permission.scope == '1'">导 入 </el-button>
|
||||||
type="primary"
|
|
||||||
icon="FolderAdd"
|
|
||||||
@click="handleAdd">新 增
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
plain
|
|
||||||
icon="UploadFilled"
|
|
||||||
class="ml10"
|
|
||||||
@click="handleExportIn"
|
|
||||||
v-if="permission.scope == '1'"
|
|
||||||
>导 入
|
|
||||||
</el-button>
|
|
||||||
<!-- <el-button
|
<!-- <el-button
|
||||||
type="warning"
|
type="warning"
|
||||||
plain
|
plain
|
||||||
@@ -130,10 +82,7 @@
|
|||||||
|
|
||||||
<el-table-column prop="inoutFlag" label="允许进出" width="100" align="center">
|
<el-table-column prop="inoutFlag" label="允许进出" width="100" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tag
|
<el-tag v-if="scope.row.inoutFlag" :type="scope.row.inoutFlag === '1' ? 'success' : 'danger'">
|
||||||
v-if="scope.row.inoutFlag"
|
|
||||||
:type="scope.row.inoutFlag === '1' ? 'success' : 'danger'"
|
|
||||||
>
|
|
||||||
{{ getDictLabel(scope.row.inoutFlag) }}
|
{{ getDictLabel(scope.row.inoutFlag) }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
<span v-else>-</span>
|
<span v-else>-</span>
|
||||||
@@ -142,14 +91,7 @@
|
|||||||
|
|
||||||
<el-table-column label="头像" width="100" align="center">
|
<el-table-column label="头像" width="100" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button type="primary" link icon="Picture" @click="handlePictureCardPreview(scope.row.employeeNo)"> 查看 </el-button>
|
||||||
type="primary"
|
|
||||||
link
|
|
||||||
icon="Picture"
|
|
||||||
@click="handlePictureCardPreview(scope.row.employeeNo)"
|
|
||||||
>
|
|
||||||
查看
|
|
||||||
</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
@@ -157,19 +99,16 @@
|
|||||||
|
|
||||||
<el-table-column label="操作" width="250" align="center" fixed="right">
|
<el-table-column label="操作" width="250" align="center" fixed="right">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button v-if="hasAuth('professional_outercompanyemployee_edit')" icon="edit-pen" link type="primary" @click="handleEdit(scope.row)"
|
||||||
v-if="hasAuth('professional_outercompanyemployee_edit')"
|
>修改
|
||||||
icon="edit-pen"
|
|
||||||
link
|
|
||||||
type="primary"
|
|
||||||
@click="handleEdit(scope.row)">修改
|
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
v-if="hasAuth('professional_outercompanyemployee_reset_pw')"
|
v-if="hasAuth('professional_outercompanyemployee_reset_pw')"
|
||||||
icon="RefreshLeft"
|
icon="RefreshLeft"
|
||||||
link
|
link
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="resetPassword(scope.row)">重置密码
|
@click="resetPassword(scope.row)"
|
||||||
|
>重置密码
|
||||||
</el-button>
|
</el-button>
|
||||||
<!-- <el-button
|
<!-- <el-button
|
||||||
v-if="hasAuth('professional_outercompanyemployee_del')"
|
v-if="hasAuth('professional_outercompanyemployee_del')"
|
||||||
@@ -183,23 +122,14 @@
|
|||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
<pagination
|
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||||
v-bind="state.pagination"
|
|
||||||
@current-change="currentChangeHandle"
|
|
||||||
@size-change="sizeChangeHandle"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 新增/编辑弹窗 -->
|
<!-- 新增/编辑弹窗 -->
|
||||||
<form-dialog
|
<form-dialog v-model="dialogVisible" :form-data="form" :company-list="companyList" @success="handleFormSuccess" />
|
||||||
v-model="dialogVisible"
|
|
||||||
:form-data="form"
|
|
||||||
:company-list="companyList"
|
|
||||||
@success="handleFormSuccess"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 头像预览对话框 -->
|
<!-- 头像预览对话框 -->
|
||||||
<el-dialog v-model="dialogUploadVisible" title="头像预览" append-to-body>
|
<el-dialog v-model="dialogUploadVisible" title="头像预览" append-to-body>
|
||||||
<img width="100%" :src="dialogImageUrl" alt="" style="max-height: 600px; object-fit: contain;" />
|
<img width="100%" :src="dialogImageUrl" alt="" style="max-height: 600px; object-fit: contain" />
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<!-- 导入对话框 -->
|
<!-- 导入对话框 -->
|
||||||
@@ -236,64 +166,58 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, onMounted } from 'vue'
|
import { ref, reactive, onMounted } from 'vue';
|
||||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||||
import { useAuth } from '/@/hooks/auth'
|
import { useAuth } from '/@/hooks/auth';
|
||||||
import { useMessage } from '/@/hooks/message'
|
import { useMessage } from '/@/hooks/message';
|
||||||
import { useMessageBox } from '/@/hooks/message'
|
import { useMessageBox } from '/@/hooks/message';
|
||||||
import { useDict } from '/@/hooks/dict'
|
import { useDict } from '/@/hooks/dict';
|
||||||
import { validateNull } from '/@/utils/validate'
|
import { validateNull } from '/@/utils/validate';
|
||||||
import axios from 'axios'
|
import axios from 'axios';
|
||||||
import request from '/@/utils/request'
|
import request from '/@/utils/request';
|
||||||
import {
|
import { fetchList, getObj, delObj, batchDel, resetPassWord } from '/@/api/professional/stayschool/outercompanyemployee';
|
||||||
fetchList,
|
import { getList as getCompanyList } from '/@/api/professional/stayschool/outercompany';
|
||||||
getObj,
|
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
|
||||||
delObj,
|
|
||||||
batchDel,
|
|
||||||
resetPassWord
|
|
||||||
} from '/@/api/professional/stayschool/outercompanyemployee'
|
|
||||||
import { getList as getCompanyList } from '/@/api/professional/stayschool/outercompany'
|
|
||||||
const FormDialog = defineAsyncComponent(() => import('./form.vue'))
|
|
||||||
|
|
||||||
// 无权限即无节点
|
// 无权限即无节点
|
||||||
const { hasAuth } = useAuth()
|
const { hasAuth } = useAuth();
|
||||||
|
|
||||||
// 消息提示 hooks
|
// 消息提示 hooks
|
||||||
const message = useMessage()
|
const message = useMessage();
|
||||||
const messageBox = useMessageBox()
|
const messageBox = useMessageBox();
|
||||||
|
|
||||||
// 字典数据
|
// 字典数据
|
||||||
const { yes_no_type: yesNoDict } = useDict('yes_no_type')
|
const { yes_no_type: yesNoDict } = useDict('yes_no_type');
|
||||||
|
|
||||||
// 获取字典标签的辅助函数
|
// 获取字典标签的辅助函数
|
||||||
const getDictLabel = (value: string | number) => {
|
const getDictLabel = (value: string | number) => {
|
||||||
const item = yesNoDict.value.find((i: any) => i.value === value)
|
const item = yesNoDict.value.find((i: any) => i.value === value);
|
||||||
return item ? item.label : ''
|
return item ? item.label : '';
|
||||||
}
|
};
|
||||||
|
|
||||||
// 表格引用
|
// 表格引用
|
||||||
const tableRef = ref()
|
const tableRef = ref();
|
||||||
const queryRef = ref()
|
const queryRef = ref();
|
||||||
const uploadFormRef = ref()
|
const uploadFormRef = ref();
|
||||||
|
|
||||||
// 搜索显示
|
// 搜索显示
|
||||||
const showSearch = ref(true)
|
const showSearch = ref(true);
|
||||||
|
|
||||||
// 弹窗状态
|
// 弹窗状态
|
||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false);
|
||||||
const dialogUploadVisible = ref(false)
|
const dialogUploadVisible = ref(false);
|
||||||
const dialogViewVisible = ref(false)
|
const dialogViewVisible = ref(false);
|
||||||
const exportLoading = ref(false)
|
const exportLoading = ref(false);
|
||||||
|
|
||||||
// 选中的行数据
|
// 选中的行数据
|
||||||
const selectList = ref<any[]>([])
|
const selectList = ref<any[]>([]);
|
||||||
const permission = reactive({
|
const permission = reactive({
|
||||||
hasPermission: "0",
|
hasPermission: '0',
|
||||||
scope: "0"
|
scope: '0',
|
||||||
})
|
});
|
||||||
|
|
||||||
// 单位列表
|
// 单位列表
|
||||||
const companyList = ref<any[]>([])
|
const companyList = ref<any[]>([]);
|
||||||
|
|
||||||
// 表单数据
|
// 表单数据
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
@@ -307,35 +231,34 @@ const form = reactive({
|
|||||||
position: '',
|
position: '',
|
||||||
address: '',
|
address: '',
|
||||||
inoutFlag: '',
|
inoutFlag: '',
|
||||||
remarks: ''
|
remarks: '',
|
||||||
})
|
});
|
||||||
|
|
||||||
// 头像相关
|
// 头像相关
|
||||||
const dialogImageUrl = ref('')
|
const dialogImageUrl = ref('');
|
||||||
|
|
||||||
// 导入相关
|
// 导入相关
|
||||||
const fileName = ref('')
|
const fileName = ref('');
|
||||||
const filesList = ref<any[]>([])
|
const filesList = ref<any[]>([]);
|
||||||
let files: File | null = null
|
let files: File | null = null;
|
||||||
|
|
||||||
|
|
||||||
// 配置 useTable - 注意这个 API 返回的数据结构特殊
|
// 配置 useTable - 注意这个 API 返回的数据结构特殊
|
||||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||||
pageList: async (params: any) => {
|
pageList: async (params: any) => {
|
||||||
const response = await fetchList({
|
const response = await fetchList({
|
||||||
...params,
|
...params,
|
||||||
companyType: '0'
|
companyType: '0',
|
||||||
})
|
});
|
||||||
// 特殊处理:API 返回的是 response.data.data.dataList.records
|
// 特殊处理:API 返回的是 response.data.data.dataList.records
|
||||||
const dataList = response.data?.data?.dataList || response.data?.dataList || {}
|
const dataList = response.data?.data?.dataList || response.data?.dataList || {};
|
||||||
permission.hasPermission = response.data?.data?.permission?.hasPermission || "0"
|
permission.hasPermission = response.data?.data?.permission?.hasPermission || '0';
|
||||||
permission.scope = response.data?.data?.permission?.scope || "0"
|
permission.scope = response.data?.data?.permission?.scope || '0';
|
||||||
return {
|
return {
|
||||||
data: {
|
data: {
|
||||||
records: dataList.records || [],
|
records: dataList.records || [],
|
||||||
total: dataList.total || 0
|
total: dataList.total || 0,
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
queryForm: {
|
queryForm: {
|
||||||
companyId: '',
|
companyId: '',
|
||||||
@@ -343,37 +266,37 @@ const state: BasicTableProps = reactive<BasicTableProps>({
|
|||||||
realName: '',
|
realName: '',
|
||||||
idCard: '',
|
idCard: '',
|
||||||
mobile: '',
|
mobile: '',
|
||||||
inoutFlag: ''
|
inoutFlag: '',
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||||
|
|
||||||
// 获取单位列表
|
// 获取单位列表
|
||||||
const loadCompanyList = async () => {
|
const loadCompanyList = async () => {
|
||||||
try {
|
try {
|
||||||
const response = await getCompanyList({ companyType: '0' })
|
const response = await getCompanyList({ companyType: '0' });
|
||||||
companyList.value = response.data || []
|
companyList.value = response.data || [];
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 获取单位列表失败
|
// 获取单位列表失败
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// 重置查询
|
// 重置查询
|
||||||
const resetQuery = () => {
|
const resetQuery = () => {
|
||||||
queryRef.value?.resetFields()
|
queryRef.value?.resetFields();
|
||||||
getDataList()
|
getDataList();
|
||||||
}
|
};
|
||||||
|
|
||||||
// 处理搜索
|
// 处理搜索
|
||||||
const handleFilter = () => {
|
const handleFilter = () => {
|
||||||
getDataList()
|
getDataList();
|
||||||
}
|
};
|
||||||
|
|
||||||
// 多选变化
|
// 多选变化
|
||||||
const handleSelectionChange = (selection: any[]) => {
|
const handleSelectionChange = (selection: any[]) => {
|
||||||
selectList.value = selection
|
selectList.value = selection;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 打开新增窗口
|
// 打开新增窗口
|
||||||
const handleAdd = () => {
|
const handleAdd = () => {
|
||||||
@@ -388,16 +311,16 @@ const handleAdd = () => {
|
|||||||
position: '',
|
position: '',
|
||||||
address: '',
|
address: '',
|
||||||
inoutFlag: '',
|
inoutFlag: '',
|
||||||
remarks: ''
|
remarks: '',
|
||||||
})
|
});
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 打开编辑窗口
|
// 打开编辑窗口
|
||||||
const handleEdit = async (row: any) => {
|
const handleEdit = async (row: any) => {
|
||||||
try {
|
try {
|
||||||
const response = await getObj(row.id)
|
const response = await getObj(row.id);
|
||||||
const data = response.data
|
const data = response.data;
|
||||||
Object.assign(form, {
|
Object.assign(form, {
|
||||||
id: data.id,
|
id: data.id,
|
||||||
companyId: data.companyId || '',
|
companyId: data.companyId || '',
|
||||||
@@ -409,114 +332,122 @@ const handleEdit = async (row: any) => {
|
|||||||
position: data.position || '',
|
position: data.position || '',
|
||||||
address: data.address || '',
|
address: data.address || '',
|
||||||
inoutFlag: data.inoutFlag || '',
|
inoutFlag: data.inoutFlag || '',
|
||||||
remarks: data.remarks || ''
|
remarks: data.remarks || '',
|
||||||
})
|
});
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 获取详情失败
|
// 获取详情失败
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// 删除
|
// 删除
|
||||||
const handleDel = (row: any) => {
|
const handleDel = (row: any) => {
|
||||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
messageBox
|
||||||
await delObj(row.id)
|
.confirm('是否确认删除该条记录')
|
||||||
message.success('删除成功')
|
.then(async () => {
|
||||||
|
await delObj(row.id);
|
||||||
|
message.success('删除成功');
|
||||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||||
state.pagination.current = state.pagination.current - 1
|
state.pagination.current = state.pagination.current - 1;
|
||||||
}
|
}
|
||||||
getDataList()
|
getDataList();
|
||||||
}).catch(() => {})
|
})
|
||||||
}
|
.catch(() => {});
|
||||||
|
};
|
||||||
|
|
||||||
// 批量删除
|
// 批量删除
|
||||||
const batchDelect = () => {
|
const batchDelect = () => {
|
||||||
if (selectList.value.length === 0) {
|
if (selectList.value.length === 0) {
|
||||||
message.warning('请至少选择一条数据')
|
message.warning('请至少选择一条数据');
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
messageBox.confirm('是否确认删除').then(async () => {
|
messageBox
|
||||||
await batchDel(selectList.value)
|
.confirm('是否确认删除')
|
||||||
message.success('删除成功')
|
.then(async () => {
|
||||||
selectList.value = []
|
await batchDel(selectList.value);
|
||||||
getDataList()
|
message.success('删除成功');
|
||||||
}).catch(() => {})
|
selectList.value = [];
|
||||||
}
|
getDataList();
|
||||||
|
})
|
||||||
|
.catch(() => {});
|
||||||
|
};
|
||||||
|
|
||||||
// 重置密码
|
// 重置密码
|
||||||
const resetPassword = (row: any) => {
|
const resetPassword = (row: any) => {
|
||||||
messageBox.confirm('是否确定重置密码?').then(async () => {
|
messageBox
|
||||||
|
.confirm('是否确定重置密码?')
|
||||||
|
.then(async () => {
|
||||||
try {
|
try {
|
||||||
const response = await resetPassWord(row)
|
const response = await resetPassWord(row);
|
||||||
const pw = response.data
|
const pw = response.data;
|
||||||
if (!validateNull(pw)) {
|
if (!validateNull(pw)) {
|
||||||
messageBox.info('重置后密码为: ' + pw)
|
messageBox.info('重置后密码为: ' + pw);
|
||||||
} else {
|
} else {
|
||||||
messageBox.error('系统繁忙,请重试')
|
messageBox.error('系统繁忙,请重试');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 重置密码失败
|
// 重置密码失败
|
||||||
}
|
}
|
||||||
}).catch(() => {})
|
})
|
||||||
}
|
.catch(() => {});
|
||||||
|
};
|
||||||
|
|
||||||
// 表单提交成功回调
|
// 表单提交成功回调
|
||||||
const handleFormSuccess = () => {
|
const handleFormSuccess = () => {
|
||||||
getDataList()
|
getDataList();
|
||||||
}
|
};
|
||||||
|
|
||||||
// 获取图片 URL
|
// 获取图片 URL
|
||||||
const getImageView = (employeeNo: string) => {
|
const getImageView = (employeeNo: string) => {
|
||||||
const timestamp = Date.parse(new Date().toString())
|
const timestamp = Date.parse(new Date().toString());
|
||||||
const baseUrl = import.meta.env.VITE_API_URL || ''
|
const baseUrl = import.meta.env.VITE_API_URL || '';
|
||||||
return `${baseUrl}/admin/user/photo/${employeeNo}?${timestamp}`
|
return `${baseUrl}/admin/user/photo/${employeeNo}?${timestamp}`;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 预览头像
|
// 预览头像
|
||||||
const handlePictureCardPreview = (employeeNo: string) => {
|
const handlePictureCardPreview = (employeeNo: string) => {
|
||||||
dialogImageUrl.value = getImageView(employeeNo)
|
dialogImageUrl.value = getImageView(employeeNo);
|
||||||
dialogUploadVisible.value = true
|
dialogUploadVisible.value = true;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
// 导入
|
// 导入
|
||||||
const handleExportIn = () => {
|
const handleExportIn = () => {
|
||||||
fileName.value = ""
|
fileName.value = '';
|
||||||
filesList.value = []
|
filesList.value = [];
|
||||||
files = null
|
files = null;
|
||||||
dialogViewVisible.value = true
|
dialogViewVisible.value = true;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 文件上传验证
|
// 文件上传验证
|
||||||
const fileUpload = (file: File) => {
|
const fileUpload = (file: File) => {
|
||||||
const fileLast = file.name.split('.')
|
const fileLast = file.name.split('.');
|
||||||
const extension = fileLast[fileLast.length - 1] === 'xls'
|
const extension = fileLast[fileLast.length - 1] === 'xls';
|
||||||
const extension2 = fileLast[fileLast.length - 1] === 'xlsx'
|
const extension2 = fileLast[fileLast.length - 1] === 'xlsx';
|
||||||
const isLt2M = file.size / 1024 / 1024 < 5
|
const isLt2M = file.size / 1024 / 1024 < 5;
|
||||||
|
|
||||||
if (!extension && !extension2) {
|
if (!extension && !extension2) {
|
||||||
message.warning('上传模板只能是 xls、xlsx格式!')
|
message.warning('上传模板只能是 xls、xlsx格式!');
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
if (!isLt2M) {
|
if (!isLt2M) {
|
||||||
message.warning('上传模板大小不能超过 5MB!')
|
message.warning('上传模板大小不能超过 5MB!');
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
fileName.value = file.name
|
fileName.value = file.name;
|
||||||
files = file
|
files = file;
|
||||||
return false // 返回false不会自动上传
|
return false; // 返回false不会自动上传
|
||||||
}
|
};
|
||||||
|
|
||||||
// 提交导入
|
// 提交导入
|
||||||
const submitUpload = async () => {
|
const submitUpload = async () => {
|
||||||
if (!fileName.value || !files) {
|
if (!fileName.value || !files) {
|
||||||
message.warning('请选择要上传的文件!')
|
message.warning('请选择要上传的文件!');
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fileFormData = new FormData()
|
const fileFormData = new FormData();
|
||||||
fileFormData.append('file', files, fileName.value)
|
fileFormData.append('file', files, fileName.value);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await request({
|
const response = await request({
|
||||||
@@ -524,35 +455,35 @@ const submitUpload = async () => {
|
|||||||
method: 'post',
|
method: 'post',
|
||||||
data: fileFormData,
|
data: fileFormData,
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'multipart/form-data'
|
'Content-Type': 'multipart/form-data',
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
if (response.code === 0) {
|
if (response.code === 0) {
|
||||||
message.success('操作成功')
|
message.success('操作成功');
|
||||||
dialogViewVisible.value = false
|
dialogViewVisible.value = false;
|
||||||
getDataList()
|
getDataList();
|
||||||
} else {
|
} else {
|
||||||
message.error(response.msg || '导入失败')
|
message.error(response.msg || '导入失败');
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
message.error(error?.msg || '导入失败')
|
message.error(error?.msg || '导入失败');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// 导出
|
// 导出
|
||||||
const handleExportScore = async () => {
|
const handleExportScore = async () => {
|
||||||
if (!state.queryForm || Object.keys(state.queryForm).length === 0) {
|
if (!state.queryForm || Object.keys(state.queryForm).length === 0) {
|
||||||
message.warning('请选择导出条件')
|
message.warning('请选择导出条件');
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
exportLoading.value = true
|
exportLoading.value = true;
|
||||||
try {
|
try {
|
||||||
const params = {
|
const params = {
|
||||||
...state.queryForm,
|
...state.queryForm,
|
||||||
companyType: "0"
|
companyType: '0',
|
||||||
}
|
};
|
||||||
|
|
||||||
const response = await axios({
|
const response = await axios({
|
||||||
method: 'post',
|
method: 'post',
|
||||||
@@ -560,32 +491,32 @@ const handleExportScore = async () => {
|
|||||||
data: params,
|
data: params,
|
||||||
responseType: 'blob',
|
responseType: 'blob',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json',
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
const blob = new Blob([response.data])
|
const blob = new Blob([response.data]);
|
||||||
const fileName = '驻校单位人员导出表.xls'
|
const fileName = '驻校单位人员导出表.xls';
|
||||||
const elink = document.createElement('a')
|
const elink = document.createElement('a');
|
||||||
elink.download = fileName
|
elink.download = fileName;
|
||||||
elink.style.display = 'none'
|
elink.style.display = 'none';
|
||||||
elink.href = URL.createObjectURL(blob)
|
elink.href = URL.createObjectURL(blob);
|
||||||
document.body.appendChild(elink)
|
document.body.appendChild(elink);
|
||||||
elink.click()
|
elink.click();
|
||||||
URL.revokeObjectURL(elink.href)
|
URL.revokeObjectURL(elink.href);
|
||||||
document.body.removeChild(elink)
|
document.body.removeChild(elink);
|
||||||
message.success('导出成功')
|
message.success('导出成功');
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
message.error(error?.msg || '导出失败')
|
message.error(error?.msg || '导出失败');
|
||||||
} finally {
|
} finally {
|
||||||
exportLoading.value = false
|
exportLoading.value = false;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// 初始化
|
// 初始化
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loadCompanyList()
|
loadCompanyList();
|
||||||
})
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@@ -5,66 +5,25 @@
|
|||||||
<el-row shadow="hover" v-show="showSearch">
|
<el-row shadow="hover" v-show="showSearch">
|
||||||
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="handleFilter">
|
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="handleFilter">
|
||||||
<el-form-item label="单位名称" prop="companyId">
|
<el-form-item label="单位名称" prop="companyId">
|
||||||
<el-select
|
<el-select v-model="state.queryForm.companyId" filterable clearable placeholder="请选择单位" style="width: 200px">
|
||||||
v-model="state.queryForm.companyId"
|
<el-option v-for="item in companyList" :key="item.id" :label="item.companyName" :value="item.id" />
|
||||||
filterable
|
|
||||||
clearable
|
|
||||||
placeholder="请选择单位"
|
|
||||||
style="width: 200px"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in companyList"
|
|
||||||
:key="item.id"
|
|
||||||
:label="item.companyName"
|
|
||||||
:value="item.id"
|
|
||||||
/>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="职员编号" prop="employeeNo">
|
<el-form-item label="职员编号" prop="employeeNo">
|
||||||
<el-input
|
<el-input v-model="state.queryForm.employeeNo" placeholder="请输入职员编号" clearable style="width: 200px" />
|
||||||
v-model="state.queryForm.employeeNo"
|
|
||||||
placeholder="请输入职员编号"
|
|
||||||
clearable
|
|
||||||
style="width: 200px"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="姓名" prop="realName">
|
<el-form-item label="姓名" prop="realName">
|
||||||
<el-input
|
<el-input v-model="state.queryForm.realName" placeholder="请输入姓名" clearable style="width: 200px" />
|
||||||
v-model="state.queryForm.realName"
|
|
||||||
placeholder="请输入姓名"
|
|
||||||
clearable
|
|
||||||
style="width: 200px"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="身份证" prop="idCard">
|
<el-form-item label="身份证" prop="idCard">
|
||||||
<el-input
|
<el-input v-model="state.queryForm.idCard" placeholder="请输入身份证" clearable style="width: 200px" />
|
||||||
v-model="state.queryForm.idCard"
|
|
||||||
placeholder="请输入身份证"
|
|
||||||
clearable
|
|
||||||
style="width: 200px"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="手机" prop="mobile">
|
<el-form-item label="手机" prop="mobile">
|
||||||
<el-input
|
<el-input v-model="state.queryForm.mobile" placeholder="请输入手机" clearable style="width: 200px" />
|
||||||
v-model="state.queryForm.mobile"
|
|
||||||
placeholder="请输入手机"
|
|
||||||
clearable
|
|
||||||
style="width: 200px"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="允许进出" prop="inoutFlag">
|
<el-form-item label="允许进出" prop="inoutFlag">
|
||||||
<el-select
|
<el-select v-model="state.queryForm.inoutFlag" clearable placeholder="请选择" style="width: 200px">
|
||||||
v-model="state.queryForm.inoutFlag"
|
<el-option v-for="item in yesNoDict" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
clearable
|
|
||||||
placeholder="请选择"
|
|
||||||
style="width: 200px"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in yesNoDict"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
@@ -76,25 +35,9 @@
|
|||||||
|
|
||||||
<!-- 操作按钮 -->
|
<!-- 操作按钮 -->
|
||||||
<el-row>
|
<el-row>
|
||||||
<div class="mb15" style="width: 100%; position: relative;">
|
<div class="mb15" style="width: 100%; position: relative">
|
||||||
<el-button
|
<el-button v-if="hasAuth('professional_outercompanyemployee_add')" type="primary" icon="FolderAdd" @click="handleAdd"> 新 增 </el-button>
|
||||||
v-if="hasAuth('professional_outercompanyemployee_add')"
|
<el-button type="primary" plain icon="UploadFilled" @click="handleExportIn" v-if="permission.scope == '1'" class="ml10"> 导 入 </el-button>
|
||||||
type="primary"
|
|
||||||
icon="FolderAdd"
|
|
||||||
@click="handleAdd"
|
|
||||||
>
|
|
||||||
新 增
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
plain
|
|
||||||
icon="UploadFilled"
|
|
||||||
@click="handleExportIn"
|
|
||||||
v-if="permission.scope == '1'"
|
|
||||||
class="ml10"
|
|
||||||
>
|
|
||||||
导 入
|
|
||||||
</el-button>
|
|
||||||
<!-- <el-button
|
<!-- <el-button
|
||||||
type="warning"
|
type="warning"
|
||||||
plain
|
plain
|
||||||
@@ -149,11 +92,7 @@
|
|||||||
|
|
||||||
<el-table-column prop="inoutFlag" label="允许进出" width="100" align="center">
|
<el-table-column prop="inoutFlag" label="允许进出" width="100" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tag
|
<el-tag v-if="scope.row.inoutFlag" :type="scope.row.inoutFlag === '1' ? 'success' : 'info'" effect="plain">
|
||||||
v-if="scope.row.inoutFlag"
|
|
||||||
:type="scope.row.inoutFlag === '1' ? 'success' : 'info'"
|
|
||||||
effect="plain"
|
|
||||||
>
|
|
||||||
{{ getDictLabel(scope.row.inoutFlag) }}
|
{{ getDictLabel(scope.row.inoutFlag) }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
<span v-else>-</span>
|
<span v-else>-</span>
|
||||||
@@ -162,14 +101,7 @@
|
|||||||
|
|
||||||
<el-table-column label="头像" width="100" align="center">
|
<el-table-column label="头像" width="100" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button type="primary" link icon="Picture" @click="handlePictureCardPreview(scope.row.employeeNo)"> 查看 </el-button>
|
||||||
type="primary"
|
|
||||||
link
|
|
||||||
icon="Picture"
|
|
||||||
@click="handlePictureCardPreview(scope.row.employeeNo)"
|
|
||||||
>
|
|
||||||
查看
|
|
||||||
</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
@@ -177,19 +109,16 @@
|
|||||||
|
|
||||||
<el-table-column label="操作" width="250" align="center" fixed="right">
|
<el-table-column label="操作" width="250" align="center" fixed="right">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button v-if="hasAuth('professional_outercompanyemployee_edit')" icon="edit-pen" link type="primary" @click="handleEdit(scope.row)"
|
||||||
v-if="hasAuth('professional_outercompanyemployee_edit')"
|
>修改
|
||||||
icon="edit-pen"
|
|
||||||
link
|
|
||||||
type="primary"
|
|
||||||
@click="handleEdit(scope.row)">修改
|
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
v-if="hasAuth('professional_outercompanyemployee_reset_pw')"
|
v-if="hasAuth('professional_outercompanyemployee_reset_pw')"
|
||||||
icon="RefreshLeft"
|
icon="RefreshLeft"
|
||||||
link
|
link
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="resetPassword(scope.row)">重置密码
|
@click="resetPassword(scope.row)"
|
||||||
|
>重置密码
|
||||||
</el-button>
|
</el-button>
|
||||||
<!-- <el-button
|
<!-- <el-button
|
||||||
v-if="hasAuth('professional_outercompanyemployee_del')"
|
v-if="hasAuth('professional_outercompanyemployee_del')"
|
||||||
@@ -203,24 +132,14 @@
|
|||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
<pagination
|
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||||
v-bind="state.pagination"
|
|
||||||
@current-change="currentChangeHandle"
|
|
||||||
@size-change="sizeChangeHandle"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 新增/编辑弹窗 -->
|
<!-- 新增/编辑弹窗 -->
|
||||||
<form-dialog
|
<form-dialog v-model="dialogVisible" :form-data="form" :company-list="companyList" :save-api="saveSecond" @success="handleFormSuccess" />
|
||||||
v-model="dialogVisible"
|
|
||||||
:form-data="form"
|
|
||||||
:company-list="companyList"
|
|
||||||
:save-api="saveSecond"
|
|
||||||
@success="handleFormSuccess"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 头像预览对话框 -->
|
<!-- 头像预览对话框 -->
|
||||||
<el-dialog v-model="dialogUploadVisible" title="头像预览" append-to-body>
|
<el-dialog v-model="dialogUploadVisible" title="头像预览" append-to-body>
|
||||||
<img width="100%" :src="dialogImageUrl" alt="" style="max-height: 600px; object-fit: contain;" />
|
<img width="100%" :src="dialogImageUrl" alt="" style="max-height: 600px; object-fit: contain" />
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<!-- 导入对话框 -->
|
<!-- 导入对话框 -->
|
||||||
@@ -257,66 +176,59 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, onMounted } from 'vue'
|
import { ref, reactive, onMounted } from 'vue';
|
||||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||||
import { useAuth } from '/@/hooks/auth'
|
import { useAuth } from '/@/hooks/auth';
|
||||||
import { useMessage } from '/@/hooks/message'
|
import { useMessage } from '/@/hooks/message';
|
||||||
import { useMessageBox } from '/@/hooks/message'
|
import { useMessageBox } from '/@/hooks/message';
|
||||||
import { useDict } from '/@/hooks/dict'
|
import { useDict } from '/@/hooks/dict';
|
||||||
import { validateNull } from '/@/utils/validate'
|
import { validateNull } from '/@/utils/validate';
|
||||||
import axios from 'axios'
|
import axios from 'axios';
|
||||||
import request from '/@/utils/request'
|
import request from '/@/utils/request';
|
||||||
import { ElMessageBox } from 'element-plus'
|
import { ElMessageBox } from 'element-plus';
|
||||||
import {
|
import { fetchList, getObj, saveSecond, delObj, batchDel, resetPassWord } from '/@/api/professional/stayschool/outercompanyemployee';
|
||||||
fetchList,
|
import { getList as getCompanyList } from '/@/api/professional/stayschool/outercompany';
|
||||||
getObj,
|
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
|
||||||
saveSecond,
|
|
||||||
delObj,
|
|
||||||
batchDel,
|
|
||||||
resetPassWord
|
|
||||||
} from '/@/api/professional/stayschool/outercompanyemployee'
|
|
||||||
import { getList as getCompanyList } from '/@/api/professional/stayschool/outercompany'
|
|
||||||
const FormDialog = defineAsyncComponent(() => import('./form.vue'))
|
|
||||||
|
|
||||||
// 无权限即无节点
|
// 无权限即无节点
|
||||||
const { hasAuth } = useAuth()
|
const { hasAuth } = useAuth();
|
||||||
|
|
||||||
// 消息提示 hooks
|
// 消息提示 hooks
|
||||||
const message = useMessage()
|
const message = useMessage();
|
||||||
const messageBox = useMessageBox()
|
const messageBox = useMessageBox();
|
||||||
|
|
||||||
// 字典数据
|
// 字典数据
|
||||||
const { yes_no_type: yesNoDict } = useDict('yes_no_type')
|
const { yes_no_type: yesNoDict } = useDict('yes_no_type');
|
||||||
|
|
||||||
// 获取字典标签的辅助函数
|
// 获取字典标签的辅助函数
|
||||||
const getDictLabel = (value: string | number) => {
|
const getDictLabel = (value: string | number) => {
|
||||||
const item = yesNoDict.value.find((i: any) => i.value === value)
|
const item = yesNoDict.value.find((i: any) => i.value === value);
|
||||||
return item ? item.label : ''
|
return item ? item.label : '';
|
||||||
}
|
};
|
||||||
|
|
||||||
// 表格引用
|
// 表格引用
|
||||||
const tableRef = ref()
|
const tableRef = ref();
|
||||||
const queryRef = ref()
|
const queryRef = ref();
|
||||||
const uploadFormRef = ref()
|
const uploadFormRef = ref();
|
||||||
|
|
||||||
// 搜索显示
|
// 搜索显示
|
||||||
const showSearch = ref(true)
|
const showSearch = ref(true);
|
||||||
|
|
||||||
// 弹窗状态
|
// 弹窗状态
|
||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false);
|
||||||
const dialogUploadVisible = ref(false)
|
const dialogUploadVisible = ref(false);
|
||||||
const dialogViewVisible = ref(false)
|
const dialogViewVisible = ref(false);
|
||||||
const exportLoading = ref(false)
|
const exportLoading = ref(false);
|
||||||
|
|
||||||
// 选中的行数据
|
// 选中的行数据
|
||||||
const selectList = ref<any[]>([])
|
const selectList = ref<any[]>([]);
|
||||||
const permission = reactive({
|
const permission = reactive({
|
||||||
hasPermission: "0",
|
hasPermission: '0',
|
||||||
scope: "0"
|
scope: '0',
|
||||||
})
|
});
|
||||||
|
|
||||||
// 单位列表
|
// 单位列表
|
||||||
const companyList = ref<any[]>([])
|
const companyList = ref<any[]>([]);
|
||||||
|
|
||||||
// 表单数据
|
// 表单数据
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
@@ -330,36 +242,34 @@ const form = reactive({
|
|||||||
position: '',
|
position: '',
|
||||||
address: '',
|
address: '',
|
||||||
inoutFlag: '',
|
inoutFlag: '',
|
||||||
remarks: ''
|
remarks: '',
|
||||||
})
|
});
|
||||||
|
|
||||||
|
|
||||||
// 头像相关
|
// 头像相关
|
||||||
const dialogImageUrl = ref('')
|
const dialogImageUrl = ref('');
|
||||||
|
|
||||||
// 导入相关
|
// 导入相关
|
||||||
const fileName = ref('')
|
const fileName = ref('');
|
||||||
const filesList = ref<any[]>([])
|
const filesList = ref<any[]>([]);
|
||||||
let files: File | null = null
|
let files: File | null = null;
|
||||||
|
|
||||||
|
|
||||||
// 配置 useTable - 注意这个 API 返回的数据结构特殊
|
// 配置 useTable - 注意这个 API 返回的数据结构特殊
|
||||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||||
pageList: async (params: any) => {
|
pageList: async (params: any) => {
|
||||||
const response = await fetchList({
|
const response = await fetchList({
|
||||||
...params,
|
...params,
|
||||||
companyType: '2' // 二期单位
|
companyType: '2', // 二期单位
|
||||||
})
|
});
|
||||||
// 特殊处理:API 返回的是 response.data.data.dataList.records
|
// 特殊处理:API 返回的是 response.data.data.dataList.records
|
||||||
const dataList = response.data?.data?.dataList || response.data?.dataList || {}
|
const dataList = response.data?.data?.dataList || response.data?.dataList || {};
|
||||||
permission.hasPermission = response.data?.data?.permission?.hasPermission || "0"
|
permission.hasPermission = response.data?.data?.permission?.hasPermission || '0';
|
||||||
permission.scope = response.data?.data?.permission?.scope || "0"
|
permission.scope = response.data?.data?.permission?.scope || '0';
|
||||||
return {
|
return {
|
||||||
data: {
|
data: {
|
||||||
records: dataList.records || [],
|
records: dataList.records || [],
|
||||||
total: dataList.total || 0
|
total: dataList.total || 0,
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
queryForm: {
|
queryForm: {
|
||||||
companyId: '',
|
companyId: '',
|
||||||
@@ -367,37 +277,37 @@ const state: BasicTableProps = reactive<BasicTableProps>({
|
|||||||
realName: '',
|
realName: '',
|
||||||
idCard: '',
|
idCard: '',
|
||||||
mobile: '',
|
mobile: '',
|
||||||
inoutFlag: ''
|
inoutFlag: '',
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||||
|
|
||||||
// 获取单位列表
|
// 获取单位列表
|
||||||
const loadCompanyList = async () => {
|
const loadCompanyList = async () => {
|
||||||
try {
|
try {
|
||||||
const response = await getCompanyList({ companyType: '2' })
|
const response = await getCompanyList({ companyType: '2' });
|
||||||
companyList.value = response.data || []
|
companyList.value = response.data || [];
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 获取单位列表失败
|
// 获取单位列表失败
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// 重置查询
|
// 重置查询
|
||||||
const resetQuery = () => {
|
const resetQuery = () => {
|
||||||
queryRef.value?.resetFields()
|
queryRef.value?.resetFields();
|
||||||
getDataList()
|
getDataList();
|
||||||
}
|
};
|
||||||
|
|
||||||
// 处理搜索
|
// 处理搜索
|
||||||
const handleFilter = () => {
|
const handleFilter = () => {
|
||||||
getDataList()
|
getDataList();
|
||||||
}
|
};
|
||||||
|
|
||||||
// 多选变化
|
// 多选变化
|
||||||
const handleSelectionChange = (selection: any[]) => {
|
const handleSelectionChange = (selection: any[]) => {
|
||||||
selectList.value = selection
|
selectList.value = selection;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 打开新增窗口
|
// 打开新增窗口
|
||||||
const handleAdd = () => {
|
const handleAdd = () => {
|
||||||
@@ -412,16 +322,16 @@ const handleAdd = () => {
|
|||||||
position: '',
|
position: '',
|
||||||
address: '',
|
address: '',
|
||||||
inoutFlag: '',
|
inoutFlag: '',
|
||||||
remarks: ''
|
remarks: '',
|
||||||
})
|
});
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 打开编辑窗口
|
// 打开编辑窗口
|
||||||
const handleEdit = async (row: any) => {
|
const handleEdit = async (row: any) => {
|
||||||
try {
|
try {
|
||||||
const response = await getObj(row.id)
|
const response = await getObj(row.id);
|
||||||
const data = response.data
|
const data = response.data;
|
||||||
Object.assign(form, {
|
Object.assign(form, {
|
||||||
id: data.id,
|
id: data.id,
|
||||||
companyId: data.companyId || '',
|
companyId: data.companyId || '',
|
||||||
@@ -433,114 +343,122 @@ const handleEdit = async (row: any) => {
|
|||||||
position: data.position || '',
|
position: data.position || '',
|
||||||
address: data.address || '',
|
address: data.address || '',
|
||||||
inoutFlag: data.inoutFlag || '',
|
inoutFlag: data.inoutFlag || '',
|
||||||
remarks: data.remarks || ''
|
remarks: data.remarks || '',
|
||||||
})
|
});
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 获取详情失败
|
// 获取详情失败
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// 删除
|
// 删除
|
||||||
const handleDel = (row: any) => {
|
const handleDel = (row: any) => {
|
||||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
messageBox
|
||||||
await delObj(row.id)
|
.confirm('是否确认删除该条记录')
|
||||||
message.success('删除成功')
|
.then(async () => {
|
||||||
|
await delObj(row.id);
|
||||||
|
message.success('删除成功');
|
||||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||||
state.pagination.current = state.pagination.current - 1
|
state.pagination.current = state.pagination.current - 1;
|
||||||
}
|
}
|
||||||
getDataList()
|
getDataList();
|
||||||
}).catch(() => {})
|
})
|
||||||
}
|
.catch(() => {});
|
||||||
|
};
|
||||||
|
|
||||||
// 批量删除
|
// 批量删除
|
||||||
const batchDelect = () => {
|
const batchDelect = () => {
|
||||||
if (selectList.value.length === 0) {
|
if (selectList.value.length === 0) {
|
||||||
message.warning('请至少选择一条数据')
|
message.warning('请至少选择一条数据');
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
messageBox.confirm('是否确认删除').then(async () => {
|
messageBox
|
||||||
await batchDel(selectList.value)
|
.confirm('是否确认删除')
|
||||||
message.success('删除成功')
|
.then(async () => {
|
||||||
selectList.value = []
|
await batchDel(selectList.value);
|
||||||
getDataList()
|
message.success('删除成功');
|
||||||
}).catch(() => {})
|
selectList.value = [];
|
||||||
}
|
getDataList();
|
||||||
|
})
|
||||||
|
.catch(() => {});
|
||||||
|
};
|
||||||
|
|
||||||
// 重置密码
|
// 重置密码
|
||||||
const resetPassword = (row: any) => {
|
const resetPassword = (row: any) => {
|
||||||
messageBox.confirm('是否确定重置密码?').then(async () => {
|
messageBox
|
||||||
|
.confirm('是否确定重置密码?')
|
||||||
|
.then(async () => {
|
||||||
try {
|
try {
|
||||||
const response = await resetPassWord(row)
|
const response = await resetPassWord(row);
|
||||||
const pw = response.data?.data
|
const pw = response.data?.data;
|
||||||
if (!validateNull(pw)) {
|
if (!validateNull(pw)) {
|
||||||
ElMessageBox.alert('重置后密码为: ' + pw, '重置密码')
|
ElMessageBox.alert('重置后密码为: ' + pw, '重置密码');
|
||||||
} else {
|
} else {
|
||||||
ElMessageBox.alert('系统繁忙,请重试', '重置密码')
|
ElMessageBox.alert('系统繁忙,请重试', '重置密码');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 重置密码失败
|
// 重置密码失败
|
||||||
}
|
}
|
||||||
}).catch(() => {})
|
})
|
||||||
}
|
.catch(() => {});
|
||||||
|
};
|
||||||
|
|
||||||
// 表单提交成功回调
|
// 表单提交成功回调
|
||||||
const handleFormSuccess = () => {
|
const handleFormSuccess = () => {
|
||||||
getDataList()
|
getDataList();
|
||||||
}
|
};
|
||||||
|
|
||||||
// 获取图片 URL
|
// 获取图片 URL
|
||||||
const getImageView = (employeeNo: string) => {
|
const getImageView = (employeeNo: string) => {
|
||||||
const timestamp = Date.parse(new Date().toString())
|
const timestamp = Date.parse(new Date().toString());
|
||||||
const baseUrl = import.meta.env.VITE_API_URL || ''
|
const baseUrl = import.meta.env.VITE_API_URL || '';
|
||||||
return `${baseUrl}/admin/user/photo/${employeeNo}?${timestamp}`
|
return `${baseUrl}/admin/user/photo/${employeeNo}?${timestamp}`;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 预览头像
|
// 预览头像
|
||||||
const handlePictureCardPreview = (employeeNo: string) => {
|
const handlePictureCardPreview = (employeeNo: string) => {
|
||||||
dialogImageUrl.value = getImageView(employeeNo)
|
dialogImageUrl.value = getImageView(employeeNo);
|
||||||
dialogUploadVisible.value = true
|
dialogUploadVisible.value = true;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
// 导入
|
// 导入
|
||||||
const handleExportIn = () => {
|
const handleExportIn = () => {
|
||||||
fileName.value = ""
|
fileName.value = '';
|
||||||
filesList.value = []
|
filesList.value = [];
|
||||||
files = null
|
files = null;
|
||||||
dialogViewVisible.value = true
|
dialogViewVisible.value = true;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 文件上传验证
|
// 文件上传验证
|
||||||
const fileUpload = (file: File) => {
|
const fileUpload = (file: File) => {
|
||||||
const fileLast = file.name.split('.')
|
const fileLast = file.name.split('.');
|
||||||
const extension = fileLast[fileLast.length - 1] === 'xls'
|
const extension = fileLast[fileLast.length - 1] === 'xls';
|
||||||
const extension2 = fileLast[fileLast.length - 1] === 'xlsx'
|
const extension2 = fileLast[fileLast.length - 1] === 'xlsx';
|
||||||
const isLt2M = file.size / 1024 / 1024 < 5
|
const isLt2M = file.size / 1024 / 1024 < 5;
|
||||||
|
|
||||||
if (!extension && !extension2) {
|
if (!extension && !extension2) {
|
||||||
message.warning('上传模板只能是 xls、xlsx格式!')
|
message.warning('上传模板只能是 xls、xlsx格式!');
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
if (!isLt2M) {
|
if (!isLt2M) {
|
||||||
message.warning('上传模板大小不能超过 5MB!')
|
message.warning('上传模板大小不能超过 5MB!');
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
fileName.value = file.name
|
fileName.value = file.name;
|
||||||
files = file
|
files = file;
|
||||||
return false // 返回false不会自动上传
|
return false; // 返回false不会自动上传
|
||||||
}
|
};
|
||||||
|
|
||||||
// 提交导入
|
// 提交导入
|
||||||
const submitUpload = async () => {
|
const submitUpload = async () => {
|
||||||
if (!fileName.value || !files) {
|
if (!fileName.value || !files) {
|
||||||
message.warning('请选择要上传的文件!')
|
message.warning('请选择要上传的文件!');
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fileFormData = new FormData()
|
const fileFormData = new FormData();
|
||||||
fileFormData.append('file', files, fileName.value)
|
fileFormData.append('file', files, fileName.value);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await request({
|
const response = await request({
|
||||||
@@ -548,35 +466,35 @@ const submitUpload = async () => {
|
|||||||
method: 'post',
|
method: 'post',
|
||||||
data: fileFormData,
|
data: fileFormData,
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'multipart/form-data'
|
'Content-Type': 'multipart/form-data',
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
if (response.code === 0) {
|
if (response.code === 0) {
|
||||||
message.success('操作成功')
|
message.success('操作成功');
|
||||||
dialogViewVisible.value = false
|
dialogViewVisible.value = false;
|
||||||
getDataList()
|
getDataList();
|
||||||
} else {
|
} else {
|
||||||
message.error(response.msg || '导入失败')
|
message.error(response.msg || '导入失败');
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
message.error(error?.msg || '导入失败')
|
message.error(error?.msg || '导入失败');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// 导出
|
// 导出
|
||||||
const handleExportScore = async () => {
|
const handleExportScore = async () => {
|
||||||
if (!state.queryForm || Object.keys(state.queryForm).length === 0) {
|
if (!state.queryForm || Object.keys(state.queryForm).length === 0) {
|
||||||
message.warning('请选择导出条件')
|
message.warning('请选择导出条件');
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
exportLoading.value = true
|
exportLoading.value = true;
|
||||||
try {
|
try {
|
||||||
const params = {
|
const params = {
|
||||||
...state.queryForm,
|
...state.queryForm,
|
||||||
companyType: "2"
|
companyType: '2',
|
||||||
}
|
};
|
||||||
|
|
||||||
const response = await axios({
|
const response = await axios({
|
||||||
method: 'post',
|
method: 'post',
|
||||||
@@ -584,32 +502,32 @@ const handleExportScore = async () => {
|
|||||||
data: params,
|
data: params,
|
||||||
responseType: 'blob',
|
responseType: 'blob',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json',
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
const blob = new Blob([response.data])
|
const blob = new Blob([response.data]);
|
||||||
const fileName = '二期单位人员导出表.xls'
|
const fileName = '二期单位人员导出表.xls';
|
||||||
const elink = document.createElement('a')
|
const elink = document.createElement('a');
|
||||||
elink.download = fileName
|
elink.download = fileName;
|
||||||
elink.style.display = 'none'
|
elink.style.display = 'none';
|
||||||
elink.href = URL.createObjectURL(blob)
|
elink.href = URL.createObjectURL(blob);
|
||||||
document.body.appendChild(elink)
|
document.body.appendChild(elink);
|
||||||
elink.click()
|
elink.click();
|
||||||
URL.revokeObjectURL(elink.href)
|
URL.revokeObjectURL(elink.href);
|
||||||
document.body.removeChild(elink)
|
document.body.removeChild(elink);
|
||||||
message.success('导出成功')
|
message.success('导出成功');
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
message.error(error?.msg || '导出失败')
|
message.error(error?.msg || '导出失败');
|
||||||
} finally {
|
} finally {
|
||||||
exportLoading.value = false
|
exportLoading.value = false;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// 初始化
|
// 初始化
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loadCompanyList()
|
loadCompanyList();
|
||||||
})
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@@ -5,66 +5,25 @@
|
|||||||
<el-row shadow="hover" v-show="showSearch">
|
<el-row shadow="hover" v-show="showSearch">
|
||||||
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="handleFilter">
|
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="handleFilter">
|
||||||
<el-form-item label="班级名称" prop="companyId">
|
<el-form-item label="班级名称" prop="companyId">
|
||||||
<el-select
|
<el-select v-model="state.queryForm.companyId" filterable clearable placeholder="请选择班级" style="width: 200px">
|
||||||
v-model="state.queryForm.companyId"
|
<el-option v-for="item in companyList" :key="item.id" :label="item.companyName" :value="item.id" />
|
||||||
filterable
|
|
||||||
clearable
|
|
||||||
placeholder="请选择班级"
|
|
||||||
style="width: 200px"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in companyList"
|
|
||||||
:key="item.id"
|
|
||||||
:label="item.companyName"
|
|
||||||
:value="item.id"
|
|
||||||
/>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="学员编号" prop="employeeNo">
|
<el-form-item label="学员编号" prop="employeeNo">
|
||||||
<el-input
|
<el-input v-model="state.queryForm.employeeNo" placeholder="请输入学员编号" clearable style="width: 200px" />
|
||||||
v-model="state.queryForm.employeeNo"
|
|
||||||
placeholder="请输入学员编号"
|
|
||||||
clearable
|
|
||||||
style="width: 200px"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="姓名" prop="realName">
|
<el-form-item label="姓名" prop="realName">
|
||||||
<el-input
|
<el-input v-model="state.queryForm.realName" placeholder="请输入姓名" clearable style="width: 200px" />
|
||||||
v-model="state.queryForm.realName"
|
|
||||||
placeholder="请输入姓名"
|
|
||||||
clearable
|
|
||||||
style="width: 200px"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="身份证" prop="idCard">
|
<el-form-item label="身份证" prop="idCard">
|
||||||
<el-input
|
<el-input v-model="state.queryForm.idCard" placeholder="请输入身份证" clearable style="width: 200px" />
|
||||||
v-model="state.queryForm.idCard"
|
|
||||||
placeholder="请输入身份证"
|
|
||||||
clearable
|
|
||||||
style="width: 200px"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="手机" prop="mobile">
|
<el-form-item label="手机" prop="mobile">
|
||||||
<el-input
|
<el-input v-model="state.queryForm.mobile" placeholder="请输入手机" clearable style="width: 200px" />
|
||||||
v-model="state.queryForm.mobile"
|
|
||||||
placeholder="请输入手机"
|
|
||||||
clearable
|
|
||||||
style="width: 200px"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="允许进出" prop="inoutFlag">
|
<el-form-item label="允许进出" prop="inoutFlag">
|
||||||
<el-select
|
<el-select v-model="state.queryForm.inoutFlag" clearable placeholder="请选择" style="width: 200px">
|
||||||
v-model="state.queryForm.inoutFlag"
|
<el-option v-for="item in yesNoDict" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
clearable
|
|
||||||
placeholder="请选择"
|
|
||||||
style="width: 200px"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in yesNoDict"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
@@ -76,25 +35,9 @@
|
|||||||
|
|
||||||
<!-- 操作按钮 -->
|
<!-- 操作按钮 -->
|
||||||
<el-row>
|
<el-row>
|
||||||
<div class="mb15" style="width: 100%;">
|
<div class="mb15" style="width: 100%">
|
||||||
<el-button
|
<el-button v-if="hasAuth('professional_outercompanyemployee_add')" type="primary" icon="FolderAdd" @click="handleAdd"> 新 增 </el-button>
|
||||||
v-if="hasAuth('professional_outercompanyemployee_add')"
|
<el-button type="primary" plain icon="UploadFilled" @click="handleExportIn" v-if="permission.scope == '1'" class="ml10"> 导 入 </el-button>
|
||||||
type="primary"
|
|
||||||
icon="FolderAdd"
|
|
||||||
@click="handleAdd"
|
|
||||||
>
|
|
||||||
新 增
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
plain
|
|
||||||
icon="UploadFilled"
|
|
||||||
@click="handleExportIn"
|
|
||||||
v-if="permission.scope == '1'"
|
|
||||||
class="ml10"
|
|
||||||
>
|
|
||||||
导 入
|
|
||||||
</el-button>
|
|
||||||
<!-- <el-button
|
<!-- <el-button
|
||||||
type="warning"
|
type="warning"
|
||||||
plain
|
plain
|
||||||
@@ -149,11 +92,7 @@
|
|||||||
|
|
||||||
<el-table-column prop="inoutFlag" label="允许进出" width="100" align="center">
|
<el-table-column prop="inoutFlag" label="允许进出" width="100" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tag
|
<el-tag v-if="scope.row.inoutFlag" :type="scope.row.inoutFlag === '1' ? 'success' : 'info'" effect="plain">
|
||||||
v-if="scope.row.inoutFlag"
|
|
||||||
:type="scope.row.inoutFlag === '1' ? 'success' : 'info'"
|
|
||||||
effect="plain"
|
|
||||||
>
|
|
||||||
{{ getDictLabel(scope.row.inoutFlag) }}
|
{{ getDictLabel(scope.row.inoutFlag) }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
<span v-else>-</span>
|
<span v-else>-</span>
|
||||||
@@ -162,14 +101,7 @@
|
|||||||
|
|
||||||
<el-table-column label="头像" width="100" align="center">
|
<el-table-column label="头像" width="100" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button type="primary" link icon="Picture" @click="handlePictureCardPreview(scope.row.employeeNo)"> 查看 </el-button>
|
||||||
type="primary"
|
|
||||||
link
|
|
||||||
icon="Picture"
|
|
||||||
@click="handlePictureCardPreview(scope.row.employeeNo)"
|
|
||||||
>
|
|
||||||
查看
|
|
||||||
</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
@@ -177,19 +109,16 @@
|
|||||||
|
|
||||||
<el-table-column label="操作" width="250" align="center" fixed="right">
|
<el-table-column label="操作" width="250" align="center" fixed="right">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button v-if="hasAuth('professional_outercompanyemployee_edit')" icon="edit-pen" link type="primary" @click="handleEdit(scope.row)"
|
||||||
v-if="hasAuth('professional_outercompanyemployee_edit')"
|
>修改
|
||||||
icon="edit-pen"
|
|
||||||
link
|
|
||||||
type="primary"
|
|
||||||
@click="handleEdit(scope.row)">修改
|
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
v-if="hasAuth('professional_outercompanyemployee_reset_pw')"
|
v-if="hasAuth('professional_outercompanyemployee_reset_pw')"
|
||||||
icon="RefreshLeft"
|
icon="RefreshLeft"
|
||||||
link
|
link
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="resetPassword(scope.row)">重置密码
|
@click="resetPassword(scope.row)"
|
||||||
|
>重置密码
|
||||||
</el-button>
|
</el-button>
|
||||||
<!-- <el-button
|
<!-- <el-button
|
||||||
v-if="hasAuth('professional_outercompanyemployee_del')"
|
v-if="hasAuth('professional_outercompanyemployee_del')"
|
||||||
@@ -203,24 +132,14 @@
|
|||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
<pagination
|
<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle" />
|
||||||
v-bind="state.pagination"
|
|
||||||
@current-change="currentChangeHandle"
|
|
||||||
@size-change="sizeChangeHandle"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 新增/编辑弹窗 -->
|
<!-- 新增/编辑弹窗 -->
|
||||||
<form-train
|
<form-train v-model="dialogVisible" :form-data="form" :company-list="companyList" :save-api="saveSecond" @success="handleFormSuccess" />
|
||||||
v-model="dialogVisible"
|
|
||||||
:form-data="form"
|
|
||||||
:company-list="companyList"
|
|
||||||
:save-api="saveSecond"
|
|
||||||
@success="handleFormSuccess"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 头像预览对话框 -->
|
<!-- 头像预览对话框 -->
|
||||||
<el-dialog v-model="dialogUploadVisible" title="头像预览" append-to-body>
|
<el-dialog v-model="dialogUploadVisible" title="头像预览" append-to-body>
|
||||||
<img width="100%" :src="dialogImageUrl" alt="" style="max-height: 600px; object-fit: contain;" />
|
<img width="100%" :src="dialogImageUrl" alt="" style="max-height: 600px; object-fit: contain" />
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<!-- 导入对话框 -->
|
<!-- 导入对话框 -->
|
||||||
@@ -257,68 +176,61 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, onMounted } from 'vue'
|
import { ref, reactive, onMounted } from 'vue';
|
||||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||||
import { useAuth } from '/@/hooks/auth'
|
import { useAuth } from '/@/hooks/auth';
|
||||||
import { useMessage } from '/@/hooks/message'
|
import { useMessage } from '/@/hooks/message';
|
||||||
import { useMessageBox } from '/@/hooks/message'
|
import { useMessageBox } from '/@/hooks/message';
|
||||||
import { useDict } from '/@/hooks/dict'
|
import { useDict } from '/@/hooks/dict';
|
||||||
import { validateNull } from '/@/utils/validate'
|
import { validateNull } from '/@/utils/validate';
|
||||||
import axios from 'axios'
|
import axios from 'axios';
|
||||||
import request from '/@/utils/request'
|
import request from '/@/utils/request';
|
||||||
import { Plus, UploadFilled, Download, Delete, Picture } from '@element-plus/icons-vue'
|
import { Plus, UploadFilled, Download, Delete, Picture } from '@element-plus/icons-vue';
|
||||||
import { ElMessageBox } from 'element-plus'
|
import { ElMessageBox } from 'element-plus';
|
||||||
import {
|
import { fetchList, getObj, saveSecond, delObj, batchDel, resetPassWord } from '/@/api/professional/stayschool/outercompanyemployee';
|
||||||
fetchList,
|
import { getList as getCompanyList } from '/@/api/professional/stayschool/outercompany';
|
||||||
getObj,
|
|
||||||
saveSecond,
|
|
||||||
delObj,
|
|
||||||
batchDel,
|
|
||||||
resetPassWord
|
|
||||||
} from '/@/api/professional/stayschool/outercompanyemployee'
|
|
||||||
import { getList as getCompanyList } from '/@/api/professional/stayschool/outercompany'
|
|
||||||
import { defineAsyncComponent } from 'vue';
|
import { defineAsyncComponent } from 'vue';
|
||||||
const FormTrain = defineAsyncComponent(() => import('./formTrain.vue'))
|
const FormTrain = defineAsyncComponent(() => import('./formTrain.vue'));
|
||||||
|
|
||||||
// 无权限即无节点
|
// 无权限即无节点
|
||||||
const { hasAuth } = useAuth()
|
const { hasAuth } = useAuth();
|
||||||
|
|
||||||
// 消息提示 hooks
|
// 消息提示 hooks
|
||||||
const message = useMessage()
|
const message = useMessage();
|
||||||
const messageBox = useMessageBox()
|
const messageBox = useMessageBox();
|
||||||
|
|
||||||
// 字典数据
|
// 字典数据
|
||||||
const { yes_no_type: yesNoDict } = useDict('yes_no_type')
|
const { yes_no_type: yesNoDict } = useDict('yes_no_type');
|
||||||
|
|
||||||
// 获取字典标签的辅助函数
|
// 获取字典标签的辅助函数
|
||||||
const getDictLabel = (value: string | number) => {
|
const getDictLabel = (value: string | number) => {
|
||||||
const item = yesNoDict.value.find((i: any) => i.value === value)
|
const item = yesNoDict.value.find((i: any) => i.value === value);
|
||||||
return item ? item.label : ''
|
return item ? item.label : '';
|
||||||
}
|
};
|
||||||
|
|
||||||
// 表格引用
|
// 表格引用
|
||||||
const tableRef = ref()
|
const tableRef = ref();
|
||||||
const queryRef = ref()
|
const queryRef = ref();
|
||||||
const uploadFormRef = ref()
|
const uploadFormRef = ref();
|
||||||
|
|
||||||
// 搜索显示
|
// 搜索显示
|
||||||
const showSearch = ref(true)
|
const showSearch = ref(true);
|
||||||
|
|
||||||
// 弹窗状态
|
// 弹窗状态
|
||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false);
|
||||||
const dialogUploadVisible = ref(false)
|
const dialogUploadVisible = ref(false);
|
||||||
const dialogViewVisible = ref(false)
|
const dialogViewVisible = ref(false);
|
||||||
const exportLoading = ref(false)
|
const exportLoading = ref(false);
|
||||||
|
|
||||||
// 选中的行数据
|
// 选中的行数据
|
||||||
const selectList = ref<any[]>([])
|
const selectList = ref<any[]>([]);
|
||||||
const permission = reactive({
|
const permission = reactive({
|
||||||
hasPermission: "0",
|
hasPermission: '0',
|
||||||
scope: "0"
|
scope: '0',
|
||||||
})
|
});
|
||||||
|
|
||||||
// 单位列表
|
// 单位列表
|
||||||
const companyList = ref<any[]>([])
|
const companyList = ref<any[]>([]);
|
||||||
|
|
||||||
// 表单数据
|
// 表单数据
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
@@ -330,36 +242,34 @@ const form = reactive({
|
|||||||
idCard: '',
|
idCard: '',
|
||||||
mobile: '',
|
mobile: '',
|
||||||
inoutFlag: '',
|
inoutFlag: '',
|
||||||
remarks: ''
|
remarks: '',
|
||||||
})
|
});
|
||||||
|
|
||||||
|
|
||||||
// 头像相关
|
// 头像相关
|
||||||
const dialogImageUrl = ref('')
|
const dialogImageUrl = ref('');
|
||||||
|
|
||||||
// 导入相关
|
// 导入相关
|
||||||
const fileName = ref('')
|
const fileName = ref('');
|
||||||
const filesList = ref<any[]>([])
|
const filesList = ref<any[]>([]);
|
||||||
let files: File | null = null
|
let files: File | null = null;
|
||||||
|
|
||||||
|
|
||||||
// 配置 useTable - 注意这个 API 返回的数据结构特殊
|
// 配置 useTable - 注意这个 API 返回的数据结构特殊
|
||||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||||
pageList: async (params: any) => {
|
pageList: async (params: any) => {
|
||||||
const response = await fetchList({
|
const response = await fetchList({
|
||||||
...params,
|
...params,
|
||||||
companyType: '1' // 培训单位
|
companyType: '1', // 培训单位
|
||||||
})
|
});
|
||||||
// 特殊处理:API 返回的是 response.data.data.dataList.records
|
// 特殊处理:API 返回的是 response.data.data.dataList.records
|
||||||
const dataList = response.data?.data?.dataList || response.data?.dataList || {}
|
const dataList = response.data?.data?.dataList || response.data?.dataList || {};
|
||||||
permission.hasPermission = response.data?.data?.permission?.hasPermission || "0"
|
permission.hasPermission = response.data?.data?.permission?.hasPermission || '0';
|
||||||
permission.scope = response.data?.data?.permission?.scope || "0"
|
permission.scope = response.data?.data?.permission?.scope || '0';
|
||||||
return {
|
return {
|
||||||
data: {
|
data: {
|
||||||
records: dataList.records || [],
|
records: dataList.records || [],
|
||||||
total: dataList.total || 0
|
total: dataList.total || 0,
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
queryForm: {
|
queryForm: {
|
||||||
companyId: '',
|
companyId: '',
|
||||||
@@ -367,37 +277,37 @@ const state: BasicTableProps = reactive<BasicTableProps>({
|
|||||||
realName: '',
|
realName: '',
|
||||||
idCard: '',
|
idCard: '',
|
||||||
mobile: '',
|
mobile: '',
|
||||||
inoutFlag: ''
|
inoutFlag: '',
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||||
|
|
||||||
// 获取单位列表
|
// 获取单位列表
|
||||||
const loadCompanyList = async () => {
|
const loadCompanyList = async () => {
|
||||||
try {
|
try {
|
||||||
const response = await getCompanyList({ companyType: '1' })
|
const response = await getCompanyList({ companyType: '1' });
|
||||||
companyList.value = response.data || []
|
companyList.value = response.data || [];
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 获取单位列表失败
|
// 获取单位列表失败
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// 重置查询
|
// 重置查询
|
||||||
const resetQuery = () => {
|
const resetQuery = () => {
|
||||||
queryRef.value?.resetFields()
|
queryRef.value?.resetFields();
|
||||||
getDataList()
|
getDataList();
|
||||||
}
|
};
|
||||||
|
|
||||||
// 处理搜索
|
// 处理搜索
|
||||||
const handleFilter = () => {
|
const handleFilter = () => {
|
||||||
getDataList()
|
getDataList();
|
||||||
}
|
};
|
||||||
|
|
||||||
// 多选变化
|
// 多选变化
|
||||||
const handleSelectionChange = (selection: any[]) => {
|
const handleSelectionChange = (selection: any[]) => {
|
||||||
selectList.value = selection
|
selectList.value = selection;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 打开新增窗口
|
// 打开新增窗口
|
||||||
const handleAdd = () => {
|
const handleAdd = () => {
|
||||||
@@ -410,16 +320,16 @@ const handleAdd = () => {
|
|||||||
idCard: '',
|
idCard: '',
|
||||||
mobile: '',
|
mobile: '',
|
||||||
inoutFlag: '',
|
inoutFlag: '',
|
||||||
remarks: ''
|
remarks: '',
|
||||||
})
|
});
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 打开编辑窗口
|
// 打开编辑窗口
|
||||||
const handleEdit = async (row: any) => {
|
const handleEdit = async (row: any) => {
|
||||||
try {
|
try {
|
||||||
const response = await getObj(row.id)
|
const response = await getObj(row.id);
|
||||||
const data = response.data
|
const data = response.data;
|
||||||
Object.assign(form, {
|
Object.assign(form, {
|
||||||
id: data.id,
|
id: data.id,
|
||||||
companyId: data.companyId || '',
|
companyId: data.companyId || '',
|
||||||
@@ -429,114 +339,122 @@ const handleEdit = async (row: any) => {
|
|||||||
idCard: data.idCard || '',
|
idCard: data.idCard || '',
|
||||||
mobile: data.mobile || '',
|
mobile: data.mobile || '',
|
||||||
inoutFlag: data.inoutFlag || '',
|
inoutFlag: data.inoutFlag || '',
|
||||||
remarks: data.remarks || ''
|
remarks: data.remarks || '',
|
||||||
})
|
});
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 获取详情失败
|
// 获取详情失败
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// 删除
|
// 删除
|
||||||
const handleDel = (row: any) => {
|
const handleDel = (row: any) => {
|
||||||
messageBox.confirm('是否确认删除该条记录').then(async () => {
|
messageBox
|
||||||
await delObj(row.id)
|
.confirm('是否确认删除该条记录')
|
||||||
message.success('删除成功')
|
.then(async () => {
|
||||||
|
await delObj(row.id);
|
||||||
|
message.success('删除成功');
|
||||||
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
// 如果当前页只剩一条数据,且不是第一页,则跳转到上一页
|
||||||
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
if (state.pagination && state.dataList && state.dataList.length === 1 && state.pagination.current && state.pagination.current > 1) {
|
||||||
state.pagination.current = state.pagination.current - 1
|
state.pagination.current = state.pagination.current - 1;
|
||||||
}
|
}
|
||||||
getDataList()
|
getDataList();
|
||||||
}).catch(() => {})
|
})
|
||||||
}
|
.catch(() => {});
|
||||||
|
};
|
||||||
|
|
||||||
// 批量删除
|
// 批量删除
|
||||||
const batchDelect = () => {
|
const batchDelect = () => {
|
||||||
if (selectList.value.length === 0) {
|
if (selectList.value.length === 0) {
|
||||||
message.warning('请至少选择一条数据')
|
message.warning('请至少选择一条数据');
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
messageBox.confirm('是否确认删除').then(async () => {
|
messageBox
|
||||||
await batchDel(selectList.value)
|
.confirm('是否确认删除')
|
||||||
message.success('删除成功')
|
.then(async () => {
|
||||||
selectList.value = []
|
await batchDel(selectList.value);
|
||||||
getDataList()
|
message.success('删除成功');
|
||||||
}).catch(() => {})
|
selectList.value = [];
|
||||||
}
|
getDataList();
|
||||||
|
})
|
||||||
|
.catch(() => {});
|
||||||
|
};
|
||||||
|
|
||||||
// 重置密码
|
// 重置密码
|
||||||
const resetPassword = (row: any) => {
|
const resetPassword = (row: any) => {
|
||||||
messageBox.confirm('是否确定重置密码?').then(async () => {
|
messageBox
|
||||||
|
.confirm('是否确定重置密码?')
|
||||||
|
.then(async () => {
|
||||||
try {
|
try {
|
||||||
const response = await resetPassWord(row)
|
const response = await resetPassWord(row);
|
||||||
const pw = response.data?.data
|
const pw = response.data?.data;
|
||||||
if (!validateNull(pw)) {
|
if (!validateNull(pw)) {
|
||||||
ElMessageBox.alert('重置后密码为: ' + pw, '重置密码')
|
ElMessageBox.alert('重置后密码为: ' + pw, '重置密码');
|
||||||
} else {
|
} else {
|
||||||
ElMessageBox.alert('系统繁忙,请重试', '重置密码')
|
ElMessageBox.alert('系统繁忙,请重试', '重置密码');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 重置密码失败
|
// 重置密码失败
|
||||||
}
|
}
|
||||||
}).catch(() => {})
|
})
|
||||||
}
|
.catch(() => {});
|
||||||
|
};
|
||||||
|
|
||||||
// 表单提交成功回调
|
// 表单提交成功回调
|
||||||
const handleFormSuccess = () => {
|
const handleFormSuccess = () => {
|
||||||
getDataList()
|
getDataList();
|
||||||
}
|
};
|
||||||
|
|
||||||
// 获取图片 URL
|
// 获取图片 URL
|
||||||
const getImageView = (employeeNo: string) => {
|
const getImageView = (employeeNo: string) => {
|
||||||
const timestamp = Date.parse(new Date().toString())
|
const timestamp = Date.parse(new Date().toString());
|
||||||
const baseUrl = import.meta.env.VITE_API_URL || ''
|
const baseUrl = import.meta.env.VITE_API_URL || '';
|
||||||
return `${baseUrl}/admin/user/photo/${employeeNo}?${timestamp}`
|
return `${baseUrl}/admin/user/photo/${employeeNo}?${timestamp}`;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 预览头像
|
// 预览头像
|
||||||
const handlePictureCardPreview = (employeeNo: string) => {
|
const handlePictureCardPreview = (employeeNo: string) => {
|
||||||
dialogImageUrl.value = getImageView(employeeNo)
|
dialogImageUrl.value = getImageView(employeeNo);
|
||||||
dialogUploadVisible.value = true
|
dialogUploadVisible.value = true;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
// 导入
|
// 导入
|
||||||
const handleExportIn = () => {
|
const handleExportIn = () => {
|
||||||
fileName.value = ""
|
fileName.value = '';
|
||||||
filesList.value = []
|
filesList.value = [];
|
||||||
files = null
|
files = null;
|
||||||
dialogViewVisible.value = true
|
dialogViewVisible.value = true;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 文件上传验证
|
// 文件上传验证
|
||||||
const fileUpload = (file: File) => {
|
const fileUpload = (file: File) => {
|
||||||
const fileLast = file.name.split('.')
|
const fileLast = file.name.split('.');
|
||||||
const extension = fileLast[fileLast.length - 1] === 'xls'
|
const extension = fileLast[fileLast.length - 1] === 'xls';
|
||||||
const extension2 = fileLast[fileLast.length - 1] === 'xlsx'
|
const extension2 = fileLast[fileLast.length - 1] === 'xlsx';
|
||||||
const isLt2M = file.size / 1024 / 1024 < 5
|
const isLt2M = file.size / 1024 / 1024 < 5;
|
||||||
|
|
||||||
if (!extension && !extension2) {
|
if (!extension && !extension2) {
|
||||||
message.warning('上传模板只能是 xls、xlsx格式!')
|
message.warning('上传模板只能是 xls、xlsx格式!');
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
if (!isLt2M) {
|
if (!isLt2M) {
|
||||||
message.warning('上传模板大小不能超过 5MB!')
|
message.warning('上传模板大小不能超过 5MB!');
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
fileName.value = file.name
|
fileName.value = file.name;
|
||||||
files = file
|
files = file;
|
||||||
return false // 返回false不会自动上传
|
return false; // 返回false不会自动上传
|
||||||
}
|
};
|
||||||
|
|
||||||
// 提交导入
|
// 提交导入
|
||||||
const submitUpload = async () => {
|
const submitUpload = async () => {
|
||||||
if (!fileName.value || !files) {
|
if (!fileName.value || !files) {
|
||||||
message.warning('请选择要上传的文件!')
|
message.warning('请选择要上传的文件!');
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fileFormData = new FormData()
|
const fileFormData = new FormData();
|
||||||
fileFormData.append('file', files, fileName.value)
|
fileFormData.append('file', files, fileName.value);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await request({
|
const response = await request({
|
||||||
@@ -544,35 +462,35 @@ const submitUpload = async () => {
|
|||||||
method: 'post',
|
method: 'post',
|
||||||
data: fileFormData,
|
data: fileFormData,
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'multipart/form-data'
|
'Content-Type': 'multipart/form-data',
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
if (response.code === 0) {
|
if (response.code === 0) {
|
||||||
message.success('操作成功')
|
message.success('操作成功');
|
||||||
dialogViewVisible.value = false
|
dialogViewVisible.value = false;
|
||||||
getDataList()
|
getDataList();
|
||||||
} else {
|
} else {
|
||||||
message.error(response.msg || '导入失败')
|
message.error(response.msg || '导入失败');
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
message.error(error?.msg || '导入失败')
|
message.error(error?.msg || '导入失败');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// 导出
|
// 导出
|
||||||
const handleExportScore = async () => {
|
const handleExportScore = async () => {
|
||||||
if (!state.queryForm || Object.keys(state.queryForm).length === 0) {
|
if (!state.queryForm || Object.keys(state.queryForm).length === 0) {
|
||||||
message.warning('请选择导出条件')
|
message.warning('请选择导出条件');
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
exportLoading.value = true
|
exportLoading.value = true;
|
||||||
try {
|
try {
|
||||||
const params = {
|
const params = {
|
||||||
...state.queryForm,
|
...state.queryForm,
|
||||||
companyType: "1"
|
companyType: '1',
|
||||||
}
|
};
|
||||||
|
|
||||||
const response = await axios({
|
const response = await axios({
|
||||||
method: 'post',
|
method: 'post',
|
||||||
@@ -580,32 +498,32 @@ const handleExportScore = async () => {
|
|||||||
data: params,
|
data: params,
|
||||||
responseType: 'blob',
|
responseType: 'blob',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json',
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
const blob = new Blob([response.data])
|
const blob = new Blob([response.data]);
|
||||||
const fileName = '培训单位人员导出表.xls'
|
const fileName = '培训单位人员导出表.xls';
|
||||||
const elink = document.createElement('a')
|
const elink = document.createElement('a');
|
||||||
elink.download = fileName
|
elink.download = fileName;
|
||||||
elink.style.display = 'none'
|
elink.style.display = 'none';
|
||||||
elink.href = URL.createObjectURL(blob)
|
elink.href = URL.createObjectURL(blob);
|
||||||
document.body.appendChild(elink)
|
document.body.appendChild(elink);
|
||||||
elink.click()
|
elink.click();
|
||||||
URL.revokeObjectURL(elink.href)
|
URL.revokeObjectURL(elink.href);
|
||||||
document.body.removeChild(elink)
|
document.body.removeChild(elink);
|
||||||
message.success('导出成功')
|
message.success('导出成功');
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
message.error(error?.msg || '导出失败')
|
message.error(error?.msg || '导出失败');
|
||||||
} finally {
|
} finally {
|
||||||
exportLoading.value = false
|
exportLoading.value = false;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// 初始化
|
// 初始化
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loadCompanyList()
|
loadCompanyList();
|
||||||
})
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user