|
@@ -2,10 +2,10 @@
|
|
|
<div class="app-container">
|
|
<div class="app-container">
|
|
|
<el-card shadow="never" class="mb16 filter-card">
|
|
<el-card shadow="never" class="mb16 filter-card">
|
|
|
<el-form :model="queryParams" ref="queryForm" :inline="true" size="small">
|
|
<el-form :model="queryParams" ref="queryForm" :inline="true" size="small">
|
|
|
- <el-form-item label="租户" prop="companyId">
|
|
|
|
|
- <el-select v-model="queryParams.companyId" placeholder="选择租户" clearable filterable remote
|
|
|
|
|
- reserve-keyword :remote-method="searchCompanies" :loading="companySearchLoading" style="width:200px">
|
|
|
|
|
- <el-option v-for="c in companyOptions" :key="c.companyId" :label="c.companyName" :value="c.companyId" />
|
|
|
|
|
|
|
+ <el-form-item label="租户" prop="tenantId">
|
|
|
|
|
+ <el-select v-model="queryParams.tenantId" placeholder="选择租户" clearable filterable remote
|
|
|
|
|
+ reserve-keyword :remote-method="searchTenants" :loading="tenantSearchLoading" style="width:200px">
|
|
|
|
|
+ <el-option v-for="c in tenantOptions" :key="c.tenantId" :label="c.tenantName" :value="c.tenantId" />
|
|
|
</el-select>
|
|
</el-select>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
<el-form-item label="接口" prop="apiId">
|
|
<el-form-item label="接口" prop="apiId">
|
|
@@ -30,56 +30,84 @@
|
|
|
<el-col :span="1.5">
|
|
<el-col :span="1.5">
|
|
|
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增绑定</el-button>
|
|
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增绑定</el-button>
|
|
|
</el-col>
|
|
</el-col>
|
|
|
|
|
+ <el-col :span="1.5">
|
|
|
|
|
+ <el-button type="success" plain icon="el-icon-edit-outline" size="mini" :disabled="!selectedRows.length" @click="handleBatchPricing">批量定价</el-button>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :span="1.5">
|
|
|
|
|
+ <el-button type="warning" plain icon="el-icon-open" size="mini" :disabled="!selectedRows.length" @click="handleBatchStatus(1)">批量启用</el-button>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :span="1.5">
|
|
|
|
|
+ <el-button type="info" plain icon="el-icon-turn-off" size="mini" :disabled="!selectedRows.length" @click="handleBatchStatus(0)">批量禁用</el-button>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :span="1.5" v-if="selectedRows.length">
|
|
|
|
|
+ <span class="selected-tip">已选 {{ selectedRows.length }} 条</span>
|
|
|
|
|
+ </el-col>
|
|
|
</el-row>
|
|
</el-row>
|
|
|
|
|
|
|
|
- <el-table v-loading="loading" :data="dataList" border size="small" style="width:100%">
|
|
|
|
|
- <el-table-column label="租户" align="center" prop="companyName" min-width="120" show-overflow-tooltip />
|
|
|
|
|
- <el-table-column label="接口名称" align="center" prop="apiName" min-width="120" show-overflow-tooltip />
|
|
|
|
|
- <el-table-column label="服务商" align="center" prop="provider" min-width="80">
|
|
|
|
|
|
|
+ <el-table
|
|
|
|
|
+ v-loading="loading"
|
|
|
|
|
+ :data="dataList"
|
|
|
|
|
+ border
|
|
|
|
|
+ size="small"
|
|
|
|
|
+ style="width:100%"
|
|
|
|
|
+ class="voice-api-tenant-table"
|
|
|
|
|
+ @selection-change="handleSelectionChange"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-table-column type="selection" width="45" align="center" />
|
|
|
|
|
+ <el-table-column label="租户" align="center" prop="tenantName" min-width="100" show-overflow-tooltip />
|
|
|
|
|
+ <el-table-column label="接口名称" align="center" prop="apiName" min-width="100" show-overflow-tooltip />
|
|
|
|
|
+ <el-table-column label="服务商" align="center" prop="provider" min-width="76">
|
|
|
<template slot-scope="scope">
|
|
<template slot-scope="scope">
|
|
|
<el-tag v-if="scope.row.provider === 'card'" type="warning" size="mini">手机卡</el-tag>
|
|
<el-tag v-if="scope.row.provider === 'card'" type="warning" size="mini">手机卡</el-tag>
|
|
|
<el-tag v-else type="primary" size="mini">平台</el-tag>
|
|
<el-tag v-else type="primary" size="mini">平台</el-tag>
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
- <el-table-column label="接口类型" align="center" prop="apiType" min-width="70">
|
|
|
|
|
|
|
+ <el-table-column label="类型" align="center" prop="apiType" width="58">
|
|
|
<template slot-scope="scope">
|
|
<template slot-scope="scope">
|
|
|
<span>{{ apiTypeMap[scope.row.apiType] || scope.row.apiType }}</span>
|
|
<span>{{ apiTypeMap[scope.row.apiType] || scope.row.apiType }}</span>
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
- <el-table-column label="成本价" align="center" prop="costPrice" min-width="90">
|
|
|
|
|
|
|
+ <el-table-column label="成本价" align="center" prop="costPrice" min-width="82">
|
|
|
<template slot-scope="scope">
|
|
<template slot-scope="scope">
|
|
|
- <span>{{ scope.row.costPrice != null ? scope.row.costPrice + ' 元/分钟' : '-' }}</span>
|
|
|
|
|
|
|
+ <span>{{ scope.row.costPrice != null ? scope.row.costPrice : '-' }}</span>
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
- <el-table-column label="售价(元/分钟)" align="center" prop="price" min-width="120">
|
|
|
|
|
|
|
+ <el-table-column label="售价" align="center" prop="salePrice" min-width="82">
|
|
|
<template slot-scope="scope">
|
|
<template slot-scope="scope">
|
|
|
- <span>{{ scope.row.price != null ? scope.row.price : '未定价' }}</span>
|
|
|
|
|
|
|
+ <span>{{ scope.row.salePrice != null ? scope.row.salePrice : '未定价' }}</span>
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
- <el-table-column label="优先级" align="center" prop="priority" min-width="70">
|
|
|
|
|
|
|
+ <el-table-column label="优先级" align="center" prop="priority" width="68">
|
|
|
<template slot-scope="scope">
|
|
<template slot-scope="scope">
|
|
|
<el-tag :type="scope.row.isPrimary === 1 ? 'success' : 'info'" size="mini">{{ scope.row.priority || '-' }}</el-tag>
|
|
<el-tag :type="scope.row.isPrimary === 1 ? 'success' : 'info'" size="mini">{{ scope.row.priority || '-' }}</el-tag>
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
- <el-table-column label="主线路" align="center" prop="isPrimary" min-width="70">
|
|
|
|
|
|
|
+ <el-table-column label="主线路" align="center" prop="isPrimary" width="68">
|
|
|
<template slot-scope="scope">
|
|
<template slot-scope="scope">
|
|
|
<el-tag v-if="scope.row.isPrimary === 1" type="success" size="mini">是</el-tag>
|
|
<el-tag v-if="scope.row.isPrimary === 1" type="success" size="mini">是</el-tag>
|
|
|
<span v-else>-</span>
|
|
<span v-else>-</span>
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
- <el-table-column label="手动选择" align="center" prop="allowManual" min-width="80">
|
|
|
|
|
|
|
+ <el-table-column label="手动选择" align="center" prop="selectable" min-width="88">
|
|
|
<template slot-scope="scope">
|
|
<template slot-scope="scope">
|
|
|
- <el-tag v-if="scope.row.allowManual === 1" type="warning" size="mini">允许</el-tag>
|
|
|
|
|
|
|
+ <el-tag v-if="isSelectable(scope.row)" type="warning" size="mini">允许</el-tag>
|
|
|
<span v-else>否</span>
|
|
<span v-else>否</span>
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
- <el-table-column label="状态" align="center" prop="status" min-width="70">
|
|
|
|
|
|
|
+ <el-table-column label="状态" align="center" prop="status" width="72" class-name="status-column">
|
|
|
<template slot-scope="scope">
|
|
<template slot-scope="scope">
|
|
|
- <el-tag v-if="scope.row.status === 1" type="success" size="mini">启用</el-tag>
|
|
|
|
|
- <el-tag v-else type="danger" size="mini">禁用</el-tag>
|
|
|
|
|
|
|
+ <el-tooltip :content="scope.row.status === 1 ? '启用' : '禁用'" placement="top">
|
|
|
|
|
+ <el-switch
|
|
|
|
|
+ v-model="scope.row.status"
|
|
|
|
|
+ :active-value="1"
|
|
|
|
|
+ :inactive-value="0"
|
|
|
|
|
+ :disabled="statusUpdatingId === scope.row.id"
|
|
|
|
|
+ @change="val => handleStatusChange(scope.row, val)"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-tooltip>
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
- <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="140">
|
|
|
|
|
|
|
+ <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="120">
|
|
|
<template slot-scope="scope">
|
|
<template slot-scope="scope">
|
|
|
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleEditPricing(scope.row)">定价</el-button>
|
|
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleEditPricing(scope.row)">定价</el-button>
|
|
|
<el-button size="mini" type="text" icon="el-icon-delete" style="color:#f56c6c" @click="handleUnbind(scope.row)">解除</el-button>
|
|
<el-button size="mini" type="text" icon="el-icon-delete" style="color:#f56c6c" @click="handleUnbind(scope.row)">解除</el-button>
|
|
@@ -97,13 +125,13 @@
|
|
|
<el-option v-for="api in apiOptions" :key="api.apiId" :label="api.apiName" :value="api.apiId" />
|
|
<el-option v-for="api in apiOptions" :key="api.apiId" :label="api.apiName" :value="api.apiId" />
|
|
|
</el-select>
|
|
</el-select>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
- <el-form-item label="选择租户" prop="companyId">
|
|
|
|
|
- <el-select v-model="addForm.companyId" placeholder="请选择租户" filterable style="width:100%">
|
|
|
|
|
- <el-option v-for="c in companyList" :key="c.companyId" :label="c.companyName" :value="c.companyId" />
|
|
|
|
|
|
|
+ <el-form-item label="选择租户" prop="tenantId">
|
|
|
|
|
+ <el-select v-model="addForm.tenantId" placeholder="请选择租户" filterable style="width:100%">
|
|
|
|
|
+ <el-option v-for="c in tenantList" :key="c.tenantId" :label="c.tenantName" :value="c.tenantId" />
|
|
|
</el-select>
|
|
</el-select>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
- <el-form-item label="售价(元/分钟)" prop="price">
|
|
|
|
|
- <el-input-number v-model="addForm.price" :precision="4" :step="0.01" :min="0" style="width:100%" />
|
|
|
|
|
|
|
+ <el-form-item label="售价(元/分钟)" prop="salePrice">
|
|
|
|
|
+ <el-input-number v-model="addForm.salePrice" :precision="4" :step="0.01" :min="0" style="width:100%" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
<el-form-item label="优先级" prop="priority">
|
|
<el-form-item label="优先级" prop="priority">
|
|
|
<el-input-number v-model="addForm.priority" :min="1" :max="99" style="width:100%" />
|
|
<el-input-number v-model="addForm.priority" :min="1" :max="99" style="width:100%" />
|
|
@@ -113,7 +141,7 @@
|
|
|
<el-switch v-model="addForm.isPrimary" :active-value="1" :inactive-value="0" active-text="是" inactive-text="否" />
|
|
<el-switch v-model="addForm.isPrimary" :active-value="1" :inactive-value="0" active-text="是" inactive-text="否" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
<el-form-item label="允许手动选择">
|
|
<el-form-item label="允许手动选择">
|
|
|
- <el-switch v-model="addForm.allowManual" :active-value="1" :inactive-value="0" active-text="允许" inactive-text="禁止" />
|
|
|
|
|
|
|
+ <el-switch v-model="addForm.selectable" active-value="1" inactive-value="0" active-text="允许" inactive-text="禁止" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
<el-form-item v-if="selectedApiCost" label="">
|
|
<el-form-item v-if="selectedApiCost" label="">
|
|
|
<span style="color:#909399;font-size:12px">该接口成本价: {{ selectedApiCost }} 元/分钟,建议售价 >= 成本价</span>
|
|
<span style="color:#909399;font-size:12px">该接口成本价: {{ selectedApiCost }} 元/分钟,建议售价 >= 成本价</span>
|
|
@@ -125,11 +153,11 @@
|
|
|
</div>
|
|
</div>
|
|
|
</el-dialog>
|
|
</el-dialog>
|
|
|
|
|
|
|
|
- <!-- 定价编辑弹窗 -->
|
|
|
|
|
|
|
+ <!-- 单条定价编辑弹窗 -->
|
|
|
<el-dialog title="编辑租户定价" :visible.sync="pricingOpen" width="500px" append-to-body>
|
|
<el-dialog title="编辑租户定价" :visible.sync="pricingOpen" width="500px" append-to-body>
|
|
|
<el-form ref="pricingForm" :model="pricingForm" label-width="140px" size="small">
|
|
<el-form ref="pricingForm" :model="pricingForm" label-width="140px" size="small">
|
|
|
<el-form-item label="租户">
|
|
<el-form-item label="租户">
|
|
|
- <el-input :value="pricingForm.companyName" disabled />
|
|
|
|
|
|
|
+ <el-input :value="pricingForm.tenantName" disabled />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
<el-form-item label="接口">
|
|
<el-form-item label="接口">
|
|
|
<el-input :value="pricingForm.apiName" disabled />
|
|
<el-input :value="pricingForm.apiName" disabled />
|
|
@@ -137,8 +165,8 @@
|
|
|
<el-form-item label="成本价(元/分钟)">
|
|
<el-form-item label="成本价(元/分钟)">
|
|
|
<el-input :value="pricingForm.costPrice != null ? pricingForm.costPrice : '-'" disabled />
|
|
<el-input :value="pricingForm.costPrice != null ? pricingForm.costPrice : '-'" disabled />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
- <el-form-item label="售价(元/分钟)" prop="price">
|
|
|
|
|
- <el-input-number v-model="pricingForm.price" :precision="4" :min="0" :step="0.01" style="width:100%" />
|
|
|
|
|
|
|
+ <el-form-item label="售价(元/分钟)" prop="salePrice">
|
|
|
|
|
+ <el-input-number v-model="pricingForm.salePrice" :precision="4" :min="0" :step="0.01" style="width:100%" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
<el-form-item label="优先级" prop="priority">
|
|
<el-form-item label="优先级" prop="priority">
|
|
|
<el-input-number v-model="pricingForm.priority" :min="1" :max="99" :step="1" style="width:100%" />
|
|
<el-input-number v-model="pricingForm.priority" :min="1" :max="99" :step="1" style="width:100%" />
|
|
@@ -147,7 +175,7 @@
|
|
|
<el-switch v-model="pricingForm.isPrimary" :active-value="1" :inactive-value="0" active-text="是" inactive-text="否" />
|
|
<el-switch v-model="pricingForm.isPrimary" :active-value="1" :inactive-value="0" active-text="是" inactive-text="否" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
<el-form-item label="允许手动选择">
|
|
<el-form-item label="允许手动选择">
|
|
|
- <el-switch v-model="pricingForm.allowManual" :active-value="1" :inactive-value="0" active-text="允许" inactive-text="禁止" />
|
|
|
|
|
|
|
+ <el-switch v-model="pricingForm.selectable" active-value="1" inactive-value="0" active-text="允许" inactive-text="禁止" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
<el-form-item label="状态">
|
|
<el-form-item label="状态">
|
|
|
<el-switch v-model="pricingForm.status" :active-value="1" :inactive-value="0" active-text="启用" inactive-text="禁用" />
|
|
<el-switch v-model="pricingForm.status" :active-value="1" :inactive-value="0" active-text="启用" inactive-text="禁用" />
|
|
@@ -158,11 +186,55 @@
|
|
|
<el-button @click="pricingOpen = false">取 消</el-button>
|
|
<el-button @click="pricingOpen = false">取 消</el-button>
|
|
|
</div>
|
|
</div>
|
|
|
</el-dialog>
|
|
</el-dialog>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 批量定价弹窗 -->
|
|
|
|
|
+ <el-dialog title="批量定价" :visible.sync="batchPricingOpen" width="520px" append-to-body>
|
|
|
|
|
+ <div class="batch-tip">将对已选 {{ selectedRows.length }} 条记录批量更新,仅填写需要修改的项,留空则保持原值不变。</div>
|
|
|
|
|
+ <el-form ref="batchPricingForm" :model="batchPricingForm" label-width="140px" size="small">
|
|
|
|
|
+ <el-form-item label="售价(元/分钟)">
|
|
|
|
|
+ <el-input-number v-model="batchPricingForm.salePrice" :precision="4" :min="0" :step="0.01" style="width:100%" placeholder="留空不修改" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="优先级">
|
|
|
|
|
+ <el-input-number v-model="batchPricingForm.priority" :min="1" :max="99" :step="1" style="width:100%" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="主线路">
|
|
|
|
|
+ <el-checkbox v-model="batchPricingForm.applyIsPrimary">更新主线路</el-checkbox>
|
|
|
|
|
+ <el-switch
|
|
|
|
|
+ v-model="batchPricingForm.isPrimary"
|
|
|
|
|
+ :disabled="!batchPricingForm.applyIsPrimary"
|
|
|
|
|
+ :active-value="1"
|
|
|
|
|
+ :inactive-value="0"
|
|
|
|
|
+ active-text="是"
|
|
|
|
|
+ inactive-text="否"
|
|
|
|
|
+ style="margin-left:12px"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="允许手动选择">
|
|
|
|
|
+ <el-checkbox v-model="batchPricingForm.applySelectable">更新手动选择</el-checkbox>
|
|
|
|
|
+ <el-switch
|
|
|
|
|
+ v-model="batchPricingForm.selectable"
|
|
|
|
|
+ :disabled="!batchPricingForm.applySelectable"
|
|
|
|
|
+ active-value="1"
|
|
|
|
|
+ inactive-value="0"
|
|
|
|
|
+ active-text="允许"
|
|
|
|
|
+ inactive-text="禁止"
|
|
|
|
|
+ style="margin-left:12px"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ <div slot="footer" class="dialog-footer">
|
|
|
|
|
+ <el-button type="primary" @click="submitBatchPricing" :loading="batchPricingSubmitting">确 定</el-button>
|
|
|
|
|
+ <el-button @click="batchPricingOpen = false">取 消</el-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-dialog>
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
<script>
|
|
|
-import { listVoiceApiTenant, updateTenantPricing, getVoiceApiList, assignTenants, unassignTenant } from '@/api/company/companyVoiceApi'
|
|
|
|
|
|
|
+import {
|
|
|
|
|
+ listVoiceApiTenantV2, updateTenantPricingV2, getVoiceApiListV2,
|
|
|
|
|
+ assignTenantsV2, unassignTenantV2, batchUpdateTenantPricingV2, batchUpdateTenantStatusV2
|
|
|
|
|
+} from '@/api/company/companyVoiceApi'
|
|
|
import { listAllCompanies } from '@/api/admin/sysCompany'
|
|
import { listAllCompanies } from '@/api/admin/sysCompany'
|
|
|
|
|
|
|
|
export default {
|
|
export default {
|
|
@@ -172,43 +244,50 @@ export default {
|
|
|
loading: true,
|
|
loading: true,
|
|
|
total: 0,
|
|
total: 0,
|
|
|
dataList: [],
|
|
dataList: [],
|
|
|
|
|
+ selectedRows: [],
|
|
|
|
|
+ statusUpdatingId: null,
|
|
|
apiTypeMap: { '0': 'SIP', '1': '网关', '2': 'API' },
|
|
apiTypeMap: { '0': 'SIP', '1': '网关', '2': 'API' },
|
|
|
queryParams: {
|
|
queryParams: {
|
|
|
pageNum: 1,
|
|
pageNum: 1,
|
|
|
pageSize: 10,
|
|
pageSize: 10,
|
|
|
- companyId: null,
|
|
|
|
|
|
|
+ tenantId: null,
|
|
|
apiId: null,
|
|
apiId: null,
|
|
|
status: null
|
|
status: null
|
|
|
},
|
|
},
|
|
|
- // 租户搜索
|
|
|
|
|
- companyOptions: [],
|
|
|
|
|
- companySearchLoading: false,
|
|
|
|
|
- // 接口列表
|
|
|
|
|
|
|
+ tenantOptions: [],
|
|
|
|
|
+ tenantSearchLoading: false,
|
|
|
apiOptions: [],
|
|
apiOptions: [],
|
|
|
- // 新增绑定
|
|
|
|
|
addDialogVisible: false,
|
|
addDialogVisible: false,
|
|
|
addSubmitting: false,
|
|
addSubmitting: false,
|
|
|
- addForm: { apiId: undefined, companyId: undefined, price: 0, priority: 1, isPrimary: 0, allowManual: 0 },
|
|
|
|
|
|
|
+ addForm: { apiId: undefined, tenantId: undefined, salePrice: 0, priority: 1, isPrimary: 0, selectable: '0' },
|
|
|
addRules: {
|
|
addRules: {
|
|
|
apiId: [{ required: true, message: '请选择接口', trigger: 'change' }],
|
|
apiId: [{ required: true, message: '请选择接口', trigger: 'change' }],
|
|
|
- companyId: [{ required: true, message: '请选择租户', trigger: 'change' }],
|
|
|
|
|
- price: [{ required: true, message: '请填写售价', trigger: 'blur' }]
|
|
|
|
|
|
|
+ tenantId: [{ required: true, message: '请选择租户', trigger: 'change' }],
|
|
|
|
|
+ salePrice: [{ required: true, message: '请填写售价', trigger: 'blur' }]
|
|
|
},
|
|
},
|
|
|
- // 租户列表(新增绑定用)
|
|
|
|
|
- companyList: [],
|
|
|
|
|
- // 定价编辑
|
|
|
|
|
|
|
+ tenantList: [],
|
|
|
pricingOpen: false,
|
|
pricingOpen: false,
|
|
|
pricingSubmitting: false,
|
|
pricingSubmitting: false,
|
|
|
pricingForm: {
|
|
pricingForm: {
|
|
|
id: null,
|
|
id: null,
|
|
|
- companyName: '',
|
|
|
|
|
|
|
+ tenantName: '',
|
|
|
apiName: '',
|
|
apiName: '',
|
|
|
costPrice: null,
|
|
costPrice: null,
|
|
|
- price: null,
|
|
|
|
|
|
|
+ salePrice: null,
|
|
|
priority: 1,
|
|
priority: 1,
|
|
|
isPrimary: 0,
|
|
isPrimary: 0,
|
|
|
- allowManual: 0,
|
|
|
|
|
|
|
+ selectable: '0',
|
|
|
status: 1
|
|
status: 1
|
|
|
|
|
+ },
|
|
|
|
|
+ batchPricingOpen: false,
|
|
|
|
|
+ batchPricingSubmitting: false,
|
|
|
|
|
+ batchPricingForm: {
|
|
|
|
|
+ salePrice: undefined,
|
|
|
|
|
+ priority: undefined,
|
|
|
|
|
+ applyIsPrimary: false,
|
|
|
|
|
+ isPrimary: 0,
|
|
|
|
|
+ applySelectable: false,
|
|
|
|
|
+ selectable: '0'
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
@@ -221,12 +300,19 @@ export default {
|
|
|
created() {
|
|
created() {
|
|
|
this.getList()
|
|
this.getList()
|
|
|
this.loadApiOptions()
|
|
this.loadApiOptions()
|
|
|
- this.loadCompanyList()
|
|
|
|
|
|
|
+ this.loadTenantList()
|
|
|
},
|
|
},
|
|
|
methods: {
|
|
methods: {
|
|
|
|
|
+ isSelectable(row) {
|
|
|
|
|
+ return row.selectable === '1' || row.selectable === 1 || row.selectable === true
|
|
|
|
|
+ },
|
|
|
|
|
+ normalizeSelectable(value) {
|
|
|
|
|
+ if (value === 1 || value === true || value === '1') return '1'
|
|
|
|
|
+ return '0'
|
|
|
|
|
+ },
|
|
|
getList() {
|
|
getList() {
|
|
|
this.loading = true
|
|
this.loading = true
|
|
|
- listVoiceApiTenant(this.queryParams).then(response => {
|
|
|
|
|
|
|
+ listVoiceApiTenantV2(this.queryParams).then(response => {
|
|
|
this.dataList = response.rows || []
|
|
this.dataList = response.rows || []
|
|
|
this.total = response.total || 0
|
|
this.total = response.total || 0
|
|
|
this.loading = false
|
|
this.loading = false
|
|
@@ -240,24 +326,31 @@ export default {
|
|
|
this.resetForm('queryForm')
|
|
this.resetForm('queryForm')
|
|
|
this.handleQuery()
|
|
this.handleQuery()
|
|
|
},
|
|
},
|
|
|
|
|
+ handleSelectionChange(rows) {
|
|
|
|
|
+ this.selectedRows = rows || []
|
|
|
|
|
+ },
|
|
|
loadApiOptions() {
|
|
loadApiOptions() {
|
|
|
- getVoiceApiList().then(response => {
|
|
|
|
|
|
|
+ getVoiceApiListV2().then(response => {
|
|
|
this.apiOptions = response.rows || response.data || []
|
|
this.apiOptions = response.rows || response.data || []
|
|
|
}).catch(() => {})
|
|
}).catch(() => {})
|
|
|
},
|
|
},
|
|
|
- loadCompanyList() {
|
|
|
|
|
|
|
+ loadTenantList() {
|
|
|
listAllCompanies({ pageNum: 1, pageSize: 1000 }).then(res => {
|
|
listAllCompanies({ pageNum: 1, pageSize: 1000 }).then(res => {
|
|
|
- this.companyList = res.rows || res.data || []
|
|
|
|
|
|
|
+ const rows = res.rows || res.data || []
|
|
|
|
|
+ this.tenantList = rows.map(c => ({
|
|
|
|
|
+ tenantId: c.id || c.companyId,
|
|
|
|
|
+ tenantName: c.tenantName || c.companyName
|
|
|
|
|
+ }))
|
|
|
})
|
|
})
|
|
|
},
|
|
},
|
|
|
onApiChange(apiId) {
|
|
onApiChange(apiId) {
|
|
|
const api = this.apiOptions.find(a => a.apiId === apiId)
|
|
const api = this.apiOptions.find(a => a.apiId === apiId)
|
|
|
if (api && api.costPrice) {
|
|
if (api && api.costPrice) {
|
|
|
- this.addForm.price = api.costPrice
|
|
|
|
|
|
|
+ this.addForm.salePrice = api.costPrice
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
handleAdd() {
|
|
handleAdd() {
|
|
|
- this.addForm = { apiId: undefined, companyId: undefined, price: 0, priority: 1, isPrimary: 0, allowManual: 0 }
|
|
|
|
|
|
|
+ this.addForm = { apiId: undefined, tenantId: undefined, salePrice: 0, priority: 1, isPrimary: 0, selectable: '0' }
|
|
|
this.addDialogVisible = true
|
|
this.addDialogVisible = true
|
|
|
this.$nextTick(() => {
|
|
this.$nextTick(() => {
|
|
|
if (this.$refs.addForm) this.$refs.addForm.clearValidate()
|
|
if (this.$refs.addForm) this.$refs.addForm.clearValidate()
|
|
@@ -267,16 +360,15 @@ export default {
|
|
|
this.$refs.addForm.validate(valid => {
|
|
this.$refs.addForm.validate(valid => {
|
|
|
if (!valid) return
|
|
if (!valid) return
|
|
|
this.addSubmitting = true
|
|
this.addSubmitting = true
|
|
|
- assignTenants(this.addForm.apiId, [this.addForm.companyId]).then(() => {
|
|
|
|
|
- // 分配后设置定价
|
|
|
|
|
- if (this.addForm.price || this.addForm.priority > 1 || this.addForm.isPrimary || this.addForm.allowManual) {
|
|
|
|
|
- updateTenantPricing({
|
|
|
|
|
|
|
+ assignTenantsV2(this.addForm.apiId, [this.addForm.tenantId]).then(() => {
|
|
|
|
|
+ if (this.addForm.salePrice || this.addForm.priority > 1 || this.addForm.isPrimary || this.addForm.selectable === '1') {
|
|
|
|
|
+ updateTenantPricingV2({
|
|
|
apiId: this.addForm.apiId,
|
|
apiId: this.addForm.apiId,
|
|
|
- companyId: this.addForm.companyId,
|
|
|
|
|
- price: this.addForm.price,
|
|
|
|
|
|
|
+ tenantId: this.addForm.tenantId,
|
|
|
|
|
+ salePrice: this.addForm.salePrice,
|
|
|
priority: this.addForm.priority,
|
|
priority: this.addForm.priority,
|
|
|
isPrimary: this.addForm.isPrimary,
|
|
isPrimary: this.addForm.isPrimary,
|
|
|
- allowManual: this.addForm.allowManual,
|
|
|
|
|
|
|
+ selectable: this.addForm.selectable,
|
|
|
status: 1
|
|
status: 1
|
|
|
}).catch(() => {})
|
|
}).catch(() => {})
|
|
|
}
|
|
}
|
|
@@ -287,35 +379,35 @@ export default {
|
|
|
})
|
|
})
|
|
|
},
|
|
},
|
|
|
handleUnbind(row) {
|
|
handleUnbind(row) {
|
|
|
- this.$confirm('确认解除租户"' + row.companyName + '"与接口"' + row.apiName + '"的绑定?', '提示', {
|
|
|
|
|
|
|
+ this.$confirm('确认解除租户"' + row.tenantName + '"与接口"' + row.apiName + '"的绑定?', '提示', {
|
|
|
confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning'
|
|
confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning'
|
|
|
}).then(() => {
|
|
}).then(() => {
|
|
|
- unassignTenant(row.apiId, row.companyId).then(() => {
|
|
|
|
|
|
|
+ unassignTenantV2(row.apiId, row.tenantId).then(() => {
|
|
|
this.$message.success('解除绑定成功')
|
|
this.$message.success('解除绑定成功')
|
|
|
this.getList()
|
|
this.getList()
|
|
|
})
|
|
})
|
|
|
}).catch(() => {})
|
|
}).catch(() => {})
|
|
|
},
|
|
},
|
|
|
- searchCompanies(query) {
|
|
|
|
|
- if (query.length < 1) { this.companyOptions = []; return }
|
|
|
|
|
- this.companySearchLoading = true
|
|
|
|
|
|
|
+ searchTenants(query) {
|
|
|
|
|
+ if (query.length < 1) { this.tenantOptions = []; return }
|
|
|
|
|
+ this.tenantSearchLoading = true
|
|
|
listAllCompanies({ companyName: query, pageNum: 1, pageSize: 20 }).then(response => {
|
|
listAllCompanies({ companyName: query, pageNum: 1, pageSize: 20 }).then(response => {
|
|
|
- this.companyOptions = (response.rows || []).map(c => ({
|
|
|
|
|
- companyId: c.companyId || c.id,
|
|
|
|
|
- companyName: c.companyName || c.tenantName
|
|
|
|
|
|
|
+ this.tenantOptions = (response.rows || []).map(c => ({
|
|
|
|
|
+ tenantId: c.id || c.companyId,
|
|
|
|
|
+ tenantName: c.tenantName || c.companyName
|
|
|
}))
|
|
}))
|
|
|
- }).finally(() => { this.companySearchLoading = false })
|
|
|
|
|
|
|
+ }).finally(() => { this.tenantSearchLoading = false })
|
|
|
},
|
|
},
|
|
|
handleEditPricing(row) {
|
|
handleEditPricing(row) {
|
|
|
this.pricingForm = {
|
|
this.pricingForm = {
|
|
|
id: row.id,
|
|
id: row.id,
|
|
|
- companyName: row.companyName,
|
|
|
|
|
|
|
+ tenantName: row.tenantName,
|
|
|
apiName: row.apiName,
|
|
apiName: row.apiName,
|
|
|
costPrice: row.costPrice,
|
|
costPrice: row.costPrice,
|
|
|
- price: row.price,
|
|
|
|
|
|
|
+ salePrice: row.salePrice,
|
|
|
priority: row.priority || 1,
|
|
priority: row.priority || 1,
|
|
|
isPrimary: row.isPrimary || 0,
|
|
isPrimary: row.isPrimary || 0,
|
|
|
- allowManual: row.allowManual || 0,
|
|
|
|
|
|
|
+ selectable: this.normalizeSelectable(row.selectable),
|
|
|
status: row.status
|
|
status: row.status
|
|
|
}
|
|
}
|
|
|
this.pricingOpen = true
|
|
this.pricingOpen = true
|
|
@@ -325,24 +417,116 @@ export default {
|
|
|
},
|
|
},
|
|
|
submitPricing() {
|
|
submitPricing() {
|
|
|
this.pricingSubmitting = true
|
|
this.pricingSubmitting = true
|
|
|
- updateTenantPricing({
|
|
|
|
|
|
|
+ updateTenantPricingV2({
|
|
|
id: this.pricingForm.id,
|
|
id: this.pricingForm.id,
|
|
|
- price: this.pricingForm.price,
|
|
|
|
|
|
|
+ salePrice: this.pricingForm.salePrice,
|
|
|
priority: this.pricingForm.priority,
|
|
priority: this.pricingForm.priority,
|
|
|
isPrimary: this.pricingForm.isPrimary,
|
|
isPrimary: this.pricingForm.isPrimary,
|
|
|
- allowManual: this.pricingForm.allowManual,
|
|
|
|
|
|
|
+ selectable: this.pricingForm.selectable,
|
|
|
status: this.pricingForm.status
|
|
status: this.pricingForm.status
|
|
|
}).then(() => {
|
|
}).then(() => {
|
|
|
this.$message.success('定价保存成功')
|
|
this.$message.success('定价保存成功')
|
|
|
this.pricingOpen = false
|
|
this.pricingOpen = false
|
|
|
this.getList()
|
|
this.getList()
|
|
|
}).finally(() => { this.pricingSubmitting = false })
|
|
}).finally(() => { this.pricingSubmitting = false })
|
|
|
|
|
+ },
|
|
|
|
|
+ handleBatchPricing() {
|
|
|
|
|
+ if (!this.selectedRows.length) {
|
|
|
|
|
+ this.$message.warning('请先选择要批量定价的记录')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ this.batchPricingForm = {
|
|
|
|
|
+ salePrice: undefined,
|
|
|
|
|
+ priority: undefined,
|
|
|
|
|
+ applyIsPrimary: false,
|
|
|
|
|
+ isPrimary: 0,
|
|
|
|
|
+ applySelectable: false,
|
|
|
|
|
+ selectable: '0'
|
|
|
|
|
+ }
|
|
|
|
|
+ this.batchPricingOpen = true
|
|
|
|
|
+ },
|
|
|
|
|
+ submitBatchPricing() {
|
|
|
|
|
+ const data = { ids: this.selectedRows.map(row => row.id) }
|
|
|
|
|
+ if (this.batchPricingForm.salePrice != null && this.batchPricingForm.salePrice !== '') {
|
|
|
|
|
+ data.salePrice = this.batchPricingForm.salePrice
|
|
|
|
|
+ }
|
|
|
|
|
+ if (this.batchPricingForm.priority != null && this.batchPricingForm.priority !== '') {
|
|
|
|
|
+ data.priority = this.batchPricingForm.priority
|
|
|
|
|
+ }
|
|
|
|
|
+ if (this.batchPricingForm.applyIsPrimary) {
|
|
|
|
|
+ data.isPrimary = this.batchPricingForm.isPrimary
|
|
|
|
|
+ }
|
|
|
|
|
+ if (this.batchPricingForm.applySelectable) {
|
|
|
|
|
+ data.selectable = this.batchPricingForm.selectable
|
|
|
|
|
+ }
|
|
|
|
|
+ if (data.salePrice == null && data.priority == null && data.isPrimary == null && data.selectable == null) {
|
|
|
|
|
+ this.$message.warning('请至少填写或勾选一项要批量更新的配置')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ this.batchPricingSubmitting = true
|
|
|
|
|
+ batchUpdateTenantPricingV2(data).then(() => {
|
|
|
|
|
+ this.$message.success('批量定价成功')
|
|
|
|
|
+ this.batchPricingOpen = false
|
|
|
|
|
+ this.getList()
|
|
|
|
|
+ }).finally(() => { this.batchPricingSubmitting = false })
|
|
|
|
|
+ },
|
|
|
|
|
+ handleBatchStatus(status) {
|
|
|
|
|
+ if (!this.selectedRows.length) {
|
|
|
|
|
+ this.$message.warning('请先选择要操作的记录')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ const actionText = status === 1 ? '启用' : '禁用'
|
|
|
|
|
+ this.$confirm('确认批量' + actionText + '已选 ' + this.selectedRows.length + ' 条记录?', '提示', {
|
|
|
|
|
+ confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning'
|
|
|
|
|
+ }).then(() => {
|
|
|
|
|
+ return batchUpdateTenantStatusV2({
|
|
|
|
|
+ ids: this.selectedRows.map(row => row.id),
|
|
|
|
|
+ status
|
|
|
|
|
+ })
|
|
|
|
|
+ }).then(() => {
|
|
|
|
|
+ this.$message.success('批量' + actionText + '成功')
|
|
|
|
|
+ this.getList()
|
|
|
|
|
+ }).catch(() => {})
|
|
|
|
|
+ },
|
|
|
|
|
+ handleStatusChange(row, status) {
|
|
|
|
|
+ const previousStatus = status === 1 ? 0 : 1
|
|
|
|
|
+ this.statusUpdatingId = row.id
|
|
|
|
|
+ updateTenantPricingV2({ id: row.id, status }).then(() => {
|
|
|
|
|
+ this.$message.success(status === 1 ? '已启用' : '已禁用')
|
|
|
|
|
+ }).catch(() => {
|
|
|
|
|
+ row.status = previousStatus
|
|
|
|
|
+ }).finally(() => {
|
|
|
|
|
+ this.statusUpdatingId = null
|
|
|
|
|
+ })
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped>
|
|
<style scoped>
|
|
|
|
|
+.mb8 { margin-bottom: 8px; }
|
|
|
.mb16 { margin-bottom: 16px; }
|
|
.mb16 { margin-bottom: 16px; }
|
|
|
.filter-card { padding-bottom: 0; }
|
|
.filter-card { padding-bottom: 0; }
|
|
|
|
|
+.selected-tip { color: #909399; font-size: 13px; line-height: 28px; }
|
|
|
|
|
+.batch-tip {
|
|
|
|
|
+ margin-bottom: 16px;
|
|
|
|
|
+ padding: 10px 12px;
|
|
|
|
|
+ background: #f4f4f5;
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+ color: #606266;
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ line-height: 1.5;
|
|
|
|
|
+}
|
|
|
|
|
+.voice-api-tenant-table {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+}
|
|
|
|
|
+.voice-api-tenant-table >>> .status-column .cell {
|
|
|
|
|
+ overflow: visible;
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+ padding-left: 8px;
|
|
|
|
|
+ padding-right: 8px;
|
|
|
|
|
+}
|
|
|
|
|
+.voice-api-tenant-table >>> .status-column .el-switch {
|
|
|
|
|
+ vertical-align: middle;
|
|
|
|
|
+}
|
|
|
</style>
|
|
</style>
|