fix: 端点问题调整
This commit is contained in:
parent
eb8cab3f5a
commit
c2c1ff8063
|
|
@ -5,7 +5,7 @@ VUE_APP_TITLE = 管理系统
|
||||||
ENV = 'production'
|
ENV = 'production'
|
||||||
|
|
||||||
# 若依管理系统/生产环境
|
# 若依管理系统/生产环境
|
||||||
VUE_APP_BASE_API = 'http://111.230.37.169:10009'
|
# VUE_APP_BASE_API = 'http://111.230.37.169:10009'
|
||||||
# VUE_APP_BASE_API = 'http://101.96.201.225:8011'
|
# VUE_APP_BASE_API = 'http://101.96.201.225:8011'
|
||||||
# VUE_APP_BASE_API = 'http://47.86.170.114:8011'
|
VUE_APP_BASE_API = 'http://47.86.170.114:8011'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
|
<el-dialog :title="title" :visible.sync="open" width="760px" append-to-body>
|
||||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="24" v-if="form.parentId !== 0">
|
<el-col :span="24" v-if="form.parentId !== 0">
|
||||||
|
|
@ -160,6 +160,41 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
<el-row v-if="isSecondLevelCompanyForm">
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="视频模型">
|
||||||
|
<div class="model-parm-block">
|
||||||
|
<div
|
||||||
|
v-for="(row, idx) in modelParamRows"
|
||||||
|
:key="'mp-' + idx"
|
||||||
|
class="model-parm-row"
|
||||||
|
>
|
||||||
|
<el-input
|
||||||
|
v-model="row.label"
|
||||||
|
placeholder="显示名称(如 Seedance 2.0)"
|
||||||
|
class="model-parm-input-label"
|
||||||
|
/>
|
||||||
|
<el-input
|
||||||
|
v-model="row.value"
|
||||||
|
placeholder="Endpoint / 模型 ID(ep-…)"
|
||||||
|
class="model-parm-input-value"
|
||||||
|
/>
|
||||||
|
<el-button
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-delete"
|
||||||
|
:disabled="modelParamRows.length <= 1"
|
||||||
|
@click="removeModelParamRow(idx)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<el-button type="text" icon="el-icon-plus" @click="addModelParamRow">添加模型</el-button>
|
||||||
|
<p class="model-parm-hint">
|
||||||
|
保存为 JSON 写入库表 model_parm;门户「视频生成」按用户所属二级部门读取。
|
||||||
|
留空或未配置时,使用配置文件 portal.video.models。
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div slot="footer" class="dialog-footer">
|
<div slot="footer" class="dialog-footer">
|
||||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
|
@ -169,6 +204,31 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.model-parm-block {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.model-parm-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
.model-parm-input-label {
|
||||||
|
width: 38%;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
.model-parm-input-value {
|
||||||
|
flex: 1;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
.model-parm-hint {
|
||||||
|
margin: 8px 0 0;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #909399;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { listDept, getDept, delDept, addDept, updateDept, listDeptExcludeChild } from "@/api/ai/dept"
|
import { listDept, getDept, delDept, addDept, updateDept, listDeptExcludeChild } from "@/api/ai/dept"
|
||||||
import Treeselect from "@riophae/vue-treeselect"
|
import Treeselect from "@riophae/vue-treeselect"
|
||||||
|
|
@ -193,6 +253,7 @@ export default {
|
||||||
status: undefined
|
status: undefined
|
||||||
},
|
},
|
||||||
form: {},
|
form: {},
|
||||||
|
modelParamRows: [{ label: '', value: '' }],
|
||||||
rules: {
|
rules: {
|
||||||
parentId: [
|
parentId: [
|
||||||
{ required: true, message: "上级部门不能为空", trigger: "blur" }
|
{ required: true, message: "上级部门不能为空", trigger: "blur" }
|
||||||
|
|
@ -268,8 +329,10 @@ export default {
|
||||||
phone: undefined,
|
phone: undefined,
|
||||||
email: undefined,
|
email: undefined,
|
||||||
byteApiKey: undefined,
|
byteApiKey: undefined,
|
||||||
|
modelParm: undefined,
|
||||||
status: "0"
|
status: "0"
|
||||||
}
|
}
|
||||||
|
this.modelParamRows = [{ label: '', value: '' }]
|
||||||
this.resetForm("form")
|
this.resetForm("form")
|
||||||
},
|
},
|
||||||
handleQuery() {
|
handleQuery() {
|
||||||
|
|
@ -297,10 +360,45 @@ export default {
|
||||||
this.refreshTable = true
|
this.refreshTable = true
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
syncModelRowsFromForm() {
|
||||||
|
this.modelParamRows = [{ label: '', value: '' }]
|
||||||
|
const raw = this.form.modelParm
|
||||||
|
if (!raw || String(raw).trim() === '') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const arr = JSON.parse(raw)
|
||||||
|
if (Array.isArray(arr) && arr.length) {
|
||||||
|
this.modelParamRows = arr.map(x => ({
|
||||||
|
label: (x && x.label) ? String(x.label) : '',
|
||||||
|
value: (x && x.value) ? String(x.value) : ''
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.modelParamRows = [{ label: '', value: '' }]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
buildModelParmPayload() {
|
||||||
|
if (!this.isSecondLevelCompanyForm) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const rows = (this.modelParamRows || []).filter(r => r.label && r.value)
|
||||||
|
this.form.modelParm = rows.length ? JSON.stringify(rows) : ''
|
||||||
|
},
|
||||||
|
addModelParamRow() {
|
||||||
|
this.modelParamRows.push({ label: '', value: '' })
|
||||||
|
},
|
||||||
|
removeModelParamRow(idx) {
|
||||||
|
if (this.modelParamRows.length <= 1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.modelParamRows.splice(idx, 1)
|
||||||
|
},
|
||||||
handleUpdate(row) {
|
handleUpdate(row) {
|
||||||
this.reset()
|
this.reset()
|
||||||
getDept(row.deptId).then(response => {
|
getDept(row.deptId).then(response => {
|
||||||
this.form = response.data
|
this.form = response.data
|
||||||
|
this.syncModelRowsFromForm()
|
||||||
this.open = true
|
this.open = true
|
||||||
this.title = "修改部门"
|
this.title = "修改部门"
|
||||||
listDeptExcludeChild(row.deptId).then(response => {
|
listDeptExcludeChild(row.deptId).then(response => {
|
||||||
|
|
@ -315,6 +413,7 @@ export default {
|
||||||
submitForm: function() {
|
submitForm: function() {
|
||||||
this.$refs["form"].validate(valid => {
|
this.$refs["form"].validate(valid => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
|
this.buildModelParmPayload()
|
||||||
if (this.form.deptId != undefined) {
|
if (this.form.deptId != undefined) {
|
||||||
updateDept(this.form).then(response => {
|
updateDept(this.form).then(response => {
|
||||||
this.$modal.msgSuccess("修改成功")
|
this.$modal.msgSuccess("修改成功")
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<!-- 添加或修改部门对话框 -->
|
<!-- 添加或修改部门对话框 -->
|
||||||
<el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
|
<el-dialog :title="title" :visible.sync="open" width="760px" append-to-body>
|
||||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="24" v-if="form.parentId !== 0">
|
<el-col :span="24" v-if="form.parentId !== 0">
|
||||||
|
|
@ -174,6 +174,41 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
<el-row v-if="isSecondLevelCompanyForm">
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="视频模型">
|
||||||
|
<div class="model-parm-block">
|
||||||
|
<div
|
||||||
|
v-for="(row, idx) in modelParamRows"
|
||||||
|
:key="'mp-' + idx"
|
||||||
|
class="model-parm-row"
|
||||||
|
>
|
||||||
|
<el-input
|
||||||
|
v-model="row.label"
|
||||||
|
placeholder="显示名称(如 Seedance 2.0)"
|
||||||
|
class="model-parm-input-label"
|
||||||
|
/>
|
||||||
|
<el-input
|
||||||
|
v-model="row.value"
|
||||||
|
placeholder="Endpoint / 模型 ID(ep-…)"
|
||||||
|
class="model-parm-input-value"
|
||||||
|
/>
|
||||||
|
<el-button
|
||||||
|
type="text"
|
||||||
|
icon="el-icon-delete"
|
||||||
|
:disabled="modelParamRows.length <= 1"
|
||||||
|
@click="removeModelParamRow(idx)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<el-button type="text" icon="el-icon-plus" @click="addModelParamRow">添加模型</el-button>
|
||||||
|
<p class="model-parm-hint">
|
||||||
|
保存为 JSON 写入 model_parm;门户「视频生成」按用户所属二级部门读取。
|
||||||
|
留空则使用 portal.video.models。
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div slot="footer" class="dialog-footer">
|
<div slot="footer" class="dialog-footer">
|
||||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||||
|
|
@ -183,6 +218,31 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.model-parm-block {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.model-parm-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
.model-parm-input-label {
|
||||||
|
width: 38%;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
.model-parm-input-value {
|
||||||
|
flex: 1;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
.model-parm-hint {
|
||||||
|
margin: 8px 0 0;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #909399;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { listDept, getDept, delDept, addDept, updateDept, listDeptExcludeChild } from "@/api/system/dept"
|
import { listDept, getDept, delDept, addDept, updateDept, listDeptExcludeChild } from "@/api/system/dept"
|
||||||
import Treeselect from "@riophae/vue-treeselect"
|
import Treeselect from "@riophae/vue-treeselect"
|
||||||
|
|
@ -217,6 +277,7 @@ export default {
|
||||||
},
|
},
|
||||||
// 表单参数
|
// 表单参数
|
||||||
form: {},
|
form: {},
|
||||||
|
modelParamRows: [{ label: '', value: '' }],
|
||||||
// 表单校验
|
// 表单校验
|
||||||
rules: {
|
rules: {
|
||||||
parentId: [
|
parentId: [
|
||||||
|
|
@ -262,6 +323,40 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
syncModelRowsFromForm() {
|
||||||
|
this.modelParamRows = [{ label: '', value: '' }]
|
||||||
|
const raw = this.form.modelParm
|
||||||
|
if (!raw || String(raw).trim() === '') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const arr = JSON.parse(raw)
|
||||||
|
if (Array.isArray(arr) && arr.length) {
|
||||||
|
this.modelParamRows = arr.map(x => ({
|
||||||
|
label: (x && x.label) ? String(x.label) : '',
|
||||||
|
value: (x && x.value) ? String(x.value) : ''
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.modelParamRows = [{ label: '', value: '' }]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
buildModelParmPayload() {
|
||||||
|
if (!this.isSecondLevelCompanyForm) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const rows = (this.modelParamRows || []).filter(r => r.label && r.value)
|
||||||
|
this.form.modelParm = rows.length ? JSON.stringify(rows) : ''
|
||||||
|
},
|
||||||
|
addModelParamRow() {
|
||||||
|
this.modelParamRows.push({ label: '', value: '' })
|
||||||
|
},
|
||||||
|
removeModelParamRow(idx) {
|
||||||
|
if (this.modelParamRows.length <= 1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.modelParamRows.splice(idx, 1)
|
||||||
|
},
|
||||||
/** 查询部门列表 */
|
/** 查询部门列表 */
|
||||||
getList() {
|
getList() {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
|
|
@ -298,8 +393,11 @@ export default {
|
||||||
phone: undefined,
|
phone: undefined,
|
||||||
email: undefined,
|
email: undefined,
|
||||||
byteApiKey: undefined,
|
byteApiKey: undefined,
|
||||||
|
project: undefined,
|
||||||
|
modelParm: undefined,
|
||||||
status: "0"
|
status: "0"
|
||||||
}
|
}
|
||||||
|
this.modelParamRows = [{ label: '', value: '' }]
|
||||||
this.resetForm("form")
|
this.resetForm("form")
|
||||||
},
|
},
|
||||||
/** 搜索按钮操作 */
|
/** 搜索按钮操作 */
|
||||||
|
|
@ -336,6 +434,7 @@ export default {
|
||||||
this.reset()
|
this.reset()
|
||||||
getDept(row.deptId).then(response => {
|
getDept(row.deptId).then(response => {
|
||||||
this.form = response.data
|
this.form = response.data
|
||||||
|
this.syncModelRowsFromForm()
|
||||||
this.open = true
|
this.open = true
|
||||||
this.title = "修改部门"
|
this.title = "修改部门"
|
||||||
listDeptExcludeChild(row.deptId).then(response => {
|
listDeptExcludeChild(row.deptId).then(response => {
|
||||||
|
|
@ -351,6 +450,7 @@ export default {
|
||||||
submitForm: function() {
|
submitForm: function() {
|
||||||
this.$refs["form"].validate(valid => {
|
this.$refs["form"].validate(valid => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
|
this.buildModelParmPayload()
|
||||||
if (this.form.deptId != undefined) {
|
if (this.form.deptId != undefined) {
|
||||||
updateDept(this.form).then(response => {
|
updateDept(this.form).then(response => {
|
||||||
this.$modal.msgSuccess("修改成功")
|
this.$modal.msgSuccess("修改成功")
|
||||||
|
|
|
||||||
|
|
@ -468,7 +468,7 @@ export default {
|
||||||
const res = await this.$axios({
|
const res = await this.$axios({
|
||||||
url: 'api/portal/video/tasks',
|
url: 'api/portal/video/tasks',
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
data: { pageNum, pageSize }
|
params: { pageNum, pageSize }
|
||||||
})
|
})
|
||||||
|
|
||||||
const newRows = res.code === 200 ? res.rows || [] : []
|
const newRows = res.code === 200 ? res.rows || [] : []
|
||||||
|
|
@ -542,7 +542,7 @@ export default {
|
||||||
const res = await this.$axios({
|
const res = await this.$axios({
|
||||||
url: 'api/portal/video/tasks',
|
url: 'api/portal/video/tasks',
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
data: { pageNum: 1, pageSize: this.chatPageSize }
|
params: { pageNum: 1, pageSize: this.chatPageSize }
|
||||||
})
|
})
|
||||||
const newRows = res.code === 200 ? res.rows || [] : []
|
const newRows = res.code === 200 ? res.rows || [] : []
|
||||||
const existMap = new Map((this.taskRows || []).map((x) => [x.id, x]))
|
const existMap = new Map((this.taskRows || []).map((x) => [x.id, x]))
|
||||||
|
|
@ -581,18 +581,31 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
taskRowResultTrim(row) {
|
taskRowResultTrim(row) {
|
||||||
return String(row?.result ?? '').trim()
|
let r = String(row?.result ?? '').trim()
|
||||||
|
if (r) return r
|
||||||
|
const raw = row?.videoParams
|
||||||
|
if (raw == null || raw === '') return ''
|
||||||
|
if (typeof raw !== 'string') return ''
|
||||||
|
try {
|
||||||
|
const o = JSON.parse(raw)
|
||||||
|
const id = o?.volcTaskId
|
||||||
|
if (id != null && String(id).trim() !== '') return String(id).trim()
|
||||||
|
} catch (_) {
|
||||||
|
/* ignore */
|
||||||
|
}
|
||||||
|
return ''
|
||||||
},
|
},
|
||||||
|
|
||||||
taskStatusText(row) {
|
taskStatusText(row) {
|
||||||
if (row.status === 2) return '已失败/已取消'
|
const st = row?.status
|
||||||
if (row.status === 0) return '执行中'
|
if (st === 2 || st === '2') return '已失败/已取消'
|
||||||
if (row.status === 1) {
|
if (st === 0 || st === '0') return '执行中'
|
||||||
|
if (st === 1 || st === '1') {
|
||||||
const r = this.taskRowResultTrim(row)
|
const r = this.taskRowResultTrim(row)
|
||||||
if (!r) return '失败'
|
if (!r) return '失败'
|
||||||
if (this.isHttpOrHttpsUrl(r)) return '已完成'
|
if (this.isHttpOrHttpsUrl(r)) return '已完成'
|
||||||
if (/^cgt/i.test(r)) return '任务执行中'
|
// 任务 id 格式由火山侧决定,不再假定 cgt 前缀;非 URL 的中间态均视为执行中
|
||||||
return '任务生成失败'
|
return '任务执行中'
|
||||||
}
|
}
|
||||||
return '执行中'
|
return '执行中'
|
||||||
},
|
},
|
||||||
|
|
@ -600,17 +613,17 @@ export default {
|
||||||
/** 是否展示完整「结果区」(视频 / 链接);其余状态仅紧凑展示在用户行右侧 */
|
/** 是否展示完整「结果区」(视频 / 链接);其余状态仅紧凑展示在用户行右侧 */
|
||||||
isChatRowSuccessWithMedia(row) {
|
isChatRowSuccessWithMedia(row) {
|
||||||
const r = this.taskRowResultTrim(row)
|
const r = this.taskRowResultTrim(row)
|
||||||
return row.status === 1 && !!r && this.isHttpOrHttpsUrl(r)
|
const st = row?.status
|
||||||
|
return (st === 1 || st === '1') && !!r && this.isHttpOrHttpsUrl(r)
|
||||||
},
|
},
|
||||||
|
|
||||||
chatRowInlineStatusClass(row) {
|
chatRowInlineStatusClass(row) {
|
||||||
if (row.status === 2) return 'vg-chat-inline-status--failed'
|
const st = row?.status
|
||||||
if (row.status === 1) {
|
if (st === 2 || st === '2') return 'vg-chat-inline-status--failed'
|
||||||
|
if (st === 1 || st === '1') {
|
||||||
const r = this.taskRowResultTrim(row)
|
const r = this.taskRowResultTrim(row)
|
||||||
if (!r) return 'vg-chat-inline-status--failed'
|
if (!r) return 'vg-chat-inline-status--failed'
|
||||||
if (/^cgt/i.test(r)) return 'vg-chat-inline-status--running'
|
return 'vg-chat-inline-status--running'
|
||||||
if (this.isHttpOrHttpsUrl(r)) return 'vg-chat-inline-status--running'
|
|
||||||
return 'vg-chat-inline-status--failed'
|
|
||||||
}
|
}
|
||||||
return 'vg-chat-inline-status--running'
|
return 'vg-chat-inline-status--running'
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,8 @@ public class ByteApiController extends BaseController {
|
||||||
|
|
||||||
aiOrder.setImg1(firstUrl.toString());
|
aiOrder.setImg1(firstUrl.toString());
|
||||||
ByteBodyReq byteBodyReq = new ByteBodyReq();
|
ByteBodyReq byteBodyReq = new ByteBodyReq();
|
||||||
byteBodyReq.setModel("ep-20251104104536-2gpgz");
|
byteBodyReq.setModel(StringUtils.isNotEmpty(request.getModel()) ?
|
||||||
|
request.getModel() : "ep-20260326165811-dlkth");
|
||||||
byteBodyReq.setPrompt(text);
|
byteBodyReq.setPrompt(text);
|
||||||
byteBodyReq.setImage(firstUrl);
|
byteBodyReq.setImage(firstUrl);
|
||||||
byteBodyReq.setSequential_image_generation("disabled");
|
byteBodyReq.setSequential_image_generation("disabled");
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
package com.ruoyi.api;
|
package com.ruoyi.api;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
|
||||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
import com.ruoyi.ai.domain.AiOrder;
|
import com.ruoyi.ai.domain.AiOrder;
|
||||||
|
|
@ -72,8 +72,77 @@ public class PortalVideoController extends BaseController {
|
||||||
return "21";
|
return "21";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyOptionalParams(ByteBodyReq body, PortalVideoGenRequest req) {
|
private List<PortalVideoProperties.ModelOption> loadModelOptionsForAiUser(Long aiUserId, Long secondDeptId) {
|
||||||
PortalVideoProperties.Defaults d = portalVideoProperties.getDefaults();
|
String json = byteDeptApiKeyService.resolveSecondLevelModelParm(aiUserId);
|
||||||
|
List<PortalVideoProperties.ModelOption> fromDb = parseModelParmJson(json);
|
||||||
|
if (fromDb != null && !fromDb.isEmpty()) {
|
||||||
|
return fromDb;
|
||||||
|
}
|
||||||
|
return portalVideoProperties.resolveModelsForSecondDept(secondDeptId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<PortalVideoProperties.ModelOption> parseModelParmJson(String json) {
|
||||||
|
if (StringUtils.isEmpty(json)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
List<PortalVideoProperties.ModelOption> list = OM.readValue(json.trim(),
|
||||||
|
new TypeReference<List<PortalVideoProperties.ModelOption>>() { });
|
||||||
|
if (list == null || list.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
List<PortalVideoProperties.ModelOption> out = new ArrayList<>();
|
||||||
|
for (PortalVideoProperties.ModelOption o : list) {
|
||||||
|
if (o != null && StringUtils.isNotEmpty(o.getLabel()) && StringUtils.isNotEmpty(o.getValue())) {
|
||||||
|
out.add(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out.isEmpty() ? null : out;
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.warn("解析二级部门 model_parm 失败: {}", e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isModelInOptions(String modelId, List<PortalVideoProperties.ModelOption> options) {
|
||||||
|
if (modelId == null || modelId.isEmpty() || options == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (PortalVideoProperties.ModelOption o : options) {
|
||||||
|
if (modelId.equals(o.getValue())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void alignDefaultsModelToOptions(PortalVideoProperties.Defaults defs, List<PortalVideoProperties.ModelOption> models) {
|
||||||
|
if (defs == null || models == null || models.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String m = defs.getModel();
|
||||||
|
if (m == null || m.isEmpty()) {
|
||||||
|
defs.setModel(models.get(0).getValue());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!isModelInOptions(m, models)) {
|
||||||
|
defs.setModel(models.get(0).getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String resolveDefaultModelForAiUser(Long aiUserId, Long secondDeptId, List<PortalVideoProperties.ModelOption> allowed) {
|
||||||
|
PortalVideoProperties.Defaults d = portalVideoProperties.resolveEffectiveDefaults(secondDeptId);
|
||||||
|
if (d.getModel() != null && !d.getModel().isEmpty() && isModelInOptions(d.getModel(), allowed)) {
|
||||||
|
return d.getModel();
|
||||||
|
}
|
||||||
|
if (!allowed.isEmpty() && StringUtils.isNotEmpty(allowed.get(0).getValue())) {
|
||||||
|
return allowed.get(0).getValue();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyOptionalParams(ByteBodyReq body, PortalVideoGenRequest req, Long secondDeptId) {
|
||||||
|
PortalVideoProperties.Defaults d = portalVideoProperties.resolveEffectiveDefaults(secondDeptId);
|
||||||
body.setDuration(req.getDuration() != null ? req.getDuration() : d.getDuration());
|
body.setDuration(req.getDuration() != null ? req.getDuration() : d.getDuration());
|
||||||
body.setResolution(StringUtils.isNotEmpty(req.getResolution()) ? req.getResolution() : d.getResolution());
|
body.setResolution(StringUtils.isNotEmpty(req.getResolution()) ? req.getResolution() : d.getResolution());
|
||||||
body.setRatio(StringUtils.isNotEmpty(req.getRatio()) ? req.getRatio() : d.getRatio());
|
body.setRatio(StringUtils.isNotEmpty(req.getRatio()) ? req.getRatio() : d.getRatio());
|
||||||
|
|
@ -83,14 +152,20 @@ public class PortalVideoController extends BaseController {
|
||||||
}
|
}
|
||||||
|
|
||||||
private ByteBodyReq newVideoBody(PortalVideoGenRequest req, List<ContentItem> content) {
|
private ByteBodyReq newVideoBody(PortalVideoGenRequest req, List<ContentItem> content) {
|
||||||
String modelId = StringUtils.isNotEmpty(req.getModel()) ? req.getModel() : portalVideoProperties.resolveDefaultModelId();
|
Long uid = SecurityUtils.getAiUserId();
|
||||||
|
Long secondDeptId = byteDeptApiKeyService.resolveSecondLevelDeptId(uid);
|
||||||
|
List<PortalVideoProperties.ModelOption> allowed = loadModelOptionsForAiUser(uid, secondDeptId);
|
||||||
|
String modelId = StringUtils.isNotEmpty(req.getModel()) ? req.getModel() : resolveDefaultModelForAiUser(uid, secondDeptId, allowed);
|
||||||
if (StringUtils.isEmpty(modelId)) {
|
if (StringUtils.isEmpty(modelId)) {
|
||||||
throw new ServiceException("未配置门户视频模型,请在 application.yml 的 portal.video 中配置 models 与 defaults.model");
|
throw new ServiceException("未配置门户视频模型:请在后台为该用户所属二级部门配置 model_parm,或在 portal.video.models 中配置全局列表");
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotEmpty(req.getModel()) && !isModelInOptions(modelId, allowed)) {
|
||||||
|
throw new ServiceException("所选模型对当前部门不可用");
|
||||||
}
|
}
|
||||||
ByteBodyReq body = new ByteBodyReq();
|
ByteBodyReq body = new ByteBodyReq();
|
||||||
body.setModel(modelId);
|
body.setModel(modelId);
|
||||||
body.setContent(content);
|
body.setContent(content);
|
||||||
applyOptionalParams(body, req);
|
applyOptionalParams(body, req, secondDeptId);
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -405,9 +480,14 @@ public class PortalVideoController extends BaseController {
|
||||||
@GetMapping("/options")
|
@GetMapping("/options")
|
||||||
@ApiOperation("门户视频生成可选参数(模型/比例/时长等,来自配置)")
|
@ApiOperation("门户视频生成可选参数(模型/比例/时长等,来自配置)")
|
||||||
public AjaxResult videoParamOptions() {
|
public AjaxResult videoParamOptions() {
|
||||||
|
Long uid = SecurityUtils.getAiUserId();
|
||||||
|
Long secondDeptId = byteDeptApiKeyService.resolveSecondLevelDeptId(uid);
|
||||||
|
List<PortalVideoProperties.ModelOption> models = loadModelOptionsForAiUser(uid, secondDeptId);
|
||||||
|
PortalVideoProperties.Defaults defs = portalVideoProperties.resolveEffectiveDefaults(secondDeptId);
|
||||||
|
alignDefaultsModelToOptions(defs, models);
|
||||||
Map<String, Object> data = new LinkedHashMap<>();
|
Map<String, Object> data = new LinkedHashMap<>();
|
||||||
data.put("defaults", portalVideoProperties.getDefaults());
|
data.put("defaults", defs);
|
||||||
data.put("models", portalVideoProperties.getModels());
|
data.put("models", models);
|
||||||
data.put("ratios", portalVideoProperties.getRatios());
|
data.put("ratios", portalVideoProperties.getRatios());
|
||||||
data.put("durations", portalVideoProperties.getDurations());
|
data.put("durations", portalVideoProperties.getDurations());
|
||||||
data.put("resolutions", portalVideoProperties.getResolutions());
|
data.put("resolutions", portalVideoProperties.getResolutions());
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 门户视频生成参数(模型、比例、时长、分辨率等从配置读取,不在代码中写死业务默认值)。
|
* 门户视频生成参数(模型、比例、时长、分辨率等从配置读取,不在代码中写死业务默认值)。
|
||||||
|
|
@ -17,6 +19,16 @@ public class PortalVideoProperties {
|
||||||
|
|
||||||
private List<ModelOption> models = new ArrayList<>();
|
private List<ModelOption> models = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按二级部门 {@code dept_id}(字符串,如 {@code "101"})配置专属模型列表;未命中时使用全局 {@link #models}。
|
||||||
|
*/
|
||||||
|
private Map<String, List<ModelOption>> modelsBySecondDept = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按二级部门覆盖 {@link #defaults} 中的字段;仅配置需要覆盖的项即可。
|
||||||
|
*/
|
||||||
|
private Map<String, Defaults> defaultsBySecondDept = new LinkedHashMap<>();
|
||||||
|
|
||||||
private List<String> ratios = new ArrayList<>();
|
private List<String> ratios = new ArrayList<>();
|
||||||
|
|
||||||
private List<Integer> durations = new ArrayList<>();
|
private List<Integer> durations = new ArrayList<>();
|
||||||
|
|
@ -54,6 +66,22 @@ public class PortalVideoProperties {
|
||||||
this.models = models != null ? models : new ArrayList<>();
|
this.models = models != null ? models : new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, List<ModelOption>> getModelsBySecondDept() {
|
||||||
|
return modelsBySecondDept;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModelsBySecondDept(Map<String, List<ModelOption>> modelsBySecondDept) {
|
||||||
|
this.modelsBySecondDept = modelsBySecondDept != null ? modelsBySecondDept : new LinkedHashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Defaults> getDefaultsBySecondDept() {
|
||||||
|
return defaultsBySecondDept;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefaultsBySecondDept(Map<String, Defaults> defaultsBySecondDept) {
|
||||||
|
this.defaultsBySecondDept = defaultsBySecondDept != null ? defaultsBySecondDept : new LinkedHashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
public List<String> getRatios() {
|
public List<String> getRatios() {
|
||||||
return ratios;
|
return ratios;
|
||||||
}
|
}
|
||||||
|
|
@ -91,6 +119,70 @@ public class PortalVideoProperties {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<ModelOption> resolveModelsForSecondDept(Long secondDeptId) {
|
||||||
|
if (secondDeptId != null) {
|
||||||
|
List<ModelOption> byDept = modelsBySecondDept.get(String.valueOf(secondDeptId));
|
||||||
|
if (byDept != null && !byDept.isEmpty()) {
|
||||||
|
return byDept;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return models;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Defaults resolveEffectiveDefaults(Long secondDeptId) {
|
||||||
|
Defaults out = new Defaults();
|
||||||
|
Defaults g = this.defaults;
|
||||||
|
out.setModel(g.getModel());
|
||||||
|
out.setDuration(g.getDuration());
|
||||||
|
out.setResolution(g.getResolution());
|
||||||
|
out.setRatio(g.getRatio());
|
||||||
|
if (secondDeptId != null) {
|
||||||
|
Defaults o = defaultsBySecondDept.get(String.valueOf(secondDeptId));
|
||||||
|
if (o != null) {
|
||||||
|
if (o.getModel() != null && !o.getModel().isEmpty()) {
|
||||||
|
out.setModel(o.getModel());
|
||||||
|
}
|
||||||
|
if (o.getDuration() != null) {
|
||||||
|
out.setDuration(o.getDuration());
|
||||||
|
}
|
||||||
|
if (o.getResolution() != null && !o.getResolution().isEmpty()) {
|
||||||
|
out.setResolution(o.getResolution());
|
||||||
|
}
|
||||||
|
if (o.getRatio() != null && !o.getRatio().isEmpty()) {
|
||||||
|
out.setRatio(o.getRatio());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在给定二级部门下,解析默认模型:先看合并后的 defaults.model,否则取该部门 models 列表首项。
|
||||||
|
*/
|
||||||
|
public String resolveDefaultModelIdForSecondDept(Long secondDeptId) {
|
||||||
|
Defaults d = resolveEffectiveDefaults(secondDeptId);
|
||||||
|
if (d.getModel() != null && !d.getModel().isEmpty()) {
|
||||||
|
return d.getModel();
|
||||||
|
}
|
||||||
|
List<ModelOption> m = resolveModelsForSecondDept(secondDeptId);
|
||||||
|
if (!m.isEmpty() && m.get(0).getValue() != null && !m.get(0).getValue().isEmpty()) {
|
||||||
|
return m.get(0).getValue();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isModelAllowedForSecondDept(String modelId, Long secondDeptId) {
|
||||||
|
if (modelId == null || modelId.isEmpty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (ModelOption opt : resolveModelsForSecondDept(secondDeptId)) {
|
||||||
|
if (modelId.equals(opt.getValue())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public static class Defaults {
|
public static class Defaults {
|
||||||
private String model;
|
private String model;
|
||||||
private Integer duration;
|
private Integer duration;
|
||||||
|
|
|
||||||
|
|
@ -261,6 +261,8 @@ portal:
|
||||||
value: ep-20260326165811-dlkth
|
value: ep-20260326165811-dlkth
|
||||||
- label: Seedance 2.0 Fast
|
- label: Seedance 2.0 Fast
|
||||||
value: ep-20260326170056-dkj9m
|
value: ep-20260326170056-dkj9m
|
||||||
|
# 可选:按二级部门 dept_id 覆盖 YAML(仅当库表 sys_dept.model_parm 为空时才会用到)
|
||||||
|
# models-by-second-dept / defaults-by-second-dept 见 PortalVideoProperties 说明
|
||||||
ratios:
|
ratios:
|
||||||
- "16:9"
|
- "16:9"
|
||||||
- "9:16"
|
- "9:16"
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,9 @@ public class SysDept extends BaseEntity
|
||||||
/** Byte API Key */
|
/** Byte API Key */
|
||||||
private String byteApiKey;
|
private String byteApiKey;
|
||||||
|
|
||||||
|
/** 门户视频模型列表 JSON:[{"label":"…","value":"ep-…"},…] */
|
||||||
|
private String modelParm;
|
||||||
|
|
||||||
/** Byte project */
|
/** Byte project */
|
||||||
private String project;
|
private String project;
|
||||||
|
|
||||||
|
|
@ -187,6 +190,16 @@ public class SysDept extends BaseEntity
|
||||||
this.byteApiKey = byteApiKey;
|
this.byteApiKey = byteApiKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getModelParm()
|
||||||
|
{
|
||||||
|
return modelParm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModelParm(String modelParm)
|
||||||
|
{
|
||||||
|
this.modelParm = modelParm;
|
||||||
|
}
|
||||||
|
|
||||||
public String getProject()
|
public String getProject()
|
||||||
{
|
{
|
||||||
return project;
|
return project;
|
||||||
|
|
@ -219,6 +232,7 @@ public class SysDept extends BaseEntity
|
||||||
.append("phone", getPhone())
|
.append("phone", getPhone())
|
||||||
.append("email", getEmail())
|
.append("email", getEmail())
|
||||||
.append("byteApiKey", getByteApiKey())
|
.append("byteApiKey", getByteApiKey())
|
||||||
|
.append("modelParm", getModelParm())
|
||||||
.append("project", getProject())
|
.append("project", getProject())
|
||||||
.append("status", getStatus())
|
.append("status", getStatus())
|
||||||
.append("delFlag", getDelFlag())
|
.append("delFlag", getDelFlag())
|
||||||
|
|
|
||||||
|
|
@ -9,4 +9,15 @@ public interface IByteDeptApiKeyService {
|
||||||
* Redis 键:{userId}_byte_api_key,优先读缓存,再读库;均无有效 key 则抛出业务异常。
|
* Redis 键:{userId}_byte_api_key,优先读缓存,再读库;均无有效 key 则抛出业务异常。
|
||||||
*/
|
*/
|
||||||
String resolveVolcApiKey(Long aiUserId);
|
String resolveVolcApiKey(Long aiUserId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前 AI 用户所属二级部门 {@code sys_dept.dept_id}(与 {@link #resolveVolcApiKey(Long)} 中使用的二级节点一致)。
|
||||||
|
* 用户未分配部门或部门数据缺失时返回 null。
|
||||||
|
*/
|
||||||
|
Long resolveSecondLevelDeptId(Long aiUserId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前用户所属二级部门 {@code sys_dept.model_parm}(JSON 模型列表);未配置或为空时返回 null。
|
||||||
|
*/
|
||||||
|
String resolveSecondLevelModelParm(Long aiUserId);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -149,13 +149,23 @@ public class AiUserServiceImpl implements IAiUserService {
|
||||||
public int updateAiUser(AiUser aiUser) {
|
public int updateAiUser(AiUser aiUser) {
|
||||||
aiUser.setUpdateTime(DateUtils.getNowDate());
|
aiUser.setUpdateTime(DateUtils.getNowDate());
|
||||||
if (StringUtils.isNotEmpty(aiUser.getPassword())) {
|
if (StringUtils.isNotEmpty(aiUser.getPassword())) {
|
||||||
|
// 登录后 update 常带上库里的 BCrypt 密文;勿对密文再 encrypt,否则第二次登录永远密码错误
|
||||||
|
if (!isBcryptPasswordHash(aiUser.getPassword())) {
|
||||||
aiUser.setPassword(SecurityUtils.encryptPassword(aiUser.getPassword()));
|
aiUser.setPassword(SecurityUtils.encryptPassword(aiUser.getPassword()));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
aiUser.setPassword(null);
|
aiUser.setPassword(null);
|
||||||
}
|
}
|
||||||
return aiUserMapper.updateById(aiUser);
|
return aiUserMapper.updateById(aiUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isBcryptPasswordHash(String password) {
|
||||||
|
if (password == null || password.length() < 4) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return password.startsWith("$2a$") || password.startsWith("$2b$") || password.startsWith("$2y$");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int countAiUserByDeptId(Long deptId) {
|
public int countAiUserByDeptId(Long deptId) {
|
||||||
if (deptId == null) {
|
if (deptId == null) {
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ public class ByteDeptApiKeyServiceImpl implements IByteDeptApiKeyService {
|
||||||
// 优先使用用户直接归属部门的 Key;多数业务把用户挂在分公司(如 101)并在该节点配 byte_api_key
|
// 优先使用用户直接归属部门的 Key;多数业务把用户挂在分公司(如 101)并在该节点配 byte_api_key
|
||||||
String apiKey = trimKey(userDept.getByteApiKey());
|
String apiKey = trimKey(userDept.getByteApiKey());
|
||||||
if (StringUtils.isEmpty(apiKey)) {
|
if (StringUtils.isEmpty(apiKey)) {
|
||||||
Long fallbackDeptId = resolveSecondLevelDeptId(userDept);
|
Long fallbackDeptId = secondLevelDeptIdFrom(userDept);
|
||||||
if (!fallbackDeptId.equals(userDept.getDeptId())) {
|
if (!fallbackDeptId.equals(userDept.getDeptId())) {
|
||||||
SysDept keyDept = sysDeptService.selectDeptById(fallbackDeptId);
|
SysDept keyDept = sysDeptService.selectDeptById(fallbackDeptId);
|
||||||
if (keyDept != null) {
|
if (keyDept != null) {
|
||||||
|
|
@ -75,6 +75,39 @@ public class ByteDeptApiKeyServiceImpl implements IByteDeptApiKeyService {
|
||||||
return apiKey;
|
return apiKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long resolveSecondLevelDeptId(Long aiUserId) {
|
||||||
|
if (aiUserId == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
AiUser aiUser = aiUserService.selectAiUserById(aiUserId);
|
||||||
|
if (aiUser == null || aiUser.getDeptId() == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
SysDept userDept = sysDeptService.selectDeptById(aiUser.getDeptId());
|
||||||
|
if (userDept == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return secondLevelDeptIdFrom(userDept);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String resolveSecondLevelModelParm(Long aiUserId) {
|
||||||
|
Long secondId = resolveSecondLevelDeptId(aiUserId);
|
||||||
|
if (secondId == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
SysDept second = sysDeptService.selectDeptById(secondId);
|
||||||
|
if (second == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String raw = second.getModelParm();
|
||||||
|
if (StringUtils.isEmpty(raw)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return raw.trim();
|
||||||
|
}
|
||||||
|
|
||||||
private static String trimKey(String raw) {
|
private static String trimKey(String raw) {
|
||||||
return raw == null ? null : raw.trim();
|
return raw == null ? null : raw.trim();
|
||||||
}
|
}
|
||||||
|
|
@ -83,7 +116,7 @@ public class ByteDeptApiKeyServiceImpl implements IByteDeptApiKeyService {
|
||||||
* 二级部门:祖级路径中,紧接在「一级」(ancestors 第二段)之下的部门节点;
|
* 二级部门:祖级路径中,紧接在「一级」(ancestors 第二段)之下的部门节点;
|
||||||
* 深度不足时退回用户当前部门。
|
* 深度不足时退回用户当前部门。
|
||||||
*/
|
*/
|
||||||
private Long resolveSecondLevelDeptId(SysDept userDept) {
|
private Long secondLevelDeptIdFrom(SysDept userDept) {
|
||||||
String ancestors = userDept.getAncestors();
|
String ancestors = userDept.getAncestors();
|
||||||
if (StringUtils.isEmpty(ancestors)) {
|
if (StringUtils.isEmpty(ancestors)) {
|
||||||
return userDept.getDeptId();
|
return userDept.getDeptId();
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<result property="phone" column="phone" />
|
<result property="phone" column="phone" />
|
||||||
<result property="email" column="email" />
|
<result property="email" column="email" />
|
||||||
<result property="byteApiKey" column="byte_api_key" />
|
<result property="byteApiKey" column="byte_api_key" />
|
||||||
|
<result property="modelParm" column="model_parm" />
|
||||||
<result property="status" column="status" />
|
<result property="status" column="status" />
|
||||||
<result property="delFlag" column="del_flag" />
|
<result property="delFlag" column="del_flag" />
|
||||||
<result property="parentName" column="parent_name" />
|
<result property="parentName" column="parent_name" />
|
||||||
|
|
@ -61,7 +62,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="selectDeptById" parameterType="Long" resultMap="SysDeptResult">
|
<select id="selectDeptById" parameterType="Long" resultMap="SysDeptResult">
|
||||||
select d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.phone, d.email, d.byte_api_key, d.status, d.project,
|
select d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.phone, d.email, d.byte_api_key, d.model_parm, d.status, d.project,
|
||||||
(select dept_name from sys_dept where dept_id = d.parent_id) parent_name
|
(select dept_name from sys_dept where dept_id = d.parent_id) parent_name
|
||||||
from sys_dept d
|
from sys_dept d
|
||||||
where d.dept_id = #{deptId}
|
where d.dept_id = #{deptId}
|
||||||
|
|
@ -104,6 +105,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<if test="phone != null and phone != ''">phone,</if>
|
<if test="phone != null and phone != ''">phone,</if>
|
||||||
<if test="email != null and email != ''">email,</if>
|
<if test="email != null and email != ''">email,</if>
|
||||||
<if test="byteApiKey != null">byte_api_key,</if>
|
<if test="byteApiKey != null">byte_api_key,</if>
|
||||||
|
<if test="modelParm != null">model_parm,</if>
|
||||||
<if test="project != null">project,</if>
|
<if test="project != null">project,</if>
|
||||||
<if test="status != null">status,</if>
|
<if test="status != null">status,</if>
|
||||||
<if test="createBy != null and createBy != ''">create_by,</if>
|
<if test="createBy != null and createBy != ''">create_by,</if>
|
||||||
|
|
@ -118,6 +120,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<if test="phone != null and phone != ''">#{phone},</if>
|
<if test="phone != null and phone != ''">#{phone},</if>
|
||||||
<if test="email != null and email != ''">#{email},</if>
|
<if test="email != null and email != ''">#{email},</if>
|
||||||
<if test="byteApiKey != null">#{byteApiKey},</if>
|
<if test="byteApiKey != null">#{byteApiKey},</if>
|
||||||
|
<if test="modelParm != null">#{modelParm},</if>
|
||||||
<if test="project != null">#{project},</if>
|
<if test="project != null">#{project},</if>
|
||||||
<if test="status != null">#{status},</if>
|
<if test="status != null">#{status},</if>
|
||||||
<if test="createBy != null and createBy != ''">#{createBy},</if>
|
<if test="createBy != null and createBy != ''">#{createBy},</if>
|
||||||
|
|
@ -136,6 +139,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
<if test="phone != null">phone = #{phone},</if>
|
<if test="phone != null">phone = #{phone},</if>
|
||||||
<if test="email != null">email = #{email},</if>
|
<if test="email != null">email = #{email},</if>
|
||||||
<if test="byteApiKey != null">byte_api_key = #{byteApiKey},</if>
|
<if test="byteApiKey != null">byte_api_key = #{byteApiKey},</if>
|
||||||
|
<if test="modelParm != null">model_parm = #{modelParm},</if>
|
||||||
<if test="project != null">project = #{project},</if>
|
<if test="project != null">project = #{project},</if>
|
||||||
<if test="status != null and status != ''">status = #{status},</if>
|
<if test="status != null and status != ''">status = #{status},</if>
|
||||||
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
|
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue