修改套餐状态
This commit is contained in:
+10
-2
@@ -152,15 +152,23 @@ public class PriceSetController extends BaseController
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:set:audit')")
|
||||
@Log(title = "价格套餐停用", businessType = BusinessType.UPDATE)
|
||||
@Log(title = "Price set disable", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/disable/{priceSetId}")
|
||||
public AjaxResult disable(@PathVariable Long priceSetId)
|
||||
{
|
||||
return toAjax(priceSetService.disable(priceSetId, getUsername()));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:set:audit')")
|
||||
@Log(title = "Price set enable", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/enable/{priceSetId}")
|
||||
public AjaxResult enable(@PathVariable Long priceSetId)
|
||||
{
|
||||
return toAjax(priceSetService.enable(priceSetId, getUsername()));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:set:add')")
|
||||
@Log(title = "价格套餐复用", businessType = BusinessType.INSERT)
|
||||
@Log(title = "Price set copy", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/copy/{priceSetId}")
|
||||
public AjaxResult copy(@PathVariable Long priceSetId)
|
||||
{
|
||||
|
||||
@@ -54,12 +54,13 @@ price.set.name.exists=套餐名称已存在
|
||||
price.set.effectiveDate.empty=生效日期不能为空
|
||||
price.set.date.invalid=生效日期不能晚于失效日期
|
||||
price.set.discount.range=折扣模式默认折扣需在 1~99
|
||||
price.set.delete.statusNotAllowed=仅草稿或驳回状态的套餐允许删除:{0}
|
||||
price.set.delete.statusNotAllowed=仅待启用或驳回状态的套餐允许删除:{0}
|
||||
price.set.delete.boundCustomer=套餐【{0}】已绑定客户,请先解绑后再删除
|
||||
price.set.submit.statusNotAllowed=当前状态不允许提交审核
|
||||
price.set.approve.statusNotAllowed=仅审核中的套餐可以生效
|
||||
price.set.reject.statusNotAllowed=仅审核中的套餐可以驳回
|
||||
price.set.disable.statusNotAllowed=仅生效中的套餐可以停用
|
||||
price.set.disable.statusNotAllowed=仅生效中的套餐可停用
|
||||
price.set.enable.statusNotAllowed=套餐已是生效状态
|
||||
price.set.edit.audit=审核中的套餐不允许修改
|
||||
price.set.edit.stopped=已停用的套餐不允许修改,请使用复用新建
|
||||
price.set.childEdit.audit=审核中的套餐不允许改明细或客户
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@ public class BmsCustomerPriceSet extends BaseEntity
|
||||
/** 计价类型 FIXED=固定价 DISCOUNT=折扣 */
|
||||
private String setType;
|
||||
|
||||
/** 套餐状态 D草稿 A审核中 E生效 R驳回 S停用 */
|
||||
/** Package status D=pending-enable A=audit E=effective R=reject S=stopped */
|
||||
private String priceSetStatus;
|
||||
|
||||
/** 套餐生效日期 */
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ public class BmsPriceSetOption
|
||||
/** 计价类型 FIXED=固定价 DISCOUNT=折扣 */
|
||||
private String setType;
|
||||
|
||||
/** 套餐状态 D草稿 A审核中 E生效 R驳回 S停用 */
|
||||
/** Package status D=pending-enable A=audit E=effective R=reject S=stopped */
|
||||
private String status;
|
||||
|
||||
/** 生效日期 */
|
||||
|
||||
@@ -34,6 +34,9 @@ public interface IPrcPriceSetService
|
||||
|
||||
public int disable(Long priceSetId, String updateBy);
|
||||
|
||||
/** Re-enable a stopped package (S -> E). */
|
||||
public int enable(Long priceSetId, String updateBy);
|
||||
|
||||
/**
|
||||
* Activate a draft or reschedule a pending version with user-specified effectiveTime.
|
||||
* effectiveTime <= now -> EFFECT; future -> PENDING(3). Then refresh 0/3/1/2.
|
||||
|
||||
+18
@@ -49,6 +49,7 @@ import com.ruoyi.price.task.PrcPriceSetSaveAsyncRunner;
|
||||
@Service
|
||||
public class PrcPriceSetServiceImpl implements IPrcPriceSetService
|
||||
{
|
||||
/** Package status: D pending-enable / A audit / E effective / R reject / S stopped */
|
||||
private static final String STATUS_DRAFT = "D";
|
||||
private static final String STATUS_AUDIT = "A";
|
||||
private static final String STATUS_EFFECT = "E";
|
||||
@@ -271,6 +272,23 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
|
||||
return setMapper.updatePrcPriceSetStatus(upd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int enable(Long priceSetId, String updateBy)
|
||||
{
|
||||
PrcPriceSet db = requireSet(priceSetId);
|
||||
if (STATUS_EFFECT.equals(db.getStatus()))
|
||||
{
|
||||
throw new ServiceException(MessageUtils.message("price.set.enable.statusNotAllowed"));
|
||||
}
|
||||
PrcPriceSet upd = new PrcPriceSet();
|
||||
upd.setPriceSetId(priceSetId);
|
||||
upd.setStatus(STATUS_EFFECT);
|
||||
upd.setUpdateBy(updateBy);
|
||||
int rows = setMapper.updatePrcPriceSetStatus(upd);
|
||||
refreshVersionStatus(priceSetId);
|
||||
return rows;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public int activateVersion(Long psvId, Date effectiveTime, String updateBy)
|
||||
|
||||
+1
-1
@@ -272,7 +272,7 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService
|
||||
for (PrcCustomerPriceSet bind : binds)
|
||||
{
|
||||
PrcPriceSet set = priceSetMapper.selectPrcPriceSetById(bind.getPriceSetId());
|
||||
if (set == null || "S".equals(set.getStatus()))
|
||||
if (set == null || !"E".equals(set.getStatus()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -13,8 +13,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<result property="defaultDiscount" column="default_discount" />
|
||||
<result property="defaultType" column="default_type" />
|
||||
<result property="calculateSign" column="calculate_sign" />
|
||||
<result property="effectiveDate" column="effective_date" />
|
||||
<result property="expireDate" column="expire_date" />
|
||||
<result property="status" column="status" />
|
||||
<result property="tmsId" column="tms_id" />
|
||||
<result property="createBy" column="created_by" />
|
||||
@@ -28,7 +26,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<sql id="selectPrcPriceSetVo">
|
||||
select s.price_set_id, s.price_set_code, s.price_set_name, s.price_set_note,
|
||||
s.set_type, s.default_discount, s.default_type, s.calculate_sign,
|
||||
s.effective_date, s.expire_date, s.status, s.tms_id,
|
||||
s.status, s.tms_id,
|
||||
s.created_by, s.create_time, s.updated_by, s.update_time,
|
||||
(select count(distinct d.product_code) from prc_price_set_detail d where d.price_set_id = s.price_set_id) as product_count,
|
||||
(select count(1) from prc_customer_price_set c where c.price_set_id = s.price_set_id) as customer_count
|
||||
@@ -93,8 +91,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="defaultDiscount != null">default_discount,</if>
|
||||
<if test="defaultType != null">default_type,</if>
|
||||
<if test="calculateSign != null">calculate_sign,</if>
|
||||
<if test="effectiveDate != null">effective_date,</if>
|
||||
<if test="expireDate != null">expire_date,</if>
|
||||
<if test="status != null and status != ''">status,</if>
|
||||
<if test="tmsId != null">tms_id,</if>
|
||||
<if test="createBy != null and createBy != ''">created_by,</if>
|
||||
@@ -107,8 +103,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="defaultDiscount != null">#{defaultDiscount},</if>
|
||||
<if test="defaultType != null">#{defaultType},</if>
|
||||
<if test="calculateSign != null">#{calculateSign},</if>
|
||||
<if test="effectiveDate != null">#{effectiveDate},</if>
|
||||
<if test="expireDate != null">#{expireDate},</if>
|
||||
<if test="status != null and status != ''">#{status},</if>
|
||||
<if test="tmsId != null">#{tmsId},</if>
|
||||
<if test="createBy != null and createBy != ''">#{createBy},</if>
|
||||
@@ -126,8 +120,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
default_discount = #{defaultDiscount},
|
||||
<if test="defaultType != null">default_type = #{defaultType},</if>
|
||||
<if test="calculateSign != null">calculate_sign = #{calculateSign},</if>
|
||||
<if test="effectiveDate != null">effective_date = #{effectiveDate},</if>
|
||||
expire_date = #{expireDate},
|
||||
<if test="status != null and status != ''">status = #{status},</if>
|
||||
<if test="tmsId != null">tms_id = #{tmsId},</if>
|
||||
<if test="updateBy != null and updateBy != ''">updated_by = #{updateBy},</if>
|
||||
@@ -140,7 +132,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
update prc_price_set
|
||||
<set>
|
||||
status = #{status},
|
||||
<if test="effectiveDate != null">effective_date = #{effectiveDate},</if>
|
||||
<if test="updateBy != null and updateBy != ''">updated_by = #{updateBy},</if>
|
||||
update_time = sysdate()
|
||||
</set>
|
||||
|
||||
@@ -142,6 +142,13 @@ export function disablePriceSet(priceSetId) {
|
||||
})
|
||||
}
|
||||
|
||||
export function enablePriceSet(priceSetId) {
|
||||
return request({
|
||||
url: '/price/set/enable/' + priceSetId,
|
||||
method: 'put'
|
||||
})
|
||||
}
|
||||
|
||||
export function copyPriceSet(priceSetId) {
|
||||
return request({
|
||||
url: '/price/set/copy/' + priceSetId,
|
||||
|
||||
@@ -800,8 +800,8 @@ function removeProduct(productId) {
|
||||
|
||||
/* ---------------- 套餐绑定(prc_customer_price_set,一客户一套餐) ---------------- */
|
||||
const setTypeMap = { FIXED: '固定价', DISCOUNT: '折扣' }
|
||||
const priceSetStatusMap = { D: '草稿', A: '审核中', E: '生效', R: '驳回', S: '停用' }
|
||||
const priceSetStatusTagType = { D: 'info', A: 'warning', E: 'success', R: 'danger', S: 'info' }
|
||||
const priceSetStatusMap = { D: '待启用', A: '审核中', E: '生效', R: '驳回', S: '停用' }
|
||||
const priceSetStatusTagType = { D: 'warning', A: 'warning', E: 'success', R: 'danger', S: 'info' }
|
||||
|
||||
const boundPriceSets = ref([])
|
||||
const priceSetOptions = ref([])
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<div class="hd-line">
|
||||
<h2 class="hd-name">{{ set.priceSetName || '套餐详情' }}</h2>
|
||||
<span v-if="set.priceSetCode" class="hd-code">{{ set.priceSetCode }}</span>
|
||||
<el-tag :type="setStatusTagType(set)" size="small">{{ setStatusLabel(set) }}</el-tag>
|
||||
</div>
|
||||
<div class="hd-line hd-meta">
|
||||
<el-tag :type="isFixedType(set.setType) ? 'warning' : 'primary'" size="small" effect="plain">
|
||||
@@ -15,31 +16,31 @@
|
||||
<div class="hd-actions">
|
||||
<el-button @click="emit('back')">返回列表</el-button>
|
||||
<el-button
|
||||
v-if="set.status === 'E' && !set.expired"
|
||||
v-if="set.status === 'E'"
|
||||
type="danger"
|
||||
plain
|
||||
@click="emit('disable')"
|
||||
v-hasPermi="['price:set:audit']"
|
||||
>停用</el-button>
|
||||
<el-button
|
||||
v-else-if="set.status === 'S'"
|
||||
type="primary"
|
||||
v-if="set.status !== 'E'"
|
||||
type="success"
|
||||
plain
|
||||
@click="emit('copy')"
|
||||
v-hasPermi="['price:set:add']"
|
||||
>复用新建</el-button>
|
||||
@click="emit('enable')"
|
||||
v-hasPermi="['price:set:audit']"
|
||||
>启用</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="SetDetailHeader">
|
||||
import { isFixedType, setTypeLabel } from '../../utils/priceSet'
|
||||
import { isFixedType, setTypeLabel, setStatusLabel, setStatusTagType } from '../../utils/priceSet'
|
||||
|
||||
defineProps({
|
||||
set: { type: Object, required: true }
|
||||
})
|
||||
|
||||
const emit = defineEmits(['back', 'disable', 'copy'])
|
||||
const emit = defineEmits(['back', 'disable', 'enable'])
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<el-button @click="goBack">取消</el-button>
|
||||
<el-button v-if="active > 0 && !directStep2" @click="active--">上一步</el-button>
|
||||
<el-button v-if="active === 0" type="primary" :loading="creating" @click="goStep2">创建套餐价格</el-button>
|
||||
<el-button v-if="active === 0" type="info" :loading="saving" @click="saveDraft">保存草稿</el-button>
|
||||
<el-button v-if="active === 0" type="info" :loading="saving" @click="saveDraft">保存</el-button>
|
||||
<el-button v-if="active === 1" type="primary" @click="finishEdit">完成</el-button>
|
||||
</div>
|
||||
|
||||
@@ -199,7 +199,7 @@ async function saveDraft() {
|
||||
try {
|
||||
const priceSetId = await runSaveWithProgress(buildPayload())
|
||||
form.priceSetId = priceSetId
|
||||
proxy.$modal.msgSuccess('草稿已保存,套餐ID=' + priceSetId)
|
||||
proxy.$modal.msgSuccess('已保存(待启用),套餐ID=' + priceSetId)
|
||||
goBack()
|
||||
} catch (e) {
|
||||
// surfaced
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
:set="set"
|
||||
@back="goList"
|
||||
@disable="onDisable"
|
||||
@copy="onCopy"
|
||||
@enable="onEnable"
|
||||
/>
|
||||
|
||||
<set-basic-info-card :set="set" />
|
||||
@@ -77,7 +77,7 @@ import SetVersionDetailDrawer from './components/detail/SetVersionDetailDrawer.v
|
||||
import PriceEditPanel from './components/create/PriceEditPanel.vue'
|
||||
import { usePriceSetRefData } from './composables/usePriceSetRefData'
|
||||
import {
|
||||
getPriceSet, disablePriceSet, copyPriceSet, activatePriceSetVersion, copyPriceSetVersion, deletePriceSetVersion
|
||||
getPriceSet, disablePriceSet, enablePriceSet, activatePriceSetVersion, copyPriceSetVersion, deletePriceSetVersion
|
||||
} from '@/api/price/set'
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
@@ -121,6 +121,9 @@ function confirmAction(text, request, successText, done) {
|
||||
function onDisable() {
|
||||
confirmAction('停用后不再参与计费命中,确认停用?', () => disablePriceSet(set.value.priceSetId), '已停用')
|
||||
}
|
||||
function onEnable() {
|
||||
confirmAction('启用后套餐将重新参与计费命中,确认启用?', () => enablePriceSet(set.value.priceSetId), '已启用')
|
||||
}
|
||||
function formatNow() {
|
||||
const d = new Date()
|
||||
const p = n => String(n).padStart(2, '0')
|
||||
@@ -199,12 +202,6 @@ function submitActivate() {
|
||||
})
|
||||
})
|
||||
}
|
||||
function onCopy() {
|
||||
copyPriceSet(set.value.priceSetId).then(res => {
|
||||
proxy.$modal.msgSuccess('已复制为草稿')
|
||||
proxy.$router.push({ path: '/customer/setCreate', query: { priceSetId: res.data } })
|
||||
})
|
||||
}
|
||||
function onCopyVersion(row) {
|
||||
if (!row || row.psvId == null) return
|
||||
const hasDraft = (set.value.versions || []).some(v => v && String(v.status) === '0')
|
||||
|
||||
@@ -25,10 +25,6 @@
|
||||
</el-tag>
|
||||
</template>
|
||||
|
||||
<template #col-dateRange="{ row }">
|
||||
{{ formatDate(row.effectiveDate) }} ~ {{ row.expireDate ? formatDate(row.expireDate) : '长期' }}
|
||||
</template>
|
||||
|
||||
<template #col-status="{ row }">
|
||||
<el-tag :type="statusTag(row)" size="small">{{ statusLabel(row) }}</el-tag>
|
||||
</template>
|
||||
@@ -46,11 +42,19 @@
|
||||
<template #col-action="{ row }">
|
||||
<el-button link type="primary" @click="handleDetail(row)" v-hasPermi="['price:set:query']">详情</el-button>
|
||||
<el-button
|
||||
v-if="row.status === 'E'"
|
||||
link
|
||||
type="warning"
|
||||
@click="handleDisable(row)"
|
||||
v-hasPermi="['price:set:audit']"
|
||||
>停用</el-button>
|
||||
<el-button
|
||||
v-if="row.status === 'D' || row.status === 'S'"
|
||||
link
|
||||
type="success"
|
||||
@click="handleEnable(row)"
|
||||
v-hasPermi="['price:set:audit']"
|
||||
>启用</el-button>
|
||||
</template>
|
||||
</basic-table>
|
||||
|
||||
@@ -65,10 +69,10 @@
|
||||
|
||||
<script setup name="PriceSet">
|
||||
import {
|
||||
listPriceSet, disablePriceSet, copyPriceSet, getPriceSet
|
||||
listPriceSet, disablePriceSet, enablePriceSet, copyPriceSet, getPriceSet
|
||||
} from '@/api/price/set'
|
||||
import { parseTime } from '@/utils/ruoyi'
|
||||
import SetVersionDetailDrawer from './components/detail/SetVersionDetailDrawer.vue'
|
||||
import { setStatusLabel, setStatusTagType } from './utils/priceSet'
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
const tableRef = ref()
|
||||
@@ -91,6 +95,7 @@ const searchColumns = [
|
||||
prop: 'status',
|
||||
component: 'select',
|
||||
options: [
|
||||
{ label: '待启用', value: 'D' },
|
||||
{ label: '生效', value: 'E' },
|
||||
{ label: '已停用', value: 'S' }
|
||||
],
|
||||
@@ -105,6 +110,7 @@ const columns = [
|
||||
{ label: '套餐名称', prop: 'priceSetName', minWidth: 160 },
|
||||
{ label: '类型', prop: 'setType', width: 140 },
|
||||
{ label: '说明', prop: 'priceSetNote', minWidth: 160 },
|
||||
{ label: '状态', prop: 'status', width: 90 },
|
||||
{ label: '生效明细', prop: 'activeDetail', width: 100 },
|
||||
{ label: '操作', prop: 'action', width: 160, showInToolbar: false }
|
||||
]
|
||||
@@ -113,20 +119,12 @@ function queryList(params) {
|
||||
return listPriceSet(params)
|
||||
}
|
||||
|
||||
function formatDate(val) {
|
||||
return val ? parseTime(val, '{y}-{m}-{d}') : ''
|
||||
}
|
||||
|
||||
function statusLabel(row) {
|
||||
if (row.expired) return '已过期'
|
||||
const map = { D: '草稿', A: '审核中', E: '生效', R: '驳回', S: '已停用' }
|
||||
return map[row.status] || row.status
|
||||
return setStatusLabel(row)
|
||||
}
|
||||
|
||||
function statusTag(row) {
|
||||
if (row.expired) return 'danger'
|
||||
const map = { D: 'warning', A: 'primary', E: 'success', R: 'danger', S: 'info' }
|
||||
return map[row.status] || 'info'
|
||||
return setStatusTagType(row)
|
||||
}
|
||||
|
||||
function handleCreate() {
|
||||
@@ -184,6 +182,15 @@ function handleDisable(row) {
|
||||
}).catch(() => {})
|
||||
}
|
||||
|
||||
function handleEnable(row) {
|
||||
proxy.$modal.confirm('启用后该套餐将重新参与计费命中,确认启用【' + row.priceSetName + '】?').then(() => {
|
||||
return enablePriceSet(row.priceSetId)
|
||||
}).then(() => {
|
||||
proxy.$modal.msgSuccess('已启用')
|
||||
tableRef.value.refresh()
|
||||
}).catch(() => {})
|
||||
}
|
||||
|
||||
function handleCopy(row) {
|
||||
copyPriceSet(row.priceSetId).then(res => {
|
||||
proxy.$modal.msgSuccess('已复制为草稿')
|
||||
|
||||
@@ -12,7 +12,7 @@ export const SET_TYPE = {
|
||||
DISCOUNT: 'DISCOUNT'
|
||||
}
|
||||
|
||||
/** 套餐状态枚举:D 草稿 / A 审核中 / E 生效中 / R 驳回 / S 已停用 */
|
||||
/** 套餐状态枚举:D 待启用 / A 审核中 / E 生效 / R 驳回 / S 已停用 */
|
||||
export const SET_STATUS = {
|
||||
DRAFT: 'D',
|
||||
AUDIT: 'A',
|
||||
@@ -22,9 +22,9 @@ export const SET_STATUS = {
|
||||
}
|
||||
|
||||
const STATUS_LABEL = {
|
||||
D: '草稿',
|
||||
D: '待启用',
|
||||
A: '审核中',
|
||||
E: '生效中',
|
||||
E: '生效',
|
||||
R: '驳回',
|
||||
S: '已停用'
|
||||
}
|
||||
@@ -83,19 +83,21 @@ export function nextVersionNo(versions) {
|
||||
return 'V' + (max + 1)
|
||||
}
|
||||
|
||||
/** 状态文案(已过期优先) */
|
||||
/** Package status label */
|
||||
export function setStatusLabel(set) {
|
||||
if (set && set.expired) return '已过期'
|
||||
return STATUS_LABEL[set && set.status] || (set && set.status) || '-'
|
||||
if (set && set.status && STATUS_LABEL[set.status]) return STATUS_LABEL[set.status]
|
||||
return set && set.status ? String(set.status) : '-'
|
||||
}
|
||||
|
||||
/** 状态标签色(已过期优先) */
|
||||
/** Package status tag type */
|
||||
export function setStatusTagType(set) {
|
||||
if (set && set.expired) return 'danger'
|
||||
return STATUS_TAG[set && set.status] || 'info'
|
||||
if (set && set.status && STATUS_TAG[set.status]) return STATUS_TAG[set.status]
|
||||
return 'info'
|
||||
}
|
||||
|
||||
/** 明细 / 客户是否可维护:草稿、驳回、生效中 */
|
||||
/** 明细 / 客户是否可维护:待启用、驳回、生效 */
|
||||
export function isChildEditable(status) {
|
||||
return [SET_STATUS.DRAFT, SET_STATUS.REJECT, SET_STATUS.EFFECTIVE].includes(status)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user