Commit 28953717 by haojie

1

parent 10705f77
...@@ -93,6 +93,9 @@ ...@@ -93,6 +93,9 @@
<template #type="{ row }"> <template #type="{ row }">
<slot name="type" :row="row"> </slot> <slot name="type" :row="row"> </slot>
</template> </template>
<template #status="{ row }">
<slot name="status" :row="row"> </slot>
</template>
<template #content="{ row }"> <template #content="{ row }">
<slot name="content" :row="row"></slot> <slot name="content" :row="row"></slot>
</template> </template>
...@@ -196,20 +199,33 @@ onMounted(() => { ...@@ -196,20 +199,33 @@ onMounted(() => {
}); });
// 过滤出表格id // 过滤出表格id
const filterTableId = () => { const filterTable = () => {
const is_array = DataType('array', SelectedRows.value); let params: any = {};
if (is_array) { const option = props.form.delete_options ?? [{ key: 'id', value: 'ids' }];
let ids = ''; if (option) {
// 开始过滤 // 扩展字段
SelectedRows.value.forEach((item: any) => { const is_array = DataType('array', SelectedRows.value);
if (item.id) { if (is_array) {
ids += item.id + '' + ','; let ids = [];
} // 开始过滤
}); SelectedRows.value.forEach((item: any) => {
return ids; option.forEach((it: any) => {
} else { if (item[it.key]) {
show_message('格式错误'); // 存在这个参数
if (!params[it.value]) {
params[it.value] = [];
}
if (params[it.value]) {
params[it.value].push(item[it.key]);
}
}
});
});
} else {
show_message('格式错误');
}
} }
return params;
}; };
// 多选事件触发 // 多选事件触发
...@@ -217,14 +233,14 @@ const MultiSelectEvent = async (item: any) => { ...@@ -217,14 +233,14 @@ const MultiSelectEvent = async (item: any) => {
if (item.value == 'delete') { if (item.value == 'delete') {
const { form } = props; const { form } = props;
loading.value = true; loading.value = true;
const ids = filterTableId(); const params = filterTable();
const stauts = await form.delete_api({ const stauts = await form.delete_api(params);
ids: ids,
});
loading.value = false; loading.value = false;
if (stauts) { if (stauts) {
// 更新表格数据 // 更新表格数据
table_num.value += 1; table_num.value += 1;
// 清空多选项
SelectedRows.value = [];
} }
} }
}; };
......
...@@ -369,12 +369,13 @@ const formatTime = (value: string) => { ...@@ -369,12 +369,13 @@ const formatTime = (value: string) => {
display: flex; display: flex;
.audio-player-left { .audio-player-left {
max-width: 92%; max-width: 92%;
flex: 1;
} }
.check-audio-box { .check-audio-box {
width: 8%;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
flex: 1;
:deep(.check-audio) { :deep(.check-audio) {
.t-checkbox__input { .t-checkbox__input {
border: 1px solid #ffffff; border: 1px solid #ffffff;
......
<template> <template>
<div class="admin-page-edit-parent custom-scrollbar"> <div class="admin-page-edit-parent narrow-scrollbar">
<div class="custom-admin-page-edit"> <div class="custom-admin-page-edit">
<div class="admin-page-header"> <div class="admin-page-header">
<div> <div>
...@@ -59,67 +59,73 @@ ...@@ -59,67 +59,73 @@
v-for="it in item.lists" v-for="it in item.lists"
:key="it.name" :key="it.name"
> >
<div class="label"> <template v-if="!it.is_hidden">
{{ it.label }} <div class="label">
</div> {{ it.label }}
<div class="value"> </div>
<template v-if="it.type == 'text'"> <div class="value">
<CustomInput <template v-if="it.type == 'text'">
align="left" <CustomInput
class="edit-input" align="left"
width="100%" class="edit-input"
v-model="it.value" width="100%"
:placeholder="it.placeholder" v-model="it.value"
:disabled="it.disabled ? it.disabled : false" :placeholder="it.placeholder"
> :disabled="it.disabled ? it.disabled : false"
<template #rightIcon> >
<template v-if="!it.disabled"> <template #rightIcon>
<span class="input-right-icon"> <template v-if="!it.disabled">
<EditInputSvg></EditInputSvg> <span class="input-right-icon">
</span> <EditInputSvg></EditInputSvg>
</span>
</template>
</template> </template>
</template> </CustomInput>
</CustomInput> </template>
</template> <template v-else-if="it.type == 'select'">
<template v-else-if="it.type == 'select'"> <CustomSelect
<CustomSelect :options="it.options"
:options="it.options" :name="it.name"
:name="it.name" v-model="it.value"
v-model="it.value" :item="{}"
:item="{}" :align="it.align"
:align="it.align" :audio="it.audio"
:audio="it.audio" :audio_list="audio_list"
:audio_list="[]" :is_watch="it.watch ? it.watch : false"
:is_watch="it.watch ? it.watch : false" width="100%"
width="100%" :multiple="it.multiple ? it.multiple : false"
@change="SelectChange" @change="SelectChange"
@ValueChange="SelectValueChange" @ValueChange="SelectValueChange"
></CustomSelect> ></CustomSelect>
</template> </template>
<template v-else-if="it.type == 'textarea'"> <template v-else-if="it.type == 'textarea'">
<CustomTextarea <CustomTextarea
v-model="it.value" v-model="it.value"
:maxlength="it.maxlength ?? null" :maxlength="it.maxlength ?? null"
:disabled="form.is_send ? form.is_send.disabled : false" :disabled="
></CustomTextarea> form.is_send ? form.is_send.disabled : false
</template> "
<template v-else-if="it.type == 'number'"> ></CustomTextarea>
<CustomInput </template>
type="number" <template v-else-if="it.type == 'number'">
align="left" <CustomInput
class="edit-input" type="number"
v-model="it.value" align="left"
:placeholder="it.placeholder" width="100%"
:disabled="it.disabled ? it.disabled : false" class="edit-input"
> v-model="it.value"
<template #rightIcon> :placeholder="it.placeholder"
<template v-if="!it.disabled"> :disabled="it.disabled ? it.disabled : false"
<span class="input-right-icon"> M </span> >
<template #rightIcon>
<template v-if="!it.disabled">
<span class="input-right-icon"> M </span>
</template>
</template> </template>
</template> </CustomInput>
</CustomInput> </template>
</template> </div>
</div> </template>
</div> </div>
</div> </div>
</template> </template>
...@@ -194,10 +200,17 @@ import ManualResponseSvg from '@/assets/svg/form/ManualResponse.svg'; ...@@ -194,10 +200,17 @@ import ManualResponseSvg from '@/assets/svg/form/ManualResponse.svg';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { show_message } from '@/utils/tdesign_tool'; import { show_message } from '@/utils/tdesign_tool';
import { getFormParams } from '@/constants/admin_form'; import { getFormParams } from '@/constants/admin_form';
import { reactive, ref } from 'vue'; import { ref } from 'vue';
const props = defineProps<{ const props = withDefaults(
form: any; defineProps<{
}>(); form: any;
audio_list?: any[];
}>(),
{
audio_list: () => [],
}
);
const emit = defineEmits(['ConfigChange']);
const router = useRouter(); const router = useRouter();
const loading = ref(false); const loading = ref(false);
// 弹窗状态 // 弹窗状态
...@@ -225,18 +238,22 @@ const onSend = () => { ...@@ -225,18 +238,22 @@ const onSend = () => {
// 下拉框事件 // 下拉框事件
const SelectChange = (value: string, fun: any) => { const SelectChange = (value: string, fun: any) => {
console.log(value);
fun(value); fun(value);
}; };
// 开始转换语音 // 开始转换语音
const StartConvert = () => { const StartConvert = async () => {
const { form } = props; const { form } = props;
// 校验表单完整性 // 校验表单完整性
let params = getFormParams(form.form_options); let params = getFormParams(form.form_options);
if (!params) { if (!params) {
return; return;
} }
form.conversion.method(params, form.page_name); loading.value = true;
// 请求语音
await form.conversion.method(params, form.page_name);
loading.value = false;
}; };
// 提交接口 // 提交接口
...@@ -257,12 +274,18 @@ const realDelete = async () => { ...@@ -257,12 +274,18 @@ const realDelete = async () => {
const { form } = props; const { form } = props;
loading.value = true; loading.value = true;
// 获取当前id // 获取当前id
await form.delete_api( if (form.get_params) {
{ // 自定义参数
ids: form.get_id(), await form.delete_api(form.get_params(), form.back_url);
}, } else {
form.back_url await form.delete_api(
); {
ids: form.get_id(),
},
form.back_url
);
}
loading.value = false; loading.value = false;
}; };
...@@ -276,16 +299,11 @@ const onDelete = async () => { ...@@ -276,16 +299,11 @@ const onDelete = async () => {
realDelete(); realDelete();
} }
}; };
// 记录当前语音和语言
const CurrentConfig = reactive({
language: '',
voice: '',
});
// 语音列表 // 语音列表
const SelectValueChange = (name: string, value: string) => { const SelectValueChange = (name: string, value: string) => {
if (name == 'language' || name == 'voice') { if (name == 'language' || (name == 'voice' && props.form.audition)) {
CurrentConfig[name] = value; emit('ConfigChange', name, value);
} }
}; };
</script> </script>
......
...@@ -10,9 +10,15 @@ ...@@ -10,9 +10,15 @@
alt="" alt=""
class="play-icon" class="play-icon"
@click="onPlay" @click="onPlay"
v-if="!playStatus" v-show="!playStatus"
/>
<img
:src="imgs.stop"
alt=""
class="play-icon"
@click="onPause"
v-show="playStatus"
/> />
<img :src="imgs.stop" alt="" class="play-icon" @click="onPause" v-else />
<template v-if="need_progress"> <template v-if="need_progress">
<span class="play-time"> <span class="play-time">
{{ transTime(audioCurrent) }}/{{ transTime(audioDuration) }} {{ transTime(audioCurrent) }}/{{ transTime(audioDuration) }}
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
v-model="SelectValue" v-model="SelectValue"
:placeholder="item.placeholder" :placeholder="item.placeholder"
:filterable="filterable" :filterable="filterable"
:multiple="multiple"
:popupProps="{ :popupProps="{
overlayClassName: [className, 'admin-select-popup'], overlayClassName: [className, 'admin-select-popup'],
}" }"
...@@ -40,7 +41,7 @@ const props = withDefaults( ...@@ -40,7 +41,7 @@ const props = withDefaults(
defineProps<{ defineProps<{
item?: any; item?: any;
options: any[]; options: any[];
modelValue: number | string; modelValue: number | string | string[];
width?: string; width?: string;
className?: string; className?: string;
align?: string; align?: string;
...@@ -49,6 +50,7 @@ const props = withDefaults( ...@@ -49,6 +50,7 @@ const props = withDefaults(
filterable?: boolean; filterable?: boolean;
audio_list?: string[]; audio_list?: string[];
name?: string; name?: string;
multiple?: boolean;
}>(), }>(),
{ {
width: '357px', width: '357px',
...@@ -57,6 +59,7 @@ const props = withDefaults( ...@@ -57,6 +59,7 @@ const props = withDefaults(
is_watch: false, is_watch: false,
filterable: false, filterable: false,
audio_list: () => [], audio_list: () => [],
multiple: false,
} }
); );
const emit = defineEmits(['update:modelValue', 'change', 'ValueChange']); const emit = defineEmits(['update:modelValue', 'change', 'ValueChange']);
...@@ -89,6 +92,22 @@ watch( ...@@ -89,6 +92,22 @@ watch(
} }
.t-select__list { .t-select__list {
padding: 0; padding: 0;
.t-checkbox {
.t-checkbox__label {
color: #00dddd;
}
.t-checkbox__input {
background: transparent;
}
}
.t-is-selected {
.t-checkbox__input {
border-color: #00dddd;
&::after {
border-color: #00dddd;
}
}
}
.t-select-option { .t-select-option {
color: white; color: white;
--ripple-color: #00dddd; --ripple-color: #00dddd;
...@@ -99,11 +118,26 @@ watch( ...@@ -99,11 +118,26 @@ watch(
color: #00dddd; color: #00dddd;
background: #161616 !important; background: #161616 !important;
} }
.t-select-option__hover {
.t-checkbox {
.t-checkbox__input {
border-color: #00dddd !important;
}
.t-checkbox__label {
color: #00dddd;
}
}
}
} }
} }
.custom-admin-select { .custom-admin-select {
display: flex; display: flex;
align-items: center; align-items: center;
.t-select-input--multiple {
.t-input--focused {
box-shadow: 0px 0px 0px 1px #00dddd;
}
}
.select-label { .select-label {
color: white; color: white;
width: 60px; width: 60px;
...@@ -137,6 +171,12 @@ watch( ...@@ -137,6 +171,12 @@ watch(
.t-fake-arrow { .t-fake-arrow {
color: #00dddd; color: #00dddd;
} }
.t-input__prefix {
display: flex;
.t-tag {
background: #00dddd;
}
}
} }
} }
} }
......
...@@ -39,6 +39,11 @@ ...@@ -39,6 +39,11 @@
{{ row.type }} {{ row.type }}
</slot> </slot>
</template> </template>
<template #status="{ row }">
<slot name="status" :row="row">
{{ row.status }}
</slot>
</template>
<template #edit="{ row }"> <template #edit="{ row }">
<slot name="edit" :row="row"> <slot name="edit" :row="row">
<span class="edit-text" @click="onEdit(row)">编辑</span> <span class="edit-text" @click="onEdit(row)">编辑</span>
......
import { getLocalData, setLocalData } from '@/utils/tool'; import { DataType, getLocalData, setLocalData } from '@/utils/tool';
import router from '@/router'; import router from '@/router';
import { show_message } from '@/utils/tdesign_tool'; import { show_message } from '@/utils/tdesign_tool';
import { Validationrules } from '@/utils/tool'; import { Validationrules } from '@/utils/tool';
import { DeleteVioce } from '@/utils/api/ai'; import {
DeleteVioce,
InteractionTableDelete,
getLiveStreamConfig,
LiveStreamTableDelete,
} from '@/utils/api/ai';
// 语音列表 // 语音列表
export const voice_list = [ export const voice_list = [
{ {
...@@ -67,8 +72,18 @@ export const language_type = { ...@@ -67,8 +72,18 @@ export const language_type = {
// 互动类型 // 互动类型
export const interaction_type = { export const interaction_type = {
'0': '直播互动', '0': '直播互动', // 串场互动
'0_': 'crosstown', // name
'1': '自动回复', '1': '自动回复',
'1_': 'auto',
};
// 直播管理-状态
export const live_stream_status = {
'1': '等待',
'2': '进行中',
'3': '完成',
'4': '失败',
}; };
// 任务类型 // 任务类型
...@@ -83,6 +98,10 @@ export const getFormParams = (list: any[]) => { ...@@ -83,6 +98,10 @@ export const getFormParams = (list: any[]) => {
// 遍历整个列表 // 遍历整个列表
for (let i = 0; i < list.length; i++) { for (let i = 0; i < list.length; i++) {
const item: any = list[i]; const item: any = list[i];
if (item.is_hidden) {
// 隐藏的内容不参与
continue;
}
for (let j = 0; j < item.lists.length; j++) { for (let j = 0; j < item.lists.length; j++) {
const it = item.lists[j]; const it = item.lists[j];
// 校验规则 // 校验规则
...@@ -161,8 +180,22 @@ export const EditFillData = (form: any[], row: any) => { ...@@ -161,8 +180,22 @@ export const EditFillData = (form: any[], row: any) => {
// 查找name相同的字段 // 查找name相同的字段
Object.keys(row).forEach((key: string) => { Object.keys(row).forEach((key: string) => {
if (it.name == key) { if (it.name == key) {
// 填充数据 if (
it.value = row[key] + ''; typeof row[key] === 'string' &&
(row[key] + '').indexOf('[') !== -1 &&
DataType('array', it.value)
) {
const list = JSON.parse(row[key]);
list.forEach((list_item: any) => {
it.value.push(list_item);
});
} else if (
typeof row[key] === 'string' ||
typeof row[key] === 'number'
) {
// 填充数据
it.value = row[key] + '';
}
} }
}); });
}); });
...@@ -194,6 +227,29 @@ export const FilterConfigFill = (resData: any, form: any[]) => { ...@@ -194,6 +227,29 @@ export const FilterConfigFill = (resData: any, form: any[]) => {
}); });
}; };
// 直播管理基本配置,格式转换
export const LiveStreamFill = (resData: any, form: any) => {
form.forEach((item: any) => {
item.lists.forEach((it: any) => {
// 循环resdata的key
Object.keys(resData).forEach((key: any) => {
if (it.name == key && DataType('array', resData[key])) {
// 转换为select组件需要的格式
const list: any = [];
resData[key].forEach((res: any) => {
const obj = {
label: res.title,
value: res.id,
};
list.push(obj);
});
it.options = list;
}
});
});
});
};
// 话术管理删除 // 话术管理删除
export const DiscourseManagementDelete = async ( export const DiscourseManagementDelete = async (
data: any, data: any,
...@@ -214,3 +270,54 @@ export const DiscourseManagementDelete = async ( ...@@ -214,3 +270,54 @@ export const DiscourseManagementDelete = async (
console.log(e); console.log(e);
} }
}; };
// 互动设置删除
export const InteractiveSettingDelete = async (
data: any,
path: string = ''
) => {
try {
const res: any = await InteractionTableDelete(data);
if (res.code == 0) {
show_message('删除成功', 'success');
if (path) {
router.replace({
path: path,
});
}
return true;
}
} catch (e) {
console.log(e);
}
};
// 直播管理删除
export const LiveStreamDelete = async (data: any, path: string = '') => {
try {
const res: any = await LiveStreamTableDelete(data);
if (res.code == 0) {
show_message('删除成功', 'success');
if (path) {
router.replace({
path: path,
});
}
return true;
}
} catch (e) {
console.log(e);
}
};
// 获取直播配置并填充数据
export const LiveStreamConfigFill = async (form: any) => {
try {
const res: any = await getLiveStreamConfig();
if (res.code == 0) {
LiveStreamFill(res.data, form);
}
} catch (e) {
console.log(e);
}
};
...@@ -80,12 +80,16 @@ export default function () { ...@@ -80,12 +80,16 @@ export default function () {
} }
status.value = false; status.value = false;
let res: any = null; let res: any = null;
// 话术内容
let content = '';
if (name === admin_task_type.dialogues) { if (name === admin_task_type.dialogues) {
// 话术管理 // 话术管理
res = await DiscourseManagementConvertTask(data); res = await DiscourseManagementConvertTask(data);
content = data.content;
} else if (name === admin_task_type.interaction) { } else if (name === admin_task_type.interaction) {
// 互动设置 // 互动设置
res = await SubmitTaskInteract(data); res = await SubmitTaskInteract(data);
content = data.reply ?? data.interact;
} }
// //
if (res.code == 0 && res.data.hash) { if (res.code == 0 && res.data.hash) {
...@@ -100,7 +104,7 @@ export default function () { ...@@ -100,7 +104,7 @@ export default function () {
check_time: 0, check_time: 0,
}); });
// 开始定时任务 // 开始定时任务
openInterval(res.data.hash, data.content, name); openInterval(res.data.hash, content, name);
} else { } else {
console.log('报错了'); console.log('报错了');
console.log(res); console.log(res);
......
...@@ -59,7 +59,7 @@ const SubmitCreateEvent = async () => { ...@@ -59,7 +59,7 @@ const SubmitCreateEvent = async () => {
// 获取id // 获取id
const getRowid = () => { const getRowid = () => {
return cur_id.value + ''; return [cur_id.value];
}; };
// 编辑页面组件 // 编辑页面组件
const ManagementForm = reactive({ const ManagementForm = reactive({
...@@ -191,6 +191,21 @@ const ManagementForm = reactive({ ...@@ -191,6 +191,21 @@ const ManagementForm = reactive({
}, },
], ],
}, },
// 隐藏的内容
{
type: 'text',
label: '',
name: 'is_edit',
value: '1',
align: 'left',
is_hidden: true,
rules: [
{
type: 'required',
message: '隐藏内容缺失',
},
],
},
{ {
type: 'select', type: 'select',
label: '语音', label: '语音',
......
...@@ -19,6 +19,7 @@ import { ...@@ -19,6 +19,7 @@ import {
FilterConfigFill, FilterConfigFill,
language_list, language_list,
interaction_type, interaction_type,
InteractiveSettingDelete,
} from '@/constants/admin_form'; } from '@/constants/admin_form';
import { interactive_setting_edit } from '@/constants/token'; import { interactive_setting_edit } from '@/constants/token';
import { import {
...@@ -87,6 +88,8 @@ const ManagementForm = reactive({ ...@@ -87,6 +88,8 @@ const ManagementForm = reactive({
edit_key: interactive_setting_edit, edit_key: interactive_setting_edit,
// 新增页面 // 新增页面
create_page: '/AILiveStreaming/InteractiveSetting/create', create_page: '/AILiveStreaming/InteractiveSetting/create',
// 删除api
delete_api: InteractiveSettingDelete,
// 多选功能操作项 // 多选功能操作项
row_selected_options: [ row_selected_options: [
{ {
......
...@@ -8,12 +8,18 @@ import { reactive } from 'vue'; ...@@ -8,12 +8,18 @@ import { reactive } from 'vue';
import { getLocalData, isDevContext } from '@/utils/tool'; import { getLocalData, isDevContext } from '@/utils/tool';
import { show_message } from '@/utils/tdesign_tool'; import { show_message } from '@/utils/tdesign_tool';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { admin_task_type } from '@/constants/admin_form'; import { admin_task_type, voice_list } from '@/constants/admin_form';
import ConvertVoice from '@/hooks/ConvertVoice';
import { InteractionTableCreate } from '@/utils/api/ai';
const { CurrentVoice, SubmitConvertTask } = ConvertVoice();
const router = useRouter(); const router = useRouter();
const imgs = {
fill: new URL('../../../assets/svg/form/edit.svg', import.meta.url).href,
};
// 获取选中的语言hash
const getHash = () => {
let list = ManagementForm.conversion.list;
const index = list.findIndex((item: any) => item.is_check);
return index !== -1 ? list[index].hash : '';
};
// 修改组件显示状态 // 修改组件显示状态
const ChangeComponentsShow = (value: string) => { const ChangeComponentsShow = (value: string) => {
ManagementForm.form_options.forEach((item: any) => { ManagementForm.form_options.forEach((item: any) => {
...@@ -25,6 +31,27 @@ const ChangeComponentsShow = (value: string) => { ...@@ -25,6 +31,27 @@ const ChangeComponentsShow = (value: string) => {
} }
}); });
}; };
const SubmitCreateEvent = async () => {
try {
// 先过滤出选中的hash
const hash = getHash();
if (!hash) {
show_message('必须选择一条语音');
return;
}
const res: any = await InteractionTableCreate({
hash: hash,
});
if (res.code == 0) {
show_message('添加成功', 'success');
router.replace({
path: ManagementForm.back_url,
});
}
} catch (e) {
console.log(e);
}
};
// 新增组件--所有value为空 // 新增组件--所有value为空
const ManagementForm = reactive({ const ManagementForm = reactive({
page_name: admin_task_type.interaction, page_name: admin_task_type.interaction,
...@@ -34,17 +61,48 @@ const ManagementForm = reactive({ ...@@ -34,17 +61,48 @@ const ManagementForm = reactive({
// 是否显示返回列表页 // 是否显示返回列表页
back: true, back: true,
back_url: '/AILiveStreaming/InteractiveSetting', back_url: '/AILiveStreaming/InteractiveSetting',
// 能否删除,
delete: false,
// 删除api // 删除api
delete_api: '', delete_api: '',
submit_api: '1', // 新增接口
submit_api: SubmitCreateEvent,
// 是否试听
audition: true,
//能否重置 //能否重置
reset: true, reset: true,
// 是否转换为语音 // 是否转换为语音 -- 自定义方法
conversion: false, conversion: {
// 播放音频 list: CurrentVoice.list,
play_audio: false, // 测试list
// list: [
// {
// audio: [
// 'https://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/4c1bdfa0fd604ce3ab2b1579a788685e_0.mp3',
// 'https://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/214fcc1b9c4c4d8ba4851a7d4c20b481_1.mp3',
// 'https://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/adf91b511b484fe4be5a5c192c4b933d_2.mp3',
// ],
// content:
// '大家好!今天我很兴奋地向大家介绍我们最新的牙刷产品!这款牙刷采用了最先进的声波技术,可以快速且彻底地清洁牙齿,轻轻松松祛除口腔细菌,令您每天远离口臭和牙齿问题。它还拥有集多种功能于一身的设计:磁悬浮电机、充电式电池、可调节的振动模式等,完美地满足了每个人的口腔需求。与传统的牙刷相比,这款牙刷具有更强的能力和更广泛的使用范围。拥有一款优质的牙刷,是每个人在健康生活中不可或缺的一个环节。所以,我们的团队不仅将其引入这个市场,而且已经通过大量的实验和测试,证明了这款牙刷确实能够在口腔清洁方面达到出色的表现。如果您是那种注重口腔卫生的人,那么这款牙刷绝对是您的首选',
// hash: 'a6d66c701602513e93e70ae962223668',
// is_check: false,
// status: true,
// check_time: 0,
// },
// {
// audio: [
// 'https://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/4c1bdfa0fd604ce3ab2b1579a788685e_0.mp3',
// 'https://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/214fcc1b9c4c4d8ba4851a7d4c20b481_1.mp3',
// 'https://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/adf91b511b484fe4be5a5c192c4b933d_2.mp3',
// ],
// content:
// '大家好!今天我很兴奋地向大家介绍我们最新的牙刷产品!这款牙刷采用了最先进的声波技术,可以快速且彻底地清洁牙齿,轻轻松松祛除口腔细菌,令您每天远离口臭和牙齿问题。它还拥有集多种功能于一身的设计:磁悬浮电机、充电式电池、可调节的振动模式等,完美地满足了每个人的口腔需求。与传统的牙刷相比,这款牙刷具有更强的能力和更广泛的使用范围。拥有一款优质的牙刷,是每个人在健康生活中不可或缺的一个环节。所以,我们的团队不仅将其引入这个市场,而且已经通过大量的实验和测试,证明了这款牙刷确实能够在口腔清洁方面达到出色的表现。如果您是那种注重口腔卫生的人,那么这款牙刷绝对是您的首选',
// hash: 'a6d66c701602513e93e70ae9622236681',
// is_check: false,
// status: true,
// check_time: 0,
// },
// ],
method: SubmitConvertTask,
},
form_options: [ form_options: [
{ {
icon: '', icon: '',
...@@ -53,19 +111,25 @@ const ManagementForm = reactive({ ...@@ -53,19 +111,25 @@ const ManagementForm = reactive({
{ {
type: 'select', type: 'select',
label: '类型', label: '类型',
name: 'select_type', name: 'type',
placeholder: '请选择类型', placeholder: '请选择类型',
value: 'auto', value: '',
align: 'left', align: 'left',
watch: ChangeComponentsShow, watch: ChangeComponentsShow,
options: [ options: [
{ {
label: '自动回复设置', label: '自动回复设置',
value: 'auto', value: '1',
}, },
{ {
label: '串场互动话术设置', label: '串场互动话术设置',
value: 'crosstown', value: '0',
},
],
rules: [
{
type: 'required',
message: '类型必选',
}, },
], ],
}, },
...@@ -92,6 +156,27 @@ const ManagementForm = reactive({ ...@@ -92,6 +156,27 @@ const ManagementForm = reactive({
value: 'en', value: 'en',
}, },
], ],
rules: [
{
type: 'required',
message: '语言必选',
},
],
},
// 隐藏的内容
{
type: 'text',
label: '',
name: 'is_edit',
value: '1',
align: 'left',
is_hidden: true,
rules: [
{
type: 'required',
message: '隐藏内容缺失',
},
],
}, },
{ {
type: 'select', type: 'select',
...@@ -101,14 +186,11 @@ const ManagementForm = reactive({ ...@@ -101,14 +186,11 @@ const ManagementForm = reactive({
value: '', value: '',
align: 'left', align: 'left',
audio: true, audio: true,
options: [ options: voice_list,
{ rules: [
label: '小微 (直播间专属)',
value: '123',
},
{ {
label: '小爱 (直播间专属)', type: 'required',
value: '12345', message: '语音必选',
}, },
], ],
}, },
...@@ -118,22 +200,48 @@ const ManagementForm = reactive({ ...@@ -118,22 +200,48 @@ const ManagementForm = reactive({
icon: 'message', icon: 'message',
title: '自动回复设置', title: '自动回复设置',
is_hidden: false, is_hidden: false,
name: 'auto', name: '1',
lists: [ lists: [
{ {
type: 'text', type: 'text',
label: '标题',
name: 'title',
placeholder: '请输入标题',
value: '',
align: 'left',
rules: [
{
type: 'required',
message: '标题必填',
},
],
},
{
type: 'text',
label: '触发关键词', label: '触发关键词',
name: 'language_20', name: 'key_words',
placeholder: '请输入', placeholder: '请输入',
value: '', value: '',
align: 'left', align: 'left',
rules: [
{
type: 'required',
message: '触发关键词必填',
},
],
}, },
{ {
type: 'textarea', type: 'textarea',
label: '回复内容', label: '回复内容',
name: 'product_30', name: 'reply',
placeholder: '请输入语音内容', placeholder: '请输入语音内容',
value: '', value: '',
rules: [
{
type: 'required',
message: '回复内容必填',
},
],
}, },
], ],
}, },
...@@ -141,22 +249,34 @@ const ManagementForm = reactive({ ...@@ -141,22 +249,34 @@ const ManagementForm = reactive({
icon: 'discourseBind', icon: 'discourseBind',
title: '串场互动话术设置', title: '串场互动话术设置',
is_hidden: true, is_hidden: true,
name: 'crosstown', name: '0',
lists: [ lists: [
{ {
type: 'text', type: 'text',
label: '标题', label: '标题',
name: 'language_20', name: 'title',
placeholder: '请输入', placeholder: '请输入',
value: '', value: '',
align: 'left', align: 'left',
rules: [
{
type: 'required',
message: '标题必填',
},
],
}, },
{ {
type: 'textarea', type: 'textarea',
label: '话术内容', label: '话术内容',
name: 'product_30', name: 'interact',
placeholder: '请输入话术内容', placeholder: '请输入话术内容',
value: '', value: '',
rules: [
{
type: 'required',
message: '话术内容必填',
},
],
}, },
], ],
}, },
......
<template> <template>
<PageEdit :form="ManagementForm"></PageEdit> <PageEdit
:form="ManagementForm"
:audio_list="audio_list"
@ConfigChange="ConfigChange"
></PageEdit>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import PageEdit from '@/components/Admin/PageEdit.vue'; import PageEdit from '@/components/Admin/PageEdit.vue';
import { onBeforeMount, reactive } from 'vue'; import { onBeforeMount, reactive, ref, watch } from 'vue';
import { interactive_setting_edit } from '@/constants/token'; import { interactive_setting_edit } from '@/constants/token';
import { getLocalData, isDevContext } from '@/utils/tool';
import { show_message } from '@/utils/tdesign_tool'; import { show_message } from '@/utils/tdesign_tool';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { import {
...@@ -14,13 +17,40 @@ import { ...@@ -14,13 +17,40 @@ import {
EditFillData, EditFillData,
admin_task_type, admin_task_type,
voice_list, voice_list,
interaction_type,
InteractiveSettingDelete,
} from '@/constants/admin_form'; } from '@/constants/admin_form';
import { InteractionTableUpdate } from '@/utils/api/ai';
import ConvertVoice from '@/hooks/ConvertVoice'; import ConvertVoice from '@/hooks/ConvertVoice';
const { CurrentVoice, SubmitConvertTask } = ConvertVoice(); const { CurrentVoice, SubmitConvertTask } = ConvertVoice();
const router = useRouter(); const router = useRouter();
const imgs = { // 当前试听语音
fill: new URL('../../../assets/svg/form/edit.svg', import.meta.url).href, const audio_list = ref([]);
const old_hash = ref('');
const cur_id = ref('');
// 记录当前语音和语言
const CurrentConfig = reactive({
language: '',
voice: '',
});
watch(CurrentConfig, (config) => {
if (config.language && config.voice) {
// 修改试听语音
const obj = voice_list.find((item: any) => item.value == config.voice);
if (obj) {
audio_list.value = [obj.audio[config.language]];
}
}
});
const ConfigChange = (name: string, value: string) => {
CurrentConfig[name] = value;
}; };
// 获取row id
const getCurrentId = () => {
return [cur_id.value];
};
// 修改组件显示状态 // 修改组件显示状态
const ChangeComponentsShow = (value: string) => { const ChangeComponentsShow = (value: string) => {
ManagementForm.form_options.forEach((item: any) => { ManagementForm.form_options.forEach((item: any) => {
...@@ -32,6 +62,36 @@ const ChangeComponentsShow = (value: string) => { ...@@ -32,6 +62,36 @@ const ChangeComponentsShow = (value: string) => {
} }
}); });
}; };
// 获取选中的语言hash
const getHash = () => {
let list = ManagementForm.conversion.list;
const index = list.findIndex((item: any) => item.is_check);
return index !== -1 ? list[index].hash : '';
};
//自定义提交事件
const SubmitCreateEvent = async () => {
// 先过滤出选中的hash
const hash = getHash();
if (!hash || !old_hash.value) {
show_message('必须选择一条语音');
return;
}
try {
const res: any = await InteractionTableUpdate({
hash: hash,
old_hash: old_hash.value,
});
if (res.code == 0) {
show_message('修改成功', 'success');
router.replace({
path: ManagementForm.back_url,
});
}
} catch (e) {
console.log(e);
}
};
// 编辑页面组件 // 编辑页面组件
const ManagementForm = reactive({ const ManagementForm = reactive({
page_name: admin_task_type.interaction, page_name: admin_task_type.interaction,
...@@ -42,10 +102,13 @@ const ManagementForm = reactive({ ...@@ -42,10 +102,13 @@ const ManagementForm = reactive({
back: true, back: true,
back_url: '/AILiveStreaming/InteractiveSetting', back_url: '/AILiveStreaming/InteractiveSetting',
// 删除api // 删除api
delete_api: '1', delete_api: InteractiveSettingDelete,
submit_api: '1', // 删除前是否确认
delete_confirm: true,
submit_api: SubmitCreateEvent,
get_id: getCurrentId,
// 是否试听 // 是否试听
audition: true,
//能否重置 //能否重置
reset: true, reset: true,
// 是否转换为语音 -- 自定义方法 // 是否转换为语音 -- 自定义方法
...@@ -90,19 +153,25 @@ const ManagementForm = reactive({ ...@@ -90,19 +153,25 @@ const ManagementForm = reactive({
{ {
type: 'select', type: 'select',
label: '类型', label: '类型',
name: 'select_type', name: 'type',
placeholder: '请选择类型', placeholder: '请选择类型',
value: 'auto', value: '',
align: 'left', align: 'left',
watch: ChangeComponentsShow, watch: ChangeComponentsShow,
options: [ options: [
{ {
label: '自动回复设置', label: '自动回复设置',
value: 'auto', value: '1',
}, },
{ {
label: '串场互动话术设置', label: '串场互动话术设置',
value: 'crosstown', value: '0',
},
],
rules: [
{
type: 'required',
message: '类型必选',
}, },
], ],
}, },
...@@ -129,6 +198,27 @@ const ManagementForm = reactive({ ...@@ -129,6 +198,27 @@ const ManagementForm = reactive({
value: 'en', value: 'en',
}, },
], ],
rules: [
{
type: 'required',
message: '语言必选',
},
],
},
// 隐藏的内容
{
type: 'text',
label: '',
name: 'is_edit',
value: '1',
align: 'left',
is_hidden: true,
rules: [
{
type: 'required',
message: '隐藏内容缺失',
},
],
}, },
{ {
type: 'select', type: 'select',
...@@ -139,6 +229,12 @@ const ManagementForm = reactive({ ...@@ -139,6 +229,12 @@ const ManagementForm = reactive({
align: 'left', align: 'left',
audio: true, audio: true,
options: voice_list, options: voice_list,
rules: [
{
type: 'required',
message: '语音必选',
},
],
}, },
], ],
}, },
...@@ -146,22 +242,48 @@ const ManagementForm = reactive({ ...@@ -146,22 +242,48 @@ const ManagementForm = reactive({
icon: 'message', icon: 'message',
title: '自动回复设置', title: '自动回复设置',
is_hidden: false, is_hidden: false,
name: 'auto', name: '1',
lists: [ lists: [
{ {
type: 'text', type: 'text',
label: '标题',
name: 'title',
placeholder: '请输入标题',
value: '',
align: 'left',
rules: [
{
type: 'required',
message: '标题必填',
},
],
},
{
type: 'text',
label: '触发关键词', label: '触发关键词',
name: 'language_20', name: 'key_words',
placeholder: '请输入', placeholder: '请输入',
value: '', value: '',
align: 'left', align: 'left',
rules: [
{
type: 'required',
message: '触发关键词必填',
},
],
}, },
{ {
type: 'textarea', type: 'textarea',
label: '回复内容', label: '回复内容',
name: 'product_30', name: 'reply',
placeholder: '请输入语音内容', placeholder: '请输入语音内容',
value: '', value: '',
rules: [
{
type: 'required',
message: '回复内容必填',
},
],
}, },
], ],
}, },
...@@ -169,22 +291,34 @@ const ManagementForm = reactive({ ...@@ -169,22 +291,34 @@ const ManagementForm = reactive({
icon: 'discourseBind', icon: 'discourseBind',
title: '串场互动话术设置', title: '串场互动话术设置',
is_hidden: true, is_hidden: true,
name: 'crosstown', name: '0',
lists: [ lists: [
{ {
type: 'text', type: 'text',
label: '标题', label: '标题',
name: 'language_20', name: 'title',
placeholder: '请输入', placeholder: '请输入',
value: '', value: '',
align: 'left', align: 'left',
rules: [
{
type: 'required',
message: '标题必填',
},
],
}, },
{ {
type: 'textarea', type: 'textarea',
label: '话术内容', label: '话术内容',
name: 'product_30', name: 'interact',
placeholder: '请输入话术内容', placeholder: '请输入话术内容',
value: '', value: '',
rules: [
{
type: 'required',
message: '话术内容必填',
},
],
}, },
], ],
}, },
...@@ -199,6 +333,40 @@ onBeforeMount(() => { ...@@ -199,6 +333,40 @@ onBeforeMount(() => {
); );
// 填充 // 填充
EditFillData(ManagementForm.form_options, row); EditFillData(ManagementForm.form_options, row);
const content =
typeof row.interact == 'string' ? row.interact : row.interact.reply;
// 填充原有的语音列表
ManagementForm.conversion.list.push({
hash: row.hash,
status: true,
audio: JSON.parse(row.audio),
content: content,
is_check: false,
check_time: 0,
});
// 获取本地的语言语音
if (row.language && row.voice) {
CurrentConfig.language = row.language;
CurrentConfig.voice = row.voice;
}
// 设置类型
ChangeComponentsShow(row.type);
if (
row.type == '1' &&
row.interact &&
row.interact.key_words &&
row.interact.reply
) {
// 自动回复
EditFillData(ManagementForm.form_options, {
key_words: row.interact.key_words,
reply: row.interact.reply,
});
}
// 获取old_hash
old_hash.value = row.hash;
cur_id.value = row.id;
}); });
</script> </script>
......
...@@ -3,31 +3,81 @@ ...@@ -3,31 +3,81 @@
:form="ManagementForm" :form="ManagementForm"
v-model:list="ManagementForm.table_list" v-model:list="ManagementForm.table_list"
@reset="ResetFilter" @reset="ResetFilter"
@PageNumChange="PageNumChange"
> >
<template #title>
<div>111</div>
</template>
<template #edit="{ row }"> <template #edit="{ row }">
<!-- custom --> <!-- custom -->
<div class="custom-operation" @click="onEdit(row)">编辑</div> <div class="custom-operation" @click="onEdit(row)">编辑</div>
<div class="custom-operation" @click="onDetail(row)">查看</div> <div class="custom-operation" @click="onDetail(row)">查看</div>
<div class="custom-operation" @click="onReply(row)">人工回复</div> <div class="custom-operation" @click="onReply(row)">人工回复</div>
</template> </template>
<template #status="{ row }">
{{ live_stream_status[row.status] }}
</template>
</AdminPublicPageVue> </AdminPublicPageVue>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import AdminPublicPageVue from '@/components/Admin/AdminPublicPage.vue'; import AdminPublicPageVue from '@/components/Admin/AdminPublicPage.vue';
import { reactive } from 'vue'; import { onBeforeMount, reactive, ref } from 'vue';
import { isDevContext } from '@/utils/tool'; import { isDevContext } from '@/utils/tool';
import { ResetForm, EditButtonEvent } from '@/constants/admin_form'; import {
ResetForm,
EditButtonEvent,
FilterConfigFill,
live_stream_status,
LiveStreamDelete,
} from '@/constants/admin_form';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { import {
live_stream_edit, live_stream_edit,
live_stream_detail, live_stream_detail,
live_stream_reply, live_stream_reply,
} from '@/constants/token'; } from '@/constants/token';
import {
LiveStreamFilterConfig,
LiveStreamTableList,
LiveStreamFilter,
} from '@/utils/api/ai';
const router = useRouter(); const router = useRouter();
const pageNum = ref(1);
const pageSize = ref(10);
// 开始筛选
const onFilter = async (params: any) => {
try {
const res: any = await LiveStreamFilter({
page: pageNum.value,
limit: pageSize.value,
...params,
});
return {
list: res.data.data,
total: res.data.total,
};
} catch (e) {
console.log(e);
}
};
// 获取表格数据
const getTableList = async () => {
try {
const res: any = await LiveStreamTableList({
page: pageNum.value,
limit: pageSize.value,
});
return {
list: res.data.data,
total: res.data.total,
};
} catch (e) {
console.log(e);
}
};
// 分页变化
const PageNumChange = (value: number) => {
pageNum.value = value;
};
// 表单配置项 // 表单配置项
const ManagementForm = reactive({ const ManagementForm = reactive({
title: '直播管理', title: '直播管理',
...@@ -37,17 +87,27 @@ const ManagementForm = reactive({ ...@@ -37,17 +87,27 @@ const ManagementForm = reactive({
// 能否筛选 // 能否筛选
filter: true, filter: true,
// 筛选接口 // 筛选接口
filter_api: isDevContext() ? '' : '', filter_api: onFilter,
// 能否新增 // 能否新增
add: true, add: true,
// 表格key--用来缓存表格分页 // 表格key--用来缓存表格分页
local_key: 'admin_live_stream', local_key: 'admin_live_stream',
// 表格数据
table_list: [], table_list: [],
// 表格接口 // 表格接口
table_api: isDevContext() ? '' : '', table_api: getTableList,
// api类型 // 删除api
table_api_type: 'get', delete_api: LiveStreamDelete,
// 删除api拓展字段
delete_options: [
{
key: 'id',
value: 'ids',
},
{
key: 'hash',
value: 'hash',
},
],
// 能否多选--默认为true // 能否多选--默认为true
checkbox: true, checkbox: true,
// 编辑页面 // 编辑页面
...@@ -76,11 +136,11 @@ const ManagementForm = reactive({ ...@@ -76,11 +136,11 @@ const ManagementForm = reactive({
}, },
{ {
title: '直播间标题', title: '直播间标题',
colKey: 'lv_title', colKey: 'live_title',
}, },
{ {
title: '直播间接', title: '直播间接',
colKey: 'connect', colKey: 'live_link',
align: 'center', align: 'center',
}, },
{ {
...@@ -98,54 +158,31 @@ const ManagementForm = reactive({ ...@@ -98,54 +158,31 @@ const ManagementForm = reactive({
filter_option: [ filter_option: [
{ {
type: 'select', type: 'select',
name: 'select_title', name: 'live_title',
label: '标题', label: '标题',
placeholder: '请选择标题', placeholder: '请选择标题',
value: '', value: '',
options: [ options: [],
{ // 能否输入
label: '你好', filterable: true,
value: '你好',
},
{
label: '你好2',
value: '你好2',
},
],
}, },
{ {
type: 'select', type: 'select',
name: 'select_product', name: 'live_link',
label: '产品', label: '链接',
placeholder: '产品', placeholder: '请选择链接',
value: '', value: '',
options: [ options: [],
{ // 能否输入
label: '你好', filterable: true,
value: '你好',
},
{
label: '你好2',
value: '你好2',
},
],
}, },
{ {
type: 'select', type: 'select',
name: 'select_language', name: 'status',
label: '语言', label: '状态',
placeholder: '语言', placeholder: '选择状态',
value: '', value: '',
options: [ options: [],
{
label: '你好',
value: '你好',
},
{
label: '你好2',
value: '你好2',
},
],
}, },
], ],
}); });
...@@ -167,6 +204,34 @@ const onReply = (row: any) => { ...@@ -167,6 +204,34 @@ const onReply = (row: any) => {
// //
EditButtonEvent(live_stream_reply, ManagementForm.reply_page, row); EditButtonEvent(live_stream_reply, ManagementForm.reply_page, row);
}; };
const getFilterConfig = async () => {
try {
const res: any = await LiveStreamFilterConfig();
if (res.data) {
FilterConfigFill(res.data, ManagementForm.filter_option);
// 修改status的数组类型
ManagementForm.filter_option.forEach((item: any) => {
if (item.name == 'status') {
item.options = [];
res.data.status.forEach((it: any) => {
let obj = {
label: live_stream_status[it],
value: it,
};
item.options.push(obj);
});
}
});
}
} catch (e) {
console.log(e);
}
};
onBeforeMount(() => {
getFilterConfig();
});
</script> </script>
<style lang="less"> <style lang="less">
......
...@@ -4,17 +4,38 @@ ...@@ -4,17 +4,38 @@
<script lang="ts" setup> <script lang="ts" setup>
import PageEdit from '@/components/Admin/PageEdit.vue'; import PageEdit from '@/components/Admin/PageEdit.vue';
import { reactive } from 'vue'; import { onBeforeMount, reactive } from 'vue';
import { getLocalData, isDevContext } from '@/utils/tool';
import { show_message } from '@/utils/tdesign_tool'; import { show_message } from '@/utils/tdesign_tool';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { LiveStreamTableCreate } from '@/utils/api/ai';
import { LiveStreamConfigFill, getFormParams } from '@/constants/admin_form';
const router = useRouter(); const router = useRouter();
const imgs = { const imgs = {
fill: new URL('../../../assets/svg/form/edit.svg', import.meta.url).href, fill: new URL('../../../assets/svg/form/edit.svg', import.meta.url).href,
}; };
// 新增接口
const SubmitCreateEvent = async () => {
try {
// 过滤出所有value
const params = getFormParams(ManagementForm.form_options);
if (!params) {
return;
}
const res: any = await LiveStreamTableCreate(params);
if (res.code == 0) {
show_message('添加成功', 'success');
router.replace({
path: ManagementForm.back_url,
});
}
} catch (e) {
console.log(e);
}
};
// 新增组件--所有value为空 // 新增组件--所有value为空
const ManagementForm = reactive({ const ManagementForm = reactive({
title: '互动设置', title: '直播管理',
title_2: '新增', title_2: '新增',
body_title: '新增', body_title: '新增',
// 是否显示返回列表页 // 是否显示返回列表页
...@@ -27,7 +48,7 @@ const ManagementForm = reactive({ ...@@ -27,7 +48,7 @@ const ManagementForm = reactive({
// 能否提交 // 能否提交
submit: true, submit: true,
// 提交接口 // 提交接口
submit_api: isDevContext() ? '' : '', submit_api: SubmitCreateEvent,
//能否重置 //能否重置
reset: true, reset: true,
// 是否转换为语音 // 是否转换为语音
...@@ -42,16 +63,16 @@ const ManagementForm = reactive({ ...@@ -42,16 +63,16 @@ const ManagementForm = reactive({
{ {
type: 'text', type: 'text',
label: '直播间标题', label: '直播间标题',
name: 'title_1', name: 'live_title',
value: '', value: '',
disabled: true, placeholder: '请输入直播间标题',
placeholder: '',
}, },
{ {
type: 'text', type: 'text',
label: '直播间接', label: '直播间接',
name: 'title_12', name: 'live_link',
value: '', value: '',
placeholder: '请输入直播间链接',
}, },
], ],
}, },
...@@ -62,60 +83,36 @@ const ManagementForm = reactive({ ...@@ -62,60 +83,36 @@ const ManagementForm = reactive({
{ {
type: 'select', type: 'select',
label: '直播话术', label: '直播话术',
name: 'language_1', name: 'live_voice',
placeholder: '请选择语言', placeholder: '请选择语言',
value: '', value: [],
align: 'left', align: 'left',
options: [ options: [],
{ multiple: true,
label: '话术1',
value: 'cn',
},
{
label: '话术2',
value: 'en',
},
],
}, },
{ {
type: 'select', type: 'select',
label: '自动回复话术', label: '自动回复话术',
name: 'voice', name: 'live_auto',
placeholder: '请选择自动回复话术', placeholder: '请选择自动回复话术',
value: '', value: [],
align: 'left', align: 'left',
options: [ options: [],
{ multiple: true,
label: '自动回复话术1',
value: '123',
},
{
label: '自动回复话术2',
value: '12345',
},
],
}, },
{ {
type: 'select', type: 'select',
label: '串场互动话术', label: '串场互动话术',
name: 'voice', name: 'live_interaction',
placeholder: '请选择串场互动话术', placeholder: '请选择串场互动话术',
value: '', value: [],
align: 'left', align: 'left',
options: [ options: [],
{ multiple: true,
label: '串场互动话术1',
value: '123',
},
{
label: '串场互动话术2',
value: '12345',
},
],
}, },
{ {
type: 'number', type: 'number',
name: 'number', name: 'interaction_interval',
label: '串场互动触发时间间隔', label: '串场互动触发时间间隔',
value: '', value: '',
}, },
...@@ -123,6 +120,15 @@ const ManagementForm = reactive({ ...@@ -123,6 +120,15 @@ const ManagementForm = reactive({
}, },
], ],
}); });
const onFill = async () => {
const data = await LiveStreamConfigFill(ManagementForm.form_options);
};
onBeforeMount(() => {
// 填充数据
onFill();
});
</script> </script>
<style lang="less"></style> <style lang="less"></style>
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
import PageEdit from '@/components/Admin/PageEdit.vue'; import PageEdit from '@/components/Admin/PageEdit.vue';
import { onBeforeMount, reactive } from 'vue'; import { onBeforeMount, reactive } from 'vue';
import { live_stream_detail } from '@/constants/token'; import { live_stream_detail } from '@/constants/token';
import { getLocalData, isDevContext } from '@/utils/tool'; import { isDevContext } from '@/utils/tool';
import { show_message } from '@/utils/tdesign_tool'; import { show_message } from '@/utils/tdesign_tool';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { getEditLocalData, EditFillData } from '@/constants/admin_form'; import { getEditLocalData, EditFillData } from '@/constants/admin_form';
......
...@@ -4,16 +4,50 @@ ...@@ -4,16 +4,50 @@
<script lang="ts" setup> <script lang="ts" setup>
import PageEdit from '@/components/Admin/PageEdit.vue'; import PageEdit from '@/components/Admin/PageEdit.vue';
import { onBeforeMount, reactive } from 'vue'; import { onBeforeMount, reactive, ref } from 'vue';
import { live_stream_edit } from '@/constants/token'; import { live_stream_edit } from '@/constants/token';
import { getLocalData, isDevContext } from '@/utils/tool'; import { getLocalData, isDevContext } from '@/utils/tool';
import { show_message } from '@/utils/tdesign_tool'; import { show_message } from '@/utils/tdesign_tool';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { getEditLocalData, EditFillData } from '@/constants/admin_form'; import {
getEditLocalData,
LiveStreamConfigFill,
EditFillData,
getFormParams,
LiveStreamDelete,
} from '@/constants/admin_form';
import { LiveStreamTableUpdate } from '@/utils/api/ai';
const router = useRouter(); const router = useRouter();
const imgs = { const imgs = {
fill: new URL('../../../assets/svg/form/edit.svg', import.meta.url).href, fill: new URL('../../../assets/svg/form/edit.svg', import.meta.url).href,
}; };
const cur_id = ref('');
const cur_hash = ref('');
// 获取删除接口参数
const getDeleteParams = () => {
return {
ids: [cur_id.value],
hash: [cur_hash.value],
};
};
//自定义提交事件
const SubmitCreateEvent = async () => {
const params = getFormParams(ManagementForm.form_options);
if (!params) {
return;
}
try {
const res: any = await LiveStreamTableUpdate(params);
if (res.code == 0) {
show_message('修改成功', 'success');
router.replace({
path: ManagementForm.back_url,
});
}
} catch (e) {
console.log(e);
}
};
// 编辑页面组件 // 编辑页面组件
const ManagementForm = reactive({ const ManagementForm = reactive({
title: '直播管理', title: '直播管理',
...@@ -23,12 +57,16 @@ const ManagementForm = reactive({ ...@@ -23,12 +57,16 @@ const ManagementForm = reactive({
back: true, back: true,
back_url: '/AILiveStreaming/LiveStream', back_url: '/AILiveStreaming/LiveStream',
// 能否删除, // 能否删除,
delete: true, delete: false,
// 删除api // 删除api
delete_api: isDevContext() ? '' : '', delete_api: LiveStreamDelete,
get_params: getDeleteParams,
// 能否提交 // 能否提交
submit: true, submit: true,
submit_api: isDevContext() ? '' : '', // 提交接口
submit_api: SubmitCreateEvent,
// 删除前是否确认
delete_confirm: true,
//能否重置 //能否重置
reset: true, reset: true,
// 是否转换为语音 // 是否转换为语音
...@@ -43,16 +81,16 @@ const ManagementForm = reactive({ ...@@ -43,16 +81,16 @@ const ManagementForm = reactive({
{ {
type: 'text', type: 'text',
label: '直播间标题', label: '直播间标题',
name: 'title_1', name: 'live_title',
value: '', value: '',
disabled: true, placeholder: '请输入直播间标题',
placeholder: '',
}, },
{ {
type: 'text', type: 'text',
label: '直播间接', label: '直播间接',
name: 'title_12', name: 'live_link',
value: '', value: '',
placeholder: '请输入直播间链接',
}, },
], ],
}, },
...@@ -63,72 +101,62 @@ const ManagementForm = reactive({ ...@@ -63,72 +101,62 @@ const ManagementForm = reactive({
{ {
type: 'select', type: 'select',
label: '直播话术', label: '直播话术',
name: 'language_1', name: 'live_voice',
placeholder: '请选择语言', placeholder: '请选择语言',
value: '', value: [],
align: 'left', align: 'left',
options: [ options: [],
{ multiple: true,
label: '话术1',
value: 'cn',
},
{
label: '话术2',
value: 'en',
},
],
}, },
{ {
type: 'select', type: 'select',
label: '自动回复话术', label: '自动回复话术',
name: 'voice', name: 'live_auto',
placeholder: '请选择自动回复话术', placeholder: '请选择自动回复话术',
value: '', value: [],
align: 'left', align: 'left',
options: [ options: [],
{ multiple: true,
label: '自动回复话术1',
value: '123',
},
{
label: '自动回复话术2',
value: '12345',
},
],
}, },
{ {
type: 'select', type: 'select',
label: '串场互动话术', label: '串场互动话术',
name: 'voice', name: 'live_interaction',
placeholder: '请选择串场互动话术', placeholder: '请选择串场互动话术',
value: '', value: [],
align: 'left', align: 'left',
options: [ options: [],
{ multiple: true,
label: '串场互动话术1',
value: '123',
},
{
label: '串场互动话术2',
value: '12345',
},
],
}, },
{ {
type: 'number', type: 'number',
name: 'number', name: 'interaction_interval',
label: '串场互动触发时间间隔', label: '串场互动触发时间间隔',
value: '', value: '',
}, },
{
type: 'text',
name: 'hash',
label: 'hash',
value: '',
is_hidden: true,
},
], ],
}, },
], ],
}); });
const onFill = async () => {
const data = await LiveStreamConfigFill(ManagementForm.form_options);
};
onBeforeMount(() => { onBeforeMount(async () => {
// 填充数据--话术
await onFill();
// 本地是否有缓存 // 本地是否有缓存
const row = getEditLocalData(live_stream_edit, ManagementForm.back_url); const row = getEditLocalData(live_stream_edit, ManagementForm.back_url);
EditFillData(ManagementForm.form_options, row); EditFillData(ManagementForm.form_options, row);
cur_id.value = row.id;
cur_hash.value = row.hash;
}); });
</script> </script>
......
...@@ -119,6 +119,33 @@ export const InteractionTableList = (data: any) => { ...@@ -119,6 +119,33 @@ export const InteractionTableList = (data: any) => {
}); });
}; };
// 更新行
export const InteractionTableUpdate = (data: any) => {
return request.post('/api/voices/update-interact', data, {
headers: {
authorization: `Bearer ${getUserCookie()}`,
},
});
};
// 新增行
export const InteractionTableCreate = (data: any) => {
return request.post('/api/voices/save-interact', data, {
headers: {
authorization: `Bearer ${getUserCookie()}`,
},
});
};
// 删除
export const InteractionTableDelete = (data: any) => {
return request.post('/api/voices/delete-interact', data, {
headers: {
authorization: `Bearer ${getUserCookie()}`,
},
});
};
// 提交生成语音任务 // 提交生成语音任务
export const SubmitTaskInteract = (data: any) => { export const SubmitTaskInteract = (data: any) => {
return request.post('/api/voices/add-task-interact', data, { return request.post('/api/voices/add-task-interact', data, {
...@@ -141,3 +168,79 @@ export const QueryInteractResponse = (data: any) => { ...@@ -141,3 +168,79 @@ export const QueryInteractResponse = (data: any) => {
/** /**
* 互动设置 end * 互动设置 end
*/ */
/**
* 直播管理 LiveStream
*/
// 筛选配置项
export const LiveStreamFilterConfig = () => {
return request.get('/api/voices/live-config', {
headers: {
authorization: `Bearer ${getUserCookie()}`,
},
});
};
// 开始筛选
export const LiveStreamFilter = (data: any) => {
return request.get('/api/voices/live-filter', {
params: data,
headers: {
authorization: `Bearer ${getUserCookie()}`,
},
});
};
// 表格数据
export const LiveStreamTableList = () => {
return request.get('/api/voices/live-manage', {
headers: {
authorization: `Bearer ${getUserCookie()}`,
},
});
};
// 获取配置项
export const getLiveStreamConfig = () => {
return request.post(
'/api/voices/get-live-config',
{},
{
headers: {
authorization: `Bearer ${getUserCookie()}`,
},
}
);
};
// 新增
export const LiveStreamTableCreate = (data: any) => {
return request.post('/api/voices/set-live-config', data, {
headers: {
authorization: `Bearer ${getUserCookie()}`,
},
});
};
// 修改
export const LiveStreamTableUpdate = (data: any) => {
return request.post('/api/voices/update-live-config', data, {
headers: {
authorization: `Bearer ${getUserCookie()}`,
},
});
};
// 删除
export const LiveStreamTableDelete = (data: any) => {
return request.post('/api/voices/delete-live-config', data, {
headers: {
authorization: `Bearer ${getUserCookie()}`,
},
});
};
/**
* 直播管理 end
*/
...@@ -121,15 +121,12 @@ export const Validationrules = ( ...@@ -121,15 +121,12 @@ export const Validationrules = (
for (let i = 0; i < rules.length; i++) { for (let i = 0; i < rules.length; i++) {
const item = rules[i]; const item = rules[i];
if (item.type == 'required' && !value && name.indexOf('size_') == -1) { if (item.type == 'required' && !value && name.indexOf('size_') == -1) {
console.log(item);
// 必填项 // 必填项
console.log('我执行了21');
return item.message; return item.message;
} else if (item.type == 'regex' && value) { } else if (item.type == 'regex' && value) {
// 正则 // 正则
const status = item.value.test(value); const status = item.value.test(value);
if (!status) { if (!status) {
console.log('我执行了2');
return item.message; return item.message;
} }
} }
......
...@@ -55,7 +55,7 @@ export default defineConfig(({ mode }) => { ...@@ -55,7 +55,7 @@ export default defineConfig(({ mode }) => {
build: { build: {
minify: 'terser', // 混淆器,terser构建后文件体积更小 minify: 'terser', // 混淆器,terser构建后文件体积更小
outDir: mode != 'app' ? `GPT-AI-${newDate}` : 'dist', //指定输出路径 outDir: mode != 'app' ? `GPT-AI-${newDate}` : 'dist', //指定输出路径
cssCodeSplit: false, // 如果设置为false,整个项目中的所有 CSS 将被提取到一个 CSS 文件中 cssCodeSplit: true, // 如果设置为false,整个项目中的所有 CSS 将被提取到一个 CSS 文件中
terserOptions: { terserOptions: {
compress: { compress: {
//生产环境时移除console //生产环境时移除console
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment