20260708001
This commit is contained in:
+26
-2
@@ -17,9 +17,24 @@ import {
|
|||||||
pickSupplierBlocCode,
|
pickSupplierBlocCode,
|
||||||
pickSupplierCompanyCode,
|
pickSupplierCompanyCode,
|
||||||
pickSupplierDisplayName,
|
pickSupplierDisplayName,
|
||||||
|
pickSupplierSpecialDeliveryCommissionRate,
|
||||||
|
formatSupplierSpecialDeliveryCommissionRate,
|
||||||
resolveOrgEffectiveSceneCodes,
|
resolveOrgEffectiveSceneCodes,
|
||||||
} from '@/api/supplySupplier'
|
} from '@/api/supplySupplier'
|
||||||
|
|
||||||
|
function buildCustomerSpecialDeliveryFields(formOrRow) {
|
||||||
|
const rate = pickSupplierSpecialDeliveryCommissionRate(formOrRow)
|
||||||
|
return {
|
||||||
|
special_delivery_commission_rate: rate ?? 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildCustomerSpecialDeliveryFieldsFromRow(row) {
|
||||||
|
return {
|
||||||
|
special_delivery_commission_rate: pickSupplierSpecialDeliveryCommissionRate(row) ?? 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** @param {unknown} res */
|
/** @param {unknown} res */
|
||||||
function unwrapResponseData(res) {
|
function unwrapResponseData(res) {
|
||||||
if (res == null) return res
|
if (res == null) return res
|
||||||
@@ -99,15 +114,22 @@ export function buildCustomerAddPayload(form, { blocCode }) {
|
|||||||
return {
|
return {
|
||||||
...buildSupplierAddPayload(form, { blocCode }),
|
...buildSupplierAddPayload(form, { blocCode }),
|
||||||
company_type: 3,
|
company_type: 3,
|
||||||
|
...buildCustomerSpecialDeliveryFields(form),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function buildCustomerModifyPayload(form, companyCode, opts = {}) {
|
export function buildCustomerModifyPayload(form, companyCode, opts = {}) {
|
||||||
return buildSupplierModifyPayload(form, companyCode, opts)
|
return {
|
||||||
|
...buildSupplierModifyPayload(form, companyCode, opts),
|
||||||
|
...buildCustomerSpecialDeliveryFields(form),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function buildCustomerModifyPayloadFromRow(row, opts = {}) {
|
export function buildCustomerModifyPayloadFromRow(row, opts = {}) {
|
||||||
return buildSupplierModifyPayloadFromRow(row, opts)
|
return {
|
||||||
|
...buildSupplierModifyPayloadFromRow(row, opts),
|
||||||
|
...buildCustomerSpecialDeliveryFieldsFromRow(row),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchCustomerGroupTreeListed() {
|
export async function fetchCustomerGroupTreeListed() {
|
||||||
@@ -132,5 +154,7 @@ export {
|
|||||||
pickSupplierCompanyCode as pickCustomerCompanyCode,
|
pickSupplierCompanyCode as pickCustomerCompanyCode,
|
||||||
pickSupplierDisplayName as pickCustomerDisplayName,
|
pickSupplierDisplayName as pickCustomerDisplayName,
|
||||||
resolveOrgEffectiveSceneCodes,
|
resolveOrgEffectiveSceneCodes,
|
||||||
|
pickSupplierSpecialDeliveryCommissionRate,
|
||||||
|
formatSupplierSpecialDeliveryCommissionRate,
|
||||||
buildSupplierFormFields as buildCustomerFormFields,
|
buildSupplierFormFields as buildCustomerFormFields,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -524,6 +524,30 @@ export function serializeBenefitBuckets(buckets) {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** add 接口:excess_performance / benefit 须为 JSONArray;无票种分组时传 [] */
|
||||||
|
export function serializeExcessPerformanceForAdd(buckets) {
|
||||||
|
const src = buckets && typeof buckets === 'object' ? buckets : {}
|
||||||
|
const namedKeys = Object.keys(src).filter((k) => String(k).trim() !== '')
|
||||||
|
if (!namedKeys.length) return []
|
||||||
|
return serializeExcessPerformanceBucketsAsCustomArray(src)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** add 接口:benefit 同 excess_performance,无分组时传 [] */
|
||||||
|
export function serializeBenefitForAdd(buckets) {
|
||||||
|
const src = buckets && typeof buckets === 'object' ? buckets : {}
|
||||||
|
const namedKeys = Object.keys(src).filter((k) => String(k).trim() !== '')
|
||||||
|
if (!namedKeys.length) return []
|
||||||
|
return serializeBenefitBucketsAsCustomArray(src)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 表单 → 新增请求体(超额绩效/好处费为数组) */
|
||||||
|
export function buildCustomerPriceAddBody(form, extras = {}) {
|
||||||
|
const body = buildCustomerPriceWriteBody(form, extras)
|
||||||
|
body.excess_performance = serializeExcessPerformanceForAdd(form?.excess_performance_buckets)
|
||||||
|
body.benefit = serializeBenefitForAdd(form?.benefit_buckets)
|
||||||
|
return body
|
||||||
|
}
|
||||||
|
|
||||||
/** 表单 → 新增/修改请求体 */
|
/** 表单 → 新增/修改请求体 */
|
||||||
export function buildCustomerPriceWriteBody(form, extras = {}) {
|
export function buildCustomerPriceWriteBody(form, extras = {}) {
|
||||||
const excess_performance = serializeExcessPerformanceBuckets(form?.excess_performance_buckets)
|
const excess_performance = serializeExcessPerformanceBuckets(form?.excess_performance_buckets)
|
||||||
@@ -586,7 +610,7 @@ export function buildCustomerPriceAddItem(company_code, goods_code, overrides =
|
|||||||
const cc = String(company_code ?? '').trim()
|
const cc = String(company_code ?? '').trim()
|
||||||
const gc = String(goods_code ?? '').trim()
|
const gc = String(goods_code ?? '').trim()
|
||||||
const o = overrides && typeof overrides === 'object' ? overrides : {}
|
const o = overrides && typeof overrides === 'object' ? overrides : {}
|
||||||
return buildCustomerPriceWriteBody(
|
return buildCustomerPriceAddBody(
|
||||||
{
|
{
|
||||||
excess_performance_buckets: groupsToPerformanceBuckets([]),
|
excess_performance_buckets: groupsToPerformanceBuckets([]),
|
||||||
benefit_buckets: groupsToBenefitBuckets([]),
|
benefit_buckets: groupsToBenefitBuckets([]),
|
||||||
|
|||||||
+12
-7
@@ -88,16 +88,16 @@ export function normalizePricingTableRow(raw, idx = 0) {
|
|||||||
const internal_bill_type = pickText(raw, 'internal_bill_name', 'internal_bill_type')
|
const internal_bill_type = pickText(raw, 'internal_bill_name', 'internal_bill_type')
|
||||||
const internal_input_tax_rate = pickRate(raw, 'internal_bill_tax', 'internal_input_tax_rate')
|
const internal_input_tax_rate = pickRate(raw, 'internal_bill_tax', 'internal_input_tax_rate')
|
||||||
const source_rdc_name = pickText(raw, 'rdc_warehouse_name', 'source_rdc_name')
|
const source_rdc_name = pickText(raw, 'rdc_warehouse_name', 'source_rdc_name')
|
||||||
const source_rdc_code = pickText(raw, 'rdc_warehouse_code', 'source_rdc')
|
const source_rdc_code = pickText(raw, 'rdc_warehouse_code', 'source_rdc_code', 'source_rdc')
|
||||||
const fence_value = pickMoney(raw, 'fence_price', 'fence_value')
|
const fence_value = pickMoney(raw, 'fence_price', 'fence_value')
|
||||||
|
|
||||||
const bloc = pickText(raw, 'supplier_bloc_code')
|
const bloc = pickText(raw, 'supplier_bloc_code')
|
||||||
const company = pickText(raw, 'supplier_company_code')
|
const supplier_company_code = pickText(raw, 'supplier_company_code', 'company_code')
|
||||||
|
|
||||||
return {
|
return {
|
||||||
key: pickText(raw, 'key', 'id') ?? `${bloc || 'bloc'}-${company || idx}`,
|
key: pickText(raw, 'key', 'id') ?? `${bloc || 'bloc'}-${supplier_company_code || idx}`,
|
||||||
supplier_bloc_name,
|
supplier_bloc_name,
|
||||||
supplier_company_name,
|
supplier_company_name,
|
||||||
|
supplier_company_code,
|
||||||
goods_name,
|
goods_name,
|
||||||
bill_type,
|
bill_type,
|
||||||
input_tax_rate,
|
input_tax_rate,
|
||||||
@@ -107,6 +107,7 @@ export function normalizePricingTableRow(raw, idx = 0) {
|
|||||||
internal_input_tax_rate,
|
internal_input_tax_rate,
|
||||||
source_rdc: source_rdc_name || source_rdc_code,
|
source_rdc: source_rdc_name || source_rdc_code,
|
||||||
source_rdc_name,
|
source_rdc_name,
|
||||||
|
source_rdc_code,
|
||||||
fence_value,
|
fence_value,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -150,16 +151,16 @@ function unwrapPricingCalculatePayload(res) {
|
|||||||
return envelope
|
return envelope
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 算价响应 → debug 文本(供弹窗展示) */
|
/** 算价响应 → 明细文本(供弹窗展示) */
|
||||||
export function formatPricingCalculateDebug(res) {
|
export function formatPricingCalculateDebug(res) {
|
||||||
const payload = unwrapPricingCalculatePayload(res)
|
const payload = unwrapPricingCalculatePayload(res)
|
||||||
const debug = payload?.debug ?? res?.data?.debug ?? res?.debug
|
const debug = payload?.debug ?? res?.data?.debug ?? res?.debug
|
||||||
if (debug == null || debug === '') {
|
if (debug == null || debug === '') {
|
||||||
const fallback = payload && typeof payload === 'object' ? payload : (res?.data ?? res)
|
const fallback = payload && typeof payload === 'object' ? payload : (res?.data ?? res)
|
||||||
try {
|
try {
|
||||||
return `(接口未返回 debug)\n\n${JSON.stringify(fallback, null, 2)}`
|
return `(接口未返回计算明细)\n\n${JSON.stringify(fallback, null, 2)}`
|
||||||
} catch {
|
} catch {
|
||||||
return '(接口未返回 debug)'
|
return '(接口未返回计算明细)'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (typeof debug === 'string') return debug
|
if (typeof debug === 'string') return debug
|
||||||
@@ -193,8 +194,12 @@ export async function pricingCalculate(body = {}) {
|
|||||||
}
|
}
|
||||||
const supply_collection_code = str(body.supply_collection_code)
|
const supply_collection_code = str(body.supply_collection_code)
|
||||||
const customer_price_code = str(body.customer_price_code)
|
const customer_price_code = str(body.customer_price_code)
|
||||||
|
const supplier_company_code = str(body.supplier_company_code)
|
||||||
|
const warehouse_code = str(body.warehouse_code)
|
||||||
if (supply_collection_code) payload.supply_collection_code = supply_collection_code
|
if (supply_collection_code) payload.supply_collection_code = supply_collection_code
|
||||||
if (customer_price_code) payload.customer_price_code = customer_price_code
|
if (customer_price_code) payload.customer_price_code = customer_price_code
|
||||||
|
if (supplier_company_code) payload.supplier_company_code = supplier_company_code
|
||||||
|
if (warehouse_code) payload.warehouse_code = warehouse_code
|
||||||
|
|
||||||
return request.post('/api/pricing/calculate', payload)
|
return request.post('/api/pricing/calculate', payload)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -677,17 +677,17 @@ export function pickCollectionTargetDelayedRebateMonths(row) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 列表/编辑回填:帐期月数(接口仍用 payment_days,后端新增 payment_months 时再兼容读取)
|
* 列表/编辑回填:帐期月数(接口字段 payment_months;兼容旧 payment_days)
|
||||||
* @param {object} [row]
|
* @param {object} [row]
|
||||||
*/
|
*/
|
||||||
export function pickCollectionPaymentMonths(row) {
|
export function pickCollectionPaymentMonths(row) {
|
||||||
const r = row && typeof row === 'object' ? row : {}
|
const r = row && typeof row === 'object' ? row : {}
|
||||||
const v =
|
const v =
|
||||||
r.payment_days
|
r.payment_months
|
||||||
|
?? r.payment_month
|
||||||
|
?? r.payment_days
|
||||||
?? r.payment_period_days
|
?? r.payment_period_days
|
||||||
?? r.paymentDays
|
?? r.paymentDays
|
||||||
?? r.payment_months
|
|
||||||
?? r.payment_month
|
|
||||||
if (v === null || v === undefined || v === '') return ''
|
if (v === null || v === undefined || v === '') return ''
|
||||||
return String(v)
|
return String(v)
|
||||||
}
|
}
|
||||||
@@ -711,6 +711,14 @@ export function resolveOrgContactPerson(raw) {
|
|||||||
return { code: '', label: nameLabel || contactRaw }
|
return { code: '', label: nameLabel || contactRaw }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resolveCollectionPaymentMonthsValue(p) {
|
||||||
|
const src = p && typeof p === 'object' ? p : {}
|
||||||
|
const v = src.payment_months ?? src.payment_days
|
||||||
|
if (v === null || v === undefined || v === '') return 0
|
||||||
|
const n = Number(v)
|
||||||
|
return Number.isFinite(n) ? n : 0
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* POST /api/supply/collection/add 请求体(与三步向导快照对齐)
|
* POST /api/supply/collection/add 请求体(与三步向导快照对齐)
|
||||||
* @param {object} parts
|
* @param {object} parts
|
||||||
@@ -751,7 +759,7 @@ export function buildSupplyCollectionAddBody(parts) {
|
|||||||
owner_code: String(p.owner_code || '').trim(),
|
owner_code: String(p.owner_code || '').trim(),
|
||||||
scenes,
|
scenes,
|
||||||
warehouses,
|
warehouses,
|
||||||
payment_days: p.payment_days ?? 60,
|
payment_months: resolveCollectionPaymentMonthsValue(p),
|
||||||
is_support_acceptance:
|
is_support_acceptance:
|
||||||
p.is_support_acceptance === true || acceptanceRaw === '支持',
|
p.is_support_acceptance === true || acceptanceRaw === '支持',
|
||||||
is_support_receipt: p.is_support_receipt === true,
|
is_support_receipt: p.is_support_receipt === true,
|
||||||
@@ -805,7 +813,7 @@ export function buildCoordCollectionSaveBody(parts) {
|
|||||||
supplier_org_type: String(p.supplier_org_type || '').trim(),
|
supplier_org_type: String(p.supplier_org_type || '').trim(),
|
||||||
partner_org_type: String(p.partner_org_type || '').trim(),
|
partner_org_type: String(p.partner_org_type || '').trim(),
|
||||||
warehouse_codes: Array.isArray(p.warehouse_codes) ? [...p.warehouse_codes] : [],
|
warehouse_codes: Array.isArray(p.warehouse_codes) ? [...p.warehouse_codes] : [],
|
||||||
payment_days: p.payment_days,
|
payment_months: resolveCollectionPaymentMonthsValue(p),
|
||||||
acceptance_payment: String(p.acceptance_payment || '').trim(),
|
acceptance_payment: String(p.acceptance_payment || '').trim(),
|
||||||
rebate_delay_base_months:
|
rebate_delay_base_months:
|
||||||
p.rebate_delay_base_months
|
p.rebate_delay_base_months
|
||||||
|
|||||||
@@ -439,6 +439,27 @@ export function formatSupplierOutputVatRateLabel(row) {
|
|||||||
return '—'
|
return '—'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** listed 行解析专项送货计提率 */
|
||||||
|
export function pickSupplierSpecialDeliveryCommissionRate(row) {
|
||||||
|
if (!row || typeof row !== 'object') return null
|
||||||
|
const r = /** @type {Record<string, unknown>} */ (row)
|
||||||
|
const field = r.field && typeof r.field === 'object' ? r.field : null
|
||||||
|
const fields = r.fields && typeof r.fields === 'object' ? r.fields : null
|
||||||
|
const raw = r.special_delivery_commission_rate
|
||||||
|
?? field?.special_delivery_commission_rate
|
||||||
|
?? fields?.special_delivery_commission_rate
|
||||||
|
if (raw === null || raw === undefined || raw === '') return null
|
||||||
|
const n = Number(raw)
|
||||||
|
return Number.isFinite(n) ? n : null
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 详情展示:专项送货计提率 */
|
||||||
|
export function formatSupplierSpecialDeliveryCommissionRate(row) {
|
||||||
|
const n = pickSupplierSpecialDeliveryCommissionRate(row)
|
||||||
|
if (n == null) return '—'
|
||||||
|
return `${n}%`
|
||||||
|
}
|
||||||
|
|
||||||
/** listed 行解析 sale_type(1 渠道 / 2 零售) */
|
/** listed 行解析 sale_type(1 渠道 / 2 零售) */
|
||||||
export function pickSupplierSaleType(row) {
|
export function pickSupplierSaleType(row) {
|
||||||
if (!row || typeof row !== 'object') return ORG_SALE_TYPE_CHANNEL
|
if (!row || typeof row !== 'object') return ORG_SALE_TYPE_CHANNEL
|
||||||
@@ -458,6 +479,7 @@ export function buildSupplierFormStateFromRow(row) {
|
|||||||
output_vat_rate_key: '',
|
output_vat_rate_key: '',
|
||||||
is_support_receipt: false,
|
is_support_receipt: false,
|
||||||
sale_type: ORG_SALE_TYPE_CHANNEL,
|
sale_type: ORG_SALE_TYPE_CHANNEL,
|
||||||
|
special_delivery_commission_rate: null,
|
||||||
credit_code: '',
|
credit_code: '',
|
||||||
legal_person: '',
|
legal_person: '',
|
||||||
contact_person: '',
|
contact_person: '',
|
||||||
@@ -469,7 +491,7 @@ export function buildSupplierFormStateFromRow(row) {
|
|||||||
if (!row || typeof row !== 'object') return { ...base }
|
if (!row || typeof row !== 'object') return { ...base }
|
||||||
const next = { ...base }
|
const next = { ...base }
|
||||||
for (const key of Object.keys(base)) {
|
for (const key of Object.keys(base)) {
|
||||||
if (key === 'output_vat_rate_key' || key === 'is_support_receipt' || key === 'org_type' || key === 'sale_type') continue
|
if (key === 'output_vat_rate_key' || key === 'is_support_receipt' || key === 'org_type' || key === 'sale_type' || key === 'special_delivery_commission_rate') continue
|
||||||
if (row[key] !== undefined && row[key] !== null) next[key] = row[key]
|
if (row[key] !== undefined && row[key] !== null) next[key] = row[key]
|
||||||
}
|
}
|
||||||
const tax = hydrateSupplierOrgTaxFields(row)
|
const tax = hydrateSupplierOrgTaxFields(row)
|
||||||
@@ -479,6 +501,7 @@ export function buildSupplierFormStateFromRow(row) {
|
|||||||
is_support_receipt: tax.is_support_receipt,
|
is_support_receipt: tax.is_support_receipt,
|
||||||
output_vat_rate_key: tax.output_vat_rate_key,
|
output_vat_rate_key: tax.output_vat_rate_key,
|
||||||
sale_type: pickSupplierSaleType(row),
|
sale_type: pickSupplierSaleType(row),
|
||||||
|
special_delivery_commission_rate: pickSupplierSpecialDeliveryCommissionRate(row),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -106,7 +106,22 @@
|
|||||||
<div class="wops-col wops-col--wh">
|
<div class="wops-col wops-col--wh">
|
||||||
<span class="wops-name wops-ellipsis">{{ row.source_rdc_name || row.source_rdc || '—' }}</span>
|
<span class="wops-name wops-ellipsis">{{ row.source_rdc_name || row.source_rdc || '—' }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="wops-col wops-col--num">{{ fmtMoney(row.fence_value) }}</div>
|
<div class="wops-col wops-col--num gt-cost-col--fence">
|
||||||
|
<span
|
||||||
|
v-if="hasFenceNumericValue(row.fence_value)"
|
||||||
|
class="gt-cost-fence-value"
|
||||||
|
>
|
||||||
|
<el-icon
|
||||||
|
class="gt-cost-fence-help-icon"
|
||||||
|
aria-label="围栏值说明"
|
||||||
|
@click.stop="onFenceValueHelpClick(row)"
|
||||||
|
>
|
||||||
|
<QuestionFilled />
|
||||||
|
</el-icon>
|
||||||
|
<span class="gt-cost-fence-num">{{ fmtMoney(row.fence_value) }}</span>
|
||||||
|
</span>
|
||||||
|
<span v-else class="gt-cost-fence-num">{{ fmtMoney(row.fence_value) }}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -115,17 +130,49 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<Teleport to="body">
|
||||||
|
<el-dialog
|
||||||
|
v-if="calculateDebugVisible"
|
||||||
|
v-model="calculateDebugVisible"
|
||||||
|
:title="calculateDebugTitle"
|
||||||
|
width="1200px"
|
||||||
|
class="gt-cost-calc-debug-dlg"
|
||||||
|
modal-class="gt-cost-calc-debug-overlay"
|
||||||
|
align-center
|
||||||
|
append-to-body
|
||||||
|
lock-scroll
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
destroy-on-close
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="gt-cost-calc-debug-body"
|
||||||
|
v-loading="calculateLoading"
|
||||||
|
element-loading-text="算价中…"
|
||||||
|
>
|
||||||
|
<pre class="gt-cost-calc-debug-pre">{{ calculateDebugText }}</pre>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<el-button type="primary" @click="calculateDebugVisible = false">关闭</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</Teleport>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, ref, watch } from 'vue'
|
import { computed, onBeforeUnmount, ref, watch } from 'vue'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
import { QuestionFilled } from '@element-plus/icons-vue'
|
||||||
import { mapGoodsRdcsToOptions } from '@/utils/warehouseGlobalTabSchema'
|
import { mapGoodsRdcsToOptions } from '@/utils/warehouseGlobalTabSchema'
|
||||||
import {
|
import {
|
||||||
PRICING_TAXPAYER_DEFAULT,
|
PRICING_TAXPAYER_DEFAULT,
|
||||||
PRICING_TAXPAYER_TABS,
|
PRICING_TAXPAYER_TABS,
|
||||||
PRICING_TRADE_DOMESTIC,
|
PRICING_TRADE_DOMESTIC,
|
||||||
|
formatPricingCalculateDebug,
|
||||||
|
pickPricingCalculateError,
|
||||||
pickPricingTableError,
|
pickPricingTableError,
|
||||||
|
pricingCalculate,
|
||||||
pricingTableQuery,
|
pricingTableQuery,
|
||||||
} from '@/api/pricingTable'
|
} from '@/api/pricingTable'
|
||||||
|
|
||||||
@@ -194,6 +241,11 @@ const fenceRows = ref([])
|
|||||||
/** 递增序号,避免切换 RDC / 纳税身份时旧请求覆盖新结果 */
|
/** 递增序号,避免切换 RDC / 纳税身份时旧请求覆盖新结果 */
|
||||||
let fenceFetchSeq = 0
|
let fenceFetchSeq = 0
|
||||||
|
|
||||||
|
const calculateDebugVisible = ref(false)
|
||||||
|
const calculateDebugTitle = ref('算价明细')
|
||||||
|
const calculateDebugText = ref('')
|
||||||
|
const calculateLoading = ref(false)
|
||||||
|
|
||||||
const rdcOptions = computed(() => mapGoodsRdcsToOptions(props.rdcList))
|
const rdcOptions = computed(() => mapGoodsRdcsToOptions(props.rdcList))
|
||||||
|
|
||||||
function rdcDisplayName(rdc) {
|
function rdcDisplayName(rdc) {
|
||||||
@@ -235,6 +287,68 @@ function fmtTaxRate(v) {
|
|||||||
return `${n}%`
|
return `${n}%`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hasFenceNumericValue(v) {
|
||||||
|
if (v == null || v === '') return false
|
||||||
|
return Number.isFinite(Number(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
function fenceRowCalculateLabel(row) {
|
||||||
|
const supplier = String(row?.supplier_company_name || '').trim()
|
||||||
|
const warehouse = String(row?.source_rdc_name || row?.source_rdc || '').trim()
|
||||||
|
const parts = [supplier, warehouse].filter(Boolean)
|
||||||
|
return parts.length ? parts.join(' · ') : '围栏值'
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildPricingCalculateBody(row) {
|
||||||
|
return {
|
||||||
|
taxpayer_type: activeTaxpayerType.value,
|
||||||
|
trade_type: PRICING_TRADE_DOMESTIC,
|
||||||
|
goods_code: String(props.goodsCode || '').trim(),
|
||||||
|
supplier_company_code: String(row?.supplier_company_code || '').trim(),
|
||||||
|
warehouse_code: String(row?.source_rdc_code || '').trim(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function openCalculateDebug(title, debugText) {
|
||||||
|
calculateDebugTitle.value = title
|
||||||
|
calculateDebugText.value = String(debugText ?? '').trim()
|
||||||
|
calculateDebugVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onFenceValueHelpClick(row) {
|
||||||
|
const body = buildPricingCalculateBody(row)
|
||||||
|
if (!body.goods_code) {
|
||||||
|
ElMessage.warning('缺少商品编码,无法算价')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!body.supplier_company_code) {
|
||||||
|
ElMessage.warning('缺少供应商组织编码,无法算价')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!body.warehouse_code) {
|
||||||
|
ElMessage.warning('缺少源采购 RDC 仓库编码,无法算价')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (calculateLoading.value) return
|
||||||
|
|
||||||
|
calculateLoading.value = true
|
||||||
|
openCalculateDebug(`算价明细 · ${fenceRowCalculateLabel(row)}`, '算价中…')
|
||||||
|
try {
|
||||||
|
const res = await pricingCalculate(body)
|
||||||
|
openCalculateDebug(
|
||||||
|
`算价明细 · ${fenceRowCalculateLabel(row)}`,
|
||||||
|
formatPricingCalculateDebug(res),
|
||||||
|
)
|
||||||
|
} catch (e) {
|
||||||
|
openCalculateDebug(
|
||||||
|
`算价明细 · ${fenceRowCalculateLabel(row)}`,
|
||||||
|
`【失败】${pickPricingCalculateError(e)}`,
|
||||||
|
)
|
||||||
|
} finally {
|
||||||
|
calculateLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function fetchFenceTable() {
|
async function fetchFenceTable() {
|
||||||
const goods_code = String(props.goodsCode || '').trim()
|
const goods_code = String(props.goodsCode || '').trim()
|
||||||
const rdc_code = String(activeRdcCode.value || '').trim()
|
const rdc_code = String(activeRdcCode.value || '').trim()
|
||||||
@@ -314,6 +428,11 @@ watch(activeRdcCode, () => {
|
|||||||
watch(activeTaxpayerType, () => {
|
watch(activeTaxpayerType, () => {
|
||||||
void fetchFenceTable()
|
void fetchFenceTable()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
calculateDebugVisible.value = false
|
||||||
|
calculateLoading.value = false
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@@ -544,6 +663,33 @@ watch(activeTaxpayerType, () => {
|
|||||||
.gt-cost-table-wrap :deep(.is-cols-cost-fence .gt-cost-col--min-price) {
|
.gt-cost-table-wrap :deep(.is-cols-cost-fence .gt-cost-col--min-price) {
|
||||||
padding-right: 4px;
|
padding-right: 4px;
|
||||||
}
|
}
|
||||||
|
.gt-cost-table-wrap :deep(.gt-cost-col--fence) {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
.gt-cost-fence-value {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 4px;
|
||||||
|
min-width: 0;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
.gt-cost-fence-help-icon {
|
||||||
|
flex-shrink: 0;
|
||||||
|
font-size: calc(13px + var(--wh-fs-delta, 0px));
|
||||||
|
color: #909399;
|
||||||
|
cursor: pointer;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
.gt-cost-fence-help-icon:hover {
|
||||||
|
color: #409eff;
|
||||||
|
}
|
||||||
|
.gt-cost-fence-num {
|
||||||
|
line-height: 1;
|
||||||
|
font-variant-numeric: tabular-nums;
|
||||||
|
}
|
||||||
@media (max-width: 900px) {
|
@media (max-width: 900px) {
|
||||||
.gt-cost-layout {
|
.gt-cost-layout {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -557,3 +703,66 @@ watch(activeTaxpayerType, () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.gt-cost-calc-debug-overlay .el-overlay-dialog {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 24px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gt-cost-calc-debug-dlg.el-dialog {
|
||||||
|
width: min(1200px, 94vw);
|
||||||
|
max-width: 94vw;
|
||||||
|
max-height: calc(100vh - 48px);
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gt-cost-calc-debug-dlg.el-dialog .el-dialog__header {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gt-cost-calc-debug-dlg.el-dialog .el-dialog__body {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
min-height: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 12px 20px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gt-cost-calc-debug-dlg.el-dialog .el-dialog__footer {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gt-cost-calc-debug-dlg .gt-cost-calc-debug-body {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
min-height: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gt-cost-calc-debug-dlg .gt-cost-calc-debug-pre {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
min-height: 0;
|
||||||
|
margin: 0;
|
||||||
|
overflow: auto;
|
||||||
|
overscroll-behavior: contain;
|
||||||
|
padding: 12px 14px;
|
||||||
|
background: #1e1e1e;
|
||||||
|
color: #d4d4d4;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.55;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{
|
{
|
||||||
"buildId": "20260707009",
|
"buildId": "20260708004",
|
||||||
"generatedAt": "2026-07-07T14:48:25.301Z"
|
"generatedAt": "2026-07-08T08:40:29.095Z"
|
||||||
}
|
}
|
||||||
@@ -42,11 +42,61 @@
|
|||||||
* @typedef {{ date: string, items: ChangelogItem[] }} ChangelogDay
|
* @typedef {{ date: string, items: ChangelogItem[] }} ChangelogDay
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** 应用版本(如 0.7.032 → 侧栏 v0.7,弹窗 v0.7.032) */
|
/** 应用版本(如 0.7.035 → 侧栏 v0.7,弹窗 v0.7.035) */
|
||||||
export const APP_VERSION = '0.7.032'
|
export const APP_VERSION = '0.7.39'
|
||||||
|
|
||||||
/** @type {ChangelogDay[]} */
|
/** @type {ChangelogDay[]} */
|
||||||
export const APP_CHANGELOG = [
|
export const APP_CHANGELOG = [
|
||||||
|
{
|
||||||
|
date: '2026-07-08',
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
icon: 'mdi:format-list-bulleted',
|
||||||
|
kind: 'add',
|
||||||
|
text: '「物料列表 → 成本围栏」围栏值前增加可点击「?」,对接 `POST /api/pricing/calculate` 查看算价明细(传 `supplier_company_code`、`warehouse_code` 及当前纳税身份/商品);弹窗宽 1200px、仅内容区滚动,`Teleport` 挂 body 避免嵌套物料弹窗生命周期警告。',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'mdi:notebook-outline',
|
||||||
|
kind: 'change',
|
||||||
|
text: '「客户管理 → 客户价格本」移除顶栏「批量计算」按钮及相关算价弹窗逻辑。',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'mdi:storefront-outline',
|
||||||
|
kind: 'add',
|
||||||
|
text: '「客户管理 → 客户列表」组织新建/编辑对接 `special_delivery_commission_rate`(客户专项送货计提率),仅走 `/api/customer/add`、`/api/customer/modify`;供货目录供应商接口不带该字段。',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'mdi:truck-delivery-outline',
|
||||||
|
kind: 'change',
|
||||||
|
text: '「供应商列表」「客户列表」组织详情与新建/编辑弹窗:基本信息拆为「工商信息」「其他信息」;销售类型单独置于「其他信息」;客户另增专项送货计提率,输入框与详情展示带 % 单位。',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'mdi:storefront-outline',
|
||||||
|
kind: 'fix',
|
||||||
|
text: '「客户列表」组织详情「工商信息」卡片(信用代码、法人、组织类型)因 computed 漏写 return 未渲染,已修复。',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'mdi:warehouse',
|
||||||
|
kind: 'change',
|
||||||
|
text: '「仓库管理 → RDC 物料」可调配仓相关文案统一为「源采购仓」:Tab、批量关联按钮、关联弹窗标题/说明/候选区、确认保存提示及列表空态等用户可见文案同步更名。',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'mdi:warehouse',
|
||||||
|
kind: 'change',
|
||||||
|
text: '「仓库管理 → 关联物料」弹窗:全部/已关联/未关联 Tab 移入物料顶栏,缩小字号并固定高度,与「物料 · N 条」垂直对齐,避免单行过扁。',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'mdi:notebook-outline',
|
||||||
|
kind: 'fix',
|
||||||
|
text: '「客户管理 → 客户价格本」通过场景/分类添加或手动新增时,`/api/customer/price/add` / `batch_add` 的 `excess_performance`、`benefit` 无票种分组时改传空数组 `[]`,不再提交 `{ rate, amount }` 对象,修复后端 JSONArray 类型转换报错。',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'mdi:folder-cog-outline',
|
||||||
|
kind: 'change',
|
||||||
|
text: '「统筹集合管理」新建/编辑第三步「财务成本损益」:接口字段 `payment_days` 更名为 `payment_months`(帐期月数);add/modify 提交与列表回填优先读新字段,兼容旧 `payment_days`。',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
date: '2026-07-07',
|
date: '2026-07-07',
|
||||||
items: [
|
items: [
|
||||||
|
|||||||
@@ -278,7 +278,7 @@ export function validateDeployPairings(anchorRows, anchorToDeployMap, deployTree
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (!pick.key || !pickToWarehouseCode(pick)) {
|
if (!pick.key || !pickToWarehouseCode(pick)) {
|
||||||
return { ok: false, message: '可调配仓勾选数据不完整', unmappedCount: unmappedRows.length + 1 }
|
return { ok: false, message: '源采购仓勾选数据不完整', unmappedCount: unmappedRows.length + 1 }
|
||||||
}
|
}
|
||||||
mappedCount += 1
|
mappedCount += 1
|
||||||
rowsToSave.push(row)
|
rowsToSave.push(row)
|
||||||
@@ -290,14 +290,14 @@ export function validateDeployPairings(anchorRows, anchorToDeployMap, deployTree
|
|||||||
if (pendingRequired.length) {
|
if (pendingRequired.length) {
|
||||||
return {
|
return {
|
||||||
ok: false,
|
ok: false,
|
||||||
message: `还有 ${pendingRequired.length} 条物料有可调配仓尚未勾选,请先完成关联后再确定`,
|
message: `还有 ${pendingRequired.length} 条物料有源采购仓尚未勾选,请先完成关联后再确定`,
|
||||||
unmappedCount: pendingRequired.length,
|
unmappedCount: pendingRequired.length,
|
||||||
mappedCount,
|
mappedCount,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mappedCount === 0) {
|
if (mappedCount === 0) {
|
||||||
return { ok: false, message: '没有可保存的可调配仓关联', unmappedCount: unmappedRows.length }
|
return { ok: false, message: '没有可保存的源采购仓关联', unmappedCount: unmappedRows.length }
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
class="wh-rdc-deploy-link-dlg wh-fs-scope"
|
class="wh-rdc-deploy-link-dlg wh-fs-scope"
|
||||||
@closed="onClosed"
|
@closed="onClosed"
|
||||||
>
|
>
|
||||||
<div v-loading="loading" class="wh-rdc-deploy-link-body" element-loading-text="加载可调配仓候选…">
|
<div v-loading="loading" class="wh-rdc-deploy-link-body" element-loading-text="加载源采购仓候选…">
|
||||||
<p v-if="pairHint" class="wh-rdc-deploy-link-hint">{{ pairHint }}</p>
|
<p v-if="pairHint" class="wh-rdc-deploy-link-hint">{{ pairHint }}</p>
|
||||||
<el-alert
|
<el-alert
|
||||||
v-if="showDeployEmptyTip"
|
v-if="showDeployEmptyTip"
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
type="warning"
|
type="warning"
|
||||||
show-icon
|
show-icon
|
||||||
:closable="false"
|
:closable="false"
|
||||||
title="未查到可关联的可调配仓"
|
title="未查到可关联的源采购仓"
|
||||||
description="请确认其它仓库 RDC 中已维护与左侧相同编码的物料;若仍无结果,请联系管理员检查配置。"
|
description="请确认其它仓库 RDC 中已维护与左侧相同编码的物料;若仍无结果,请联系管理员检查配置。"
|
||||||
/>
|
/>
|
||||||
<div class="wh-rdc-deploy-link-split">
|
<div class="wh-rdc-deploy-link-split">
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="wh-rdc-deploy-link-pane">
|
<section class="wh-rdc-deploy-link-pane">
|
||||||
<header class="wh-rdc-deploy-link-pane-hd">可调配仓候选</header>
|
<header class="wh-rdc-deploy-link-pane-hd">源采购仓候选</header>
|
||||||
<div class="wh-rdc-deploy-link-tree-wrap">
|
<div class="wh-rdc-deploy-link-tree-wrap">
|
||||||
<el-tree
|
<el-tree
|
||||||
v-if="deployTreeData.length"
|
v-if="deployTreeData.length"
|
||||||
@@ -94,7 +94,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-tree>
|
</el-tree>
|
||||||
<div v-else-if="!loading" class="wh-rdc-deploy-link-empty">未查到可调配仓候选</div>
|
<div v-else-if="!loading" class="wh-rdc-deploy-link-empty">未查到源采购仓候选</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
@@ -173,15 +173,15 @@ const dialogTitle = computed(() => {
|
|||||||
if (n <= 1) {
|
if (n <= 1) {
|
||||||
const row = anchorRows.value[0]
|
const row = anchorRows.value[0]
|
||||||
const name = String(row?.goods_name || row?.goods_code || '').trim()
|
const name = String(row?.goods_name || row?.goods_code || '').trim()
|
||||||
return name ? `关联可调配仓 · ${name}` : '关联可调配仓'
|
return name ? `关联源采购仓 · ${name}` : '关联源采购仓'
|
||||||
}
|
}
|
||||||
return `批量关联可调配仓 · ${n} 条`
|
return `批量关联源采购仓 · ${n} 条`
|
||||||
})
|
})
|
||||||
|
|
||||||
const pairHint = computed(() => {
|
const pairHint = computed(() => {
|
||||||
const n = anchorRows.value.length
|
const n = anchorRows.value.length
|
||||||
const mapped = Object.keys(anchorToDeployMap.value).length
|
const mapped = Object.keys(anchorToDeployMap.value).length
|
||||||
return `在右侧勾选可调配仓,左侧将按编码自动显示配对结果(${mapped}/${n})。同一条物料可改选其它仓下的同名项。`
|
return `在右侧勾选源采购仓,左侧将按编码自动显示配对结果(${mapped}/${n})。同一条物料可改选其它仓下的同名项。`
|
||||||
})
|
})
|
||||||
|
|
||||||
const showDeployEmptyTip = computed(() => (
|
const showDeployEmptyTip = computed(() => (
|
||||||
@@ -278,7 +278,7 @@ function onDeployTreeCheck(data, payload) {
|
|||||||
if (ambiguous) {
|
if (ambiguous) {
|
||||||
ElMessage.warning('同编码物料有多条,无法自动配对')
|
ElMessage.warning('同编码物料有多条,无法自动配对')
|
||||||
} else {
|
} else {
|
||||||
ElMessage.warning('该可调配仓物料与左侧待关联物料编码不一致')
|
ElMessage.warning('该源采购仓物料与左侧待关联物料编码不一致')
|
||||||
}
|
}
|
||||||
syncDeployTreeChecks()
|
syncDeployTreeChecks()
|
||||||
return
|
return
|
||||||
@@ -329,7 +329,7 @@ async function loadDialogData() {
|
|||||||
const { tree } = await fetchCandidatesTree(rows)
|
const { tree } = await fetchCandidatesTree(rows)
|
||||||
await applyCandidatesTree(tree)
|
await applyCandidatesTree(tree)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
ElMessage.error('加载可调配仓候选失败:' + (e?.data?.message || e?.message || '未知错误'))
|
ElMessage.error('加载源采购仓候选失败:' + (e?.data?.message || e?.message || '未知错误'))
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
@@ -342,8 +342,8 @@ function normalizeAnchorRows(rows) {
|
|||||||
async function persistDeployMappings(rowsToSave, map, { confirmSkipped = 0 } = {}) {
|
async function persistDeployMappings(rowsToSave, map, { confirmSkipped = 0 } = {}) {
|
||||||
const skippedCount = Number(confirmSkipped) || 0
|
const skippedCount = Number(confirmSkipped) || 0
|
||||||
const confirmText = skippedCount > 0
|
const confirmText = skippedCount > 0
|
||||||
? `确定为 ${rowsToSave.length} 条物料保存可调配仓关联?另有 ${skippedCount} 条暂无可调配仓,将跳过。`
|
? `确定为 ${rowsToSave.length} 条物料保存源采购仓关联?另有 ${skippedCount} 条暂无源采购仓,将跳过。`
|
||||||
: `确定为 ${rowsToSave.length} 条物料保存可调配仓关联?`
|
: `确定为 ${rowsToSave.length} 条物料保存源采购仓关联?`
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await ElMessageBox.confirm(
|
await ElMessageBox.confirm(
|
||||||
@@ -367,7 +367,7 @@ async function persistDeployMappings(rowsToSave, map, { confirmSkipped = 0 } = {
|
|||||||
ElMessage.warning('缺少物料或目标仓编码,无法保存')
|
ElMessage.warning('缺少物料或目标仓编码,无法保存')
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
ElMessage.success(`已关联 ${rowsToSave.length} 条物料的可调配仓`)
|
ElMessage.success(`已关联 ${rowsToSave.length} 条物料的源采购仓`)
|
||||||
emit('saved')
|
emit('saved')
|
||||||
visible.value = false
|
visible.value = false
|
||||||
return true
|
return true
|
||||||
@@ -410,7 +410,7 @@ async function prepareLinkDeploy(rawAnchors) {
|
|||||||
try {
|
try {
|
||||||
const { tree } = await fetchCandidatesTree(rows)
|
const { tree } = await fetchCandidatesTree(rows)
|
||||||
if (!tree.length) {
|
if (!tree.length) {
|
||||||
ElMessage.warning('未找到可调配的仓库,请确认相关 RDC 仓中已维护该物料')
|
ElMessage.warning('未找到源采购仓,请确认相关 RDC 仓中已维护该物料')
|
||||||
return { handled: true }
|
return { handled: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -423,7 +423,7 @@ async function prepareLinkDeploy(rawAnchors) {
|
|||||||
}
|
}
|
||||||
return { handled: false }
|
return { handled: false }
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
ElMessage.error('加载可调配仓候选失败:' + (e?.data?.message || e?.message || '未知错误'))
|
ElMessage.error('加载源采购仓候选失败:' + (e?.data?.message || e?.message || '未知错误'))
|
||||||
return { handled: true }
|
return { handled: true }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,11 +73,16 @@
|
|||||||
|
|
||||||
<section class="wh-slg-col wh-slg-col--goods">
|
<section class="wh-slg-col wh-slg-col--goods">
|
||||||
<div class="wh-slg-col-hd wh-slg-goods-hd">
|
<div class="wh-slg-col-hd wh-slg-goods-hd">
|
||||||
<span>物料</span>
|
<span class="wh-slg-goods-hd-title">物料</span>
|
||||||
<span class="wh-slg-col-meta">
|
<span class="wh-slg-col-meta">
|
||||||
{{ goodsTotal }} 条
|
{{ goodsTotal }} 条
|
||||||
<template v-if="checkedSelectCount"> · 已选 {{ checkedSelectCount }}</template>
|
<template v-if="checkedSelectCount"> · 已选 {{ checkedSelectCount }}</template>
|
||||||
</span>
|
</span>
|
||||||
|
<el-radio-group v-model="goodsTab" size="small" class="wh-slg-goods-tabs">
|
||||||
|
<el-radio-button :value="GOODS_TAB_ALL">全部</el-radio-button>
|
||||||
|
<el-radio-button :value="GOODS_TAB_LINKED">已关联</el-radio-button>
|
||||||
|
<el-radio-button :value="GOODS_TAB_UNLINKED">未关联</el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
<span class="wh-slg-col-hd-spacer" />
|
<span class="wh-slg-col-hd-spacer" />
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
:disabled="advancedSearchBtnEnabled"
|
:disabled="advancedSearchBtnEnabled"
|
||||||
@@ -105,11 +110,6 @@
|
|||||||
清除搜索
|
清除搜索
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
<el-radio-group v-model="goodsTab" size="small" class="wh-slg-goods-tabs">
|
|
||||||
<el-radio-button :value="GOODS_TAB_ALL">全部</el-radio-button>
|
|
||||||
<el-radio-button :value="GOODS_TAB_LINKED">已关联</el-radio-button>
|
|
||||||
<el-radio-button :value="GOODS_TAB_UNLINKED">未关联</el-radio-button>
|
|
||||||
</el-radio-group>
|
|
||||||
<el-input
|
<el-input
|
||||||
v-model="goodsKeyword"
|
v-model="goodsKeyword"
|
||||||
clearable
|
clearable
|
||||||
@@ -1092,13 +1092,40 @@ defineExpose({ clearGoodsSelection })
|
|||||||
line-height: 1.55;
|
line-height: 1.55;
|
||||||
padding: 28px 16px;
|
padding: 28px 16px;
|
||||||
}
|
}
|
||||||
|
.wh-slg-goods-hd {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.wh-slg-goods-hd-title,
|
||||||
|
.wh-slg-goods-hd .wh-slg-col-meta {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 26px;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
.wh-slg-goods-hd-title {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
.wh-slg-goods-tabs {
|
.wh-slg-goods-tabs {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
margin: 0 8px;
|
margin-left: 6px;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
.wh-slg-goods-tabs :deep(.el-radio-button__inner) {
|
.wh-slg-goods-tabs :deep(.el-radio-button__inner) {
|
||||||
font-size: 14px;
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
height: 26px;
|
||||||
|
line-height: 24px;
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.wh-slg-goods-tabs :deep(.el-radio-button:first-child .el-radio-button__inner) {
|
||||||
|
border-radius: 4px 0 0 4px;
|
||||||
|
}
|
||||||
|
.wh-slg-goods-tabs :deep(.el-radio-button:last-child .el-radio-button__inner) {
|
||||||
|
border-radius: 0 4px 4px 0;
|
||||||
}
|
}
|
||||||
.wh-slg-search {
|
.wh-slg-search {
|
||||||
display: block;
|
display: block;
|
||||||
@@ -1121,9 +1148,6 @@ defineExpose({ clearGoodsSelection })
|
|||||||
height: 34px;
|
height: 34px;
|
||||||
line-height: 34px;
|
line-height: 34px;
|
||||||
}
|
}
|
||||||
.wh-slg-goods-hd {
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
.wh-slg-goods-body {
|
.wh-slg-goods-body {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<div class="wh-srf-rdc-deploy">
|
<div class="wh-srf-rdc-deploy">
|
||||||
<div v-if="!goodsRow" class="wh-srf-rdc-deploy-empty">
|
<div v-if="!goodsRow" class="wh-srf-rdc-deploy-empty">
|
||||||
<p>请在左侧点击物料</p>
|
<p>请在左侧点击物料</p>
|
||||||
<p class="wh-srf-rdc-deploy-empty-sub">选中后可维护该 RDC 的可调配仓</p>
|
<p class="wh-srf-rdc-deploy-empty-sub">选中后可维护该 RDC 的源采购仓</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
<div
|
<div
|
||||||
v-loading="loading || mutating"
|
v-loading="loading || mutating"
|
||||||
class="wh-srf-rdc-deploy-body"
|
class="wh-srf-rdc-deploy-body"
|
||||||
element-loading-text="加载可调配仓…"
|
element-loading-text="加载源采购仓…"
|
||||||
>
|
>
|
||||||
<el-table
|
<el-table
|
||||||
v-if="filteredRows.length"
|
v-if="filteredRows.length"
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
@selection-change="onSelectionChange"
|
@selection-change="onSelectionChange"
|
||||||
>
|
>
|
||||||
<el-table-column v-if="canUpdate" type="selection" width="40" />
|
<el-table-column v-if="canUpdate" type="selection" width="40" />
|
||||||
<el-table-column label="调配仓库" min-width="160" show-overflow-tooltip>
|
<el-table-column label="源采购仓" min-width="160" show-overflow-tooltip>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
{{ deployRowLabel(row) }}
|
{{ deployRowLabel(row) }}
|
||||||
</template>
|
</template>
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<div v-else-if="!loading" class="wh-srf-rdc-deploy-empty wh-srf-rdc-deploy-empty--inner">
|
<div v-else-if="!loading" class="wh-srf-rdc-deploy-empty wh-srf-rdc-deploy-empty--inner">
|
||||||
<p>暂无可调配仓</p>
|
<p>暂无源采购仓</p>
|
||||||
<p v-if="canUpdate" class="wh-srf-rdc-deploy-empty-sub">点击「添加」关联其他仓的 RDC</p>
|
<p v-if="canUpdate" class="wh-srf-rdc-deploy-empty-sub">点击「添加」关联其他仓的 RDC</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -148,7 +148,7 @@ function onSelectionChange(rows) {
|
|||||||
async function onAddDeploy() {
|
async function onAddDeploy() {
|
||||||
if (!props.goodsRow) return
|
if (!props.goodsRow) return
|
||||||
if (!sourceRdcCode.value) {
|
if (!sourceRdcCode.value) {
|
||||||
ElMessage.warning('缺少 RDC 编码,无法查询可调配仓候选')
|
ElMessage.warning('缺少 RDC 编码,无法查询源采购仓候选')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const dlg = deployLinkDlgRef.value
|
const dlg = deployLinkDlgRef.value
|
||||||
@@ -183,7 +183,7 @@ async function loadDeployList() {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (seq !== loadSeq) return
|
if (seq !== loadSeq) return
|
||||||
deployRows.value = []
|
deployRows.value = []
|
||||||
ElMessage.error('加载可调配仓失败:' + (e?.data?.message || e?.message || '未知错误'))
|
ElMessage.error('加载源采购仓失败:' + (e?.data?.message || e?.message || '未知错误'))
|
||||||
} finally {
|
} finally {
|
||||||
if (seq === loadSeq) loading.value = false
|
if (seq === loadSeq) loading.value = false
|
||||||
}
|
}
|
||||||
@@ -223,7 +223,7 @@ async function unlinkRows(rows) {
|
|||||||
async function unlinkOne(row) {
|
async function unlinkOne(row) {
|
||||||
const label = deployRowLabel(row)
|
const label = deployRowLabel(row)
|
||||||
try {
|
try {
|
||||||
await ElMessageBox.confirm(`确定移除「${label}」?`, '移除可调配仓', {
|
await ElMessageBox.confirm(`确定移除「${label}」?`, '移除源采购仓', {
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
@@ -238,7 +238,7 @@ async function unlinkSelected() {
|
|||||||
const rows = selectedRows.value
|
const rows = selectedRows.value
|
||||||
if (!rows.length) return
|
if (!rows.length) return
|
||||||
try {
|
try {
|
||||||
await ElMessageBox.confirm(`确定移除已选的 ${rows.length} 个可调配仓?`, '批量移除', {
|
await ElMessageBox.confirm(`确定移除已选的 ${rows.length} 个源采购仓?`, '批量移除', {
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
:disabled="!effectiveSelectedRows.length || unlinking"
|
:disabled="!effectiveSelectedRows.length || unlinking"
|
||||||
@click="openBatchDeployDlg"
|
@click="openBatchDeployDlg"
|
||||||
>
|
>
|
||||||
批量关联可调配仓
|
批量关联源采购仓
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
v-if="canUpdate && goodsRows.length"
|
v-if="canUpdate && goodsRows.length"
|
||||||
@@ -692,7 +692,7 @@ async function linkGoods(items) {
|
|||||||
async function openBatchDeployDlg() {
|
async function openBatchDeployDlg() {
|
||||||
const rows = effectiveSelectedRows.value.filter(Boolean)
|
const rows = effectiveSelectedRows.value.filter(Boolean)
|
||||||
if (!rows.length) {
|
if (!rows.length) {
|
||||||
ElMessage.warning('请先勾选要关联可调配仓的 RDC 物料')
|
ElMessage.warning('请先勾选要关联源采购仓的 RDC 物料')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const prep = await batchDeployDlgRef.value?.prepareLinkDeploy?.(rows)
|
const prep = await batchDeployDlgRef.value?.prepareLinkDeploy?.(rows)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<header class="wh-srf-rdc-right-hd">
|
<header class="wh-srf-rdc-right-hd">
|
||||||
<el-radio-group v-model="activeTab" size="small" class="wh-srf-rdc-right-tabs">
|
<el-radio-group v-model="activeTab" size="small" class="wh-srf-rdc-right-tabs">
|
||||||
<el-radio-button value="region">可售卖区域</el-radio-button>
|
<el-radio-button value="region">可售卖区域</el-radio-button>
|
||||||
<el-radio-button value="deploy">源采购 RDC</el-radio-button>
|
<el-radio-button value="deploy">源采购仓</el-radio-button>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</header>
|
</header>
|
||||||
<div class="wh-srf-rdc-right-body">
|
<div class="wh-srf-rdc-right-body">
|
||||||
|
|||||||
@@ -45,16 +45,6 @@
|
|||||||
>
|
>
|
||||||
批量修改
|
批量修改
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
|
||||||
class="dpb-batch-calc-btn"
|
|
||||||
type="success"
|
|
||||||
size="small"
|
|
||||||
:disabled="!selectedEditableRows.length || batchCalculating"
|
|
||||||
:loading="batchCalculating"
|
|
||||||
@click="runBatchCalculate"
|
|
||||||
>
|
|
||||||
批量计算
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
<el-button
|
||||||
type="warning"
|
type="warning"
|
||||||
size="small"
|
size="small"
|
||||||
@@ -444,20 +434,6 @@
|
|||||||
:submitting="addingPriceBook"
|
:submitting="addingPriceBook"
|
||||||
@confirm="onCategoryGoodsPicked"
|
@confirm="onCategoryGoodsPicked"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<el-dialog
|
|
||||||
v-model="calculateDebugVisible"
|
|
||||||
:title="calculateDebugTitle"
|
|
||||||
width="760px"
|
|
||||||
class="dpb-calc-debug-dlg"
|
|
||||||
:close-on-click-modal="false"
|
|
||||||
destroy-on-close
|
|
||||||
>
|
|
||||||
<pre class="dpb-calc-debug-pre">{{ calculateDebugText }}</pre>
|
|
||||||
<template #footer>
|
|
||||||
<el-button type="primary" @click="calculateDebugVisible = false">关闭</el-button>
|
|
||||||
</template>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -475,6 +451,7 @@ import {
|
|||||||
customerPriceAdd,
|
customerPriceAdd,
|
||||||
customerPriceListed,
|
customerPriceListed,
|
||||||
customerPriceRemove,
|
customerPriceRemove,
|
||||||
|
buildCustomerPriceAddBody,
|
||||||
buildCustomerPriceWriteBody,
|
buildCustomerPriceWriteBody,
|
||||||
createEmptyCustomerPriceForm,
|
createEmptyCustomerPriceForm,
|
||||||
customerPriceFormFromRow,
|
customerPriceFormFromRow,
|
||||||
@@ -497,13 +474,6 @@ import {
|
|||||||
normalizeFinanceBillType,
|
normalizeFinanceBillType,
|
||||||
} from '@/utils/financeBillTypes'
|
} from '@/utils/financeBillTypes'
|
||||||
import { pickDisplayCode, pickDisplayName } from '@/utils/warehouseOpsDisplay'
|
import { pickDisplayCode, pickDisplayName } from '@/utils/warehouseOpsDisplay'
|
||||||
import {
|
|
||||||
PRICING_TAXPAYER_DEFAULT,
|
|
||||||
PRICING_TRADE_DOMESTIC,
|
|
||||||
formatPricingCalculateDebug,
|
|
||||||
pickPricingCalculateError,
|
|
||||||
pricingCalculate,
|
|
||||||
} from '@/api/pricingTable'
|
|
||||||
|
|
||||||
defineOptions({ name: 'DealerPriceBook' })
|
defineOptions({ name: 'DealerPriceBook' })
|
||||||
|
|
||||||
@@ -558,11 +528,6 @@ const batchEditRows = ref([])
|
|||||||
const formRef = ref()
|
const formRef = ref()
|
||||||
const selected = ref(new Set())
|
const selected = ref(new Set())
|
||||||
|
|
||||||
const calculateDebugVisible = ref(false)
|
|
||||||
const calculateDebugTitle = ref('算价 debug')
|
|
||||||
const calculateDebugText = ref('')
|
|
||||||
const batchCalculating = ref(false)
|
|
||||||
|
|
||||||
const formDialogTitle = computed(() => {
|
const formDialogTitle = computed(() => {
|
||||||
if (formMode.value === 'batch') return `批量修改价格本(${batchEditRows.value.length} 条)`
|
if (formMode.value === 'batch') return `批量修改价格本(${batchEditRows.value.length} 条)`
|
||||||
if (formMode.value === 'edit') return '编辑价格本'
|
if (formMode.value === 'edit') return '编辑价格本'
|
||||||
@@ -741,68 +706,6 @@ function fmtValidStatus(v) {
|
|||||||
return '—'
|
return '—'
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildPricingCalculateBody(row) {
|
|
||||||
const goods_code = String(row?.goods_code ?? '').trim()
|
|
||||||
const customer_price_code = pickCustomerPriceCode(row)
|
|
||||||
return {
|
|
||||||
taxpayer_type: PRICING_TAXPAYER_DEFAULT,
|
|
||||||
trade_type: PRICING_TRADE_DOMESTIC,
|
|
||||||
goods_code,
|
|
||||||
customer_price_code,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function pricingCalculateRowLabel(row) {
|
|
||||||
const name = pickGoodsDisplayName(row)
|
|
||||||
const code = String(row?.goods_code ?? '').trim()
|
|
||||||
if (name && code && name !== code) return `${name}(${code})`
|
|
||||||
return name || code || '—'
|
|
||||||
}
|
|
||||||
|
|
||||||
function openCalculateDebug(title, debugText) {
|
|
||||||
calculateDebugTitle.value = title
|
|
||||||
calculateDebugText.value = String(debugText ?? '').trim()
|
|
||||||
calculateDebugVisible.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
async function runBatchCalculate() {
|
|
||||||
const targets = selectedEditableRows.value.filter((row) => {
|
|
||||||
const goods_code = String(row?.goods_code ?? '').trim()
|
|
||||||
const customer_price_code = pickCustomerPriceCode(row)
|
|
||||||
return goods_code && customer_price_code
|
|
||||||
})
|
|
||||||
if (!targets.length) {
|
|
||||||
ElMessage.warning('请先勾选可计算的物料')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (batchCalculating.value) return
|
|
||||||
|
|
||||||
batchCalculating.value = true
|
|
||||||
const parts = []
|
|
||||||
let failCount = 0
|
|
||||||
|
|
||||||
for (let i = 0; i < targets.length; i += 1) {
|
|
||||||
const row = targets[i]
|
|
||||||
const label = pricingCalculateRowLabel(row)
|
|
||||||
parts.push(`========== ${i + 1}/${targets.length} · ${label} ==========`)
|
|
||||||
try {
|
|
||||||
const res = await pricingCalculate(buildPricingCalculateBody(row))
|
|
||||||
const debug = formatPricingCalculateDebug(res)
|
|
||||||
parts.push(debug || '(无 debug 内容)')
|
|
||||||
} catch (e) {
|
|
||||||
failCount += 1
|
|
||||||
parts.push(`【失败】${pickPricingCalculateError(e)}`)
|
|
||||||
}
|
|
||||||
if (i < targets.length - 1) parts.push('')
|
|
||||||
}
|
|
||||||
|
|
||||||
batchCalculating.value = false
|
|
||||||
openCalculateDebug(
|
|
||||||
`批量算价 debug · ${targets.length} 条${failCount ? `(${failCount} 条失败)` : ''}`,
|
|
||||||
parts.join('\n'),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function fmtNum(v) {
|
function fmtNum(v) {
|
||||||
if (v == null || v === '') return '—'
|
if (v == null || v === '') return '—'
|
||||||
const n = Number(v)
|
const n = Number(v)
|
||||||
@@ -847,7 +750,7 @@ async function loadExpenseBillNames() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function buildFormPayload() {
|
function buildFormPayload() {
|
||||||
return buildCustomerPriceWriteBody(form, {
|
return buildCustomerPriceAddBody(form, {
|
||||||
company_code: String(activeCompanyCode.value || '').trim(),
|
company_code: String(activeCompanyCode.value || '').trim(),
|
||||||
sales_policy_type: 0,
|
sales_policy_type: 0,
|
||||||
})
|
})
|
||||||
@@ -1255,17 +1158,6 @@ onMounted(() => {
|
|||||||
gap: 8px;
|
gap: 8px;
|
||||||
min-height: 24px;
|
min-height: 24px;
|
||||||
}
|
}
|
||||||
.dpb-batch-calc-btn.el-button--success:not(.is-disabled) {
|
|
||||||
--el-button-bg-color: #16a34a;
|
|
||||||
--el-button-border-color: #15803d;
|
|
||||||
--el-button-hover-bg-color: #22c55e;
|
|
||||||
--el-button-hover-border-color: #16a34a;
|
|
||||||
--el-button-active-bg-color: #15803d;
|
|
||||||
--el-button-active-border-color: #166534;
|
|
||||||
font-weight: 700;
|
|
||||||
letter-spacing: 0.02em;
|
|
||||||
box-shadow: 0 1px 4px rgba(22, 163, 74, 0.35);
|
|
||||||
}
|
|
||||||
.dpb-selected-meta {
|
.dpb-selected-meta {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
color: #409eff;
|
color: #409eff;
|
||||||
@@ -1632,21 +1524,6 @@ onMounted(() => {
|
|||||||
.dpb-op-link--muted { color: #909399; }
|
.dpb-op-link--muted { color: #909399; }
|
||||||
.dpb-op-link--muted:hover { color: #606266; }
|
.dpb-op-link--muted:hover { color: #606266; }
|
||||||
|
|
||||||
.dpb-calc-debug-pre {
|
|
||||||
margin: 0;
|
|
||||||
max-height: min(68vh, 640px);
|
|
||||||
overflow: auto;
|
|
||||||
padding: 12px 14px;
|
|
||||||
background: #1e1e1e;
|
|
||||||
color: #d4d4d4;
|
|
||||||
border-radius: 6px;
|
|
||||||
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 1.55;
|
|
||||||
white-space: pre-wrap;
|
|
||||||
word-break: break-word;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dpb-footer {
|
.dpb-footer {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
padding: 10px 16px 14px;
|
padding: 10px 16px 14px;
|
||||||
|
|||||||
@@ -179,6 +179,27 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section class="supply-supplier-info-group">
|
||||||
|
<div class="supply-supplier-info-group-title">其他信息</div>
|
||||||
|
<div class="supply-supplier-info-cards supply-supplier-info-cards--align">
|
||||||
|
<div
|
||||||
|
v-for="card in otherInfoCards"
|
||||||
|
:key="card.key"
|
||||||
|
class="supply-info-card"
|
||||||
|
:style="infoCardGridStyle(card)"
|
||||||
|
>
|
||||||
|
<div class="supply-info-card-icon" :class="`is-${card.tone}`">
|
||||||
|
<Icon :icon="card.icon" />
|
||||||
|
</div>
|
||||||
|
<div class="supply-info-card-body">
|
||||||
|
<div class="supply-info-card-label">{{ card.label }}</div>
|
||||||
|
<div class="supply-info-card-value">{{ card.value }}</div>
|
||||||
|
<div v-if="card.sub" class="supply-info-card-sub">{{ card.sub }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@@ -724,6 +745,7 @@ import {
|
|||||||
pickSupplierSaleType,
|
pickSupplierSaleType,
|
||||||
pickPartnerOrgDisplayName,
|
pickPartnerOrgDisplayName,
|
||||||
pickSupplierDisplayName,
|
pickSupplierDisplayName,
|
||||||
|
formatSupplierSpecialDeliveryCommissionRate,
|
||||||
supplySupplierBlocRemove,
|
supplySupplierBlocRemove,
|
||||||
supplySupplierBlocSceneListed,
|
supplySupplierBlocSceneListed,
|
||||||
supplySupplierBlocSceneSet,
|
supplySupplierBlocSceneSet,
|
||||||
@@ -1035,7 +1057,7 @@ const mainInfoCards = computed(() => {
|
|||||||
|
|
||||||
const businessInfoCards = computed(() => {
|
const businessInfoCards = computed(() => {
|
||||||
const row = activeRow.value
|
const row = activeRow.value
|
||||||
return [
|
const cards = [
|
||||||
{
|
{
|
||||||
key: 'credit_code',
|
key: 'credit_code',
|
||||||
icon: 'mdi:card-account-details-outline',
|
icon: 'mdi:card-account-details-outline',
|
||||||
@@ -1057,6 +1079,13 @@ const businessInfoCards = computed(() => {
|
|||||||
value: displayText(pickSupplierOrgType(row)),
|
value: displayText(pickSupplierOrgType(row)),
|
||||||
tone: 'indigo',
|
tone: 'indigo',
|
||||||
},
|
},
|
||||||
|
]
|
||||||
|
return cards
|
||||||
|
})
|
||||||
|
|
||||||
|
const otherInfoCards = computed(() => {
|
||||||
|
const row = activeRow.value
|
||||||
|
const cards = [
|
||||||
{
|
{
|
||||||
key: 'sales_type',
|
key: 'sales_type',
|
||||||
icon: 'mdi:tag-outline',
|
icon: 'mdi:tag-outline',
|
||||||
@@ -1065,6 +1094,16 @@ const businessInfoCards = computed(() => {
|
|||||||
tone: 'violet',
|
tone: 'violet',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
if (isCustomer.value) {
|
||||||
|
cards.push({
|
||||||
|
key: 'special_delivery_commission_rate',
|
||||||
|
icon: 'mdi:percent-outline',
|
||||||
|
label: '客户专项送货计提率',
|
||||||
|
value: formatSupplierSpecialDeliveryCommissionRate(row),
|
||||||
|
tone: 'amber',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return cards
|
||||||
})
|
})
|
||||||
|
|
||||||
function infoCardGridStyle(card) {
|
function infoCardGridStyle(card) {
|
||||||
|
|||||||
@@ -2604,7 +2604,7 @@ function buildStep3Payload() {
|
|||||||
const baseDelayed = parseWizardInt(form.baseDelayedRebateMonths, { allowZero: true })
|
const baseDelayed = parseWizardInt(form.baseDelayedRebateMonths, { allowZero: true })
|
||||||
const targetDelayed = parseWizardInt(form.targetDelayedRebateMonths, { allowZero: true })
|
const targetDelayed = parseWizardInt(form.targetDelayedRebateMonths, { allowZero: true })
|
||||||
return {
|
return {
|
||||||
payment_days: parseWizardInt(form.paymentMonths),
|
payment_months: parseWizardInt(form.paymentMonths),
|
||||||
acceptance_payment: form.acceptancePayment,
|
acceptance_payment: form.acceptancePayment,
|
||||||
rebate_delay_base_months: baseDelayed,
|
rebate_delay_base_months: baseDelayed,
|
||||||
rebate_delay_target_months: targetDelayed,
|
rebate_delay_target_months: targetDelayed,
|
||||||
|
|||||||
@@ -41,23 +41,10 @@
|
|||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="销售类型">
|
|
||||||
<el-select
|
|
||||||
v-model="form.sale_type"
|
|
||||||
placeholder="请选择"
|
|
||||||
style="width: 100%"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="opt in salesTypeOptions"
|
|
||||||
:key="opt.value"
|
|
||||||
:label="opt.label"
|
|
||||||
:value="opt.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item v-if="showReceiptSwitch" label="是否支持收据">
|
<el-form-item v-if="showReceiptSwitch" label="是否支持收据">
|
||||||
<el-switch v-model="form.is_support_receipt" />
|
<el-switch v-model="form.is_support_receipt" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<div class="supply-supplier-form-section-title">工商信息</div>
|
||||||
<div class="supply-supplier-form-pair-grid">
|
<div class="supply-supplier-form-pair-grid">
|
||||||
<el-form-item label="信用代码">
|
<el-form-item label="信用代码">
|
||||||
<el-input v-model="form.credit_code" clearable />
|
<el-input v-model="form.credit_code" clearable />
|
||||||
@@ -75,6 +62,37 @@
|
|||||||
<el-form-item label="联系地址">
|
<el-form-item label="联系地址">
|
||||||
<el-input v-model="form.contact_address" clearable />
|
<el-input v-model="form.contact_address" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<div class="supply-supplier-form-section-title">其他信息</div>
|
||||||
|
<div class="supply-supplier-form-pair-grid">
|
||||||
|
<el-form-item label="销售类型">
|
||||||
|
<el-select
|
||||||
|
v-model="form.sale_type"
|
||||||
|
placeholder="请选择"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="opt in salesTypeOptions"
|
||||||
|
:key="opt.value"
|
||||||
|
:label="opt.label"
|
||||||
|
:value="opt.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="isCustomer" label="客户专项送货计提率">
|
||||||
|
<div class="supply-supplier-rate-field">
|
||||||
|
<el-input-number
|
||||||
|
v-model="form.special_delivery_commission_rate"
|
||||||
|
:min="0"
|
||||||
|
:max="100"
|
||||||
|
:precision="2"
|
||||||
|
:controls="false"
|
||||||
|
class="supply-supplier-rate-input"
|
||||||
|
placeholder="如:1.5"
|
||||||
|
/>
|
||||||
|
<span class="supply-supplier-rate-unit">%</span>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
<el-form-item label="启用">
|
<el-form-item label="启用">
|
||||||
<el-switch v-model="form.is_valid" />
|
<el-switch v-model="form.is_valid" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -312,6 +330,32 @@ async function submit() {
|
|||||||
.supply-supplier-form--org .supply-supplier-form-pair-grid .el-form-item {
|
.supply-supplier-form--org .supply-supplier-form-pair-grid .el-form-item {
|
||||||
margin-bottom: 18px;
|
margin-bottom: 18px;
|
||||||
}
|
}
|
||||||
|
.supply-supplier-form-section-title {
|
||||||
|
margin: 4px 0 2px;
|
||||||
|
padding-top: 2px;
|
||||||
|
font-size: calc(13px + var(--wh-fs-delta, 0px));
|
||||||
|
font-weight: 600;
|
||||||
|
color: #606266;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
.supply-supplier-rate-field {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.supply-supplier-rate-field .supply-supplier-rate-input {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
.supply-supplier-rate-field .supply-supplier-rate-input .el-input {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.supply-supplier-rate-unit {
|
||||||
|
flex-shrink: 0;
|
||||||
|
color: #909399;
|
||||||
|
font-size: calc(14px + var(--wh-fs-delta, 0px));
|
||||||
|
}
|
||||||
.el-dialog.supply-supplier-form-dlg .el-dialog__body,
|
.el-dialog.supply-supplier-form-dlg .el-dialog__body,
|
||||||
.el-dialog.supply-supplier-form-dlg .el-form-item__label,
|
.el-dialog.supply-supplier-form-dlg .el-form-item__label,
|
||||||
.el-dialog.supply-supplier-form-dlg .el-input__inner,
|
.el-dialog.supply-supplier-form-dlg .el-input__inner,
|
||||||
|
|||||||
Reference in New Issue
Block a user