226 lines
7.0 KiB
Vue
226 lines
7.0 KiB
Vue
|
|
<template>
|
||
|
|
<el-dialog v-model="dialogVisible" :title="isEdit ? '修改排班' : '新增排班'" width="680px">
|
||
|
|
<el-form ref="formRef" :model="formData" :rules="rules" label-width="100px">
|
||
|
|
<el-row :gutter="20">
|
||
|
|
<el-col :span="12">
|
||
|
|
<el-form-item label="主播" prop="anchorId">
|
||
|
|
<el-select v-model="formData.anchorId" placeholder="请选择主播" filterable style="width: 100%">
|
||
|
|
<el-option v-for="item in anchorOptions" :key="item.id" :label="item.name" :value="item.id" />
|
||
|
|
</el-select>
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
<el-col :span="12">
|
||
|
|
<el-form-item label="直播账号" prop="accountId">
|
||
|
|
<el-select v-model="formData.accountId" placeholder="请选择直播账号" filterable style="width: 100%">
|
||
|
|
<el-option
|
||
|
|
v-for="item in liveAccountOptions"
|
||
|
|
:key="item.id"
|
||
|
|
:label="`${item.platform} / ${item.accountName}`"
|
||
|
|
:value="item.id"
|
||
|
|
/>
|
||
|
|
</el-select>
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
<el-col :span="12">
|
||
|
|
<el-form-item label="开始时间" prop="startTime">
|
||
|
|
<el-date-picker v-model="formData.startTime" type="datetime" placeholder="请选择开始时间" style="width: 100%" />
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
<el-col :span="12">
|
||
|
|
<el-form-item label="结束时间" prop="endTime">
|
||
|
|
<el-date-picker v-model="formData.endTime" type="datetime" placeholder="请选择结束时间" style="width: 100%" />
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
<el-col :span="12">
|
||
|
|
<el-form-item label="状态" prop="status">
|
||
|
|
<el-select v-model="formData.status" placeholder="请选择状态" style="width: 100%">
|
||
|
|
<el-option label="待直播" :value="0" />
|
||
|
|
<el-option label="直播中" :value="1" />
|
||
|
|
<el-option label="已结束" :value="2" />
|
||
|
|
</el-select>
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
<el-col :span="12">
|
||
|
|
<el-form-item label="商品ID" prop="productId">
|
||
|
|
<el-input-number v-model="formData.productId" :min="0" controls-position="right" style="width: 100%" />
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
<el-col :span="12">
|
||
|
|
<el-form-item label="订单ID" prop="orderId">
|
||
|
|
<el-input-number v-model="formData.orderId" :min="0" controls-position="right" style="width: 100%" />
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
<el-col :span="24">
|
||
|
|
<el-form-item label="备注" prop="remark">
|
||
|
|
<el-input v-model="formData.remark" type="textarea" :rows="3" placeholder="请输入备注" />
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
</el-row>
|
||
|
|
</el-form>
|
||
|
|
<template #footer>
|
||
|
|
<span class="dialog-footer">
|
||
|
|
<el-button @click="dialogVisible = false">取消</el-button>
|
||
|
|
<el-button type="primary" :loading="loading" @click="handleSubmit">提交</el-button>
|
||
|
|
</span>
|
||
|
|
</template>
|
||
|
|
</el-dialog>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<script lang="ts" setup>
|
||
|
|
import { reactive, ref } from 'vue';
|
||
|
|
import { ElMessage, type FormInstance, type FormRules } from 'element-plus';
|
||
|
|
import { getAnchorList } from '/@/api/trade/operation/setting/anchor';
|
||
|
|
import { getLiveAccountList } from '/@/api/trade/operation/setting/live-account';
|
||
|
|
import { createSchedule, getScheduleDetail, updateSchedule, type ScheduleSaveParams } from '/@/api/trade/operation/setting/scheduling';
|
||
|
|
|
||
|
|
const emit = defineEmits<{
|
||
|
|
(e: 'refresh'): void;
|
||
|
|
}>();
|
||
|
|
|
||
|
|
interface AnchorOption {
|
||
|
|
id: string;
|
||
|
|
name: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
interface LiveAccountOption {
|
||
|
|
id: string;
|
||
|
|
platform: string;
|
||
|
|
accountName: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
const dialogVisible = ref(false);
|
||
|
|
const loading = ref(false);
|
||
|
|
const isEdit = ref(false);
|
||
|
|
const formRef = ref<FormInstance>();
|
||
|
|
const anchorOptions = ref<AnchorOption[]>([]);
|
||
|
|
const liveAccountOptions = ref<LiveAccountOption[]>([]);
|
||
|
|
|
||
|
|
const formData = reactive({
|
||
|
|
id: '',
|
||
|
|
anchorId: undefined as string | undefined,
|
||
|
|
accountId: undefined as string | undefined,
|
||
|
|
productId: 0,
|
||
|
|
orderId: 0,
|
||
|
|
startTime: undefined as Date | undefined,
|
||
|
|
endTime: undefined as Date | undefined,
|
||
|
|
status: 0,
|
||
|
|
remark: '',
|
||
|
|
});
|
||
|
|
|
||
|
|
const rules: FormRules = {
|
||
|
|
anchorId: [{ required: true, message: '请选择主播', trigger: 'change' }],
|
||
|
|
accountId: [{ required: true, message: '请选择直播账号', trigger: 'change' }],
|
||
|
|
startTime: [{ required: true, message: '请选择开始时间', trigger: 'change' }],
|
||
|
|
endTime: [{ required: true, message: '请选择结束时间', trigger: 'change' }],
|
||
|
|
};
|
||
|
|
|
||
|
|
const resetForm = () => {
|
||
|
|
formData.id = '';
|
||
|
|
formData.anchorId = undefined;
|
||
|
|
formData.accountId = undefined;
|
||
|
|
formData.productId = 0;
|
||
|
|
formData.orderId = 0;
|
||
|
|
formData.startTime = undefined;
|
||
|
|
formData.endTime = undefined;
|
||
|
|
formData.status = 0;
|
||
|
|
formData.remark = '';
|
||
|
|
};
|
||
|
|
|
||
|
|
const loadOptions = async () => {
|
||
|
|
const [anchorRes, liveAccountRes] = await Promise.all([
|
||
|
|
getAnchorList({ pageNum: 1, pageSize: 9999 }),
|
||
|
|
getLiveAccountList({ pageNum: 1, pageSize: 9999 }),
|
||
|
|
]);
|
||
|
|
|
||
|
|
anchorOptions.value = (anchorRes?.data?.list || []).map((item: any) => ({
|
||
|
|
id: String(item.id),
|
||
|
|
name: item.name || `主播${item.id}`,
|
||
|
|
}));
|
||
|
|
|
||
|
|
liveAccountOptions.value = (liveAccountRes?.data?.list || []).map((item: any) => ({
|
||
|
|
id: String(item.id),
|
||
|
|
platform: item.platform || '',
|
||
|
|
accountName: item.accountName || `账号${item.id}`,
|
||
|
|
}));
|
||
|
|
};
|
||
|
|
|
||
|
|
const openDialog = async (row?: { id?: string }) => {
|
||
|
|
resetForm();
|
||
|
|
isEdit.value = !!row?.id;
|
||
|
|
|
||
|
|
try {
|
||
|
|
loading.value = true;
|
||
|
|
await loadOptions();
|
||
|
|
|
||
|
|
if (row?.id) {
|
||
|
|
const res = await getScheduleDetail({ id: String(row.id) });
|
||
|
|
const detail = res?.data;
|
||
|
|
if (detail) {
|
||
|
|
formData.id = String(detail.id);
|
||
|
|
formData.anchorId = detail.anchorId ? String(detail.anchorId) : undefined;
|
||
|
|
formData.accountId = detail.accountId ? String(detail.accountId) : undefined;
|
||
|
|
formData.productId = detail.productId || 0;
|
||
|
|
formData.orderId = detail.orderId || 0;
|
||
|
|
formData.startTime = detail.startTime ? new Date(detail.startTime) : undefined;
|
||
|
|
formData.endTime = detail.endTime ? new Date(detail.endTime) : undefined;
|
||
|
|
formData.status = detail.status ?? 0;
|
||
|
|
formData.remark = detail.remark || '';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
dialogVisible.value = true;
|
||
|
|
} catch (error) {
|
||
|
|
ElMessage.error(isEdit.value ? '获取排班详情失败' : '加载排班基础数据失败');
|
||
|
|
} finally {
|
||
|
|
loading.value = false;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
const handleSubmit = async () => {
|
||
|
|
if (!formRef.value) return;
|
||
|
|
|
||
|
|
try {
|
||
|
|
await formRef.value.validate();
|
||
|
|
loading.value = true;
|
||
|
|
|
||
|
|
const payload: ScheduleSaveParams = {
|
||
|
|
id: formData.id || undefined,
|
||
|
|
anchorId: formData.anchorId as string,
|
||
|
|
accountId: formData.accountId as string,
|
||
|
|
productId: formData.productId || 0,
|
||
|
|
orderId: formData.orderId || 0,
|
||
|
|
startTime: (formData.startTime as Date).toISOString(),
|
||
|
|
endTime: (formData.endTime as Date).toISOString(),
|
||
|
|
status: formData.status,
|
||
|
|
remark: formData.remark,
|
||
|
|
};
|
||
|
|
|
||
|
|
if (isEdit.value) {
|
||
|
|
await updateSchedule(payload);
|
||
|
|
ElMessage.success('修改排班成功');
|
||
|
|
} else {
|
||
|
|
await createSchedule(payload);
|
||
|
|
ElMessage.success('新增排班成功');
|
||
|
|
}
|
||
|
|
|
||
|
|
dialogVisible.value = false;
|
||
|
|
emit('refresh');
|
||
|
|
} catch (error) {
|
||
|
|
ElMessage.error(isEdit.value ? '修改排班失败' : '新增排班失败');
|
||
|
|
} finally {
|
||
|
|
loading.value = false;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
defineExpose({
|
||
|
|
openDialog,
|
||
|
|
});
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<style scoped>
|
||
|
|
.dialog-footer {
|
||
|
|
display: flex;
|
||
|
|
justify-content: flex-end;
|
||
|
|
}
|
||
|
|
</style>
|