MarketingSystemDataTool/web/index.html

305 lines
16 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>MarketingSystemDataTool</title>
<link rel="stylesheet" href="./vendor/element-plus.min.css">
<link rel="stylesheet" href="./styles.css">
</head>
<body>
<div id="app">
<el-container>
<el-header height="56px">
<el-row align="middle" justify="space-between">
<el-col :span="24">
<div class="title">导出工具</div>
</el-col>
</el-row>
</el-header>
<el-main>
<el-row :gutter="16">
<el-col :span="24">
<el-card>
<template #header>
<div style="display:flex;align-items:center;gap:8px">
<span>导出模版</span>
<el-button type="primary" size="small" @click="createVisible=true">新增模板</el-button>
</div>
</template>
<el-table :data="templates" size="small" stripe>
<el-table-column prop="id" label="ID" width="80"></el-table-column>
<el-table-column prop="name" label="名称"></el-table-column>
<el-table-column label="数据源" width="120">
<template #default="scope">{{ dsLabel(scope.row.datasource) }}</template>
</el-table-column>
<el-table-column prop="file_format" label="格式" width="100"></el-table-column>
<el-table-column prop="field_count" label="字段数" width="100"></el-table-column>
<el-table-column prop="exec_count" label="执行次数" width="120"></el-table-column>
<el-table-column label="操作" width="260">
<template #default="scope">
<el-button size="small" type="primary" @click="openExport(scope.row)">执行</el-button>
<el-button size="small" @click="openJobs(scope.row)">任务</el-button>
<el-button
v-if="(!hasUserId) || (hasUserId && Number(scope.row.owner_id)===currentUserId)"
size="small"
@click="openEdit(scope.row)">编辑</el-button>
<el-button
v-if="(!hasUserId) || (Number(scope.row.owner_id)!==0 && Number(scope.row.owner_id)===currentUserId)"
size="small"
type="danger"
@click="removeTemplate(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
</el-col>
<el-col :span="24">
<el-dialog v-model="jobsVisible" :title="'导出任务(模板 '+ (jobsTplId||'') +''" width="1000px">
<el-table :data="jobs" size="small" stripe row-key="id">
<el-table-column prop="id" label="ID"></el-table-column>
<el-table-column label="校验状态">
<template #default="scope">{{ scope.row.eval_status || '评估中' }}</template>
</el-table-column>
<el-table-column label="进度">
<template #default="scope">{{ jobPercent(scope.row) }}</template>
</el-table-column>
<el-table-column prop="row_estimate" label="行数"></el-table-column>
<el-table-column prop="total_rows" label="已写行数"></el-table-column>
<el-table-column prop="file_format" label="格式"></el-table-column>
<el-table-column label="创建时间">
<template #default="scope">{{ fmtDT(new Date(scope.row.created_at)) }}</template>
</el-table-column>
<el-table-column label="操作" width="200">
<template #default="scope">
<el-button size="small" @click="openSQL(scope.row.id)">分析</el-button>
<el-button v-if="scope.row.status==='completed' && Number(scope.row.total_rows)>0" size="small" type="success" @click="download(scope.row.id)">下载</el-button>
<el-button v-else-if="scope.row.status==='completed'" size="small" disabled>无数据</el-button>
</template>
</el-table-column>
</el-table>
<div style="display:flex;justify-content:flex-end;margin-top:8px">
<el-pagination background layout="prev, pager, next, total" :total="jobsTotal" :page-size="jobsPageSize" v-model:currentPage="jobsPage" @current-change="loadJobs" />
</div>
<template #footer>
<el-button @click="closeJobs">关闭</el-button>
</template>
</el-dialog>
<el-dialog v-model="sqlVisible" title="生成SQL" width="800px">
<div style="max-height:50vh;overflow:auto"><pre style="white-space:pre-wrap">{{ sqlText }}</pre></div>
<template #footer>
<el-button @click="sqlVisible=false">关闭</el-button>
</template>
</el-dialog>
</el-col>
</el-row>
</el-main>
</el-container>
<el-dialog v-model="createVisible" title="新增模板" :width="createWidth">
<el-form ref="createFormRef" :model="form" :rules="createRules" label-width="110px" status-icon>
<el-form-item label="模板名称" required show-message prop="name"><el-input v-model="form.name" placeholder="模板名称" /></el-form-item>
<el-form-item label="数据源" required show-message>
<el-select v-model="form.datasource" placeholder="选择" :teleported="false">
<el-option v-for="opt in datasourceOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
</el-select>
</el-form-item>
<el-form-item label="导出场景" required show-message>
<el-select v-model="form.main_table" placeholder="订单数据">
<el-option v-for="opt in sceneOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
</el-select>
</el-form-item>
<el-form-item label="订单类型" required show-message prop="orderType">
<el-radio-group v-model="form.orderType">
<el-radio :label="1">直充卡密</el-radio>
<el-radio :label="2">立减金</el-radio>
<el-radio :label="3">红包</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="字段选择" required show-message prop="fieldsSel">
<div ref="createCascaderRoot">
<el-cascader
ref="fieldsCascader"
v-model="form.fieldsSel"
:key="form.datasource + '-' + String(form.orderType)"
:options="fieldOptionsDynamic"
:props="{ multiple: true, checkStrictly: false, expandTrigger: 'hover', checkOnClickNode: true, checkOnClickLeaf: true }"
:teleported="false"
collapse-tags
collapse-tags-tooltip
placeholder="按场景逐级选择,可多选"
@visible-change="onCascaderVisible('create', $event)"
@change="onFieldsSelChange('create')"
/>
</div>
</el-form-item>
<el-row :gutter="8">
<el-col :span="12">
<el-form-item label="输出格式" required show-message prop="file_format">
<el-select v-model="form.file_format" :teleported="false" placeholder="请选择" style="width:160px">
<el-option v-for="opt in formatOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="可见性" required show-message prop="visibility">
<el-select v-model="form.visibility" clearable :teleported="false" style="width:160px" placeholder="请选择">
<el-option v-for="opt in visibilityOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<el-button @click="resizeDialog('create', -100)">缩小</el-button>
<el-button @click="resizeDialog('create', 100)">放大</el-button>
<el-button @click="createVisible=false">取消</el-button>
<el-button type="primary" @click="createTemplate">创建</el-button>
</template>
</el-dialog>
<el-dialog v-model="editVisible" title="编辑模板" :width="editWidth">
<el-form ref="editFormRef" :model="edit" :rules="editRules" label-width="110px">
<el-form-item label="模板名称" required show-message prop="name"><el-input v-model="edit.name" /></el-input></el-form-item>
<el-form-item label="数据源">
<el-select v-model="edit.datasource" placeholder="选择" :teleported="false" style="width:160px">
<el-option v-for="opt in datasourceOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
</el-select>
</el-form-item>
<el-form-item label="导出场景">
<el-select v-model="edit.main_table" placeholder="订单数据" style="width:160px">
<el-option v-for="opt in editSceneOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
</el-select>
</el-form-item>
<el-form-item label="订单类型" required show-message prop="orderType">
<el-radio-group v-model="edit.orderType">
<el-radio :label="1">直充卡密</el-radio>
<el-radio :label="2">立减金</el-radio>
<el-radio :label="3">红包</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="字段选择" required show-message prop="fieldsSel">
<div ref="editCascaderRoot">
<el-cascader
ref="editFieldsCascader"
v-model="edit.fieldsSel"
:key="edit.datasource + '-' + String(edit.orderType)"
:options="editFieldOptionsDynamic"
:props="{ multiple: true, checkStrictly: false, expandTrigger: 'hover', checkOnClickNode: true, checkOnClickLeaf: true }"
:teleported="false"
collapse-tags
collapse-tags-tooltip
placeholder="按场景逐级选择,可多选"
@visible-change="onCascaderVisible('edit', $event)"
@change="onFieldsSelChange('edit')"
/>
</div>
</el-form-item>
<el-row :gutter="8">
<el-col :span="12">
<el-form-item label="输出格式">
<el-select v-model="edit.file_format" :teleported="false" placeholder="请选择" style="width:160px">
<el-option v-for="opt in formatOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="可见性">
<el-select v-model="form.visibility" clearable :disabled="hasUserId" :teleported="false" style="width:160px" placeholder="请选择">
<el-option v-for="opt in visibilityOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<el-button @click="resizeDialog('edit', -100)">缩小</el-button>
<el-button @click="resizeDialog('edit', 100)">放大</el-button>
<el-button @click="editVisible=false">取消</el-button>
<el-button type="primary" @click="saveEdit">保存</el-button>
</template>
</el-dialog>
<el-dialog v-model="exportVisible" :title="exportTitle" width="1100px">
<el-form ref="exportFormRef" :model="exportForm" :rules="exportRules" label-width="110px" status-icon>
<el-divider content-position="left">筛选条件</el-divider>
<el-row :gutter="8">
<el-col :span="24">
<el-form-item label="时间范围" required show-message prop="dateRange">
<el-date-picker v-model="exportForm.dateRange" type="datetimerange" start-placeholder="开始时间" end-placeholder="结束时间" value-format="YYYY-MM-DD HH:mm:ss" style="width:100%" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="8" v-if="isOrder && exportForm.datasource==='ymt'">
<el-col :span="8">
<el-form-item label="创建者" prop="ymtCreatorId">
<el-select v-model.number="exportForm.ymtCreatorId" :disabled="hasUserId" clearable filterable :teleported="false" placeholder="请选择创建者" style="width:100%">
<el-option v-for="opt in ymtCreatorOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="客户" prop="ymtMerchantId">
<el-select v-model.number="exportForm.ymtMerchantId" :disabled="!exportForm.ymtCreatorId" clearable filterable :teleported="false" placeholder="请选择客户" style="width:100%">
<el-option v-for="opt in ymtMerchantOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="活动" prop="ymtActivityId">
<el-select v-model.number="exportForm.ymtActivityId" :disabled="!exportForm.ymtMerchantId" clearable filterable :teleported="false" placeholder="请选择活动" style="width:100%">
<el-option v-for="opt in ymtActivityOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="8" v-if="isOrder && exportForm.datasource==='marketing'">
<el-col :span="12">
<el-form-item label="创建者" prop="creator">
<el-select v-model="exportForm.creatorIds" multiple filterable :disabled="hasUserId" :teleported="false" placeholder="请选择创建者" style="width:100%">
<el-option v-for="opt in creatorOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="分销商" prop="resellerId">
<el-select v-model.number="exportForm.resellerId" filterable :teleported="false" placeholder="请选择分销商" style="width:100%" :disabled="!hasCreators">
<el-option v-for="opt in resellerOptions" :key="opt.value" :label="opt.label||String(opt.value)" :value="opt.value" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="8" v-if="isOrder && exportForm.datasource==='marketing'">
<el-col :span="12">
<el-form-item label="计划" prop="planId">
<el-select v-model="exportForm.planId" :disabled="!hasReseller" :teleported="false" filterable placeholder="选择计划">
<el-option v-for="opt in planOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="8" v-if="isOrder">
<el-col :span="12" v-if="exportType===2">
<el-form-item label="立减金批次号" prop="voucherChannelActivityId"><el-input v-model="exportForm.voucherChannelActivityId" placeholder="请输入立减金批次号" /></el-form-item>
</el-col>
</el-row>
<!-- 输出格式按模板设置,不在此显示 -->
</el-form>
<template #footer>
<el-button @click="exportVisible=false">取消</el-button>
<el-button type="primary" @click="submitExport">执行并分析</el-button>
</template>
</el-dialog>
</div>
<script src="./vendor/vue.global.prod.js"></script>
<script src="./vendor/element-plus.full.min.js"></script>
<script src="./main.js"></script>
</body>
</html>