feat: add RBAC controls for outbound selection module
Co-authored-by: aider (openai/DeepSeek-V3.2-Thinking) <aider@aider.chat>
This commit is contained in:
@ -1,6 +1,7 @@
|
|||||||
from flask import Blueprint, request, jsonify
|
from flask import Blueprint, request, jsonify
|
||||||
from app.services.outbound_service import OutboundService
|
from app.services.outbound_service import OutboundService
|
||||||
from flask_jwt_extended import jwt_required, get_jwt_identity
|
from flask_jwt_extended import jwt_required, get_jwt_identity
|
||||||
|
from app.utils.decorators import permission_required
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
outbound_bp = Blueprint('outbound', __name__, url_prefix='/outbound')
|
outbound_bp = Blueprint('outbound', __name__, url_prefix='/outbound')
|
||||||
@ -12,6 +13,7 @@ outbound_bp = Blueprint('outbound', __name__, url_prefix='/outbound')
|
|||||||
# --------------------------------------------------------
|
# --------------------------------------------------------
|
||||||
@outbound_bp.route('/scan', methods=['GET'])
|
@outbound_bp.route('/scan', methods=['GET'])
|
||||||
@jwt_required()
|
@jwt_required()
|
||||||
|
@permission_required('outbound_selection')
|
||||||
def scan_barcode():
|
def scan_barcode():
|
||||||
barcode = request.args.get('barcode')
|
barcode = request.args.get('barcode')
|
||||||
if not barcode:
|
if not barcode:
|
||||||
@ -44,6 +46,7 @@ def scan_barcode():
|
|||||||
# --------------------------------------------------------
|
# --------------------------------------------------------
|
||||||
@outbound_bp.route('', methods=['POST'])
|
@outbound_bp.route('', methods=['POST'])
|
||||||
@jwt_required()
|
@jwt_required()
|
||||||
|
@permission_required('outbound_selection:operation')
|
||||||
def create_outbound():
|
def create_outbound():
|
||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
if not data:
|
if not data:
|
||||||
@ -89,6 +92,7 @@ def create_outbound():
|
|||||||
# --------------------------------------------------------
|
# --------------------------------------------------------
|
||||||
@outbound_bp.route('', methods=['GET'])
|
@outbound_bp.route('', methods=['GET'])
|
||||||
@jwt_required()
|
@jwt_required()
|
||||||
|
@permission_required('outbound_selection')
|
||||||
def get_outbound_list():
|
def get_outbound_list():
|
||||||
try:
|
try:
|
||||||
page = int(request.args.get('page', 1))
|
page = int(request.args.get('page', 1))
|
||||||
|
|||||||
@ -8,14 +8,14 @@
|
|||||||
<span class="subtitle">(请添加需要出库的物品)</span>
|
<span class="subtitle">(请添加需要出库的物品)</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<el-button type="primary" :icon="Plus" @click="openManualSelect">
|
<el-button v-if="userStore.hasPermission('outbound_selection:operation')" type="primary" :icon="Plus" @click="openManualSelect">
|
||||||
手动添加库存
|
手动添加库存
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button type="warning" :icon="List" @click="openBomSelect">
|
<el-button v-if="userStore.hasPermission('outbound_selection:operation')" type="warning" :icon="List" @click="openBomSelect">
|
||||||
按 BOM 套餐添加
|
按 BOM 套餐添加
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-divider direction="vertical" />
|
<el-divider direction="vertical" />
|
||||||
<el-button type="success" :icon="Printer" :disabled="selectedItems.length === 0" @click="handlePreview">
|
<el-button v-if="userStore.hasPermission('outbound_selection:operation')" type="success" :icon="Printer" :disabled="selectedItems.length === 0" @click="handlePreview">
|
||||||
生成预览 & 打印
|
生成预览 & 打印
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
@ -71,6 +71,7 @@
|
|||||||
size="small"
|
size="small"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
controls-position="right"
|
controls-position="right"
|
||||||
|
:disabled="!userStore.hasPermission('outbound_selection:operation')"
|
||||||
@change="(val) => handleMainQuantityChange(val, row)"
|
@change="(val) => handleMainQuantityChange(val, row)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
@ -78,7 +79,7 @@
|
|||||||
|
|
||||||
<el-table-column label="操作" width="80" align="center" fixed="right">
|
<el-table-column label="操作" width="80" align="center" fixed="right">
|
||||||
<template #default="{ $index }">
|
<template #default="{ $index }">
|
||||||
<el-button type="danger" link @click="removeRow($index)">移除</el-button>
|
<el-button v-if="userStore.hasPermission('outbound_selection:operation')" type="danger" link @click="removeRow($index)">移除</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@ -133,6 +134,7 @@
|
|||||||
size="small"
|
size="small"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
placeholder="0"
|
placeholder="0"
|
||||||
|
:disabled="!userStore.hasPermission('outbound_selection:operation')"
|
||||||
@click.stop
|
@click.stop
|
||||||
@change="(val) => handleManualQuantityChange(val, row)"
|
@change="(val) => handleManualQuantityChange(val, row)"
|
||||||
/>
|
/>
|
||||||
@ -144,7 +146,7 @@
|
|||||||
已勾选 {{ tempSelection.length }} 项
|
已勾选 {{ tempSelection.length }} 项
|
||||||
</span>
|
</span>
|
||||||
<el-button @click="manualDialogVisible = false">取消</el-button>
|
<el-button @click="manualDialogVisible = false">取消</el-button>
|
||||||
<el-button type="primary" @click="confirmManualAdd">确认添加</el-button>
|
<el-button v-if="userStore.hasPermission('outbound_selection:operation')" type="primary" @click="confirmManualAdd">确认添加</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
@ -161,7 +163,7 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="生产套数">
|
<el-form-item label="生产套数">
|
||||||
<el-input-number v-model="bomSets" :min="1" label="套" style="width: 200px;" />
|
<el-input-number v-model="bomSets" :min="1" label="套" style="width: 200px;" :disabled="!userStore.hasPermission('outbound_selection:operation')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div style="margin-left: 100px; color: #909399; font-size: 12px;">
|
<div style="margin-left: 100px; color: #909399; font-size: 12px;">
|
||||||
@ -169,7 +171,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<el-button @click="bomSelectVisible = false">取消</el-button>
|
<el-button @click="bomSelectVisible = false">取消</el-button>
|
||||||
<el-button type="primary" @click="confirmBomAdd">一键计算并添加</el-button>
|
<el-button v-if="userStore.hasPermission('outbound_selection:operation')" type="primary" @click="confirmBomAdd">一键计算并添加</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
@ -204,11 +206,11 @@
|
|||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button @click="previewVisible = false">取消</el-button>
|
<el-button @click="previewVisible = false">取消</el-button>
|
||||||
|
|
||||||
<el-button type="warning" :icon="Download" :loading="exportLoading" @click="confirmExport">
|
<el-button v-if="userStore.hasPermission('outbound_selection:operation')" type="warning" :icon="Download" :loading="exportLoading" @click="confirmExport">
|
||||||
导出 Excel
|
导出 Excel
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
<el-button type="primary" :icon="Printer" :loading="printLoading" @click="confirmPrint">
|
<el-button v-if="userStore.hasPermission('outbound_selection:operation')" type="primary" :icon="Printer" :loading="printLoading" @click="confirmPrint">
|
||||||
确认打印 (A4)
|
确认打印 (A4)
|
||||||
</el-button>
|
</el-button>
|
||||||
</span>
|
</span>
|
||||||
@ -283,6 +285,9 @@ import { Printer, Search, Plus, Download, List } from '@element-plus/icons-vue'
|
|||||||
import { ElMessage, ElTable, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElTable, ElMessageBox } from 'element-plus'
|
||||||
import { getAllStock, printSelectionList } from '@/api/inbound/stock'
|
import { getAllStock, printSelectionList } from '@/api/inbound/stock'
|
||||||
import { getBomList, getBomDetail } from '@/api/bom'
|
import { getBomList, getBomDetail } from '@/api/bom'
|
||||||
|
import { useUserStore } from '@/stores/user'
|
||||||
|
|
||||||
|
const userStore = useUserStore()
|
||||||
|
|
||||||
// --- 状态变量 ---
|
// --- 状态变量 ---
|
||||||
const selectedItems = ref<any[]>([])
|
const selectedItems = ref<any[]>([])
|
||||||
|
|||||||
Reference in New Issue
Block a user