服务指令-树处理

This commit is contained in:
1378012178@qq.com 2025-07-23 08:39:10 +08:00
parent 405fe93f30
commit 49026c45b0
5 changed files with 346 additions and 127 deletions

View File

@ -15,6 +15,8 @@ enum Api {
departList = '/sys/sysDepart/list', departList = '/sys/sysDepart/list',
tree = '/services/serviceDirective/tree', tree = '/services/serviceDirective/tree',
queryById = '/services/serviceDirective/queryById', queryById = '/services/serviceDirective/queryById',
syncMediaForBiz = '/services/serviceDirective/syncMediaForBiz',
syncMediaForAllBiz= '/services/serviceDirective/syncMediaForAllBiz',
} }
/** /**
@ -89,4 +91,20 @@ export const asyncFunc = (params) => {
* @param params * @param params
* @returns * @returns
*/ */
export const tree = () => defHttp.get({ url: Api.tree }); export const tree = () => defHttp.get({ url: Api.tree });
/**
*
* @param params
*/
export const syncMediaForBiz = (params) => {
return defHttp.post({ url: Api.syncMediaForBiz, params });
};
/**
*
* @param params
*/
export const syncMediaForAllBiz = (params) => {
return defHttp.post({ url: Api.syncMediaForAllBiz, params });
};

View File

@ -7,31 +7,31 @@ export const columns: BasicColumn[] = [
align: 'center', align: 'center',
dataIndex: 'instructionTagId_dictText', dataIndex: 'instructionTagId_dictText',
width: 100, width: 100,
customCell: (record, index, column) => { // customCell: (record, index, column) => {
if (record.instructionRowSpan != null) { // if (record.instructionRowSpan != null) {
return { rowSpan: record.instructionRowSpan }; // return { rowSpan: record.instructionRowSpan };
} // }
}, // },
}, },
{ {
title: '服务类别', title: '服务类别',
align: 'center', align: 'center',
dataIndex: 'categoryId_dictText', dataIndex: 'categoryId_dictText',
customCell: (record, index, column) => { // customCell: (record, index, column) => {
if (record.categoryRowSpan != null) { // if (record.categoryRowSpan != null) {
return { rowSpan: record.categoryRowSpan }; // return { rowSpan: record.categoryRowSpan };
} // }
}, // },
}, },
{ {
title: '服务类型', title: '服务类型',
align: 'center', align: 'center',
dataIndex: 'typeId_dictText', dataIndex: 'typeId_dictText',
customCell: (record, index, column) => { // customCell: (record, index, column) => {
if (record.typeRowSpan != null) { // if (record.typeRowSpan != null) {
return { rowSpan: record.typeRowSpan }; // return { rowSpan: record.typeRowSpan };
} // }
}, // },
}, },
{ {
title: '服务指令', title: '服务指令',

View File

@ -75,12 +75,23 @@
<div> <div>
<div style="width:350px;float: left;max-height:77vh; overflow:auto;"> <div style="width:350px;float: left;max-height:77vh; overflow:auto;">
<a-empty v-if="treeLoading" /> <a-empty v-if="treeLoading" />
<a-tree v-else :tree-data="treeData" v-model:expandedKeys="expandedKeys" expandAction="click"> <a-button v-else-if="!treeLoading && treeData.length < 1" type="link" class="btnPrivate" @click="addInstruction"
preIcon="ant-design:plus-outlined">新增分类标签</a-button>
<a-tree v-else :tree-data="treeData" v-model:expandedKeys="expandedKeys" expandAction="click"
@select="handleTreeSelect">
<template #title="{ data }"> <template #title="{ data }">
<span class="node-title" @mouseenter="onNodeEnter(data, data.children)" @mouseleave="onNodeLeave(data)"> <!-- @click.stop="openMenu(data, data.children, $event)" -->
<span v-if="data.level == 4">{{ data?.title + '(' + data?.cycleTypeName + ')' }}</span> <!-- @contextmenu.prevent="openMenu(data, data.children, $event)" -->
<span class="node-title" @mouseenter="onNodeEnter(data, data.children, $event)"
@mouseleave="onNodeLeave(data)">
<div v-if="data.level == 5">
<div><strong>体型标签</strong>{{data?.bodyTagList?.map(tag => tag.tagName).join('、')}}</div>
<div><strong>情绪标签</strong>{{data?.emotionTagList?.map(tag => tag.tagName).join('、')}}</div>
</div>
<span v-else-if="data.level == 4">{{ data?.title + '(' + data?.cycleTypeName + ')' }}</span>
<span v-else>{{ data?.title }}</span> <span v-else>{{ data?.title }}</span>
<span v-if="data?.izEnabled == '1'" style="color:red;">(已停用)</span> <span v-if="data?.izEnabled == '1'" style="color:red;">(已停用)</span>
<!-- 下拉菜单 --> <!-- 下拉菜单 -->
<a-dropdown :open="menuState[data?.key]?.open" @openChange="onMenuOpenChange(data.key, $event)"> <a-dropdown :open="menuState[data?.key]?.open" @openChange="onMenuOpenChange(data.key, $event)">
<template #overlay> <template #overlay>
@ -93,9 +104,9 @@
</a-menu> </a-menu>
</template> </template>
<!-- 图标 --> <!-- 图标 -->
<Icon style="color:#1890FF;" :icon="iconClass(data.level)" class="action-icon" <Icon v-show="data.showIcon && data.level != 5" style="color:#1890FF;" :icon="iconClass(data.level)"
@click.stop="openMenu(data, data.children, $event)" class="action-icon" @mouseenter="onNodeIconEnter(data, data.children)"
@contextmenu.prevent="openMenu(data, data.children, $event)"></Icon> @mouseleave="onNodeIconLeave(data)" />
</a-dropdown> </a-dropdown>
</span> </span>
</template> </template>
@ -106,17 +117,17 @@
<BasicTable @register="registerTable"> <BasicTable @register="registerTable">
<!--插槽:table标题--> <!--插槽:table标题-->
<template #tableTitle> <template #tableTitle>
<a-button type="primary" class="btnPrivate" @click="handleinstructionTag" <!-- <a-button type="primary" class="btnPrivate" @click="handleinstructionTag"
preIcon="tabler:settings">配置分类标签</a-button> preIcon="tabler:settings">配置分类标签</a-button>
<a-button type="primary" class="btnPrivate" @click="handleCategory" <a-button type="primary" class="btnPrivate" @click="handleCategory"
preIcon="tabler:settings">配置服务类别</a-button> preIcon="tabler:settings">配置服务类别</a-button>
<a-button type="primary" class="btnPrivate" @click="handleType" preIcon="tabler:settings">配置服务类型</a-button> <a-button type="primary" class="btnPrivate" @click="handleType" preIcon="tabler:settings">配置服务类型</a-button> -->
<a-button type="primary" class="btnPrivate" @click="handleBodyTag" <a-button type="primary" class="btnPrivate" @click="handleBodyTag"
preIcon="tabler:settings">配置体型标签</a-button> preIcon="tabler:settings">配置体型标签</a-button>
<a-button type="primary" class="btnPrivate" @click="handleEmotionTag" <a-button type="primary" class="btnPrivate" @click="handleEmotionTag"
preIcon="tabler:settings">配置情绪标签</a-button> preIcon="tabler:settings">配置情绪标签</a-button>
<a-button type="primary" class="btnPrivate" @click="handleAdd" <!-- <a-button type="primary" class="btnPrivate" @click="handleAdd"
preIcon="ant-design:plus-outlined">新增服务指令</a-button> preIcon="ant-design:plus-outlined">新增服务指令</a-button> -->
</template> </template>
<!--操作栏--> <!--操作栏-->
<template #action="{ record }"> <template #action="{ record }">
@ -365,6 +376,7 @@ function handleSuperQuery(params) {
*/ */
function handleAdd() { function handleAdd() {
registerModal.value.disableSubmit = false; registerModal.value.disableSubmit = false;
registerModal.value.opeType = 'add';
registerModal.value.add(); registerModal.value.add();
} }
@ -373,6 +385,7 @@ function handleAdd() {
*/ */
function handleEdit(record: Recordable) { function handleEdit(record: Recordable) {
registerModal.value.disableSubmit = false; registerModal.value.disableSubmit = false;
registerModal.value.opeType = 'edit';
registerModal.value.edit(record); registerModal.value.edit(record);
} }
@ -381,6 +394,7 @@ function handleEdit(record: Recordable) {
*/ */
function handleMedia(record: Recordable) { function handleMedia(record: Recordable) {
registerModal.value.disableSubmit = false; registerModal.value.disableSubmit = false;
registerModal.value.opeType = 'editMedia';
registerModal.value.editMedia(record); registerModal.value.editMedia(record);
} }
@ -389,6 +403,7 @@ function handleMedia(record: Recordable) {
*/ */
function handleDetail(record: Recordable) { function handleDetail(record: Recordable) {
registerModal.value.disableSubmit = true; registerModal.value.disableSubmit = true;
registerModal.value.opeType = 'look';
registerModal.value.edit(record); registerModal.value.edit(record);
} }
@ -410,14 +425,14 @@ function getTableAction(record) {
label: '详情', label: '详情',
onClick: handleDetail.bind(null, record), onClick: handleDetail.bind(null, record),
}, },
{ // {
label: '编辑', // label: '',
onClick: handleEdit.bind(null, record) // onClick: handleEdit.bind(null, record)
}, // },
{ // {
label: '指令资源', // label: '',
onClick: handleMedia.bind(null, record) // onClick: handleMedia.bind(null, record)
}, // },
]; ];
} }
@ -429,23 +444,76 @@ function getDropDownAction(record) {
] ]
} }
function expandTreeNodeToLevel4(directiveData: any) {
//
expandedKeys.value = [];
//
const findAndExpandNode = (nodes: any[], level: number, directiveData: any) => {
for (const node of nodes) {
// level directiveData
if (level === 1 && node.instructionId === directiveData.instructionTagId) {
expandedKeys.value.push(node.key);
if (node.children && node.children.length > 0) {
findAndExpandNode(node.children, 2, directiveData);
}
} else if (level === 2 && node.categoryId === directiveData.categoryId) {
expandedKeys.value.push(node.key);
if (node.children && node.children.length > 0) {
findAndExpandNode(node.children, 3, directiveData);
}
} else if (level === 3 && node.typeId === directiveData.typeId) {
expandedKeys.value.push(node.key);
if (node.children && node.children.length > 0) {
findAndExpandNode(node.children, 4, directiveData);
}
} else if (level === 4 && node.key === directiveData.id) {
expandedKeys.value.push(node.key);
}
}
};
//
findAndExpandNode(treeData.value, 1, directiveData);
}
/** /**
* 查询 * 查询
*/ */
function searchQuery() { function searchQuery() {
reload(); reload().then(() => {
const dataSource = getDataSource();
if (dataSource.length === 1) {
const directiveData = dataSource[0]; //
expandTreeNodeToLevel4(directiveData); //
}
});
} }
/** /**
* 重置 * 重置
*/ */
function searchReset() { function searchReset() {
formRef.value.resetFields(); formRef.value.resetFields(); //
selectedRowKeys.value = []; selectedRowKeys.value = []; //
//
reload(); // queryParam
queryParam.instructionTagId = '';
queryParam.categoryId = '';
queryParam.typeId = '';
queryParam.directiveName = ''; //
queryParam.bodyTags = '';
queryParam.emotionTags = '';
queryParam.izEnabled = '';
//
reload().then(() => {
//
expandedKeys.value = [];
setDefaultExpanded(treeData.value);
});
} }
let rangeField = 'tollPrice,comPrice,' let rangeField = 'tollPrice,comPrice,'
/** /**
@ -561,7 +629,6 @@ const playAudio = (url: string) => {
if (audioPlayer.value) { if (audioPlayer.value) {
audioPlayer.value.src = getFileAccessHttpUrl(url); audioPlayer.value.src = getFileAccessHttpUrl(url);
audioPlayer.value.play().catch(e => { audioPlayer.value.play().catch(e => {
console.error('播放失败:', e);
isPlaying.value = false; isPlaying.value = false;
currentPlayingAudio.value = null; currentPlayingAudio.value = null;
}); });
@ -578,7 +645,6 @@ const pauseAudio = () => {
const resumeAudio = () => { const resumeAudio = () => {
if (audioPlayer.value) { if (audioPlayer.value) {
audioPlayer.value.play().catch(e => { audioPlayer.value.play().catch(e => {
console.error('继续播放失败:', e);
}); });
isPlaying.value = true; isPlaying.value = true;
} }
@ -588,7 +654,6 @@ const restartAudio = () => {
if (audioPlayer.value) { if (audioPlayer.value) {
audioPlayer.value.currentTime = 0; audioPlayer.value.currentTime = 0;
audioPlayer.value.play().catch(e => { audioPlayer.value.play().catch(e => {
console.error('重新播放失败:', e);
}); });
isPlaying.value = true; isPlaying.value = true;
} }
@ -608,68 +673,59 @@ const clickCount = ref(0);
const treeChildData = ref<any>([]); const treeChildData = ref<any>([]);
const expandedKeys = ref<string[]>([]); const expandedKeys = ref<string[]>([]);
watch(expandedKeys, () => {
console.log('expandedKeys', expandedKeys);
});
// node hover // node hover
const menuState = reactive<Record<string, { timer?: number, openedByClick: boolean, open: boolean }>>({ const menuState = reactive<Record<string, { timer?: number, openedByClick: boolean, open: boolean }>>({
}) })
function onNodeEnter(node, level, event) {
function onNodeEnter(node, level) { node.showIcon = true
const key = node.key
if (!menuState[key]) {
menuState[key] = { openedByClick: false, open: false }
}
//
if (level <= 3 && !menuState[key].openedByClick) {
menuState[key].timer = window.setTimeout(() => {
menuState[key].open = true
}, 2000)
}
} }
function onNodeLeave(node) { function onNodeLeave(node) {
node.showIcon = false
}
function onNodeIconEnter(node, level) {
//
const key = node.key;
const currentMenuState = menuState[key];
if (currentMenuState?.open) {
//
return;
}
//
if (!menuState[key]) {
menuState[key] = { openedByClick: false, open: false };
}
//
if (level <= 3 && !menuState[key].openedByClick) {
menuState[key].timer = window.setTimeout(() => {
menuState[key].open = true;
}, 2000);
}
}
function onNodeIconLeave(node) {
const s = menuState[node.key] const s = menuState[node.key]
if (s?.timer) { if (s?.timer) {
clearTimeout(s.timer) clearTimeout(s.timer)
delete s.timer delete s.timer
} }
} }
// //
function openMenu(node, level, ev) { function openMenu(node, level, ev) {
closeAllMenus();
const key = node.key const key = node.key
if (!menuState[key]) menuState[key] = { openedByClick: false, open: false } if (!menuState[key]) menuState[key] = { openedByClick: false, open: false }
menuState[key].openedByClick = true menuState[key].openedByClick = true
menuState[key].open = true menuState[key].open = true
} }
//
function onNodeHover(key: string, level: number, enter: boolean) {
if (!menuState[key]) menuState[key] = { open: false, openedByClick: false }
//
if (enter && !menuState[key].openedByClick) {
closeAllMenus()
menuState[key].open = true
}
//
if (!enter && !menuState[key].openedByClick) {
menuState[key].open = false
}
}
//
function onIconClick(key: string, level: number) {
if (!menuState[key]) menuState[key] = { open: false, openedByClick: false }
//
closeAllMenus()
//
menuState[key].openedByClick = !menuState[key].openedByClick
menuState[key].open = menuState[key].openedByClick
}
// Dropdown openChange // Dropdown openChange
function onMenuOpenChange(key: string, open: boolean) { function onMenuOpenChange(key: string, open: boolean) {
if (!menuState[key]) menuState[key] = { open: false, openedByClick: false } if (!menuState[key]) menuState[key] = { open: false, openedByClick: false }
@ -746,6 +802,12 @@ function editDirective(data) {
registerModal.value.disableSubmit = false; registerModal.value.disableSubmit = false;
registerModal.value.queryByIdFunc(data.key); registerModal.value.queryByIdFunc(data.key);
} }
//
function editMedia(data) {
registerModal.value.disableSubmit = false;
registerModal.value.opeType = 'editMedia';
registerModal.value.queryAndEditMedia(data.key);
}
// //
function usingDirective(data) { function usingDirective(data) {
registerModal.value.usingOrStop(data.key, '0'); registerModal.value.usingOrStop(data.key, '0');
@ -754,7 +816,14 @@ function usingDirective(data) {
function stopDirective(data) { function stopDirective(data) {
registerModal.value.usingOrStop(data.key, '1'); registerModal.value.usingOrStop(data.key, '1');
} }
//
function bodyTagsDetail(data) {
}
//
function emotionTagsDetail(data) {
}
// //
function menuItems(data) { function menuItems(data) {
if (data.level === 1) { if (data.level === 1) {
@ -802,6 +871,7 @@ function menuItems(data) {
else if (data.level === 4) { else if (data.level === 4) {
const items = [ const items = [
{ key: 'editDir', label: '编辑服务指令', icon: 'ant-design:edit-outlined', action: editDirective }, { key: 'editDir', label: '编辑服务指令', icon: 'ant-design:edit-outlined', action: editDirective },
{ key: 'editMedia', label: '编辑指令资源', icon: 'ant-design:edit-outlined', action: editMedia },
] ]
if (data.canAdd) { if (data.canAdd) {
items.push({ key: 'addDir', label: '新增服务指令', icon: 'ant-design:plus-outlined', action: addDirective }) items.push({ key: 'addDir', label: '新增服务指令', icon: 'ant-design:plus-outlined', action: addDirective })
@ -811,6 +881,12 @@ function menuItems(data) {
} else if (data.izEnabled === '0') { } else if (data.izEnabled === '0') {
items.push({ key: 'stopDir', label: '停用服务指令', icon: 'ant-design:stop-outlined', action: stopDirective }) items.push({ key: 'stopDir', label: '停用服务指令', icon: 'ant-design:stop-outlined', action: stopDirective })
} }
if (data?.bodyTagList?.length > 0) {
items.push({ key: 'bodyTagsDetail', label: '查看体型标签', icon: 'ant-design:stop-outlined', action: bodyTagsDetail })
}
if (data?.emotionTagList?.length > 0) {
items.push({ key: 'emotionTagsDetail', label: '查看情绪标签', icon: 'ant-design:stop-outlined', action: emotionTagsDetail })
}
return items return items
} }
return [] return []
@ -819,21 +895,56 @@ function menuItems(data) {
// key // key
function setDefaultExpanded(nodes: any[]) { function setDefaultExpanded(nodes: any[]) {
if (!nodes?.length) return expandedKeys.value.push(nodes[0].key)
const first = nodes[0] expandedKeys.value.push(nodes[0]?.children?.[0]?.key)
expandedKeys.value.push(first.key) expandedKeys.value.push(nodes[0]?.children?.[0]?.children?.[0]?.key)
if (first.children?.length) {
setDefaultExpanded(first.children)
}
} }
const treeLoading = ref(false) const treeLoading = ref(false)
function reloadTree() { function reloadTree() {
console.log(3333)
tree().then(res => { tree().then(res => {
treeData.value = res; treeData.value = res;
}) })
} }
function handleTreeSelect(selectedKeys: string[], { node }: any) {
const level = node.level;
//
queryParam.directiveName = '';
queryParam.bodyTags = '';
queryParam.emotionTags = '';
queryParam.izEnabled = '';
//
switch (level) {
case 1: //
queryParam.instructionTagId = node.instructionId;
queryParam.categoryId = '';
queryParam.typeId = '';
break;
case 2: //
queryParam.instructionTagId = node.instructionId;
queryParam.categoryId = node.categoryId;
queryParam.typeId = '';
break;
case 3: //
queryParam.instructionTagId = node.instructionId;
queryParam.categoryId = node.categoryId;
queryParam.typeId = node.typeId;
break;
case 4: //
//
queryParam.instructionTagId = node.instructionId;
queryParam.categoryId = node.categoryId;
queryParam.typeId = node.typeId;
queryParam.directiveName = node.title;
break;
}
if (level == 5) return
//
searchQuery();
}
// //
onMounted(() => { onMounted(() => {
if (audioPlayer.value) { if (audioPlayer.value) {
@ -909,4 +1020,18 @@ audio::-webkit-media-controls-time-remaining-display {
margin-left: 4px; margin-left: 4px;
cursor: pointer; cursor: pointer;
} }
:deep(.centered-dropdown) {
position: fixed;
left: 50% !important;
top: 50% !important;
transform: translate(-50%, -50%) !important;
max-height: 80vh;
overflow-y: auto;
.ant-dropdown-menu {
max-height: 70vh;
overflow-y: auto;
}
}
</style> </style>

View File

@ -10,15 +10,13 @@
id="ConfigServiceDirectiveForm-instructionTagId" name="instructionTagId"> id="ConfigServiceDirectiveForm-instructionTagId" name="instructionTagId">
<j-dict-select-tag v-model:value="formData.instructionTagId" <j-dict-select-tag v-model:value="formData.instructionTagId"
:dictCode="`nu_config_service_instruction_tag,instruction_name,id,del_flag = 0 order by sort asc`" :dictCode="`nu_config_service_instruction_tag,instruction_name,id,del_flag = 0 order by sort asc`"
placeholder="请选择分类标签" allowClear @upDictCode="upInstructionDictCode" placeholder="请选择分类标签" allowClear @upDictCode="upInstructionDictCode" :disabled="!!formData.id" />
:disabled="!!formData.id && formData.status == 0" />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="12"> <a-col :span="12">
<a-form-item label="服务类别" v-bind="validateInfos.categoryId" id="ConfigServiceDirectiveForm-categoryId" <a-form-item label="服务类别" v-bind="validateInfos.categoryId" id="ConfigServiceDirectiveForm-categoryId"
name="categoryId"> name="categoryId">
<j-dict-select-tag type="list" v-model:value="formData.categoryId" <j-dict-select-tag type="list" v-model:value="formData.categoryId" :disabled="!!formData.id"
:disabled="!formData.instructionTagId || (!!formData.id && formData.status == 0)"
:dictCode="categoryDictCode" placeholder="请选择服务类别" allow-clear @upDictCode="upCategoryDictCode" /> :dictCode="categoryDictCode" placeholder="请选择服务类别" allow-clear @upDictCode="upCategoryDictCode" />
</a-form-item> </a-form-item>
</a-col> </a-col>
@ -26,15 +24,14 @@
<a-form-item label="服务类型" v-bind="validateInfos.typeId" id="ConfigServiceDirectiveForm-typeId" <a-form-item label="服务类型" v-bind="validateInfos.typeId" id="ConfigServiceDirectiveForm-typeId"
name="typeId"> name="typeId">
<j-dict-select-tag type="list" v-model:value="formData.typeId" :dictCode="typeDictCode" <j-dict-select-tag type="list" v-model:value="formData.typeId" :dictCode="typeDictCode"
:disabled="!formData.categoryId || (!!formData.id && formData.status == 0)" placeholder="请选择服务类型" :disabled="!!formData.id" placeholder="请选择服务类型" allowClear @upDictCode="upTypeDictCode" />
allowClear @upDictCode="upTypeDictCode" />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="12"> <a-col :span="12">
<a-form-item label="服务指令名称" v-bind="validateInfos.directiveName" <a-form-item label="服务指令名称" v-bind="validateInfos.directiveName"
id="ConfigServiceDirectiveForm-directiveName" name="directiveName"> id="ConfigServiceDirectiveForm-directiveName" name="directiveName">
<a-input v-model:value="formData.directiveName" placeholder="请输入服务指令名称" allow-clear <a-input v-model:value="formData.directiveName" placeholder="请输入服务指令名称" allow-clear
:disabled="!!formData.id && formData.status == 0"></a-input> :disabled="!!formData.id"></a-input>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="12"> <a-col :span="12">
@ -69,8 +66,7 @@
<a-form-item label="周期类型" v-bind="validateInfos.cycleType" id="ConfigServiceDirectiveForm-cycleType" <a-form-item label="周期类型" v-bind="validateInfos.cycleType" id="ConfigServiceDirectiveForm-cycleType"
name="cycleType"> name="cycleType">
<j-dict-select-tag type="list" v-model:value="formData.cycleType" dictCode="period_type" <j-dict-select-tag type="list" v-model:value="formData.cycleType" dictCode="period_type"
placeholder="请选择周期类型" allowClear @upDictCode="upCycleTypeDictCode" placeholder="请选择周期类型" allowClear @upDictCode="upCycleTypeDictCode" :disabled="!!formData.id" />
:disabled="!!formData.id && formData.status == 0" />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="12"> <a-col :span="12">
@ -105,11 +101,11 @@
</a-form-item> </a-form-item>
</a-col> </a-col>
</a-row> </a-row>
<a-row v-if="disabled"> <a-row>
<a-col :span="12"> <a-col :span="12">
<a-form-item label="服务指令图片" v-bind="validateInfos.previewFile"> <a-form-item label="服务指令图片" v-bind="validateInfos.previewFile">
<span v-if="!formData.previewFile">无文件</span> <span v-if="disabled && !formData.previewFile">无文件</span>
<JImageUpload v-else :fileMax="1" v-model:value="formData.previewFile" disabled <JImageUpload v-else :fileMax="1" v-model:value="formData.previewFile"
:bizPath="formComputedData.mediaFileSavePath"> :bizPath="formComputedData.mediaFileSavePath">
</JImageUpload> </JImageUpload>
</a-form-item> </a-form-item>
@ -117,57 +113,60 @@
<a-col :span="12"> <a-col :span="12">
<a-form-item label="服务指令描述" v-bind="validateInfos.serviceContent" <a-form-item label="服务指令描述" v-bind="validateInfos.serviceContent"
id="ConfigServiceDirectiveForm-serviceContent" name="serviceContent"> id="ConfigServiceDirectiveForm-serviceContent" name="serviceContent">
<span v-if="!formData.serviceContent">暂无描述</span> <a-textarea v-model:value="formData.serviceContent" :rows="2" placeholder="请输入服务指令描述" />
<a-textarea v-else v-model:value="formData.serviceContent" :rows="2" disabled />
</a-form-item> </a-form-item>
</a-col> </a-col>
</a-row> </a-row>
<!-- <a-row v-if="formData.izEnabled == 0 || formData.izEnabled == 1"> <a-row v-show="!disabled">
<a-col :span="12"> <a-col :span="12">
<a-form-item label="指令音频文件" v-bind="validateInfos.mp3File" id="ConfigServiceDirectiveForm-mp3File"> <a-form-item label="指令音频文件" v-bind="validateInfos.mp3File" id="ConfigServiceDirectiveForm-mp3File">
<span v-if="!formData.mp3File">无文件</span> <j-upload v-model:value="formData.mp3File" accept=".mp3" :maxCount="1"
<j-upload v-else v-model:value="formData.mp3File" accept=".mp3" :maxCount="1" disabled
:bizPath="formComputedData.mediaFileSavePath"></j-upload> :bizPath="formComputedData.mediaFileSavePath"></j-upload>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="12"> <a-col :span="12">
<a-form-item label="指令视频文件" v-bind="validateInfos.mp4File" id="ConfigServiceDirectiveForm-mp4File"> <a-form-item label="指令视频文件" v-bind="validateInfos.mp4File" id="ConfigServiceDirectiveForm-mp4File">
<span v-if="!formData.mp4File">无文件</span> <j-upload v-model:value="formData.mp4File" accept=".mp4" :maxCount="1"
<j-upload v-else v-model:value="formData.mp4File" accept=".mp4" :maxCount="1" disabled
:bizPath="formComputedData.mediaFileSavePath"></j-upload> :bizPath="formComputedData.mediaFileSavePath"></j-upload>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-row> </a-row>
</a-row>
</a-row> -->
</a-form> </a-form>
</template> </template>
</JFormContainer> </JFormContainer>
<JFormContainer v-if="disabled"> <JFormContainer style="margin-top: -40px;">
<template #detail> <template #detail>
<a-form ref="formRef" class="antd-modal-form" :labelCol="labelCol" :wrapperCol="wrapperCol" <a-form ref="formRef" class="antd-modal-form" :labelCol="labelCol" :wrapperCol="wrapperCol"
name="ConfigServiceDirectiveForm"> name="ConfigServiceDirectiveForm">
<a-row> <a-row>
<a-col :span="12"> <a-col :span="12" v-if="!!formData.mp3File">
<a-form-item label="指令音频文件" id="ConfigServiceDirectiveForm-mp3File"> <a-form-item label="指令音频预览" id="ConfigServiceDirectiveForm-mp3File">
<span v-if="!formData.mp3File">无文件</span> <audio controls disabled="false">
<audio v-else controls disabled="false">
<source :src="getFileAccessHttpUrl(formData.mp3File)"> <source :src="getFileAccessHttpUrl(formData.mp3File)">
</audio> </audio>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="12"> <a-col :span="12" v-if="disabled && !formData.mp3File">
<a-form-item label="指令视频文件" id="ConfigServiceDirectiveForm-mp4File"> <a-form-item label="指令音频预览">
<span v-if="!formData.mp4File">无文件</span> <span>暂无文件</span>
<video v-else controls> </a-form-item>
</a-col>
<a-col :span="12" v-if="!!formData.mp4File" :push="!!formData.mp3File ? 0 : 12">
<a-form-item label="指令视频预览" id="ConfigServiceDirectiveForm-mp4File">
<video controls>
<source :src="getFileAccessHttpUrl(formData.mp4File)"> <source :src="getFileAccessHttpUrl(formData.mp4File)">
</video> </video>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="12" v-if="disabled && !formData.mp3File">
<a-form-item label="指令视频预览">
<span>暂无文件</span>
</a-form-item>
</a-col>
<a-col :span="12"> <a-col :span="12">
<a-form-item label="即时指令图标" v-bind="validateInfos.immediateFile"> <a-form-item label="即时指令图标" v-bind="validateInfos.immediateFile">
<span v-if="!formData.immediateFile">无文件</span> <span v-if="disabled && !formData.immediateFile">无文件</span>
<JImageUpload v-else :fileMax="1" v-model:value="formData.immediateFile" disabled <JImageUpload v-else :fileMax="1" v-model:value="formData.immediateFile"
:bizPath="formComputedData.mediaFileSavePath"> :bizPath="formComputedData.mediaFileSavePath">
</JImageUpload> </JImageUpload>
</a-form-item> </a-form-item>
@ -188,7 +187,7 @@ import { JCheckbox } from '/@/components/Form';
import JUpload from '/@/components/Form/src/jeecg/components/JUpload/JUpload.vue'; import JUpload from '/@/components/Form/src/jeecg/components/JUpload/JUpload.vue';
import JImageUpload from '/@/components/Form/src/jeecg/components/JImageUpload.vue'; import JImageUpload from '/@/components/Form/src/jeecg/components/JImageUpload.vue';
import { getValueType } from '/@/utils'; import { getValueType } from '/@/utils';
import { saveOrUpdate } from '../ConfigServiceDirective.api'; import { saveOrUpdate, syncMediaForBiz, syncMediaForAllBiz } from '../ConfigServiceDirective.api';
import { Form } from 'ant-design-vue'; import { Form } from 'ant-design-vue';
import JFormContainer from '/@/components/Form/src/container/JFormContainer.vue'; import JFormContainer from '/@/components/Form/src/container/JFormContainer.vue';
import { getFileAccessHttpUrl } from '/@/utils/common/compUtils'; import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
@ -461,6 +460,8 @@ async function submitForm() {
return return
} }
model.mediaFileSavePath = formComputedData.value.mediaFileSavePath
await saveOrUpdate(model, isUpdate.value) await saveOrUpdate(model, isUpdate.value)
.then((res) => { .then((res) => {
if (res.success) { if (res.success) {
@ -475,11 +476,45 @@ async function submitForm() {
}); });
} }
/**
* 同步媒体资源给指令所有者对应业务平台
*
*/
function syncMediaForBizFunc() {
formData.mediaFileSavePath = formComputedData.value.mediaFileSavePath
syncMediaForBiz(formData)
.then((res) => {
createMessage.success('操作成功!');
emit('ok');
})
.finally(() => {
confirmLoading.value = false;
});
}
/**
* 同步媒体资源给所有业务平台
*
*/
function syncMediaForAllBizFunc() {
formData.mediaFileSavePath = formComputedData.value.mediaFileSavePath
syncMediaForAllBiz(formData)
.then((res) => {
createMessage.success('操作成功!');
emit('ok');
})
.finally(() => {
confirmLoading.value = false;
});
}
defineExpose({ defineExpose({
add, add,
edit, edit,
submitForm, submitForm,
syncMediaForBizFunc,
syncMediaForAllBizFunc
}); });
</script> </script>

View File

@ -4,9 +4,10 @@
:maskClosable="false"> :maskClosable="false">
<template #footer> <template #footer>
<a-button @click="handleCancel">关闭</a-button> <a-button @click="handleCancel">关闭</a-button>
<a-button @click="handleOk" :loading="loading">确定</a-button> <a-button @click="handleOk"
<!-- <a-button @click="handleOk" v-show="opeType == 'edit' || opeType == 'audit'">确定</a-button> v-show="opeType == 'add' || opeType == 'edit' || opeType == 'audit' || opeType == 'audit' || opeType == 'editMedia'"
<a-button @click="handleSave" v-show="opeType == 'editMedia' || opeType == 'auditMedia'">暂存</a-button> :loading="loading">确定</a-button>
<!-- <a-button @click="handleSave" v-show="opeType == 'editMedia' || opeType == 'auditMedia'">暂存</a-button>
<a-button type="primary" @click="handleMediaAsync" v-show="opeType == 'auditMedia'">同步</a-button> <a-button type="primary" @click="handleMediaAsync" v-show="opeType == 'auditMedia'">同步</a-button>
<a-button type="primary" @click="handleMediaSyncAllPlat" v-show="opeType == 'editMedia'">同步</a-button> --> <a-button type="primary" @click="handleMediaSyncAllPlat" v-show="opeType == 'editMedia'">同步</a-button> -->
</template> </template>
@ -33,7 +34,7 @@ const visible = ref<boolean>(false);
const disableSubmit = ref<boolean>(false); const disableSubmit = ref<boolean>(false);
const registerForm = ref(); const registerForm = ref();
const emit = defineEmits(['register', 'success']); const emit = defineEmits(['register', 'success']);
const opeType = ref('')// add edit editMedia- look audit auditMedia-
/** /**
* 新增 * 新增
@ -58,6 +59,23 @@ function edit(record) {
}); });
} }
/**
* 编辑指令资源
* @param record
*/
function queryAndEditMedia(id) {
title.value = '编辑指令资源';
visible.value = true;
nextTick(() => {
loading.value = true
queryById({ id }).then(res => {
registerForm.value.edit(res, true);
}).finally(() => {
loading.value = false
})
});
}
/** /**
* 编辑指令资源 * 编辑指令资源
* @param record * @param record
@ -77,6 +95,27 @@ function handleOk() {
registerForm.value.submitForm(); registerForm.value.submitForm();
} }
/**
* 暂存
*/
function handleSave() {
registerForm.value.submitForm();
}
/**
* 给审核对应的业务平台同步资源
*/
function handleMediaAsync() {
registerForm.value.syncMediaForBizFunc();
}
/**
* 给所有业务平台同步资源
*/
function handleMediaSyncAllPlat() {
registerForm.value.syncMediaForAllBizFunc();
}
/** /**
* form保存回调事件 * form保存回调事件
*/ */
@ -123,6 +162,8 @@ defineExpose({
disableSubmit, disableSubmit,
usingOrStop, usingOrStop,
queryByIdFunc, queryByIdFunc,
opeType,
queryAndEditMedia,
}); });
</script> </script>