|
|
@@ -0,0 +1,439 @@
|
|
|
+<template>
|
|
|
+ <div class="cf-rule-config admin-page">
|
|
|
+ <PageHeader title="CF 规则/档位配置" subtitle="CF 值发放规则(cf_earn_rule)与销售奖档位(cf_rate_tier)">
|
|
|
+ <el-button size="small" icon="el-icon-refresh" @click="refreshAll">刷新</el-button>
|
|
|
+ </PageHeader>
|
|
|
+
|
|
|
+ <el-tabs v-model="activeTab">
|
|
|
+ <!-- ==================== 发放规则 ==================== -->
|
|
|
+ <el-tab-pane label="发放规则" name="rules">
|
|
|
+ <div class="filters">
|
|
|
+ <el-select v-model="ruleQuery.category" placeholder="分类" clearable size="small" class="filter-input-160" @change="loadRules">
|
|
|
+ <el-option label="消费返佣" value="consume" />
|
|
|
+ <el-option label="成长行为" value="behavior" />
|
|
|
+ <el-option label="管理员" value="admin" />
|
|
|
+ </el-select>
|
|
|
+ <el-select v-model="ruleQuery.enabled" placeholder="状态" clearable size="small" class="filter-input-120" @change="loadRules">
|
|
|
+ <el-option label="启用" :value="1" />
|
|
|
+ <el-option label="停用" :value="0" />
|
|
|
+ </el-select>
|
|
|
+ <el-button type="primary" size="small" @click="loadRules">查询</el-button>
|
|
|
+ <el-button type="success" size="small" @click="openRuleDialog()">新建规则</el-button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="adm-table-wrap">
|
|
|
+ <el-table :data="ruleList" v-loading="ruleLoading" border stripe height="100%">
|
|
|
+ <el-table-column prop="code" label="编码" width="90">
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ <span class="rule-code">{{ row.code }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="name" label="途径名称" min-width="150" show-overflow-tooltip />
|
|
|
+ <el-table-column label="分类" width="90">
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ <StatusTag :type="categoryType(row.category)" :text="categoryLabel(row.category)" size="small" />
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="类型" width="90">
|
|
|
+ <template slot-scope="{ row }">{{ ruleTypeLabel(row.ruleType) }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="数量/公式" min-width="140" show-overflow-tooltip>
|
|
|
+ <template slot-scope="{ row }">{{ amountText(row) }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="日限/累计/冷却" width="130">
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ <span class="limit-text">{{ row.dailyLimitPerMember || '∞' }}/{{ row.totalLimitPerMember || '∞' }}/{{ cooldownText(row.cooldownSeconds) }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="生效期" width="180">
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ <span v-if="row.effectiveFrom || row.effectiveTo" class="limit-text">
|
|
|
+ {{ dateText(row.effectiveFrom) }} ~ {{ dateText(row.effectiveTo) }}
|
|
|
+ </span>
|
|
|
+ <span v-else>-</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="状态" width="80">
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ <el-switch :value="row.enabled === 1" @change="v => onToggleRule(row, v)" active-color="var(--adm-success)" inactive-color="var(--adm-border-base)" />
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="sortOrder" label="排序" width="70" />
|
|
|
+ <el-table-column label="操作" width="160" fixed="right">
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ <el-button size="mini" type="primary" @click="openRuleDialog(row)">编辑</el-button>
|
|
|
+ <el-button size="mini" @click="openHistory(row)">历史</el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+ </el-tab-pane>
|
|
|
+
|
|
|
+ <!-- ==================== 销售奖档位 ==================== -->
|
|
|
+ <el-tab-pane label="销售奖档位" name="tiers">
|
|
|
+ <div class="filters">
|
|
|
+ <el-button type="success" size="small" @click="openTierDialog()">新建档位</el-button>
|
|
|
+ <el-button size="small" @click="loadTiers">刷新</el-button>
|
|
|
+ </div>
|
|
|
+ <el-alert
|
|
|
+ type="info"
|
|
|
+ :closable="false"
|
|
|
+ show-icon
|
|
|
+ class="tier-tip"
|
|
|
+ title="cf_rate_tier 为历史「团队规模阶梯」档位表(F-4 后仅作等级展示/历史查询);F03a/F03b 两级销售奖实际档位在 cf_direct_sales_tier / cf_indirect_sales_tier(管理端暂未开放配置,见待补项)。"
|
|
|
+ />
|
|
|
+ <div class="adm-table-wrap" style="margin-top: 12px;">
|
|
|
+ <el-table :data="tierList" v-loading="tierLoading" border stripe height="100%">
|
|
|
+ <el-table-column prop="id" label="ID" width="80" />
|
|
|
+ <el-table-column prop="tierName" label="档位名" min-width="140" />
|
|
|
+ <el-table-column prop="minTeamSize" label="团队规模下限" width="130" />
|
|
|
+ <el-table-column prop="ratePercent" label="返佣比例%" width="100" />
|
|
|
+ <el-table-column prop="sortOrder" label="排序" width="80" />
|
|
|
+ <el-table-column label="状态" width="80">
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ <StatusTag :type="row.enabled === 1 ? 'success' : 'info'" :text="row.enabled === 1 ? '启用' : '停用'" size="small" />
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="操作" width="150" fixed="right">
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ <el-button size="mini" type="primary" @click="openTierDialog(row)">编辑</el-button>
|
|
|
+ <el-button size="mini" type="danger" @click="onDeleteTier(row)">删除</el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+ </el-tab-pane>
|
|
|
+ </el-tabs>
|
|
|
+
|
|
|
+ <!-- ==================== 规则编辑弹窗 ==================== -->
|
|
|
+ <el-dialog :visible.sync="ruleDialogVisible" :title="ruleForm.id ? '编辑发放规则' : '新建发放规则'" width="640px" @closed="ruleForm = {}">
|
|
|
+ <el-form :model="ruleForm" label-width="130px" size="small">
|
|
|
+ <el-row :gutter="12">
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="规则编码" required>
|
|
|
+ <el-input v-model="ruleForm.code" :disabled="!!ruleForm.id" placeholder="如 F07" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="途径名称" required>
|
|
|
+ <el-input v-model="ruleForm.name" placeholder="发放途径名称" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="分类">
|
|
|
+ <el-select v-model="ruleForm.category" placeholder="分类" style="width: 100%">
|
|
|
+ <el-option label="消费返佣" value="consume" />
|
|
|
+ <el-option label="成长行为" value="behavior" />
|
|
|
+ <el-option label="管理员" value="admin" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="规则类型">
|
|
|
+ <el-select v-model="ruleForm.ruleType" placeholder="类型" style="width: 100%">
|
|
|
+ <el-option label="固定数量" value="fixed" />
|
|
|
+ <el-option label="公式" value="formula" />
|
|
|
+ <el-option label="逐人发放" value="per_item" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="固定数量">
|
|
|
+ <el-input-number v-model="ruleForm.amount" :min="0" style="width: 100%" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="计算公式">
|
|
|
+ <el-input v-model="ruleForm.formula" placeholder="rule_type=formula 时填写" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="日限/成员">
|
|
|
+ <el-input-number v-model="ruleForm.dailyLimitPerMember" :min="0" style="width: 100%" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="累计上限/成员">
|
|
|
+ <el-input-number v-model="ruleForm.totalLimitPerMember" :min="0" style="width: 100%" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="冷却秒数">
|
|
|
+ <el-input-number v-model="ruleForm.cooldownSeconds" :min="0" style="width: 100%" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="幂等 refType">
|
|
|
+ <el-input v-model="ruleForm.dedupRefType" placeholder="写入 cf_balance_log" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="排序">
|
|
|
+ <el-input-number v-model="ruleForm.sortOrder" :min="0" style="width: 100%" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-form-item label="启用">
|
|
|
+ <el-switch v-model="ruleForm.enabled" :active-value="1" :inactive-value="0" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="参数 JSON">
|
|
|
+ <el-input v-model="ruleForm.paramsJson" type="textarea" :rows="3" placeholder='{"bps": 50, "max_rate_percent": 70}' />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="备注">
|
|
|
+ <el-input v-model="ruleForm.remark" type="textarea" :rows="2" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="变更原因">
|
|
|
+ <el-input v-model="ruleForm.changeReason" type="textarea" :rows="2" placeholder="留痕到 cf_earn_rule_history" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-alert
|
|
|
+ v-if="ruleForm.id"
|
|
|
+ type="warning"
|
|
|
+ :closable="false"
|
|
|
+ show-icon
|
|
|
+ title="待补项:后端 save 接口未开放 effectiveFrom/effectiveTo 参数,编辑保存会把「生效期」重置为不限(长期生效);如需保留生效期,请先确认规则当前无生效期限制。"
|
|
|
+ />
|
|
|
+ </el-form>
|
|
|
+ <div slot="footer">
|
|
|
+ <el-button size="small" @click="ruleDialogVisible = false">取消</el-button>
|
|
|
+ <el-button size="small" type="primary" :loading="ruleSaving" @click="saveRule">保存</el-button>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
+ <!-- ==================== 档位编辑弹窗 ==================== -->
|
|
|
+ <el-dialog :visible.sync="tierDialogVisible" :title="tierForm.id ? '编辑档位' : '新建档位'" width="480px" @closed="tierForm = {}">
|
|
|
+ <el-form :model="tierForm" label-width="130px" size="small">
|
|
|
+ <el-form-item label="档位名" required>
|
|
|
+ <el-input v-model="tierForm.tierName" placeholder="如 青铜/白银/黄金" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="团队规模下限">
|
|
|
+ <el-input-number v-model="tierForm.minTeamSize" :min="0" style="width: 100%" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="返佣比例%">
|
|
|
+ <el-input-number v-model="tierForm.ratePercent" :min="0" :max="100" style="width: 100%" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="排序">
|
|
|
+ <el-input-number v-model="tierForm.sortOrder" :min="0" style="width: 100%" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="启用">
|
|
|
+ <el-switch v-model="tierForm.enabled" :active-value="1" :inactive-value="0" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <div slot="footer">
|
|
|
+ <el-button size="small" @click="tierDialogVisible = false">取消</el-button>
|
|
|
+ <el-button size="small" type="primary" :loading="tierSaving" @click="saveTier">保存</el-button>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
+ <!-- ==================== 规则历史弹窗 ==================== -->
|
|
|
+ <el-dialog :visible.sync="historyVisible" :title="'规则历史:' + historyCode" width="720px">
|
|
|
+ <el-table :data="historyList" v-loading="historyLoading" border stripe max-height="480">
|
|
|
+ <el-table-column prop="id" label="ID" width="80" />
|
|
|
+ <el-table-column prop="changeReason" label="变更原因" min-width="160" show-overflow-tooltip />
|
|
|
+ <el-table-column label="操作人" width="100">
|
|
|
+ <template slot-scope="{ row }">{{ row.changedBy || '-' }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="时间" width="160">
|
|
|
+ <template slot-scope="{ row }">{{ formatTime(row.createdAt) }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="变更" width="110">
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ <el-tooltip :content="historyDiff(row)" placement="top">
|
|
|
+ <el-button size="mini" type="text">查看差异</el-button>
|
|
|
+ </el-tooltip>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { getCfEarnRuleList, saveCfEarnRule, toggleCfEarnRule, getCfEarnRuleHistory, getCfRateTierList, saveCfRateTier, deleteCfRateTier } from '@/api/cfRule'
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: 'CfRuleConfig',
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ activeTab: 'rules',
|
|
|
+ // ---- rules ----
|
|
|
+ ruleList: [],
|
|
|
+ ruleLoading: false,
|
|
|
+ ruleSaving: false,
|
|
|
+ ruleQuery: { category: '', enabled: null },
|
|
|
+ ruleDialogVisible: false,
|
|
|
+ ruleForm: {},
|
|
|
+ // ---- history ----
|
|
|
+ historyVisible: false,
|
|
|
+ historyCode: '',
|
|
|
+ historyList: [],
|
|
|
+ historyLoading: false,
|
|
|
+ // ---- tiers ----
|
|
|
+ tierList: [],
|
|
|
+ tierLoading: false,
|
|
|
+ tierSaving: false,
|
|
|
+ tierDialogVisible: false,
|
|
|
+ tierForm: {}
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.loadRules()
|
|
|
+ this.loadTiers()
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ refreshAll() {
|
|
|
+ this.loadRules()
|
|
|
+ this.loadTiers()
|
|
|
+ },
|
|
|
+ // ============ 发放规则 ============
|
|
|
+ loadRules() {
|
|
|
+ this.ruleLoading = true
|
|
|
+ getCfEarnRuleList({ category: this.ruleQuery.category || undefined, enabled: this.ruleQuery.enabled === '' ? undefined : this.ruleQuery.enabled })
|
|
|
+ .then(res => {
|
|
|
+ this.ruleList = res.data || []
|
|
|
+ })
|
|
|
+ .catch(() => {})
|
|
|
+ .finally(() => { this.ruleLoading = false })
|
|
|
+ },
|
|
|
+ openRuleDialog(row) {
|
|
|
+ if (row) {
|
|
|
+ this.ruleForm = Object.assign({}, row, { enabled: row.enabled === 1 ? 1 : 0, changeReason: '' })
|
|
|
+ } else {
|
|
|
+ this.ruleForm = { enabled: 1, ruleType: 'fixed', sortOrder: 0, changeReason: '' }
|
|
|
+ }
|
|
|
+ this.ruleDialogVisible = true
|
|
|
+ },
|
|
|
+ saveRule() {
|
|
|
+ if (!this.ruleForm.code || !this.ruleForm.name) {
|
|
|
+ this.$message.warning('编码和名称必填')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.ruleSaving = true
|
|
|
+ const adminId = Number(localStorage.getItem('adminId')) || null
|
|
|
+ const payload = Object.assign({}, this.ruleForm, { changedBy: adminId })
|
|
|
+ saveCfEarnRule(payload)
|
|
|
+ .then(() => {
|
|
|
+ this.$message.success('保存成功')
|
|
|
+ this.ruleDialogVisible = false
|
|
|
+ this.loadRules()
|
|
|
+ })
|
|
|
+ .catch(() => {})
|
|
|
+ .finally(() => { this.ruleSaving = false })
|
|
|
+ },
|
|
|
+ onToggleRule(row, val) {
|
|
|
+ const adminId = Number(localStorage.getItem('adminId')) || null
|
|
|
+ toggleCfEarnRule({ code: row.code, enabled: val ? 1 : 0, changedBy: adminId, changeReason: '管理端启停:' + (val ? '启用' : '停用') })
|
|
|
+ .then(() => {
|
|
|
+ this.$message.success(val ? '已启用' : '已停用')
|
|
|
+ this.loadRules()
|
|
|
+ })
|
|
|
+ .catch(() => {})
|
|
|
+ },
|
|
|
+ openHistory(row) {
|
|
|
+ this.historyCode = row.code
|
|
|
+ this.historyVisible = true
|
|
|
+ this.historyLoading = true
|
|
|
+ getCfEarnRuleHistory({ code: row.code, limit: 50 })
|
|
|
+ .then(res => { this.historyList = res.data || [] })
|
|
|
+ .catch(() => { this.historyList = [] })
|
|
|
+ .finally(() => { this.historyLoading = false })
|
|
|
+ },
|
|
|
+ historyDiff(row) {
|
|
|
+ try {
|
|
|
+ const oldJ = JSON.parse(row.oldJson || '{}')
|
|
|
+ const newJ = JSON.parse(row.newJson || '{}')
|
|
|
+ return 'enabled: ' + (oldJ.enabled == null ? '-' : oldJ.enabled) + '→' + (newJ.enabled == null ? '-' : newJ.enabled)
|
|
|
+ + ';amount: ' + (oldJ.amount == null ? '-' : oldJ.amount) + '→' + (newJ.amount == null ? '-' : newJ.amount)
|
|
|
+ + ';formula: ' + (oldJ.formula || '-') + '→' + (newJ.formula || '-')
|
|
|
+ } catch (e) {
|
|
|
+ return 'JSON 快照'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // ============ 档位 ============
|
|
|
+ loadTiers() {
|
|
|
+ this.tierLoading = true
|
|
|
+ getCfRateTierList()
|
|
|
+ .then(res => { this.tierList = res.data || [] })
|
|
|
+ .catch(() => {})
|
|
|
+ .finally(() => { this.tierLoading = false })
|
|
|
+ },
|
|
|
+ openTierDialog(row) {
|
|
|
+ if (row) {
|
|
|
+ this.tierForm = Object.assign({}, row)
|
|
|
+ } else {
|
|
|
+ this.tierForm = { enabled: 1, minTeamSize: 0, ratePercent: 0, sortOrder: 0 }
|
|
|
+ }
|
|
|
+ this.tierDialogVisible = true
|
|
|
+ },
|
|
|
+ saveTier() {
|
|
|
+ if (!this.tierForm.tierName) {
|
|
|
+ this.$message.warning('档位名必填')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.tierSaving = true
|
|
|
+ saveCfRateTier(this.tierForm)
|
|
|
+ .then(() => {
|
|
|
+ this.$message.success('保存成功')
|
|
|
+ this.tierDialogVisible = false
|
|
|
+ this.loadTiers()
|
|
|
+ })
|
|
|
+ .catch(() => {})
|
|
|
+ .finally(() => { this.tierSaving = false })
|
|
|
+ },
|
|
|
+ onDeleteTier(row) {
|
|
|
+ this.$confirm('确认删除档位「' + row.tierName + '」?', '提示', { type: 'warning' })
|
|
|
+ .then(() => deleteCfRateTier({ id: row.id }))
|
|
|
+ .then(() => { this.$message.success('已删除'); this.loadTiers() })
|
|
|
+ .catch(() => {})
|
|
|
+ },
|
|
|
+ // ============ 展示工具 ============
|
|
|
+ categoryLabel(c) {
|
|
|
+ return { consume: '消费返佣', behavior: '成长行为', admin: '管理员' }[c] || c || '-'
|
|
|
+ },
|
|
|
+ categoryType(c) {
|
|
|
+ return { consume: 'warning', behavior: 'success', admin: 'info' }[c] || 'info'
|
|
|
+ },
|
|
|
+ ruleTypeLabel(t) {
|
|
|
+ return { fixed: '固定', formula: '公式', per_item: '逐人' }[t] || t || '-'
|
|
|
+ },
|
|
|
+ amountText(row) {
|
|
|
+ if (row.ruleType === 'formula') return row.formula || '-'
|
|
|
+ if (row.ruleType === 'per_item') return '逐人'
|
|
|
+ return row.amount != null ? row.amount + ' CF' : '-'
|
|
|
+ },
|
|
|
+ cooldownText(s) {
|
|
|
+ if (!s) return '∞'
|
|
|
+ if (s % 86400 === 0) return (s / 86400) + '天'
|
|
|
+ if (s % 3600 === 0) return (s / 3600) + '时'
|
|
|
+ return s + 's'
|
|
|
+ },
|
|
|
+ dateText(v) {
|
|
|
+ return v ? String(v).substring(0, 10) : '-'
|
|
|
+ },
|
|
|
+ formatTime(t) {
|
|
|
+ return t ? String(t).replace('T', ' ').substring(0, 19) : '-'
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.cf-rule-config { padding: 20px; }
|
|
|
+.filters {
|
|
|
+ display: flex;
|
|
|
+ gap: 8px;
|
|
|
+ margin-bottom: 12px;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+.filter-input-160 { width: 160px; }
|
|
|
+.filter-input-120 { width: 120px; }
|
|
|
+.rule-code {
|
|
|
+ font-family: monospace;
|
|
|
+ font-weight: 600;
|
|
|
+}
|
|
|
+.limit-text {
|
|
|
+ font-size: 12px;
|
|
|
+ color: #595959;
|
|
|
+}
|
|
|
+.tier-tip { margin-bottom: 0; }
|
|
|
+</style>
|