feat: add web application

This commit is contained in:
richjohnrambo
2026-10-10 20:55:59 +08:00
parent 3eb5d78875
commit 50fcfd2d3d
571 changed files with 73992 additions and 135 deletions
+147
View File
@@ -0,0 +1,147 @@
<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="会员等级" :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 { 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);
const init = () => ({
id: 0,
version: 0,
title: '',
description: '',
detailHtml: '',
coverAttachmentId: 0,
coverUrl: '',
hallId: 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: '请选择任务大厅' },
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;
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>