Files
workspace/code/fms/.tmp-panel.html
T
2026-09-08 17:03:59 +08:00

110 lines
6.9 KiB
HTML

<!-- 中:权限面板 -->
<div class="min-w-0 space-y-4">
<!-- 全部模块概览 -->
<div v-if="state.selected === '__all'" class="overflow-hidden rounded-xl border border-slate-200 bg-white">
<div class="border-b border-slate-100 px-5 py-3.5">
<h2 class="text-[14px] font-semibold text-slate-800">全部模块概览</h2>
<p class="mt-0.5 text-[11px] text-slate-400">{{ curUser.name }} · 点模块名进入详细配置</p>
</div>
<table class="w-full">
<thead>
<tr class="border-b border-slate-100 bg-slate-50/70 text-[11px] text-slate-500">
<th class="px-5 py-2.5 text-left font-medium">模块</th>
<th class="w-14 px-3 py-2.5 text-center font-medium">入口</th>
<th class="px-3 py-2.5 text-left font-medium">已授权动作</th>
<th class="w-[130px] px-3 py-2.5 text-left font-medium">数据范围</th>
</tr>
</thead>
<tbody>
<tr v-for="m in flatModules" :key="m.id" class="cursor-pointer border-b border-slate-50 last:border-0 hover:bg-slate-50/60" @click="state.selected = m.id">
<td class="px-5 py-2.5">
<div class="text-slate-700">{{ m.name }}</div>
<div class="mono text-[11px] text-slate-400">{{ m.id }}</div>
</td>
<td class="px-3 py-2.5 text-center" @click.stop>
<sw :on="hasEntry(m.id)" @toggle="toggleEntry(m.id)"></sw>
</td>
<td class="px-3 py-2.5">
<span v-if="!moduleActions(m.id).length" class="text-[11px] text-slate-300">未授权(默认拒绝)</span>
<span v-else class="flex flex-wrap gap-1">
<span v-for="a in moduleActions(m.id)" :key="a" class="rounded bg-teal-50 px-1.5 py-0.5 text-[10px] text-teal-700">{{ a }}</span>
</span>
</td>
<td class="px-3 py-2.5">
<span class="text-[12px]" :class="scopeOf(m.id) === 'all' ? 'text-slate-300' : 'text-teal-700'">{{ scopeName(scopeOf(m.id)) }}</span>
</td>
</tr>
</tbody>
</table>
</div>
<!-- 单模块配置 -->
<div v-else class="rounded-xl border border-slate-200 bg-white">
<div class="flex items-center gap-3 border-b border-slate-100 px-5 py-3.5">
<div>
<h2 class="text-[14px] font-semibold text-slate-800">{{ selName }}</h2>
<p class="mono mt-0.5 text-[11px] text-slate-400">{{ state.selected }}</p>
</div>
<span v-if="selIsPage" class="rounded bg-indigo-50 px-2 py-0.5 text-[11px] text-indigo-600">page 节点</span>
<span class="ml-auto text-[11px] text-slate-400">{{ curUser.name }} · 全部默认拒绝,勾选即授权</span>
</div>
<!-- 入口 -->
<div class="flex items-center gap-3 border-b border-slate-100 px-5 py-3">
<div class="w-16 shrink-0 text-[13px] text-slate-600">入口</div>
<sw :on="hasEntry(state.selected)" @toggle="toggleEntry(state.selected)"></sw>
<span class="text-[12px] text-slate-500">{{ hasEntry(state.selected) ? '已开通' : '未开通' }}</span>
<span class="mono text-[11px] text-slate-400">{{ entryCode }}</span>
</div>
<!-- 动作 -->
<div v-if="!selIsPage" class="flex items-start gap-3 border-b border-slate-100 px-5 py-3">
<div class="w-16 shrink-0 pt-1 text-[13px] text-slate-600">动作</div>
<div class="flex flex-1 flex-wrap gap-1.5">
<button v-for="a in selActions" :key="a.k"
class="rounded-md border px-2.5 py-1 text-[12px] transition"
:class="hasAction(state.selected, a.k) ? 'border-teal-200 bg-teal-50 text-teal-700' : 'border-slate-200 bg-white text-slate-400 hover:bg-slate-50'"
@click="toggleAction(state.selected, a.k)">{{ a.n }}</button>
</div>
</div>
<div v-else class="border-b border-slate-100 px-5 py-3 text-[11px] text-slate-400">页面节点只配入口,具体操作在下属模块上配置</div>
<!-- 数据范围 -->
<div v-if="!selIsPage" class="flex items-center gap-3 border-b border-slate-100 px-5 py-3">
<div class="w-16 shrink-0 text-[13px] text-slate-600">数据范围</div>
<select :value="scopeOf(state.selected)" @change="setScope(state.selected, $event.target.value)"
class="h-8 w-56 rounded-md border border-slate-200 bg-white px-2 text-[12px] outline-none focus:border-teal-500">
<option v-for="s in SCOPES" :key="s.v" :value="s.v">{{ s.n }}</option>
</select>
<span class="text-[11px] text-slate-400">未配置视为全部数据</span>
</div>
<!-- 敏感字段 -->
<div v-if="!selIsPage" class="flex items-start gap-3 px-5 py-3">
<div class="w-16 shrink-0 pt-1 text-[13px] text-slate-600">敏感字段</div>
<div class="flex-1">
<div v-if="!selFields.length" class="text-[11px] text-slate-400">该模块没有标记敏感字段,无需配置字段权限</div>
<div v-else class="space-y-1.5">
<div v-for="f in selFields" :key="f.n" class="flex items-center gap-3 rounded-md bg-slate-50 px-3 py-1.5">
<span class="w-36 shrink-0 text-slate-700">{{ f.l }}<span class="mono ml-1 text-[10px] text-slate-400">{{ f.n }}</span></span>
<select :value="fieldMode(state.selected, f.n)" @change="setField(state.selected, f.n, $event.target.value)"
class="h-7 w-32 rounded-md border border-slate-200 bg-white px-1.5 text-[12px] outline-none focus:border-teal-500">
<option value="default">跟随默认(可编辑)</option>
<option value="hidden">hidden · 隐藏</option>
<option value="view">view · 只读</option>
</select>
<label class="flex items-center gap-1 text-[11px] text-slate-500">
<input type="checkbox" class="h-3.5 w-3.5 accent-teal-600" :disabled="fieldMode(state.selected, f.n) === 'hidden'" :checked="fieldQuery(state.selected, f.n)" @change="setFieldFlag(state.selected, f.n, 'query', $event.target.checked)">可查询
</label>
<label class="flex items-center gap-1 text-[11px] text-slate-500">
<input type="checkbox" class="h-3.5 w-3.5 accent-teal-600" :disabled="fieldMode(state.selected, f.n) === 'hidden'" :checked="fieldExport(state.selected, f.n)" @change="setFieldFlag(state.selected, f.n, 'export', $event.target.checked)">可导出
</label>
<span v-if="fieldMode(state.selected, f.n) !== 'default'" class="ml-auto rounded bg-amber-50 px-1.5 py-0.5 text-[10px] text-amber-700">已收紧</span>
<span v-else class="ml-auto text-[10px] text-slate-300">默认</span>
</div>
</div>
</div>
</div>
</div>