|
|
@@ -16,98 +16,124 @@
|
|
|
:rules="rules"
|
|
|
label-width="160px"
|
|
|
>
|
|
|
- <el-divider content-position="left">飘屏</el-divider>
|
|
|
- <el-form-item label="飘屏总开关" prop="floatEnabled">
|
|
|
- <el-switch
|
|
|
- v-model="form.floatEnabled"
|
|
|
- :active-value="1"
|
|
|
- :inactive-value="0"
|
|
|
- />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="用户飘屏冷却" prop="floatCooldownSec">
|
|
|
- <el-input-number
|
|
|
- v-model="form.floatCooldownSec"
|
|
|
- :min="0"
|
|
|
- :precision="0"
|
|
|
- controls-position="right"
|
|
|
- placeholder="秒"
|
|
|
- />
|
|
|
- <span class="form-tip">同一用户连续飘屏的最小间隔(秒)</span>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="可飘屏角色" prop="floatRoleCodes">
|
|
|
- <el-select
|
|
|
- v-model="floatRoleList"
|
|
|
- multiple
|
|
|
- filterable
|
|
|
- placeholder="请选择角色"
|
|
|
- style="width: 420px"
|
|
|
- :loading="rolesLoading"
|
|
|
- @visible-change="ensureRolesLoaded"
|
|
|
- >
|
|
|
- <el-option
|
|
|
- v-for="r in roleOptions"
|
|
|
- :key="r"
|
|
|
- :label="r"
|
|
|
- :value="r"
|
|
|
+ <div class="feature-section section-threshold">
|
|
|
+ <el-divider content-position="left">库存提示阈值</el-divider>
|
|
|
+ <el-form-item label="阈值配置">
|
|
|
+ <el-input
|
|
|
+ v-model.trim="thresholdInput"
|
|
|
+ placeholder="请输入1~9999"
|
|
|
+ style="width: 220px"
|
|
|
+ @keyup.enter.native="saveStockThreshold"
|
|
|
/>
|
|
|
- </el-select>
|
|
|
- <span class="form-tip">选项来自企业角色;保存为英文逗号分隔的 role_name</span>
|
|
|
- </el-form-item>
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ size="mini"
|
|
|
+ :loading="thresholdSaving"
|
|
|
+ style="margin-left: 12px"
|
|
|
+ @click="saveStockThreshold"
|
|
|
+ >保存</el-button>
|
|
|
+ <span class="form-tip">当库存小于等于该阈值时,App端显示“仅剩X件”。</span>
|
|
|
+ </el-form-item>
|
|
|
+ </div>
|
|
|
|
|
|
- <el-divider content-position="left">评论置顶</el-divider>
|
|
|
- <el-form-item label="单房间最大置顶数" prop="pinMaxPerRoom">
|
|
|
- <el-input-number
|
|
|
- v-model="form.pinMaxPerRoom"
|
|
|
- :min="1"
|
|
|
- :precision="0"
|
|
|
- controls-position="right"
|
|
|
- />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="可选置顶时长" prop="pinDurationOptions">
|
|
|
- <el-select
|
|
|
- v-model="pinDurationList"
|
|
|
- multiple
|
|
|
- placeholder="分钟;-1 表示永久"
|
|
|
- style="width: 420px"
|
|
|
- >
|
|
|
- <el-option label="5 分钟" :value="5" />
|
|
|
- <el-option label="10 分钟" :value="10" />
|
|
|
- <el-option label="15 分钟" :value="15" />
|
|
|
- <el-option label="30 分钟" :value="30" />
|
|
|
- <el-option label="60 分钟" :value="60" />
|
|
|
- <el-option label="永久 (-1)" :value="-1" />
|
|
|
- </el-select>
|
|
|
- <span class="form-tip">保存为逗号分隔数字,如 5,10,30,-1</span>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="可置顶角色" prop="pinRoleCodes">
|
|
|
- <el-select
|
|
|
- v-model="pinRoleList"
|
|
|
- multiple
|
|
|
- filterable
|
|
|
- placeholder="请选择角色"
|
|
|
- style="width: 420px"
|
|
|
- :loading="rolesLoading"
|
|
|
- @visible-change="ensureRolesLoaded"
|
|
|
- >
|
|
|
- <el-option
|
|
|
- v-for="r in roleOptions"
|
|
|
- :key="r"
|
|
|
- :label="r"
|
|
|
- :value="r"
|
|
|
+ <div class="feature-section section-float">
|
|
|
+ <el-divider content-position="left">飘屏</el-divider>
|
|
|
+ <el-form-item label="飘屏总开关" prop="floatEnabled">
|
|
|
+ <el-switch
|
|
|
+ v-model="form.floatEnabled"
|
|
|
+ :active-value="1"
|
|
|
+ :inactive-value="0"
|
|
|
/>
|
|
|
- </el-select>
|
|
|
- </el-form-item>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="用户飘屏冷却" prop="floatCooldownSec">
|
|
|
+ <el-input-number
|
|
|
+ v-model="form.floatCooldownSec"
|
|
|
+ :min="0"
|
|
|
+ :precision="0"
|
|
|
+ controls-position="right"
|
|
|
+ placeholder="秒"
|
|
|
+ />
|
|
|
+ <span class="form-tip">同一用户连续飘屏的最小间隔(秒)</span>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="可飘屏角色" prop="floatRoleCodes">
|
|
|
+ <el-select
|
|
|
+ v-model="floatRoleList"
|
|
|
+ multiple
|
|
|
+ filterable
|
|
|
+ placeholder="请选择角色"
|
|
|
+ style="width: 420px"
|
|
|
+ :loading="rolesLoading"
|
|
|
+ @visible-change="ensureRolesLoaded"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="r in roleOptions"
|
|
|
+ :key="r"
|
|
|
+ :label="r"
|
|
|
+ :value="r"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ <span class="form-tip">选项来自企业角色;保存为英文逗号分隔的 role_name</span>
|
|
|
+ </el-form-item>
|
|
|
+ </div>
|
|
|
|
|
|
- <el-divider content-position="left">其他</el-divider>
|
|
|
- <el-form-item label="备注" prop="remark">
|
|
|
- <el-input v-model="form.remark" type="textarea" :rows="2" placeholder="备注" />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="最近更新人">
|
|
|
- <span>{{ form.updateBy || '—' }}</span>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="最近更新时间">
|
|
|
- <span>{{ form.updateTime ? parseTime(form.updateTime) : '—' }}</span>
|
|
|
- </el-form-item>
|
|
|
+ <div class="feature-section section-pin">
|
|
|
+ <el-divider content-position="left">评论置顶</el-divider>
|
|
|
+ <el-form-item label="单房间最大置顶数" prop="pinMaxPerRoom">
|
|
|
+ <el-input-number
|
|
|
+ v-model="form.pinMaxPerRoom"
|
|
|
+ :min="1"
|
|
|
+ :precision="0"
|
|
|
+ controls-position="right"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="可选置顶时长" prop="pinDurationOptions">
|
|
|
+ <el-select
|
|
|
+ v-model="pinDurationList"
|
|
|
+ multiple
|
|
|
+ placeholder="分钟;-1 表示永久"
|
|
|
+ style="width: 420px"
|
|
|
+ >
|
|
|
+ <el-option label="5 分钟" :value="5" />
|
|
|
+ <el-option label="10 分钟" :value="10" />
|
|
|
+ <el-option label="15 分钟" :value="15" />
|
|
|
+ <el-option label="30 分钟" :value="30" />
|
|
|
+ <el-option label="60 分钟" :value="60" />
|
|
|
+ <el-option label="永久 (-1)" :value="-1" />
|
|
|
+ </el-select>
|
|
|
+ <span class="form-tip">保存为逗号分隔数字,如 5,10,30,-1</span>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="可置顶角色" prop="pinRoleCodes">
|
|
|
+ <el-select
|
|
|
+ v-model="pinRoleList"
|
|
|
+ multiple
|
|
|
+ filterable
|
|
|
+ placeholder="请选择角色"
|
|
|
+ style="width: 420px"
|
|
|
+ :loading="rolesLoading"
|
|
|
+ @visible-change="ensureRolesLoaded"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="r in roleOptions"
|
|
|
+ :key="r"
|
|
|
+ :label="r"
|
|
|
+ :value="r"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="feature-section section-other">
|
|
|
+ <el-divider content-position="left">其他</el-divider>
|
|
|
+ <el-form-item label="备注" prop="remark">
|
|
|
+ <el-input v-model="form.remark" type="textarea" :rows="2" placeholder="备注" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="最近更新人">
|
|
|
+ <span>{{ form.updateBy || '—' }}</span>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="最近更新时间">
|
|
|
+ <span>{{ form.updateTime ? parseTime(form.updateTime) : '—' }}</span>
|
|
|
+ </el-form-item>
|
|
|
+ </div>
|
|
|
<el-form-item>
|
|
|
<el-button
|
|
|
type="primary"
|
|
|
@@ -128,6 +154,7 @@ import {
|
|
|
updateCommentFeatureConfig,
|
|
|
getCommentFeatureRoles
|
|
|
} from '@/api/live/commentFeature'
|
|
|
+import { getStockHintThreshold, updateStockHintThreshold } from '@/api/live/liveGoods'
|
|
|
|
|
|
const splitCodes = (s) => {
|
|
|
if (s == null || String(s).trim() === '') return []
|
|
|
@@ -145,6 +172,8 @@ export default {
|
|
|
return {
|
|
|
loading: false,
|
|
|
saving: false,
|
|
|
+ thresholdSaving: false,
|
|
|
+ thresholdInput: '',
|
|
|
/** 下拉候选项(GET /live/commentFeature/roles),并与已选值合并以便回显 */
|
|
|
roleOptions: [],
|
|
|
rolesLoaded: false,
|
|
|
@@ -172,8 +201,40 @@ export default {
|
|
|
},
|
|
|
created() {
|
|
|
this.loadConfig()
|
|
|
+ this.loadStockThreshold()
|
|
|
},
|
|
|
methods: {
|
|
|
+ isValidThreshold(value) {
|
|
|
+ return /^[1-9]\d{0,3}$/.test(String(value))
|
|
|
+ },
|
|
|
+ loadStockThreshold() {
|
|
|
+ getStockHintThreshold()
|
|
|
+ .then((response) => {
|
|
|
+ const threshold = response && response.threshold
|
|
|
+ this.thresholdInput = threshold != null ? String(threshold) : ''
|
|
|
+ })
|
|
|
+ .catch((error) => {
|
|
|
+ this.$message.error((error && error.msg) || (error && error.message) || '阈值加载失败')
|
|
|
+ })
|
|
|
+ },
|
|
|
+ saveStockThreshold() {
|
|
|
+ if (!this.isValidThreshold(this.thresholdInput)) {
|
|
|
+ this.$message.error('阈值范围需在1~9999')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.thresholdSaving = true
|
|
|
+ updateStockHintThreshold(Number(this.thresholdInput))
|
|
|
+ .then(() => {
|
|
|
+ this.msgSuccess('保存成功')
|
|
|
+ this.loadStockThreshold()
|
|
|
+ })
|
|
|
+ .catch((error) => {
|
|
|
+ this.$message.error((error && error.msg) || (error && error.message) || '保存失败')
|
|
|
+ })
|
|
|
+ .finally(() => {
|
|
|
+ this.thresholdSaving = false
|
|
|
+ })
|
|
|
+ },
|
|
|
/** 将已选 role_name 合并进 options,避免接口未返回历史已选项时标签不显示 */
|
|
|
mergeSelectedIntoRoleOptions() {
|
|
|
const set = new Set(Array.isArray(this.roleOptions) ? this.roleOptions : [])
|
|
|
@@ -278,4 +339,27 @@ export default {
|
|
|
color: #909399;
|
|
|
font-size: 12px;
|
|
|
}
|
|
|
+.feature-section {
|
|
|
+ padding: 10px 12px 4px;
|
|
|
+ margin-bottom: 14px;
|
|
|
+ border-radius: 6px;
|
|
|
+ border: 1px solid #ebeef5;
|
|
|
+ background: #fafafa;
|
|
|
+}
|
|
|
+.section-threshold {
|
|
|
+ border-left: 4px solid #e6a23c;
|
|
|
+ background: #fffaf2;
|
|
|
+}
|
|
|
+.section-float {
|
|
|
+ border-left: 4px solid #409eff;
|
|
|
+ background: #f4f8ff;
|
|
|
+}
|
|
|
+.section-pin {
|
|
|
+ border-left: 4px solid #67c23a;
|
|
|
+ background: #f6fcf2;
|
|
|
+}
|
|
|
+.section-other {
|
|
|
+ border-left: 4px solid #909399;
|
|
|
+ background: #f8f8f9;
|
|
|
+}
|
|
|
</style>
|