169 lines
6.1 KiB
Vue
169 lines
6.1 KiB
Vue
<template>
|
||
<n-modal
|
||
v-model:show="show"
|
||
preset="card"
|
||
:title="form.id ? '编辑任务' : '新增任务'"
|
||
class="edit-modal"
|
||
><n-spin :show="loading"
|
||
><n-form ref="formRef" :model="form" :rules="rules" label-placement="left" label-width="110"
|
||
><n-grid cols="1 m:2" responsive="screen" :x-gap="16"
|
||
><n-form-item-gi label="任务标题" path="title"
|
||
><n-input v-model:value="form.title" /></n-form-item-gi
|
||
><n-form-item-gi label="任务大厅" path="hallId"
|
||
><n-select
|
||
v-model:value="form.hallId"
|
||
:options="dict.getOptionUnRef('taskHallOption')" /></n-form-item-gi
|
||
><n-form-item-gi label="关联商品" path="productId"
|
||
><n-select
|
||
v-model:value="form.productId"
|
||
filterable
|
||
:loading="productLoading"
|
||
:options="productOptions"
|
||
placeholder="请选择关联商品" /></n-form-item-gi
|
||
><n-form-item-gi label="会员等级" :span="2" path="levelIds"
|
||
><n-select
|
||
v-model:value="form.levelIds"
|
||
multiple
|
||
:options="dict.getOptionUnRef('memberLevelOption')" /></n-form-item-gi
|
||
><n-form-item-gi label="固定佣金(元)" path="commission"
|
||
><n-input v-model:value="form.commission" /></n-form-item-gi
|
||
><n-form-item-gi label="比例佣金(%)"
|
||
><n-input-number
|
||
v-model:value="commissionPercent"
|
||
:min="0"
|
||
:max="100"
|
||
:precision="2" /></n-form-item-gi
|
||
><n-form-item-gi label="每日总量"
|
||
><n-input-number v-model:value="form.dailyLimit" :min="0" /></n-form-item-gi
|
||
><n-form-item-gi label="单会员限制"
|
||
><n-input-number v-model:value="form.perMemberLimit" :min="1" /></n-form-item-gi
|
||
><n-form-item-gi label="任务周期" :span="2"
|
||
><n-date-picker
|
||
v-model:value="dateRange"
|
||
type="datetimerange"
|
||
clearable /></n-form-item-gi
|
||
><n-form-item-gi label="任务封面" :span="2" path="coverUrl"
|
||
><UploadImage v-model:value="form.coverUrl" :max-number="1" /></n-form-item-gi
|
||
><n-form-item-gi label="任务描述" :span="2" path="description"
|
||
><n-input v-model:value="form.description" type="textarea" /></n-form-item-gi
|
||
><n-form-item-gi label="任务详情" :span="2"
|
||
><Editor
|
||
id="task-editor"
|
||
v-model:value="form.detailHtml"
|
||
class="editor" /></n-form-item-gi
|
||
><n-form-item-gi label="排序"><n-input-number v-model:value="form.sort" /></n-form-item-gi
|
||
><n-form-item-gi label="备注"
|
||
><n-input v-model:value="form.remark" /></n-form-item-gi></n-grid></n-form></n-spin
|
||
><template #action
|
||
><n-space justify="end"
|
||
><n-button @click="show = false">取消</n-button
|
||
><n-button type="primary" :loading="saving" @click="save">保存</n-button></n-space
|
||
></template
|
||
></n-modal
|
||
>
|
||
</template>
|
||
<script setup lang="ts">
|
||
import { reactive, ref } from 'vue';
|
||
import { useMessage } from 'naive-ui';
|
||
import Editor from '@/components/Editor/editor.vue';
|
||
import UploadImage from '@/components/Upload/uploadImage.vue';
|
||
import { useDictStore } from '@/store/modules/dict';
|
||
import { ProductList, TaskEdit, TaskView } from '@/api/productTask';
|
||
const emit = defineEmits(['reload']),
|
||
message = useMessage(),
|
||
dict = useDictStore(),
|
||
show = ref(false),
|
||
loading = ref(false),
|
||
saving = ref(false),
|
||
formRef = ref(),
|
||
dateRange = ref<any>(),
|
||
commissionPercent = ref(0),
|
||
productLoading = ref(false),
|
||
productOptions = ref<any[]>([]);
|
||
const init = () => ({
|
||
id: 0,
|
||
version: 0,
|
||
title: '',
|
||
description: '',
|
||
detailHtml: '',
|
||
coverAttachmentId: 0,
|
||
coverUrl: '',
|
||
hallId: null,
|
||
productId: null,
|
||
levelIds: [],
|
||
commission: '0.00',
|
||
dailyLimit: 0,
|
||
perMemberLimit: 1,
|
||
sort: 0,
|
||
remark: '',
|
||
});
|
||
const form = reactive<any>(init());
|
||
const rules = {
|
||
title: { required: true, message: '请输入任务标题' },
|
||
description: { required: true, message: '请输入任务描述' },
|
||
coverUrl: { required: true, message: '请上传任务封面' },
|
||
hallId: { required: true, type: 'number', message: '请选择任务大厅' },
|
||
productId: { required: true, type: 'number', message: '请选择关联商品' },
|
||
levelIds: { required: true, type: 'array', min: 1, message: '请选择会员等级' },
|
||
commission: { required: true, message: '请输入固定佣金' },
|
||
};
|
||
async function open(row?) {
|
||
Object.assign(form, init());
|
||
commissionPercent.value = 0;
|
||
dateRange.value = null;
|
||
show.value = true;
|
||
productLoading.value = true;
|
||
try {
|
||
const result: any = await ProductList({ page: 1, perPage: 200 });
|
||
productOptions.value = (result.list || []).map((item) => ({
|
||
label: `${item.name}(${item.productNo})`,
|
||
value: item.id,
|
||
}));
|
||
} finally {
|
||
productLoading.value = false;
|
||
}
|
||
if (row) {
|
||
loading.value = true;
|
||
try {
|
||
const r: any = await TaskView({ id: row.id });
|
||
Object.assign(form, r, { commission: ((r.commissionAmount || 0) / 100).toFixed(2) });
|
||
commissionPercent.value = (r.commissionRate || 0) / 100;
|
||
if (r.startAt && r.endAt)
|
||
dateRange.value = [new Date(r.startAt).getTime(), new Date(r.endAt).getTime()];
|
||
} finally {
|
||
loading.value = false;
|
||
}
|
||
}
|
||
}
|
||
async function save() {
|
||
try {
|
||
await formRef.value?.validate();
|
||
} catch {
|
||
return;
|
||
}
|
||
saving.value = true;
|
||
try {
|
||
await TaskEdit({
|
||
...form,
|
||
commissionRate: Math.round(commissionPercent.value * 100),
|
||
startAt: dateRange.value?.[0] || null,
|
||
endAt: dateRange.value?.[1] || null,
|
||
});
|
||
message.success('任务已保存');
|
||
show.value = false;
|
||
emit('reload');
|
||
} finally {
|
||
saving.value = false;
|
||
}
|
||
}
|
||
defineExpose({ open });
|
||
</script>
|
||
<style lang="less" scoped>
|
||
:deep(.edit-modal) {
|
||
width: min(960px, 94vw);
|
||
}
|
||
.editor {
|
||
height: 340px;
|
||
}
|
||
</style>
|