tianyi 5 days ago
parent
commit
56f75606e0
  1. 322
      src/views/app/business/luckey/luckey.vue

322
src/views/app/business/luckey/luckey.vue

@ -2,26 +2,24 @@
<div class="luckey">
<Card>
<Row class="region-bar">
<span class="region-tip">当前校区<b>{{ JSON.parse(this.getStore("user")).departmentTitle || '未识别(请确认账号已绑定校区)' }}</b></span>
<span class="region-tip">当前校区<b>{{ regionId || '未识别(请确认账号已绑定校区)' }}</b></span>
<Button type="primary" icon="ios-refresh" @click="reloadActive" :disabled="!regionId">刷新</Button>
</Row>
<Tabs v-model="activeTab" @on-click="onTabChange">
<!-- 奖池 -->
<TabPane label="奖池/开奖" name="pool">
<Row align="middle" justify="space-between" class="operation">
<Button type="primary" icon="md-add" @click="openPool()" style="margin-bottom:12px">新建奖池</Button>
<Button type="primary" icon="ios-refresh" @click="reloadActive" :disabled="!regionId">刷新</Button>
</Row>
<Alert show-icon>
现金奖池采用主动投入规则用户投入星球券后即从余额扣除并回收本期按投入券数加权开奖投入越多中奖概率越高
</Alert>
<Button type="primary" icon="md-add" @click="openPool()" style="margin-bottom:12px">新建奖池</Button>
<Table border :loading="pool.loading" :columns="poolColumns" :data="pool.data"></Table>
<Row type="flex" justify="end" class="page">
<Page :current="pool.pageNumber" :total="pool.total" :page-size="pool.pageSize"
@on-change="p => changePage('pool', p)" size="small" show-total></Page>
</Row>
</TabPane>
<!-- 任务 -->
<TabPane label="券任务规则" name="task">
<Button type="primary" icon="md-add" @click="openTask()" style="margin-bottom:12px">新增任务</Button>
@ -42,6 +40,63 @@
</Row>
</TabPane>
<!-- 经营系统 -->
<TabPane label="券树配置" name="tree">
<Button type="primary" icon="md-add" @click="openOperate('tree')" style="margin-bottom:12px">新增券树周期</Button>
<Table border :loading="tree.loading" :columns="treeColumns" :data="tree.data"></Table>
<Row type="flex" justify="end" class="page">
<Page :current="tree.pageNumber" :total="tree.total" :page-size="tree.pageSize"
@on-change="p => changePage('tree', p)" size="small" show-total></Page>
</Row>
</TabPane>
<TabPane label="仓库等级" name="warehouse">
<Button type="primary" icon="md-add" @click="openOperate('warehouse')" style="margin-bottom:12px">新增仓库等级</Button>
<Table border :loading="warehouse.loading" :columns="warehouseColumns" :data="warehouse.data"></Table>
<Row type="flex" justify="end" class="page">
<Page :current="warehouse.pageNumber" :total="warehouse.total" :page-size="warehouse.pageSize"
@on-change="p => changePage('warehouse', p)" size="small" show-total></Page>
</Row>
</TabPane>
<TabPane label="防御塔" name="tower">
<Button type="primary" icon="md-add" @click="openOperate('tower')" style="margin-bottom:12px">新增防御塔等级</Button>
<Table border :loading="tower.loading" :columns="towerColumns" :data="tower.data"></Table>
<Row type="flex" justify="end" class="page">
<Page :current="tower.pageNumber" :total="tower.total" :page-size="tower.pageSize"
@on-change="p => changePage('tower', p)" size="small" show-total></Page>
</Row>
</TabPane>
<TabPane label="搜查规则" name="search">
<Button type="primary" icon="md-add" @click="openOperate('search')" style="margin-bottom:12px">新增搜查规则</Button>
<Table border :loading="search.loading" :columns="searchColumns" :data="search.data"></Table>
<Row type="flex" justify="end" class="page">
<Page :current="search.pageNumber" :total="search.total" :page-size="search.pageSize"
@on-change="p => changePage('search', p)" size="small" show-total></Page>
</Row>
</TabPane>
<TabPane label="体力道具" name="stamina">
<Button type="primary" icon="md-add" @click="openOperate('stamina')" style="margin-bottom:12px">新增体力道具</Button>
<Table border :loading="stamina.loading" :columns="staminaColumns" :data="stamina.data"></Table>
<Row type="flex" justify="end" class="page">
<Page :current="stamina.pageNumber" :total="stamina.total" :page-size="stamina.pageSize"
@on-change="p => changePage('stamina', p)" size="small" show-total></Page>
</Row>
</TabPane>
<TabPane label="校园地标" name="landmark">
<Button type="primary" icon="md-add" @click="openOperate('landmark')" style="margin-bottom:12px">新增校园地标</Button>
<Table border :loading="landmark.loading" :columns="landmarkColumns" :data="landmark.data"></Table>
<Row type="flex" justify="end" class="page">
<Page :current="landmark.pageNumber" :total="landmark.total" :page-size="landmark.pageSize"
@on-change="p => changePage('landmark', p)" size="small" show-total></Page>
</Row>
</TabPane>
<TabPane label="经济审计" name="economy">
<Table border :loading="economy.loading" :columns="economyColumns" :data="economy.data"></Table>
<Row type="flex" justify="end" class="page">
<Page :current="economy.pageNumber" :total="economy.total" :page-size="economy.pageSize"
@on-change="p => changePage('economy', p)" size="small" show-total></Page>
</Row>
</TabPane>
<!-- 快讯 -->
<TabPane label="星球快讯" name="news">
<Button type="primary" icon="md-add" @click="openNews()" style="margin-bottom:12px">新增快讯</Button>
@ -232,6 +287,25 @@
<Button type="primary" @click="saveNews">保存</Button>
</div>
</Modal>
<!-- 经营配置编辑 -->
<Modal v-model="operateModal" :title="operateTitle" width="620" :mask-closable="false">
<Form :label-width="120">
<FormItem label="所属校区"><Input v-model="operateForm.regionId" disabled placeholder="自动取自登录校区" /></FormItem>
<FormItem v-for="f in operateFields" :key="f.key" :label="f.label">
<i-switch v-if="f.type==='switch'" v-model="operateForm[f.key]" :true-value="1" :false-value="0" />
<Select v-else-if="f.type==='select'" v-model="operateForm[f.key]">
<Option v-for="op in f.options" :key="op.value" :value="op.value">{{ op.label }}</Option>
</Select>
<InputNumber v-else-if="f.type==='number'" v-model="operateForm[f.key]" :min="f.min === undefined ? 0 : f.min" :step="f.step || 1" style="width:100%" />
<Input v-else v-model="operateForm[f.key]" />
</FormItem>
</Form>
<div slot="footer">
<Button @click="operateModal=false">取消</Button>
<Button type="primary" @click="saveOperate">保存</Button>
</div>
</Modal>
</div>
</template>
@ -243,7 +317,14 @@
planetBuffPage, planetBuffSave, planetBuffDelete,
planetNewsPage, planetNewsSave, planetNewsDelete,
planetRankPage, planetHuntPage, planetDrawPage, planetWinnerPage,
planetManualDraw
planetManualDraw,
planetTreePage, planetTreeSave, planetTreeDelete,
planetWarehousePage, planetWarehouseSave, planetWarehouseDelete,
planetTowerPage, planetTowerSave, planetTowerDelete,
planetSearchPage, planetSearchSave, planetSearchDelete,
planetStaminaPage, planetStaminaSave, planetStaminaDelete,
planetLandmarkPage, planetLandmarkSave, planetLandmarkDelete,
planetEconomyPage
} from '@/api/planet';
export default {
@ -260,6 +341,13 @@
hunt: { loading: false, data: [], total: 0, pageNumber: 1, pageSize: 10 },
draw: { loading: false, data: [], total: 0, pageNumber: 1, pageSize: 10 },
winner: { loading: false, data: [], total: 0, pageNumber: 1, pageSize: 10 },
tree: { loading: false, data: [], total: 0, pageNumber: 1, pageSize: 10 },
warehouse: { loading: false, data: [], total: 0, pageNumber: 1, pageSize: 10 },
tower: { loading: false, data: [], total: 0, pageNumber: 1, pageSize: 10 },
search: { loading: false, data: [], total: 0, pageNumber: 1, pageSize: 10 },
stamina: { loading: false, data: [], total: 0, pageNumber: 1, pageSize: 10 },
landmark: { loading: false, data: [], total: 0, pageNumber: 1, pageSize: 10 },
economy: { loading: false, data: [], total: 0, pageNumber: 1, pageSize: 10 },
//
poolModal: false,
poolForm: {},
@ -273,17 +361,88 @@
buffModal: false,
buffForm: {},
newsModal: false,
newsForm: {}
newsForm: {},
operateModal: false,
operateType: '',
operateForm: {}
}
},
computed: {
operateTitle() {
const map = { tree: '券树周期', warehouse: '仓库等级', tower: '防御塔等级', search: '搜查规则', stamina: '体力道具', landmark: '校园地标' }
return (this.operateForm.id ? '编辑' : '新增') + (map[this.operateType] || '经营配置')
},
operateFields() {
const fields = {
tree: [
{ key: 'cycleHours', label: '培育小时', type: 'number' },
{ key: 'rate', label: '收益率', type: 'number', step: 0.01 },
{ key: 'minInvest', label: '最低投入', type: 'number' },
{ key: 'maxInvest', label: '最高投入', type: 'number' },
{ key: 'maxProfit', label: '单次最高收益', type: 'number' },
{ key: 'dailyProfitLimit', label: '每日收益上限', type: 'number' },
{ key: 'sort', label: '排序', type: 'number' },
{ key: 'enabled', label: '是否启用', type: 'switch' }
],
warehouse: [
{ key: 'level', label: '等级', type: 'number' },
{ key: 'capacity', label: '容量', type: 'number' },
{ key: 'upgradeCost', label: '升级消耗券', type: 'number' },
{ key: 'enabled', label: '是否启用', type: 'switch' }
],
tower: [
{ key: 'level', label: '等级', type: 'number' },
{ key: 'interceptRate', label: '拦截率(%)', type: 'number', step: 0.1 },
{ key: 'damage', label: '体力伤害', type: 'number' },
{ key: 'counterRate', label: '反击率(%)', type: 'number', step: 0.1 },
{ key: 'upgradeCost', label: '升级消耗券', type: 'number' },
{ key: 'enabled', label: '是否启用', type: 'switch' }
],
search: [
{ key: 'dailyLimit', label: '每日次数', type: 'number' },
{ key: 'staminaCost', label: '消耗体力', type: 'number' },
{ key: 'minGain', label: '最低获得', type: 'number' },
{ key: 'maxGain', label: '最高获得', type: 'number' },
{ key: 'targetBalanceRate', label: '目标余额比例', type: 'number', step: 0.01 },
{ key: 'dailyGainLimit', label: '每日获得上限', type: 'number' },
{ key: 'targetProtectMinutes', label: '保护分钟', type: 'number' },
{ key: 'enabled', label: '是否启用', type: 'switch' }
],
stamina: [
{ key: 'name', label: '道具名称' },
{ key: 'recoverStamina', label: '恢复体力', type: 'number' },
{ key: 'costTickets', label: '消耗券', type: 'number' },
{ key: 'dailyBuyLimit', label: '每日购买上限', type: 'number' },
{ key: 'sort', label: '排序', type: 'number' },
{ key: 'enabled', label: '是否启用', type: 'switch' }
],
landmark: [
{ key: 'name', label: '地标名称' },
{ key: 'icon', label: '图标' },
{ key: 'benefitType', label: '收益类型', type: 'select', options: [
{ value: 'ticket', label: '每日发券' },
{ value: 'stamina_speed', label: '体力恢复加速' },
{ value: 'search_rate', label: '搜查成功率' },
{ value: 'tower_damage', label: '防御塔伤害' }
] },
{ key: 'benefitValue', label: '收益值', type: 'number', step: 0.1 },
{ key: 'dailyOutputLimit', label: '日输出上限', type: 'number' },
{ key: 'openStartTime', label: '开放开始' },
{ key: 'openEndTime', label: '开放结束' },
{ key: 'settleTime', label: '结算时间' },
{ key: 'sort', label: '排序', type: 'number' },
{ key: 'enabled', label: '是否启用', type: 'switch' }
]
}
return fields[this.operateType] || []
},
poolColumns() {
return [
{ title: '期号', key: 'periodNo', width: 160 },
{ title: '期号', key: 'periodNo', minWidth: 120 },
{ title: '标题', key: 'title', minWidth: 120 },
{ title: '商圈', key: 'regionId', width: 170 , render: (h, p) => h('span', p.row.regionId == JSON.parse(this.getStore("user")).departmentId ? JSON.parse(this.getStore("user")).departmentTitle : '') },
{ title: '商圈', key: 'regionId', width: 100 },
{ title: '奖池金额', key: 'poolAmount', width: 100 },
{ title: '开奖时间', key: 'drawTime', width: 170 },
{ title: '开奖时间', key: 'drawTime', minWidth: 160 },
{ title: '参与', key: 'joinCount', width: 70 },
{ title: '中奖', key: 'winnerCount', width: 70 },
{
@ -421,6 +580,82 @@
{ title: '已领取', width: 80, render: (h, p) => h('Tag', { props: { color: p.row.isReceived === 1 ? 'green' : 'orange' } }, p.row.isReceived === 1 ? '已领' : '未领') },
{ title: '时间', key: 'createTime', minWidth: 160 }
]
},
treeColumns() {
return [
{ title: '周期(h)', key: 'cycleHours', width: 90 },
{ title: '收益率', key: 'rate', width: 90 },
{ title: '投入范围', minWidth: 140, render: (h, p) => h('span', `${p.row.minInvest || 0} - ${p.row.maxInvest || '不限'}`) },
{ title: '单次收益上限', key: 'maxProfit', width: 120 },
{ title: '日收益上限', key: 'dailyProfitLimit', width: 110 },
{ title: '启用', width: 70, render: (h, p) => this.enabledTag(h, p.row.enabled) },
this.operateActionColumn('tree')
]
},
warehouseColumns() {
return [
{ title: '等级', key: 'level', width: 90 },
{ title: '容量', key: 'capacity', width: 100 },
{ title: '升级消耗券', key: 'upgradeCost', width: 120 },
{ title: '启用', width: 70, render: (h, p) => this.enabledTag(h, p.row.enabled) },
this.operateActionColumn('warehouse')
]
},
towerColumns() {
return [
{ title: '等级', key: 'level', width: 80 },
{ title: '拦截率(%)', key: 'interceptRate', width: 110 },
{ title: '伤害', key: 'damage', width: 90 },
{ title: '反击率(%)', key: 'counterRate', width: 110 },
{ title: '升级消耗券', key: 'upgradeCost', width: 120 },
{ title: '启用', width: 70, render: (h, p) => this.enabledTag(h, p.row.enabled) },
this.operateActionColumn('tower')
]
},
searchColumns() {
return [
{ title: '每日次数', key: 'dailyLimit', width: 90 },
{ title: '体力消耗', key: 'staminaCost', width: 90 },
{ title: '获得范围', minWidth: 120, render: (h, p) => h('span', `${p.row.minGain || 0} - ${p.row.maxGain || 0}`) },
{ title: '目标比例', key: 'targetBalanceRate', width: 90 },
{ title: '日获得上限', key: 'dailyGainLimit', width: 110 },
{ title: '启用', width: 70, render: (h, p) => this.enabledTag(h, p.row.enabled) },
this.operateActionColumn('search')
]
},
staminaColumns() {
return [
{ title: '名称', key: 'name', minWidth: 120 },
{ title: '恢复体力', key: 'recoverStamina', width: 90 },
{ title: '消耗券', key: 'costTickets', width: 90 },
{ title: '日购买上限', key: 'dailyBuyLimit', width: 110 },
{ title: '启用', width: 70, render: (h, p) => this.enabledTag(h, p.row.enabled) },
this.operateActionColumn('stamina')
]
},
landmarkColumns() {
return [
{ title: '名称', key: 'name', minWidth: 120 },
{ title: '图标', key: 'icon', width: 80 },
{ title: '收益类型', key: 'benefitType', width: 120 },
{ title: '收益值', key: 'benefitValue', width: 90 },
{ title: '开放时间', minWidth: 150, render: (h, p) => h('span', `${p.row.openStartTime || '--'} - ${p.row.openEndTime || '--'}`) },
{ title: '启用', width: 70, render: (h, p) => this.enabledTag(h, p.row.enabled) },
this.operateActionColumn('landmark')
]
},
economyColumns() {
return [
{ title: '日期', key: 'auditDate', width: 120 },
{ title: '产出券', key: 'newTickets', width: 90 },
{ title: '回收券', key: 'burnTickets', width: 90 },
{ title: '净增', key: 'netTickets', width: 90 },
{ title: '种植产出', key: 'plantOutput', width: 100 },
{ title: '地标回收', key: 'landmarkBurn', width: 100 },
{ title: '升级回收', key: 'upgradeBurn', width: 100 },
{ title: '活跃持券用户', key: 'activeUserCount', width: 120 },
{ title: '预警', width: 80, render: (h, p) => h('Tag', { props: { color: p.row.warning === 1 ? 'red' : 'green' } }, p.row.warning === 1 ? '净增' : '平衡') }
]
}
},
mounted() {
@ -436,11 +671,25 @@
huntResultText(r) {
return { success: '缴获成功', shield: '对方防护', fail: '扑空' }[r] || r
},
enabledTag(h, enabled) {
return h('Tag', { props: { color: enabled === 1 ? 'green' : 'default' } }, enabled === 1 ? '是' : '否')
},
operateActionColumn(type) {
return {
title: '操作', width: 150, align: 'center', render: (h, params) => h('div', [
h('Button', { props: { type: 'text', size: 'small' }, on: { click: () => this.openOperate(type, params.row) } }, '编辑'),
h('Button', { props: { type: 'text', size: 'small' }, style: { color: '#ed4014' }, on: { click: () => this.delOperate(type, params.row) } }, '删除')
])
}
},
onTabChange(name) {
const map = {
pool: this.loadPool, task: this.loadTask, buff: this.loadBuff,
news: this.loadNews, rank: this.loadRank, hunt: this.loadHunt,
draw: this.loadDraw, winner: this.loadWinner
draw: this.loadDraw, winner: this.loadWinner,
tree: this.loadTree, warehouse: this.loadWarehouse, tower: this.loadTower,
search: this.loadSearch, stamina: this.loadStamina, landmark: this.loadLandmark,
economy: this.loadEconomy
}
map[name] && map[name]()
},
@ -494,6 +743,13 @@
loadHunt() { if (!this.guardRegion('hunt')) return; this.hunt.loading = true; planetHuntPage(this.baseParams('hunt')).then(r => this.fill('hunt', r)) },
loadDraw() { if (!this.guardRegion('draw')) return; this.draw.loading = true; planetDrawPage(this.baseParams('draw')).then(r => this.fill('draw', r)) },
loadWinner() { if (!this.guardRegion('winner')) return; this.winner.loading = true; planetWinnerPage(this.baseParams('winner')).then(r => this.fill('winner', r)) },
loadTree() { if (!this.guardRegion('tree')) return; this.tree.loading = true; planetTreePage(this.baseParams('tree')).then(r => this.fill('tree', r)) },
loadWarehouse() { if (!this.guardRegion('warehouse')) return; this.warehouse.loading = true; planetWarehousePage(this.baseParams('warehouse')).then(r => this.fill('warehouse', r)) },
loadTower() { if (!this.guardRegion('tower')) return; this.tower.loading = true; planetTowerPage(this.baseParams('tower')).then(r => this.fill('tower', r)) },
loadSearch() { if (!this.guardRegion('search')) return; this.search.loading = true; planetSearchPage(this.baseParams('search')).then(r => this.fill('search', r)) },
loadStamina() { if (!this.guardRegion('stamina')) return; this.stamina.loading = true; planetStaminaPage(this.baseParams('stamina')).then(r => this.fill('stamina', r)) },
loadLandmark() { if (!this.guardRegion('landmark')) return; this.landmark.loading = true; planetLandmarkPage(this.baseParams('landmark')).then(r => this.fill('landmark', r)) },
loadEconomy() { if (!this.guardRegion('economy')) return; this.economy.loading = true; planetEconomyPage(this.baseParams('economy')).then(r => this.fill('economy', r)) },
// ---- ----
openPool(row) {
this.poolForm = row ? Object.assign({}, row) : { regionId: this.regionId || '', poolAmount: 88.88, status: 0 }
@ -602,6 +858,42 @@
delNews(row) {
planetNewsDelete(row.id).then(() => { this.$Message.success('删除成功'); this.loadNews() })
},
operateApis(type) {
return {
tree: { save: planetTreeSave, del: planetTreeDelete, load: this.loadTree, defaults: { cycleHours: 8, rate: 0.05, minInvest: 1, maxInvest: 50, maxProfit: 5, dailyProfitLimit: 10, sort: 0, enabled: 1 } },
warehouse: { save: planetWarehouseSave, del: planetWarehouseDelete, load: this.loadWarehouse, defaults: { level: 1, capacity: 10, upgradeCost: 10, enabled: 1 } },
tower: { save: planetTowerSave, del: planetTowerDelete, load: this.loadTower, defaults: { level: 1, interceptRate: 5, damage: 5, counterRate: 2, upgradeCost: 10, enabled: 1 } },
search: { save: planetSearchSave, del: planetSearchDelete, load: this.loadSearch, defaults: { dailyLimit: 3, staminaCost: 30, minGain: 1, maxGain: 3, targetBalanceRate: 0.1, dailyGainLimit: 8, targetProtectMinutes: 30, enabled: 1 } },
stamina: { save: planetStaminaSave, del: planetStaminaDelete, load: this.loadStamina, defaults: { name: '松果能量', recoverStamina: 30, costTickets: 2, dailyBuyLimit: 2, sort: 0, enabled: 1 } },
landmark: { save: planetLandmarkSave, del: planetLandmarkDelete, load: this.loadLandmark, defaults: { name: '图书馆', icon: 'LIB', benefitType: 'ticket', benefitValue: 5, dailyOutputLimit: 5, openStartTime: '08:00', openEndTime: '22:00', settleTime: '22:00', sort: 0, enabled: 1 } }
}[type]
},
openOperate(type, row) {
const api = this.operateApis(type)
this.operateType = type
this.operateForm = row ? Object.assign({}, row) : Object.assign({ regionId: this.regionId || '' }, api.defaults)
this.operateModal = true
},
saveOperate() {
const api = this.operateApis(this.operateType)
api.save(this.operateForm).then(r => {
if (r && r.success) {
this.$Message.success('保存成功')
this.operateModal = false
api.load()
} else {
this.$Message.error((r && r.message) || '保存失败')
}
})
},
delOperate(type, row) {
const api = this.operateApis(type)
this.$Modal.confirm({
title: '确认删除',
content: '确认删除该经营配置?',
onOk: () => api.del(row.id).then(() => { this.$Message.success('删除成功'); api.load() })
})
},
fmt(d) {
const p = n => (n < 10 ? '0' + n : n)
return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`

Loading…
Cancel
Save