@longhongguo/form-create-ant-design-vue 3.4.53 → 3.4.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@longhongguo/form-create-ant-design-vue",
3
- "version": "3.4.53",
3
+ "version": "3.4.54",
4
4
  "description": "AntDesignVue版本低代码表单|FormCreate 是一个可以通过 JSON 生成具有动态渲染、数据收集、验证和提交功能的低代码表单生成组件。支持6个UI框架,适配移动端,并且支持生成任何 Vue 组件。内置20种常用表单组件和自定义组件,再复杂的表单都可以轻松搞定。",
5
5
  "main": "./dist/form-create.min.js",
6
6
  "module": "./dist/form-create.esm.js",
@@ -274,16 +274,16 @@
274
274
  <span>{{ item.platformName }}</span>
275
275
  <span>{{ item.settlementText }}</span>
276
276
  </div>
277
- <div class="fc-bsad-grid two mt16">
278
- <div class="fc-bsad-item">
277
+ <div v-if="buildPlatformRows.length" class="fc-bsad-grid two mt16">
278
+ <div v-if="buildPlatformSelectedIds.includes(1)" class="fc-bsad-item">
279
279
  <label>美团建店店名与 logo 来源</label>
280
280
  <div>{{ buildNameLogoModeText(detail.mtBuildNameLogoMode, 'mt') }}</div>
281
281
  </div>
282
- <div class="fc-bsad-item">
283
- <label>饿了么建店店名与 logo 来源</label>
282
+ <div v-if="buildPlatformSelectedIds.includes(2)" class="fc-bsad-item">
283
+ <label>淘宝建店店名与 logo 来源</label>
284
284
  <div>{{ buildNameLogoModeText(detail.ebBuildNameLogoMode, 'eb') }}</div>
285
285
  </div>
286
- <div class="fc-bsad-item">
286
+ <div v-if="buildPlatformSelectedIds.includes(3)" class="fc-bsad-item">
287
287
  <label>京东建店店名与 logo 来源</label>
288
288
  <div>{{ buildNameLogoModeText(detail.jdBuildNameLogoMode, 'jd') }}</div>
289
289
  </div>
@@ -1081,6 +1081,9 @@ export default {
1081
1081
  }))
1082
1082
  })
1083
1083
 
1084
+ /** 与 buildPlatformRows 一致,用于控制各平台「建店店名与 logo 来源」是否展示 */
1085
+ const buildPlatformSelectedIds = computed(() => buildPlatformRows.value.map(r => r.platformId))
1086
+
1084
1087
  function yesNoText(value) {
1085
1088
  if (value === 1) return '是'
1086
1089
  if (value === 0) return '否'
@@ -1106,13 +1109,13 @@ export default {
1106
1109
  }
1107
1110
 
1108
1111
  /**
1109
- * 建店店名与 logo 来源:1 / 2;美团 1 为「智鲜门店名称 + 智鲜品牌 logo」,饿了么/京东 1 为「智鲜」
1112
+ * 建店店名与 logo 来源:1 / 2;美团 1 为「智鲜门店名称 + 智鲜品牌 logo」,淘宝/京东 1 为「智鲜」
1110
1113
  */
1111
1114
  function buildNameLogoModeText(mode, platformKey) {
1112
1115
  const n = toOptionalNumber(mode)
1113
- if (n === 2) return '选择门店名字'
1116
+ if (n === 2) return '选择平台门店名字'
1114
1117
  if (n === 1) {
1115
- return '选择智鲜名字'
1118
+ return '选择智鲜门店名字'
1116
1119
  }
1117
1120
  return '-'
1118
1121
  }
@@ -1250,6 +1253,7 @@ export default {
1250
1253
  foodMainBusinessTypeText,
1251
1254
  foodLicenseValidText,
1252
1255
  buildPlatformRows,
1256
+ buildPlatformSelectedIds,
1253
1257
  repeatStoreCheckRows,
1254
1258
  distanceProtectRows,
1255
1259
  repeatInnerRows,
@@ -18,24 +18,29 @@
18
18
  />
19
19
  <span v-else class="fc-sbra-readonly">{{ storeNameReadonly }}</span>
20
20
  </a-form-item>
21
-
22
- <div class="fc-sbra-section-label">当前平台费率与加包装费</div>
23
- <a-row :gutter="[12, 16]" class="fc-sbra-rate-grid">
24
- <a-col v-for="row in platformRows" :key="row.key" :xs="24" :lg="24">
25
- <div class="fc-sbra-pair">
26
- <div class="fc-sbra-field">
27
- <span class="fc-sbra-inline-label">{{ row.rateTitle }}</span>
28
- <span class="fc-sbra-value">{{ rateDisplay(row.rateField) || '—' }}</span>
29
- <span class="fc-sbra-suffix">%</span>
30
- </div>
31
- <div class="fc-sbra-field">
32
- <span class="fc-sbra-inline-label">加包装费</span>
33
- <span class="fc-sbra-value">{{ rateDisplay(row.pkgField) || '—' }}</span>
34
- <span class="fc-sbra-suffix fc-sbra-suffix-yuan">元</span>
21
+ <a-form-item
22
+ label=" "
23
+ :colon="false"
24
+ v-if="local.storeNameArr && local.storeNameArr.length > 0"
25
+ >
26
+ <div class="fc-sbra-section-label">所选门店各平台扣点与加包装费</div>
27
+ <a-row :gutter="[12, 16]" class="fc-sbra-rate-grid">
28
+ <a-col v-for="row in platformRows" :key="row.key" :xs="24" :lg="24">
29
+ <div class="fc-sbra-pair">
30
+ <div class="fc-sbra-field">
31
+ <span class="fc-sbra-inline-label">{{ row.rateTitle }}</span>
32
+ <span class="fc-sbra-value">{{ rateDisplay(row.rateField) || '—' }}</span>
33
+ <span class="fc-sbra-suffix">%</span>
34
+ </div>
35
+ <div class="fc-sbra-field">
36
+ <span class="fc-sbra-inline-label">加包装费</span>
37
+ <span class="fc-sbra-value">{{ rateDisplay(row.pkgField) || '—' }}</span>
38
+ <span class="fc-sbra-suffix fc-sbra-suffix-yuan">元</span>
39
+ </div>
35
40
  </div>
36
- </div>
37
- </a-col>
38
- </a-row>
41
+ </a-col>
42
+ </a-row>
43
+ </a-form-item>
39
44
 
40
45
  <a-form-item label="新扣点比例" name="newDeductionRatio" :rules="formRules.newDeductionRatio">
41
46
  <a-select
@@ -435,7 +440,9 @@ export default {
435
440
  margin: 8px 0 12px;
436
441
  }
437
442
  .fc-sbra-rate-grid {
443
+ padding: 10px;
438
444
  margin-bottom: 16px;
445
+ background-color: #fafafa;
439
446
  }
440
447
  .fc-sbra-pair {
441
448
  display: flex;
@@ -0,0 +1,647 @@
1
+ <template>
2
+ <div class="fc-spsp-block">
3
+ <a-form
4
+ ref="formRef"
5
+ :model="local"
6
+ :disabled="readOnly"
7
+ :label-col="{ style: { width: '140px' } }"
8
+ :wrapper-col="{ span: 18 }"
9
+ >
10
+ <a-form-item label="智鲜门店名称" name="storeNameArr" :rules="formRules.storeNameArr">
11
+ <CusStoreSelect
12
+ v-if="!readOnly"
13
+ :model-value="local.storeNameArr"
14
+ :form-create-inject="formCreateInject"
15
+ :multiple="false"
16
+ placeholder="请选择门店"
17
+ @change="onStoreChange"
18
+ />
19
+ <span v-else class="fc-spsp-readonly">{{ storeNameReadonly }}</span>
20
+ </a-form-item>
21
+
22
+ <a-form-item label="当前模式" class="fc-spsp-mode-item">
23
+ <strong class="fc-spsp-mode-bold">{{ currentModeBoldText }}</strong>
24
+ </a-form-item>
25
+
26
+ <a-form-item label="切换新模式" class="fc-spsp-mode-item">
27
+ <strong class="fc-spsp-mode-bold">{{ newModeBoldText }}</strong>
28
+ </a-form-item>
29
+
30
+ <!-- 报价 → 扣点 -->
31
+ <template v-if="showDeductionBranch">
32
+ <div class="fc-spsp-section-title">切换后门店扣点比例</div>
33
+
34
+ <a-form-item label="公司承担包装袋" name="companyBearBag" :rules="formRules.companyBearBag">
35
+ <a-radio-group v-if="!readOnly" v-model:value="local.companyBearBag" @change="onCompanyBearBagChange">
36
+ <a-radio :value="1">是</a-radio>
37
+ <a-radio :value="0">否</a-radio>
38
+ </a-radio-group>
39
+ <span v-else class="fc-spsp-readonly">{{
40
+ radioLabel(companyBearBagOptions, local.companyBearBag)
41
+ }}</span>
42
+ </a-form-item>
43
+
44
+ <div class="fc-spsp-platform-wrap">
45
+ <div
46
+ v-for="row in platformRows"
47
+ :key="row.key"
48
+ class="fc-spsp-platform-row"
49
+ >
50
+ <div class="fc-spsp-platform-label">{{ row.label }}</div>
51
+ <div class="fc-spsp-platform-fields">
52
+ <a-form-item
53
+ :name="['platformDeduction', row.key, 'rate']"
54
+ :rules="formRules.platformRateRules"
55
+ class="fc-spsp-inline-item"
56
+ >
57
+ <a-select
58
+ v-if="!readOnly"
59
+ v-model:value="local.platformDeduction[row.key].rate"
60
+ placeholder="扣点比例"
61
+ allow-clear
62
+ :options="deductionSelectOptions"
63
+ :get-popup-container="popupContainer"
64
+ style="width: 120px"
65
+ @change="onPlatformRateChange(row.key)"
66
+ />
67
+ <span v-else class="fc-spsp-readonly">{{ local.platformDeduction[row.key].rate ?? '—' }}%</span>
68
+ </a-form-item>
69
+ <template v-if="local.companyBearBag === 1">
70
+ <span class="fc-spsp-platform-plus">+</span>
71
+ <span class="fc-spsp-platform-static">公司收取包装费</span>
72
+ <a-form-item
73
+ :name="['platformDeduction', row.key, 'packageFee']"
74
+ :rules="formRules.platformPackageRules"
75
+ class="fc-spsp-inline-item"
76
+ >
77
+ <a-select
78
+ v-if="!readOnly"
79
+ v-model:value="local.platformDeduction[row.key].packageFee"
80
+ placeholder="元"
81
+ allow-clear
82
+ :options="packageSelectOptions"
83
+ :get-popup-container="popupContainer"
84
+ style="width: 100px"
85
+ @change="onPlatformPackageChange(row.key)"
86
+ />
87
+ <span v-else class="fc-spsp-readonly">{{ local.platformDeduction[row.key].packageFee ?? '—' }}</span>
88
+ </a-form-item>
89
+ <span v-if="!readOnly || local.platformDeduction[row.key].packageFee != null" class="fc-spsp-platform-unit">元</span>
90
+ </template>
91
+ </div>
92
+ </div>
93
+ </div>
94
+
95
+ <ul class="fc-spsp-hints">
96
+ <li>当公司承担包装袋为「否」时,不展示公司收取包装费;</li>
97
+ <li>扣点比例:1%~15%,每 1% 一档;</li>
98
+ <li>包装费:0.1~1 元,每 0.1 一档;</li>
99
+ <li>先填写「美团」后,将默认同步到其余平台,之后各平台可单独修改。</li>
100
+ </ul>
101
+ </template>
102
+
103
+ <!-- 扣点 → 报价 -->
104
+ <template v-else-if="showQuoteBranch">
105
+ <a-form-item label="公司承担包装袋" name="companyBearBag" :rules="formRules.companyBearBag">
106
+ <a-radio-group v-if="!readOnly" v-model:value="local.companyBearBag" disabled>
107
+ <a-radio :value="1">是</a-radio>
108
+ <a-radio :value="0">否</a-radio>
109
+ </a-radio-group>
110
+ <span v-else class="fc-spsp-readonly">{{
111
+ radioLabel(companyBearBagOptions, local.companyBearBag)
112
+ }}</span>
113
+ </a-form-item>
114
+ </template>
115
+
116
+ <a-form-item label="申请/备注原因" name="applyReason" :rules="formRules.applyReason">
117
+ <FcEditorWrapper
118
+ :model-value="local.applyReason"
119
+ :form-create-inject="formCreateInject"
120
+ :read-only="readOnly"
121
+ placeholder="请填写申请或备注原因"
122
+ :height="220"
123
+ @update:model-value="onApplyReasonUpdate"
124
+ />
125
+ </a-form-item>
126
+ </a-form>
127
+ </div>
128
+ </template>
129
+
130
+ <script>
131
+ import { ref, computed, watch, reactive } from 'vue'
132
+ import CusStoreSelect from '../CusStoreSelect/index.vue'
133
+ import FcEditorWrapper from '../FcEditorWrapper.vue'
134
+
135
+ const PLATFORM_ROWS = [
136
+ { key: 'mt', label: '美团' },
137
+ { key: 'tb', label: '淘宝' },
138
+ { key: 'jd', label: '京东' },
139
+ { key: 'applet', label: '小程序' }
140
+ ]
141
+
142
+ const DEDUCTION_SELECT_OPTIONS = Array.from({ length: 15 }, (_, i) => {
143
+ const v = i + 1
144
+ return { label: `${v}%`, value: v }
145
+ })
146
+
147
+ const PACKAGE_SELECT_OPTIONS = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1].map(n => ({
148
+ label: String(n),
149
+ value: n
150
+ }))
151
+
152
+ const COMPANY_BEAR_BAG_OPTIONS = [
153
+ { label: '是', value: 1 },
154
+ { label: '否', value: 0 }
155
+ ]
156
+
157
+ function emptyPlatformSlot() {
158
+ return { rate: undefined, packageFee: undefined }
159
+ }
160
+
161
+ function emptyPlatformDeduction() {
162
+ return {
163
+ mt: emptyPlatformSlot(),
164
+ tb: emptyPlatformSlot(),
165
+ jd: emptyPlatformSlot(),
166
+ applet: emptyPlatformSlot()
167
+ }
168
+ }
169
+
170
+ function defaultModel() {
171
+ return {
172
+ storeName: '',
173
+ storeId: '',
174
+ storeNameArr: [],
175
+ oldPricingMode: undefined,
176
+ newPricingMode: undefined,
177
+ companyBearBag: undefined,
178
+ platformDeduction: emptyPlatformDeduction(),
179
+ applyReason: '',
180
+ storeInfo: null
181
+ }
182
+ }
183
+
184
+ function normalizeLocal(v) {
185
+ const d = defaultModel()
186
+ if (!v || typeof v !== 'object') return d
187
+ const merged = { ...d, ...v }
188
+ if (!Array.isArray(merged.storeNameArr)) merged.storeNameArr = []
189
+ merged.platformDeduction = {
190
+ ...emptyPlatformDeduction(),
191
+ ...(merged.platformDeduction || {})
192
+ }
193
+ PLATFORM_ROWS.forEach(({ key }) => {
194
+ merged.platformDeduction[key] = {
195
+ ...emptyPlatformSlot(),
196
+ ...(merged.platformDeduction[key] || {})
197
+ }
198
+ })
199
+ return merged
200
+ }
201
+
202
+ function applyStoreSelectionLogic(target, storeInfo) {
203
+ target.storeInfo = storeInfo ?? null
204
+ const pm = storeInfo?.pricingMode
205
+ const num = pm === '' || pm == null ? undefined : Number(pm)
206
+ target.oldPricingMode = Number.isFinite(num) ? num : undefined
207
+
208
+ const newPricingMode = num === 1 ? 2 : 1
209
+ target.newPricingMode = newPricingMode
210
+ target.platformDeduction = emptyPlatformDeduction()
211
+
212
+ if (newPricingMode === 1) {
213
+ target.companyBearBag = null
214
+ } else {
215
+ target.companyBearBag = 1
216
+ }
217
+ }
218
+
219
+ function clearAfterStoreReset(target) {
220
+ target.storeInfo = null
221
+ target.oldPricingMode = undefined
222
+ target.newPricingMode = undefined
223
+ target.companyBearBag = undefined
224
+ target.platformDeduction = emptyPlatformDeduction()
225
+ }
226
+
227
+ function stripRichText(val) {
228
+ if (val == null) return ''
229
+ return String(val)
230
+ .replace(/<[^>]*>/g, '')
231
+ .replace(/&nbsp;/gi, ' ')
232
+ .trim()
233
+ }
234
+
235
+ export default {
236
+ name: 'StorePricingModeSwitchBlock',
237
+ components: { CusStoreSelect, FcEditorWrapper },
238
+ props: {
239
+ modelValue: {
240
+ type: Object,
241
+ default: null
242
+ },
243
+ formCreateInject: {
244
+ type: Object,
245
+ default: null
246
+ }
247
+ },
248
+ emits: ['update:modelValue'],
249
+ setup(props, { emit }) {
250
+ const formRef = ref(null)
251
+ const local = ref(normalizeLocal(props.modelValue))
252
+ /** 非美团平台是否被用户手动改过(改过则不再跟美团同步) */
253
+ const platformDirty = reactive({ tb: false, jd: false, applet: false })
254
+
255
+ const readOnly = computed(() => !!props.formCreateInject?.preview)
256
+ const platformRows = PLATFORM_ROWS
257
+ const deductionSelectOptions = DEDUCTION_SELECT_OPTIONS
258
+ const packageSelectOptions = PACKAGE_SELECT_OPTIONS
259
+ const companyBearBagOptions = COMPANY_BEAR_BAG_OPTIONS
260
+
261
+ const showDeductionBranch = computed(() => local.value.newPricingMode === 1)
262
+ const showQuoteBranch = computed(() => local.value.newPricingMode === 2)
263
+
264
+ const currentModeBoldText = computed(() => {
265
+ const m = local.value.oldPricingMode
266
+ if (m === 1) return '当前模式(扣点)'
267
+ if (m === 2) return '当前模式(报价)'
268
+ return '当前模式(—)'
269
+ })
270
+
271
+ const newModeBoldText = computed(() => {
272
+ const m = local.value.newPricingMode
273
+ if (m === 1) return '切换新模式(扣点)'
274
+ if (m === 2) return '切换新模式(报价)'
275
+ return '切换新模式(—)'
276
+ })
277
+
278
+ const storeNameReadonly = computed(() => {
279
+ const n = local.value.storeName
280
+ if (n) return n
281
+ const arr = local.value.storeNameArr
282
+ if (Array.isArray(arr) && arr.length && arr[0] && typeof arr[0] === 'object') {
283
+ return arr[0].label ?? arr[0].name ?? '—'
284
+ }
285
+ return '—'
286
+ })
287
+
288
+ function popupContainer(node) {
289
+ return node?.parentElement ?? document.body
290
+ }
291
+
292
+ function radioLabel(options, value) {
293
+ if (value === undefined || value === null) return '—'
294
+ const n = Number(value)
295
+ const hit = options.find(o => o.value === n || o.value === value)
296
+ return hit ? hit.label : String(value)
297
+ }
298
+
299
+ function emitChange() {
300
+ emit('update:modelValue', { ...local.value })
301
+ }
302
+
303
+ function resetPlatformDirty() {
304
+ platformDirty.tb = false
305
+ platformDirty.jd = false
306
+ platformDirty.applet = false
307
+ }
308
+
309
+ function syncFromLeader() {
310
+ const src = local.value.platformDeduction.mt
311
+ ;['tb', 'jd', 'applet'].forEach(k => {
312
+ if (!platformDirty[k]) {
313
+ local.value.platformDeduction[k].rate = src.rate
314
+ local.value.platformDeduction[k].packageFee = src.packageFee
315
+ }
316
+ })
317
+ }
318
+
319
+ function onPlatformRateChange(platformKey) {
320
+ if (platformKey === 'mt') {
321
+ syncFromLeader()
322
+ } else {
323
+ platformDirty[platformKey] = true
324
+ }
325
+ emitChange()
326
+ queueMicrotask(() => {
327
+ formRef.value?.validateFields?.([['platformDeduction', platformKey, 'rate']]).catch(() => {})
328
+ })
329
+ }
330
+
331
+ function onPlatformPackageChange(platformKey) {
332
+ if (platformKey === 'mt') {
333
+ syncFromLeader()
334
+ } else {
335
+ platformDirty[platformKey] = true
336
+ }
337
+ emitChange()
338
+ queueMicrotask(() => {
339
+ formRef.value
340
+ ?.validateFields?.([['platformDeduction', platformKey, 'packageFee']])
341
+ .catch(() => {})
342
+ })
343
+ }
344
+
345
+ function onCompanyBearBagChange() {
346
+ if (local.value.companyBearBag !== 1) {
347
+ PLATFORM_ROWS.forEach(({ key }) => {
348
+ local.value.platformDeduction[key].packageFee = undefined
349
+ })
350
+ }
351
+ emitChange()
352
+ queueMicrotask(() => {
353
+ PLATFORM_ROWS.forEach(({ key }) => {
354
+ formRef.value
355
+ ?.validateFields?.([['platformDeduction', key, 'packageFee']])
356
+ .catch(() => {})
357
+ })
358
+ })
359
+ }
360
+
361
+ function onApplyReasonUpdate(v) {
362
+ local.value.applyReason = v ?? ''
363
+ emitChange()
364
+ queueMicrotask(() => {
365
+ formRef.value?.validateFields?.(['applyReason']).catch(() => {})
366
+ })
367
+ }
368
+
369
+ function nextTickValidate(names) {
370
+ if (!names?.length) return
371
+ queueMicrotask(() => {
372
+ formRef.value?.validateFields?.(names).catch(() => {})
373
+ })
374
+ }
375
+
376
+ function onStoreChange(value, item) {
377
+ local.value.storeNameArr = Array.isArray(value) ? value : []
378
+ resetPlatformDirty()
379
+ if (!item || item.value == null || item.value === '') {
380
+ local.value.storeId = ''
381
+ local.value.storeName = ''
382
+ clearAfterStoreReset(local.value)
383
+ emitChange()
384
+ return
385
+ }
386
+ local.value.storeId = item.value
387
+ local.value.storeName = item.label ?? ''
388
+ emitChange()
389
+
390
+ const api = props.formCreateInject?.api
391
+ if (!api || typeof api.getStoreInfo !== 'function') return
392
+
393
+ api
394
+ .getStoreInfo(item.value)
395
+ .then(storeInfo => {
396
+ resetPlatformDirty()
397
+ if (storeInfo) applyStoreSelectionLogic(local.value, storeInfo)
398
+ else clearAfterStoreReset(local.value)
399
+ emitChange()
400
+ nextTickValidate(['companyBearBag'])
401
+ })
402
+ .catch(() => {})
403
+ }
404
+
405
+ const modeHint = '请选择设置了配送模式的门店/平台'
406
+
407
+ const formRules = computed(() => {
408
+ const v = local.value
409
+ const rules = {
410
+ storeNameArr: [
411
+ {
412
+ required: true,
413
+ validator: (_r, val) => {
414
+ const arr = Array.isArray(val) ? val : []
415
+ if (arr.length === 0) return Promise.reject(new Error('请选择门店'))
416
+ return Promise.resolve()
417
+ },
418
+ trigger: 'change'
419
+ }
420
+ ],
421
+ applyReason: [
422
+ {
423
+ validator: (_r, val) => {
424
+ if (!stripRichText(val)) return Promise.reject(new Error('请填写申请/备注原因'))
425
+ return Promise.resolve()
426
+ },
427
+ trigger: 'blur'
428
+ }
429
+ ],
430
+ platformRateRules: [
431
+ {
432
+ required: true,
433
+ validator: (_r, val) => {
434
+ if (v.newPricingMode !== 1) return Promise.resolve()
435
+ if (val === '' || val === undefined || val === null) {
436
+ return Promise.reject(new Error('请选择扣点比例'))
437
+ }
438
+ const n = Number(val)
439
+ if (!Number.isFinite(n) || n < 1 || n > 15) {
440
+ return Promise.reject(new Error('扣点比例须在 1%~15%'))
441
+ }
442
+ return Promise.resolve()
443
+ },
444
+ trigger: 'change'
445
+ }
446
+ ],
447
+ platformPackageRules: [
448
+ {
449
+ validator: (_r, val) => {
450
+ if (v.newPricingMode !== 1 || v.companyBearBag !== 1) return Promise.resolve()
451
+ if (val === '' || val === undefined || val === null) {
452
+ return Promise.reject(new Error('请选择包装费'))
453
+ }
454
+ return Promise.resolve()
455
+ },
456
+ trigger: 'change'
457
+ }
458
+ ]
459
+ }
460
+
461
+ rules.companyBearBag = [
462
+ {
463
+ validator: (_r, val) => {
464
+ if (v.newPricingMode === 1) {
465
+ if (val !== 0 && val !== 1) {
466
+ return Promise.reject(new Error('请选择公司承担包装袋'))
467
+ }
468
+ } else if (v.newPricingMode === 2) {
469
+ if (val !== 1) return Promise.reject(new Error('公司承担包装袋须为「是」'))
470
+ }
471
+ return Promise.resolve()
472
+ },
473
+ trigger: 'change'
474
+ }
475
+ ]
476
+
477
+ return rules
478
+ })
479
+
480
+ /** 无 name 的展示项:在提交前校验门店已带出模式 */
481
+ function validateModes() {
482
+ const v = local.value
483
+ if (!v.storeId && !v.storeNameArr?.length) return Promise.resolve()
484
+ if (v.oldPricingMode !== 1 && v.oldPricingMode !== 2) {
485
+ return Promise.reject(new Error(modeHint))
486
+ }
487
+ if (v.newPricingMode !== 1 && v.newPricingMode !== 2) {
488
+ return Promise.reject(new Error(modeHint))
489
+ }
490
+ return Promise.resolve()
491
+ }
492
+
493
+ function validate() {
494
+ return validateModes().then(() => {
495
+ if (!formRef.value?.validate) return Promise.resolve()
496
+ return formRef.value.validate().catch(err => Promise.reject(err || new Error('请完善表单')))
497
+ })
498
+ }
499
+
500
+ watch(
501
+ () => props.modelValue,
502
+ val => {
503
+ if (val && typeof val === 'object') local.value = normalizeLocal(val)
504
+ },
505
+ { deep: true }
506
+ )
507
+
508
+ return {
509
+ formRef,
510
+ local,
511
+ readOnly,
512
+ platformRows,
513
+ deductionSelectOptions,
514
+ packageSelectOptions,
515
+ companyBearBagOptions,
516
+ storeNameReadonly,
517
+ showDeductionBranch,
518
+ showQuoteBranch,
519
+ currentModeBoldText,
520
+ newModeBoldText,
521
+ formRules,
522
+ popupContainer,
523
+ radioLabel,
524
+ emitChange,
525
+ onStoreChange,
526
+ onCompanyBearBagChange,
527
+ onPlatformRateChange,
528
+ onPlatformPackageChange,
529
+ onApplyReasonUpdate,
530
+ validate
531
+ }
532
+ },
533
+ mounted() {
534
+ const inj = this.formCreateInject
535
+ const id = inj?.businessComponentId
536
+ const registry = inj?.$bcVm || inj?.$handle
537
+ if (id && registry?.registerBusinessComponent) {
538
+ registry.registerBusinessComponent(id, this)
539
+ }
540
+ },
541
+ beforeUnmount() {
542
+ const id = this.formCreateInject?.businessComponentId
543
+ const registry = this.formCreateInject?.$bcVm || this.formCreateInject?.$handle
544
+ if (id && registry?.unregisterBusinessComponent) registry.unregisterBusinessComponent(id)
545
+ },
546
+ methods: {
547
+ onSubmitPhase() {
548
+ return Promise.resolve()
549
+ }
550
+ }
551
+ }
552
+ </script>
553
+
554
+ <style scoped>
555
+ .fc-spsp-block {
556
+ padding: 0 4px;
557
+ overflow: visible;
558
+ }
559
+ .fc-spsp-block :deep(.ant-form) {
560
+ overflow: visible;
561
+ }
562
+ .fc-spsp-block :deep(.ant-form-item) {
563
+ margin-bottom: 24px;
564
+ }
565
+ .fc-spsp-block :deep(.ant-form-item.ant-form-item-with-help),
566
+ .fc-spsp-block :deep(.ant-form-item.ant-form-item-has-error) {
567
+ margin-bottom: 24px !important;
568
+ }
569
+ .fc-spsp-block :deep(.ant-form-item-control),
570
+ .fc-spsp-block :deep(.ant-form-item-control-input),
571
+ .fc-spsp-block :deep(.ant-form-item-control-input-content) {
572
+ overflow: visible !important;
573
+ }
574
+ .fc-spsp-block :deep(.ant-form-item-explain),
575
+ .fc-spsp-block :deep(.ant-form-item-extra) {
576
+ line-height: 1.5;
577
+ }
578
+ .fc-spsp-block :deep(.ant-form-item .ant-row) {
579
+ align-items: flex-start;
580
+ }
581
+ .fc-spsp-mode-item :deep(.ant-form-item-label > label) {
582
+ color: rgba(0, 0, 0, 0.88);
583
+ }
584
+ .fc-spsp-mode-bold {
585
+ font-size: 14px;
586
+ color: rgba(0, 0, 0, 0.88);
587
+ }
588
+ .fc-spsp-section-title {
589
+ font-weight: 600;
590
+ font-size: 14px;
591
+ color: rgba(0, 0, 0, 0.88);
592
+ margin: 4px 0 12px;
593
+ padding-bottom: 8px;
594
+ border-bottom: 1px solid #f0f0f0;
595
+ }
596
+ .fc-spsp-platform-wrap {
597
+ margin-bottom: 12px;
598
+ }
599
+ .fc-spsp-platform-row {
600
+ display: flex;
601
+ flex-wrap: wrap;
602
+ align-items: flex-start;
603
+ gap: 8px 12px;
604
+ margin-bottom: 12px;
605
+ }
606
+ .fc-spsp-platform-label {
607
+ min-width: 56px;
608
+ padding-top: 4px;
609
+ color: rgba(0, 0, 0, 0.65);
610
+ font-size: 14px;
611
+ }
612
+ .fc-spsp-platform-fields {
613
+ display: flex;
614
+ flex-wrap: wrap;
615
+ align-items: center;
616
+ gap: 6px 8px;
617
+ flex: 1;
618
+ min-width: 0;
619
+ }
620
+ .fc-spsp-inline-item {
621
+ margin-bottom: 0 !important;
622
+ }
623
+ .fc-spsp-platform-plus {
624
+ color: rgba(0, 0, 0, 0.45);
625
+ }
626
+ .fc-spsp-platform-static {
627
+ font-size: 14px;
628
+ color: rgba(0, 0, 0, 0.65);
629
+ white-space: nowrap;
630
+ }
631
+ .fc-spsp-platform-unit {
632
+ font-size: 14px;
633
+ color: rgba(0, 0, 0, 0.45);
634
+ }
635
+ .fc-spsp-hints {
636
+ margin: 0 0 20px;
637
+ padding-left: 18px;
638
+ font-size: 12px;
639
+ color: rgba(0, 0, 0, 0.45);
640
+ line-height: 1.6;
641
+ }
642
+ .fc-spsp-readonly {
643
+ color: #333;
644
+ display: inline-block;
645
+ min-height: 22px;
646
+ }
647
+ </style>