Commit 27fb1711094f8eee3fea27ec6cc2313ad5a0885a
1 parent
d4a6cf68
feat(erp): WtAccount 与收款账户展示,多模块表单/收银与后端联动
Made-with: Cursor
Showing
118 changed files
with
3859 additions
and
1255 deletions
Antis.Erp.Plat/antis-ncc-admin/src/api/extend/wtAccount.js
0 → 100644
| 1 | +import request from '@/utils/request' | |
| 2 | + | |
| 3 | +export function getAccountSelector(storeId) { | |
| 4 | + const data = {} | |
| 5 | + if (storeId) data.storeId = storeId | |
| 6 | + return request({ | |
| 7 | + url: '/api/Extend/WtAccount/Selector', | |
| 8 | + method: 'GET', | |
| 9 | + data | |
| 10 | + }) | |
| 11 | +} | |
| 12 | + | |
| 13 | +export function getAccountList(params) { | |
| 14 | + return request({ | |
| 15 | + url: '/api/Extend/WtAccount', | |
| 16 | + method: 'GET', | |
| 17 | + data: params | |
| 18 | + }) | |
| 19 | +} | |
| 20 | + | |
| 21 | +export function getAccountInfo(id) { | |
| 22 | + return request({ | |
| 23 | + url: '/api/Extend/WtAccount/' + id, | |
| 24 | + method: 'GET' | |
| 25 | + }) | |
| 26 | +} | |
| 27 | + | |
| 28 | +export function createAccount(data) { | |
| 29 | + return request({ | |
| 30 | + url: '/api/Extend/WtAccount', | |
| 31 | + method: 'POST', | |
| 32 | + data | |
| 33 | + }) | |
| 34 | +} | |
| 35 | + | |
| 36 | +export function updateAccount(id, data) { | |
| 37 | + return request({ | |
| 38 | + url: '/api/Extend/WtAccount/' + id, | |
| 39 | + method: 'PUT', | |
| 40 | + data | |
| 41 | + }) | |
| 42 | +} | |
| 43 | + | |
| 44 | +export function deleteAccount(id) { | |
| 45 | + return request({ | |
| 46 | + url: '/api/Extend/WtAccount/' + id, | |
| 47 | + method: 'DELETE' | |
| 48 | + }) | |
| 49 | +} | |
| 50 | + | |
| 51 | +export function batchRemoveAccount(ids) { | |
| 52 | + return request({ | |
| 53 | + url: '/api/Extend/WtAccount/batchRemove', | |
| 54 | + method: 'POST', | |
| 55 | + data: ids | |
| 56 | + }) | |
| 57 | +} | |
| 58 | + | |
| 59 | +export function getAccountCategories() { | |
| 60 | + return request({ | |
| 61 | + url: '/api/Extend/WtAccount/Categories', | |
| 62 | + method: 'GET' | |
| 63 | + }) | |
| 64 | +} | |
| 65 | + | |
| 66 | +export function exportAccount(params) { | |
| 67 | + return request({ | |
| 68 | + url: '/api/Extend/WtAccount/Actions/Export', | |
| 69 | + method: 'GET', | |
| 70 | + data: params | |
| 71 | + }) | |
| 72 | +} | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/utils/wtComboSkzhDisplay.js
| ... | ... | @@ -15,7 +15,7 @@ export function resolveSkzhDictionaryLabel(id, options) { |
| 15 | 15 | return oid === sid || ofid === sid |
| 16 | 16 | }) |
| 17 | 17 | if (!row) return '' |
| 18 | - const name = (row.fullName || row.F_FullName || row.F_mdmc || '').trim() | |
| 18 | + const name = (row.fullName || row.accountName || row.F_FullName || row.F_mdmc || '').trim() | |
| 19 | 19 | return name || '' |
| 20 | 20 | } |
| 21 | 21 | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtBjdbd/Form.vue
| ... | ... | @@ -290,10 +290,10 @@ |
| 290 | 290 | </template> |
| 291 | 291 | <script> |
| 292 | 292 | import request from '@/utils/request' |
| 293 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 294 | 293 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 295 | 294 | import BarcodeSelect from '../wtCgrkd/BarcodeSelect.vue' |
| 296 | 295 | import SerialNumberSelect from './SerialNumberSelect.vue' |
| 296 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 297 | 297 | export default { |
| 298 | 298 | components: { BarcodeSelect, SerialNumberSelect }, |
| 299 | 299 | props: [], |
| ... | ... | @@ -657,7 +657,7 @@ |
| 657 | 657 | }); |
| 658 | 658 | }, |
| 659 | 659 | getskzhOptions(){ |
| 660 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 660 | + getAccountSelector().then(res => { | |
| 661 | 661 | this.skzhOptions = res.data.list |
| 662 | 662 | }); |
| 663 | 663 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtBjdbd/index.vue
| ... | ... | @@ -217,10 +217,10 @@ |
| 217 | 217 | </template> |
| 218 | 218 | <script> |
| 219 | 219 | import request from '@/utils/request' |
| 220 | -import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 221 | 220 | import NCCForm from './Form' |
| 222 | 221 | import ExportBox from './ExportBox' |
| 223 | 222 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 223 | +import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 224 | 224 | |
| 225 | 225 | export default { |
| 226 | 226 | components: { NCCForm, ExportBox }, |
| ... | ... | @@ -321,7 +321,7 @@ export default { |
| 321 | 321 | }) |
| 322 | 322 | }, |
| 323 | 323 | getskzhOptions() { |
| 324 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 324 | + getAccountSelector().then(res => { | |
| 325 | 325 | this.skzhOptions = res.data.list |
| 326 | 326 | }) |
| 327 | 327 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtBsd/Form.vue
| ... | ... | @@ -267,10 +267,10 @@ |
| 267 | 267 | </template> |
| 268 | 268 | <script> |
| 269 | 269 | import request from '@/utils/request' |
| 270 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 271 | 270 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 272 | 271 | import BarcodeSelect from '../wtCgrkd/BarcodeSelect.vue' |
| 273 | 272 | import SerialNumberSelect from './SerialNumberSelect.vue' |
| 273 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 274 | 274 | export default { |
| 275 | 275 | components: { BarcodeSelect, SerialNumberSelect }, |
| 276 | 276 | props: [], |
| ... | ... | @@ -583,7 +583,7 @@ |
| 583 | 583 | }); |
| 584 | 584 | }, |
| 585 | 585 | getskzhOptions(){ |
| 586 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 586 | + getAccountSelector().then(res => { | |
| 587 | 587 | this.skzhOptions = res.data.list |
| 588 | 588 | }); |
| 589 | 589 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtBsd/index.vue
| ... | ... | @@ -144,10 +144,10 @@ |
| 144 | 144 | </template> |
| 145 | 145 | <script> |
| 146 | 146 | import request from '@/utils/request' |
| 147 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 148 | 147 | import NCCForm from './Form' |
| 149 | 148 | import ExportBox from './ExportBox' |
| 150 | 149 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 150 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 151 | 151 | export default { |
| 152 | 152 | components: { NCCForm, ExportBox }, |
| 153 | 153 | data() { |
| ... | ... | @@ -218,7 +218,7 @@ |
| 218 | 218 | }); |
| 219 | 219 | }, |
| 220 | 220 | getskzhOptions(){ |
| 221 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 221 | + getAccountSelector().then(res => { | |
| 222 | 222 | this.skzhOptions = res.data.list |
| 223 | 223 | }); |
| 224 | 224 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtByd/Form.vue
| ... | ... | @@ -267,10 +267,10 @@ |
| 267 | 267 | </template> |
| 268 | 268 | <script> |
| 269 | 269 | import request from '@/utils/request' |
| 270 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 271 | 270 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 272 | 271 | import BarcodeSelect from '../wtCgrkd/BarcodeSelect.vue' |
| 273 | 272 | import SerialNumberSelect from './SerialNumberSelect.vue' |
| 273 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 274 | 274 | export default { |
| 275 | 275 | components: { BarcodeSelect, SerialNumberSelect }, |
| 276 | 276 | props: [], |
| ... | ... | @@ -583,7 +583,7 @@ |
| 583 | 583 | }); |
| 584 | 584 | }, |
| 585 | 585 | getskzhOptions(){ |
| 586 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 586 | + getAccountSelector().then(res => { | |
| 587 | 587 | this.skzhOptions = res.data.list |
| 588 | 588 | }); |
| 589 | 589 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtByd/index.vue
| ... | ... | @@ -144,10 +144,10 @@ |
| 144 | 144 | </template> |
| 145 | 145 | <script> |
| 146 | 146 | import request from '@/utils/request' |
| 147 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 148 | 147 | import NCCForm from './Form' |
| 149 | 148 | import ExportBox from './ExportBox' |
| 150 | 149 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 150 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 151 | 151 | export default { |
| 152 | 152 | components: { NCCForm, ExportBox }, |
| 153 | 153 | data() { |
| ... | ... | @@ -218,7 +218,7 @@ |
| 218 | 218 | }); |
| 219 | 219 | }, |
| 220 | 220 | getskzhOptions(){ |
| 221 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 221 | + getAccountSelector().then(res => { | |
| 222 | 222 | this.skzhOptions = res.data.list |
| 223 | 223 | }); |
| 224 | 224 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCgrkd/Form.vue
| ... | ... | @@ -206,9 +206,9 @@ |
| 206 | 206 | </template> |
| 207 | 207 | <script> |
| 208 | 208 | import request from '@/utils/request' |
| 209 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 210 | 209 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 211 | 210 | import BarcodeSelectWithScan from './BarcodeSelectWithScan.vue' |
| 211 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 212 | 212 | export default { |
| 213 | 213 | components: { BarcodeSelect: BarcodeSelectWithScan }, |
| 214 | 214 | props: [], |
| ... | ... | @@ -352,7 +352,7 @@ setFullName(item,row){ |
| 352 | 352 | this.productQuery = val; |
| 353 | 353 | }, |
| 354 | 354 | getskzhOptions(){ |
| 355 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 355 | + getAccountSelector().then(res => { | |
| 356 | 356 | this.skzhOptions = res.data.list |
| 357 | 357 | }); |
| 358 | 358 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCgrkd/detail-view.vue
| ... | ... | @@ -173,9 +173,9 @@ |
| 173 | 173 | |
| 174 | 174 | <script> |
| 175 | 175 | import request from '@/utils/request' |
| 176 | -import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 177 | 176 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 178 | 177 | import { dynamicText } from '@/filters' |
| 178 | +import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 179 | 179 | |
| 180 | 180 | export default { |
| 181 | 181 | name: 'WtCgrkdDetailView', |
| ... | ... | @@ -295,7 +295,7 @@ export default { |
| 295 | 295 | previewDataInterface('681758216954053893').then(res => { |
| 296 | 296 | this.rkckOptions = res.data || [] |
| 297 | 297 | }) |
| 298 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 298 | + getAccountSelector().then(res => { | |
| 299 | 299 | this.skzhOptions = res.data.list || [] |
| 300 | 300 | }) |
| 301 | 301 | request({ | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCgrkd/index.vue
| ... | ... | @@ -139,12 +139,12 @@ |
| 139 | 139 | </template> |
| 140 | 140 | <script> |
| 141 | 141 | import request from '@/utils/request' |
| 142 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 143 | 142 | import NCCForm from './Form' |
| 144 | 143 | import DetailView from './detail-view' |
| 145 | 144 | import ExportBox from './ExportBox' |
| 146 | 145 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 147 | 146 | import { promptApprovalRemark, postApprovePurchaseInbound, postRejectGeneric } from '@/utils/wtRejectApproval' |
| 147 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 148 | 148 | export default { |
| 149 | 149 | components: { NCCForm, DetailView, ExportBox }, |
| 150 | 150 | data() { |
| ... | ... | @@ -221,7 +221,7 @@ |
| 221 | 221 | }); |
| 222 | 222 | }, |
| 223 | 223 | getskzhOptions(){ |
| 224 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 224 | + getAccountSelector().then(res => { | |
| 225 | 225 | this.skzhOptions = res.data.list |
| 226 | 226 | }); |
| 227 | 227 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCgthd/Form.vue
| 1 | 1 | <template> |
| 2 | - <el-dialog :title="isNew ? '新建' : isDetail ? '详情':'编辑'" :close-on-click-modal="false" :visible.sync="visible" class="NCC-dialog NCC-dialog_center" lock-scroll width="80%"> | |
| 2 | + <el-dialog :title="isNew ? '新建' : isDetail ? '详情':'编辑'" :close-on-click-modal="false" :visible.sync="visible" class="NCC-dialog NCC-dialog_center" lock-scroll width="80%" append-to-body> | |
| 3 | 3 | <el-row :gutter="15" class="" > |
| 4 | 4 | <el-form ref="elForm" :model="dataForm" size="small" label-width="100px" label-position="right" :disabled="!!isDetail" :rules="rules"> |
| 5 | 5 | <el-col :span="12"> |
| ... | ... | @@ -187,8 +187,20 @@ |
| 187 | 187 | </el-col> --> |
| 188 | 188 | <el-col :span="8"> |
| 189 | 189 | <el-form-item label="退款账户" prop="skzh"> |
| 190 | - <el-select v-model="dataForm.skzh" placeholder="请选择" clearable :style='{"width":"100%"}' filterable > | |
| 191 | - <el-option v-for="(item, index) in skzhOptions" :key="index" :label="item.fullName" :value="item.id" ></el-option> | |
| 190 | + <el-select | |
| 191 | + v-model="dataForm.skzh" | |
| 192 | + placeholder="请选择" | |
| 193 | + clearable | |
| 194 | + :style='{"width":"100%"}' | |
| 195 | + filterable | |
| 196 | + popper-append-to-body | |
| 197 | + > | |
| 198 | + <el-option | |
| 199 | + v-for="(item, index) in skzhOptions" | |
| 200 | + :key="item.id != null ? String(item.id) : index" | |
| 201 | + :label="item.fullName || item.accountName || item.accountCode || '账户'" | |
| 202 | + :value="item.id" | |
| 203 | + /> | |
| 192 | 204 | </el-select> |
| 193 | 205 | </el-form-item> |
| 194 | 206 | </el-col> |
| ... | ... | @@ -242,10 +254,10 @@ |
| 242 | 254 | </template> |
| 243 | 255 | <script> |
| 244 | 256 | import request from '@/utils/request' |
| 245 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 246 | 257 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 247 | 258 | import SerialNumberSelect from '../wtXsckd/SerialNumberSelect.vue' |
| 248 | 259 | import PurchaseInboundOrderSelect from './PurchaseInboundOrderSelect.vue' |
| 260 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 249 | 261 | export default { |
| 250 | 262 | components: { SerialNumberSelect, PurchaseInboundOrderSelect }, |
| 251 | 263 | props: [], |
| ... | ... | @@ -256,8 +268,7 @@ |
| 256 | 268 | isDetail: false, |
| 257 | 269 | isNew: false, |
| 258 | 270 | dataForm: { |
| 259 | - id:'', | |
| 260 | - id:undefined, | |
| 271 | + id: undefined, | |
| 261 | 272 | djrq:undefined, |
| 262 | 273 | cjck:undefined, |
| 263 | 274 | jsr:undefined, |
| ... | ... | @@ -278,7 +289,6 @@ |
| 278 | 289 | gysOptions: [], |
| 279 | 290 | cjckOptions : [], |
| 280 | 291 | rkckOptions : [], |
| 281 | - rkckOptions : [], | |
| 282 | 292 | ckckOptions : [], |
| 283 | 293 | spbhOptions : [], |
| 284 | 294 | skzhOptions : [], |
| ... | ... | @@ -300,7 +310,6 @@ |
| 300 | 310 | console.log('created钩子执行,准备加载商品下拉'); |
| 301 | 311 | this.getcjckOptions(); |
| 302 | 312 | this.getrkckOptions(); |
| 303 | - this.getrkckOptions(); | |
| 304 | 313 | this.getckckOptions(); |
| 305 | 314 | this.getspbhOptions(); |
| 306 | 315 | this.getskzhOptions(); |
| ... | ... | @@ -326,11 +335,6 @@ |
| 326 | 335 | this.rkckOptions = res.data |
| 327 | 336 | }); |
| 328 | 337 | }, |
| 329 | - getrkckOptions(){ | |
| 330 | - previewDataInterface('681758216954053893').then(res => { | |
| 331 | - this.rkckOptions = res.data | |
| 332 | - }); | |
| 333 | - }, | |
| 334 | 338 | getckckOptions(){ |
| 335 | 339 | previewDataInterface('681758216954053893').then(res => { |
| 336 | 340 | this.ckckOptions = res.data |
| ... | ... | @@ -343,9 +347,16 @@ |
| 343 | 347 | }); |
| 344 | 348 | }, |
| 345 | 349 | getskzhOptions(){ |
| 346 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 347 | - this.skzhOptions = res.data.list | |
| 348 | - }); | |
| 350 | + return getAccountSelector() | |
| 351 | + .then(res => { | |
| 352 | + const raw = res && res.data | |
| 353 | + let list = raw && raw.list != null ? raw.list : null | |
| 354 | + if (list == null && Array.isArray(raw)) list = raw | |
| 355 | + this.skzhOptions = Array.isArray(list) ? list : [] | |
| 356 | + }) | |
| 357 | + .catch(() => { | |
| 358 | + this.skzhOptions = [] | |
| 359 | + }) | |
| 349 | 360 | }, |
| 350 | 361 | getgysOptions() { |
| 351 | 362 | return request({ |
| ... | ... | @@ -419,10 +430,12 @@ |
| 419 | 430 | this.visible = true; |
| 420 | 431 | this.isDetail = isDetail || false; |
| 421 | 432 | this.currentSerialRowIndex = -1; |
| 422 | - this.$nextTick(() => { | |
| 423 | - this.$refs['elForm'].resetFields(); | |
| 424 | - if (this.dataForm.id) { | |
| 425 | - request({ | |
| 433 | + this.$nextTick(async () => { | |
| 434 | + if (this.$refs['elForm']) this.$refs['elForm'].resetFields(); | |
| 435 | + // 弹窗打开后再拉一次账户,避免 v-if 首屏竞态导致 skzhOptions 为空或 undefined | |
| 436 | + await this.getskzhOptions(); | |
| 437 | + if (this.dataForm.id) { | |
| 438 | + request({ | |
| 426 | 439 | url: '/api/Extend/WtXsckd/' + this.dataForm.id, |
| 427 | 440 | method: 'get' |
| 428 | 441 | }).then(res =>{ |
| ... | ... | @@ -462,7 +475,7 @@ |
| 462 | 475 | this.updateTotalAmount(); |
| 463 | 476 | this.reloadInboundOrdersForExistingRows(); |
| 464 | 477 | }) |
| 465 | - } else { | |
| 478 | + } else { | |
| 466 | 479 | this.dataForm.wtXsckdMxList = []; |
| 467 | 480 | // 预生成单据编号 |
| 468 | 481 | request({ |
| ... | ... | @@ -474,7 +487,7 @@ |
| 474 | 487 | this.dataForm.id = res.data.billNo; |
| 475 | 488 | } |
| 476 | 489 | }).catch(() => {}); |
| 477 | - } | |
| 490 | + } | |
| 478 | 491 | }) |
| 479 | 492 | }, |
| 480 | 493 | dataFormSubmit() { | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCgthd/detail-view.vue
| ... | ... | @@ -184,9 +184,9 @@ |
| 184 | 184 | |
| 185 | 185 | <script> |
| 186 | 186 | import request from '@/utils/request' |
| 187 | -import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 188 | 187 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 189 | 188 | import { dynamicText } from '@/filters' |
| 189 | +import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 190 | 190 | |
| 191 | 191 | export default { |
| 192 | 192 | name: 'WtCgthdDetailView', |
| ... | ... | @@ -291,7 +291,7 @@ export default { |
| 291 | 291 | previewDataInterface('681758216954053893').then(res => { |
| 292 | 292 | this.ckckOptions = res.data || [] |
| 293 | 293 | }) |
| 294 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 294 | + getAccountSelector().then(res => { | |
| 295 | 295 | this.skzhOptions = res.data.list || [] |
| 296 | 296 | }) |
| 297 | 297 | } | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCgthd/index.vue
| ... | ... | @@ -146,11 +146,11 @@ |
| 146 | 146 | </template> |
| 147 | 147 | <script> |
| 148 | 148 | import request from '@/utils/request' |
| 149 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 150 | 149 | import NCCForm from './Form' |
| 151 | 150 | import DetailView from './detail-view' |
| 152 | 151 | import ExportBox from './ExportBox' |
| 153 | 152 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 153 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 154 | 154 | export default { |
| 155 | 155 | components: { NCCForm, DetailView, ExportBox }, |
| 156 | 156 | data() { |
| ... | ... | @@ -225,7 +225,7 @@ |
| 225 | 225 | }); |
| 226 | 226 | }, |
| 227 | 227 | getskzhOptions(){ |
| 228 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 228 | + getAccountSelector().then(res => { | |
| 229 | 229 | this.skzhOptions = res.data.list |
| 230 | 230 | }); |
| 231 | 231 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCwdj/Form.vue
| ... | ... | @@ -121,6 +121,7 @@ |
| 121 | 121 | import request from '@/utils/request' |
| 122 | 122 | import { getDictionaryDataSelector } from '@/api/systemData/dictionary' |
| 123 | 123 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 124 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 124 | 125 | export default { |
| 125 | 126 | components: {}, |
| 126 | 127 | props: [], |
| ... | ... | @@ -181,17 +182,17 @@ |
| 181 | 182 | }); |
| 182 | 183 | }, |
| 183 | 184 | getzhbhOptions(){ |
| 184 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 185 | + getAccountSelector().then(res => { | |
| 185 | 186 | this.zhbhOptions = res.data.list |
| 186 | 187 | }); |
| 187 | 188 | }, |
| 188 | 189 | getfkzhOptions(){ |
| 189 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 190 | + getAccountSelector().then(res => { | |
| 190 | 191 | this.fkzhOptions = res.data.list |
| 191 | 192 | }); |
| 192 | 193 | }, |
| 193 | 194 | getskzhOptions(){ |
| 194 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 195 | + getAccountSelector().then(res => { | |
| 195 | 196 | this.skzhOptions = res.data.list |
| 196 | 197 | }); |
| 197 | 198 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCwdj/index.vue
| ... | ... | @@ -85,10 +85,10 @@ |
| 85 | 85 | </template> |
| 86 | 86 | <script> |
| 87 | 87 | import request from '@/utils/request' |
| 88 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 89 | 88 | import NCCForm from './Form' |
| 90 | 89 | import ExportBox from './ExportBox' |
| 91 | 90 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 91 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 92 | 92 | export default { |
| 93 | 93 | components: { NCCForm, ExportBox }, |
| 94 | 94 | data() { |
| ... | ... | @@ -138,12 +138,12 @@ |
| 138 | 138 | }); |
| 139 | 139 | }, |
| 140 | 140 | getfkzhOptions(){ |
| 141 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 141 | + getAccountSelector().then(res => { | |
| 142 | 142 | this.fkzhOptions = res.data.list |
| 143 | 143 | }); |
| 144 | 144 | }, |
| 145 | 145 | getskzhOptions(){ |
| 146 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 146 | + getAccountSelector().then(res => { | |
| 147 | 147 | this.skzhOptions = res.data.list |
| 148 | 148 | }); |
| 149 | 149 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCwdj_dtfyfs/Form.vue
| ... | ... | @@ -127,6 +127,7 @@ |
| 127 | 127 | import request from '@/utils/request' |
| 128 | 128 | import { getDictionaryDataSelector } from '@/api/systemData/dictionary' |
| 129 | 129 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 130 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 130 | 131 | export default { |
| 131 | 132 | components: {}, |
| 132 | 133 | props: [], |
| ... | ... | @@ -193,17 +194,17 @@ |
| 193 | 194 | }); |
| 194 | 195 | }, |
| 195 | 196 | getzhbhOptions(){ |
| 196 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 197 | + getAccountSelector().then(res => { | |
| 197 | 198 | this.zhbhOptions = res.data.list |
| 198 | 199 | }); |
| 199 | 200 | }, |
| 200 | 201 | getfkzhOptions(){ |
| 201 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 202 | + getAccountSelector().then(res => { | |
| 202 | 203 | this.fkzhOptions = res.data.list |
| 203 | 204 | }); |
| 204 | 205 | }, |
| 205 | 206 | getskzhOptions(){ |
| 206 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 207 | + getAccountSelector().then(res => { | |
| 207 | 208 | this.skzhOptions = res.data.list |
| 208 | 209 | }); |
| 209 | 210 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCwdj_dtfyfs/index.vue
| ... | ... | @@ -90,10 +90,10 @@ |
| 90 | 90 | </template> |
| 91 | 91 | <script> |
| 92 | 92 | import request from '@/utils/request' |
| 93 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 94 | 93 | import NCCForm from './Form' |
| 95 | 94 | import ExportBox from './ExportBox' |
| 96 | 95 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 96 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 97 | 97 | export default { |
| 98 | 98 | components: { NCCForm, ExportBox }, |
| 99 | 99 | data() { |
| ... | ... | @@ -145,12 +145,12 @@ |
| 145 | 145 | }); |
| 146 | 146 | }, |
| 147 | 147 | getfkzhOptions(){ |
| 148 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 148 | + getAccountSelector().then(res => { | |
| 149 | 149 | this.fkzhOptions = res.data.list |
| 150 | 150 | }); |
| 151 | 151 | }, |
| 152 | 152 | getskzhOptions(){ |
| 153 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 153 | + getAccountSelector().then(res => { | |
| 154 | 154 | this.skzhOptions = res.data.list |
| 155 | 155 | }); |
| 156 | 156 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCwdj_dtfytx/Form.vue
| ... | ... | @@ -121,6 +121,7 @@ |
| 121 | 121 | import request from '@/utils/request' |
| 122 | 122 | import { getDictionaryDataSelector } from '@/api/systemData/dictionary' |
| 123 | 123 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 124 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 124 | 125 | export default { |
| 125 | 126 | components: {}, |
| 126 | 127 | props: [], |
| ... | ... | @@ -182,17 +183,17 @@ |
| 182 | 183 | }); |
| 183 | 184 | }, |
| 184 | 185 | getzhbhOptions(){ |
| 185 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 186 | + getAccountSelector().then(res => { | |
| 186 | 187 | this.zhbhOptions = res.data.list |
| 187 | 188 | }); |
| 188 | 189 | }, |
| 189 | 190 | getfkzhOptions(){ |
| 190 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 191 | + getAccountSelector().then(res => { | |
| 191 | 192 | this.fkzhOptions = res.data.list |
| 192 | 193 | }); |
| 193 | 194 | }, |
| 194 | 195 | getskzhOptions(){ |
| 195 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 196 | + getAccountSelector().then(res => { | |
| 196 | 197 | this.skzhOptions = res.data.list |
| 197 | 198 | }); |
| 198 | 199 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCwdj_dtfytx/index.vue
| ... | ... | @@ -89,10 +89,10 @@ |
| 89 | 89 | </template> |
| 90 | 90 | <script> |
| 91 | 91 | import request from '@/utils/request' |
| 92 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 93 | 92 | import NCCForm from './Form' |
| 94 | 93 | import ExportBox from './ExportBox' |
| 95 | 94 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 95 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 96 | 96 | export default { |
| 97 | 97 | components: { NCCForm, ExportBox }, |
| 98 | 98 | data() { |
| ... | ... | @@ -142,12 +142,12 @@ |
| 142 | 142 | }); |
| 143 | 143 | }, |
| 144 | 144 | getfkzhOptions(){ |
| 145 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 145 | + getAccountSelector().then(res => { | |
| 146 | 146 | this.fkzhOptions = res.data.list |
| 147 | 147 | }); |
| 148 | 148 | }, |
| 149 | 149 | getskzhOptions(){ |
| 150 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 150 | + getAccountSelector().then(res => { | |
| 151 | 151 | this.skzhOptions = res.data.list |
| 152 | 152 | }); |
| 153 | 153 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCwdj_fkd/Form.vue
| ... | ... | @@ -128,6 +128,7 @@ |
| 128 | 128 | import request from '@/utils/request' |
| 129 | 129 | import { getDictionaryDataSelector } from '@/api/systemData/dictionary' |
| 130 | 130 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 131 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 131 | 132 | export default { |
| 132 | 133 | components: {}, |
| 133 | 134 | props: [], |
| ... | ... | @@ -190,17 +191,17 @@ |
| 190 | 191 | }); |
| 191 | 192 | }, |
| 192 | 193 | getzhbhOptions(){ |
| 193 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 194 | + getAccountSelector().then(res => { | |
| 194 | 195 | this.zhbhOptions = res.data.list |
| 195 | 196 | }); |
| 196 | 197 | }, |
| 197 | 198 | getfkzhOptions(){ |
| 198 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 199 | + getAccountSelector().then(res => { | |
| 199 | 200 | this.fkzhOptions = res.data.list |
| 200 | 201 | }); |
| 201 | 202 | }, |
| 202 | 203 | getskzhOptions(){ |
| 203 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 204 | + getAccountSelector().then(res => { | |
| 204 | 205 | this.skzhOptions = res.data.list |
| 205 | 206 | }); |
| 206 | 207 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCwdj_fkd/detail-view.vue
| ... | ... | @@ -124,6 +124,7 @@ import request from '@/utils/request' |
| 124 | 124 | import { getDictionaryDataSelector } from '@/api/systemData/dictionary' |
| 125 | 125 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 126 | 126 | import { dynamicText } from '@/filters' |
| 127 | +import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 127 | 128 | |
| 128 | 129 | export default { |
| 129 | 130 | name: 'WtCwdjFkdDetailView', |
| ... | ... | @@ -216,7 +217,7 @@ export default { |
| 216 | 217 | previewDataInterface('716168694526379269').then(res => { |
| 217 | 218 | this.wldwOptions = res.data || [] |
| 218 | 219 | }) |
| 219 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 220 | + getAccountSelector().then(res => { | |
| 220 | 221 | this.zhbhOptions = res.data.list || [] |
| 221 | 222 | }) |
| 222 | 223 | getDictionaryDataSelector('715562947862070533').then(res => { | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCwdj_fkd/index.vue
| ... | ... | @@ -91,11 +91,11 @@ |
| 91 | 91 | </template> |
| 92 | 92 | <script> |
| 93 | 93 | import request from '@/utils/request' |
| 94 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 95 | 94 | import NCCForm from './Form' |
| 96 | 95 | import DetailView from './detail-view' |
| 97 | 96 | import ExportBox from './ExportBox' |
| 98 | 97 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 98 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 99 | 99 | export default { |
| 100 | 100 | components: { NCCForm, DetailView, ExportBox }, |
| 101 | 101 | data() { |
| ... | ... | @@ -146,12 +146,12 @@ |
| 146 | 146 | }); |
| 147 | 147 | }, |
| 148 | 148 | getfkzhOptions(){ |
| 149 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 149 | + getAccountSelector().then(res => { | |
| 150 | 150 | this.fkzhOptions = res.data.list |
| 151 | 151 | }); |
| 152 | 152 | }, |
| 153 | 153 | getskzhOptions(){ |
| 154 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 154 | + getAccountSelector().then(res => { | |
| 155 | 155 | this.skzhOptions = res.data.list |
| 156 | 156 | }); |
| 157 | 157 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCwdj_fyd/Form.vue
| ... | ... | @@ -134,6 +134,7 @@ |
| 134 | 134 | import request from '@/utils/request' |
| 135 | 135 | import { getDictionaryDataSelector } from '@/api/systemData/dictionary' |
| 136 | 136 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 137 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 137 | 138 | export default { |
| 138 | 139 | components: {}, |
| 139 | 140 | props: [], |
| ... | ... | @@ -195,17 +196,17 @@ |
| 195 | 196 | }); |
| 196 | 197 | }, |
| 197 | 198 | getzhbhOptions(){ |
| 198 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 199 | + getAccountSelector().then(res => { | |
| 199 | 200 | this.zhbhOptions = res.data.list |
| 200 | 201 | }); |
| 201 | 202 | }, |
| 202 | 203 | getfkzhOptions(){ |
| 203 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 204 | + getAccountSelector().then(res => { | |
| 204 | 205 | this.fkzhOptions = res.data.list |
| 205 | 206 | }); |
| 206 | 207 | }, |
| 207 | 208 | getskzhOptions(){ |
| 208 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 209 | + getAccountSelector().then(res => { | |
| 209 | 210 | this.skzhOptions = res.data.list |
| 210 | 211 | }); |
| 211 | 212 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCwdj_fyd/index.vue
| ... | ... | @@ -107,10 +107,10 @@ |
| 107 | 107 | </template> |
| 108 | 108 | <script> |
| 109 | 109 | import request from '@/utils/request' |
| 110 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 111 | 110 | import NCCForm from './Form' |
| 112 | 111 | import ExportBox from './ExportBox' |
| 113 | 112 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 113 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 114 | 114 | export default { |
| 115 | 115 | components: { NCCForm, ExportBox }, |
| 116 | 116 | data() { |
| ... | ... | @@ -162,12 +162,12 @@ |
| 162 | 162 | }); |
| 163 | 163 | }, |
| 164 | 164 | getfkzhOptions(){ |
| 165 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 165 | + getAccountSelector().then(res => { | |
| 166 | 166 | this.fkzhOptions = res.data.list |
| 167 | 167 | }); |
| 168 | 168 | }, |
| 169 | 169 | getskzhOptions(){ |
| 170 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 170 | + getAccountSelector().then(res => { | |
| 171 | 171 | this.skzhOptions = res.data.list |
| 172 | 172 | }); |
| 173 | 173 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCwdj_gdzcbm/Form.vue
| ... | ... | @@ -121,6 +121,7 @@ |
| 121 | 121 | import request from '@/utils/request' |
| 122 | 122 | import { getDictionaryDataSelector } from '@/api/systemData/dictionary' |
| 123 | 123 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 124 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 124 | 125 | export default { |
| 125 | 126 | components: {}, |
| 126 | 127 | props: [], |
| ... | ... | @@ -182,17 +183,17 @@ |
| 182 | 183 | }); |
| 183 | 184 | }, |
| 184 | 185 | getzhbhOptions(){ |
| 185 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 186 | + getAccountSelector().then(res => { | |
| 186 | 187 | this.zhbhOptions = res.data.list |
| 187 | 188 | }); |
| 188 | 189 | }, |
| 189 | 190 | getfkzhOptions(){ |
| 190 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 191 | + getAccountSelector().then(res => { | |
| 191 | 192 | this.fkzhOptions = res.data.list |
| 192 | 193 | }); |
| 193 | 194 | }, |
| 194 | 195 | getskzhOptions(){ |
| 195 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 196 | + getAccountSelector().then(res => { | |
| 196 | 197 | this.skzhOptions = res.data.list |
| 197 | 198 | }); |
| 198 | 199 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCwdj_gdzcbm/index.vue
| ... | ... | @@ -89,10 +89,10 @@ |
| 89 | 89 | </template> |
| 90 | 90 | <script> |
| 91 | 91 | import request from '@/utils/request' |
| 92 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 93 | 92 | import NCCForm from './Form' |
| 94 | 93 | import ExportBox from './ExportBox' |
| 95 | 94 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 95 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 96 | 96 | export default { |
| 97 | 97 | components: { NCCForm, ExportBox }, |
| 98 | 98 | data() { |
| ... | ... | @@ -142,12 +142,12 @@ |
| 142 | 142 | }); |
| 143 | 143 | }, |
| 144 | 144 | getfkzhOptions(){ |
| 145 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 145 | + getAccountSelector().then(res => { | |
| 146 | 146 | this.fkzhOptions = res.data.list |
| 147 | 147 | }); |
| 148 | 148 | }, |
| 149 | 149 | getskzhOptions(){ |
| 150 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 150 | + getAccountSelector().then(res => { | |
| 151 | 151 | this.skzhOptions = res.data.list |
| 152 | 152 | }); |
| 153 | 153 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCwdj_gdzcgm/Form.vue
| ... | ... | @@ -127,6 +127,7 @@ |
| 127 | 127 | import request from '@/utils/request' |
| 128 | 128 | import { getDictionaryDataSelector } from '@/api/systemData/dictionary' |
| 129 | 129 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 130 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 130 | 131 | export default { |
| 131 | 132 | components: {}, |
| 132 | 133 | props: [], |
| ... | ... | @@ -193,17 +194,17 @@ |
| 193 | 194 | }); |
| 194 | 195 | }, |
| 195 | 196 | getzhbhOptions(){ |
| 196 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 197 | + getAccountSelector().then(res => { | |
| 197 | 198 | this.zhbhOptions = res.data.list |
| 198 | 199 | }); |
| 199 | 200 | }, |
| 200 | 201 | getfkzhOptions(){ |
| 201 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 202 | + getAccountSelector().then(res => { | |
| 202 | 203 | this.fkzhOptions = res.data.list |
| 203 | 204 | }); |
| 204 | 205 | }, |
| 205 | 206 | getskzhOptions(){ |
| 206 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 207 | + getAccountSelector().then(res => { | |
| 207 | 208 | this.skzhOptions = res.data.list |
| 208 | 209 | }); |
| 209 | 210 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCwdj_gdzcgm/index.vue
| ... | ... | @@ -90,10 +90,10 @@ |
| 90 | 90 | </template> |
| 91 | 91 | <script> |
| 92 | 92 | import request from '@/utils/request' |
| 93 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 94 | 93 | import NCCForm from './Form' |
| 95 | 94 | import ExportBox from './ExportBox' |
| 96 | 95 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 96 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 97 | 97 | export default { |
| 98 | 98 | components: { NCCForm, ExportBox }, |
| 99 | 99 | data() { |
| ... | ... | @@ -145,12 +145,12 @@ |
| 145 | 145 | }); |
| 146 | 146 | }, |
| 147 | 147 | getfkzhOptions(){ |
| 148 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 148 | + getAccountSelector().then(res => { | |
| 149 | 149 | this.fkzhOptions = res.data.list |
| 150 | 150 | }); |
| 151 | 151 | }, |
| 152 | 152 | getskzhOptions(){ |
| 153 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 153 | + getAccountSelector().then(res => { | |
| 154 | 154 | this.skzhOptions = res.data.list |
| 155 | 155 | }); |
| 156 | 156 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCwdj_gdzczj/Form.vue
| ... | ... | @@ -121,6 +121,7 @@ |
| 121 | 121 | import request from '@/utils/request' |
| 122 | 122 | import { getDictionaryDataSelector } from '@/api/systemData/dictionary' |
| 123 | 123 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 124 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 124 | 125 | export default { |
| 125 | 126 | components: {}, |
| 126 | 127 | props: [], |
| ... | ... | @@ -182,17 +183,17 @@ |
| 182 | 183 | }); |
| 183 | 184 | }, |
| 184 | 185 | getzhbhOptions(){ |
| 185 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 186 | + getAccountSelector().then(res => { | |
| 186 | 187 | this.zhbhOptions = res.data.list |
| 187 | 188 | }); |
| 188 | 189 | }, |
| 189 | 190 | getfkzhOptions(){ |
| 190 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 191 | + getAccountSelector().then(res => { | |
| 191 | 192 | this.fkzhOptions = res.data.list |
| 192 | 193 | }); |
| 193 | 194 | }, |
| 194 | 195 | getskzhOptions(){ |
| 195 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 196 | + getAccountSelector().then(res => { | |
| 196 | 197 | this.skzhOptions = res.data.list |
| 197 | 198 | }); |
| 198 | 199 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCwdj_gdzczj/index.vue
| ... | ... | @@ -89,10 +89,10 @@ |
| 89 | 89 | </template> |
| 90 | 90 | <script> |
| 91 | 91 | import request from '@/utils/request' |
| 92 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 93 | 92 | import NCCForm from './Form' |
| 94 | 93 | import ExportBox from './ExportBox' |
| 95 | 94 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 95 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 96 | 96 | export default { |
| 97 | 97 | components: { NCCForm, ExportBox }, |
| 98 | 98 | data() { |
| ... | ... | @@ -142,12 +142,12 @@ |
| 142 | 142 | }); |
| 143 | 143 | }, |
| 144 | 144 | getfkzhOptions(){ |
| 145 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 145 | + getAccountSelector().then(res => { | |
| 146 | 146 | this.fkzhOptions = res.data.list |
| 147 | 147 | }); |
| 148 | 148 | }, |
| 149 | 149 | getskzhOptions(){ |
| 150 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 150 | + getAccountSelector().then(res => { | |
| 151 | 151 | this.skzhOptions = res.data.list |
| 152 | 152 | }); |
| 153 | 153 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCwdj_skd/Form.vue
| ... | ... | @@ -128,6 +128,7 @@ |
| 128 | 128 | import request from '@/utils/request' |
| 129 | 129 | import { getDictionaryDataSelector } from '@/api/systemData/dictionary' |
| 130 | 130 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 131 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 131 | 132 | export default { |
| 132 | 133 | components: {}, |
| 133 | 134 | props: [], |
| ... | ... | @@ -190,17 +191,17 @@ |
| 190 | 191 | }); |
| 191 | 192 | }, |
| 192 | 193 | getzhbhOptions(){ |
| 193 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 194 | + getAccountSelector().then(res => { | |
| 194 | 195 | this.zhbhOptions = res.data.list |
| 195 | 196 | }); |
| 196 | 197 | }, |
| 197 | 198 | getfkzhOptions(){ |
| 198 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 199 | + getAccountSelector().then(res => { | |
| 199 | 200 | this.fkzhOptions = res.data.list |
| 200 | 201 | }); |
| 201 | 202 | }, |
| 202 | 203 | getskzhOptions(){ |
| 203 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 204 | + getAccountSelector().then(res => { | |
| 204 | 205 | this.skzhOptions = res.data.list |
| 205 | 206 | }); |
| 206 | 207 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCwdj_skd/detail-view.vue
| ... | ... | @@ -124,6 +124,7 @@ import request from '@/utils/request' |
| 124 | 124 | import { getDictionaryDataSelector } from '@/api/systemData/dictionary' |
| 125 | 125 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 126 | 126 | import { dynamicText } from '@/filters' |
| 127 | +import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 127 | 128 | |
| 128 | 129 | export default { |
| 129 | 130 | name: 'WtCwdjSkdDetailView', |
| ... | ... | @@ -216,7 +217,7 @@ export default { |
| 216 | 217 | previewDataInterface('716168694526379269').then(res => { |
| 217 | 218 | this.wldwOptions = res.data || [] |
| 218 | 219 | }) |
| 219 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 220 | + getAccountSelector().then(res => { | |
| 220 | 221 | this.zhbhOptions = res.data.list || [] |
| 221 | 222 | }) |
| 222 | 223 | getDictionaryDataSelector('715562947862070533').then(res => { | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCwdj_skd/index.vue
| ... | ... | @@ -91,11 +91,11 @@ |
| 91 | 91 | </template> |
| 92 | 92 | <script> |
| 93 | 93 | import request from '@/utils/request' |
| 94 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 95 | 94 | import NCCForm from './Form' |
| 96 | 95 | import DetailView from './detail-view' |
| 97 | 96 | import ExportBox from './ExportBox' |
| 98 | 97 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 98 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 99 | 99 | export default { |
| 100 | 100 | components: { NCCForm, DetailView, ExportBox }, |
| 101 | 101 | data() { |
| ... | ... | @@ -146,12 +146,12 @@ |
| 146 | 146 | }); |
| 147 | 147 | }, |
| 148 | 148 | getfkzhOptions(){ |
| 149 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 149 | + getAccountSelector().then(res => { | |
| 150 | 150 | this.fkzhOptions = res.data.list |
| 151 | 151 | }); |
| 152 | 152 | }, |
| 153 | 153 | getskzhOptions(){ |
| 154 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 154 | + getAccountSelector().then(res => { | |
| 155 | 155 | this.skzhOptions = res.data.list |
| 156 | 156 | }); |
| 157 | 157 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtFkd/Form.vue
| ... | ... | @@ -86,8 +86,8 @@ |
| 86 | 86 | </template> |
| 87 | 87 | <script> |
| 88 | 88 | import request from '@/utils/request' |
| 89 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 90 | 89 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 90 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 91 | 91 | export default { |
| 92 | 92 | components: {}, |
| 93 | 93 | props: [], |
| ... | ... | @@ -132,7 +132,7 @@ |
| 132 | 132 | }); |
| 133 | 133 | }, |
| 134 | 134 | getjszhOptions(){ |
| 135 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 135 | + getAccountSelector().then(res => { | |
| 136 | 136 | this.jszhOptions = res.data.list |
| 137 | 137 | }); |
| 138 | 138 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtFkd/index.vue
| ... | ... | @@ -121,10 +121,10 @@ |
| 121 | 121 | </template> |
| 122 | 122 | <script> |
| 123 | 123 | import request from '@/utils/request' |
| 124 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 125 | 124 | import NCCForm from './Form' |
| 126 | 125 | import ExportBox from './ExportBox' |
| 127 | 126 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 127 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 128 | 128 | export default { |
| 129 | 129 | components: { NCCForm, ExportBox }, |
| 130 | 130 | data() { |
| ... | ... | @@ -184,7 +184,7 @@ |
| 184 | 184 | }); |
| 185 | 185 | }, |
| 186 | 186 | getjszhOptions(){ |
| 187 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 187 | + getAccountSelector().then(res => { | |
| 188 | 188 | this.jszhOptions = res.data.list |
| 189 | 189 | }); |
| 190 | 190 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtHzd/Form.vue
| ... | ... | @@ -287,10 +287,10 @@ |
| 287 | 287 | </template> |
| 288 | 288 | <script> |
| 289 | 289 | import request from '@/utils/request' |
| 290 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 291 | 290 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 292 | 291 | import BarcodeSelect from '../wtCgrkd/BarcodeSelect.vue' |
| 293 | 292 | import SerialNumberSelect from './SerialNumberSelect.vue' |
| 293 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 294 | 294 | export default { |
| 295 | 295 | components: { BarcodeSelect, SerialNumberSelect }, |
| 296 | 296 | props: [], |
| ... | ... | @@ -607,7 +607,7 @@ |
| 607 | 607 | }); |
| 608 | 608 | }, |
| 609 | 609 | getskzhOptions(){ |
| 610 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 610 | + getAccountSelector().then(res => { | |
| 611 | 611 | this.skzhOptions = res.data.list |
| 612 | 612 | }); |
| 613 | 613 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtHzd/index.vue
| ... | ... | @@ -144,10 +144,10 @@ |
| 144 | 144 | </template> |
| 145 | 145 | <script> |
| 146 | 146 | import request from '@/utils/request' |
| 147 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 148 | 147 | import NCCForm from './Form' |
| 149 | 148 | import ExportBox from './ExportBox' |
| 150 | 149 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 150 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 151 | 151 | export default { |
| 152 | 152 | components: { NCCForm, ExportBox }, |
| 153 | 153 | data() { |
| ... | ... | @@ -218,7 +218,7 @@ |
| 218 | 218 | }); |
| 219 | 219 | }, |
| 220 | 220 | getskzhOptions(){ |
| 221 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 221 | + getAccountSelector().then(res => { | |
| 222 | 222 | this.skzhOptions = res.data.list |
| 223 | 223 | }); |
| 224 | 224 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtMrsz/index.vue
| ... | ... | @@ -32,8 +32,8 @@ |
| 32 | 32 | |
| 33 | 33 | <script> |
| 34 | 34 | import request from '@/utils/request' |
| 35 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 36 | 35 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 36 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 37 | 37 | |
| 38 | 38 | export default { |
| 39 | 39 | name: 'wtMrsz', |
| ... | ... | @@ -72,7 +72,7 @@ |
| 72 | 72 | }).catch(() => {}) |
| 73 | 73 | |
| 74 | 74 | // 收款账户(字典数据,与销售出库单一致) |
| 75 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 75 | + getAccountSelector().then(res => { | |
| 76 | 76 | this.skzhOptions = res.data && res.data.list ? res.data.list : [] |
| 77 | 77 | }).catch(() => {}) |
| 78 | 78 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtPdd/Form.vue
| ... | ... | @@ -282,10 +282,10 @@ |
| 282 | 282 | </template> |
| 283 | 283 | <script> |
| 284 | 284 | import request from '@/utils/request' |
| 285 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 286 | 285 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 287 | 286 | import BarcodeSelect from '../wtCgrkd/BarcodeSelect.vue' |
| 288 | 287 | import SerialNumberSelect from './SerialNumberSelect.vue' |
| 288 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 289 | 289 | export default { |
| 290 | 290 | components: { BarcodeSelect, SerialNumberSelect }, |
| 291 | 291 | props: [], |
| ... | ... | @@ -606,7 +606,7 @@ |
| 606 | 606 | }); |
| 607 | 607 | }, |
| 608 | 608 | getskzhOptions(){ |
| 609 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 609 | + getAccountSelector().then(res => { | |
| 610 | 610 | this.skzhOptions = res.data.list |
| 611 | 611 | }); |
| 612 | 612 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtPdd/index.vue
| ... | ... | @@ -144,10 +144,10 @@ |
| 144 | 144 | </template> |
| 145 | 145 | <script> |
| 146 | 146 | import request from '@/utils/request' |
| 147 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 148 | 147 | import NCCForm from './Form' |
| 149 | 148 | import ExportBox from './ExportBox' |
| 150 | 149 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 150 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 151 | 151 | export default { |
| 152 | 152 | components: { NCCForm, ExportBox }, |
| 153 | 153 | data() { |
| ... | ... | @@ -218,7 +218,7 @@ |
| 218 | 218 | }); |
| 219 | 219 | }, |
| 220 | 220 | getskzhOptions(){ |
| 221 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 221 | + getAccountSelector().then(res => { | |
| 222 | 222 | this.skzhOptions = res.data.list |
| 223 | 223 | }); |
| 224 | 224 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtPurchaseSummary/index.vue
| 1 | 1 | <template> |
| 2 | - <div class="purchase-summary-page"> | |
| 3 | - <div class="form-section"> | |
| 4 | - <el-form :inline="false" :model="filters" label-width="90px" size="small"> | |
| 5 | - <el-row :gutter="10"> | |
| 6 | - <el-col :span="12"> | |
| 2 | + <div class="NCC-common-layout"> | |
| 3 | + <div class="NCC-common-layout-center"> | |
| 4 | + <el-row class="NCC-common-search-box" :gutter="16"> | |
| 5 | + <el-form @submit.native.prevent> | |
| 6 | + <el-col :span="6"> | |
| 7 | 7 | <el-form-item label="查询日期"> |
| 8 | 8 | <el-date-picker |
| 9 | 9 | v-model="filters.dateRange" |
| ... | ... | @@ -13,10 +13,11 @@ |
| 13 | 13 | end-placeholder="结束日期" |
| 14 | 14 | style="width: 100%" |
| 15 | 15 | value-format="yyyy-MM-dd" |
| 16 | + clearable | |
| 16 | 17 | /> |
| 17 | 18 | </el-form-item> |
| 18 | 19 | </el-col> |
| 19 | - <el-col :span="12"> | |
| 20 | + <el-col :span="6"> | |
| 20 | 21 | <el-form-item label="往来单位"> |
| 21 | 22 | <el-select |
| 22 | 23 | v-model="filters.contactUnit" |
| ... | ... | @@ -36,8 +37,8 @@ |
| 36 | 37 | </el-select> |
| 37 | 38 | </el-form-item> |
| 38 | 39 | </el-col> |
| 39 | - <el-col :span="12"> | |
| 40 | - <el-form-item label="经 手 人"> | |
| 40 | + <el-col :span="6"> | |
| 41 | + <el-form-item label="经手人"> | |
| 41 | 42 | <el-select |
| 42 | 43 | v-model="filters.agent" |
| 43 | 44 | multiple |
| ... | ... | @@ -49,36 +50,43 @@ |
| 49 | 50 | > |
| 50 | 51 | <el-option |
| 51 | 52 | v-for="item in agentOptions" |
| 52 | - :key="item" | |
| 53 | - :label="item" | |
| 54 | - :value="item" | |
| 53 | + :key="item.value" | |
| 54 | + :label="item.label" | |
| 55 | + :value="item.value" | |
| 55 | 56 | /> |
| 56 | 57 | </el-select> |
| 57 | 58 | </el-form-item> |
| 58 | 59 | </el-col> |
| 59 | - <el-col :span="12"> | |
| 60 | + <el-col :span="6"> | |
| 60 | 61 | <el-form-item label="商品"> |
| 61 | 62 | <el-select |
| 62 | - v-model="filters.productName" | |
| 63 | + v-model="filters.productSpId" | |
| 63 | 64 | filterable |
| 64 | 65 | remote |
| 65 | 66 | clearable |
| 66 | 67 | reserve-keyword |
| 68 | + popper-class="wt-purchase-sum-product-dropdown" | |
| 67 | 69 | :remote-method="handleProductSearch" |
| 68 | 70 | :loading="productLoading" |
| 69 | - placeholder="请输入商品编号或名称搜索" | |
| 71 | + placeholder="输入商品编码或名称搜索" | |
| 70 | 72 | style="width: 100%" |
| 71 | 73 | > |
| 72 | 74 | <el-option |
| 73 | 75 | v-for="item in productOptions" |
| 74 | - :key="item.F_Id || item.id || item.spbm || item.productCode" | |
| 76 | + :key="item.F_Id || item.id" | |
| 75 | 77 | :label="formatProductLabel(item)" |
| 76 | - :value="formatProductLabel(item)" | |
| 77 | - /> | |
| 78 | + :value="item.F_Id || item.id" | |
| 79 | + > | |
| 80 | + <div class="product-opt-row cell-nowrap" :title="formatProductLabel(item)"> | |
| 81 | + <span v-if="productCodeRaw(item)" class="product-opt-code">{{ productCodeRaw(item) }}</span> | |
| 82 | + <span v-if="productCodeRaw(item) && productNameRaw(item)" class="product-opt-sep">|</span> | |
| 83 | + <span class="product-opt-name">{{ productNameRaw(item) || '无' }}</span> | |
| 84 | + </div> | |
| 85 | + </el-option> | |
| 78 | 86 | </el-select> |
| 79 | 87 | </el-form-item> |
| 80 | 88 | </el-col> |
| 81 | - <el-col :span="12"> | |
| 89 | + <el-col :span="6"> | |
| 82 | 90 | <el-form-item label="入库仓库"> |
| 83 | 91 | <el-select |
| 84 | 92 | v-model="filters.warehouse" |
| ... | ... | @@ -98,7 +106,7 @@ |
| 98 | 106 | </el-select> |
| 99 | 107 | </el-form-item> |
| 100 | 108 | </el-col> |
| 101 | - <el-col :span="12"> | |
| 109 | + <el-col :span="6"> | |
| 102 | 110 | <el-form-item label="单据类型"> |
| 103 | 111 | <el-select |
| 104 | 112 | v-model="filters.billType" |
| ... | ... | @@ -106,7 +114,7 @@ |
| 106 | 114 | collapse-tags |
| 107 | 115 | clearable |
| 108 | 116 | style="width: 100%" |
| 109 | - placeholder="全部单据" | |
| 117 | + placeholder="全部相关单据" | |
| 110 | 118 | > |
| 111 | 119 | <el-option |
| 112 | 120 | v-for="item in billTypeOptions" |
| ... | ... | @@ -117,65 +125,220 @@ |
| 117 | 125 | </el-select> |
| 118 | 126 | </el-form-item> |
| 119 | 127 | </el-col> |
| 120 | - <el-col :span="24"> | |
| 121 | - <div class="action-row"> | |
| 122 | - <el-button type="primary" size="mini" @click="handleSearch">搜索</el-button> | |
| 123 | - <el-button size="mini" @click="handleReset">重置</el-button> | |
| 124 | - </div> | |
| 128 | + <el-col :span="6"> | |
| 129 | + <el-form-item> | |
| 130 | + <el-button type="primary" icon="el-icon-search" @click="handleSearch">查询</el-button> | |
| 131 | + <el-button icon="el-icon-refresh-right" @click="handleReset">重置</el-button> | |
| 132 | + </el-form-item> | |
| 125 | 133 | </el-col> |
| 126 | - </el-row> | |
| 127 | - </el-form> | |
| 128 | - </div> | |
| 129 | - <div class="table-section"> | |
| 130 | - <div class="table-title-bar"> | |
| 131 | - <i class="el-icon-document" style="font-size: 20px; margin-right: 6px; color: #409eff" /> | |
| 132 | - <span>商品采购汇总表 · 过往采购记录</span> | |
| 133 | - </div> | |
| 134 | - <div class="table-scroll"> | |
| 134 | + </el-form> | |
| 135 | + </el-row> | |
| 136 | + | |
| 137 | + <div class="NCC-common-layout-main NCC-flex-main"> | |
| 138 | + <div class="NCC-common-head purchase-sum-head"> | |
| 139 | + <div> | |
| 140 | + <span class="purchase-sum-head__title"> | |
| 141 | + <i class="el-icon-s-data purchase-sum-head__icon" aria-hidden="true" /> | |
| 142 | + 商品采购汇总(分类 → 品牌 → 商品明细分类 → 采购明细) | |
| 143 | + </span> | |
| 144 | + </div> | |
| 145 | + <div class="NCC-common-head-right"> | |
| 146 | + <el-tooltip effect="dark" content="刷新" placement="top"> | |
| 147 | + <el-link | |
| 148 | + icon="icon-ym icon-ym-Refresh NCC-common-head-icon" | |
| 149 | + :underline="false" | |
| 150 | + @click="handleSearch" | |
| 151 | + /> | |
| 152 | + </el-tooltip> | |
| 153 | + <screenfull isContainer /> | |
| 154 | + </div> | |
| 155 | + </div> | |
| 156 | + | |
| 135 | 157 | <el-table |
| 136 | - :data="list" | |
| 158 | + v-loading="categoryLoading" | |
| 159 | + :data="categoryList" | |
| 137 | 160 | border |
| 138 | - style="width: 100%" | |
| 139 | - :header-cell-style="{ background: '#f5f7fa' }" | |
| 140 | - class="purchase-record-table" | |
| 161 | + class="purchase-tree-table" | |
| 162 | + :row-key="r => String(r['分类Id'])" | |
| 163 | + @expand-change="onCategoryExpand" | |
| 141 | 164 | > |
| 142 | - <el-table-column type="index" label="行号" width="56" :index="indexMethod" fixed /> | |
| 143 | - <el-table-column prop="单据日期" label="单据日期" width="110" show-overflow-tooltip /> | |
| 144 | - <el-table-column prop="单据编号" label="单据编号" min-width="160" show-overflow-tooltip /> | |
| 145 | - <el-table-column prop="单据类型" label="单据类型" width="120" show-overflow-tooltip /> | |
| 146 | - <el-table-column prop="往来单位" label="往来单位" min-width="140" show-overflow-tooltip /> | |
| 147 | - <el-table-column prop="经手人" label="经手人" width="100" show-overflow-tooltip /> | |
| 148 | - <el-table-column prop="仓库名称" label="仓库名称" min-width="120" show-overflow-tooltip /> | |
| 149 | - <el-table-column prop="商品名称" label="商品名称" min-width="160" show-overflow-tooltip /> | |
| 150 | - <el-table-column prop="数量" label="数量" width="90" align="right"> | |
| 151 | - <template slot-scope="scope"> | |
| 152 | - {{ formatQty(scope.row['数量']) }} | |
| 165 | + <el-table-column type="expand" width="48"> | |
| 166 | + <template slot-scope="catScope"> | |
| 167 | + <div v-loading="brandLoading[categoryRowKey(catScope.row)]" class="nested-wrap"> | |
| 168 | + <el-table | |
| 169 | + :data="brandMap[categoryRowKey(catScope.row)] || []" | |
| 170 | + border | |
| 171 | + size="small" | |
| 172 | + class="nested-table" | |
| 173 | + :row-key="r => brandRowKey(catScope.row, r)" | |
| 174 | + @expand-change="(r, er) => onBrandExpand(catScope.row, r, er)" | |
| 175 | + > | |
| 176 | + <el-table-column type="expand" width="44"> | |
| 177 | + <template slot-scope="brandScope"> | |
| 178 | + <div v-loading="productLoading[brandRowKey(catScope.row, brandScope.row)]" class="nested-wrap"> | |
| 179 | + <el-table | |
| 180 | + :data="productMap[brandRowKey(catScope.row, brandScope.row)] || []" | |
| 181 | + border | |
| 182 | + size="small" | |
| 183 | + class="nested-table nested-table--deep" | |
| 184 | + :row-key="r => productRowKey(catScope.row, brandScope.row, r)" | |
| 185 | + @expand-change="(r, er) => onProductExpand(catScope.row, brandScope.row, r, er)" | |
| 186 | + > | |
| 187 | + <el-table-column type="expand" width="42"> | |
| 188 | + <template slot-scope="prodScope"> | |
| 189 | + <div v-loading="lineLoading[lineKey(catScope.row, brandScope.row, prodScope.row)]" class="nested-wrap detail-wrap"> | |
| 190 | + <el-table | |
| 191 | + :data="(lineMap[lineKey(catScope.row, brandScope.row, prodScope.row)] || {}).list || []" | |
| 192 | + border | |
| 193 | + size="mini" | |
| 194 | + class="nested-table" | |
| 195 | + > | |
| 196 | + <el-table-column type="index" label="行号" width="52" align="center" /> | |
| 197 | + <el-table-column prop="单据日期" label="单据日期" width="108" show-overflow-tooltip sortable :sort-method="sortTextCol('单据日期')" /> | |
| 198 | + <el-table-column prop="单据编号" label="单据编号" min-width="140" show-overflow-tooltip sortable :sort-method="sortTextCol('单据编号')" /> | |
| 199 | + <el-table-column prop="单据类型" label="单据类型" width="108" show-overflow-tooltip sortable :sort-method="sortTextCol('单据类型')" /> | |
| 200 | + <el-table-column prop="往来单位" label="往来单位" min-width="120" show-overflow-tooltip sortable :sort-method="sortTextCol('往来单位')" /> | |
| 201 | + <el-table-column prop="经手人" label="经手人" width="88" show-overflow-tooltip sortable :sort-method="sortTextCol('经手人')" /> | |
| 202 | + <el-table-column prop="仓库名称" label="仓库名称" min-width="100" show-overflow-tooltip sortable :sort-method="sortTextCol('仓库名称')" /> | |
| 203 | + <el-table-column prop="商品名称" label="商品名称" min-width="140" show-overflow-tooltip sortable :sort-method="sortTextCol('商品名称')" /> | |
| 204 | + <el-table-column prop="数量" label="数量" width="88" align="right" sortable :sort-method="sortNumCol('数量')"> | |
| 205 | + <template slot-scope="s">{{ formatQty(s.row['数量']) }}</template> | |
| 206 | + </el-table-column> | |
| 207 | + <el-table-column prop="入库单价" label="入库单价" width="100" align="right" sortable :sort-method="sortNumCol('入库单价')"> | |
| 208 | + <template slot-scope="s">{{ formatMoney(s.row['入库单价']) }}</template> | |
| 209 | + </el-table-column> | |
| 210 | + <el-table-column prop="采购金额" label="采购金额" width="108" align="right" sortable :sort-method="sortNumCol('采购金额')"> | |
| 211 | + <template slot-scope="s">{{ formatMoney(s.row['采购金额']) }}</template> | |
| 212 | + </el-table-column> | |
| 213 | + </el-table> | |
| 214 | + <div v-if="linePager[lineKey(catScope.row, brandScope.row, prodScope.row)]" class="mini-pager"> | |
| 215 | + <el-pagination | |
| 216 | + small | |
| 217 | + layout="prev, pager, next, total" | |
| 218 | + :total="linePager[lineKey(catScope.row, brandScope.row, prodScope.row)].total" | |
| 219 | + :page-size="linePager[lineKey(catScope.row, brandScope.row, prodScope.row)].pageSize" | |
| 220 | + :current-page="linePager[lineKey(catScope.row, brandScope.row, prodScope.row)].currentPage" | |
| 221 | + @current-change="p => fetchLines(catScope.row, brandScope.row, prodScope.row, p)" | |
| 222 | + /> | |
| 223 | + </div> | |
| 224 | + </div> | |
| 225 | + </template> | |
| 226 | + </el-table-column> | |
| 227 | + <el-table-column label="商品编号" min-width="100" show-overflow-tooltip sortable :sort-method="sortTextCol('商品编号')"> | |
| 228 | + <template slot-scope="s"> | |
| 229 | + <i class="el-icon-postcard row-ico row-ico--primary" /> | |
| 230 | + {{ cellText(s.row['商品编号']) }} | |
| 231 | + </template> | |
| 232 | + </el-table-column> | |
| 233 | + <el-table-column label="明细分类" min-width="120" show-overflow-tooltip sortable :sort-method="sortTextCol('明细分类')"> | |
| 234 | + <template slot-scope="s"> | |
| 235 | + <i class="el-icon-collection-tag row-ico row-ico--info" /> | |
| 236 | + {{ cellText(s.row['明细分类']) }} | |
| 237 | + </template> | |
| 238 | + </el-table-column> | |
| 239 | + <el-table-column label="商品名称" min-width="140" show-overflow-tooltip sortable :sort-method="sortTextCol('商品名称')"> | |
| 240 | + <template slot-scope="s"> | |
| 241 | + <i class="el-icon-goods row-ico row-ico--muted" /> | |
| 242 | + {{ cellText(s.row['商品名称']) }} | |
| 243 | + </template> | |
| 244 | + </el-table-column> | |
| 245 | + <el-table-column label="数量" width="88" align="right" sortable :sort-method="sortNumCol('数量')"> | |
| 246 | + <template slot-scope="s">{{ formatQty(s.row['数量']) }}</template> | |
| 247 | + </el-table-column> | |
| 248 | + <el-table-column label="入库单价" width="100" align="right" sortable :sort-method="sortNumCol('入库单价')"> | |
| 249 | + <template slot-scope="s">{{ formatMoney(s.row['入库单价']) }}</template> | |
| 250 | + </el-table-column> | |
| 251 | + <el-table-column label="采购金额" width="108" align="right" sortable :sort-method="sortNumCol('采购金额')"> | |
| 252 | + <template slot-scope="s">{{ formatMoney(s.row['采购金额']) }}</template> | |
| 253 | + </el-table-column> | |
| 254 | + </el-table> | |
| 255 | + </div> | |
| 256 | + </template> | |
| 257 | + </el-table-column> | |
| 258 | + <el-table-column label="品牌" min-width="140" show-overflow-tooltip sortable :sort-method="sortTextCol('品牌名称')"> | |
| 259 | + <template slot-scope="s"> | |
| 260 | + <i class="el-icon-medal row-ico row-ico--primary" /> | |
| 261 | + {{ cellText(s.row['品牌名称'] || s.row['商品名称']) }} | |
| 262 | + </template> | |
| 263 | + </el-table-column> | |
| 264 | + <el-table-column label="数量" width="88" align="right" sortable :sort-method="sortNumCol('数量')"> | |
| 265 | + <template slot-scope="s">{{ formatQty(s.row['数量']) }}</template> | |
| 266 | + </el-table-column> | |
| 267 | + <el-table-column label="入库单价" width="100" align="right" sortable :sort-method="sortNumCol('入库单价')"> | |
| 268 | + <template slot-scope="s">{{ formatMoney(s.row['入库单价']) }}</template> | |
| 269 | + </el-table-column> | |
| 270 | + <el-table-column label="采购金额" width="108" align="right" sortable :sort-method="sortNumCol('采购金额')"> | |
| 271 | + <template slot-scope="s">{{ formatMoney(s.row['采购金额']) }}</template> | |
| 272 | + </el-table-column> | |
| 273 | + </el-table> | |
| 274 | + <div v-if="!(brandMap[categoryRowKey(catScope.row)] || []).length && !brandLoading[categoryRowKey(catScope.row)]" class="nested-empty">暂无品牌数据</div> | |
| 275 | + </div> | |
| 153 | 276 | </template> |
| 154 | 277 | </el-table-column> |
| 155 | - <el-table-column prop="入库单价" label="入库单价" width="110" align="right"> | |
| 278 | + <el-table-column type="index" label="行号" width="56" align="center" /> | |
| 279 | + <el-table-column label="分类名称" min-width="160" show-overflow-tooltip sortable :sort-method="sortTextCol('分类名称')"> | |
| 156 | 280 | <template slot-scope="scope"> |
| 157 | - {{ formatMoney(scope.row['入库单价']) }} | |
| 281 | + <i class="el-icon-folder-opened row-ico row-ico--primary" /> | |
| 282 | + {{ cellText(scope.row['分类名称']) }} | |
| 158 | 283 | </template> |
| 159 | 284 | </el-table-column> |
| 160 | - <el-table-column prop="采购金额" label="采购金额" width="120" align="right"> | |
| 285 | + <el-table-column label="数量" width="96" align="right" sortable :sort-method="sortNumCol('数量')"> | |
| 286 | + <template slot-scope="scope">{{ formatQty(scope.row['数量']) }}</template> | |
| 287 | + </el-table-column> | |
| 288 | + <el-table-column label="入库单价" width="104" align="right" sortable :sort-method="sortNumCol('入库单价')"> | |
| 289 | + <template slot-scope="scope">{{ formatMoney(scope.row['入库单价']) }}</template> | |
| 290 | + </el-table-column> | |
| 291 | + <el-table-column label="采购金额" width="112" align="right" sortable :sort-method="sortNumCol('采购金额')"> | |
| 292 | + <template slot-scope="scope">{{ formatMoney(scope.row['采购金额']) }}</template> | |
| 293 | + </el-table-column> | |
| 294 | + <el-table-column label="操作" width="120" align="left" fixed="right"> | |
| 161 | 295 | <template slot-scope="scope"> |
| 162 | - {{ formatMoney(scope.row['采购金额']) }} | |
| 296 | + <el-button type="text" size="mini" icon="el-icon-tickets" @click.stop="openLinearDialog(scope.row)">线性列表</el-button> | |
| 163 | 297 | </template> |
| 164 | 298 | </el-table-column> |
| 165 | 299 | </el-table> |
| 166 | - <div class="pager-wrap"> | |
| 167 | - <el-pagination | |
| 168 | - :current-page="pagination.currentPage" | |
| 169 | - :page-sizes="[50, 100, 200, 500]" | |
| 170 | - :page-size="pagination.pageSize" | |
| 171 | - layout="total, sizes, prev, pager, next, jumper" | |
| 172 | - :total="pagination.total" | |
| 173 | - @size-change="handleSizeChange" | |
| 174 | - @current-change="handleCurrentChange" | |
| 175 | - /> | |
| 300 | + | |
| 301 | + <div v-if="categoryList.length" class="purchase-sum-footer"> | |
| 302 | + <i class="el-icon-s-data row-ico--primary" /> | |
| 303 | + <span>合计(当前分类列表)</span> | |
| 304 | + <span class="sum-item">数量:{{ formatQty(sumCategoryQty) }}</span> | |
| 305 | + <span class="sum-item">采购金额:{{ formatMoney(sumCategoryAmt) }}</span> | |
| 176 | 306 | </div> |
| 177 | 307 | </div> |
| 178 | 308 | </div> |
| 309 | + | |
| 310 | + <el-dialog | |
| 311 | + title="线性列表 — 分类下全部采购明细" | |
| 312 | + :visible.sync="linearVisible" | |
| 313 | + width="1180px" | |
| 314 | + top="5vh" | |
| 315 | + append-to-body | |
| 316 | + class="NCC-dialog NCC-dialog_center" | |
| 317 | + @close="linearRows = []" | |
| 318 | + > | |
| 319 | + <div v-loading="linearLoading" class="linear-dialog-body"> | |
| 320 | + <p class="linear-hint">{{ linearHint }}</p> | |
| 321 | + <el-table :data="linearRows" border size="small" max-height="520" class="linear-table"> | |
| 322 | + <el-table-column type="index" label="行号" width="52" /> | |
| 323 | + <el-table-column prop="单据日期" label="单据日期" width="100" show-overflow-tooltip sortable :sort-method="sortTextCol('单据日期')" /> | |
| 324 | + <el-table-column prop="单据编号" label="单据编号" min-width="130" show-overflow-tooltip sortable :sort-method="sortTextCol('单据编号')" /> | |
| 325 | + <el-table-column prop="单据类型" label="单据类型" width="100" show-overflow-tooltip /> | |
| 326 | + <el-table-column prop="往来单位" label="往来单位" min-width="110" show-overflow-tooltip /> | |
| 327 | + <el-table-column prop="经手人" label="经手人" width="80" show-overflow-tooltip /> | |
| 328 | + <el-table-column prop="仓库名称" label="仓库名称" min-width="96" show-overflow-tooltip /> | |
| 329 | + <el-table-column prop="商品名称" label="商品名称" min-width="120" show-overflow-tooltip /> | |
| 330 | + <el-table-column prop="数量" label="数量" width="80" align="right" sortable :sort-method="sortNumCol('数量')"> | |
| 331 | + <template slot-scope="s">{{ formatQty(s.row['数量']) }}</template> | |
| 332 | + </el-table-column> | |
| 333 | + <el-table-column prop="入库单价" label="入库单价" width="92" align="right"> | |
| 334 | + <template slot-scope="s">{{ formatMoney(s.row['入库单价']) }}</template> | |
| 335 | + </el-table-column> | |
| 336 | + <el-table-column prop="采购金额" label="采购金额" width="100" align="right" sortable :sort-method="sortNumCol('采购金额')"> | |
| 337 | + <template slot-scope="s">{{ formatMoney(s.row['采购金额']) }}</template> | |
| 338 | + </el-table-column> | |
| 339 | + </el-table> | |
| 340 | + </div> | |
| 341 | + </el-dialog> | |
| 179 | 342 | </div> |
| 180 | 343 | </template> |
| 181 | 344 | |
| ... | ... | @@ -183,37 +346,84 @@ |
| 183 | 346 | import request from '@/utils/request' |
| 184 | 347 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 185 | 348 | |
| 349 | +const DEFAULT_BILL_TYPES = ['采购入库单', '采购退货单'] | |
| 350 | + | |
| 186 | 351 | export default { |
| 187 | 352 | name: 'PurchaseSummary', |
| 188 | - | |
| 189 | 353 | data() { |
| 190 | 354 | return { |
| 191 | - list: [], | |
| 192 | - billTypeOptions: ['采购入库单', '采购退货单'], | |
| 355 | + categoryList: [], | |
| 356 | + categoryLoading: false, | |
| 357 | + brandMap: {}, | |
| 358 | + brandLoading: {}, | |
| 359 | + productMap: {}, | |
| 360 | + productLoading: {}, | |
| 361 | + lineMap: {}, | |
| 362 | + linePager: {}, | |
| 363 | + lineLoading: {}, | |
| 364 | + billTypeOptions: [...DEFAULT_BILL_TYPES], | |
| 193 | 365 | filters: { |
| 194 | 366 | dateRange: [], |
| 195 | 367 | contactUnit: [], |
| 196 | 368 | agent: [], |
| 197 | - productName: '', | |
| 369 | + productSpId: '', | |
| 198 | 370 | warehouse: [], |
| 199 | - billType: ['采购入库单', '采购退货单'] | |
| 371 | + billType: [...DEFAULT_BILL_TYPES] | |
| 200 | 372 | }, |
| 201 | 373 | contactUnitOptions: [], |
| 202 | 374 | agentOptions: [], |
| 203 | 375 | warehouseOptions: [], |
| 204 | 376 | productOptions: [], |
| 205 | 377 | productLoading: false, |
| 206 | - pagination: { | |
| 207 | - currentPage: 1, | |
| 208 | - pageSize: 100, | |
| 209 | - total: 0 | |
| 210 | - } | |
| 378 | + linearVisible: false, | |
| 379 | + linearLoading: false, | |
| 380 | + linearRows: [], | |
| 381 | + linearHint: '' | |
| 211 | 382 | } |
| 212 | 383 | }, |
| 213 | - | |
| 384 | + computed: { | |
| 385 | + sumCategoryQty() { | |
| 386 | + return this.categoryList.reduce((s, r) => s + this.parseNum(r['数量']), 0) | |
| 387 | + }, | |
| 388 | + sumCategoryAmt() { | |
| 389 | + return this.categoryList.reduce((s, r) => s + this.parseNum(r['采购金额']), 0) | |
| 390 | + } | |
| 391 | + }, | |
| 392 | + created() { | |
| 393 | + this.loadFilterOptions() | |
| 394 | + this.fetchCategories() | |
| 395 | + }, | |
| 214 | 396 | methods: { |
| 215 | - indexMethod(index) { | |
| 216 | - return (this.pagination.currentPage - 1) * this.pagination.pageSize + index + 1 | |
| 397 | + categoryRowKey(row) { | |
| 398 | + return String(row['分类Id'] != null ? row['分类Id'] : '') | |
| 399 | + }, | |
| 400 | + brandRowKey(catRow, brandRow) { | |
| 401 | + return `${this.categoryRowKey(catRow)}|${String(brandRow['品牌Id'] != null ? brandRow['品牌Id'] : '')}` | |
| 402 | + }, | |
| 403 | + productRowKey(catRow, brandRow, prodRow) { | |
| 404 | + return `${this.brandRowKey(catRow, brandRow)}|${String(prodRow['商品Id'] != null ? prodRow['商品Id'] : '')}` | |
| 405 | + }, | |
| 406 | + lineKey(catRow, brandRow, prodRow) { | |
| 407 | + return this.productRowKey(catRow, brandRow, prodRow) | |
| 408 | + }, | |
| 409 | + parseNum(val) { | |
| 410 | + if (val == null || val === '') return 0 | |
| 411 | + const n = Number(String(val).replace(/,/g, '').trim()) | |
| 412 | + return Number.isFinite(n) ? n : 0 | |
| 413 | + }, | |
| 414 | + sortNumCol(prop) { | |
| 415 | + return (a, b) => this.parseNum(a[prop]) - this.parseNum(b[prop]) | |
| 416 | + }, | |
| 417 | + sortTextCol(prop) { | |
| 418 | + return (a, b) => { | |
| 419 | + const sa = String(a[prop] != null ? a[prop] : '').trim() | |
| 420 | + const sb = String(b[prop] != null ? b[prop] : '').trim() | |
| 421 | + return sa.localeCompare(sb, 'zh-CN') | |
| 422 | + } | |
| 423 | + }, | |
| 424 | + cellText(v) { | |
| 425 | + if (v == null || String(v).trim() === '') return '无' | |
| 426 | + return String(v) | |
| 217 | 427 | }, |
| 218 | 428 | formatQty(val) { |
| 219 | 429 | if (val === null || val === undefined || val === '') return '无' |
| ... | ... | @@ -227,6 +437,62 @@ export default { |
| 227 | 437 | if (Number.isNaN(n)) return String(val) |
| 228 | 438 | return n.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 4 }) |
| 229 | 439 | }, |
| 440 | + /** 商品编码(空则返回空串,便于单行展示) */ | |
| 441 | + productCodeRaw(item) { | |
| 442 | + if (!item) return '' | |
| 443 | + const c = | |
| 444 | + item.F_Spbm || | |
| 445 | + item.spbm || | |
| 446 | + item.Spbm || | |
| 447 | + item.商品编号 || | |
| 448 | + item.code || | |
| 449 | + '' | |
| 450 | + const t = c != null && String(c).trim() !== '' ? String(c).trim() : '' | |
| 451 | + return t | |
| 452 | + }, | |
| 453 | + /** 商品名称 */ | |
| 454 | + productNameRaw(item) { | |
| 455 | + if (!item) return '' | |
| 456 | + const n = | |
| 457 | + item.F_Spmc || | |
| 458 | + item.spmc || | |
| 459 | + item.Spmc || | |
| 460 | + item.productName || | |
| 461 | + item.商品名称 || | |
| 462 | + item.name || | |
| 463 | + '' | |
| 464 | + const t = n != null && String(n).trim() !== '' ? String(n).trim() : '' | |
| 465 | + return t | |
| 466 | + }, | |
| 467 | + /** 选中后在输入框内显示的完整文案(编码 + 名称) */ | |
| 468 | + formatProductLabel(item) { | |
| 469 | + if (!item) return '' | |
| 470 | + const code = this.productCodeRaw(item) | |
| 471 | + const name = this.productNameRaw(item) | |
| 472 | + if (code && name) return `${code} | ${name}` | |
| 473 | + if (name) return name | |
| 474 | + if (code) return code | |
| 475 | + const id = item.F_Id || item.id | |
| 476 | + return id ? String(id) : '无' | |
| 477 | + }, | |
| 478 | + buildBasePayload() { | |
| 479 | + const payload = {} | |
| 480 | + if (this.filters.dateRange && this.filters.dateRange.length === 2) { | |
| 481 | + payload.startDate = this.filters.dateRange[0] | |
| 482 | + payload.endDate = this.filters.dateRange[1] | |
| 483 | + } | |
| 484 | + if (this.filters.contactUnit.length) payload.contactUnit = this.filters.contactUnit.join(',') | |
| 485 | + if (this.filters.agent.length) payload.agent = this.filters.agent.join(',') | |
| 486 | + if (this.filters.warehouse.length) payload.warehouse = this.filters.warehouse.join(',') | |
| 487 | + if (this.filters.productSpId) payload.productSpId = this.filters.productSpId | |
| 488 | + const bt = this.filters.billType || [] | |
| 489 | + if (bt.length > 0 && bt.length < this.billTypeOptions.length) { | |
| 490 | + payload.billType = bt.join(',') | |
| 491 | + } else { | |
| 492 | + payload.billType = '' | |
| 493 | + } | |
| 494 | + return payload | |
| 495 | + }, | |
| 230 | 496 | async loadFilterOptions() { |
| 231 | 497 | try { |
| 232 | 498 | const companyRes = await request({ |
| ... | ... | @@ -255,9 +521,12 @@ export default { |
| 255 | 521 | |
| 256 | 522 | const userRes = await previewDataInterface('675937572047815941') |
| 257 | 523 | const userList = userRes.data || [] |
| 258 | - this.agentOptions = Array.from( | |
| 259 | - new Set(userList.map(x => x.realName || x.F_RealName || x.fullName).filter(Boolean)) | |
| 260 | - ) | |
| 524 | + this.agentOptions = (userList || []) | |
| 525 | + .map(x => ({ | |
| 526 | + label: x.realName || x.F_RealName || x.fullName || x.name || x.F_Account || x.account || '', | |
| 527 | + value: x.id || x.F_Id || x.userId | |
| 528 | + })) | |
| 529 | + .filter(x => x.value && x.label) | |
| 261 | 530 | } catch (e) { |
| 262 | 531 | console.error('采购汇总筛选下拉加载失败', e) |
| 263 | 532 | } |
| ... | ... | @@ -270,7 +539,7 @@ export default { |
| 270 | 539 | this.productLoading = true |
| 271 | 540 | try { |
| 272 | 541 | const res = await request({ |
| 273 | - url: '/api/Extend/WtSp', | |
| 542 | + url: '/api/Extend/WtSp/GetListByKeyword', | |
| 274 | 543 | method: 'GET', |
| 275 | 544 | data: { pageSize: 200, currentPage: 1, keyword: query } |
| 276 | 545 | }) |
| ... | ... | @@ -281,138 +550,320 @@ export default { |
| 281 | 550 | this.productLoading = false |
| 282 | 551 | } |
| 283 | 552 | }, |
| 284 | - formatProductLabel(item) { | |
| 285 | - if (!item) return '' | |
| 286 | - const code = item.spbm || item.productCode || item.商品编号 || item.code || item.F_Id || item.id || '' | |
| 287 | - const name = item.F_Spmc || item.productName || item.商品名称 || item.name || '' | |
| 288 | - return [code, name].filter(Boolean).join(' ') | |
| 553 | + clearTreeCaches() { | |
| 554 | + this.brandMap = {} | |
| 555 | + this.brandLoading = {} | |
| 556 | + this.productMap = {} | |
| 557 | + this.productLoading = {} | |
| 558 | + this.lineMap = {} | |
| 559 | + this.linePager = {} | |
| 560 | + this.lineLoading = {} | |
| 289 | 561 | }, |
| 290 | - buildQueryPayload() { | |
| 291 | - const payload = {} | |
| 292 | - if (this.filters.dateRange && this.filters.dateRange.length === 2) { | |
| 293 | - payload.startDate = this.filters.dateRange[0] | |
| 294 | - payload.endDate = this.filters.dateRange[1] | |
| 562 | + fetchCategories() { | |
| 563 | + this.categoryLoading = true | |
| 564 | + this.clearTreeCaches() | |
| 565 | + request({ | |
| 566 | + url: '/api/Extend/WtXsckd/Actions/GetPurchaseSummaryByCategory', | |
| 567 | + method: 'GET', | |
| 568 | + data: this.buildBasePayload() | |
| 569 | + }) | |
| 570 | + .then(res => { | |
| 571 | + const rows = Array.isArray(res.data) ? res.data : (res.data && res.data.list) || [] | |
| 572 | + this.categoryList = rows | |
| 573 | + }) | |
| 574 | + .catch(() => { | |
| 575 | + this.categoryList = [] | |
| 576 | + }) | |
| 577 | + .finally(() => { | |
| 578 | + this.categoryLoading = false | |
| 579 | + }) | |
| 580 | + }, | |
| 581 | + onCategoryExpand(row, expandedRows) { | |
| 582 | + const id = String(row['分类Id']) | |
| 583 | + if (expandedRows.some(r => String(r['分类Id']) === id)) { | |
| 584 | + this.loadBrands(row) | |
| 295 | 585 | } |
| 296 | - if (this.filters.productName) payload.product = this.filters.productName | |
| 297 | - if (this.filters.contactUnit.length) payload.contactUnit = this.filters.contactUnit.join(',') | |
| 298 | - if (this.filters.agent.length) payload.agent = this.filters.agent.join(',') | |
| 299 | - if (this.filters.warehouse.length) payload.warehouse = this.filters.warehouse.join(',') | |
| 300 | - | |
| 301 | - if (this.filters.billType.length > 0 && this.filters.billType.length < this.billTypeOptions.length) { | |
| 302 | - payload.billType = this.filters.billType.join(',') | |
| 303 | - } else { | |
| 304 | - payload.billType = '' | |
| 586 | + }, | |
| 587 | + loadBrands(catRow) { | |
| 588 | + const k = this.categoryRowKey(catRow) | |
| 589 | + if (this.brandMap[k] !== undefined || this.brandLoading[k]) return | |
| 590 | + this.$set(this.brandLoading, k, true) | |
| 591 | + const cid = String(catRow['分类Id'] != null ? catRow['分类Id'] : '') | |
| 592 | + request({ | |
| 593 | + url: '/api/Extend/WtXsckd/Actions/GetPurchaseSummaryByBrand', | |
| 594 | + method: 'GET', | |
| 595 | + data: { ...this.buildBasePayload(), categoryId: cid } | |
| 596 | + }) | |
| 597 | + .then(res => { | |
| 598 | + const rows = Array.isArray(res.data) ? res.data : (res.data && res.data.list) || [] | |
| 599 | + this.$set(this.brandMap, k, rows) | |
| 600 | + }) | |
| 601 | + .catch(() => { | |
| 602 | + this.$set(this.brandMap, k, []) | |
| 603 | + }) | |
| 604 | + .finally(() => { | |
| 605 | + this.$set(this.brandLoading, k, false) | |
| 606 | + }) | |
| 607 | + }, | |
| 608 | + onBrandExpand(catRow, brandRow, expandedRows) { | |
| 609 | + if (expandedRows.some(r => this.brandRowKey(catRow, r) === this.brandRowKey(catRow, brandRow))) { | |
| 610 | + this.loadProducts(catRow, brandRow) | |
| 305 | 611 | } |
| 306 | - payload.currentPage = this.pagination.currentPage | |
| 307 | - payload.pageSize = this.pagination.pageSize | |
| 308 | - return payload | |
| 309 | 612 | }, |
| 310 | - handleSearch() { | |
| 311 | - this.pagination.currentPage = 1 | |
| 312 | - this.fetchData() | |
| 613 | + loadProducts(catRow, brandRow) { | |
| 614 | + const k = this.brandRowKey(catRow, brandRow) | |
| 615 | + if (this.productMap[k] !== undefined || this.productLoading[k]) return | |
| 616 | + this.$set(this.productLoading, k, true) | |
| 617 | + const cid = String(catRow['分类Id'] != null ? catRow['分类Id'] : '') | |
| 618 | + const bid = String(brandRow['品牌Id'] != null ? brandRow['品牌Id'] : '') | |
| 619 | + request({ | |
| 620 | + url: '/api/Extend/WtXsckd/Actions/GetPurchaseSummaryByProductAgg', | |
| 621 | + method: 'GET', | |
| 622 | + data: { ...this.buildBasePayload(), categoryId: cid, brandId: bid } | |
| 623 | + }) | |
| 624 | + .then(res => { | |
| 625 | + const rows = Array.isArray(res.data) ? res.data : (res.data && res.data.list) || [] | |
| 626 | + this.$set(this.productMap, k, rows) | |
| 627 | + }) | |
| 628 | + .catch(() => { | |
| 629 | + this.$set(this.productMap, k, []) | |
| 630 | + }) | |
| 631 | + .finally(() => { | |
| 632 | + this.$set(this.productLoading, k, false) | |
| 633 | + }) | |
| 313 | 634 | }, |
| 314 | - fetchData() { | |
| 315 | - const payload = this.buildQueryPayload() | |
| 635 | + onProductExpand(catRow, brandRow, prodRow, expandedRows) { | |
| 636 | + if (expandedRows.some(r => this.productRowKey(catRow, brandRow, r) === this.productRowKey(catRow, brandRow, prodRow))) { | |
| 637 | + this.initLinePager(catRow, brandRow, prodRow) | |
| 638 | + this.fetchLines(catRow, brandRow, prodRow, 1) | |
| 639 | + } | |
| 640 | + }, | |
| 641 | + initLinePager(catRow, brandRow, prodRow) { | |
| 642 | + const lk = this.lineKey(catRow, brandRow, prodRow) | |
| 643 | + if (!this.linePager[lk]) { | |
| 644 | + this.$set(this.linePager, lk, { currentPage: 1, pageSize: 50, total: 0 }) | |
| 645 | + } | |
| 646 | + }, | |
| 647 | + fetchLines(catRow, brandRow, prodRow, page) { | |
| 648 | + const lk = this.lineKey(catRow, brandRow, prodRow) | |
| 649 | + this.initLinePager(catRow, brandRow, prodRow) | |
| 650 | + const pager = this.linePager[lk] | |
| 651 | + pager.currentPage = page || 1 | |
| 652 | + this.$set(this.lineLoading, lk, true) | |
| 653 | + const cid = String(catRow['分类Id'] != null ? catRow['分类Id'] : '') | |
| 654 | + const bid = String(brandRow['品牌Id'] != null ? brandRow['品牌Id'] : '') | |
| 655 | + const pid = String(prodRow['商品Id'] != null ? prodRow['商品Id'] : '') | |
| 316 | 656 | request({ |
| 317 | - url: `/api/Extend/WtXsckd/Actions/GetPurchaseSummary`, | |
| 657 | + url: '/api/Extend/WtXsckd/Actions/GetPurchaseSummary', | |
| 318 | 658 | method: 'GET', |
| 319 | - data: payload | |
| 320 | - }).then(res => { | |
| 321 | - const body = res.data | |
| 322 | - if (body && typeof body === 'object' && !Array.isArray(body) && body.list !== undefined) { | |
| 323 | - this.list = body.list || [] | |
| 324 | - this.pagination.total = body.total != null ? Number(body.total) : 0 | |
| 325 | - } else if (Array.isArray(body)) { | |
| 326 | - this.list = body | |
| 327 | - this.pagination.total = body.length | |
| 328 | - } else { | |
| 329 | - this.list = [] | |
| 330 | - this.pagination.total = 0 | |
| 659 | + data: { | |
| 660 | + ...this.buildBasePayload(), | |
| 661 | + categoryId: cid, | |
| 662 | + brandId: bid, | |
| 663 | + productSpId: pid, | |
| 664 | + currentPage: pager.currentPage, | |
| 665 | + pageSize: pager.pageSize | |
| 331 | 666 | } |
| 332 | 667 | }) |
| 668 | + .then(res => { | |
| 669 | + const body = res.data | |
| 670 | + let list = [] | |
| 671 | + let total = 0 | |
| 672 | + if (body && typeof body === 'object' && !Array.isArray(body) && body.list !== undefined) { | |
| 673 | + list = body.list || [] | |
| 674 | + total = body.total != null ? Number(body.total) : 0 | |
| 675 | + } else if (Array.isArray(body)) { | |
| 676 | + list = body | |
| 677 | + total = body.length | |
| 678 | + } | |
| 679 | + this.$set(this.lineMap, lk, { list }) | |
| 680 | + this.$set(this.linePager[lk], 'total', total) | |
| 681 | + }) | |
| 682 | + .catch(() => { | |
| 683 | + this.$set(this.lineMap, lk, { list: [] }) | |
| 684 | + }) | |
| 685 | + .finally(() => { | |
| 686 | + this.$set(this.lineLoading, lk, false) | |
| 687 | + }) | |
| 333 | 688 | }, |
| 334 | - handleSizeChange(size) { | |
| 335 | - this.pagination.pageSize = size | |
| 336 | - this.pagination.currentPage = 1 | |
| 337 | - this.fetchData() | |
| 689 | + openLinearDialog(catRow) { | |
| 690 | + const cid = String(catRow['分类Id'] != null ? catRow['分类Id'] : '') | |
| 691 | + const cname = this.cellText(catRow['分类名称']) | |
| 692 | + this.linearHint = `分类:${cname}(最多展示 2000 条,与当前筛选条件一致)` | |
| 693 | + this.linearVisible = true | |
| 694 | + this.linearLoading = true | |
| 695 | + this.linearRows = [] | |
| 696 | + request({ | |
| 697 | + url: '/api/Extend/WtXsckd/Actions/GetPurchaseSummaryLinear', | |
| 698 | + method: 'GET', | |
| 699 | + data: { ...this.buildBasePayload(), categoryId: cid } | |
| 700 | + }) | |
| 701 | + .then(res => { | |
| 702 | + this.linearRows = Array.isArray(res.data) ? res.data : (res.data && res.data.list) || [] | |
| 703 | + }) | |
| 704 | + .catch(() => { | |
| 705 | + this.linearRows = [] | |
| 706 | + }) | |
| 707 | + .finally(() => { | |
| 708 | + this.linearLoading = false | |
| 709 | + }) | |
| 338 | 710 | }, |
| 339 | - handleCurrentChange(page) { | |
| 340 | - this.pagination.currentPage = page | |
| 341 | - this.fetchData() | |
| 711 | + handleSearch() { | |
| 712 | + this.fetchCategories() | |
| 342 | 713 | }, |
| 343 | 714 | handleReset() { |
| 344 | 715 | this.filters = { |
| 345 | 716 | dateRange: [], |
| 346 | 717 | contactUnit: [], |
| 347 | 718 | agent: [], |
| 348 | - productName: '', | |
| 719 | + productSpId: '', | |
| 349 | 720 | warehouse: [], |
| 350 | - billType: [...this.billTypeOptions] | |
| 721 | + billType: [...DEFAULT_BILL_TYPES] | |
| 351 | 722 | } |
| 352 | - this.pagination.currentPage = 1 | |
| 353 | - this.fetchData() | |
| 723 | + this.productOptions = [] | |
| 724 | + this.fetchCategories() | |
| 354 | 725 | } |
| 355 | - }, | |
| 356 | - created() { | |
| 357 | - this.loadFilterOptions() | |
| 358 | - this.fetchData() | |
| 359 | 726 | } |
| 360 | 727 | } |
| 361 | 728 | </script> |
| 362 | 729 | |
| 363 | -<style scoped> | |
| 364 | -.purchase-summary-page { | |
| 365 | - width: 100%; | |
| 366 | - min-height: 100%; | |
| 367 | - background: #f9f9f9; | |
| 368 | - padding: 10px 20px; | |
| 369 | - box-sizing: border-box; | |
| 730 | +<style lang="scss" scoped> | |
| 731 | +.purchase-sum-head { | |
| 732 | + align-items: center; | |
| 733 | + margin-bottom: 8px; | |
| 734 | +} | |
| 735 | + | |
| 736 | +.purchase-sum-head__title { | |
| 737 | + font-size: 15px; | |
| 738 | + font-weight: 600; | |
| 739 | + color: #303133; | |
| 740 | + display: inline-flex; | |
| 741 | + align-items: center; | |
| 742 | + gap: 8px; | |
| 370 | 743 | } |
| 371 | 744 | |
| 372 | -.form-section { | |
| 373 | - background: #fff; | |
| 374 | - border-radius: 6px; | |
| 375 | - padding: 10px 10px 0 10px; | |
| 376 | - margin-bottom: 10px; | |
| 745 | +.purchase-sum-head__icon { | |
| 746 | + color: #409eff; | |
| 747 | + font-size: 18px; | |
| 748 | +} | |
| 749 | + | |
| 750 | +.purchase-tree-table { | |
| 751 | + ::v-deep .el-table .cell { | |
| 752 | + white-space: nowrap; | |
| 753 | + } | |
| 754 | +} | |
| 755 | + | |
| 756 | +.nested-wrap { | |
| 757 | + padding: 8px 8px 8px 24px; | |
| 758 | + background: #fafbfc; | |
| 377 | 759 | } |
| 378 | 760 | |
| 379 | -.table-section { | |
| 380 | - background: #fff; | |
| 381 | - border-radius: 6px; | |
| 382 | - padding: 12px 12px 10px 12px; | |
| 383 | - margin: 0; | |
| 761 | +.nested-table { | |
| 384 | 762 | width: 100%; |
| 385 | - box-sizing: border-box; | |
| 386 | 763 | } |
| 387 | 764 | |
| 388 | -.action-row { | |
| 389 | - display: flex; | |
| 390 | - justify-content: flex-start; | |
| 391 | - gap: 8px; | |
| 392 | - padding: 4px 0 10px; | |
| 765 | +.nested-table--deep ::v-deep .el-table__body-wrapper { | |
| 766 | + max-height: 320px; | |
| 767 | + overflow-y: auto; | |
| 393 | 768 | } |
| 394 | 769 | |
| 395 | -.table-title-bar { | |
| 396 | - font-size: 18px; | |
| 397 | - font-weight: bold; | |
| 398 | - margin-bottom: 10px; | |
| 770 | +.detail-wrap { | |
| 771 | + min-width: 720px; | |
| 772 | +} | |
| 773 | + | |
| 774 | +.mini-pager { | |
| 775 | + margin-top: 8px; | |
| 776 | + text-align: left; | |
| 777 | +} | |
| 778 | + | |
| 779 | +.nested-empty { | |
| 780 | + padding: 12px; | |
| 781 | + color: #909399; | |
| 782 | + font-size: 13px; | |
| 783 | +} | |
| 784 | + | |
| 785 | +.row-ico { | |
| 786 | + margin-right: 4px; | |
| 787 | +} | |
| 788 | + | |
| 789 | +.row-ico--primary { | |
| 790 | + color: #409eff; | |
| 791 | +} | |
| 792 | + | |
| 793 | +.row-ico--info { | |
| 794 | + color: #909399; | |
| 795 | +} | |
| 796 | + | |
| 797 | +.row-ico--muted { | |
| 798 | + color: #c0c4cc; | |
| 799 | +} | |
| 800 | + | |
| 801 | +.purchase-sum-footer { | |
| 802 | + margin-top: 12px; | |
| 803 | + padding: 10px 12px; | |
| 804 | + background: #f5f7fa; | |
| 805 | + border-radius: 8px; | |
| 806 | + font-size: 13px; | |
| 807 | + color: #606266; | |
| 399 | 808 | display: flex; |
| 809 | + flex-wrap: wrap; | |
| 400 | 810 | align-items: center; |
| 401 | - gap: 12px; | |
| 811 | + gap: 16px; | |
| 402 | 812 | } |
| 403 | 813 | |
| 404 | -.table-scroll { | |
| 405 | - max-height: calc(100vh - 300px); | |
| 406 | - overflow-y: auto; | |
| 814 | +.sum-item { | |
| 815 | + font-weight: 600; | |
| 816 | + color: #303133; | |
| 407 | 817 | } |
| 408 | 818 | |
| 409 | -.pager-wrap { | |
| 410 | - display: flex; | |
| 411 | - justify-content: flex-start; | |
| 412 | - padding: 12px 0 4px; | |
| 819 | +.linear-dialog-body { | |
| 820 | + min-height: 120px; | |
| 413 | 821 | } |
| 414 | 822 | |
| 415 | -.purchase-record-table ::v-deep .cell { | |
| 823 | +.linear-hint { | |
| 824 | + font-size: 12px; | |
| 825 | + color: #909399; | |
| 826 | + margin: 0 0 10px; | |
| 827 | +} | |
| 828 | + | |
| 829 | +.linear-table ::v-deep .el-table .cell { | |
| 416 | 830 | white-space: nowrap; |
| 417 | 831 | } |
| 832 | + | |
| 833 | +/* 商品远程下拉:单行「编码 | 名称」,避免多行标签错位 */ | |
| 834 | +.product-opt-row { | |
| 835 | + display: flex; | |
| 836 | + align-items: center; | |
| 837 | + max-width: 100%; | |
| 838 | + font-size: 13px; | |
| 839 | + line-height: 1.4; | |
| 840 | +} | |
| 841 | + | |
| 842 | +.product-opt-code { | |
| 843 | + flex-shrink: 0; | |
| 844 | + color: #606266; | |
| 845 | + font-weight: 600; | |
| 846 | +} | |
| 847 | + | |
| 848 | +.product-opt-sep { | |
| 849 | + flex-shrink: 0; | |
| 850 | + margin: 0 6px; | |
| 851 | + color: #dcdfe6; | |
| 852 | +} | |
| 853 | + | |
| 854 | +.product-opt-name { | |
| 855 | + flex: 1; | |
| 856 | + min-width: 0; | |
| 857 | + overflow: hidden; | |
| 858 | + text-overflow: ellipsis; | |
| 859 | + color: #303133; | |
| 860 | +} | |
| 861 | +</style> | |
| 862 | + | |
| 863 | +<!-- 下拉挂到 body,需非 scoped 才能命中 popper --> | |
| 864 | +<style lang="scss"> | |
| 865 | +.wt-purchase-sum-product-dropdown.el-select-dropdown { | |
| 866 | + min-width: 420px !important; | |
| 867 | + max-width: min(720px, 92vw); | |
| 868 | +} | |
| 418 | 869 | </style> | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtSfk/Form.vue
| ... | ... | @@ -91,8 +91,8 @@ |
| 91 | 91 | </template> |
| 92 | 92 | <script> |
| 93 | 93 | import request from '@/utils/request' |
| 94 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 95 | 94 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 95 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 96 | 96 | export default { |
| 97 | 97 | components: {}, |
| 98 | 98 | props: [], |
| ... | ... | @@ -138,7 +138,7 @@ |
| 138 | 138 | }); |
| 139 | 139 | }, |
| 140 | 140 | getjszhOptions(){ |
| 141 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 141 | + getAccountSelector().then(res => { | |
| 142 | 142 | this.jszhOptions = res.data.list |
| 143 | 143 | }); |
| 144 | 144 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtSfk/index.vue
| ... | ... | @@ -127,10 +127,10 @@ |
| 127 | 127 | </template> |
| 128 | 128 | <script> |
| 129 | 129 | import request from '@/utils/request' |
| 130 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 131 | 130 | import NCCForm from './Form' |
| 132 | 131 | import ExportBox from './ExportBox' |
| 133 | 132 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 133 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 134 | 134 | export default { |
| 135 | 135 | components: { NCCForm, ExportBox }, |
| 136 | 136 | data() { |
| ... | ... | @@ -190,7 +190,7 @@ |
| 190 | 190 | }); |
| 191 | 191 | }, |
| 192 | 192 | getjszhOptions(){ |
| 193 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 193 | + getAccountSelector().then(res => { | |
| 194 | 194 | this.jszhOptions = res.data.list |
| 195 | 195 | }); |
| 196 | 196 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtSkzhb/Form.vue
| ... | ... | @@ -32,8 +32,8 @@ |
| 32 | 32 | </template> |
| 33 | 33 | <script> |
| 34 | 34 | import request from '@/utils/request' |
| 35 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 36 | 35 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 36 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 37 | 37 | export default { |
| 38 | 38 | components: {}, |
| 39 | 39 | props: [], |
| ... | ... | @@ -65,7 +65,7 @@ |
| 65 | 65 | methods: { |
| 66 | 66 | // ✅ 获取账户名称选项(从数据字典) |
| 67 | 67 | getzhmcOptions(){ |
| 68 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 68 | + getAccountSelector().then(res => { | |
| 69 | 69 | this.zhmcOptions = res.data.list || []; |
| 70 | 70 | }).catch(() => { |
| 71 | 71 | this.zhmcOptions = []; | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtSkzhb/account-form.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <el-dialog :title="!dataForm.id ? '新建账户' : '编辑账户'" :close-on-click-modal="false" :visible.sync="visible" class="NCC-dialog NCC-dialog_center" lock-scroll width="600px"> | |
| 3 | + <el-form ref="elForm" :model="dataForm" size="small" label-width="100px" label-position="right" :rules="rules"> | |
| 4 | + <el-row :gutter="15"> | |
| 5 | + <el-col :span="24"> | |
| 6 | + <el-form-item label="账户名称" prop="accountName"> | |
| 7 | + <el-input v-model="dataForm.accountName" placeholder="请输入账户名称" clearable /> | |
| 8 | + </el-form-item> | |
| 9 | + </el-col> | |
| 10 | + <el-col :span="24"> | |
| 11 | + <el-form-item label="业务编码" prop="accountCode"> | |
| 12 | + <el-input v-model="dataForm.accountCode" placeholder="留空自动生成" clearable /> | |
| 13 | + </el-form-item> | |
| 14 | + </el-col> | |
| 15 | + <el-col :span="24" v-if="!dataForm.id && !dataForm.accountCode"> | |
| 16 | + <el-form-item label="编码规则" prop="codeRule"> | |
| 17 | + <el-radio-group v-model="dataForm.codeRule"> | |
| 18 | + <el-radio :label="1">数字序号</el-radio> | |
| 19 | + <el-radio :label="2">拼音缩写</el-radio> | |
| 20 | + </el-radio-group> | |
| 21 | + </el-form-item> | |
| 22 | + </el-col> | |
| 23 | + <el-col :span="24"> | |
| 24 | + <el-form-item label="账户分类" prop="category"> | |
| 25 | + <el-select v-model="dataForm.category" placeholder="请选择或输入分类" clearable filterable allow-create default-first-option style="width:100%"> | |
| 26 | + <el-option v-for="item in categoryOptions" :key="item" :label="item" :value="item" /> | |
| 27 | + </el-select> | |
| 28 | + </el-form-item> | |
| 29 | + </el-col> | |
| 30 | + <el-col :span="24"> | |
| 31 | + <el-form-item label="排序码" prop="sortCode"> | |
| 32 | + <el-input-number v-model="dataForm.sortCode" :min="0" :step="1" controls-position="right" style="width:100%" /> | |
| 33 | + </el-form-item> | |
| 34 | + </el-col> | |
| 35 | + <el-col :span="24" v-if="dataForm.id"> | |
| 36 | + <el-form-item label="状态" prop="status"> | |
| 37 | + <el-radio-group v-model="dataForm.status"> | |
| 38 | + <el-radio :label="1">启用</el-radio> | |
| 39 | + <el-radio :label="0">禁用</el-radio> | |
| 40 | + </el-radio-group> | |
| 41 | + </el-form-item> | |
| 42 | + </el-col> | |
| 43 | + </el-row> | |
| 44 | + </el-form> | |
| 45 | + <span slot="footer" class="dialog-footer"> | |
| 46 | + <el-button @click="visible = false">取 消</el-button> | |
| 47 | + <el-button type="primary" :loading="btnLoading" @click="dataFormSubmit()">确 定</el-button> | |
| 48 | + </span> | |
| 49 | + </el-dialog> | |
| 50 | +</template> | |
| 51 | +<script> | |
| 52 | +import { getAccountInfo, createAccount, updateAccount, getAccountCategories } from '@/api/extend/wtAccount' | |
| 53 | +export default { | |
| 54 | + data() { | |
| 55 | + return { | |
| 56 | + visible: false, | |
| 57 | + btnLoading: false, | |
| 58 | + categoryOptions: [], | |
| 59 | + dataForm: { | |
| 60 | + id: '', | |
| 61 | + accountName: '', | |
| 62 | + accountCode: '', | |
| 63 | + codeRule: 1, | |
| 64 | + category: '', | |
| 65 | + sortCode: 0, | |
| 66 | + status: 1 | |
| 67 | + }, | |
| 68 | + rules: { | |
| 69 | + accountName: [{ required: true, message: '请输入账户名称', trigger: 'blur' }] | |
| 70 | + } | |
| 71 | + } | |
| 72 | + }, | |
| 73 | + methods: { | |
| 74 | + init(id) { | |
| 75 | + this.dataForm.id = id || '' | |
| 76 | + this.visible = true | |
| 77 | + this.loadCategories() | |
| 78 | + this.$nextTick(function () { | |
| 79 | + this.$refs['elForm'].resetFields() | |
| 80 | + if (this.dataForm.id) { | |
| 81 | + getAccountInfo(this.dataForm.id).then(function (res) { | |
| 82 | + this.dataForm = res.data | |
| 83 | + }.bind(this)) | |
| 84 | + } else { | |
| 85 | + this.dataForm.codeRule = 1 | |
| 86 | + this.dataForm.sortCode = 0 | |
| 87 | + this.dataForm.status = 1 | |
| 88 | + } | |
| 89 | + }) | |
| 90 | + }, | |
| 91 | + loadCategories() { | |
| 92 | + getAccountCategories().then(function (res) { | |
| 93 | + this.categoryOptions = res.data || [] | |
| 94 | + }.bind(this)).catch(function () { | |
| 95 | + this.categoryOptions = [] | |
| 96 | + }.bind(this)) | |
| 97 | + }, | |
| 98 | + dataFormSubmit() { | |
| 99 | + this.$refs['elForm'].validate(function (valid) { | |
| 100 | + if (!valid) return | |
| 101 | + this.btnLoading = true | |
| 102 | + var body = { | |
| 103 | + accountName: this.dataForm.accountName, | |
| 104 | + accountCode: this.dataForm.accountCode, | |
| 105 | + category: this.dataForm.category, | |
| 106 | + sortCode: this.dataForm.sortCode | |
| 107 | + } | |
| 108 | + var promise | |
| 109 | + if (!this.dataForm.id) { | |
| 110 | + body.codeRule = this.dataForm.codeRule | |
| 111 | + promise = createAccount(body) | |
| 112 | + } else { | |
| 113 | + body.status = this.dataForm.status | |
| 114 | + promise = updateAccount(this.dataForm.id, body) | |
| 115 | + } | |
| 116 | + promise.then(function (res) { | |
| 117 | + this.btnLoading = false | |
| 118 | + this.$message({ | |
| 119 | + message: res.msg, | |
| 120 | + type: 'success', | |
| 121 | + duration: 1000, | |
| 122 | + onClose: function () { | |
| 123 | + this.visible = false | |
| 124 | + this.$emit('refresh', true) | |
| 125 | + }.bind(this) | |
| 126 | + }) | |
| 127 | + }.bind(this)).catch(function () { | |
| 128 | + this.btnLoading = false | |
| 129 | + }.bind(this)) | |
| 130 | + }.bind(this)) | |
| 131 | + } | |
| 132 | + } | |
| 133 | +} | |
| 134 | +</script> | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtSkzhb/index.vue
| 1 | 1 | <template> |
| 2 | 2 | <div class="NCC-common-layout"> |
| 3 | 3 | <div class="NCC-common-layout-center"> |
| 4 | - <el-row class="NCC-common-search-box" :gutter="16"> | |
| 5 | - <el-form @submit.native.prevent> | |
| 6 | - <el-col :span="6"> | |
| 7 | - <el-form-item label="账户编号"> | |
| 8 | - <el-input v-model="query.id" placeholder="账户编号" clearable /> | |
| 9 | - </el-form-item> | |
| 10 | - </el-col> | |
| 11 | - <el-col :span="6"> | |
| 12 | - <el-form-item label="账户名称"> | |
| 13 | - <el-select v-model="query.zhmc" placeholder="请选择账户名称" clearable :style='{"width":"100%"}' > | |
| 14 | - <el-option v-for="(item, index) in zhmcOptions" :key="index" :label="item.fullName" :value="item.id" ></el-option> | |
| 15 | - </el-select> | |
| 16 | - </el-form-item> | |
| 17 | - </el-col> | |
| 18 | - <el-col :span="6"> | |
| 19 | - <el-form-item label="所属门店"> | |
| 20 | - <el-select v-model="query.ssmd" placeholder="请选择门店" clearable :style='{"width":"100%"}' > | |
| 21 | - <el-option v-for="(item, index) in ssmdOptions" :key="index" :label="item.F_Mdmc" :value="item.F_Id" ></el-option> | |
| 22 | - </el-select> | |
| 23 | - </el-form-item> | |
| 24 | - </el-col> | |
| 25 | - <el-col :span="6"> | |
| 26 | - <el-form-item> | |
| 27 | - <el-button type="primary" icon="el-icon-search" @click="search()">查询</el-button> | |
| 28 | - <el-button icon="el-icon-refresh-right" @click="reset()">重置</el-button> | |
| 29 | - </el-form-item> | |
| 30 | - </el-col> | |
| 31 | - </el-form> | |
| 32 | - </el-row> | |
| 33 | - <div class="NCC-common-layout-main NCC-flex-main"> | |
| 34 | - <div class="NCC-common-head"> | |
| 35 | - <div> | |
| 36 | - <el-button type="primary" icon="el-icon-plus" @click="addOrUpdateHandle()">新增</el-button> | |
| 37 | - <el-button type="text" icon="el-icon-download" @click="exportData()">导出</el-button> | |
| 38 | - <el-button type="text" icon="el-icon-delete" @click="handleBatchRemoveDel()">批量删除</el-button> | |
| 4 | + <el-tabs v-model="activeTab" @tab-click="handleTabClick"> | |
| 5 | + <el-tab-pane label="账户管理" name="account"> | |
| 6 | + <!-- Tab1 搜索区 --> | |
| 7 | + <el-row class="NCC-common-search-box" :gutter="16"> | |
| 8 | + <el-form @submit.native.prevent> | |
| 9 | + <el-col :span="6"> | |
| 10 | + <el-form-item label="关键字"> | |
| 11 | + <el-input v-model="accountQuery.keyword" placeholder="编码/名称模糊搜索" clearable /> | |
| 12 | + </el-form-item> | |
| 13 | + </el-col> | |
| 14 | + <el-col :span="6"> | |
| 15 | + <el-form-item label="账户分类"> | |
| 16 | + <el-select v-model="accountQuery.category" placeholder="请选择分类" clearable style="width:100%"> | |
| 17 | + <el-option v-for="item in categoryOptions" :key="item" :label="item" :value="item" /> | |
| 18 | + </el-select> | |
| 19 | + </el-form-item> | |
| 20 | + </el-col> | |
| 21 | + <el-col :span="6"> | |
| 22 | + <el-form-item label="状态"> | |
| 23 | + <el-select v-model="accountQuery.status" placeholder="全部" clearable style="width:100%"> | |
| 24 | + <el-option label="启用" :value="1" /> | |
| 25 | + <el-option label="禁用" :value="0" /> | |
| 26 | + </el-select> | |
| 27 | + </el-form-item> | |
| 28 | + </el-col> | |
| 29 | + <el-col :span="6"> | |
| 30 | + <el-form-item> | |
| 31 | + <el-button type="primary" icon="el-icon-search" @click="accountSearch()">查询</el-button> | |
| 32 | + <el-button icon="el-icon-refresh-right" @click="accountReset()">重置</el-button> | |
| 33 | + </el-form-item> | |
| 34 | + </el-col> | |
| 35 | + </el-form> | |
| 36 | + </el-row> | |
| 37 | + <!-- Tab1 操作区 + 列表 --> | |
| 38 | + <div class="NCC-common-layout-main NCC-flex-main"> | |
| 39 | + <div class="NCC-common-head"> | |
| 40 | + <div> | |
| 41 | + <el-button type="primary" icon="el-icon-plus" @click="openAccountForm()">新增</el-button> | |
| 42 | + </div> | |
| 43 | + <div class="NCC-common-head-right"> | |
| 44 | + <el-tooltip effect="dark" content="刷新" placement="top"> | |
| 45 | + <el-link icon="icon-ym icon-ym-Refresh NCC-common-head-icon" :underline="false" @click="accountReset()" /> | |
| 46 | + </el-tooltip> | |
| 47 | + <screenfull isContainer /> | |
| 48 | + </div> | |
| 49 | + </div> | |
| 50 | + <NCC-table v-loading="accountLoading" :data="accountList"> | |
| 51 | + <el-table-column prop="accountCode" label="业务编码" align="left" sortable /> | |
| 52 | + <el-table-column prop="accountName" label="账户名称" align="left" sortable /> | |
| 53 | + <el-table-column prop="category" label="账户分类" align="left"> | |
| 54 | + <template slot-scope="scope"> | |
| 55 | + {{ scope.row.category || '无' }} | |
| 56 | + </template> | |
| 57 | + </el-table-column> | |
| 58 | + <el-table-column prop="status" label="状态" align="left" width="100"> | |
| 59 | + <template slot-scope="scope"> | |
| 60 | + <el-tag v-if="scope.row.status === 1" type="success" size="mini">启用</el-tag> | |
| 61 | + <el-tag v-else type="info" size="mini">禁用</el-tag> | |
| 62 | + </template> | |
| 63 | + </el-table-column> | |
| 64 | + <el-table-column prop="sortCode" label="排序码" align="left" width="100" sortable /> | |
| 65 | + <el-table-column label="操作" fixed="right" width="120"> | |
| 66 | + <template slot-scope="scope"> | |
| 67 | + <el-button type="text" @click="openAccountForm(scope.row.id)">编辑</el-button> | |
| 68 | + <el-button type="text" class="NCC-table-delBtn" @click="accountDel(scope.row.id)">删除</el-button> | |
| 69 | + </template> | |
| 70 | + </el-table-column> | |
| 71 | + </NCC-table> | |
| 72 | + <pagination :total="accountTotal" :page.sync="accountListQuery.currentPage" :limit.sync="accountListQuery.pageSize" @pagination="loadAccountList" /> | |
| 39 | 73 | </div> |
| 40 | - <div class="NCC-common-head-right"> | |
| 41 | - <el-tooltip effect="dark" content="刷新" placement="top"> | |
| 42 | - <el-link icon="icon-ym icon-ym-Refresh NCC-common-head-icon" :underline="false" @click="reset()" /> | |
| 43 | - </el-tooltip> | |
| 44 | - <screenfull isContainer /> | |
| 74 | + </el-tab-pane> | |
| 75 | + | |
| 76 | + <el-tab-pane label="门店账户授权" name="store"> | |
| 77 | + <!-- Tab2 搜索区(原有) --> | |
| 78 | + <el-row class="NCC-common-search-box" :gutter="16"> | |
| 79 | + <el-form @submit.native.prevent> | |
| 80 | + <el-col :span="6"> | |
| 81 | + <el-form-item label="账户编号"> | |
| 82 | + <el-input v-model="query.id" placeholder="账户编号" clearable /> | |
| 83 | + </el-form-item> | |
| 84 | + </el-col> | |
| 85 | + <el-col :span="6"> | |
| 86 | + <el-form-item label="账户名称"> | |
| 87 | + <el-select v-model="query.zhmc" placeholder="请选择账户名称" clearable style="width:100%"> | |
| 88 | + <el-option v-for="(item, index) in zhmcOptions" :key="index" :label="item.fullName" :value="item.id" /> | |
| 89 | + </el-select> | |
| 90 | + </el-form-item> | |
| 91 | + </el-col> | |
| 92 | + <el-col :span="6"> | |
| 93 | + <el-form-item label="所属门店"> | |
| 94 | + <el-select v-model="query.ssmd" placeholder="请选择门店" clearable style="width:100%"> | |
| 95 | + <el-option v-for="(item, index) in ssmdOptions" :key="index" :label="item.F_Mdmc" :value="item.F_Id" /> | |
| 96 | + </el-select> | |
| 97 | + </el-form-item> | |
| 98 | + </el-col> | |
| 99 | + <el-col :span="6"> | |
| 100 | + <el-form-item> | |
| 101 | + <el-button type="primary" icon="el-icon-search" @click="search()">查询</el-button> | |
| 102 | + <el-button icon="el-icon-refresh-right" @click="reset()">重置</el-button> | |
| 103 | + </el-form-item> | |
| 104 | + </el-col> | |
| 105 | + </el-form> | |
| 106 | + </el-row> | |
| 107 | + <!-- Tab2 操作区 + 列表(原有) --> | |
| 108 | + <div class="NCC-common-layout-main NCC-flex-main"> | |
| 109 | + <div class="NCC-common-head"> | |
| 110 | + <div> | |
| 111 | + <el-button type="primary" icon="el-icon-plus" @click="addOrUpdateHandle()">新增</el-button> | |
| 112 | + <el-button type="text" icon="el-icon-download" @click="exportData()">导出</el-button> | |
| 113 | + <el-button type="text" icon="el-icon-delete" @click="handleBatchRemoveDel()">批量删除</el-button> | |
| 114 | + </div> | |
| 115 | + <div class="NCC-common-head-right"> | |
| 116 | + <el-tooltip effect="dark" content="刷新" placement="top"> | |
| 117 | + <el-link icon="icon-ym icon-ym-Refresh NCC-common-head-icon" :underline="false" @click="reset()" /> | |
| 118 | + </el-tooltip> | |
| 119 | + <screenfull isContainer /> | |
| 120 | + </div> | |
| 121 | + </div> | |
| 122 | + <NCC-table v-loading="listLoading" :data="list" has-c @selection-change="handleSelectionChange"> | |
| 123 | + <el-table-column prop="id" label="账户编号" align="left" /> | |
| 124 | + <el-table-column prop="zhmc" label="账户名称" align="left" /> | |
| 125 | + <el-table-column prop="ssmd" label="所属门店" align="left" /> | |
| 126 | + <el-table-column label="操作" fixed="right" width="100"> | |
| 127 | + <template slot-scope="scope"> | |
| 128 | + <el-button type="text" @click="addOrUpdateHandle(scope.row.id)">编辑</el-button> | |
| 129 | + <el-button type="text" class="NCC-table-delBtn" @click="handleDel(scope.row.id)">删除</el-button> | |
| 130 | + </template> | |
| 131 | + </el-table-column> | |
| 132 | + </NCC-table> | |
| 133 | + <pagination :total="total" :page.sync="listQuery.currentPage" :limit.sync="listQuery.pageSize" @pagination="initData" /> | |
| 45 | 134 | </div> |
| 46 | - </div> | |
| 47 | - <NCC-table v-loading="listLoading" :data="list" has-c @selection-change="handleSelectionChange"> | |
| 48 | - <el-table-column prop="id" label="账户编号" align="left" /> | |
| 49 | - <el-table-column prop="zhmc" label="账户名称" align="left" /> | |
| 50 | - <el-table-column prop="ssmd" label="所属门店" align="left" /> | |
| 51 | - <el-table-column label="操作" fixed="right" width="100"> | |
| 52 | - <template slot-scope="scope"> | |
| 53 | - <el-button type="text" @click="addOrUpdateHandle(scope.row.id)" >编辑</el-button> | |
| 54 | - <el-button type="text" @click="handleDel(scope.row.id)" class="NCC-table-delBtn" >删除</el-button> | |
| 55 | - </template> | |
| 56 | - </el-table-column> | |
| 57 | - </NCC-table> | |
| 58 | - <pagination :total="total" :page.sync="listQuery.currentPage" :limit.sync="listQuery.pageSize" @pagination="initData" /> | |
| 59 | - </div> | |
| 60 | - </div> | |
| 135 | + </el-tab-pane> | |
| 136 | + </el-tabs> | |
| 137 | + </div> | |
| 138 | + <!-- Tab1 弹窗 --> | |
| 139 | + <AccountForm v-if="accountFormVisible" ref="AccountForm" @refresh="accountRefresh" /> | |
| 140 | + <!-- Tab2 弹窗 --> | |
| 61 | 141 | <NCC-Form v-if="formVisible" ref="NCCForm" @refresh="refresh" /> |
| 142 | + <!-- Tab2 导出 --> | |
| 62 | 143 | <ExportBox v-if="exportBoxVisible" ref="ExportBox" @download="download" /> |
| 63 | 144 | </div> |
| 64 | 145 | </template> |
| 65 | 146 | <script> |
| 66 | - import request from '@/utils/request' | |
| 67 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 68 | - import NCCForm from './Form' | |
| 69 | - import ExportBox from './ExportBox' | |
| 70 | - import { previewDataInterface } from '@/api/systemData/dataInterface' | |
| 71 | - export default { | |
| 72 | - components: { NCCForm, ExportBox }, | |
| 73 | - data() { | |
| 74 | - return { | |
| 75 | - showAll: false, | |
| 76 | - query: { | |
| 77 | - id:undefined, | |
| 78 | - zhmc:undefined, | |
| 79 | - ssmd:undefined, | |
| 80 | - }, | |
| 81 | - list: [], | |
| 82 | - listLoading: true, | |
| 83 | - multipleSelection: [], total: 0, | |
| 84 | - listQuery: { | |
| 85 | - currentPage: 1, | |
| 86 | - pageSize: 20, | |
| 87 | - sort: "desc", | |
| 88 | - sidx: "", | |
| 89 | - }, | |
| 90 | - formVisible: false, | |
| 91 | - exportBoxVisible: false, | |
| 92 | - columnList: [ | |
| 93 | - { prop: 'id', label: '账户编号' }, | |
| 94 | - { prop: 'zhmc', label: '账户名称' }, | |
| 95 | - { prop: 'ssmd', label: '所属门店' }, | |
| 96 | - ], | |
| 97 | - zhmcOptions: [], // ✅ 账户名称选项(从数据字典获取) | |
| 98 | - ssmdOptions: [], // ✅ 门店选项(从门店记录获取) | |
| 99 | - } | |
| 100 | - }, | |
| 101 | - computed: {}, | |
| 102 | - created() { | |
| 103 | - this.initData(); | |
| 104 | - this.getzhmcOptions(); | |
| 105 | - this.getssmdOptions(); | |
| 106 | - }, | |
| 107 | - methods: { | |
| 108 | - // ✅ 获取账户名称选项(从数据字典) | |
| 109 | - getzhmcOptions(){ | |
| 110 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 111 | - this.zhmcOptions = res.data.list || []; | |
| 112 | - }).catch(() => { | |
| 113 | - this.zhmcOptions = []; | |
| 114 | - }); | |
| 147 | +import request from '@/utils/request' | |
| 148 | +import NCCForm from './Form' | |
| 149 | +import AccountForm from './account-form' | |
| 150 | +import ExportBox from './ExportBox' | |
| 151 | +import { previewDataInterface } from '@/api/systemData/dataInterface' | |
| 152 | +import { | |
| 153 | + getAccountSelector, | |
| 154 | + getAccountList, | |
| 155 | + deleteAccount, | |
| 156 | + getAccountCategories | |
| 157 | +} from '@/api/extend/wtAccount' | |
| 158 | +export default { | |
| 159 | + components: { NCCForm, AccountForm, ExportBox }, | |
| 160 | + data() { | |
| 161 | + return { | |
| 162 | + activeTab: 'account', | |
| 163 | + // ---- Tab1:账户管理 ---- | |
| 164 | + accountQuery: { | |
| 165 | + keyword: undefined, | |
| 166 | + category: undefined, | |
| 167 | + status: undefined | |
| 168 | + }, | |
| 169 | + accountList: [], | |
| 170 | + accountLoading: false, | |
| 171 | + accountTotal: 0, | |
| 172 | + accountListQuery: { | |
| 173 | + currentPage: 1, | |
| 174 | + pageSize: 20, | |
| 175 | + sort: 'desc', | |
| 176 | + sidx: '' | |
| 115 | 177 | }, |
| 116 | - // ✅ 获取门店选项(从门店记录) | |
| 117 | - getssmdOptions(){ | |
| 118 | - previewDataInterface('672484412352365829').then(res => { | |
| 119 | - this.ssmdOptions = res.data || []; | |
| 120 | - }).catch(() => { | |
| 121 | - this.ssmdOptions = []; | |
| 122 | - }); | |
| 178 | + accountFormVisible: false, | |
| 179 | + categoryOptions: [], | |
| 180 | + // ---- Tab2:门店账户授权(原有) ---- | |
| 181 | + showAll: false, | |
| 182 | + query: { | |
| 183 | + id: undefined, | |
| 184 | + zhmc: undefined, | |
| 185 | + ssmd: undefined | |
| 123 | 186 | }, |
| 124 | - initData() { | |
| 125 | - this.listLoading = true; | |
| 126 | - let _query = { | |
| 127 | - ...this.listQuery, | |
| 128 | - ...this.query | |
| 129 | - }; | |
| 130 | - let query = {} | |
| 131 | - for (let key in _query) { | |
| 132 | - if (Array.isArray(_query[key])) { | |
| 133 | - query[key] = _query[key].join() | |
| 134 | - } else { | |
| 135 | - query[key] = _query[key] | |
| 136 | - } | |
| 137 | - } | |
| 138 | - request({ | |
| 139 | - url: `/api/Extend/WtSkzhb`, | |
| 140 | - method: 'GET', | |
| 141 | - data: query | |
| 142 | - }).then(res => { | |
| 143 | - this.list = res.data.list | |
| 144 | - this.total = res.data.pagination.total | |
| 145 | - this.listLoading = false | |
| 146 | - }) | |
| 147 | - }, | |
| 148 | - handleDel(id) { | |
| 149 | - this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', { | |
| 150 | - type: 'warning' | |
| 151 | - }).then(() => { | |
| 152 | - request({ | |
| 153 | - url: `/api/Extend/WtSkzhb/${id}`, | |
| 154 | - method: 'DELETE' | |
| 155 | - }).then(res => { | |
| 156 | - this.$message({ | |
| 157 | - type: 'success', | |
| 158 | - message: res.msg, | |
| 159 | - onClose: () => { | |
| 160 | - this.initData() | |
| 161 | - } | |
| 162 | - }); | |
| 163 | - }) | |
| 164 | - }).catch(() => { | |
| 165 | - }); | |
| 166 | - }, | |
| 167 | - handleSelectionChange(val) { | |
| 168 | - const res = val.map(item => item.id) | |
| 169 | - this.multipleSelection = res | |
| 170 | - }, | |
| 171 | - handleBatchRemoveDel() { | |
| 172 | - if (!this.multipleSelection.length) { | |
| 173 | - this.$message({ | |
| 174 | - type: 'error', | |
| 175 | - message: '请选择一条数据', | |
| 176 | - duration: 1500, | |
| 177 | - }) | |
| 178 | - return | |
| 179 | - } | |
| 180 | - const ids = this.multipleSelection | |
| 181 | - this.$confirm('您确定要删除这些数据吗, 是否继续?', '提示', { | |
| 182 | - type: 'warning' | |
| 183 | - }).then(() => { | |
| 184 | - request({ | |
| 185 | - url: `/api/Extend/WtSkzhb/batchRemove`, | |
| 186 | - method: 'POST', | |
| 187 | - data: ids , | |
| 188 | - }).then(res => { | |
| 189 | - this.$message({ | |
| 190 | - type: 'success', | |
| 191 | - message: res.msg, | |
| 192 | - onClose: () => { | |
| 193 | - this.initData() | |
| 194 | - } | |
| 195 | - }); | |
| 196 | - }) | |
| 197 | - }).catch(() => { }) | |
| 198 | - }, | |
| 199 | - addOrUpdateHandle(id, isDetail) { | |
| 200 | - this.formVisible = true | |
| 201 | - this.$nextTick(() => { | |
| 202 | - this.$refs.NCCForm.init(id, isDetail) | |
| 203 | - }) | |
| 204 | - }, | |
| 205 | - exportData() { | |
| 206 | - this.exportBoxVisible = true | |
| 207 | - this.$nextTick(() => { | |
| 208 | - this.$refs.ExportBox.init(this.columnList) | |
| 209 | - }) | |
| 210 | - }, | |
| 211 | - download(data) { | |
| 212 | - let query = { ...data, ...this.listQuery, ...this.query } | |
| 213 | - request({ | |
| 214 | - url: `/api/Extend/WtSkzhb/Actions/Export`, | |
| 215 | - method: 'GET', | |
| 216 | - data: query | |
| 217 | - }).then(res => { | |
| 218 | - if (!res.data.url) return | |
| 219 | - window.location.href = this.define.comUrl + res.data.url | |
| 220 | - this.$refs.ExportBox.visible = false | |
| 221 | - this.exportBoxVisible = false | |
| 222 | - }) | |
| 223 | - }, | |
| 224 | - search() { | |
| 225 | - this.listQuery = { | |
| 226 | - currentPage: 1, | |
| 227 | - pageSize: 20, | |
| 228 | - sort: "desc", | |
| 229 | - sidx: "", | |
| 230 | - } | |
| 231 | - this.initData() | |
| 232 | - }, | |
| 233 | - refresh(isrRefresh) { | |
| 234 | - this.formVisible = false | |
| 235 | - if (isrRefresh) this.reset() | |
| 236 | - }, | |
| 237 | - reset() { | |
| 238 | - for (let key in this.query) { | |
| 239 | - this.query[key] = undefined | |
| 240 | - } | |
| 241 | - this.listQuery = { | |
| 242 | - currentPage: 1, | |
| 243 | - pageSize: 20, | |
| 244 | - sort: "desc", | |
| 245 | - sidx: "", | |
| 246 | - } | |
| 247 | - this.initData() | |
| 248 | - } | |
| 187 | + list: [], | |
| 188 | + listLoading: true, | |
| 189 | + multipleSelection: [], | |
| 190 | + total: 0, | |
| 191 | + listQuery: { | |
| 192 | + currentPage: 1, | |
| 193 | + pageSize: 20, | |
| 194 | + sort: 'desc', | |
| 195 | + sidx: '' | |
| 196 | + }, | |
| 197 | + formVisible: false, | |
| 198 | + exportBoxVisible: false, | |
| 199 | + columnList: [ | |
| 200 | + { prop: 'id', label: '账户编号' }, | |
| 201 | + { prop: 'zhmc', label: '账户名称' }, | |
| 202 | + { prop: 'ssmd', label: '所属门店' } | |
| 203 | + ], | |
| 204 | + zhmcOptions: [], | |
| 205 | + ssmdOptions: [] | |
| 206 | + } | |
| 207 | + }, | |
| 208 | + created() { | |
| 209 | + this.loadAccountList() | |
| 210 | + this.loadCategories() | |
| 211 | + }, | |
| 212 | + methods: { | |
| 213 | + handleTabClick(tab) { | |
| 214 | + if (tab.name === 'store' && this.list.length === 0) { | |
| 215 | + this.initData() | |
| 216 | + this.getzhmcOptions() | |
| 217 | + this.getssmdOptions() | |
| 218 | + } | |
| 219 | + }, | |
| 220 | + // ========== Tab1:账户管理 ========== | |
| 221 | + loadAccountList() { | |
| 222 | + this.accountLoading = true | |
| 223 | + var params = {} | |
| 224 | + Object.assign(params, this.accountListQuery) | |
| 225 | + if (this.accountQuery.keyword) params.keyword = this.accountQuery.keyword | |
| 226 | + if (this.accountQuery.category) params.category = this.accountQuery.category | |
| 227 | + if (this.accountQuery.status !== undefined && this.accountQuery.status !== null) { | |
| 228 | + params.status = this.accountQuery.status | |
| 229 | + } | |
| 230 | + getAccountList(params).then(function (res) { | |
| 231 | + this.accountList = res.data.list || [] | |
| 232 | + this.accountTotal = (res.data.pagination && res.data.pagination.total) || 0 | |
| 233 | + this.accountLoading = false | |
| 234 | + }.bind(this)).catch(function () { | |
| 235 | + this.accountLoading = false | |
| 236 | + }.bind(this)) | |
| 237 | + }, | |
| 238 | + loadCategories() { | |
| 239 | + getAccountCategories().then(function (res) { | |
| 240 | + this.categoryOptions = res.data || [] | |
| 241 | + }.bind(this)).catch(function () { | |
| 242 | + this.categoryOptions = [] | |
| 243 | + }.bind(this)) | |
| 244 | + }, | |
| 245 | + accountSearch() { | |
| 246 | + this.accountListQuery.currentPage = 1 | |
| 247 | + this.loadAccountList() | |
| 248 | + }, | |
| 249 | + accountReset() { | |
| 250 | + this.accountQuery = { keyword: undefined, category: undefined, status: undefined } | |
| 251 | + this.accountListQuery = { currentPage: 1, pageSize: 20, sort: 'desc', sidx: '' } | |
| 252 | + this.loadAccountList() | |
| 253 | + }, | |
| 254 | + openAccountForm(id) { | |
| 255 | + this.accountFormVisible = true | |
| 256 | + this.$nextTick(function () { | |
| 257 | + this.$refs.AccountForm.init(id) | |
| 258 | + }) | |
| 259 | + }, | |
| 260 | + accountRefresh(isRefresh) { | |
| 261 | + this.accountFormVisible = false | |
| 262 | + if (isRefresh) { | |
| 263 | + this.accountReset() | |
| 264 | + this.loadCategories() | |
| 265 | + this.getzhmcOptions() | |
| 266 | + } | |
| 267 | + }, | |
| 268 | + accountDel(id) { | |
| 269 | + this.$confirm('此操作将永久删除该账户, 是否继续?', '提示', { type: 'warning' }).then(function () { | |
| 270 | + deleteAccount(id).then(function (res) { | |
| 271 | + this.$message({ type: 'success', message: res.msg, onClose: function () { this.loadAccountList() }.bind(this) }) | |
| 272 | + }.bind(this)) | |
| 273 | + }.bind(this)).catch(function () {}) | |
| 274 | + }, | |
| 275 | + // ========== Tab2:门店账户授权(原有) ========== | |
| 276 | + getzhmcOptions() { | |
| 277 | + getAccountSelector().then(function (res) { | |
| 278 | + this.zhmcOptions = res.data.list || [] | |
| 279 | + }.bind(this)).catch(function () { | |
| 280 | + this.zhmcOptions = [] | |
| 281 | + }.bind(this)) | |
| 282 | + }, | |
| 283 | + getssmdOptions() { | |
| 284 | + previewDataInterface('672484412352365829').then(function (res) { | |
| 285 | + this.ssmdOptions = res.data || [] | |
| 286 | + }.bind(this)).catch(function () { | |
| 287 | + this.ssmdOptions = [] | |
| 288 | + }.bind(this)) | |
| 289 | + }, | |
| 290 | + initData() { | |
| 291 | + this.listLoading = true | |
| 292 | + var _query = {} | |
| 293 | + Object.assign(_query, this.listQuery, this.query) | |
| 294 | + var queryParams = {} | |
| 295 | + for (var key in _query) { | |
| 296 | + if (Array.isArray(_query[key])) { | |
| 297 | + queryParams[key] = _query[key].join() | |
| 298 | + } else { | |
| 299 | + queryParams[key] = _query[key] | |
| 300 | + } | |
| 301 | + } | |
| 302 | + request({ | |
| 303 | + url: '/api/Extend/WtSkzhb', | |
| 304 | + method: 'GET', | |
| 305 | + data: queryParams | |
| 306 | + }).then(function (res) { | |
| 307 | + this.list = res.data.list | |
| 308 | + this.total = res.data.pagination.total | |
| 309 | + this.listLoading = false | |
| 310 | + }.bind(this)) | |
| 311 | + }, | |
| 312 | + handleDel(id) { | |
| 313 | + this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', { type: 'warning' }).then(function () { | |
| 314 | + request({ | |
| 315 | + url: '/api/Extend/WtSkzhb/' + id, | |
| 316 | + method: 'DELETE' | |
| 317 | + }).then(function (res) { | |
| 318 | + this.$message({ type: 'success', message: res.msg, onClose: function () { this.initData() }.bind(this) }) | |
| 319 | + }.bind(this)) | |
| 320 | + }.bind(this)).catch(function () {}) | |
| 321 | + }, | |
| 322 | + handleSelectionChange(val) { | |
| 323 | + this.multipleSelection = val.map(function (item) { return item.id }) | |
| 324 | + }, | |
| 325 | + handleBatchRemoveDel() { | |
| 326 | + if (!this.multipleSelection.length) { | |
| 327 | + this.$message({ type: 'error', message: '请选择一条数据', duration: 1500 }) | |
| 328 | + return | |
| 329 | + } | |
| 330 | + this.$confirm('您确定要删除这些数据吗, 是否继续?', '提示', { type: 'warning' }).then(function () { | |
| 331 | + request({ | |
| 332 | + url: '/api/Extend/WtSkzhb/batchRemove', | |
| 333 | + method: 'POST', | |
| 334 | + data: this.multipleSelection | |
| 335 | + }).then(function (res) { | |
| 336 | + this.$message({ type: 'success', message: res.msg, onClose: function () { this.initData() }.bind(this) }) | |
| 337 | + }.bind(this)) | |
| 338 | + }.bind(this)).catch(function () {}) | |
| 339 | + }, | |
| 340 | + addOrUpdateHandle(id, isDetail) { | |
| 341 | + this.formVisible = true | |
| 342 | + this.$nextTick(function () { | |
| 343 | + this.$refs.NCCForm.init(id, isDetail) | |
| 344 | + }) | |
| 345 | + }, | |
| 346 | + exportData() { | |
| 347 | + this.exportBoxVisible = true | |
| 348 | + this.$nextTick(function () { | |
| 349 | + this.$refs.ExportBox.init(this.columnList) | |
| 350 | + }) | |
| 351 | + }, | |
| 352 | + download(data) { | |
| 353 | + var downloadQuery = {} | |
| 354 | + Object.assign(downloadQuery, data, this.listQuery, this.query) | |
| 355 | + request({ | |
| 356 | + url: '/api/Extend/WtSkzhb/Actions/Export', | |
| 357 | + method: 'GET', | |
| 358 | + data: downloadQuery | |
| 359 | + }).then(function (res) { | |
| 360 | + if (!res.data.url) return | |
| 361 | + window.location.href = this.define.comUrl + res.data.url | |
| 362 | + this.$refs.ExportBox.visible = false | |
| 363 | + this.exportBoxVisible = false | |
| 364 | + }.bind(this)) | |
| 365 | + }, | |
| 366 | + search() { | |
| 367 | + this.listQuery = { currentPage: 1, pageSize: 20, sort: 'desc', sidx: '' } | |
| 368 | + this.initData() | |
| 369 | + }, | |
| 370 | + refresh(isRefresh) { | |
| 371 | + this.formVisible = false | |
| 372 | + if (isRefresh) this.reset() | |
| 373 | + }, | |
| 374 | + reset() { | |
| 375 | + for (var key in this.query) { | |
| 376 | + this.query[key] = undefined | |
| 377 | + } | |
| 378 | + this.listQuery = { currentPage: 1, pageSize: 20, sort: 'desc', sidx: '' } | |
| 379 | + this.initData() | |
| 249 | 380 | } |
| 250 | - } | |
| 251 | -</script> | |
| 252 | 381 | \ No newline at end of file |
| 382 | + } | |
| 383 | +} | |
| 384 | +</script> | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtSwdd/Form.vue
| ... | ... | @@ -159,8 +159,8 @@ |
| 159 | 159 | </template> |
| 160 | 160 | <script> |
| 161 | 161 | import request from '@/utils/request' |
| 162 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 163 | 162 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 163 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 164 | 164 | export default { |
| 165 | 165 | components: {}, |
| 166 | 166 | props: [], |
| ... | ... | @@ -235,7 +235,7 @@ |
| 235 | 235 | }); |
| 236 | 236 | }, |
| 237 | 237 | getskzhOptions(){ |
| 238 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 238 | + getAccountSelector().then(res => { | |
| 239 | 239 | this.skzhOptions = res.data.list |
| 240 | 240 | }); |
| 241 | 241 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtSwdd/index.vue
| ... | ... | @@ -132,10 +132,10 @@ |
| 132 | 132 | </template> |
| 133 | 133 | <script> |
| 134 | 134 | import request from '@/utils/request' |
| 135 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 136 | 135 | import NCCForm from './Form' |
| 137 | 136 | import ExportBox from './ExportBox' |
| 138 | 137 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 138 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 139 | 139 | export default { |
| 140 | 140 | components: { NCCForm, ExportBox }, |
| 141 | 141 | data() { |
| ... | ... | @@ -205,7 +205,7 @@ |
| 205 | 205 | }); |
| 206 | 206 | }, |
| 207 | 207 | getskzhOptions(){ |
| 208 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 208 | + getAccountSelector().then(res => { | |
| 209 | 209 | this.skzhOptions = res.data.list |
| 210 | 210 | }); |
| 211 | 211 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtTjdbd/Form.vue
| ... | ... | @@ -251,10 +251,10 @@ |
| 251 | 251 | </template> |
| 252 | 252 | <script> |
| 253 | 253 | import request from '@/utils/request' |
| 254 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 255 | 254 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 256 | 255 | import BarcodeSelect from '../wtCgrkd/BarcodeSelect.vue' |
| 257 | 256 | import SerialNumberSelect from './SerialNumberSelect.vue' |
| 257 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 258 | 258 | export default { |
| 259 | 259 | components: { BarcodeSelect, SerialNumberSelect }, |
| 260 | 260 | props: [], |
| ... | ... | @@ -605,7 +605,7 @@ |
| 605 | 605 | }); |
| 606 | 606 | }, |
| 607 | 607 | getskzhOptions(){ |
| 608 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 608 | + getAccountSelector().then(res => { | |
| 609 | 609 | this.skzhOptions = res.data.list |
| 610 | 610 | }); |
| 611 | 611 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtTjdbd/index.vue
| ... | ... | @@ -177,12 +177,12 @@ |
| 177 | 177 | </template> |
| 178 | 178 | <script> |
| 179 | 179 | import request from '@/utils/request' |
| 180 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 181 | 180 | import NCCForm from './Form' |
| 182 | 181 | import DetailView from './detail-view' |
| 183 | 182 | import ExportBox from './ExportBox' |
| 184 | 183 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 185 | 184 | import { promptApprovalRemark, postApproveGeneric, postRejectGeneric } from '@/utils/wtRejectApproval' |
| 185 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 186 | 186 | export default { |
| 187 | 187 | components: { NCCForm, DetailView, ExportBox }, |
| 188 | 188 | data() { |
| ... | ... | @@ -333,7 +333,7 @@ |
| 333 | 333 | }); |
| 334 | 334 | }, |
| 335 | 335 | getskzhOptions(){ |
| 336 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 336 | + getAccountSelector().then(res => { | |
| 337 | 337 | this.skzhOptions = res.data.list |
| 338 | 338 | }); |
| 339 | 339 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtXlh/index.vue
| ... | ... | @@ -33,6 +33,7 @@ |
| 33 | 33 | <el-col :span="6"> |
| 34 | 34 | <el-form-item> |
| 35 | 35 | <el-button type="primary" icon="el-icon-search" @click="search()">查询</el-button> |
| 36 | + <el-button type="success" plain icon="el-icon-sort" @click="openSerialTrace">序列号流水</el-button> | |
| 36 | 37 | <el-button icon="el-icon-refresh-right" @click="reset()">重置</el-button> |
| 37 | 38 | <el-button type="text" icon="el-icon-arrow-down" @click="showAll=true" v-if="!showAll">展开</el-button> |
| 38 | 39 | <el-button type="text" icon="el-icon-arrow-up" @click="showAll=false" v-else>收起</el-button> |
| ... | ... | @@ -43,9 +44,7 @@ |
| 43 | 44 | <div class="NCC-common-layout-main NCC-flex-main"> |
| 44 | 45 | <div class="NCC-common-head"> |
| 45 | 46 | <div> |
| 46 | - <el-button type="primary" icon="el-icon-plus" @click="addOrUpdateHandle()">新增</el-button> | |
| 47 | 47 | <el-button type="text" icon="el-icon-download" @click="exportData()">导出</el-button> |
| 48 | - <el-button type="text" icon="el-icon-delete" @click="handleBatchRemoveDel()">批量删除</el-button> | |
| 49 | 48 | </div> |
| 50 | 49 | <div class="NCC-common-head-right"> |
| 51 | 50 | <el-tooltip effect="dark" content="刷新" placement="top"> |
| ... | ... | @@ -54,7 +53,7 @@ |
| 54 | 53 | <screenfull isContainer /> |
| 55 | 54 | </div> |
| 56 | 55 | </div> |
| 57 | - <NCC-table v-loading="listLoading" :data="list" has-c @selection-change="handleSelectionChange"> | |
| 56 | + <NCC-table v-loading="listLoading" :data="list"> | |
| 58 | 57 | <el-table-column prop="xlh" label="序列号" align="left" /> |
| 59 | 58 | <el-table-column prop="spbh" label="商品编号" align="left" /> |
| 60 | 59 | <el-table-column prop="spmc" label="商品名称" align="left" /> |
| ... | ... | @@ -65,29 +64,20 @@ |
| 65 | 64 | <el-table-column prop="djlx" label="单据类型" align="left" /> |
| 66 | 65 | <el-table-column prop="zt" label="状态" align="left" /> |
| 67 | 66 | <el-table-column prop="djrq" label="单据日期" :formatter="ncc.tableDateFormat" align="left" /> |
| 68 | - | |
| 69 | - <el-table-column label="操作" fixed="right" width="100"> | |
| 70 | - <template slot-scope="scope"> | |
| 71 | - <el-button type="text" @click="addOrUpdateHandle(scope.row.id)" >编辑</el-button> | |
| 72 | - <el-button type="text" @click="handleDel(scope.row.id)" class="NCC-table-delBtn" >删除</el-button> | |
| 73 | - </template> | |
| 74 | - </el-table-column> | |
| 75 | 67 | </NCC-table> |
| 76 | 68 | <pagination :total="total" :page.sync="listQuery.currentPage" :limit.sync="listQuery.pageSize" @pagination="initData" /> |
| 77 | 69 | </div> |
| 78 | 70 | </div> |
| 79 | - <NCC-Form v-if="formVisible" ref="NCCForm" @refresh="refresh" /> | |
| 80 | 71 | <ExportBox v-if="exportBoxVisible" ref="ExportBox" @download="download" /> |
| 72 | + <serial-trace-dialog :visible.sync="traceVisible" :xlh="traceXlh" /> | |
| 81 | 73 | </div> |
| 82 | 74 | </template> |
| 83 | 75 | <script> |
| 84 | 76 | import request from '@/utils/request' |
| 85 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 86 | - import NCCForm from './Form' | |
| 87 | 77 | import ExportBox from './ExportBox' |
| 88 | - import { previewDataInterface } from '@/api/systemData/dataInterface' | |
| 78 | + import SerialTraceDialog from './serial-trace-dialog.vue' | |
| 89 | 79 | export default { |
| 90 | - components: { NCCForm, ExportBox }, | |
| 80 | + components: { ExportBox, SerialTraceDialog }, | |
| 91 | 81 | data() { |
| 92 | 82 | return { |
| 93 | 83 | showAll: false, |
| ... | ... | @@ -100,15 +90,16 @@ |
| 100 | 90 | }, |
| 101 | 91 | list: [], |
| 102 | 92 | listLoading: true, |
| 103 | - multipleSelection: [], total: 0, | |
| 93 | + total: 0, | |
| 104 | 94 | listQuery: { |
| 105 | 95 | currentPage: 1, |
| 106 | 96 | pageSize: 20, |
| 107 | 97 | sort: "desc", |
| 108 | 98 | sidx: "", |
| 109 | 99 | }, |
| 110 | - formVisible: false, | |
| 111 | 100 | exportBoxVisible: false, |
| 101 | + traceVisible: false, | |
| 102 | + traceXlh: '', | |
| 112 | 103 | columnList: [ |
| 113 | 104 | { prop: 'xlh', label: '序列号' }, |
| 114 | 105 | { prop: 'spbh', label: '商品编号' }, |
| ... | ... | @@ -147,63 +138,6 @@ |
| 147 | 138 | this.listLoading = false |
| 148 | 139 | }) |
| 149 | 140 | }, |
| 150 | - handleDel(id) { | |
| 151 | - this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', { | |
| 152 | - type: 'warning' | |
| 153 | - }).then(() => { | |
| 154 | - request({ | |
| 155 | - url: `/api/Extend/WtXlh/${id}`, | |
| 156 | - method: 'DELETE' | |
| 157 | - }).then(res => { | |
| 158 | - this.$message({ | |
| 159 | - type: 'success', | |
| 160 | - message: res.msg, | |
| 161 | - onClose: () => { | |
| 162 | - this.initData() | |
| 163 | - } | |
| 164 | - }); | |
| 165 | - }) | |
| 166 | - }).catch(() => { | |
| 167 | - }); | |
| 168 | - }, | |
| 169 | - handleSelectionChange(val) { | |
| 170 | - const res = val.map(item => item.id) | |
| 171 | - this.multipleSelection = res | |
| 172 | - }, | |
| 173 | - handleBatchRemoveDel() { | |
| 174 | - if (!this.multipleSelection.length) { | |
| 175 | - this.$message({ | |
| 176 | - type: 'error', | |
| 177 | - message: '请选择一条数据', | |
| 178 | - duration: 1500, | |
| 179 | - }) | |
| 180 | - return | |
| 181 | - } | |
| 182 | - const ids = this.multipleSelection | |
| 183 | - this.$confirm('您确定要删除这些数据吗, 是否继续?', '提示', { | |
| 184 | - type: 'warning' | |
| 185 | - }).then(() => { | |
| 186 | - request({ | |
| 187 | - url: `/api/Extend/WtXlh/batchRemove`, | |
| 188 | - method: 'POST', | |
| 189 | - data: ids , | |
| 190 | - }).then(res => { | |
| 191 | - this.$message({ | |
| 192 | - type: 'success', | |
| 193 | - message: res.msg, | |
| 194 | - onClose: () => { | |
| 195 | - this.initData() | |
| 196 | - } | |
| 197 | - }); | |
| 198 | - }) | |
| 199 | - }).catch(() => { }) | |
| 200 | - }, | |
| 201 | - addOrUpdateHandle(id, isDetail) { | |
| 202 | - this.formVisible = true | |
| 203 | - this.$nextTick(() => { | |
| 204 | - this.$refs.NCCForm.init(id, isDetail) | |
| 205 | - }) | |
| 206 | - }, | |
| 207 | 141 | exportData() { |
| 208 | 142 | this.exportBoxVisible = true |
| 209 | 143 | this.$nextTick(() => { |
| ... | ... | @@ -232,8 +166,16 @@ |
| 232 | 166 | } |
| 233 | 167 | this.initData() |
| 234 | 168 | }, |
| 169 | + openSerialTrace() { | |
| 170 | + const x = (this.query.xlh != null ? String(this.query.xlh) : '').trim() | |
| 171 | + if (!x) { | |
| 172 | + this.$message.warning('请先在「序列号」中输入要查询的完整序列号') | |
| 173 | + return | |
| 174 | + } | |
| 175 | + this.traceXlh = x | |
| 176 | + this.traceVisible = true | |
| 177 | + }, | |
| 235 | 178 | refresh(isrRefresh) { |
| 236 | - this.formVisible = false | |
| 237 | 179 | if (isrRefresh) this.reset() |
| 238 | 180 | }, |
| 239 | 181 | reset() { | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtXlh/serial-trace-dialog.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <el-dialog | |
| 3 | + title="序列号单据流水" | |
| 4 | + :visible.sync="innerVisible" | |
| 5 | + width="900px" | |
| 6 | + append-to-body | |
| 7 | + class="NCC-dialog NCC-dialog_center" | |
| 8 | + @close="onClose" | |
| 9 | + > | |
| 10 | + <div v-if="xlhKey" class="trace-tip"> | |
| 11 | + 序列号:<strong>{{ xlhKey }}</strong>(按单据日期从早到晚排列,含出货与退货等) | |
| 12 | + </div> | |
| 13 | + <el-table | |
| 14 | + v-loading="loading" | |
| 15 | + :data="list" | |
| 16 | + size="small" | |
| 17 | + border | |
| 18 | + style="width: 100%; margin-top: 12px;" | |
| 19 | + > | |
| 20 | + <el-table-column prop="djrq" label="单据日期" width="168" :formatter="formatDjrq" show-overflow-tooltip /> | |
| 21 | + <el-table-column prop="djlx" label="单据类型" width="140" show-overflow-tooltip /> | |
| 22 | + <el-table-column prop="djbh" label="单据编号" min-width="140" show-overflow-tooltip /> | |
| 23 | + <el-table-column prop="zt" label="状态" width="100" show-overflow-tooltip /> | |
| 24 | + <el-table-column prop="spmc" label="商品名称" min-width="160" show-overflow-tooltip /> | |
| 25 | + </el-table> | |
| 26 | + <el-pagination | |
| 27 | + v-if="total > pageSize" | |
| 28 | + style="margin-top: 12px;" | |
| 29 | + background | |
| 30 | + layout="total, prev, pager, next" | |
| 31 | + :total="total" | |
| 32 | + :page-size="pageSize" | |
| 33 | + :current-page.sync="page" | |
| 34 | + @current-change="loadData" | |
| 35 | + /> | |
| 36 | + <span slot="footer" class="dialog-footer"> | |
| 37 | + <el-button @click="innerVisible = false">关 闭</el-button> | |
| 38 | + </span> | |
| 39 | + </el-dialog> | |
| 40 | +</template> | |
| 41 | + | |
| 42 | +<script> | |
| 43 | +import request from '@/utils/request' | |
| 44 | +import ncc from '@/utils/ncc' | |
| 45 | + | |
| 46 | +export default { | |
| 47 | + name: 'SerialTraceDialog', | |
| 48 | + props: { | |
| 49 | + visible: { | |
| 50 | + type: Boolean, | |
| 51 | + default: false | |
| 52 | + }, | |
| 53 | + xlh: { | |
| 54 | + type: String, | |
| 55 | + default: '' | |
| 56 | + } | |
| 57 | + }, | |
| 58 | + data() { | |
| 59 | + return { | |
| 60 | + innerVisible: false, | |
| 61 | + list: [], | |
| 62 | + loading: false, | |
| 63 | + total: 0, | |
| 64 | + page: 1, | |
| 65 | + pageSize: 100, | |
| 66 | + xlhKey: '' | |
| 67 | + } | |
| 68 | + }, | |
| 69 | + watch: { | |
| 70 | + visible(v) { | |
| 71 | + this.innerVisible = v | |
| 72 | + if (v) { | |
| 73 | + this.xlhKey = (this.xlh || '').trim() | |
| 74 | + this.page = 1 | |
| 75 | + this.loadData() | |
| 76 | + } | |
| 77 | + }, | |
| 78 | + innerVisible(v) { | |
| 79 | + if (!v) { | |
| 80 | + this.$emit('update:visible', false) | |
| 81 | + } | |
| 82 | + } | |
| 83 | + }, | |
| 84 | + methods: { | |
| 85 | + formatDjrq(row, column, cellValue) { | |
| 86 | + return ncc.tableDateFormat(row, column, cellValue) | |
| 87 | + }, | |
| 88 | + onClose() { | |
| 89 | + this.$emit('update:visible', false) | |
| 90 | + }, | |
| 91 | + loadData() { | |
| 92 | + if (!this.xlhKey) { | |
| 93 | + this.list = [] | |
| 94 | + this.total = 0 | |
| 95 | + return | |
| 96 | + } | |
| 97 | + this.loading = true | |
| 98 | + request({ | |
| 99 | + url: '/api/Extend/WtXlh/SerialTrace', | |
| 100 | + method: 'GET', | |
| 101 | + data: { | |
| 102 | + xlh: this.xlhKey, | |
| 103 | + currentPage: this.page, | |
| 104 | + pageSize: this.pageSize | |
| 105 | + } | |
| 106 | + }) | |
| 107 | + .then(res => { | |
| 108 | + this.list = res.data.list || [] | |
| 109 | + this.total = (res.data.pagination && res.data.pagination.total) || 0 | |
| 110 | + }) | |
| 111 | + .finally(() => { | |
| 112 | + this.loading = false | |
| 113 | + }) | |
| 114 | + } | |
| 115 | + } | |
| 116 | +} | |
| 117 | +</script> | |
| 118 | + | |
| 119 | +<style scoped> | |
| 120 | +.trace-tip { | |
| 121 | + font-size: 13px; | |
| 122 | + color: #606266; | |
| 123 | +} | |
| 124 | +</style> | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtXndd/Form.vue
| ... | ... | @@ -159,8 +159,8 @@ |
| 159 | 159 | </template> |
| 160 | 160 | <script> |
| 161 | 161 | import request from '@/utils/request' |
| 162 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 163 | 162 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 163 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 164 | 164 | export default { |
| 165 | 165 | components: {}, |
| 166 | 166 | props: [], |
| ... | ... | @@ -235,7 +235,7 @@ |
| 235 | 235 | }); |
| 236 | 236 | }, |
| 237 | 237 | getskzhOptions(){ |
| 238 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 238 | + getAccountSelector().then(res => { | |
| 239 | 239 | this.skzhOptions = res.data.list |
| 240 | 240 | }); |
| 241 | 241 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtXndd/index.vue
| ... | ... | @@ -132,10 +132,10 @@ |
| 132 | 132 | </template> |
| 133 | 133 | <script> |
| 134 | 134 | import request from '@/utils/request' |
| 135 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 136 | 135 | import NCCForm from './Form' |
| 137 | 136 | import ExportBox from './ExportBox' |
| 138 | 137 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 138 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 139 | 139 | export default { |
| 140 | 140 | components: { NCCForm, ExportBox }, |
| 141 | 141 | data() { |
| ... | ... | @@ -205,7 +205,7 @@ |
| 205 | 205 | }); |
| 206 | 206 | }, |
| 207 | 207 | getskzhOptions(){ |
| 208 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 208 | + getAccountSelector().then(res => { | |
| 209 | 209 | this.skzhOptions = res.data.list |
| 210 | 210 | }); |
| 211 | 211 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtXsckd/Form.vue
| ... | ... | @@ -147,16 +147,6 @@ |
| 147 | 147 | <el-input v-model="scope.row.je" placeholder="请输入" clearable readonly></el-input> |
| 148 | 148 | </template> |
| 149 | 149 | </el-table-column> |
| 150 | - <el-table-column prop="cbdj" label="成本单价" width="100" align="right"> | |
| 151 | - <template slot-scope="scope"> | |
| 152 | - <span class="cost-cell">{{ formatCostCell(scope.row.cbdj) }}</span> | |
| 153 | - </template> | |
| 154 | - </el-table-column> | |
| 155 | - <el-table-column prop="cbje" label="成本金额" width="100" align="right"> | |
| 156 | - <template slot-scope="scope"> | |
| 157 | - <span class="cost-cell">{{ formatCostCell(scope.row.cbje) }}</span> | |
| 158 | - </template> | |
| 159 | - </el-table-column> | |
| 160 | 150 | <el-table-column prop="description" label="备注"> |
| 161 | 151 | <template slot-scope="scope"> |
| 162 | 152 | <el-input v-model="scope.row.description" placeholder="请输入备注" clearable></el-input> |
| ... | ... | @@ -220,19 +210,14 @@ |
| 220 | 210 | </div> |
| 221 | 211 | </el-form-item> |
| 222 | 212 | </el-col> |
| 223 | - <el-col :span="8"> | |
| 213 | + <el-col :span="12"> | |
| 224 | 214 | <el-form-item label="收款账户" prop="skzh"> |
| 225 | 215 | <el-select v-model="dataForm.skzh" placeholder="请选择" clearable :style='{"width":"100%"}' filterable > |
| 226 | 216 | <el-option v-for="(item, index) in skzhOptions" :key="index" :label="item.fullName" :value="item.id" ></el-option> |
| 227 | 217 | </el-select> |
| 228 | 218 | </el-form-item> |
| 229 | 219 | </el-col> |
| 230 | - <el-col :span="8"> | |
| 231 | - <el-form-item label="出库成本合计"> | |
| 232 | - <el-input :value="displayOutboundCostTotalText" placeholder="按明细成本汇总" readonly :style='{"width":"100%"}' /> | |
| 233 | - </el-form-item> | |
| 234 | - </el-col> | |
| 235 | - <el-col :span="8"> | |
| 220 | + <el-col :span="12"> | |
| 236 | 221 | <el-form-item label="收款金额" prop="skje"> |
| 237 | 222 | <el-input v-model="dataForm.skje" placeholder="自动计算" clearable :style='{"width":"100%"}' readonly> |
| 238 | 223 | </el-input> |
| ... | ... | @@ -299,10 +284,10 @@ |
| 299 | 284 | </template> |
| 300 | 285 | <script> |
| 301 | 286 | import request from '@/utils/request' |
| 302 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 303 | 287 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 304 | 288 | import BarcodeSelect from '../wtCgrkd/BarcodeSelect.vue' |
| 305 | 289 | import SerialNumberSelect from './SerialNumberSelect.vue' |
| 290 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 306 | 291 | export default { |
| 307 | 292 | components: { BarcodeSelect, SerialNumberSelect }, |
| 308 | 293 | props: [], |
| ... | ... | @@ -339,8 +324,6 @@ |
| 339 | 324 | }, |
| 340 | 325 | rules: { |
| 341 | 326 | }, |
| 342 | - // 当前出库门店下各商品成本预览(下拉展示用,key=商品F_Id) | |
| 343 | - productCostPreviewMap: {}, | |
| 344 | 327 | cjckOptions : [], |
| 345 | 328 | rkckOptions : [], |
| 346 | 329 | khOptions : [], |
| ... | ... | @@ -364,19 +347,6 @@ |
| 364 | 347 | totalJe() { |
| 365 | 348 | return (this.dataForm.wtXsckdMxList || []).reduce((sum, row) => sum + (parseFloat(row.je) || 0), 0) |
| 366 | 349 | }, |
| 367 | - // 详情页优先用主表 cbje;新建/编辑按明细成本金额汇总 | |
| 368 | - displayOutboundCostTotal() { | |
| 369 | - if (this.isDetail && this.dataForm.cbje != null && this.dataForm.cbje !== '') { | |
| 370 | - const m = parseFloat(this.dataForm.cbje) | |
| 371 | - if (!isNaN(m)) return m | |
| 372 | - } | |
| 373 | - return (this.dataForm.wtXsckdMxList || []).reduce((s, r) => s + (parseFloat(r.cbje) || 0), 0) | |
| 374 | - }, | |
| 375 | - displayOutboundCostTotalText() { | |
| 376 | - const v = this.displayOutboundCostTotal | |
| 377 | - return (typeof v === 'number' && !isNaN(v)) ? v.toFixed(2) : '0.00' | |
| 378 | - }, | |
| 379 | - | |
| 380 | 350 | }, |
| 381 | 351 | watch: {}, |
| 382 | 352 | created() { |
| ... | ... | @@ -643,7 +613,7 @@ |
| 643 | 613 | }); |
| 644 | 614 | }, |
| 645 | 615 | getskzhOptions(){ |
| 646 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 616 | + getAccountSelector().then(res => { | |
| 647 | 617 | this.skzhOptions = res.data.list |
| 648 | 618 | }); |
| 649 | 619 | }, |
| ... | ... | @@ -723,7 +693,6 @@ |
| 723 | 693 | _this.restoreSerialNumbers(); |
| 724 | 694 | // 编辑时自动获取所有明细行的账面库存 |
| 725 | 695 | _this.$nextTick(() => { |
| 726 | - _this.loadProductCostPreviewMap(); | |
| 727 | 696 | _this.dataForm.wtXsckdMxList.forEach(row => { |
| 728 | 697 | if (row.spbh && row.ckck) { |
| 729 | 698 | _this.getStockQuantity(row); |
| ... | ... | @@ -745,7 +714,6 @@ |
| 745 | 714 | if (res.data.mrwldw) _this.dataForm.kh = res.data.mrwldw |
| 746 | 715 | if (res.data.mrskzh) _this.dataForm.skzh = res.data.mrskzh |
| 747 | 716 | } |
| 748 | - _this.loadProductCostPreviewMap(); | |
| 749 | 717 | }).catch(() => {}) |
| 750 | 718 | } |
| 751 | 719 | }) |
| ... | ... | @@ -1117,7 +1085,12 @@ |
| 1117 | 1085 | if (!this.currentBarcodeRow.ckck && this.dataForm.cjck) { |
| 1118 | 1086 | this.currentBarcodeRow.ckck = this.dataForm.cjck |
| 1119 | 1087 | } |
| 1120 | - this.fetchRowCost(this.currentBarcodeRow) | |
| 1088 | + // 与下拉选商品一致:拉序列号类型、账面库存(销售单价仍手工录入) | |
| 1089 | + this.$nextTick(() => { | |
| 1090 | + if (this.currentBarcodeRow && this.currentBarcodeRow.spbh) { | |
| 1091 | + this.handleProductChange(this.currentBarcodeRow) | |
| 1092 | + } | |
| 1093 | + }) | |
| 1121 | 1094 | } |
| 1122 | 1095 | }, |
| 1123 | 1096 | |
| ... | ... | @@ -1154,7 +1127,6 @@ |
| 1154 | 1127 | if (currentRow.dj) { |
| 1155 | 1128 | currentRow.je = (parseFloat(currentRow.sl) * parseFloat(currentRow.dj)).toFixed(2) |
| 1156 | 1129 | } |
| 1157 | - this.updateRowCostAmount(currentRow) | |
| 1158 | 1130 | // 更新总收款金额 |
| 1159 | 1131 | this.calculateTotalAmount(); |
| 1160 | 1132 | |
| ... | ... | @@ -1165,7 +1137,6 @@ |
| 1165 | 1137 | const sl = parseFloat(row.sl) || 0; |
| 1166 | 1138 | const dj = parseFloat(row.dj) || 0; |
| 1167 | 1139 | row.je = (sl * dj).toFixed(2); |
| 1168 | - this.updateRowCostAmount(row) | |
| 1169 | 1140 | // 自动计算总收款金额 |
| 1170 | 1141 | this.calculateTotalAmount(); |
| 1171 | 1142 | // 检查数量与序列号数量是否一致 |
| ... | ... | @@ -1187,12 +1158,10 @@ |
| 1187 | 1158 | } |
| 1188 | 1159 | // 同步更新所有明细行的出库仓库 |
| 1189 | 1160 | this.syncDetailWarehouses(); |
| 1190 | - this.loadProductCostPreviewMap() | |
| 1191 | - // 更新所有明细行的库存与成本预览 | |
| 1161 | + // 更新所有明细行的账面库存 | |
| 1192 | 1162 | this.dataForm.wtXsckdMxList.forEach(row => { |
| 1193 | 1163 | if (row.spbh) { |
| 1194 | 1164 | this.getStockQuantity(row); |
| 1195 | - this.fetchRowCost(row); | |
| 1196 | 1165 | } |
| 1197 | 1166 | }); |
| 1198 | 1167 | }, |
| ... | ... | @@ -1561,12 +1530,12 @@ |
| 1561 | 1530 | sums[index] = '合计'; |
| 1562 | 1531 | return; |
| 1563 | 1532 | } |
| 1564 | - if (['kucun', 'sl', 'je', 'cbje'].includes(column.property)) { | |
| 1533 | + if (['kucun', 'sl', 'je'].includes(column.property)) { | |
| 1565 | 1534 | const t = data.reduce((total, row) => { |
| 1566 | 1535 | const value = parseFloat(row[column.property]); |
| 1567 | 1536 | return total + (isNaN(value) ? 0 : value); |
| 1568 | 1537 | }, 0); |
| 1569 | - sums[index] = (column.property === 'cbje' || column.property === 'je') ? t.toFixed(2) : t; | |
| 1538 | + sums[index] = column.property === 'je' ? t.toFixed(2) : t; | |
| 1570 | 1539 | } else { |
| 1571 | 1540 | sums[index] = ''; |
| 1572 | 1541 | } |
| ... | ... | @@ -1578,99 +1547,24 @@ |
| 1578 | 1547 | const label = (option.label || '').toLowerCase(); |
| 1579 | 1548 | return label.includes(query.toLowerCase()); |
| 1580 | 1549 | }, |
| 1581 | - // 成本/库存接口使用的门店或仓库ID | |
| 1582 | - costContextCk() { | |
| 1583 | - if (this.dataForm.cjckId != null && this.dataForm.cjckId !== '') { | |
| 1584 | - return this.dataForm.cjckId | |
| 1585 | - } | |
| 1586 | - return this.dataForm.cjck | |
| 1587 | - }, | |
| 1588 | - formatCostCell(val) { | |
| 1589 | - if (val == null || val === '') return '无' | |
| 1590 | - const n = parseFloat(val) | |
| 1591 | - if (isNaN(n)) return '无' | |
| 1592 | - return n.toFixed(2) | |
| 1593 | - }, | |
| 1594 | 1550 | getSpOptionLabel(item) { |
| 1595 | 1551 | const base = ((item.spbm || '') + ' ' + (item.F_Spmc || '')).trim() |
| 1596 | - // const c = this.productCostPreviewMap[item.F_Id] | |
| 1597 | - // if (c != null && c !== '' && !isNaN(parseFloat(c))) { | |
| 1598 | - // return base + ' (成本¥' + parseFloat(c).toFixed(2) + ')' | |
| 1599 | - // } | |
| 1600 | - // if (!this.costContextCk()) { | |
| 1601 | - // return base + ' (选仓库后显示成本)' | |
| 1602 | - // } | |
| 1603 | 1552 | return base |
| 1604 | 1553 | }, |
| 1605 | - async loadProductCostPreviewMap() { | |
| 1606 | - const ck = this.costContextCk() | |
| 1607 | - if (!ck) { | |
| 1608 | - this.productCostPreviewMap = {} | |
| 1609 | - return | |
| 1610 | - } | |
| 1611 | - try { | |
| 1612 | - const res = await request({ | |
| 1613 | - url: '/api/Extend/WtTjd/Actions/GetCostPreviewForStore', | |
| 1614 | - method: 'get', | |
| 1615 | - data: { ck } | |
| 1616 | - }) | |
| 1617 | - let items = res.data | |
| 1618 | - if (items && items.items) items = items.items | |
| 1619 | - else if (res.items) items = res.items | |
| 1620 | - const map = {} | |
| 1621 | - ;(Array.isArray(items) ? items : []).forEach(x => { | |
| 1622 | - if (x && x.spbh != null && map[x.spbh] == null) { | |
| 1623 | - map[x.spbh] = parseFloat(x.cbj) || 0 | |
| 1624 | - } | |
| 1625 | - }) | |
| 1626 | - this.productCostPreviewMap = map | |
| 1627 | - } catch (e) { | |
| 1628 | - console.warn('loadProductCostPreviewMap failed', e) | |
| 1629 | - this.productCostPreviewMap = {} | |
| 1630 | - } | |
| 1631 | - }, | |
| 1632 | - async fetchRowCost(row) { | |
| 1633 | - const ck = row.ckck || this.costContextCk() | |
| 1634 | - if (!row.spbh || !ck) { | |
| 1635 | - this.$set(row, 'cbdj', undefined) | |
| 1636 | - this.$set(row, 'cbje', undefined) | |
| 1637 | - return | |
| 1638 | - } | |
| 1639 | - try { | |
| 1640 | - const res = await request({ | |
| 1641 | - url: '/api/Extend/WtTjd/Actions/GetCost', | |
| 1642 | - method: 'get', | |
| 1643 | - data: { spbh: row.spbh, ck } | |
| 1644 | - }) | |
| 1645 | - let payload = res.data | |
| 1646 | - if (payload && typeof payload.cbj === 'undefined' && res.data && res.data.data) { | |
| 1647 | - payload = res.data.data | |
| 1648 | - } | |
| 1649 | - const cbj = parseFloat(payload && payload.cbj != null ? payload.cbj : 0) || 0 | |
| 1650 | - this.$set(row, 'cbdj', cbj) | |
| 1651 | - this.updateRowCostAmount(row) | |
| 1652 | - } catch (e) { | |
| 1653 | - this.$set(row, 'cbdj', 0) | |
| 1654 | - this.updateRowCostAmount(row) | |
| 1655 | - } | |
| 1656 | - }, | |
| 1657 | - updateRowCostAmount(row) { | |
| 1658 | - const sl = parseFloat(row.sl) || 0 | |
| 1659 | - const cbdj = parseFloat(row.cbdj) || 0 | |
| 1660 | - this.$set(row, 'cbje', (cbdj * sl).toFixed(2)) | |
| 1661 | - }, | |
| 1662 | 1554 | handleProductChange(row) { |
| 1663 | 1555 | if (!row.spbh) { |
| 1664 | 1556 | this.$set(row, 'cbdj', undefined) |
| 1665 | 1557 | this.$set(row, 'cbje', undefined) |
| 1558 | + this.$set(row, 'dj', undefined) | |
| 1559 | + this.$set(row, 'je', undefined) | |
| 1560 | + this.$set(row, 'spmc', '') | |
| 1666 | 1561 | return |
| 1667 | 1562 | } |
| 1668 | 1563 | // 选中商品后可自动回填商品名称等信息 |
| 1669 | 1564 | const product = this.spbhOptions.find(item => item.F_Id === row.spbh); |
| 1670 | 1565 | if (product) { |
| 1671 | 1566 | row.spmc = product.F_Spmc || ''; |
| 1672 | - // ✅ 从商品主档回填单价(零售价) | |
| 1673 | - row.dj = product.F_Lsj || 0; | |
| 1567 | + // 销售单价由用户手工录入,不从商品主档自动带出 | |
| 1674 | 1568 | // 选中商品后,立即加载商品信息(如序列号类型) |
| 1675 | 1569 | this.getProductInfo(row.spbh).then(productInfo => { |
| 1676 | 1570 | // 触发当前行的响应式刷新 |
| ... | ... | @@ -1697,11 +1591,9 @@ |
| 1697 | 1591 | return; |
| 1698 | 1592 | } |
| 1699 | 1593 | |
| 1700 | - // 如果已选择出库仓库,自动获取库存与成本 | |
| 1594 | + // 如果已选择出库仓库,自动获取账面库存 | |
| 1701 | 1595 | console.log('开始获取库存...'); |
| 1702 | - this.getStockQuantity(row).finally(() => { | |
| 1703 | - this.fetchRowCost(row) | |
| 1704 | - }); | |
| 1596 | + this.getStockQuantity(row) | |
| 1705 | 1597 | } |
| 1706 | 1598 | }, |
| 1707 | 1599 | handleProductQuery(val, scope) { | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtXsckd/detail-view.vue
| ... | ... | @@ -134,11 +134,6 @@ |
| 134 | 134 | <span class="cell-nowrap mx-cell__money">{{ formatMoneyCol(scope.row.je) }}</span> |
| 135 | 135 | </template> |
| 136 | 136 | </el-table-column> |
| 137 | - <el-table-column prop="cbje" label="成本" width="96" align="right"> | |
| 138 | - <template slot-scope="scope"> | |
| 139 | - <span class="cell-nowrap">{{ formatMoneyCol(scope.row.cbje) }}</span> | |
| 140 | - </template> | |
| 141 | - </el-table-column> | |
| 142 | 137 | <el-table-column label="序列号" min-width="168"> |
| 143 | 138 | <template slot-scope="scope"> |
| 144 | 139 | <div v-if="scope.row.selectedSerialNumbers && scope.row.selectedSerialNumbers.length" class="sn-tags"> |
| ... | ... | @@ -181,12 +176,6 @@ |
| 181 | 176 | {{ displayDiscountAmount }} |
| 182 | 177 | </span> |
| 183 | 178 | </el-descriptions-item> |
| 184 | - <el-descriptions-item label="出库成本"> | |
| 185 | - <span class="cell-nowrap"> | |
| 186 | - <i class="el-icon-s-grid desc-icon desc-icon--info" /> | |
| 187 | - {{ formatMoneyCol(detail.cbje) }} | |
| 188 | - </span> | |
| 189 | - </el-descriptions-item> | |
| 190 | 179 | <el-descriptions-item label="制单人"> |
| 191 | 180 | <span class="cell-nowrap"> |
| 192 | 181 | <i class="el-icon-edit-outline desc-icon desc-icon--muted" /> |
| ... | ... | @@ -310,9 +299,9 @@ |
| 310 | 299 | |
| 311 | 300 | <script> |
| 312 | 301 | import request from '@/utils/request' |
| 313 | -import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 314 | 302 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 315 | 303 | import { dynamicText } from '@/filters' |
| 304 | +import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 316 | 305 | import { |
| 317 | 306 | formatWtSkzhDisplay, |
| 318 | 307 | resolveSkzhDictionaryLabel, |
| ... | ... | @@ -473,12 +462,23 @@ export default { |
| 473 | 462 | }, |
| 474 | 463 | formatDjrq(ts) { |
| 475 | 464 | if (ts == null || ts === '') return '无' |
| 476 | - const d = new Date(typeof ts === 'number' ? ts : Number(ts)) | |
| 465 | + const raw = typeof ts === 'string' ? ts.trim() : ts | |
| 466 | + if (raw === '') return '无' | |
| 467 | + let d | |
| 468 | + if (typeof raw === 'number') { | |
| 469 | + d = new Date(raw) | |
| 470 | + } else { | |
| 471 | + const n = Number(raw) | |
| 472 | + d = !isNaN(n) ? new Date(n) : new Date(String(raw).replace(/-/g, '/')) | |
| 473 | + } | |
| 477 | 474 | if (isNaN(d.getTime())) return '无' |
| 478 | 475 | const y = d.getFullYear() |
| 479 | 476 | const m = String(d.getMonth() + 1).padStart(2, '0') |
| 480 | 477 | const day = String(d.getDate()).padStart(2, '0') |
| 481 | - return `${y}-${m}-${day}` | |
| 478 | + const h = String(d.getHours()).padStart(2, '0') | |
| 479 | + const mi = String(d.getMinutes()).padStart(2, '0') | |
| 480 | + const s = String(d.getSeconds()).padStart(2, '0') | |
| 481 | + return `${y}-${m}-${day} ${h}:${mi}:${s}` | |
| 482 | 482 | }, |
| 483 | 483 | getSummaries(param) { |
| 484 | 484 | const { columns, data } = param |
| ... | ... | @@ -494,10 +494,6 @@ export default { |
| 494 | 494 | sums[index] = data |
| 495 | 495 | .reduce((t, row) => t + (parseFloat(row.je) || 0), 0) |
| 496 | 496 | .toFixed(2) |
| 497 | - } else if (column.property === 'cbje') { | |
| 498 | - sums[index] = data | |
| 499 | - .reduce((t, row) => t + (parseFloat(row.cbje) || 0), 0) | |
| 500 | - .toFixed(2) | |
| 501 | 497 | } else { |
| 502 | 498 | sums[index] = '' |
| 503 | 499 | } |
| ... | ... | @@ -539,7 +535,7 @@ export default { |
| 539 | 535 | previewDataInterface('681758216954053893').then(res => { |
| 540 | 536 | this.cjckOptions = res.data || [] |
| 541 | 537 | }) |
| 542 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 538 | + getAccountSelector().then(res => { | |
| 543 | 539 | const d = res.data |
| 544 | 540 | this.skzhOptions = |
| 545 | 541 | d && Array.isArray(d.list) ? d.list : Array.isArray(d) ? d : [] | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtXsckd/index.vue
| ... | ... | @@ -140,15 +140,9 @@ |
| 140 | 140 | <el-table-column label="优惠金额" align="right" min-width="96" show-overflow-tooltip> |
| 141 | 141 | <template slot-scope="scope">{{ getDisplayDiscountAmount(scope.row) }}</template> |
| 142 | 142 | </el-table-column> |
| 143 | - <el-table-column label="出库成本" align="right" min-width="96" show-overflow-tooltip> | |
| 144 | - <template slot-scope="scope">{{ getDisplayOutboundCost(scope.row) }}</template> | |
| 145 | - </el-table-column> | |
| 146 | 143 | <el-table-column label="收款账户" prop="skzh" align="left" min-width="120" show-overflow-tooltip> |
| 147 | 144 | <template slot-scope="scope">{{ displayText(formatSkzhRow(scope.row)) }}</template> |
| 148 | 145 | </el-table-column> |
| 149 | - <el-table-column prop="zdr" label="制单人" align="left" min-width="88" show-overflow-tooltip> | |
| 150 | - <template slot-scope="scope">{{ displayText(scope.row.zdr) }}</template> | |
| 151 | - </el-table-column> | |
| 152 | 146 | <el-table-column prop="shr" label="审核人" align="left" min-width="88" show-overflow-tooltip> |
| 153 | 147 | <template slot-scope="scope">{{ displayText(scope.row.shr) }}</template> |
| 154 | 148 | </el-table-column> |
| ... | ... | @@ -210,7 +204,6 @@ |
| 210 | 204 | </template> |
| 211 | 205 | <script> |
| 212 | 206 | import request from '@/utils/request' |
| 213 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 214 | 207 | import NCCForm from './Form' |
| 215 | 208 | import DetailView from './detail-view' |
| 216 | 209 | import ExportBox from './ExportBox' |
| ... | ... | @@ -218,6 +211,7 @@ |
| 218 | 211 | import { promptApprovalRemark, postApproveSalesOutbound, postRejectGeneric } from '@/utils/wtRejectApproval' |
| 219 | 212 | import { formatWtSkzhDisplay } from '@/utils/wtComboSkzhDisplay' |
| 220 | 213 | import { dynamicText } from '@/filters' |
| 214 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 221 | 215 | export default { |
| 222 | 216 | components: { NCCForm, DetailView, ExportBox }, |
| 223 | 217 | data() { |
| ... | ... | @@ -260,7 +254,6 @@ |
| 260 | 254 | { prop: 'skzh', label: '收款账户' }, |
| 261 | 255 | { prop: 'skje', label: '收款金额' }, |
| 262 | 256 | { prop: 'ysje', label: '优惠金额' }, |
| 263 | - { prop: 'zdr', label: '制单人' }, | |
| 264 | 257 | { prop: 'shr', label: '审核人' }, |
| 265 | 258 | { prop: 'gzr', label: '过账人' }, |
| 266 | 259 | { prop: 'bz', label: '备注' }, |
| ... | ... | @@ -404,11 +397,6 @@ |
| 404 | 397 | } |
| 405 | 398 | return (row.skje != null && row.skje !== '') ? parseFloat(row.skje).toFixed(2) : '0.00'; |
| 406 | 399 | }, |
| 407 | - // ✅ 出库成本:使用主表字段 cbje,空值按金额风格显示为 0.00 | |
| 408 | - getDisplayOutboundCost(row) { | |
| 409 | - const val = parseFloat(row.cbje); | |
| 410 | - return isNaN(val) ? '0.00' : val.toFixed(2); | |
| 411 | - }, | |
| 412 | 400 | getcjckOptions(){ |
| 413 | 401 | previewDataInterface('681758216954053893').then(res => { |
| 414 | 402 | this.cjckOptions = res.data |
| ... | ... | @@ -420,7 +408,7 @@ |
| 420 | 408 | }); |
| 421 | 409 | }, |
| 422 | 410 | getskzhOptions(){ |
| 423 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 411 | + getAccountSelector().then(res => { | |
| 424 | 412 | this.skzhOptions = res.data.list |
| 425 | 413 | }); |
| 426 | 414 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtXsthd/Form.vue
| ... | ... | @@ -250,10 +250,10 @@ |
| 250 | 250 | </template> |
| 251 | 251 | <script> |
| 252 | 252 | import request from '@/utils/request' |
| 253 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 254 | 253 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 255 | 254 | import SerialNumberSelect from '../wtXsckd/SerialNumberSelect.vue' |
| 256 | 255 | import ShipmentOrderSelect from '../wtXswtdxjsd/ShipmentOrderSelect.vue' |
| 256 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 257 | 257 | export default { |
| 258 | 258 | components: { SerialNumberSelect, ShipmentOrderSelect }, |
| 259 | 259 | props: [], |
| ... | ... | @@ -345,7 +345,7 @@ |
| 345 | 345 | }); |
| 346 | 346 | }, |
| 347 | 347 | getskzhOptions(){ |
| 348 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 348 | + getAccountSelector().then(res => { | |
| 349 | 349 | this.skzhOptions = res.data.list |
| 350 | 350 | }); |
| 351 | 351 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtXsthd/detail-view.vue
| ... | ... | @@ -203,10 +203,10 @@ |
| 203 | 203 | <script> |
| 204 | 204 | import request from '@/utils/request' |
| 205 | 205 | import { getUserInfoList } from '@/api/permission/user' |
| 206 | -import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 207 | 206 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 208 | 207 | import { dynamicText } from '@/filters' |
| 209 | 208 | import XsckdDetailView from '../wtXsckd/detail-view' |
| 209 | +import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 210 | 210 | |
| 211 | 211 | export default { |
| 212 | 212 | name: 'WtXsthdDetailView', |
| ... | ... | @@ -298,12 +298,23 @@ export default { |
| 298 | 298 | }, |
| 299 | 299 | formatDjrq(ts) { |
| 300 | 300 | if (ts == null || ts === '') return '无' |
| 301 | - const d = new Date(typeof ts === 'number' ? ts : Number(ts)) | |
| 301 | + const raw = typeof ts === 'string' ? ts.trim() : ts | |
| 302 | + if (raw === '') return '无' | |
| 303 | + let d | |
| 304 | + if (typeof raw === 'number') { | |
| 305 | + d = new Date(raw) | |
| 306 | + } else { | |
| 307 | + const n = Number(raw) | |
| 308 | + d = !isNaN(n) ? new Date(n) : new Date(String(raw).replace(/-/g, '/')) | |
| 309 | + } | |
| 302 | 310 | if (isNaN(d.getTime())) return '无' |
| 303 | 311 | const y = d.getFullYear() |
| 304 | 312 | const m = String(d.getMonth() + 1).padStart(2, '0') |
| 305 | 313 | const day = String(d.getDate()).padStart(2, '0') |
| 306 | - return `${y}-${m}-${day}` | |
| 314 | + const h = String(d.getHours()).padStart(2, '0') | |
| 315 | + const mi = String(d.getMinutes()).padStart(2, '0') | |
| 316 | + const s = String(d.getSeconds()).padStart(2, '0') | |
| 317 | + return `${y}-${m}-${day} ${h}:${mi}:${s}` | |
| 307 | 318 | }, |
| 308 | 319 | getSummaries(param) { |
| 309 | 320 | const { columns, data } = param |
| ... | ... | @@ -419,7 +430,7 @@ export default { |
| 419 | 430 | previewDataInterface('681758216954053893').then(res => { |
| 420 | 431 | this.cjckOptions = res.data || [] |
| 421 | 432 | }) |
| 422 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 433 | + getAccountSelector().then(res => { | |
| 423 | 434 | this.skzhOptions = res.data.list || [] |
| 424 | 435 | }) |
| 425 | 436 | } | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtXsthd/index.vue
| ... | ... | @@ -161,13 +161,13 @@ |
| 161 | 161 | </template> |
| 162 | 162 | <script> |
| 163 | 163 | import request from '@/utils/request' |
| 164 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 165 | 164 | import NCCForm from './Form' |
| 166 | 165 | import DetailView from './detail-view' |
| 167 | 166 | import XsckdDetailView from '../wtXsckd/detail-view' |
| 168 | 167 | import ExportBox from './ExportBox' |
| 169 | 168 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 170 | 169 | import { promptApprovalRemark, postApproveGeneric, postRejectGeneric } from '@/utils/wtRejectApproval' |
| 170 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 171 | 171 | export default { |
| 172 | 172 | components: { NCCForm, DetailView, XsckdDetailView, ExportBox }, |
| 173 | 173 | data() { |
| ... | ... | @@ -280,7 +280,7 @@ |
| 280 | 280 | }); |
| 281 | 281 | }, |
| 282 | 282 | getskzhOptions(){ |
| 283 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 283 | + getAccountSelector().then(res => { | |
| 284 | 284 | this.skzhOptions = res.data.list |
| 285 | 285 | }); |
| 286 | 286 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtXswtdxfhd/Form.vue
| ... | ... | @@ -280,10 +280,10 @@ |
| 280 | 280 | </template> |
| 281 | 281 | <script> |
| 282 | 282 | import request from '@/utils/request' |
| 283 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 284 | 283 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 285 | 284 | import BarcodeSelect from '../wtCgrkd/BarcodeSelect.vue' |
| 286 | 285 | import SerialNumberSelect from './SerialNumberSelect.vue' |
| 286 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 287 | 287 | export default { |
| 288 | 288 | components: { BarcodeSelect, SerialNumberSelect }, |
| 289 | 289 | props: [], |
| ... | ... | @@ -632,7 +632,7 @@ |
| 632 | 632 | }); |
| 633 | 633 | }, |
| 634 | 634 | getskzhOptions(){ |
| 635 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 635 | + getAccountSelector().then(res => { | |
| 636 | 636 | this.skzhOptions = res.data.list |
| 637 | 637 | }); |
| 638 | 638 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtXswtdxfhd/detail-view.vue
| ... | ... | @@ -133,11 +133,6 @@ |
| 133 | 133 | <span class="cell-nowrap mx-cell__money">{{ formatMoneyCol(scope.row.je) }}</span> |
| 134 | 134 | </template> |
| 135 | 135 | </el-table-column> |
| 136 | - <el-table-column prop="cbje" label="成本" width="96" align="right"> | |
| 137 | - <template slot-scope="scope"> | |
| 138 | - <span class="cell-nowrap">{{ formatMoneyCol(scope.row.cbje) }}</span> | |
| 139 | - </template> | |
| 140 | - </el-table-column> | |
| 141 | 136 | <el-table-column label="序列号" min-width="168"> |
| 142 | 137 | <template slot-scope="scope"> |
| 143 | 138 | <div v-if="scope.row.selectedSerialNumbers && scope.row.selectedSerialNumbers.length" class="sn-tags"> |
| ... | ... | @@ -180,12 +175,6 @@ |
| 180 | 175 | {{ displayDiscountAmount }} |
| 181 | 176 | </span> |
| 182 | 177 | </el-descriptions-item> |
| 183 | - <el-descriptions-item label="出库成本"> | |
| 184 | - <span class="cell-nowrap"> | |
| 185 | - <i class="el-icon-s-grid desc-icon desc-icon--info" /> | |
| 186 | - {{ formatMoneyCol(detail.cbje) }} | |
| 187 | - </span> | |
| 188 | - </el-descriptions-item> | |
| 189 | 178 | <el-descriptions-item label="制单人"> |
| 190 | 179 | <span class="cell-nowrap"> |
| 191 | 180 | <i class="el-icon-edit-outline desc-icon desc-icon--muted" /> |
| ... | ... | @@ -225,9 +214,9 @@ |
| 225 | 214 | |
| 226 | 215 | <script> |
| 227 | 216 | import request from '@/utils/request' |
| 228 | -import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 229 | 217 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 230 | 218 | import { dynamicText } from '@/filters' |
| 219 | +import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 231 | 220 | |
| 232 | 221 | export default { |
| 233 | 222 | name: 'WtXswtdxfhdDetailView', |
| ... | ... | @@ -330,12 +319,23 @@ export default { |
| 330 | 319 | }, |
| 331 | 320 | formatDjrq(ts) { |
| 332 | 321 | if (ts == null || ts === '') return '无' |
| 333 | - const d = new Date(typeof ts === 'number' ? ts : Number(ts)) | |
| 322 | + const raw = typeof ts === 'string' ? ts.trim() : ts | |
| 323 | + if (raw === '') return '无' | |
| 324 | + let d | |
| 325 | + if (typeof raw === 'number') { | |
| 326 | + d = new Date(raw) | |
| 327 | + } else { | |
| 328 | + const n = Number(raw) | |
| 329 | + d = !isNaN(n) ? new Date(n) : new Date(String(raw).replace(/-/g, '/')) | |
| 330 | + } | |
| 334 | 331 | if (isNaN(d.getTime())) return '无' |
| 335 | 332 | const y = d.getFullYear() |
| 336 | 333 | const m = String(d.getMonth() + 1).padStart(2, '0') |
| 337 | 334 | const day = String(d.getDate()).padStart(2, '0') |
| 338 | - return `${y}-${m}-${day}` | |
| 335 | + const h = String(d.getHours()).padStart(2, '0') | |
| 336 | + const mi = String(d.getMinutes()).padStart(2, '0') | |
| 337 | + const s = String(d.getSeconds()).padStart(2, '0') | |
| 338 | + return `${y}-${m}-${day} ${h}:${mi}:${s}` | |
| 339 | 339 | }, |
| 340 | 340 | getSummaries(param) { |
| 341 | 341 | const { columns, data } = param |
| ... | ... | @@ -351,10 +351,6 @@ export default { |
| 351 | 351 | sums[index] = data |
| 352 | 352 | .reduce((t, row) => t + (parseFloat(row.je) || 0), 0) |
| 353 | 353 | .toFixed(2) |
| 354 | - } else if (column.property === 'cbje') { | |
| 355 | - sums[index] = data | |
| 356 | - .reduce((t, row) => t + (parseFloat(row.cbje) || 0), 0) | |
| 357 | - .toFixed(2) | |
| 358 | 354 | } else { |
| 359 | 355 | sums[index] = '' |
| 360 | 356 | } |
| ... | ... | @@ -396,7 +392,7 @@ export default { |
| 396 | 392 | previewDataInterface('681758216954053893').then(res => { |
| 397 | 393 | this.cjckOptions = res.data || [] |
| 398 | 394 | }) |
| 399 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 395 | + getAccountSelector().then(res => { | |
| 400 | 396 | this.skzhOptions = res.data.list || [] |
| 401 | 397 | }) |
| 402 | 398 | request({ | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtXswtdxfhd/index.vue
| ... | ... | @@ -165,12 +165,12 @@ |
| 165 | 165 | </template> |
| 166 | 166 | <script> |
| 167 | 167 | import request from '@/utils/request' |
| 168 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 169 | 168 | import NCCForm from './Form' |
| 170 | 169 | import DetailView from './detail-view' |
| 171 | 170 | import ExportBox from './ExportBox' |
| 172 | 171 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 173 | 172 | import { promptApprovalRemark, postApproveGeneric } from '@/utils/wtRejectApproval' |
| 173 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 174 | 174 | export default { |
| 175 | 175 | components: { NCCForm, DetailView, ExportBox }, |
| 176 | 176 | data() { |
| ... | ... | @@ -244,7 +244,7 @@ |
| 244 | 244 | }); |
| 245 | 245 | }, |
| 246 | 246 | getskzhOptions(){ |
| 247 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 247 | + getAccountSelector().then(res => { | |
| 248 | 248 | this.skzhOptions = res.data.list |
| 249 | 249 | }); |
| 250 | 250 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtXswtdxjsd/Form.vue
| ... | ... | @@ -278,11 +278,11 @@ |
| 278 | 278 | </template> |
| 279 | 279 | <script> |
| 280 | 280 | import request from '@/utils/request' |
| 281 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 282 | 281 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 283 | 282 | import BarcodeSelect from '../wtCgrkd/BarcodeSelect.vue' |
| 284 | 283 | import SerialNumberSelect from './SerialNumberSelect.vue' |
| 285 | 284 | import ShipmentOrderSelect from './ShipmentOrderSelect.vue' |
| 285 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 286 | 286 | export default { |
| 287 | 287 | components: { BarcodeSelect, SerialNumberSelect, ShipmentOrderSelect }, |
| 288 | 288 | props: [], |
| ... | ... | @@ -596,7 +596,7 @@ |
| 596 | 596 | }); |
| 597 | 597 | }, |
| 598 | 598 | getskzhOptions(){ |
| 599 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 599 | + getAccountSelector().then(res => { | |
| 600 | 600 | this.skzhOptions = res.data.list |
| 601 | 601 | }); |
| 602 | 602 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtXswtdxjsd/detail-view.vue
| ... | ... | @@ -230,9 +230,9 @@ |
| 230 | 230 | |
| 231 | 231 | <script> |
| 232 | 232 | import request from '@/utils/request' |
| 233 | -import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 234 | 233 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 235 | 234 | import { dynamicText } from '@/filters' |
| 235 | +import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 236 | 236 | |
| 237 | 237 | export default { |
| 238 | 238 | name: 'WtXswtdxjsdDetailView', |
| ... | ... | @@ -303,12 +303,23 @@ export default { |
| 303 | 303 | }, |
| 304 | 304 | formatDjrq(ts) { |
| 305 | 305 | if (ts == null || ts === '') return '无' |
| 306 | - const d = new Date(typeof ts === 'number' ? ts : Number(ts)) | |
| 306 | + const raw = typeof ts === 'string' ? ts.trim() : ts | |
| 307 | + if (raw === '') return '无' | |
| 308 | + let d | |
| 309 | + if (typeof raw === 'number') { | |
| 310 | + d = new Date(raw) | |
| 311 | + } else { | |
| 312 | + const n = Number(raw) | |
| 313 | + d = !isNaN(n) ? new Date(n) : new Date(String(raw).replace(/-/g, '/')) | |
| 314 | + } | |
| 307 | 315 | if (isNaN(d.getTime())) return '无' |
| 308 | 316 | const y = d.getFullYear() |
| 309 | 317 | const m = String(d.getMonth() + 1).padStart(2, '0') |
| 310 | 318 | const day = String(d.getDate()).padStart(2, '0') |
| 311 | - return `${y}-${m}-${day}` | |
| 319 | + const h = String(d.getHours()).padStart(2, '0') | |
| 320 | + const mi = String(d.getMinutes()).padStart(2, '0') | |
| 321 | + const s = String(d.getSeconds()).padStart(2, '0') | |
| 322 | + return `${y}-${m}-${day} ${h}:${mi}:${s}` | |
| 312 | 323 | }, |
| 313 | 324 | getSummaries(param) { |
| 314 | 325 | const { columns, data } = param |
| ... | ... | @@ -365,7 +376,7 @@ export default { |
| 365 | 376 | previewDataInterface('681758216954053893').then(res => { |
| 366 | 377 | this.cjckOptions = res.data || [] |
| 367 | 378 | }) |
| 368 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 379 | + getAccountSelector().then(res => { | |
| 369 | 380 | this.skzhOptions = res.data.list || [] |
| 370 | 381 | }) |
| 371 | 382 | } | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtXswtdxjsd/index.vue
| ... | ... | @@ -155,12 +155,12 @@ |
| 155 | 155 | </template> |
| 156 | 156 | <script> |
| 157 | 157 | import request from '@/utils/request' |
| 158 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 159 | 158 | import NCCForm from './Form' |
| 160 | 159 | import DetailView from './detail-view' |
| 161 | 160 | import ExportBox from './ExportBox' |
| 162 | 161 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 163 | 162 | import { promptApprovalRemark, postApproveGeneric } from '@/utils/wtRejectApproval' |
| 163 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 164 | 164 | export default { |
| 165 | 165 | components: { NCCForm, DetailView, ExportBox }, |
| 166 | 166 | data() { |
| ... | ... | @@ -231,7 +231,7 @@ |
| 231 | 231 | }); |
| 232 | 232 | }, |
| 233 | 233 | getskzhOptions(){ |
| 234 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 234 | + getAccountSelector().then(res => { | |
| 235 | 235 | this.skzhOptions = res.data.list |
| 236 | 236 | }); |
| 237 | 237 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtXswtdxthd/Form.vue
| ... | ... | @@ -264,10 +264,10 @@ |
| 264 | 264 | </template> |
| 265 | 265 | <script> |
| 266 | 266 | import request from '@/utils/request' |
| 267 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 268 | 267 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 269 | 268 | import SerialNumberSelect from '../wtXsckd/SerialNumberSelect.vue' |
| 270 | 269 | import ShipmentOrderSelect from '../wtXswtdxjsd/ShipmentOrderSelect.vue' |
| 270 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 271 | 271 | export default { |
| 272 | 272 | components: { SerialNumberSelect, ShipmentOrderSelect }, |
| 273 | 273 | props: [], |
| ... | ... | @@ -363,7 +363,7 @@ |
| 363 | 363 | }); |
| 364 | 364 | }, |
| 365 | 365 | getskzhOptions(){ |
| 366 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 366 | + getAccountSelector().then(res => { | |
| 367 | 367 | this.skzhOptions = res.data.list |
| 368 | 368 | }); |
| 369 | 369 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtXswtdxthd/detail-view.vue
| ... | ... | @@ -196,9 +196,9 @@ |
| 196 | 196 | |
| 197 | 197 | <script> |
| 198 | 198 | import request from '@/utils/request' |
| 199 | -import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 200 | 199 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 201 | 200 | import { dynamicText } from '@/filters' |
| 201 | +import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 202 | 202 | |
| 203 | 203 | export default { |
| 204 | 204 | name: 'WtXswtdxthdDetailView', |
| ... | ... | @@ -287,12 +287,23 @@ export default { |
| 287 | 287 | }, |
| 288 | 288 | formatDjrq(ts) { |
| 289 | 289 | if (ts == null || ts === '') return '无' |
| 290 | - const d = new Date(typeof ts === 'number' ? ts : Number(ts)) | |
| 290 | + const raw = typeof ts === 'string' ? ts.trim() : ts | |
| 291 | + if (raw === '') return '无' | |
| 292 | + let d | |
| 293 | + if (typeof raw === 'number') { | |
| 294 | + d = new Date(raw) | |
| 295 | + } else { | |
| 296 | + const n = Number(raw) | |
| 297 | + d = !isNaN(n) ? new Date(n) : new Date(String(raw).replace(/-/g, '/')) | |
| 298 | + } | |
| 291 | 299 | if (isNaN(d.getTime())) return '无' |
| 292 | 300 | const y = d.getFullYear() |
| 293 | 301 | const m = String(d.getMonth() + 1).padStart(2, '0') |
| 294 | 302 | const day = String(d.getDate()).padStart(2, '0') |
| 295 | - return `${y}-${m}-${day}` | |
| 303 | + const h = String(d.getHours()).padStart(2, '0') | |
| 304 | + const mi = String(d.getMinutes()).padStart(2, '0') | |
| 305 | + const s = String(d.getSeconds()).padStart(2, '0') | |
| 306 | + return `${y}-${m}-${day} ${h}:${mi}:${s}` | |
| 296 | 307 | }, |
| 297 | 308 | getSummaries(param) { |
| 298 | 309 | const { columns, data } = param |
| ... | ... | @@ -405,7 +416,7 @@ export default { |
| 405 | 416 | previewDataInterface('681758216954053893').then(res => { |
| 406 | 417 | this.cjckOptions = res.data || [] |
| 407 | 418 | }) |
| 408 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 419 | + getAccountSelector().then(res => { | |
| 409 | 420 | this.skzhOptions = res.data.list || [] |
| 410 | 421 | }) |
| 411 | 422 | } | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtXswtdxthd/index.vue
| ... | ... | @@ -156,12 +156,12 @@ |
| 156 | 156 | </template> |
| 157 | 157 | <script> |
| 158 | 158 | import request from '@/utils/request' |
| 159 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 160 | 159 | import NCCForm from './Form' |
| 161 | 160 | import DetailView from './detail-view' |
| 162 | 161 | import ExportBox from './ExportBox' |
| 163 | 162 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 164 | 163 | import { promptApprovalRemark, postApproveGeneric } from '@/utils/wtRejectApproval' |
| 164 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 165 | 165 | export default { |
| 166 | 166 | components: { NCCForm, DetailView, ExportBox }, |
| 167 | 167 | data() { |
| ... | ... | @@ -234,7 +234,7 @@ |
| 234 | 234 | }); |
| 235 | 235 | }, |
| 236 | 236 | getskzhOptions(){ |
| 237 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 237 | + getAccountSelector().then(res => { | |
| 238 | 238 | this.skzhOptions = res.data.list |
| 239 | 239 | }); |
| 240 | 240 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtYfkzjjs/Form.vue
| ... | ... | @@ -127,6 +127,7 @@ |
| 127 | 127 | import request from '@/utils/request' |
| 128 | 128 | import { getDictionaryDataSelector } from '@/api/systemData/dictionary' |
| 129 | 129 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 130 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 130 | 131 | export default { |
| 131 | 132 | components: {}, |
| 132 | 133 | props: [], |
| ... | ... | @@ -202,17 +203,17 @@ |
| 202 | 203 | }); |
| 203 | 204 | }, |
| 204 | 205 | getzhbhOptions(){ |
| 205 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 206 | + getAccountSelector().then(res => { | |
| 206 | 207 | this.zhbhOptions = res.data.list |
| 207 | 208 | }); |
| 208 | 209 | }, |
| 209 | 210 | getfkzhOptions(){ |
| 210 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 211 | + getAccountSelector().then(res => { | |
| 211 | 212 | this.fkzhOptions = res.data.list |
| 212 | 213 | }); |
| 213 | 214 | }, |
| 214 | 215 | getskzhOptions(){ |
| 215 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 216 | + getAccountSelector().then(res => { | |
| 216 | 217 | this.skzhOptions = res.data.list |
| 217 | 218 | }); |
| 218 | 219 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtYfkzjjs/index.vue
| ... | ... | @@ -121,10 +121,10 @@ |
| 121 | 121 | </template> |
| 122 | 122 | <script> |
| 123 | 123 | import request from '@/utils/request' |
| 124 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 125 | 124 | import NCCForm from './Form' |
| 126 | 125 | import DetailView from './detail-view' |
| 127 | 126 | import ExportBox from './ExportBox' |
| 127 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 128 | 128 | export default { |
| 129 | 129 | components: { NCCForm, DetailView, ExportBox }, |
| 130 | 130 | data() { |
| ... | ... | @@ -178,12 +178,12 @@ |
| 178 | 178 | }, |
| 179 | 179 | methods: { |
| 180 | 180 | getfkzhOptions(){ |
| 181 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 181 | + getAccountSelector().then(res => { | |
| 182 | 182 | this.fkzhOptions = res.data.list |
| 183 | 183 | }); |
| 184 | 184 | }, |
| 185 | 185 | getskzhOptions(){ |
| 186 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 186 | + getAccountSelector().then(res => { | |
| 187 | 187 | this.skzhOptions = res.data.list |
| 188 | 188 | }); |
| 189 | 189 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtYfkzjjs_js/Form.vue
| ... | ... | @@ -110,6 +110,7 @@ |
| 110 | 110 | import request from '@/utils/request' |
| 111 | 111 | import { getDictionaryDataSelector } from '@/api/systemData/dictionary' |
| 112 | 112 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 113 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 113 | 114 | export default { |
| 114 | 115 | components: {}, |
| 115 | 116 | props: [], |
| ... | ... | @@ -183,17 +184,17 @@ |
| 183 | 184 | }); |
| 184 | 185 | }, |
| 185 | 186 | getzhbhOptions(){ |
| 186 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 187 | + getAccountSelector().then(res => { | |
| 187 | 188 | this.zhbhOptions = res.data.list |
| 188 | 189 | }); |
| 189 | 190 | }, |
| 190 | 191 | getfkzhOptions(){ |
| 191 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 192 | + getAccountSelector().then(res => { | |
| 192 | 193 | this.fkzhOptions = res.data.list |
| 193 | 194 | }); |
| 194 | 195 | }, |
| 195 | 196 | getskzhOptions(){ |
| 196 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 197 | + getAccountSelector().then(res => { | |
| 197 | 198 | this.skzhOptions = res.data.list |
| 198 | 199 | }); |
| 199 | 200 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtYfkzjjs_js/index.vue
| ... | ... | @@ -121,10 +121,10 @@ |
| 121 | 121 | </template> |
| 122 | 122 | <script> |
| 123 | 123 | import request from '@/utils/request' |
| 124 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 125 | 124 | import NCCForm from './Form' |
| 126 | 125 | import DetailView from './detail-view' |
| 127 | 126 | import ExportBox from './ExportBox' |
| 127 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 128 | 128 | export default { |
| 129 | 129 | components: { NCCForm, DetailView, ExportBox }, |
| 130 | 130 | data() { |
| ... | ... | @@ -178,12 +178,12 @@ |
| 178 | 178 | }, |
| 179 | 179 | methods: { |
| 180 | 180 | getfkzhOptions(){ |
| 181 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 181 | + getAccountSelector().then(res => { | |
| 182 | 182 | this.fkzhOptions = res.data.list |
| 183 | 183 | }); |
| 184 | 184 | }, |
| 185 | 185 | getskzhOptions(){ |
| 186 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 186 | + getAccountSelector().then(res => { | |
| 187 | 187 | this.skzhOptions = res.data.list |
| 188 | 188 | }); |
| 189 | 189 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtYsckd/Form.vue
| ... | ... | @@ -278,10 +278,10 @@ |
| 278 | 278 | </template> |
| 279 | 279 | <script> |
| 280 | 280 | import request from '@/utils/request' |
| 281 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 282 | 281 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 283 | 282 | import BarcodeSelect from '../wtCgrkd/BarcodeSelect.vue' |
| 284 | 283 | import SerialNumberSelect from './SerialNumberSelect.vue' |
| 284 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 285 | 285 | export default { |
| 286 | 286 | components: { BarcodeSelect, SerialNumberSelect }, |
| 287 | 287 | props: [], |
| ... | ... | @@ -608,7 +608,7 @@ |
| 608 | 608 | }); |
| 609 | 609 | }, |
| 610 | 610 | getskzhOptions(){ |
| 611 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 611 | + getAccountSelector().then(res => { | |
| 612 | 612 | this.skzhOptions = res.data.list |
| 613 | 613 | }); |
| 614 | 614 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtYsckd/detail-view.vue
| ... | ... | @@ -139,11 +139,6 @@ |
| 139 | 139 | <span class="cell-nowrap mx-cell__money">{{ formatMoneyCol(scope.row.je) }}</span> |
| 140 | 140 | </template> |
| 141 | 141 | </el-table-column> |
| 142 | - <el-table-column prop="cbje" label="成本" width="96" align="right"> | |
| 143 | - <template slot-scope="scope"> | |
| 144 | - <span class="cell-nowrap">{{ formatMoneyCol(scope.row.cbje) }}</span> | |
| 145 | - </template> | |
| 146 | - </el-table-column> | |
| 147 | 142 | <el-table-column label="序列号" min-width="168"> |
| 148 | 143 | <template slot-scope="scope"> |
| 149 | 144 | <div v-if="scope.row.selectedSerialNumbers && scope.row.selectedSerialNumbers.length" class="sn-tags"> |
| ... | ... | @@ -186,12 +181,6 @@ |
| 186 | 181 | {{ displayDiscountAmount }} |
| 187 | 182 | </span> |
| 188 | 183 | </el-descriptions-item> |
| 189 | - <el-descriptions-item label="出库成本"> | |
| 190 | - <span class="cell-nowrap"> | |
| 191 | - <i class="el-icon-s-grid desc-icon desc-icon--info" /> | |
| 192 | - {{ formatMoneyCol(detail.cbje) }} | |
| 193 | - </span> | |
| 194 | - </el-descriptions-item> | |
| 195 | 184 | <el-descriptions-item label="制单人"> |
| 196 | 185 | <span class="cell-nowrap"> |
| 197 | 186 | <i class="el-icon-edit-outline desc-icon desc-icon--muted" /> |
| ... | ... | @@ -312,9 +301,9 @@ |
| 312 | 301 | |
| 313 | 302 | <script> |
| 314 | 303 | import request from '@/utils/request' |
| 315 | -import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 316 | 304 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 317 | 305 | import { dynamicText } from '@/filters' |
| 306 | +import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 318 | 307 | import { |
| 319 | 308 | formatWtSkzhDisplay, |
| 320 | 309 | resolveSkzhDictionaryLabel, |
| ... | ... | @@ -467,12 +456,23 @@ export default { |
| 467 | 456 | }, |
| 468 | 457 | formatDjrq(ts) { |
| 469 | 458 | if (ts == null || ts === '') return '无' |
| 470 | - const d = new Date(typeof ts === 'number' ? ts : Number(ts)) | |
| 459 | + const raw = typeof ts === 'string' ? ts.trim() : ts | |
| 460 | + if (raw === '') return '无' | |
| 461 | + let d | |
| 462 | + if (typeof raw === 'number') { | |
| 463 | + d = new Date(raw) | |
| 464 | + } else { | |
| 465 | + const n = Number(raw) | |
| 466 | + d = !isNaN(n) ? new Date(n) : new Date(String(raw).replace(/-/g, '/')) | |
| 467 | + } | |
| 471 | 468 | if (isNaN(d.getTime())) return '无' |
| 472 | 469 | const y = d.getFullYear() |
| 473 | 470 | const m = String(d.getMonth() + 1).padStart(2, '0') |
| 474 | 471 | const day = String(d.getDate()).padStart(2, '0') |
| 475 | - return `${y}-${m}-${day}` | |
| 472 | + const h = String(d.getHours()).padStart(2, '0') | |
| 473 | + const mi = String(d.getMinutes()).padStart(2, '0') | |
| 474 | + const s = String(d.getSeconds()).padStart(2, '0') | |
| 475 | + return `${y}-${m}-${day} ${h}:${mi}:${s}` | |
| 476 | 476 | }, |
| 477 | 477 | getSummaries(param) { |
| 478 | 478 | const { columns, data } = param |
| ... | ... | @@ -488,10 +488,6 @@ export default { |
| 488 | 488 | sums[index] = data |
| 489 | 489 | .reduce((t, row) => t + (parseFloat(row.je) || 0), 0) |
| 490 | 490 | .toFixed(2) |
| 491 | - } else if (column.property === 'cbje') { | |
| 492 | - sums[index] = data | |
| 493 | - .reduce((t, row) => t + (parseFloat(row.cbje) || 0), 0) | |
| 494 | - .toFixed(2) | |
| 495 | 491 | } else { |
| 496 | 492 | sums[index] = '' |
| 497 | 493 | } |
| ... | ... | @@ -530,7 +526,7 @@ export default { |
| 530 | 526 | previewDataInterface('681758216954053893').then(res => { |
| 531 | 527 | this.cjckOptions = res.data || [] |
| 532 | 528 | }) |
| 533 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 529 | + getAccountSelector().then(res => { | |
| 534 | 530 | const d = res.data |
| 535 | 531 | this.skzhOptions = |
| 536 | 532 | d && Array.isArray(d.list) ? d.list : Array.isArray(d) ? d : [] | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtYsckd/index.vue
| ... | ... | @@ -135,9 +135,6 @@ |
| 135 | 135 | <el-table-column label="优惠金额" align="left" min-width="90"> |
| 136 | 136 | <template slot-scope="scope">{{ getDisplayDiscountAmount(scope.row) }}</template> |
| 137 | 137 | </el-table-column> |
| 138 | - <el-table-column label="出库成本" align="left" min-width="90"> | |
| 139 | - <template slot-scope="scope">{{ getDisplayOutboundCost(scope.row) }}</template> | |
| 140 | - </el-table-column> | |
| 141 | 138 | <el-table-column label="收款账户" prop="skzh" align="left"> |
| 142 | 139 | <template slot-scope="scope">{{ formatSkzhRow(scope.row) }}</template> |
| 143 | 140 | </el-table-column> |
| ... | ... | @@ -257,7 +254,6 @@ |
| 257 | 254 | </template> |
| 258 | 255 | <script> |
| 259 | 256 | import request from '@/utils/request' |
| 260 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 261 | 257 | import NCCForm from './Form' |
| 262 | 258 | import DetailView from './detail-view' |
| 263 | 259 | import ExportBox from './ExportBox' |
| ... | ... | @@ -265,6 +261,7 @@ |
| 265 | 261 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 266 | 262 | import { promptApprovalRemark, postApproveSalesOutbound } from '@/utils/wtRejectApproval' |
| 267 | 263 | import { formatWtSkzhDisplay } from '@/utils/wtComboSkzhDisplay' |
| 264 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 268 | 265 | export default { |
| 269 | 266 | components: { NCCForm, DetailView, ExportBox, SerialNumberSelect }, |
| 270 | 267 | data() { |
| ... | ... | @@ -307,7 +304,6 @@ |
| 307 | 304 | { prop: 'skzh', label: '收款账户' }, |
| 308 | 305 | { prop: 'skje', label: '收款金额' }, |
| 309 | 306 | { prop: 'ysje', label: '优惠金额' }, |
| 310 | - { prop: 'cbje', label: '出库成本' }, | |
| 311 | 307 | { prop: 'zdr', label: '制单人' }, |
| 312 | 308 | { prop: 'shr', label: '审核人' }, |
| 313 | 309 | { prop: 'gzr', label: '过账人' }, |
| ... | ... | @@ -369,10 +365,6 @@ |
| 369 | 365 | formatSkzhRow(row) { |
| 370 | 366 | return formatWtSkzhDisplay(row, this.skzhOptions) |
| 371 | 367 | }, |
| 372 | - getDisplayOutboundCost(row) { | |
| 373 | - const val = parseFloat(row.cbje) | |
| 374 | - return isNaN(val) ? '0.00' : val.toFixed(2) | |
| 375 | - }, | |
| 376 | 368 | openDetail(id) { |
| 377 | 369 | if (!id) return |
| 378 | 370 | this.detailVisible = true |
| ... | ... | @@ -454,7 +446,7 @@ |
| 454 | 446 | }); |
| 455 | 447 | }, |
| 456 | 448 | getskzhOptions(){ |
| 457 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 449 | + getAccountSelector().then(res => { | |
| 458 | 450 | this.skzhOptions = res.data.list |
| 459 | 451 | }); |
| 460 | 452 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtYskzjjs/Form.vue
| ... | ... | @@ -127,6 +127,7 @@ |
| 127 | 127 | import request from '@/utils/request' |
| 128 | 128 | import { getDictionaryDataSelector } from '@/api/systemData/dictionary' |
| 129 | 129 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 130 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 130 | 131 | export default { |
| 131 | 132 | components: {}, |
| 132 | 133 | props: [], |
| ... | ... | @@ -202,17 +203,17 @@ |
| 202 | 203 | }); |
| 203 | 204 | }, |
| 204 | 205 | getzhbhOptions(){ |
| 205 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 206 | + getAccountSelector().then(res => { | |
| 206 | 207 | this.zhbhOptions = res.data.list |
| 207 | 208 | }); |
| 208 | 209 | }, |
| 209 | 210 | getfkzhOptions(){ |
| 210 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 211 | + getAccountSelector().then(res => { | |
| 211 | 212 | this.fkzhOptions = res.data.list |
| 212 | 213 | }); |
| 213 | 214 | }, |
| 214 | 215 | getskzhOptions(){ |
| 215 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 216 | + getAccountSelector().then(res => { | |
| 216 | 217 | this.skzhOptions = res.data.list |
| 217 | 218 | }); |
| 218 | 219 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtYskzjjs/index.vue
| ... | ... | @@ -122,10 +122,10 @@ |
| 122 | 122 | </template> |
| 123 | 123 | <script> |
| 124 | 124 | import request from '@/utils/request' |
| 125 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 126 | 125 | import NCCForm from './Form' |
| 127 | 126 | import DetailView from './detail-view' |
| 128 | 127 | import ExportBox from './ExportBox' |
| 128 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 129 | 129 | export default { |
| 130 | 130 | components: { NCCForm, DetailView, ExportBox }, |
| 131 | 131 | data() { |
| ... | ... | @@ -178,12 +178,12 @@ |
| 178 | 178 | }, |
| 179 | 179 | methods: { |
| 180 | 180 | getfkzhOptions(){ |
| 181 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 181 | + getAccountSelector().then(res => { | |
| 182 | 182 | this.fkzhOptions = res.data.list |
| 183 | 183 | }); |
| 184 | 184 | }, |
| 185 | 185 | getskzhOptions(){ |
| 186 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 186 | + getAccountSelector().then(res => { | |
| 187 | 187 | this.skzhOptions = res.data.list |
| 188 | 188 | }); |
| 189 | 189 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtYskzjjs_hy/Form.vue
| ... | ... | @@ -152,6 +152,7 @@ |
| 152 | 152 | import request from '@/utils/request' |
| 153 | 153 | import { getDictionaryDataSelector } from '@/api/systemData/dictionary' |
| 154 | 154 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 155 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 155 | 156 | export default { |
| 156 | 157 | components: {}, |
| 157 | 158 | props: [], |
| ... | ... | @@ -234,17 +235,17 @@ |
| 234 | 235 | }); |
| 235 | 236 | }, |
| 236 | 237 | getzhbhOptions(){ |
| 237 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 238 | + getAccountSelector().then(res => { | |
| 238 | 239 | this.zhbhOptions = res.data.list |
| 239 | 240 | }); |
| 240 | 241 | }, |
| 241 | 242 | getfkzhOptions(){ |
| 242 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 243 | + getAccountSelector().then(res => { | |
| 243 | 244 | this.fkzhOptions = res.data.list |
| 244 | 245 | }); |
| 245 | 246 | }, |
| 246 | 247 | getskzhOptions(){ |
| 247 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 248 | + getAccountSelector().then(res => { | |
| 248 | 249 | this.skzhOptions = res.data.list |
| 249 | 250 | }); |
| 250 | 251 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtYskzjjs_hy/detail-view.vue
| ... | ... | @@ -43,7 +43,7 @@ |
| 43 | 43 | |
| 44 | 44 | <script> |
| 45 | 45 | import request from '@/utils/request' |
| 46 | -import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 46 | +import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 47 | 47 | |
| 48 | 48 | export default { |
| 49 | 49 | name: 'WtYskzjjsHyDetailView', |
| ... | ... | @@ -60,7 +60,7 @@ export default { |
| 60 | 60 | }, |
| 61 | 61 | methods: { |
| 62 | 62 | loadAccountOptions() { |
| 63 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 63 | + getAccountSelector().then(res => { | |
| 64 | 64 | this.accountOptions = (res.data && res.data.list) || [] |
| 65 | 65 | }) |
| 66 | 66 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtYskzjjs_hy/index.vue
| ... | ... | @@ -101,11 +101,11 @@ |
| 101 | 101 | </template> |
| 102 | 102 | <script> |
| 103 | 103 | import request from '@/utils/request' |
| 104 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 105 | 104 | import NCCForm from './Form' |
| 106 | 105 | import DetailView from './detail-view' |
| 107 | 106 | import ExportBox from './ExportBox' |
| 108 | 107 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 108 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 109 | 109 | export default { |
| 110 | 110 | components: { NCCForm, ExportBox, DetailView }, |
| 111 | 111 | data() { |
| ... | ... | @@ -155,12 +155,12 @@ |
| 155 | 155 | }, |
| 156 | 156 | methods: { |
| 157 | 157 | getfkzhOptions(){ |
| 158 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 158 | + getAccountSelector().then(res => { | |
| 159 | 159 | this.fkzhOptions = res.data.list |
| 160 | 160 | }); |
| 161 | 161 | }, |
| 162 | 162 | getskzhOptions(){ |
| 163 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 163 | + getAccountSelector().then(res => { | |
| 164 | 164 | this.skzhOptions = res.data.list |
| 165 | 165 | }); |
| 166 | 166 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtYskzjjs_js/Form.vue
| ... | ... | @@ -110,6 +110,7 @@ |
| 110 | 110 | import request from '@/utils/request' |
| 111 | 111 | import { getDictionaryDataSelector } from '@/api/systemData/dictionary' |
| 112 | 112 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 113 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 113 | 114 | export default { |
| 114 | 115 | components: {}, |
| 115 | 116 | props: [], |
| ... | ... | @@ -183,17 +184,17 @@ |
| 183 | 184 | }); |
| 184 | 185 | }, |
| 185 | 186 | getzhbhOptions(){ |
| 186 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 187 | + getAccountSelector().then(res => { | |
| 187 | 188 | this.zhbhOptions = res.data.list |
| 188 | 189 | }); |
| 189 | 190 | }, |
| 190 | 191 | getfkzhOptions(){ |
| 191 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 192 | + getAccountSelector().then(res => { | |
| 192 | 193 | this.fkzhOptions = res.data.list |
| 193 | 194 | }); |
| 194 | 195 | }, |
| 195 | 196 | getskzhOptions(){ |
| 196 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 197 | + getAccountSelector().then(res => { | |
| 197 | 198 | this.skzhOptions = res.data.list |
| 198 | 199 | }); |
| 199 | 200 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtYskzjjs_js/index.vue
| ... | ... | @@ -121,10 +121,10 @@ |
| 121 | 121 | </template> |
| 122 | 122 | <script> |
| 123 | 123 | import request from '@/utils/request' |
| 124 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 125 | 124 | import NCCForm from './Form' |
| 126 | 125 | import DetailView from './detail-view' |
| 127 | 126 | import ExportBox from './ExportBox' |
| 127 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 128 | 128 | export default { |
| 129 | 129 | components: { NCCForm, DetailView, ExportBox }, |
| 130 | 130 | data() { |
| ... | ... | @@ -178,12 +178,12 @@ |
| 178 | 178 | }, |
| 179 | 179 | methods: { |
| 180 | 180 | getfkzhOptions(){ |
| 181 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 181 | + getAccountSelector().then(res => { | |
| 182 | 182 | this.fkzhOptions = res.data.list |
| 183 | 183 | }); |
| 184 | 184 | }, |
| 185 | 185 | getskzhOptions(){ |
| 186 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 186 | + getAccountSelector().then(res => { | |
| 187 | 187 | this.skzhOptions = res.data.list |
| 188 | 188 | }); |
| 189 | 189 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtYskzjjs_qt/Form.vue
| ... | ... | @@ -120,6 +120,7 @@ |
| 120 | 120 | <script> |
| 121 | 121 | import request from '@/utils/request' |
| 122 | 122 | import { getDictionaryDataSelector } from '@/api/systemData/dictionary' |
| 123 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 123 | 124 | export default { |
| 124 | 125 | components: {}, |
| 125 | 126 | props: [], |
| ... | ... | @@ -177,12 +178,12 @@ |
| 177 | 178 | }); |
| 178 | 179 | }, |
| 179 | 180 | getfkzhOptions(){ |
| 180 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 181 | + getAccountSelector().then(res => { | |
| 181 | 182 | this.fkzhOptions = res.data.list |
| 182 | 183 | }); |
| 183 | 184 | }, |
| 184 | 185 | getskzhOptions(){ |
| 185 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 186 | + getAccountSelector().then(res => { | |
| 186 | 187 | this.skzhOptions = res.data.list |
| 187 | 188 | }); |
| 188 | 189 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtYskzjjs_xj/Form.vue
| ... | ... | @@ -121,6 +121,7 @@ |
| 121 | 121 | import request from '@/utils/request' |
| 122 | 122 | import { getDictionaryDataSelector } from '@/api/systemData/dictionary' |
| 123 | 123 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 124 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 124 | 125 | export default { |
| 125 | 126 | components: {}, |
| 126 | 127 | props: [], |
| ... | ... | @@ -198,17 +199,17 @@ |
| 198 | 199 | }); |
| 199 | 200 | }, |
| 200 | 201 | getzhbhOptions(){ |
| 201 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 202 | + getAccountSelector().then(res => { | |
| 202 | 203 | this.zhbhOptions = res.data.list |
| 203 | 204 | }); |
| 204 | 205 | }, |
| 205 | 206 | getfkzhOptions(){ |
| 206 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 207 | + getAccountSelector().then(res => { | |
| 207 | 208 | this.fkzhOptions = res.data.list |
| 208 | 209 | }); |
| 209 | 210 | }, |
| 210 | 211 | getskzhOptions(){ |
| 211 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 212 | + getAccountSelector().then(res => { | |
| 212 | 213 | this.skzhOptions = res.data.list |
| 213 | 214 | }); |
| 214 | 215 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtYskzjjs_xj/detail-view.vue
| ... | ... | @@ -44,6 +44,7 @@ |
| 44 | 44 | <script> |
| 45 | 45 | import request from '@/utils/request' |
| 46 | 46 | import { getDictionaryDataSelector } from '@/api/systemData/dictionary' |
| 47 | +import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 47 | 48 | |
| 48 | 49 | export default { |
| 49 | 50 | name: 'WtYskzjjsXjDetailView', |
| ... | ... | @@ -81,7 +82,7 @@ export default { |
| 81 | 82 | }) |
| 82 | 83 | }, |
| 83 | 84 | loadAccounts() { |
| 84 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 85 | + getAccountSelector().then(res => { | |
| 85 | 86 | this.accountOptions = res.data.list || [] |
| 86 | 87 | }) |
| 87 | 88 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtYskzjjs_xj/index.vue
| ... | ... | @@ -118,10 +118,10 @@ |
| 118 | 118 | </template> |
| 119 | 119 | <script> |
| 120 | 120 | import request from '@/utils/request' |
| 121 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 122 | 121 | import NCCForm from './Form' |
| 123 | 122 | import DetailView from './detail-view' |
| 124 | 123 | import ExportBox from './ExportBox' |
| 124 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 125 | 125 | export default { |
| 126 | 126 | components: { NCCForm, DetailView, ExportBox }, |
| 127 | 127 | data() { |
| ... | ... | @@ -170,12 +170,12 @@ |
| 170 | 170 | }, |
| 171 | 171 | methods: { |
| 172 | 172 | getfkzhOptions(){ |
| 173 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 173 | + getAccountSelector().then(res => { | |
| 174 | 174 | this.fkzhOptions = res.data.list |
| 175 | 175 | }); |
| 176 | 176 | }, |
| 177 | 177 | getskzhOptions(){ |
| 178 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 178 | + getAccountSelector().then(res => { | |
| 179 | 179 | this.skzhOptions = res.data.list |
| 180 | 180 | }); |
| 181 | 181 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtYskzjjs_zk/Form.vue
| ... | ... | @@ -106,6 +106,7 @@ |
| 106 | 106 | import request from '@/utils/request' |
| 107 | 107 | import { getDictionaryDataSelector } from '@/api/systemData/dictionary' |
| 108 | 108 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 109 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 109 | 110 | export default { |
| 110 | 111 | components: {}, |
| 111 | 112 | props: [], |
| ... | ... | @@ -183,17 +184,17 @@ |
| 183 | 184 | }); |
| 184 | 185 | }, |
| 185 | 186 | getzhbhOptions(){ |
| 186 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 187 | + getAccountSelector().then(res => { | |
| 187 | 188 | this.zhbhOptions = res.data.list |
| 188 | 189 | }); |
| 189 | 190 | }, |
| 190 | 191 | getfkzhOptions(){ |
| 191 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 192 | + getAccountSelector().then(res => { | |
| 192 | 193 | this.fkzhOptions = res.data.list |
| 193 | 194 | }); |
| 194 | 195 | }, |
| 195 | 196 | getskzhOptions(){ |
| 196 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 197 | + getAccountSelector().then(res => { | |
| 197 | 198 | this.skzhOptions = res.data.list |
| 198 | 199 | }); |
| 199 | 200 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtYskzjjs_zk/detail-view.vue
| ... | ... | @@ -47,7 +47,7 @@ |
| 47 | 47 | |
| 48 | 48 | <script> |
| 49 | 49 | import request from '@/utils/request' |
| 50 | -import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 50 | +import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 51 | 51 | |
| 52 | 52 | export default { |
| 53 | 53 | name: 'WtYskzjjsZkDetailView', |
| ... | ... | @@ -64,7 +64,7 @@ export default { |
| 64 | 64 | }, |
| 65 | 65 | methods: { |
| 66 | 66 | getZhOptions() { |
| 67 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 67 | + getAccountSelector().then(res => { | |
| 68 | 68 | this.zhOptions = (res.data && res.data.list) || [] |
| 69 | 69 | }) |
| 70 | 70 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtYskzjjs_zk/index.vue
| ... | ... | @@ -126,10 +126,10 @@ |
| 126 | 126 | </template> |
| 127 | 127 | <script> |
| 128 | 128 | import request from '@/utils/request' |
| 129 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 130 | 129 | import NCCForm from './Form' |
| 131 | 130 | import DetailView from './detail-view' |
| 132 | 131 | import ExportBox from './ExportBox' |
| 132 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 133 | 133 | export default { |
| 134 | 134 | components: { NCCForm, DetailView, ExportBox }, |
| 135 | 135 | data() { |
| ... | ... | @@ -180,12 +180,12 @@ |
| 180 | 180 | }, |
| 181 | 181 | methods: { |
| 182 | 182 | getfkzhOptions(){ |
| 183 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 183 | + getAccountSelector().then(res => { | |
| 184 | 184 | this.fkzhOptions = res.data.list |
| 185 | 185 | }); |
| 186 | 186 | }, |
| 187 | 187 | getskzhOptions(){ |
| 188 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 188 | + getAccountSelector().then(res => { | |
| 189 | 189 | this.skzhOptions = res.data.list |
| 190 | 190 | }); |
| 191 | 191 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtYsthd copy/Form.vue
| ... | ... | @@ -223,9 +223,9 @@ |
| 223 | 223 | </template> |
| 224 | 224 | <script> |
| 225 | 225 | import request from '@/utils/request' |
| 226 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 227 | 226 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 228 | 227 | import SerialNumberSelect from '../wtXsckd/SerialNumberSelect.vue' |
| 228 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 229 | 229 | export default { |
| 230 | 230 | components: { SerialNumberSelect }, |
| 231 | 231 | props: [], |
| ... | ... | @@ -317,7 +317,7 @@ |
| 317 | 317 | }); |
| 318 | 318 | }, |
| 319 | 319 | getskzhOptions(){ |
| 320 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 320 | + getAccountSelector().then(res => { | |
| 321 | 321 | this.skzhOptions = res.data.list |
| 322 | 322 | }); |
| 323 | 323 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtYsthd copy/index.vue
| ... | ... | @@ -127,10 +127,10 @@ |
| 127 | 127 | </template> |
| 128 | 128 | <script> |
| 129 | 129 | import request from '@/utils/request' |
| 130 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 131 | 130 | import NCCForm from './Form' |
| 132 | 131 | import ExportBox from './ExportBox' |
| 133 | 132 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 133 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 134 | 134 | export default { |
| 135 | 135 | components: { NCCForm, ExportBox }, |
| 136 | 136 | data() { |
| ... | ... | @@ -199,7 +199,7 @@ |
| 199 | 199 | }); |
| 200 | 200 | }, |
| 201 | 201 | getskzhOptions(){ |
| 202 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 202 | + getAccountSelector().then(res => { | |
| 203 | 203 | this.skzhOptions = res.data.list |
| 204 | 204 | }); |
| 205 | 205 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtYsthd/Form.vue
| ... | ... | @@ -251,10 +251,10 @@ |
| 251 | 251 | </template> |
| 252 | 252 | <script> |
| 253 | 253 | import request from '@/utils/request' |
| 254 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 255 | 254 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 256 | 255 | import SerialNumberSelect from '../wtXsckd/SerialNumberSelect.vue' |
| 257 | 256 | import ShipmentOrderSelect from '../wtXswtdxjsd/ShipmentOrderSelect.vue' |
| 257 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 258 | 258 | export default { |
| 259 | 259 | components: { SerialNumberSelect, ShipmentOrderSelect }, |
| 260 | 260 | props: [], |
| ... | ... | @@ -347,7 +347,7 @@ |
| 347 | 347 | }); |
| 348 | 348 | }, |
| 349 | 349 | getskzhOptions(){ |
| 350 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 350 | + getAccountSelector().then(res => { | |
| 351 | 351 | this.skzhOptions = res.data.list |
| 352 | 352 | }); |
| 353 | 353 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtYsthd/detail-view.vue
| ... | ... | @@ -201,10 +201,10 @@ |
| 201 | 201 | <script> |
| 202 | 202 | import request from '@/utils/request' |
| 203 | 203 | import { getUserInfoList } from '@/api/permission/user' |
| 204 | -import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 205 | 204 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 206 | 205 | import { dynamicText } from '@/filters' |
| 207 | 206 | import YsckdDetailView from '../wtYsckd/detail-view' |
| 207 | +import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 208 | 208 | |
| 209 | 209 | export default { |
| 210 | 210 | name: 'WtYsthdDetailView', |
| ... | ... | @@ -289,12 +289,23 @@ export default { |
| 289 | 289 | }, |
| 290 | 290 | formatDjrq(ts) { |
| 291 | 291 | if (ts == null || ts === '') return '无' |
| 292 | - const d = new Date(typeof ts === 'number' ? ts : Number(ts)) | |
| 292 | + const raw = typeof ts === 'string' ? ts.trim() : ts | |
| 293 | + if (raw === '') return '无' | |
| 294 | + let d | |
| 295 | + if (typeof raw === 'number') { | |
| 296 | + d = new Date(raw) | |
| 297 | + } else { | |
| 298 | + const n = Number(raw) | |
| 299 | + d = !isNaN(n) ? new Date(n) : new Date(String(raw).replace(/-/g, '/')) | |
| 300 | + } | |
| 293 | 301 | if (isNaN(d.getTime())) return '无' |
| 294 | 302 | const y = d.getFullYear() |
| 295 | 303 | const m = String(d.getMonth() + 1).padStart(2, '0') |
| 296 | 304 | const day = String(d.getDate()).padStart(2, '0') |
| 297 | - return `${y}-${m}-${day}` | |
| 305 | + const h = String(d.getHours()).padStart(2, '0') | |
| 306 | + const mi = String(d.getMinutes()).padStart(2, '0') | |
| 307 | + const s = String(d.getSeconds()).padStart(2, '0') | |
| 308 | + return `${y}-${m}-${day} ${h}:${mi}:${s}` | |
| 298 | 309 | }, |
| 299 | 310 | getSummaries(param) { |
| 300 | 311 | const { columns, data } = param |
| ... | ... | @@ -418,7 +429,7 @@ export default { |
| 418 | 429 | previewDataInterface('681758216954053893').then(res => { |
| 419 | 430 | this.cjckOptions = res.data || [] |
| 420 | 431 | }) |
| 421 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 432 | + getAccountSelector().then(res => { | |
| 422 | 433 | this.skzhOptions = res.data.list || [] |
| 423 | 434 | }) |
| 424 | 435 | } | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtYsthd/index.vue
| ... | ... | @@ -159,13 +159,13 @@ |
| 159 | 159 | </template> |
| 160 | 160 | <script> |
| 161 | 161 | import request from '@/utils/request' |
| 162 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 163 | 162 | import NCCForm from './Form' |
| 164 | 163 | import DetailView from './detail-view' |
| 165 | 164 | import YsckdDetailView from '../wtYsckd/detail-view' |
| 166 | 165 | import ExportBox from './ExportBox' |
| 167 | 166 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 168 | 167 | import { promptApprovalRemark, postApproveGeneric } from '@/utils/wtRejectApproval' |
| 168 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 169 | 169 | export default { |
| 170 | 170 | components: { NCCForm, DetailView, YsckdDetailView, ExportBox }, |
| 171 | 171 | data() { |
| ... | ... | @@ -279,7 +279,7 @@ |
| 279 | 279 | }); |
| 280 | 280 | }, |
| 281 | 281 | getskzhOptions(){ |
| 282 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 282 | + getAccountSelector().then(res => { | |
| 283 | 283 | this.skzhOptions = res.data.list |
| 284 | 284 | }); |
| 285 | 285 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtZkd/Form.vue
| ... | ... | @@ -92,8 +92,8 @@ |
| 92 | 92 | </template> |
| 93 | 93 | <script> |
| 94 | 94 | import request from '@/utils/request' |
| 95 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 96 | 95 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 96 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 97 | 97 | export default { |
| 98 | 98 | components: {}, |
| 99 | 99 | props: [], |
| ... | ... | @@ -134,12 +134,12 @@ |
| 134 | 134 | }, |
| 135 | 135 | methods: { |
| 136 | 136 | getfkzhOptions(){ |
| 137 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 137 | + getAccountSelector().then(res => { | |
| 138 | 138 | this.fkzhOptions = res.data.list |
| 139 | 139 | }); |
| 140 | 140 | }, |
| 141 | 141 | getskzhOptions(){ |
| 142 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 142 | + getAccountSelector().then(res => { | |
| 143 | 143 | this.skzhOptions = res.data.list |
| 144 | 144 | }); |
| 145 | 145 | }, | ... | ... |
Antis.Erp.Plat/antis-ncc-admin/src/views/wtZkd/index.vue
| ... | ... | @@ -133,10 +133,10 @@ |
| 133 | 133 | </template> |
| 134 | 134 | <script> |
| 135 | 135 | import request from '@/utils/request' |
| 136 | - import { getDictionaryDataSelector } from '@/api/systemData/dictionary' | |
| 137 | 136 | import NCCForm from './Form' |
| 138 | 137 | import ExportBox from './ExportBox' |
| 139 | 138 | import { previewDataInterface } from '@/api/systemData/dataInterface' |
| 139 | + import { getAccountSelector } from '@/api/extend/wtAccount' | |
| 140 | 140 | export default { |
| 141 | 141 | components: { NCCForm, ExportBox }, |
| 142 | 142 | data() { |
| ... | ... | @@ -195,12 +195,12 @@ |
| 195 | 195 | }, |
| 196 | 196 | methods: { |
| 197 | 197 | getfkzhOptions(){ |
| 198 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 198 | + getAccountSelector().then(res => { | |
| 199 | 199 | this.fkzhOptions = res.data.list |
| 200 | 200 | }); |
| 201 | 201 | }, |
| 202 | 202 | getskzhOptions(){ |
| 203 | - getDictionaryDataSelector('681761709836207365').then(res => { | |
| 203 | + getAccountSelector().then(res => { | |
| 204 | 204 | this.skzhOptions = res.data.list |
| 205 | 205 | }); |
| 206 | 206 | }, | ... | ... |
Antis.Erp.Plat/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/WtAccount/WtAccountCrInput.cs
0 → 100644
| 1 | +namespace NCC.Extend.Entitys.Dto.WtAccount | |
| 2 | +{ | |
| 3 | + /// <summary> | |
| 4 | + /// 账户管理 - 新建入参 | |
| 5 | + /// </summary> | |
| 6 | + public class WtAccountCrInput | |
| 7 | + { | |
| 8 | + /// <summary> | |
| 9 | + /// 账户名称(必填) | |
| 10 | + /// </summary> | |
| 11 | + public string accountName { get; set; } | |
| 12 | + | |
| 13 | + /// <summary> | |
| 14 | + /// 账户分类 | |
| 15 | + /// </summary> | |
| 16 | + public string category { get; set; } | |
| 17 | + | |
| 18 | + /// <summary> | |
| 19 | + /// 业务编码;留空则按 codeRule 自动生成 | |
| 20 | + /// </summary> | |
| 21 | + public string accountCode { get; set; } | |
| 22 | + | |
| 23 | + /// <summary> | |
| 24 | + /// 编码生成规则:1=数字序号(SKZH00001 递增),2=名称拼音首字母缩写;默认1 | |
| 25 | + /// </summary> | |
| 26 | + public int? codeRule { get; set; } | |
| 27 | + | |
| 28 | + /// <summary> | |
| 29 | + /// 排序码 | |
| 30 | + /// </summary> | |
| 31 | + public int? sortCode { get; set; } | |
| 32 | + } | |
| 33 | +} | ... | ... |
Antis.Erp.Plat/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/WtAccount/WtAccountInfoOutput.cs
0 → 100644
| 1 | +using System; | |
| 2 | + | |
| 3 | +namespace NCC.Extend.Entitys.Dto.WtAccount | |
| 4 | +{ | |
| 5 | + /// <summary> | |
| 6 | + /// 账户管理 - 详情输出 | |
| 7 | + /// </summary> | |
| 8 | + public class WtAccountInfoOutput | |
| 9 | + { | |
| 10 | + /// <summary> | |
| 11 | + /// 主键 | |
| 12 | + /// </summary> | |
| 13 | + public string id { get; set; } | |
| 14 | + | |
| 15 | + /// <summary> | |
| 16 | + /// 业务编码 | |
| 17 | + /// </summary> | |
| 18 | + public string accountCode { get; set; } | |
| 19 | + | |
| 20 | + /// <summary> | |
| 21 | + /// 账户名称 | |
| 22 | + /// </summary> | |
| 23 | + public string accountName { get; set; } | |
| 24 | + | |
| 25 | + /// <summary> | |
| 26 | + /// 账户分类 | |
| 27 | + /// </summary> | |
| 28 | + public string category { get; set; } | |
| 29 | + | |
| 30 | + /// <summary> | |
| 31 | + /// 状态:1=启用 0=禁用 | |
| 32 | + /// </summary> | |
| 33 | + public int status { get; set; } | |
| 34 | + | |
| 35 | + /// <summary> | |
| 36 | + /// 排序码 | |
| 37 | + /// </summary> | |
| 38 | + public int sortCode { get; set; } | |
| 39 | + | |
| 40 | + /// <summary> | |
| 41 | + /// 创建时间 | |
| 42 | + /// </summary> | |
| 43 | + public DateTime? createTime { get; set; } | |
| 44 | + } | |
| 45 | +} | ... | ... |
Antis.Erp.Plat/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/WtAccount/WtAccountListOutput.cs
0 → 100644
| 1 | +namespace NCC.Extend.Entitys.Dto.WtAccount | |
| 2 | +{ | |
| 3 | + /// <summary> | |
| 4 | + /// 账户管理 - 列表输出 | |
| 5 | + /// </summary> | |
| 6 | + public class WtAccountListOutput | |
| 7 | + { | |
| 8 | + /// <summary> | |
| 9 | + /// 主键 | |
| 10 | + /// </summary> | |
| 11 | + public string id { get; set; } | |
| 12 | + | |
| 13 | + /// <summary> | |
| 14 | + /// 业务编码 | |
| 15 | + /// </summary> | |
| 16 | + public string accountCode { get; set; } | |
| 17 | + | |
| 18 | + /// <summary> | |
| 19 | + /// 账户名称 | |
| 20 | + /// </summary> | |
| 21 | + public string accountName { get; set; } | |
| 22 | + | |
| 23 | + /// <summary> | |
| 24 | + /// 账户分类 | |
| 25 | + /// </summary> | |
| 26 | + public string category { get; set; } | |
| 27 | + | |
| 28 | + /// <summary> | |
| 29 | + /// 状态:1=启用 0=禁用 | |
| 30 | + /// </summary> | |
| 31 | + public int status { get; set; } | |
| 32 | + | |
| 33 | + /// <summary> | |
| 34 | + /// 排序码 | |
| 35 | + /// </summary> | |
| 36 | + public int sortCode { get; set; } | |
| 37 | + } | |
| 38 | +} | ... | ... |
Antis.Erp.Plat/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/WtAccount/WtAccountListQueryInput.cs
0 → 100644
| 1 | +using NCC.Common.Filter; | |
| 2 | + | |
| 3 | +namespace NCC.Extend.Entitys.Dto.WtAccount | |
| 4 | +{ | |
| 5 | + /// <summary> | |
| 6 | + /// 账户管理 - 列表查询入参 | |
| 7 | + /// </summary> | |
| 8 | + public class WtAccountListQueryInput : PageInputBase | |
| 9 | + { | |
| 10 | + /// <summary> | |
| 11 | + /// 选择导出数据key | |
| 12 | + /// </summary> | |
| 13 | + public string selectKey { get; set; } | |
| 14 | + | |
| 15 | + /// <summary> | |
| 16 | + /// 导出类型 | |
| 17 | + /// </summary> | |
| 18 | + public int dataType { get; set; } | |
| 19 | + | |
| 20 | + /// <summary> | |
| 21 | + /// 账户分类(精确) | |
| 22 | + /// </summary> | |
| 23 | + public string category { get; set; } | |
| 24 | + | |
| 25 | + /// <summary> | |
| 26 | + /// 状态:1=启用 0=禁用(不传则全部) | |
| 27 | + /// </summary> | |
| 28 | + public int? status { get; set; } | |
| 29 | + } | |
| 30 | +} | ... | ... |
Antis.Erp.Plat/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/WtAccount/WtAccountUpInput.cs
0 → 100644
| 1 | +namespace NCC.Extend.Entitys.Dto.WtAccount | |
| 2 | +{ | |
| 3 | + /// <summary> | |
| 4 | + /// 账户管理 - 更新入参 | |
| 5 | + /// </summary> | |
| 6 | + public class WtAccountUpInput : WtAccountCrInput | |
| 7 | + { | |
| 8 | + /// <summary> | |
| 9 | + /// 主键 | |
| 10 | + /// </summary> | |
| 11 | + public string id { get; set; } | |
| 12 | + | |
| 13 | + /// <summary> | |
| 14 | + /// 状态:1=启用 0=禁用 | |
| 15 | + /// </summary> | |
| 16 | + public int? status { get; set; } | |
| 17 | + } | |
| 18 | +} | ... | ... |
Antis.Erp.Plat/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/WtPurchaseSummaryQueryInput.cs
| ... | ... | @@ -41,6 +41,21 @@ namespace NCC.Extend.Entitys.Dto.WtXsckd |
| 41 | 41 | public string BillType { get; set; } |
| 42 | 42 | |
| 43 | 43 | /// <summary> |
| 44 | + /// 下钻:商品分类主键(wt_pl.F_Id),与明细接口联用 | |
| 45 | + /// </summary> | |
| 46 | + public string CategoryId { get; set; } | |
| 47 | + | |
| 48 | + /// <summary> | |
| 49 | + /// 下钻:品牌主键(wt_pp.F_Id) | |
| 50 | + /// </summary> | |
| 51 | + public string BrandId { get; set; } | |
| 52 | + | |
| 53 | + /// <summary> | |
| 54 | + /// 下钻:商品主键(wt_sp.F_Id,与明细 mx.spbh 一致) | |
| 55 | + /// </summary> | |
| 56 | + public string ProductSpId { get; set; } | |
| 57 | + | |
| 58 | + /// <summary> | |
| 44 | 59 | /// 当前页(默认 1) |
| 45 | 60 | /// </summary> |
| 46 | 61 | public int? CurrentPage { get; set; } | ... | ... |
Antis.Erp.Plat/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/WtAccountEntity.cs
0 → 100644
| 1 | +using NCC.Common.Const; | |
| 2 | +using SqlSugar; | |
| 3 | +using System; | |
| 4 | + | |
| 5 | +namespace NCC.Extend.Entitys | |
| 6 | +{ | |
| 7 | + /// <summary> | |
| 8 | + /// 账户管理(独立业务表,替代原数据字典 681761709836207365) | |
| 9 | + /// </summary> | |
| 10 | + /// <remarks> | |
| 11 | + /// 建表 SQL: | |
| 12 | + /// CREATE TABLE wt_account ( | |
| 13 | + /// F_Id VARCHAR(50) NOT NULL PRIMARY KEY COMMENT '主键', | |
| 14 | + /// account_code VARCHAR(32) NOT NULL COMMENT '业务编码(唯一,用于检索)', | |
| 15 | + /// account_name VARCHAR(100) NOT NULL COMMENT '账户名称', | |
| 16 | + /// category VARCHAR(64) NULL COMMENT '账户分类', | |
| 17 | + /// status INT NOT NULL DEFAULT 1 COMMENT '状态:1=启用 0=禁用', | |
| 18 | + /// sort_code INT NOT NULL DEFAULT 0 COMMENT '排序', | |
| 19 | + /// create_time DATETIME NULL COMMENT '创建时间', | |
| 20 | + /// UNIQUE INDEX IX_wt_account_code (account_code) | |
| 21 | + /// ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='账户主数据'; | |
| 22 | + /// | |
| 23 | + /// 门店-账户关联继续用 wt_skzhb 表,zhmc 字段改存 wt_account.F_Id: | |
| 24 | + /// UPDATE wt_skzhb SET zhmc = (新账户ID) WHERE zhmc = (旧字典ID); | |
| 25 | + /// </remarks> | |
| 26 | + [SugarTable("wt_account")] | |
| 27 | + [Tenant(ClaimConst.TENANT_ID)] | |
| 28 | + public class WtAccountEntity | |
| 29 | + { | |
| 30 | + /// <summary> | |
| 31 | + /// 主键 | |
| 32 | + /// </summary> | |
| 33 | + [SugarColumn(ColumnName = "F_Id", IsPrimaryKey = true)] | |
| 34 | + public string Id { get; set; } | |
| 35 | + | |
| 36 | + /// <summary> | |
| 37 | + /// 业务编码(唯一,用于检索:数字序号 SKZH00001 或名称拼音首字母缩写) | |
| 38 | + /// </summary> | |
| 39 | + [SugarColumn(ColumnName = "account_code")] | |
| 40 | + public string AccountCode { get; set; } | |
| 41 | + | |
| 42 | + /// <summary> | |
| 43 | + /// 账户名称 | |
| 44 | + /// </summary> | |
| 45 | + [SugarColumn(ColumnName = "account_name")] | |
| 46 | + public string AccountName { get; set; } | |
| 47 | + | |
| 48 | + /// <summary> | |
| 49 | + /// 账户分类 | |
| 50 | + /// </summary> | |
| 51 | + [SugarColumn(ColumnName = "category")] | |
| 52 | + public string Category { get; set; } | |
| 53 | + | |
| 54 | + /// <summary> | |
| 55 | + /// 状态:1=启用 0=禁用 | |
| 56 | + /// </summary> | |
| 57 | + [SugarColumn(ColumnName = "status")] | |
| 58 | + public int Status { get; set; } = 1; | |
| 59 | + | |
| 60 | + /// <summary> | |
| 61 | + /// 排序码 | |
| 62 | + /// </summary> | |
| 63 | + [SugarColumn(ColumnName = "sort_code")] | |
| 64 | + public int SortCode { get; set; } = 0; | |
| 65 | + | |
| 66 | + /// <summary> | |
| 67 | + /// 创建时间 | |
| 68 | + /// </summary> | |
| 69 | + [SugarColumn(ColumnName = "create_time")] | |
| 70 | + public DateTime? CreateTime { get; set; } | |
| 71 | + } | |
| 72 | +} | ... | ... |
Antis.Erp.Plat/netcore/src/Modularity/Extend/NCC.Extend.Interfaces/IWtAccountService.cs
0 → 100644
Antis.Erp.Plat/netcore/src/Modularity/Extend/NCC.Extend/WtAccountService.cs
0 → 100644
| 1 | +using NCC.Common.Core.Manager; | |
| 2 | +using NCC.Common.Enum; | |
| 3 | +using NCC.Common.Extension; | |
| 4 | +using NCC.Common.Filter; | |
| 5 | +using NCC.Common.Util; | |
| 6 | +using NCC.Dependency; | |
| 7 | +using NCC.DynamicApiController; | |
| 8 | +using NCC.FriendlyException; | |
| 9 | +using NCC.Extend.Interfaces.WtAccount; | |
| 10 | +using Mapster; | |
| 11 | +using Microsoft.AspNetCore.Mvc; | |
| 12 | +using SqlSugar; | |
| 13 | +using System; | |
| 14 | +using System.Collections.Generic; | |
| 15 | +using System.Linq; | |
| 16 | +using System.Text; | |
| 17 | +using System.Text.RegularExpressions; | |
| 18 | +using System.Threading.Tasks; | |
| 19 | +using NCC.Extend.Entitys; | |
| 20 | +using NCC.Extend.Entitys.Dto.WtAccount; | |
| 21 | +using Yitter.IdGenerator; | |
| 22 | +using NCC.Common.Helper; | |
| 23 | +using NCC.JsonSerialization; | |
| 24 | +using NCC.Common.Model.NPOI; | |
| 25 | +using NCC.Common.Configuration; | |
| 26 | +using NCC.DataEncryption; | |
| 27 | +using NCC.ClayObject; | |
| 28 | + | |
| 29 | +namespace NCC.Extend.WtAccount | |
| 30 | +{ | |
| 31 | + /// <summary> | |
| 32 | + /// 账户管理服务(独立业务模块,替代原数据字典) | |
| 33 | + /// </summary> | |
| 34 | + [ApiDescriptionSettings(Tag = "Extend", Name = "WtAccount", Order = 200)] | |
| 35 | + [Route("api/Extend/[controller]")] | |
| 36 | + public class WtAccountService : IWtAccountService, IDynamicApiController, ITransient | |
| 37 | + { | |
| 38 | + private readonly ISqlSugarRepository<WtAccountEntity> _repo; | |
| 39 | + private readonly SqlSugarScope _db; | |
| 40 | + private readonly IUserManager _userManager; | |
| 41 | + | |
| 42 | + /// <summary> | |
| 43 | + /// 初始化 | |
| 44 | + /// </summary> | |
| 45 | + public WtAccountService( | |
| 46 | + ISqlSugarRepository<WtAccountEntity> repo, | |
| 47 | + IUserManager userManager) | |
| 48 | + { | |
| 49 | + _repo = repo; | |
| 50 | + _db = _repo.Context; | |
| 51 | + _userManager = userManager; | |
| 52 | + } | |
| 53 | + | |
| 54 | + /// <summary> | |
| 55 | + /// 获取账户详情 | |
| 56 | + /// </summary> | |
| 57 | + [HttpGet("{id}")] | |
| 58 | + public async Task<dynamic> GetInfo(string id) | |
| 59 | + { | |
| 60 | + var entity = await _db.Queryable<WtAccountEntity>().Where(p => p.Id == id).FirstAsync(); | |
| 61 | + _ = entity ?? throw NCCException.Oh(ErrorCode.COM1005); | |
| 62 | + return new WtAccountInfoOutput | |
| 63 | + { | |
| 64 | + id = entity.Id, | |
| 65 | + accountCode = entity.AccountCode, | |
| 66 | + accountName = entity.AccountName, | |
| 67 | + category = entity.Category, | |
| 68 | + status = entity.Status, | |
| 69 | + sortCode = entity.SortCode, | |
| 70 | + createTime = entity.CreateTime | |
| 71 | + }; | |
| 72 | + } | |
| 73 | + | |
| 74 | + /// <summary> | |
| 75 | + /// 获取账户列表(分页) | |
| 76 | + /// </summary> | |
| 77 | + [HttpGet("")] | |
| 78 | + public async Task<dynamic> GetList([FromQuery] WtAccountListQueryInput input) | |
| 79 | + { | |
| 80 | + // MergeTable 后 OrderBy 的列名须与 Select 投影别名一致(camelCase),不能用库表列名 sort_code | |
| 81 | + var sidx = string.IsNullOrEmpty(input.sidx) ? "accountCode" : input.sidx; | |
| 82 | + var data = await _db.Queryable<WtAccountEntity>() | |
| 83 | + .WhereIF(!string.IsNullOrEmpty(input.keyword), | |
| 84 | + p => p.AccountCode.Contains(input.keyword) | |
| 85 | + || p.AccountName.Contains(input.keyword)) | |
| 86 | + .WhereIF(!string.IsNullOrEmpty(input.category), p => p.Category == input.category) | |
| 87 | + .WhereIF(input.status.HasValue, p => p.Status == input.status.Value) | |
| 88 | + .Select(it => new WtAccountListOutput | |
| 89 | + { | |
| 90 | + id = it.Id, | |
| 91 | + accountCode = it.AccountCode, | |
| 92 | + accountName = it.AccountName, | |
| 93 | + category = it.Category, | |
| 94 | + status = it.Status, | |
| 95 | + sortCode = it.SortCode | |
| 96 | + }) | |
| 97 | + .MergeTable() | |
| 98 | + .OrderBy(sidx + " " + input.sort) | |
| 99 | + .ToPagedListAsync(input.currentPage, input.pageSize); | |
| 100 | + return PageResult<WtAccountListOutput>.SqlSugarPageResult(data); | |
| 101 | + } | |
| 102 | + | |
| 103 | + /// <summary> | |
| 104 | + /// 获取账户下拉选项(前端 el-select 用,只返回启用账户)。 | |
| 105 | + /// 若传 storeId,只返回该门店在 wt_skzhb 中关联的账户;不传则返回全部启用账户。 | |
| 106 | + /// </summary> | |
| 107 | + [HttpGet("Selector")] | |
| 108 | + public async Task<dynamic> GetSelector([FromQuery] string storeId = null) | |
| 109 | + { | |
| 110 | + ISugarQueryable<WtAccountEntity> query; | |
| 111 | + if (!string.IsNullOrWhiteSpace(storeId)) | |
| 112 | + { | |
| 113 | + var sid = storeId.Trim(); | |
| 114 | + var accountIds = await _db.Queryable<WtSkzhbEntity>() | |
| 115 | + .Where(r => r.Ssmd == sid) | |
| 116 | + .Select(r => r.Zhmc) | |
| 117 | + .ToListAsync(); | |
| 118 | + var idSet = accountIds.Where(x => !string.IsNullOrWhiteSpace(x)).Select(x => x.Trim()).Distinct().ToList(); | |
| 119 | + query = _db.Queryable<WtAccountEntity>() | |
| 120 | + .Where(p => p.Status == 1 && idSet.Contains(p.Id)); | |
| 121 | + } | |
| 122 | + else | |
| 123 | + { | |
| 124 | + query = _db.Queryable<WtAccountEntity>().Where(p => p.Status == 1); | |
| 125 | + } | |
| 126 | + | |
| 127 | + var list = await query | |
| 128 | + .OrderBy(p => p.AccountCode) | |
| 129 | + .Select(p => new | |
| 130 | + { | |
| 131 | + id = p.Id, | |
| 132 | + accountCode = p.AccountCode, | |
| 133 | + accountName = p.AccountName, | |
| 134 | + fullName = p.AccountName, | |
| 135 | + category = p.Category | |
| 136 | + }) | |
| 137 | + .ToListAsync(); | |
| 138 | + return new { list }; | |
| 139 | + } | |
| 140 | + | |
| 141 | + /// <summary> | |
| 142 | + /// 新建账户 | |
| 143 | + /// </summary> | |
| 144 | + [HttpPost("")] | |
| 145 | + public async Task Create([FromBody] WtAccountCrInput input) | |
| 146 | + { | |
| 147 | + if (string.IsNullOrWhiteSpace(input.accountName)) | |
| 148 | + { | |
| 149 | + throw NCCException.Oh("账户名称不能为空"); | |
| 150 | + } | |
| 151 | + | |
| 152 | + var entity = new WtAccountEntity | |
| 153 | + { | |
| 154 | + Id = YitIdHelper.NextId().ToString(), | |
| 155 | + AccountName = input.accountName.Trim(), | |
| 156 | + Category = string.IsNullOrWhiteSpace(input.category) ? null : input.category.Trim(), | |
| 157 | + Status = 1, | |
| 158 | + SortCode = input.sortCode ?? 0, | |
| 159 | + CreateTime = DateTime.Now | |
| 160 | + }; | |
| 161 | + | |
| 162 | + if (string.IsNullOrWhiteSpace(input.accountCode)) | |
| 163 | + { | |
| 164 | + var rule = input.codeRule.GetValueOrDefault(1); | |
| 165 | + entity.AccountCode = await GenerateCodeAsync(rule, entity.AccountName); | |
| 166 | + } | |
| 167 | + else | |
| 168 | + { | |
| 169 | + var manual = input.accountCode.Trim(); | |
| 170 | + if (await _db.Queryable<WtAccountEntity>().AnyAsync(x => x.AccountCode == manual)) | |
| 171 | + { | |
| 172 | + throw NCCException.Oh("业务编码已存在,请更换或留空自动生成"); | |
| 173 | + } | |
| 174 | + entity.AccountCode = manual; | |
| 175 | + } | |
| 176 | + | |
| 177 | + var isOk = await _db.Insertable(entity).ExecuteCommandAsync(); | |
| 178 | + if (!(isOk > 0)) throw NCCException.Oh(ErrorCode.COM1000); | |
| 179 | + } | |
| 180 | + | |
| 181 | + /// <summary> | |
| 182 | + /// 更新账户 | |
| 183 | + /// </summary> | |
| 184 | + [HttpPut("{id}")] | |
| 185 | + public async Task Update(string id, [FromBody] WtAccountUpInput input) | |
| 186 | + { | |
| 187 | + var entity = await _db.Queryable<WtAccountEntity>().FirstAsync(p => p.Id == id); | |
| 188 | + _ = entity ?? throw NCCException.Oh(ErrorCode.COM1005); | |
| 189 | + | |
| 190 | + if (!string.IsNullOrWhiteSpace(input.accountName)) | |
| 191 | + { | |
| 192 | + entity.AccountName = input.accountName.Trim(); | |
| 193 | + } | |
| 194 | + | |
| 195 | + entity.Category = string.IsNullOrWhiteSpace(input.category) ? null : input.category.Trim(); | |
| 196 | + | |
| 197 | + if (input.status.HasValue) | |
| 198 | + { | |
| 199 | + entity.Status = input.status.Value; | |
| 200 | + } | |
| 201 | + | |
| 202 | + if (input.sortCode.HasValue) | |
| 203 | + { | |
| 204 | + entity.SortCode = input.sortCode.Value; | |
| 205 | + } | |
| 206 | + | |
| 207 | + if (!string.IsNullOrWhiteSpace(input.accountCode)) | |
| 208 | + { | |
| 209 | + var code = input.accountCode.Trim(); | |
| 210 | + if (await _db.Queryable<WtAccountEntity>().AnyAsync(x => x.AccountCode == code && x.Id != id)) | |
| 211 | + { | |
| 212 | + throw NCCException.Oh("业务编码已存在"); | |
| 213 | + } | |
| 214 | + entity.AccountCode = code; | |
| 215 | + } | |
| 216 | + | |
| 217 | + var isOk = await _db.Updateable(entity).ExecuteCommandAsync(); | |
| 218 | + if (!(isOk > 0)) throw NCCException.Oh(ErrorCode.COM1001); | |
| 219 | + } | |
| 220 | + | |
| 221 | + /// <summary> | |
| 222 | + /// 删除账户 | |
| 223 | + /// </summary> | |
| 224 | + [HttpDelete("{id}")] | |
| 225 | + public async Task Delete(string id) | |
| 226 | + { | |
| 227 | + var entity = await _db.Queryable<WtAccountEntity>().FirstAsync(p => p.Id == id); | |
| 228 | + _ = entity ?? throw NCCException.Oh(ErrorCode.COM1005); | |
| 229 | + var isOk = await _db.Deleteable<WtAccountEntity>().Where(d => d.Id == id).ExecuteCommandAsync(); | |
| 230 | + if (!(isOk > 0)) throw NCCException.Oh(ErrorCode.COM1002); | |
| 231 | + } | |
| 232 | + | |
| 233 | + /// <summary> | |
| 234 | + /// 批量删除账户 | |
| 235 | + /// </summary> | |
| 236 | + [HttpPost("batchRemove")] | |
| 237 | + public async Task BatchRemove([FromBody] List<string> ids) | |
| 238 | + { | |
| 239 | + if (ids == null || ids.Count == 0) return; | |
| 240 | + try | |
| 241 | + { | |
| 242 | + _db.BeginTran(); | |
| 243 | + await _db.Deleteable<WtAccountEntity>().In(d => d.Id, ids).ExecuteCommandAsync(); | |
| 244 | + _db.CommitTran(); | |
| 245 | + } | |
| 246 | + catch (Exception) | |
| 247 | + { | |
| 248 | + _db.RollbackTran(); | |
| 249 | + throw NCCException.Oh(ErrorCode.COM1002); | |
| 250 | + } | |
| 251 | + } | |
| 252 | + | |
| 253 | + /// <summary> | |
| 254 | + /// 导出账户 | |
| 255 | + /// </summary> | |
| 256 | + [HttpGet("Actions/Export")] | |
| 257 | + public async Task<dynamic> Export([FromQuery] WtAccountListQueryInput input) | |
| 258 | + { | |
| 259 | + var exportData = new List<WtAccountListOutput>(); | |
| 260 | + if (input.dataType == 0) | |
| 261 | + { | |
| 262 | + var data = Clay.Object(await this.GetList(input)); | |
| 263 | + exportData = data.Solidify<PageResult<WtAccountListOutput>>().list; | |
| 264 | + } | |
| 265 | + else | |
| 266 | + { | |
| 267 | + exportData = await GetNoPagingList(input); | |
| 268 | + } | |
| 269 | + List<ParamsModel> paramList = "[{\"value\":\"业务编码\",\"field\":\"accountCode\"},{\"value\":\"账户名称\",\"field\":\"accountName\"},{\"value\":\"账户分类\",\"field\":\"category\"},{\"value\":\"状态\",\"field\":\"status\"}]".ToList<ParamsModel>(); | |
| 270 | + var excelconfig = new ExcelConfig(); | |
| 271 | + excelconfig.FileName = "账户管理.xls"; | |
| 272 | + excelconfig.HeadFont = "微软雅黑"; | |
| 273 | + excelconfig.HeadPoint = 10; | |
| 274 | + excelconfig.IsAllSizeColumn = true; | |
| 275 | + excelconfig.ColumnModel = new List<ExcelColumnModel>(); | |
| 276 | + var selectKeyList = input.selectKey.Split(',').ToList(); | |
| 277 | + foreach (var item in selectKeyList) | |
| 278 | + { | |
| 279 | + var isExist = paramList.Find(p => p.field == item); | |
| 280 | + if (isExist != null) | |
| 281 | + { | |
| 282 | + excelconfig.ColumnModel.Add(new ExcelColumnModel() { Column = isExist.field, ExcelColumn = isExist.value }); | |
| 283 | + } | |
| 284 | + } | |
| 285 | + var addPath = FileVariable.TemporaryFilePath + excelconfig.FileName; | |
| 286 | + ExcelExportHelper<WtAccountListOutput>.Export(exportData, excelconfig, addPath); | |
| 287 | + var fileName = _userManager.UserId + "|" + addPath + "|xls"; | |
| 288 | + return new | |
| 289 | + { | |
| 290 | + name = excelconfig.FileName, | |
| 291 | + url = "/api/File/Download?encryption=" + DESCEncryption.Encrypt(fileName, "NCC") | |
| 292 | + }; | |
| 293 | + } | |
| 294 | + | |
| 295 | + /// <summary> | |
| 296 | + /// 获取分类列表(去重) | |
| 297 | + /// </summary> | |
| 298 | + [HttpGet("Categories")] | |
| 299 | + public async Task<dynamic> GetCategories() | |
| 300 | + { | |
| 301 | + var categories = await _db.Queryable<WtAccountEntity>() | |
| 302 | + .Where(p => p.Category != null && p.Category != "") | |
| 303 | + .GroupBy(p => p.Category) | |
| 304 | + .Select(p => p.Category) | |
| 305 | + .ToListAsync(); | |
| 306 | + return categories; | |
| 307 | + } | |
| 308 | + | |
| 309 | + #region 私有方法 | |
| 310 | + | |
| 311 | + private async Task<List<WtAccountListOutput>> GetNoPagingList(WtAccountListQueryInput input) | |
| 312 | + { | |
| 313 | + var sidx = string.IsNullOrEmpty(input.sidx) ? "accountCode" : input.sidx; | |
| 314 | + return await _db.Queryable<WtAccountEntity>() | |
| 315 | + .WhereIF(!string.IsNullOrEmpty(input.keyword), | |
| 316 | + p => p.AccountCode.Contains(input.keyword) | |
| 317 | + || p.AccountName.Contains(input.keyword)) | |
| 318 | + .WhereIF(!string.IsNullOrEmpty(input.category), p => p.Category == input.category) | |
| 319 | + .WhereIF(input.status.HasValue, p => p.Status == input.status.Value) | |
| 320 | + .Select(it => new WtAccountListOutput | |
| 321 | + { | |
| 322 | + id = it.Id, | |
| 323 | + accountCode = it.AccountCode, | |
| 324 | + accountName = it.AccountName, | |
| 325 | + category = it.Category, | |
| 326 | + status = it.Status, | |
| 327 | + sortCode = it.SortCode | |
| 328 | + }) | |
| 329 | + .MergeTable() | |
| 330 | + .OrderBy(sidx + " " + input.sort) | |
| 331 | + .ToListAsync(); | |
| 332 | + } | |
| 333 | + | |
| 334 | + private const string CodePrefix = "SKZH"; | |
| 335 | + | |
| 336 | + private async Task<string> GenerateCodeAsync(int codeRule, string accountName) | |
| 337 | + { | |
| 338 | + if (codeRule == 2) | |
| 339 | + { | |
| 340 | + var abbr = BuildPinyinAbbreviation(accountName); | |
| 341 | + return await EnsureUniqueCodeAsync(abbr); | |
| 342 | + } | |
| 343 | + | |
| 344 | + return await NextSequentialCodeAsync(); | |
| 345 | + } | |
| 346 | + | |
| 347 | + private async Task<string> NextSequentialCodeAsync() | |
| 348 | + { | |
| 349 | + var codes = await _db.Queryable<WtAccountEntity>() | |
| 350 | + .Where(x => x.AccountCode != null && x.AccountCode.StartsWith(CodePrefix)) | |
| 351 | + .Select(x => x.AccountCode) | |
| 352 | + .ToListAsync(); | |
| 353 | + var max = 0; | |
| 354 | + foreach (var z in codes) | |
| 355 | + { | |
| 356 | + if (z == null || z.Length <= CodePrefix.Length) continue; | |
| 357 | + var tail = z.Substring(CodePrefix.Length); | |
| 358 | + if (int.TryParse(tail, out var n) && n > max) max = n; | |
| 359 | + } | |
| 360 | + return CodePrefix + (max + 1).ToString("D5"); | |
| 361 | + } | |
| 362 | + | |
| 363 | + private static string BuildPinyinAbbreviation(string text) | |
| 364 | + { | |
| 365 | + if (string.IsNullOrWhiteSpace(text)) return "ZH"; | |
| 366 | + var sb = new StringBuilder(); | |
| 367 | + foreach (var c in text.Trim()) | |
| 368 | + { | |
| 369 | + if (c >= 0x4e00 && c <= 0x9fff) | |
| 370 | + { | |
| 371 | + var py = PinyinUtil.PinyinString(c.ToString()); | |
| 372 | + if (!string.IsNullOrEmpty(py)) | |
| 373 | + { | |
| 374 | + var token = py.Split(',')[0].Trim(); | |
| 375 | + if (token.Length > 0 && char.IsLetter(token[0])) | |
| 376 | + sb.Append(char.ToUpperInvariant(token[0])); | |
| 377 | + } | |
| 378 | + } | |
| 379 | + else if (char.IsLetterOrDigit(c)) | |
| 380 | + { | |
| 381 | + sb.Append(char.ToUpperInvariant(c)); | |
| 382 | + } | |
| 383 | + } | |
| 384 | + var raw = Regex.Replace(sb.ToString(), "[^A-Z0-9]", ""); | |
| 385 | + if (string.IsNullOrEmpty(raw)) return "ZH"; | |
| 386 | + return raw.Length > 12 ? raw.Substring(0, 12) : raw; | |
| 387 | + } | |
| 388 | + | |
| 389 | + private async Task<string> EnsureUniqueCodeAsync(string candidate) | |
| 390 | + { | |
| 391 | + var baseCode = string.IsNullOrWhiteSpace(candidate) ? "ZH" : candidate.Trim(); | |
| 392 | + var c = baseCode; | |
| 393 | + var n = 0; | |
| 394 | + while (await _db.Queryable<WtAccountEntity>().AnyAsync(x => x.AccountCode == c)) | |
| 395 | + { | |
| 396 | + n++; | |
| 397 | + c = baseCode + n; | |
| 398 | + } | |
| 399 | + return c; | |
| 400 | + } | |
| 401 | + | |
| 402 | + #endregion | |
| 403 | + } | |
| 404 | +} | ... | ... |
Antis.Erp.Plat/netcore/src/Modularity/Extend/NCC.Extend/WtCzdService.cs
| ... | ... | @@ -734,7 +734,7 @@ namespace NCC.Extend.WtCzd |
| 734 | 734 | { |
| 735 | 735 | await _db.Ado.ExecuteCommandAsync( |
| 736 | 736 | "INSERT INTO wt_sp_cost (F_Id, spbh, ck, cbj, sl, update_time) VALUES (@id, @spbh, @ck, @cbj, @sl, NOW())", |
| 737 | - new { id = $"{item.Spbh}_{warehouseId}", spbh = item.Spbh, ck = warehouseId, cbj = inCostPerUnit, sl = qty }); | |
| 737 | + new { id = YitIdHelper.NextId().ToString(), spbh = item.Spbh, ck = warehouseId, cbj = inCostPerUnit, sl = qty }); | |
| 738 | 738 | } |
| 739 | 739 | } |
| 740 | 740 | } | ... | ... |
Antis.Erp.Plat/netcore/src/Modularity/Extend/NCC.Extend/WtMdService.cs
| ... | ... | @@ -178,7 +178,58 @@ namespace NCC.Extend.WtMd |
| 178 | 178 | } |
| 179 | 179 | |
| 180 | 180 | /// <summary> |
| 181 | - /// 批量删除门店管理 | |
| 181 | + /// 查询 <c>wt_ck.F_ssmd</c> 中与门店主键或门店分组绑定的仓库名称(单值或逗号分隔多值均匹配)。 | |
| 182 | + /// </summary> | |
| 183 | + private static (string WhereSql, object Pars) BuildSsmdMatchWhere(string sid, string grp) | |
| 184 | + { | |
| 185 | + if (string.IsNullOrWhiteSpace(grp)) | |
| 186 | + { | |
| 187 | + const string sql = "(`F_ssmd` = @sid OR FIND_IN_SET(@sid, `F_ssmd`) > 0)"; | |
| 188 | + return (sql, new { sid }); | |
| 189 | + } | |
| 190 | + | |
| 191 | + var sqlGrp = | |
| 192 | + "( (`F_ssmd` = @sid OR FIND_IN_SET(@sid, `F_ssmd`) > 0) OR " + | |
| 193 | + "(`F_ssmd` = @grp OR FIND_IN_SET(@grp, `F_ssmd`) > 0) )"; | |
| 194 | + return (sqlGrp, new { sid, grp }); | |
| 195 | + } | |
| 196 | + | |
| 197 | + /// <summary> | |
| 198 | + /// 返回 <c>wt_ck</c> 中与门店主键或门店分组(<c>F_MdfzId</c>)在 <c>F_ssmd</c> 上绑定的仓库名称列表。 | |
| 199 | + /// </summary> | |
| 200 | + private async Task<List<string>> GetLinkedWarehouseNamesAsync(WtMdEntity md) | |
| 201 | + { | |
| 202 | + if (md == null) return new List<string>(); | |
| 203 | + var sid = md.Id?.Trim(); | |
| 204 | + if (string.IsNullOrEmpty(sid)) return new List<string>(); | |
| 205 | + var grp = string.IsNullOrWhiteSpace(md.MdfzId) ? null : md.MdfzId.Trim(); | |
| 206 | + var (whereSql, pars) = BuildSsmdMatchWhere(sid, grp); | |
| 207 | + var names = await _db.Queryable<WtCkEntity>() | |
| 208 | + .Where(whereSql + " AND (`F_ssmd` IS NOT NULL AND TRIM(`F_ssmd`) <> '')", pars) | |
| 209 | + .Select(c => c.Mdmc) | |
| 210 | + .ToListAsync(); | |
| 211 | + return names | |
| 212 | + .Where(x => !string.IsNullOrWhiteSpace(x)) | |
| 213 | + .Select(x => x.Trim()) | |
| 214 | + .Distinct(StringComparer.Ordinal) | |
| 215 | + .ToList(); | |
| 216 | + } | |
| 217 | + | |
| 218 | + /// <summary> | |
| 219 | + /// 若存在关联仓库(所属门店指向本店或本店分组),则抛出业务异常。 | |
| 220 | + /// </summary> | |
| 221 | + private async Task EnsureNoLinkedWarehousesAsync(WtMdEntity md) | |
| 222 | + { | |
| 223 | + var distinct = await GetLinkedWarehouseNamesAsync(md); | |
| 224 | + if (distinct.Count == 0) return; | |
| 225 | + var sid = md.Id?.Trim(); | |
| 226 | + var mdLabel = string.IsNullOrWhiteSpace(md.Mdmc) ? sid : md.Mdmc.Trim(); | |
| 227 | + throw NCCException.Oh( | |
| 228 | + $"门店「{mdLabel}」存在关联仓库({string.Join("、", distinct)}),请先在仓库管理中将所属门店解绑后再删除。"); | |
| 229 | + } | |
| 230 | + | |
| 231 | + /// <summary> | |
| 232 | + /// 批量删除门店管理;任一条门店存在关联仓库则整批不删并返回汇总提示。 | |
| 182 | 233 | /// </summary> |
| 183 | 234 | /// <param name="ids">主键数组</param> |
| 184 | 235 | /// <returns></returns> |
| ... | ... | @@ -188,6 +239,19 @@ namespace NCC.Extend.WtMd |
| 188 | 239 | var entitys = await _db.Queryable<WtMdEntity>().In(it => it.Id, ids).ToListAsync(); |
| 189 | 240 | if (entitys.Count > 0) |
| 190 | 241 | { |
| 242 | + var blocks = new List<string>(); | |
| 243 | + foreach (var e in entitys) | |
| 244 | + { | |
| 245 | + var wh = await GetLinkedWarehouseNamesAsync(e); | |
| 246 | + if (wh.Count == 0) continue; | |
| 247 | + var sid = e.Id?.Trim(); | |
| 248 | + var mdLabel = string.IsNullOrWhiteSpace(e.Mdmc) ? sid : e.Mdmc.Trim(); | |
| 249 | + blocks.Add($"「{mdLabel}」:{string.Join("、", wh)}"); | |
| 250 | + } | |
| 251 | + | |
| 252 | + if (blocks.Count > 0) | |
| 253 | + throw NCCException.Oh( | |
| 254 | + "以下门店存在关联仓库,请先在仓库管理中将所属门店解绑后再删除:" + string.Join(";", blocks)); | |
| 191 | 255 | try |
| 192 | 256 | { |
| 193 | 257 | //开启事务 |
| ... | ... | @@ -221,7 +285,7 @@ namespace NCC.Extend.WtMd |
| 221 | 285 | } |
| 222 | 286 | |
| 223 | 287 | /// <summary> |
| 224 | - /// 删除门店管理 | |
| 288 | + /// 删除门店管理;若 <c>wt_ck</c> 中仍有仓库的所属门店指向该门店(或门店分组),则禁止删除。 | |
| 225 | 289 | /// </summary> |
| 226 | 290 | /// <returns></returns> |
| 227 | 291 | [HttpDelete("{id}")] |
| ... | ... | @@ -229,6 +293,7 @@ namespace NCC.Extend.WtMd |
| 229 | 293 | { |
| 230 | 294 | var entity = await _db.Queryable<WtMdEntity>().FirstAsync(p => p.Id == id); |
| 231 | 295 | _ = entity ?? throw NCCException.Oh(ErrorCode.COM1005); |
| 296 | + await EnsureNoLinkedWarehousesAsync(entity); | |
| 232 | 297 | var isOk = await _db.Deleteable<WtMdEntity>().Where(d => d.Id == id).ExecuteCommandAsync(); |
| 233 | 298 | if (!(isOk > 0)) throw NCCException.Oh(ErrorCode.COM1002); |
| 234 | 299 | } | ... | ... |
Antis.Erp.Plat/netcore/src/Modularity/Extend/NCC.Extend/WtSkfkChannelStatService.cs
| ... | ... | @@ -552,14 +552,14 @@ namespace NCC.Extend.WtSkfkChannelStat |
| 552 | 552 | var idList = ids.Where(x => !string.IsNullOrEmpty(x)).Distinct().ToList(); |
| 553 | 553 | if (idList.Count == 0) |
| 554 | 554 | return map; |
| 555 | - var rows = await _db.Queryable<DictionaryDataEntity>() | |
| 556 | - .Where(d => d.DeleteMark == null && idList.Contains(d.Id)) | |
| 557 | - .Select(d => new { d.Id, d.FullName }) | |
| 555 | + var rows = await _db.Queryable<WtAccountEntity>() | |
| 556 | + .Where(a => idList.Contains(a.Id)) | |
| 557 | + .Select(a => new { a.Id, a.AccountName }) | |
| 558 | 558 | .ToListAsync(); |
| 559 | 559 | foreach (var r in rows) |
| 560 | 560 | { |
| 561 | 561 | if (!string.IsNullOrEmpty(r.Id)) |
| 562 | - map[r.Id] = r.FullName ?? ""; | |
| 562 | + map[r.Id] = r.AccountName ?? ""; | |
| 563 | 563 | } |
| 564 | 564 | |
| 565 | 565 | return map; | ... | ... |
Antis.Erp.Plat/netcore/src/Modularity/Extend/NCC.Extend/WtSkzhbService.cs
| ... | ... | @@ -57,17 +57,16 @@ namespace NCC.Extend.WtSkzhb |
| 57 | 57 | [HttpGet("{id}")] |
| 58 | 58 | public async Task<dynamic> GetInfo(string id) |
| 59 | 59 | { |
| 60 | - var output = await _db.Queryable<WtSkzhbEntity>() | |
| 61 | - .Where(p => p.Id == id) | |
| 62 | - .Select(it => new WtSkzhbInfoOutput | |
| 60 | + var output = await _db.Queryable<WtSkzhbEntity, WtAccountEntity, DictionaryDataEntity, WtMdEntity>((sk, acc, dict, md) => new JoinQueryInfos( | |
| 61 | + JoinType.Left, sk.Zhmc == acc.Id, | |
| 62 | + JoinType.Left, sk.Zhmc == dict.Id && (dict.DeleteMark == null || dict.DeleteMark == 0), | |
| 63 | + JoinType.Left, sk.Ssmd == md.Id)) | |
| 64 | + .Where((sk, acc, dict, md) => sk.Id == id) | |
| 65 | + .Select((sk, acc, dict, md) => new WtSkzhbInfoOutput | |
| 63 | 66 | { |
| 64 | - id = it.Id, | |
| 65 | - zhmc = SqlFunc.Subqueryable<DictionaryDataEntity>() | |
| 66 | - .Where(d => d.Id == it.Zhmc) | |
| 67 | - .Select(d => d.FullName), | |
| 68 | - ssmd = SqlFunc.Subqueryable<WtMdEntity>() | |
| 69 | - .Where(m => m.Id == it.Ssmd) | |
| 70 | - .Select(m => m.Mdmc), | |
| 67 | + id = sk.Id, | |
| 68 | + zhmc = SqlFunc.IsNull(SqlFunc.IsNull(acc.AccountName, dict.FullName), sk.Zhmc), | |
| 69 | + ssmd = md.Mdmc, | |
| 71 | 70 | }) |
| 72 | 71 | .FirstAsync(); |
| 73 | 72 | return output; |
| ... | ... | @@ -81,25 +80,36 @@ namespace NCC.Extend.WtSkzhb |
| 81 | 80 | [HttpGet("")] |
| 82 | 81 | public async Task<dynamic> GetList([FromQuery] WtSkzhbListQueryInput input) |
| 83 | 82 | { |
| 84 | - var sidx = input.sidx == null ? "id" : input.sidx; | |
| 85 | - var data = await _db.Queryable<WtSkzhbEntity>() | |
| 86 | - .WhereIF(!string.IsNullOrEmpty(input.id), p => p.Id.Contains(input.id)) | |
| 87 | - .WhereIF(!string.IsNullOrEmpty(input.zhmc), p => p.Zhmc.Contains(input.zhmc)) | |
| 88 | - .WhereIF(!string.IsNullOrEmpty(input.ssmd), p => p.Ssmd.Contains(input.ssmd)) | |
| 89 | - .Select(it=> new WtSkzhbListOutput | |
| 83 | + input ??= new WtSkzhbListQueryInput(); | |
| 84 | + var pageIndex = input.currentPage > 0 ? input.currentPage : 1; | |
| 85 | + var pageSize = input.pageSize > 0 ? input.pageSize : 50; | |
| 86 | + var sidxRaw = string.IsNullOrWhiteSpace(input.sidx) ? "id" : input.sidx.Trim(); | |
| 87 | + var sortRaw = string.IsNullOrWhiteSpace(input.sort) ? "desc" : input.sort.Trim(); | |
| 88 | + // MergeTable 后 OrderBy 使用输出列名;限制字段避免注入 | |
| 89 | + var sidx = new[] { "id", "zhmc", "ssmd", "skzhDictId" }.Contains(sidxRaw, StringComparer.OrdinalIgnoreCase) ? sidxRaw : "id"; | |
| 90 | + var sort = sortRaw.Equals("asc", StringComparison.OrdinalIgnoreCase) ? "asc" : "desc"; | |
| 91 | + var ssmdEq = string.IsNullOrWhiteSpace(input.ssmd) ? null : input.ssmd.Trim(); | |
| 92 | + // 不用 Select 内嵌 Subqueryable + MergeTable(SqlSugar SubResolve 会 NRE),改为 LeftJoin 拼列 | |
| 93 | + var data = await _db.Queryable<WtSkzhbEntity, WtAccountEntity, DictionaryDataEntity, WtMdEntity>((sk, acc, dict, md) => new JoinQueryInfos( | |
| 94 | + JoinType.Left, sk.Zhmc == acc.Id, | |
| 95 | + JoinType.Left, sk.Zhmc == dict.Id && (dict.DeleteMark == null || dict.DeleteMark == 0), | |
| 96 | + JoinType.Left, sk.Ssmd == md.Id)) | |
| 97 | + .WhereIF(!string.IsNullOrEmpty(input.id), (sk, acc, dict, md) => sk.Id.Contains(input.id)) | |
| 98 | + .WhereIF(!string.IsNullOrEmpty(input.zhmc), (sk, acc, dict, md) => sk.Zhmc.Contains(input.zhmc)) | |
| 99 | + .WhereIF(ssmdEq != null, (sk, acc, dict, md) => sk.Ssmd != null && ( | |
| 100 | + SqlFunc.Trim(sk.Ssmd) == ssmdEq || | |
| 101 | + sk.Ssmd.Contains(ssmdEq))) | |
| 102 | + .Select((sk, acc, dict, md) => new WtSkzhbListOutput | |
| 90 | 103 | { |
| 91 | - id = it.Id, | |
| 92 | - skzhDictId = it.Zhmc, | |
| 93 | - // ✅ 账户名称:通过子查询关联字典表,将ID转换为中文名称 | |
| 94 | - zhmc = SqlFunc.Subqueryable<DictionaryDataEntity>() | |
| 95 | - .Where(d => d.Id == it.Zhmc) | |
| 96 | - .Select(d => d.FullName), | |
| 97 | - // ✅ 门店:通过子查询关联门店表,将ID转换为中文名称 | |
| 98 | - ssmd = SqlFunc.Subqueryable<WtMdEntity>() | |
| 99 | - .Where(m => m.Id == it.Ssmd) | |
| 100 | - .Select(m => m.Mdmc), | |
| 101 | - }).MergeTable().OrderBy(sidx+" "+input.sort).ToPagedListAsync(input.currentPage, input.pageSize); | |
| 102 | - return PageResult<WtSkzhbListOutput>.SqlSugarPageResult(data); | |
| 104 | + id = sk.Id, | |
| 105 | + skzhDictId = sk.Zhmc, | |
| 106 | + zhmc = SqlFunc.IsNull(SqlFunc.IsNull(acc.AccountName, dict.FullName), sk.Zhmc), | |
| 107 | + ssmd = md.Mdmc, | |
| 108 | + }) | |
| 109 | + .MergeTable() | |
| 110 | + .OrderBy(sidx + " " + sort) | |
| 111 | + .ToPagedListAsync(pageIndex, pageSize); | |
| 112 | + return PageResult<WtSkzhbListOutput>.SqlSugarPageResult(data); | |
| 103 | 113 | } |
| 104 | 114 | |
| 105 | 115 | /// <summary> |
| ... | ... | @@ -125,25 +135,32 @@ namespace NCC.Extend.WtSkzhb |
| 125 | 135 | [NonAction] |
| 126 | 136 | public async Task<dynamic> GetNoPagingList([FromQuery] WtSkzhbListQueryInput input) |
| 127 | 137 | { |
| 128 | - var sidx = input.sidx == null ? "id" : input.sidx; | |
| 129 | - var data = await _db.Queryable<WtSkzhbEntity>() | |
| 130 | - .WhereIF(!string.IsNullOrEmpty(input.id), p => p.Id.Contains(input.id)) | |
| 131 | - .WhereIF(!string.IsNullOrEmpty(input.zhmc), p => p.Zhmc.Contains(input.zhmc)) | |
| 132 | - .WhereIF(!string.IsNullOrEmpty(input.ssmd), p => p.Ssmd.Contains(input.ssmd)) | |
| 133 | - .Select(it=> new WtSkzhbListOutput | |
| 138 | + input ??= new WtSkzhbListQueryInput(); | |
| 139 | + var sidxRaw = string.IsNullOrWhiteSpace(input.sidx) ? "id" : input.sidx.Trim(); | |
| 140 | + var sortRaw = string.IsNullOrWhiteSpace(input.sort) ? "desc" : input.sort.Trim(); | |
| 141 | + var sidx = new[] { "id", "zhmc", "ssmd", "skzhDictId" }.Contains(sidxRaw, StringComparer.OrdinalIgnoreCase) ? sidxRaw : "id"; | |
| 142 | + var sort = sortRaw.Equals("asc", StringComparison.OrdinalIgnoreCase) ? "asc" : "desc"; | |
| 143 | + var ssmdEq = string.IsNullOrWhiteSpace(input.ssmd) ? null : input.ssmd.Trim(); | |
| 144 | + var data = await _db.Queryable<WtSkzhbEntity, WtAccountEntity, DictionaryDataEntity, WtMdEntity>((sk, acc, dict, md) => new JoinQueryInfos( | |
| 145 | + JoinType.Left, sk.Zhmc == acc.Id, | |
| 146 | + JoinType.Left, sk.Zhmc == dict.Id && (dict.DeleteMark == null || dict.DeleteMark == 0), | |
| 147 | + JoinType.Left, sk.Ssmd == md.Id)) | |
| 148 | + .WhereIF(!string.IsNullOrEmpty(input.id), (sk, acc, dict, md) => sk.Id.Contains(input.id)) | |
| 149 | + .WhereIF(!string.IsNullOrEmpty(input.zhmc), (sk, acc, dict, md) => sk.Zhmc.Contains(input.zhmc)) | |
| 150 | + .WhereIF(ssmdEq != null, (sk, acc, dict, md) => sk.Ssmd != null && ( | |
| 151 | + SqlFunc.Trim(sk.Ssmd) == ssmdEq || | |
| 152 | + sk.Ssmd.Contains(ssmdEq))) | |
| 153 | + .Select((sk, acc, dict, md) => new WtSkzhbListOutput | |
| 134 | 154 | { |
| 135 | - id = it.Id, | |
| 136 | - skzhDictId = it.Zhmc, | |
| 137 | - // ✅ 账户名称:通过子查询关联字典表,将ID转换为中文名称 | |
| 138 | - zhmc = SqlFunc.Subqueryable<DictionaryDataEntity>() | |
| 139 | - .Where(d => d.Id == it.Zhmc) | |
| 140 | - .Select(d => d.FullName), | |
| 141 | - // ✅ 门店:通过子查询关联门店表,将ID转换为中文名称 | |
| 142 | - ssmd = SqlFunc.Subqueryable<WtMdEntity>() | |
| 143 | - .Where(m => m.Id == it.Ssmd) | |
| 144 | - .Select(m => m.Mdmc), | |
| 145 | - }).MergeTable().OrderBy(sidx+" "+input.sort).ToListAsync(); | |
| 146 | - return data; | |
| 155 | + id = sk.Id, | |
| 156 | + skzhDictId = sk.Zhmc, | |
| 157 | + zhmc = SqlFunc.IsNull(SqlFunc.IsNull(acc.AccountName, dict.FullName), sk.Zhmc), | |
| 158 | + ssmd = md.Mdmc, | |
| 159 | + }) | |
| 160 | + .MergeTable() | |
| 161 | + .OrderBy(sidx + " " + sort) | |
| 162 | + .ToListAsync(); | |
| 163 | + return data; | |
| 147 | 164 | } |
| 148 | 165 | |
| 149 | 166 | /// <summary> | ... | ... |
Antis.Erp.Plat/netcore/src/Modularity/Extend/NCC.Extend/WtSpService.cs
| ... | ... | @@ -12,6 +12,7 @@ using Microsoft.AspNetCore.Mvc; |
| 12 | 12 | using SqlSugar; |
| 13 | 13 | using System; |
| 14 | 14 | using System.Collections.Generic; |
| 15 | +using System.Data; | |
| 15 | 16 | using System.Linq; |
| 16 | 17 | using System.Threading.Tasks; |
| 17 | 18 | using NCC.Extend.Entitys; |
| ... | ... | @@ -37,6 +38,7 @@ namespace NCC.Extend.WtSp |
| 37 | 38 | private readonly ISqlSugarRepository<WtSpEntity> _wtSpRepository; |
| 38 | 39 | private readonly SqlSugarScope _db; |
| 39 | 40 | private readonly IUserManager _userManager; |
| 41 | + private static bool _spCostCkMigrated; | |
| 40 | 42 | |
| 41 | 43 | /// <summary> |
| 42 | 44 | /// 初始化一个<see cref="WtSpService"/>类型的新实例 |
| ... | ... | @@ -61,23 +63,95 @@ namespace NCC.Extend.WtSp |
| 61 | 63 | } |
| 62 | 64 | |
| 63 | 65 | /// <summary> |
| 64 | - /// 解析门店下属仓库 ID(<c>F_ssmd</c> 为单 ID 或逗号分隔多门店时均匹配,与品类 FIND_IN_SET 口径一致)。 | |
| 66 | + /// 从门店名称得到用于匹配仓库名称(<c>F_mdmc</c>)的简称:去掉常见业态后缀,便于「景枫店」与「景枫仓」对齐。 | |
| 67 | + /// </summary> | |
| 68 | + private static string StoreNameToWarehouseStem(string mdmc) | |
| 69 | + { | |
| 70 | + if (string.IsNullOrWhiteSpace(mdmc)) return ""; | |
| 71 | + var s = mdmc.Trim(); | |
| 72 | + var suffixes = new[] | |
| 73 | + { | |
| 74 | + "旗舰店", "专卖店", "体验店", "直营店", "加盟店", "概念店", "快闪店", | |
| 75 | + "店", "厅", "馆", "部", "行", "中心", "超市", "商场", "广场" | |
| 76 | + }; | |
| 77 | + foreach (var suf in suffixes.OrderByDescending(x => x.Length)) | |
| 78 | + { | |
| 79 | + if (s.EndsWith(suf, StringComparison.Ordinal) && s.Length > suf.Length) | |
| 80 | + { | |
| 81 | + s = s.Substring(0, s.Length - suf.Length).Trim(); | |
| 82 | + break; | |
| 83 | + } | |
| 84 | + } | |
| 85 | + | |
| 86 | + return s; | |
| 87 | + } | |
| 88 | + | |
| 89 | + /// <summary> | |
| 90 | + /// 当 <c>wt_ck.F_ssmd</c> 未维护或与门店/分组不一致(历史删店、换主键)导致查不到仓库时, | |
| 91 | + /// 按门店名称前缀匹配 <c>F_mdmc</c>(<c>StartsWith</c> 简称)作为兜底,避免 <c>wt_sp_cost</c> 有数而列表 <c>mdkc</c> 恒为 0。 | |
| 92 | + /// </summary> | |
| 93 | + private async Task<List<string>> GetWarehouseIdsByStoreNameStemAsync(string storeId) | |
| 94 | + { | |
| 95 | + if (string.IsNullOrWhiteSpace(storeId)) return new List<string>(); | |
| 96 | + var mdmc = await _db.Queryable<WtMdEntity>() | |
| 97 | + .Where(m => m.Id == storeId) | |
| 98 | + .Select(m => m.Mdmc) | |
| 99 | + .FirstAsync(); | |
| 100 | + var stem = StoreNameToWarehouseStem(mdmc); | |
| 101 | + if (string.IsNullOrEmpty(stem) || stem.Length < 2) return new List<string>(); | |
| 102 | + | |
| 103 | + var ids = await _db.Queryable<WtCkEntity>() | |
| 104 | + .Where(c => c.Mdmc != null && c.Mdmc.StartsWith(stem)) | |
| 105 | + .Select(c => c.Id) | |
| 106 | + .ToListAsync(); | |
| 107 | + return ids | |
| 108 | + .Where(x => !string.IsNullOrWhiteSpace(x)) | |
| 109 | + .Select(x => x.Trim()) | |
| 110 | + .Distinct(StringComparer.OrdinalIgnoreCase) | |
| 111 | + .ToList(); | |
| 112 | + } | |
| 113 | + | |
| 114 | + /// <summary> | |
| 115 | + /// 解析门店下属仓库 ID(<c>F_ssmd</c> 为单 ID 或逗号分隔多值时均匹配)。 | |
| 116 | + /// 同时匹配<strong>门店主键</strong>与门店绑定的<strong>门店分组</strong>(<c>wt_md.F_MdfzId</c>): | |
| 117 | + /// 业务上仓库常挂在分组下,仅按门店 ID 查会漏库,导致 <c>wt_sp_cost</c> 汇总为 0。 | |
| 118 | + /// 若仍无结果,再按门店名称前缀匹配仓库名称(见 <see cref="GetWarehouseIdsByStoreNameStemAsync"/>)。 | |
| 65 | 119 | /// </summary> |
| 66 | 120 | private async Task<List<string>> GetWarehouseIdsForStoreAsync(string xsmd) |
| 67 | 121 | { |
| 68 | 122 | var sid = xsmd?.Trim(); |
| 69 | 123 | if (string.IsNullOrEmpty(sid)) return new List<string>(); |
| 124 | + var grp = await ResolveMdfzIdForStoreAsync(sid); | |
| 125 | + object pars; | |
| 126 | + string whereSql; | |
| 127 | + if (string.IsNullOrEmpty(grp)) | |
| 128 | + { | |
| 129 | + whereSql = "(`F_ssmd` = @sid OR FIND_IN_SET(@sid, `F_ssmd`) > 0)"; | |
| 130 | + pars = new { sid }; | |
| 131 | + } | |
| 132 | + else | |
| 133 | + { | |
| 134 | + whereSql = | |
| 135 | + "( (`F_ssmd` = @sid OR FIND_IN_SET(@sid, `F_ssmd`) > 0) OR " + | |
| 136 | + "(`F_ssmd` = @grp OR FIND_IN_SET(@grp, `F_ssmd`) > 0) )"; | |
| 137 | + pars = new { sid, grp }; | |
| 138 | + } | |
| 139 | + | |
| 70 | 140 | var ids = await _db.Queryable<WtCkEntity>() |
| 71 | - .Where("(`F_ssmd` = @sid OR FIND_IN_SET(@sid, `F_ssmd`) > 0)", new { sid }) | |
| 141 | + .Where(whereSql, pars) | |
| 72 | 142 | .Select(c => c.Id) |
| 73 | 143 | .ToListAsync(); |
| 74 | - return ids | |
| 144 | + var list = ids | |
| 75 | 145 | .Where(x => !string.IsNullOrWhiteSpace(x)) |
| 76 | 146 | .Select(x => x.Trim()) |
| 77 | 147 | .Distinct(StringComparer.OrdinalIgnoreCase) |
| 78 | 148 | .ToList(); |
| 149 | + if (list.Count > 0) return list; | |
| 150 | + | |
| 151 | + return await GetWarehouseIdsByStoreNameStemAsync(sid); | |
| 79 | 152 | } |
| 80 | 153 | |
| 154 | + | |
| 81 | 155 | /// <summary> |
| 82 | 156 | /// 当前门店所属分组 ID(<c>wt_md.F_MdfzId</c>);非门店主键或未绑定时返回 null。 |
| 83 | 157 | /// </summary> |
| ... | ... | @@ -168,48 +242,90 @@ namespace NCC.Extend.WtSp |
| 168 | 242 | } |
| 169 | 243 | |
| 170 | 244 | /// <summary> |
| 171 | - /// 按门店写入列表行的 <see cref="WtSpListOutput.mdkc"/>:与商品库存汇总一致,仅按 <c>wt_sp_cost.sl</c> 汇总(不按序列号条数;无成本行则为 0)。 | |
| 245 | + /// 在指定门店/分组上下文下,按 <c>wt_sp_cost</c> 汇总各商品 <c>sl</c>(与列表 <c>mdkc</c>、<c>BatchCheckStock</c> 一致)。 | |
| 246 | + /// <c>wt_sp_cost.ck</c> 统一存仓库 ID(<c>MigrateSpCostCkToWarehouseId</c> 保证)。 | |
| 247 | + /// 已解析出下属仓库时先只计仓库维度;仅当某商品在下属仓库合计为 0 时再回退 <c>ck=门店主键</c>,避免与误存门店行重复加计。 | |
| 172 | 248 | /// </summary> |
| 173 | - private async Task ApplyMdkcBySerialAsync(List<WtSpListOutput> resultList, string xsmd) | |
| 249 | + private async Task<Dictionary<string, int>> SumSpCostSlForStoreContextAsync(List<string> productIds, string storeIdTrimmed) | |
| 174 | 250 | { |
| 175 | - if (resultList == null || resultList.Count == 0) return; | |
| 251 | + var costDict = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase); | |
| 252 | + if (productIds == null || productIds.Count == 0 || string.IsNullOrEmpty(storeIdTrimmed)) | |
| 253 | + return costDict; | |
| 176 | 254 | |
| 177 | - var productIds = resultList.Select(p => p.id).Distinct().ToList(); | |
| 178 | - var storeId = xsmd?.Trim(); | |
| 255 | + var storeId = storeIdTrimmed.Trim(); | |
| 256 | + var warehouseIds = await GetWarehouseIdsForStoreAsync(storeId); | |
| 179 | 257 | |
| 180 | - List<string> warehouseIds = null; | |
| 181 | - if (!string.IsNullOrEmpty(storeId)) | |
| 258 | + if (warehouseIds != null && warehouseIds.Count > 0) | |
| 182 | 259 | { |
| 183 | - warehouseIds = await GetWarehouseIdsForStoreAsync(storeId); | |
| 184 | - if (warehouseIds.Count == 0) | |
| 260 | + var whSet = new HashSet<string>( | |
| 261 | + warehouseIds.Where(x => !string.IsNullOrWhiteSpace(x)).Select(x => x.Trim()), | |
| 262 | + StringComparer.OrdinalIgnoreCase); | |
| 263 | + var sumsWh = await _db.Queryable<WtSpCostEntity>() | |
| 264 | + .Where(c => productIds.Contains(c.Spbh) && c.Ck != null && whSet.Contains(c.Ck.Trim())) | |
| 265 | + .GroupBy(c => c.Spbh) | |
| 266 | + .Select(c => new { Spbh = c.Spbh, SumSl = SqlFunc.AggregateSum(c.Sl) }) | |
| 267 | + .ToListAsync(); | |
| 268 | + foreach (var row in sumsWh) | |
| 269 | + costDict[row.Spbh] = (int)(row.SumSl); | |
| 270 | + | |
| 271 | + var needStoreCk = productIds | |
| 272 | + .Where(pid => | |
| 273 | + { | |
| 274 | + var key = pid?.Trim(); | |
| 275 | + if (string.IsNullOrEmpty(key)) return false; | |
| 276 | + return !costDict.TryGetValue(key, out var n) || n == 0; | |
| 277 | + }) | |
| 278 | + .ToList(); | |
| 279 | + if (needStoreCk.Count > 0) | |
| 185 | 280 | { |
| 186 | - foreach (var item in resultList) | |
| 187 | - item.mdkc = "0"; | |
| 188 | - return; | |
| 281 | + var sumsStore = await _db.Queryable<WtSpCostEntity>() | |
| 282 | + .Where(c => needStoreCk.Contains(c.Spbh) && c.Ck == storeId) | |
| 283 | + .GroupBy(c => c.Spbh) | |
| 284 | + .Select(c => new { Spbh = c.Spbh, SumSl = SqlFunc.AggregateSum(c.Sl) }) | |
| 285 | + .ToListAsync(); | |
| 286 | + foreach (var row in sumsStore) | |
| 287 | + costDict[row.Spbh] = (int)(row.SumSl); | |
| 189 | 288 | } |
| 190 | 289 | } |
| 191 | - | |
| 192 | - var costDict = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase); | |
| 193 | - if (warehouseIds == null) | |
| 290 | + else | |
| 194 | 291 | { |
| 195 | 292 | var sums = await _db.Queryable<WtSpCostEntity>() |
| 196 | - .Where(c => productIds.Contains(c.Spbh)) | |
| 293 | + .Where(c => productIds.Contains(c.Spbh) && c.Ck == storeId) | |
| 197 | 294 | .GroupBy(c => c.Spbh) |
| 198 | 295 | .Select(c => new { Spbh = c.Spbh, SumSl = SqlFunc.AggregateSum(c.Sl) }) |
| 199 | 296 | .ToListAsync(); |
| 200 | 297 | foreach (var row in sums) |
| 201 | 298 | costDict[row.Spbh] = (int)(row.SumSl); |
| 202 | 299 | } |
| 203 | - else | |
| 300 | + | |
| 301 | + return costDict; | |
| 302 | + } | |
| 303 | + | |
| 304 | + /// <summary> | |
| 305 | + /// 按门店写入列表行的 <see cref="WtSpListOutput.mdkc"/>:与库存汇总一致,按 <c>wt_sp_cost.sl</c> 汇总(<strong>不是</strong>按序列号条数;方法名历史遗留)。 | |
| 306 | + /// 口径:<c>ck</c> 为仓库主键时须落在门店下属 <c>wt_ck</c>;兼容 <c>ck</c> 误存为<strong>门店主键</strong>的旧数据;未配置门店仓库时不再整表置 0,改为仅按 <c>ck=门店Id</c> 汇总。 | |
| 307 | + /// </summary> | |
| 308 | + private async Task ApplyMdkcBySerialAsync(List<WtSpListOutput> resultList, string xsmd) | |
| 309 | + { | |
| 310 | + if (resultList == null || resultList.Count == 0) return; | |
| 311 | + | |
| 312 | + var productIds = resultList.Select(p => p.id).Distinct().ToList(); | |
| 313 | + var storeId = xsmd?.Trim(); | |
| 314 | + | |
| 315 | + Dictionary<string, int> costDict; | |
| 316 | + if (string.IsNullOrEmpty(storeId)) | |
| 204 | 317 | { |
| 318 | + costDict = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase); | |
| 205 | 319 | var sums = await _db.Queryable<WtSpCostEntity>() |
| 206 | - .Where(c => productIds.Contains(c.Spbh) && warehouseIds.Contains(c.Ck)) | |
| 320 | + .Where(c => productIds.Contains(c.Spbh)) | |
| 207 | 321 | .GroupBy(c => c.Spbh) |
| 208 | 322 | .Select(c => new { Spbh = c.Spbh, SumSl = SqlFunc.AggregateSum(c.Sl) }) |
| 209 | 323 | .ToListAsync(); |
| 210 | 324 | foreach (var row in sums) |
| 211 | 325 | costDict[row.Spbh] = (int)(row.SumSl); |
| 212 | 326 | } |
| 327 | + else | |
| 328 | + costDict = await SumSpCostSlForStoreContextAsync(productIds, storeId); | |
| 213 | 329 | |
| 214 | 330 | foreach (var item in resultList) |
| 215 | 331 | item.mdkc = costDict.TryGetValue(item.id, out var csum) ? csum.ToString() : "0"; |
| ... | ... | @@ -297,6 +413,48 @@ namespace NCC.Extend.WtSp |
| 297 | 413 | } |
| 298 | 414 | |
| 299 | 415 | /// <summary> |
| 416 | + /// 一次性修复 wt_sp_cost 历史数据:ck 存仓库名称的改为仓库 ID;F_Id 为「商品_仓库」等非雪花主键的改为 YitId。 | |
| 417 | + /// </summary> | |
| 418 | + private void MigrateSpCostCkToWarehouseId() | |
| 419 | + { | |
| 420 | + if (_spCostCkMigrated) return; | |
| 421 | + lock (typeof(WtSpService)) | |
| 422 | + { | |
| 423 | + if (_spCostCkMigrated) return; | |
| 424 | + try | |
| 425 | + { | |
| 426 | + var affected = _db.Ado.ExecuteCommand( | |
| 427 | + @"UPDATE wt_sp_cost sc | |
| 428 | + INNER JOIN wt_ck ck ON ck.F_mdmc = sc.ck | |
| 429 | + LEFT JOIN wt_ck ck2 ON ck2.F_Id = sc.ck | |
| 430 | + SET sc.ck = ck.F_Id | |
| 431 | + WHERE ck2.F_Id IS NULL"); | |
| 432 | + if (affected > 0) | |
| 433 | + Console.WriteLine($"✅ wt_sp_cost.ck 数据修复:{affected} 行由仓库名称改为仓库 ID"); | |
| 434 | + | |
| 435 | + var dt = _db.Ado.GetDataTable("SELECT F_Id FROM wt_sp_cost WHERE F_Id REGEXP '[^0-9]'"); | |
| 436 | + if (dt != null && dt.Rows.Count > 0) | |
| 437 | + { | |
| 438 | + var fidFixed = 0; | |
| 439 | + foreach (DataRow dr in dt.Rows) | |
| 440 | + { | |
| 441 | + var oldId = dr["F_Id"]?.ToString()?.Trim(); | |
| 442 | + if (string.IsNullOrEmpty(oldId)) continue; | |
| 443 | + var newId = YitIdHelper.NextId().ToString(); | |
| 444 | + fidFixed += _db.Ado.ExecuteCommand( | |
| 445 | + "UPDATE wt_sp_cost SET F_Id = @newId WHERE F_Id = @oldId", | |
| 446 | + new SugarParameter("@newId", newId), new SugarParameter("@oldId", oldId)); | |
| 447 | + } | |
| 448 | + if (fidFixed > 0) | |
| 449 | + Console.WriteLine($"✅ wt_sp_cost.F_Id 数据修复:{fidFixed} 行由复合键改为雪花 ID"); | |
| 450 | + } | |
| 451 | + } | |
| 452 | + catch (Exception ex) { Console.WriteLine($"⚠️ MigrateSpCostCkToWarehouseId: {ex.Message}"); } | |
| 453 | + _spCostCkMigrated = true; | |
| 454 | + } | |
| 455 | + } | |
| 456 | + | |
| 457 | + /// <summary> | |
| 300 | 458 | /// 获取商品档案列表 |
| 301 | 459 | /// </summary> |
| 302 | 460 | /// <param name="input">请求参数</param> |
| ... | ... | @@ -304,6 +462,7 @@ namespace NCC.Extend.WtSp |
| 304 | 462 | [HttpGet("")] |
| 305 | 463 | public async Task<dynamic> GetList([FromQuery] WtSpListQueryInput input) |
| 306 | 464 | { |
| 465 | + MigrateSpCostCkToWarehouseId(); | |
| 307 | 466 | Console.WriteLine("=== GetList方法开始执行 ==="); |
| 308 | 467 | Console.WriteLine($"输入参数: spmc={input.spmc}, spbm={input.spbm}, xsmd={input.xsmd}"); |
| 309 | 468 | |
| ... | ... | @@ -398,7 +557,12 @@ namespace NCC.Extend.WtSp |
| 398 | 557 | |
| 399 | 558 | |
| 400 | 559 | var qk0 = WherePlCategoryIfAny(_db.Queryable<WtSpEntity>() |
| 401 | - .WhereIF(!string.IsNullOrEmpty(input.keyword), p => p.Spmc.Contains(input.keyword)||p.Spbm.Contains(input.keyword)||p.Dyspid.Contains(input.keyword)), input.pl); | |
| 560 | + .WhereIF( | |
| 561 | + !string.IsNullOrEmpty(input.keyword), | |
| 562 | + p => p.Spmc.Contains(input.keyword) | |
| 563 | + || p.Spbm.Contains(input.keyword) | |
| 564 | + || (!SqlFunc.IsNullOrEmpty(p.Dyspid) && p.Dyspid.Contains(input.keyword))), | |
| 565 | + input.pl); | |
| 402 | 566 | var qk1 = await ApplyXsmdFilterAsync(qk0, input.xsmd); |
| 403 | 567 | var data = await qk1 |
| 404 | 568 | .Select(it=> new WtSpListOutput |
| ... | ... | @@ -882,10 +1046,6 @@ namespace NCC.Extend.WtSp |
| 882 | 1046 | try |
| 883 | 1047 | { |
| 884 | 1048 | var storeId = input.StoreId.Trim(); |
| 885 | - var warehouseIds = await GetWarehouseIdsForStoreAsync(storeId); | |
| 886 | - | |
| 887 | - if (warehouseIds == null || warehouseIds.Count == 0) | |
| 888 | - return new { success = false, msg = "该门店下没有关联的仓库" }; | |
| 889 | 1049 | |
| 890 | 1050 | var spbmList = input.Items.Select(i => i.Spbm).Where(s => !string.IsNullOrEmpty(s)).Distinct().ToList(); |
| 891 | 1051 | |
| ... | ... | @@ -896,13 +1056,7 @@ namespace NCC.Extend.WtSp |
| 896 | 1056 | |
| 897 | 1057 | var productIds = products.Select(p => p.Id).ToList(); |
| 898 | 1058 | |
| 899 | - var costSums = await _db.Queryable<WtSpCostEntity>() | |
| 900 | - .Where(c => productIds.Contains(c.Spbh) && warehouseIds.Contains(c.Ck)) | |
| 901 | - .GroupBy(c => c.Spbh) | |
| 902 | - .Select(c => new { Spbh = c.Spbh, SumSl = SqlFunc.AggregateSum(c.Sl) }) | |
| 903 | - .ToListAsync(); | |
| 904 | - | |
| 905 | - var stockDict = costSums.ToDictionary(x => x.Spbh, x => (int)(x.SumSl)); | |
| 1059 | + var stockDict = await SumSpCostSlForStoreContextAsync(productIds, storeId); | |
| 906 | 1060 | |
| 907 | 1061 | var results = input.Items.Select(item => |
| 908 | 1062 | { | ... | ... |
Antis.Erp.Plat/netcore/src/Modularity/Extend/NCC.Extend/WtXlhService.cs
| ... | ... | @@ -49,6 +49,46 @@ namespace NCC.Extend.WtXlh |
| 49 | 49 | } |
| 50 | 50 | |
| 51 | 51 | /// <summary> |
| 52 | + /// 按完整序列号查询关联单据流水(出货、退货等),按单据日期升序,便于查看单条序列号全链路。 | |
| 53 | + /// </summary> | |
| 54 | + /// <param name="xlh">完整序列号(精确匹配,区分大小写与数据库一致)</param> | |
| 55 | + /// <param name="currentPage">页码</param> | |
| 56 | + /// <param name="pageSize">每页条数,最大 200</param> | |
| 57 | + [HttpGet("SerialTrace")] | |
| 58 | + public async Task<dynamic> GetSerialTrace([FromQuery] string xlh, [FromQuery] int currentPage = 1, [FromQuery] int pageSize = 100) | |
| 59 | + { | |
| 60 | + var key = xlh?.Trim(); | |
| 61 | + if (string.IsNullOrEmpty(key)) | |
| 62 | + throw NCCException.Bah("请输入序列号"); | |
| 63 | + | |
| 64 | + if (currentPage < 1) currentPage = 1; | |
| 65 | + if (pageSize < 1) pageSize = 20; | |
| 66 | + if (pageSize > 200) pageSize = 200; | |
| 67 | + | |
| 68 | + var querySql = _db.Queryable<WtXlhEntity, WtSpEntity, WtXsckdEntity>((it, sp, xs) => it.Spbh == sp.Id && it.Djbh == xs.Id) | |
| 69 | + .Where((it, sp, xs) => it.Xlh == key); | |
| 70 | + | |
| 71 | + var data = await querySql | |
| 72 | + .Select((it, sp, xs) => new WtXlhListOutput | |
| 73 | + { | |
| 74 | + id = it.Id, | |
| 75 | + xlh = it.Xlh, | |
| 76 | + spbh = it.Spbh, | |
| 77 | + djbh = it.Djbh, | |
| 78 | + djlx = it.Djlx, | |
| 79 | + zt = it.Zt, | |
| 80 | + spmc = sp.Spmc, | |
| 81 | + djrq = SqlFunc.ToDate(xs.Djrq), | |
| 82 | + pp = SqlFunc.Subqueryable<WtPpEntity>().Where(u => u.Id == sp.Pp).Select(u => u.Ppmc) | |
| 83 | + }) | |
| 84 | + .MergeTable() | |
| 85 | + .OrderBy("djrq asc") | |
| 86 | + .ToPagedListAsync(currentPage, pageSize); | |
| 87 | + | |
| 88 | + return PageResult<WtXlhListOutput>.SqlSugarPageResult(data); | |
| 89 | + } | |
| 90 | + | |
| 91 | + /// <summary> | |
| 52 | 92 | /// 获取序列号管理 |
| 53 | 93 | /// </summary> |
| 54 | 94 | /// <param name="id">参数</param> |
| ... | ... | @@ -76,8 +116,7 @@ namespace NCC.Extend.WtXlh |
| 76 | 116 | .WhereIF(!string.IsNullOrEmpty(input.djbh), it => it.Djbh.Contains(input.djbh)) |
| 77 | 117 | .WhereIF(!string.IsNullOrEmpty(input.djlx), it => it.Djlx.Contains(input.djlx)) |
| 78 | 118 | .WhereIF(!string.IsNullOrEmpty(input.zt), it => it.Zt.Contains(input.zt)); |
| 79 | - Console.WriteLine(query_sql.ToSql()); | |
| 80 | - | |
| 119 | + | |
| 81 | 120 | var data =await query_sql.Select((it,sp,xs)=> new WtXlhListOutput |
| 82 | 121 | { |
| 83 | 122 | id = it.Id, | ... | ... |
Antis.Erp.Plat/netcore/src/Modularity/Extend/NCC.Extend/WtXsckdService.cs
| ... | ... | @@ -12,6 +12,7 @@ using Microsoft.AspNetCore.Authorization; |
| 12 | 12 | using SqlSugar; |
| 13 | 13 | using System; |
| 14 | 14 | using System.Collections.Generic; |
| 15 | +using System.Data; | |
| 15 | 16 | using System.Linq; |
| 16 | 17 | using System.Text.RegularExpressions; |
| 17 | 18 | using System.Threading; |
| ... | ... | @@ -60,6 +61,52 @@ namespace NCC.Extend.WtXsckd |
| 60 | 61 | private static bool _bjhcbColumnChecked; |
| 61 | 62 | private static bool _fkmxColumnChecked; |
| 62 | 63 | private static bool _syPchColumnChecked; |
| 64 | + private static bool _spCostCkMigrated; | |
| 65 | + | |
| 66 | + /// <summary> | |
| 67 | + /// 一次性修复 wt_sp_cost 历史数据:ck 存仓库名称的改为仓库 ID;F_Id 为「商品_仓库」等非雪花主键的改为 YitId。 | |
| 68 | + /// </summary> | |
| 69 | + private void MigrateSpCostCkToWarehouseId() | |
| 70 | + { | |
| 71 | + if (_spCostCkMigrated) return; | |
| 72 | + lock (typeof(WtXsckdService)) | |
| 73 | + { | |
| 74 | + if (_spCostCkMigrated) return; | |
| 75 | + try | |
| 76 | + { | |
| 77 | + var affected = _db.Ado.ExecuteCommand( | |
| 78 | + @"UPDATE wt_sp_cost sc | |
| 79 | + INNER JOIN wt_ck ck ON ck.F_mdmc = sc.ck | |
| 80 | + LEFT JOIN wt_ck ck2 ON ck2.F_Id = sc.ck | |
| 81 | + SET sc.ck = ck.F_Id | |
| 82 | + WHERE ck2.F_Id IS NULL"); | |
| 83 | + if (affected > 0) | |
| 84 | + Console.WriteLine($"✅ wt_sp_cost.ck 数据修复:{affected} 行由仓库名称改为仓库 ID"); | |
| 85 | + | |
| 86 | + var dt = _db.Ado.GetDataTable("SELECT F_Id FROM wt_sp_cost WHERE F_Id REGEXP '[^0-9]'"); | |
| 87 | + if (dt != null && dt.Rows.Count > 0) | |
| 88 | + { | |
| 89 | + var fidFixed = 0; | |
| 90 | + foreach (DataRow dr in dt.Rows) | |
| 91 | + { | |
| 92 | + var oldId = dr["F_Id"]?.ToString()?.Trim(); | |
| 93 | + if (string.IsNullOrEmpty(oldId)) continue; | |
| 94 | + var newId = YitIdHelper.NextId().ToString(); | |
| 95 | + fidFixed += _db.Ado.ExecuteCommand( | |
| 96 | + "UPDATE wt_sp_cost SET F_Id = @newId WHERE F_Id = @oldId", | |
| 97 | + new SugarParameter("@newId", newId), new SugarParameter("@oldId", oldId)); | |
| 98 | + } | |
| 99 | + if (fidFixed > 0) | |
| 100 | + Console.WriteLine($"✅ wt_sp_cost.F_Id 数据修复:{fidFixed} 行由复合键改为雪花 ID"); | |
| 101 | + } | |
| 102 | + } | |
| 103 | + catch (Exception ex) | |
| 104 | + { | |
| 105 | + Console.WriteLine($"⚠️ MigrateSpCostCkToWarehouseId: {ex.Message}"); | |
| 106 | + } | |
| 107 | + _spCostCkMigrated = true; | |
| 108 | + } | |
| 109 | + } | |
| 63 | 110 | |
| 64 | 111 | /// <summary> |
| 65 | 112 | /// 确保收银批次号列存在(同一次结账拆单关联) |
| ... | ... | @@ -377,6 +424,131 @@ namespace NCC.Extend.WtXsckd |
| 377 | 424 | } |
| 378 | 425 | |
| 379 | 426 | /// <summary> |
| 427 | + /// 删除销售类出库单(销售出库单/零售单/预售出库单)时冲回创建时产生的会员消费送积分、积分抵扣、余额支付; | |
| 428 | + /// 同时删除导购提成记录(wt_dgtchsb)。与 Create 中写入逻辑对称。 | |
| 429 | + /// </summary> | |
| 430 | + private async Task TryReverseSalesOutboundMemberAndCommissionAsync(WtXsckdEntity entity, string reasonTag = "删除单据") | |
| 431 | + { | |
| 432 | + if (entity == null) return; | |
| 433 | + if (entity.Djlx != "销售出库单" && entity.Djlx != "零售单" && entity.Djlx != "预售出库单") return; | |
| 434 | + | |
| 435 | + // 导购提成(与 Update 中先删除再重建逻辑一致) | |
| 436 | + try | |
| 437 | + { | |
| 438 | + if (entity.Djlx == "销售出库单" || entity.Djlx == "零售单") | |
| 439 | + { | |
| 440 | + await _db.Deleteable<WtDgtchsbEntity>().Where(t => t.Djbh == entity.Id).ExecuteCommandAsync(); | |
| 441 | + Console.WriteLine($"✅ {reasonTag}删除导购提成: 单{entity.Id}"); | |
| 442 | + } | |
| 443 | + } | |
| 444 | + catch (Exception ex) | |
| 445 | + { | |
| 446 | + Console.WriteLine($"⚠️ {reasonTag}删除导购提成失败(不影响删除): {ex.Message}"); | |
| 447 | + } | |
| 448 | + | |
| 449 | + if (string.IsNullOrEmpty(entity.Kh)) return; | |
| 450 | + | |
| 451 | + try | |
| 452 | + { | |
| 453 | + // 冲回消费送积分 | |
| 454 | + if (entity.Skje > 0) | |
| 455 | + { | |
| 456 | + var points = (int)Math.Floor(entity.Skje); | |
| 457 | + if (points > 0) | |
| 458 | + { | |
| 459 | + await _db.Insertable(new WtHyJfEntity | |
| 460 | + { | |
| 461 | + Id = YitIdHelper.NextId().ToString(), | |
| 462 | + Jfgz = $"{reasonTag}冲回消费送积分", | |
| 463 | + Jfyxq = 0, | |
| 464 | + Jf = (-points).ToString(), | |
| 465 | + JfUserId = entity.Kh, | |
| 466 | + Jfsj = DateTime.Now | |
| 467 | + }).ExecuteCommandAsync(); | |
| 468 | + Console.WriteLine($"✅ {reasonTag}冲回消费送积分: 会员{entity.Kh}, -{points}积分"); | |
| 469 | + } | |
| 470 | + } | |
| 471 | + | |
| 472 | + // 退回积分抵扣 | |
| 473 | + var pointsDeductYuan = ParsePointsDeductYuanFromFkmxSkmx(entity.Fkmx, entity.Skmx); | |
| 474 | + if (pointsDeductYuan > 0) | |
| 475 | + { | |
| 476 | + var pointsToReturn = (int)Math.Ceiling(pointsDeductYuan * 100m); | |
| 477 | + await _db.Insertable(new WtHyJfEntity | |
| 478 | + { | |
| 479 | + Id = YitIdHelper.NextId().ToString(), | |
| 480 | + Jfgz = $"{reasonTag}退回积分抵扣", | |
| 481 | + Jfyxq = 0, | |
| 482 | + Jf = pointsToReturn.ToString(), | |
| 483 | + JfUserId = entity.Kh, | |
| 484 | + Jfsj = DateTime.Now | |
| 485 | + }).ExecuteCommandAsync(); | |
| 486 | + Console.WriteLine($"✅ {reasonTag}退回积分抵扣: 会员{entity.Kh}, +{pointsToReturn}积分"); | |
| 487 | + } | |
| 488 | + | |
| 489 | + // 退回余额支付 | |
| 490 | + var balYuan = ParseBalanceConsumeYuanFromFkmxSkmx(entity.Fkmx, entity.Skmx); | |
| 491 | + if (balYuan > 0) | |
| 492 | + { | |
| 493 | + await InsertMemberBalanceLedgerAsync(entity.Kh, -balYuan, | |
| 494 | + $"{entity.Djlx}{entity.Id}{reasonTag}退回余额支付"); | |
| 495 | + Console.WriteLine($"✅ {reasonTag}退回余额支付: 会员{entity.Kh}, ¥{balYuan}"); | |
| 496 | + } | |
| 497 | + } | |
| 498 | + catch (Exception ex) | |
| 499 | + { | |
| 500 | + Console.WriteLine($"⚠️ {reasonTag}冲回会员影响失败(不影响删除): {ex.Message}"); | |
| 501 | + } | |
| 502 | + } | |
| 503 | + | |
| 504 | + /// <summary> | |
| 505 | + /// 删除退货单(销售退货单/预售退货单/委托代销退货单)时,将创建时恢复为在库的序列号还原为已售出状态。 | |
| 506 | + /// 利用 wt_xlh 中 zt="退货入库" 的跟踪记录定位被恢复的序列号(须在 DeleteWtXlhTrackingForDocumentAsync 之前调用)。 | |
| 507 | + /// 与 ApplySalesReturnSerialRestoreForEntityAsync 对称。 | |
| 508 | + /// </summary> | |
| 509 | + private async Task RevertSerialNumbersForDeletedReturnAsync(WtXsckdEntity returnEntity) | |
| 510 | + { | |
| 511 | + if (returnEntity == null) return; | |
| 512 | + if (returnEntity.Djlx != "销售退货单" && returnEntity.Djlx != "预售退货单" | |
| 513 | + && !returnEntity.Djlx.Contains("委托代销退货单")) return; | |
| 514 | + | |
| 515 | + var origId = returnEntity.Ycddh; | |
| 516 | + if (string.IsNullOrEmpty(origId)) | |
| 517 | + origId = TryParseYcddhFromRemark(returnEntity.Bz); | |
| 518 | + | |
| 519 | + // 从 wt_xlh 找到本退货单「退货入库」的序列号列表 | |
| 520 | + var xlhRecords = await _db.Queryable<WtXlhEntity>() | |
| 521 | + .Where(x => x.Djbh == returnEntity.Id && x.Zt == "退货入库") | |
| 522 | + .Select(x => new { x.Xlh, x.Spbh }) | |
| 523 | + .ToListAsync(); | |
| 524 | + | |
| 525 | + if (xlhRecords == null || xlhRecords.Count == 0) return; | |
| 526 | + | |
| 527 | + var serialNumbers = xlhRecords | |
| 528 | + .Where(x => !string.IsNullOrWhiteSpace(x.Xlh)) | |
| 529 | + .Select(x => x.Xlh.Trim()) | |
| 530 | + .Distinct(StringComparer.OrdinalIgnoreCase) | |
| 531 | + .ToList(); | |
| 532 | + | |
| 533 | + if (serialNumbers.Count == 0) return; | |
| 534 | + | |
| 535 | + // 将这些序列号还原为已售出状态(OutDjbh 指回原出库单,与出库时写入一致) | |
| 536 | + await _db.Updateable<WtSerialNumberEntity>() | |
| 537 | + .SetColumns(it => new WtSerialNumberEntity | |
| 538 | + { | |
| 539 | + Status = 1, | |
| 540 | + OutDjbh = origId ?? "", | |
| 541 | + OutDjlx = returnEntity.Djlx == "销售退货单" ? "销售出库单" | |
| 542 | + : (returnEntity.Djlx == "预售退货单" ? "预售出库单" : "委托代销发货单"), | |
| 543 | + OutTime = DateTime.Now | |
| 544 | + }) | |
| 545 | + .Where(it => serialNumbers.Contains(it.SerialNumber) && it.Status == 0) | |
| 546 | + .ExecuteCommandAsync(); | |
| 547 | + | |
| 548 | + Console.WriteLine($"✅ 删除退货单{returnEntity.Id}:已将 {serialNumbers.Count} 条序列号还原为已售出(原单{origId})"); | |
| 549 | + } | |
| 550 | + | |
| 551 | + /// <summary> | |
| 380 | 552 | /// 确保原价金额列存在(迁移) |
| 381 | 553 | /// </summary> |
| 382 | 554 | private void EnsureYdjeColumn() |
| ... | ... | @@ -591,6 +763,200 @@ namespace NCC.Extend.WtXsckd |
| 591 | 763 | } |
| 592 | 764 | |
| 593 | 765 | /// <summary> |
| 766 | + /// 将门店主键或仓库主键展开为仓库 ID 列表,用于 <c>wt_sp_cost</c> / <c>wt_serial_number</c> 操作。 | |
| 767 | + /// 与 <c>WtSpService.GetWarehouseIdsForStoreAsync</c> 保持一致的解析口径: | |
| 768 | + /// 支持 <c>FIND_IN_SET</c>(逗号分隔的 <c>F_ssmd</c>)与门店分组 <c>F_MdfzId</c>。 | |
| 769 | + /// </summary> | |
| 770 | + private async Task<List<string>> ResolveWarehouseIdsForSpCostFromStoreOrCkAsync(string storeOrWarehouseId) | |
| 771 | + { | |
| 772 | + if (string.IsNullOrWhiteSpace(storeOrWarehouseId)) return new List<string>(); | |
| 773 | + var raw = storeOrWarehouseId.Trim(); | |
| 774 | + | |
| 775 | + string grp = null; | |
| 776 | + var mdRow = await _db.Queryable<WtMdEntity>() | |
| 777 | + .Where(m => m.Id == raw) | |
| 778 | + .Select(m => new { m.MdfzId }) | |
| 779 | + .FirstAsync(); | |
| 780 | + if (mdRow != null) grp = mdRow?.MdfzId; | |
| 781 | + | |
| 782 | + List<string> ids; | |
| 783 | + if (!string.IsNullOrEmpty(grp)) | |
| 784 | + { | |
| 785 | + ids = await _db.Ado.SqlQueryAsync<string>( | |
| 786 | + "SELECT F_Id FROM wt_ck WHERE F_Id = @sid " + | |
| 787 | + "OR (`F_ssmd` = @sid OR FIND_IN_SET(@sid, `F_ssmd`) > 0) " + | |
| 788 | + "OR (`F_ssmd` = @grp OR FIND_IN_SET(@grp, `F_ssmd`) > 0)", | |
| 789 | + new { sid = raw, grp }); | |
| 790 | + } | |
| 791 | + else | |
| 792 | + { | |
| 793 | + ids = await _db.Ado.SqlQueryAsync<string>( | |
| 794 | + "SELECT F_Id FROM wt_ck WHERE F_Id = @sid " + | |
| 795 | + "OR `F_ssmd` = @sid OR FIND_IN_SET(@sid, `F_ssmd`) > 0", | |
| 796 | + new { sid = raw }); | |
| 797 | + } | |
| 798 | + | |
| 799 | + var list = ids? | |
| 800 | + .Where(x => !string.IsNullOrWhiteSpace(x)) | |
| 801 | + .Select(x => x.Trim()) | |
| 802 | + .Distinct(StringComparer.OrdinalIgnoreCase) | |
| 803 | + .ToList() ?? new List<string>(); | |
| 804 | + if (list.Count > 0) return list; | |
| 805 | + | |
| 806 | + var wid = await ResolveWarehouseIdForSerialAsync(raw); | |
| 807 | + return string.IsNullOrWhiteSpace(wid) ? new List<string>() : new List<string> { wid.Trim() }; | |
| 808 | + } | |
| 809 | + | |
| 810 | + /// <summary> | |
| 811 | + /// 删除与某出库单关联的 <c>wt_xlh</c> 跟踪行(删单或反审恢复序列号前调用,避免列表残留)。 | |
| 812 | + /// </summary> | |
| 813 | + private async Task DeleteWtXlhTrackingForDocumentAsync(string djbh) | |
| 814 | + { | |
| 815 | + if (string.IsNullOrWhiteSpace(djbh)) return; | |
| 816 | + await _db.Deleteable<WtXlhEntity>().Where(x => x.Djbh == djbh).ExecuteCommandAsync(); | |
| 817 | + } | |
| 818 | + | |
| 819 | + /// <summary> | |
| 820 | + /// 向 <c>wt_xlh</c> 写入跟踪行(出货、退货等);同一 <c>djbh + xlh</c> 已存在则跳过,可重复调用。 | |
| 821 | + /// </summary> | |
| 822 | + private async Task InsertWtXlhDistinctAsync(string djbh, string djlx, string spbh, IEnumerable<string> xlhs, string zt) | |
| 823 | + { | |
| 824 | + if (string.IsNullOrWhiteSpace(djbh) || string.IsNullOrWhiteSpace(spbh)) return; | |
| 825 | + if (string.IsNullOrWhiteSpace(zt)) zt = "已出库"; | |
| 826 | + var list = xlhs? | |
| 827 | + .Where(s => !string.IsNullOrWhiteSpace(s)) | |
| 828 | + .Select(s => s.Trim()) | |
| 829 | + .Distinct(StringComparer.OrdinalIgnoreCase) | |
| 830 | + .ToList() ?? new List<string>(); | |
| 831 | + if (list.Count == 0) return; | |
| 832 | + | |
| 833 | + var existing = await _db.Queryable<WtXlhEntity>() | |
| 834 | + .Where(x => x.Djbh == djbh && list.Contains(x.Xlh)) | |
| 835 | + .Select(x => x.Xlh) | |
| 836 | + .ToListAsync(); | |
| 837 | + var existingSet = new HashSet<string>( | |
| 838 | + existing.Where(x => !string.IsNullOrWhiteSpace(x)).Select(x => x.Trim()), | |
| 839 | + StringComparer.OrdinalIgnoreCase); | |
| 840 | + var toAdd = list.Where(x => !existingSet.Contains(x)).ToList(); | |
| 841 | + if (toAdd.Count == 0) return; | |
| 842 | + | |
| 843 | + var rows = toAdd.Select(xlh => new WtXlhEntity | |
| 844 | + { | |
| 845 | + Id = YitIdHelper.NextId().ToString(), | |
| 846 | + Xlh = xlh, | |
| 847 | + Spbh = spbh, | |
| 848 | + Djbh = djbh, | |
| 849 | + Djlx = djlx ?? "", | |
| 850 | + Zt = zt | |
| 851 | + }).ToList(); | |
| 852 | + await _db.Insertable(rows).ExecuteCommandAsync(); | |
| 853 | + } | |
| 854 | + | |
| 855 | + /// <summary> | |
| 856 | + /// 根据 <c>wt_serial_number</c> 中已出库(<c>status=1</c> 且 <c>out_djbh</c> 为本单)的记录,补全 <c>wt_xlh</c> 序列号跟踪表, | |
| 857 | + /// 与 <see cref="WtXlhService"/> 列表(联查 <c>wt_xsckd</c>)一致;幂等,已存在同单同序列号则跳过。 | |
| 858 | + /// </summary> | |
| 859 | + private async Task SyncWtXlhOutboundFromSerialTableAsync(string djbh, string djlx, string spbh) | |
| 860 | + { | |
| 861 | + if (string.IsNullOrWhiteSpace(djbh) || string.IsNullOrWhiteSpace(spbh)) return; | |
| 862 | + var outSn = await _db.Queryable<WtSerialNumberEntity>() | |
| 863 | + .Where(s => s.OutDjbh == djbh && s.Spbh == spbh && s.Status == 1) | |
| 864 | + .Select(s => s.SerialNumber) | |
| 865 | + .ToListAsync(); | |
| 866 | + if (outSn.Count == 0) return; | |
| 867 | + await InsertWtXlhDistinctAsync(djbh, djlx, spbh, outSn, "已出库"); | |
| 868 | + } | |
| 869 | + | |
| 870 | + /// <summary> | |
| 871 | + /// 销售类建单后补齐 <c>wt_xlh</c>:先按请求明细中的 <c>selectedSerialNumbers</c> 写入(收银台已选序列号但 | |
| 872 | + /// <c>wt_serial_number.in_warehouse</c> 与门店/仓库解析不一致时,原逻辑会 <c>continue</c> 导致未更新序列号池、跟踪表也为空), | |
| 873 | + /// 再按库表 <c>out_djbh</c> 同步 FIFO 等已落库的出库记录。幂等。 | |
| 874 | + /// </summary> | |
| 875 | + private async Task EnsureWtXlhForSalesOutboundCreateAsync( | |
| 876 | + string djbh, | |
| 877 | + string djlx, | |
| 878 | + List<WtXsckdMxCrInput> inputMxList, | |
| 879 | + List<WtXsckdMxEntity> mxList) | |
| 880 | + { | |
| 881 | + if (string.IsNullOrWhiteSpace(djbh) || mxList == null || mxList.Count == 0) return; | |
| 882 | + for (var i = 0; i < mxList.Count; i++) | |
| 883 | + { | |
| 884 | + var detail = mxList[i]; | |
| 885 | + if (string.IsNullOrEmpty(detail?.Spbh)) continue; | |
| 886 | + var inputDetail = inputMxList != null && inputMxList.Count > i ? inputMxList[i] : null; | |
| 887 | + var sel = inputDetail?.selectedSerialNumbers? | |
| 888 | + .Where(s => !string.IsNullOrWhiteSpace(s)) | |
| 889 | + .Select(s => s.Trim()) | |
| 890 | + .Distinct(StringComparer.OrdinalIgnoreCase) | |
| 891 | + .ToList() ?? new List<string>(); | |
| 892 | + if (sel.Count > 0) | |
| 893 | + await InsertWtXlhDistinctAsync(djbh, djlx, detail.Spbh, sel, "已出库"); | |
| 894 | + await SyncWtXlhOutboundFromSerialTableAsync(djbh, djlx, detail.Spbh); | |
| 895 | + } | |
| 896 | + } | |
| 897 | + | |
| 898 | + /// <summary> | |
| 899 | + /// 退货单保存后补齐 <c>wt_xlh</c>「退货入库」行:<see cref="ApplySalesReturnSerialRestoreForEntityAsync"/> 依赖 | |
| 900 | + /// <c>wt_serial_number.out_djbh</c> 指向原出库单;若出货时仅写入 <c>wt_xlh</c> 而序列号池未写 <c>out_djbh</c>,则回库为 0 且无退货跟踪。 | |
| 901 | + /// 此时按<strong>原单</strong>在 <c>wt_xlh</c> 中「已出库」记录 FIFO 与退货数量补写;请求体带 <c>selectedSerialNumbers</c> 时优先使用。 | |
| 902 | + /// 同一原单多行同商品共用队列,避免重复分配序列号。 | |
| 903 | + /// </summary> | |
| 904 | + private async Task EnsureWtXlhAfterSalesReturnCreateAsync( | |
| 905 | + WtXsckdEntity header, | |
| 906 | + List<WtXsckdMxCrInput> inputMxList, | |
| 907 | + List<WtXsckdMxEntity> mxList, | |
| 908 | + string returnDocId) | |
| 909 | + { | |
| 910 | + if (header == null || string.IsNullOrWhiteSpace(returnDocId) || mxList == null || mxList.Count == 0) return; | |
| 911 | + var lx = header.Djlx ?? ""; | |
| 912 | + if (lx != "销售退货单" && lx != "预售退货单" && !lx.Contains("委托代销退货单")) return; | |
| 913 | + | |
| 914 | + var pools = new Dictionary<string, Queue<string>>(StringComparer.Ordinal); | |
| 915 | + | |
| 916 | + for (var i = 0; i < mxList.Count; i++) | |
| 917 | + { | |
| 918 | + var detail = mxList[i]; | |
| 919 | + if (string.IsNullOrEmpty(detail?.Spbh) || !int.TryParse(detail.Sl, out var slVal) || slVal <= 0) | |
| 920 | + continue; | |
| 921 | + | |
| 922 | + var orig = ResolveOriginalOutboundDjbhForSalesReturn(detail, header, returnDocId); | |
| 923 | + if (string.IsNullOrEmpty(orig)) continue; | |
| 924 | + | |
| 925 | + var inputDetail = inputMxList != null && inputMxList.Count > i ? inputMxList[i] : null; | |
| 926 | + var fromInput = inputDetail?.selectedSerialNumbers? | |
| 927 | + .Where(s => !string.IsNullOrWhiteSpace(s)) | |
| 928 | + .Select(s => s.Trim()) | |
| 929 | + .Distinct(StringComparer.OrdinalIgnoreCase) | |
| 930 | + .ToList() ?? new List<string>(); | |
| 931 | + if (fromInput.Count > 0) | |
| 932 | + { | |
| 933 | + var use = fromInput.Count <= slVal ? fromInput : fromInput.Take(slVal).ToList(); | |
| 934 | + await InsertWtXlhDistinctAsync(returnDocId, lx, detail.Spbh, use, "退货入库"); | |
| 935 | + continue; | |
| 936 | + } | |
| 937 | + | |
| 938 | + var poolKey = orig + "\u001f" + detail.Spbh; | |
| 939 | + if (!pools.TryGetValue(poolKey, out var q)) | |
| 940 | + { | |
| 941 | + var rows = await _db.Queryable<WtXlhEntity>() | |
| 942 | + .Where(x => x.Djbh == orig && x.Spbh == detail.Spbh && | |
| 943 | + (x.Zt == "已出库" || SqlFunc.IsNullOrEmpty(x.Zt))) | |
| 944 | + .OrderBy(x => x.Id) | |
| 945 | + .Select(x => x.Xlh) | |
| 946 | + .ToListAsync(); | |
| 947 | + q = new Queue<string>(rows.Where(x => !string.IsNullOrWhiteSpace(x))); | |
| 948 | + pools[poolKey] = q; | |
| 949 | + } | |
| 950 | + | |
| 951 | + var consume = new List<string>(); | |
| 952 | + while (consume.Count < slVal && q.Count > 0) | |
| 953 | + consume.Add(q.Dequeue()); | |
| 954 | + if (consume.Count > 0) | |
| 955 | + await InsertWtXlhDistinctAsync(returnDocId, lx, detail.Spbh, consume, "退货入库"); | |
| 956 | + } | |
| 957 | + } | |
| 958 | + | |
| 959 | + /// <summary> | |
| 594 | 960 | /// 销售/预售/委托代销退货单:将原单已出库序列号恢复为在库(按主表原单号纠正明细 djbh)。幂等。 |
| 595 | 961 | /// </summary> |
| 596 | 962 | /// <returns>成功更新为在库的序列号条数</returns> |
| ... | ... | @@ -645,6 +1011,8 @@ namespace NCC.Extend.WtXsckd |
| 645 | 1011 | .ExecuteCommandAsync(); |
| 646 | 1012 | |
| 647 | 1013 | total += updateCount; |
| 1014 | + if (updateCount > 0) | |
| 1015 | + await InsertWtXlhDistinctAsync(returnDocId, header.Djlx ?? "", detail.Spbh, toUpdate, "退货入库"); | |
| 648 | 1016 | } |
| 649 | 1017 | |
| 650 | 1018 | return total; |
| ... | ... | @@ -1036,6 +1404,7 @@ namespace NCC.Extend.WtXsckd |
| 1036 | 1404 | EnsureYcddhColumn(); |
| 1037 | 1405 | EnsureYtWtfhdColumn(); |
| 1038 | 1406 | EnsureSyPchColumn(); |
| 1407 | + MigrateSpCostCkToWarehouseId(); | |
| 1039 | 1408 | var entity = await _db.Queryable<WtXsckdEntity>().FirstAsync(p => p.Id == id); |
| 1040 | 1409 | _ = entity ?? throw NCCException.Oh(ErrorCode.COM1005); |
| 1041 | 1410 | var output = entity.Adapt<WtXsckdInfoOutput>(); |
| ... | ... | @@ -1980,7 +2349,6 @@ namespace NCC.Extend.WtXsckd |
| 1980 | 2349 | // 将字符串类型的Sl转换为int |
| 1981 | 2350 | if (!string.IsNullOrEmpty(detail.Spbh) && int.TryParse(detail.Sl, out int slValue) && slValue > 0) |
| 1982 | 2351 | { |
| 1983 | - // 确定出库门店(优先使用明细的ckck,否则使用主表的cjck) | |
| 1984 | 2352 | var outStoreId = !string.IsNullOrEmpty(detail.Ckck) ? detail.Ckck : entity.Cjck; |
| 1985 | 2353 | |
| 1986 | 2354 | if (string.IsNullOrEmpty(outStoreId)) |
| ... | ... | @@ -1989,15 +2357,9 @@ namespace NCC.Extend.WtXsckd |
| 1989 | 2357 | continue; |
| 1990 | 2358 | } |
| 1991 | 2359 | |
| 1992 | - // 门店下属仓库;兼容仓库主键误填在 ckck 的情况(与采购退货明细一致) | |
| 1993 | - var warehouseIds = await _db.Queryable<WtCkEntity>() | |
| 1994 | - .Where(c => c.Ssmd == outStoreId || c.Id == outStoreId) | |
| 1995 | - .Select(c => c.Id) | |
| 1996 | - .ToListAsync(); | |
| 1997 | - if (warehouseIds == null || warehouseIds.Count == 0) | |
| 1998 | - { | |
| 1999 | - warehouseIds = new List<string> { outStoreId }; | |
| 2000 | - } | |
| 2360 | + // 序列号操作只用仓库 ID(wt_serial_number.in_warehouse 存的是 ID) | |
| 2361 | + var warehouseIds = await ResolveWarehouseIdsForSpCostFromStoreOrCkAsync(outStoreId); | |
| 2362 | + if (warehouseIds.Count == 0) warehouseIds = new List<string> { outStoreId }; | |
| 2001 | 2363 | |
| 2002 | 2364 | var selectedSerials = inputDetail?.selectedSerialNumbers? |
| 2003 | 2365 | .Where(s => !string.IsNullOrWhiteSpace(s)) |
| ... | ... | @@ -2059,9 +2421,16 @@ namespace NCC.Extend.WtXsckd |
| 2059 | 2421 | .ExecuteCommandAsync(); |
| 2060 | 2422 | |
| 2061 | 2423 | Console.WriteLine($"✅ 商品 {detail.Spmc} 已出库序列号 {updated} 条(指定或 FIFO)"); |
| 2424 | + await SyncWtXlhOutboundFromSerialTableAsync(newEntity.Id, input.djlx, detail.Spbh); | |
| 2062 | 2425 | } |
| 2063 | 2426 | } |
| 2064 | 2427 | } |
| 2428 | + | |
| 2429 | + await EnsureWtXlhForSalesOutboundCreateAsync( | |
| 2430 | + newEntity.Id, | |
| 2431 | + input.djlx, | |
| 2432 | + input.wtXsckdMxList, | |
| 2433 | + wtXsckdMxEntityList); | |
| 2065 | 2434 | } |
| 2066 | 2435 | // ✅ 销售/预售/委托代销退货单:按原单号恢复在库序列号 |
| 2067 | 2436 | else if (input.djlx == "销售退货单" || input.djlx == "预售退货单" || input.djlx == "委托代销退货单") |
| ... | ... | @@ -2071,6 +2440,11 @@ namespace NCC.Extend.WtXsckd |
| 2071 | 2440 | { |
| 2072 | 2441 | var n = await ApplySalesReturnSerialRestoreForEntityAsync(newEntity, wtXsckdMxEntityList, newEntity.Id); |
| 2073 | 2442 | Console.WriteLine($"✅ 退货序列号恢复合计 {n} 条"); |
| 2443 | + await EnsureWtXlhAfterSalesReturnCreateAsync( | |
| 2444 | + newEntity, | |
| 2445 | + input.wtXsckdMxList, | |
| 2446 | + wtXsckdMxEntityList, | |
| 2447 | + newEntity.Id); | |
| 2074 | 2448 | } |
| 2075 | 2449 | } |
| 2076 | 2450 | // ✅ 处理采购退货单:扣减在库序列号(Status 0 -> 1) |
| ... | ... | @@ -2097,16 +2471,10 @@ namespace NCC.Extend.WtXsckd |
| 2097 | 2471 | { |
| 2098 | 2472 | throw new Exception($"商品 {detail.Spmc} 未指定出库仓库,无法处理采购退货序列号"); |
| 2099 | 2473 | } |
| 2100 | - | |
| 2101 | - var warehouseIds = await _db.Queryable<WtCkEntity>() | |
| 2102 | - .Where(c => c.Ssmd == outStoreId || c.Id == outStoreId) | |
| 2103 | - .Select(c => c.Id) | |
| 2104 | - .ToListAsync(); | |
| 2105 | - if (warehouseIds == null || warehouseIds.Count == 0) | |
| 2106 | - { | |
| 2107 | - warehouseIds = new List<string> { outStoreId }; | |
| 2108 | - } | |
| 2109 | - | |
| 2474 | + | |
| 2475 | + var warehouseIds = await ResolveWarehouseIdsForSpCostFromStoreOrCkAsync(outStoreId); | |
| 2476 | + if (warehouseIds.Count == 0) warehouseIds = new List<string> { outStoreId }; | |
| 2477 | + | |
| 2110 | 2478 | var selectedSerials = inputDetail?.selectedSerialNumbers? |
| 2111 | 2479 | .Where(s => !string.IsNullOrWhiteSpace(s)) |
| 2112 | 2480 | .Select(s => s.Trim()) |
| ... | ... | @@ -2157,6 +2525,7 @@ namespace NCC.Extend.WtXsckd |
| 2157 | 2525 | }) |
| 2158 | 2526 | .Where(it => serialsToOut.Contains(it.SerialNumber)) |
| 2159 | 2527 | .ExecuteCommandAsync(); |
| 2528 | + await SyncWtXlhOutboundFromSerialTableAsync(newEntity.Id, input.djlx, detail.Spbh); | |
| 2160 | 2529 | } |
| 2161 | 2530 | } |
| 2162 | 2531 | } |
| ... | ... | @@ -2521,15 +2890,26 @@ namespace NCC.Extend.WtXsckd |
| 2521 | 2890 | { |
| 2522 | 2891 | _db.BeginTran(); |
| 2523 | 2892 | |
| 2524 | - // 逐单回退成本;退货单同步冲回会员账(审核不通过已冲回的跳过) | |
| 2893 | + // 逐单回退成本/积分/余额/提成/序列号 | |
| 2525 | 2894 | foreach (var entity in entitys) |
| 2526 | 2895 | { |
| 2527 | - if ((entity.Djlx == "销售退货单" || entity.Djlx == "预售退货单") | |
| 2528 | - && !string.Equals(entity.Djzt, "审核不通过", StringComparison.Ordinal)) | |
| 2529 | - await TryReverseReturnMemberRefundAsync(entity, "删除单据"); | |
| 2530 | - if (IsStockOutboundDocumentForSerialRevert(entity.Djlx)) | |
| 2531 | - await RevertSerialNumbersForDeletedOutboundAsync(entity.Id); | |
| 2532 | - await RollbackSpCostOnDelete(entity); | |
| 2896 | + var isRejected = string.Equals(entity.Djzt, "审核不通过", StringComparison.Ordinal); | |
| 2897 | + | |
| 2898 | + if (!isRejected) | |
| 2899 | + { | |
| 2900 | + if (entity.Djlx == "销售退货单" || entity.Djlx == "预售退货单") | |
| 2901 | + await TryReverseReturnMemberRefundAsync(entity, "删除单据"); | |
| 2902 | + | |
| 2903 | + await TryReverseSalesOutboundMemberAndCommissionAsync(entity, "删除单据"); | |
| 2904 | + | |
| 2905 | + if (IsStockOutboundDocumentForSerialRevert(entity.Djlx)) | |
| 2906 | + await RevertSerialNumbersForDeletedOutboundAsync(entity.Id); | |
| 2907 | + | |
| 2908 | + await RevertSerialNumbersForDeletedReturnAsync(entity); | |
| 2909 | + await RollbackSpCostOnDelete(entity); | |
| 2910 | + } | |
| 2911 | + | |
| 2912 | + await DeleteWtXlhTrackingForDocumentAsync(entity.Id); | |
| 2533 | 2913 | } |
| 2534 | 2914 | |
| 2535 | 2915 | await _wtDjzyService.DeleteByXsckdAsync(ids); |
| ... | ... | @@ -2610,6 +2990,37 @@ namespace NCC.Extend.WtXsckd |
| 2610 | 2990 | { |
| 2611 | 2991 | await RollbackSamePriceTransferStock(oldHeader, oldMxList); |
| 2612 | 2992 | } |
| 2993 | + | |
| 2994 | + // 编辑前先按旧明细冲回 wt_sp_cost,避免 UpdateSpCostOnCreate 二次扣减/加回 | |
| 2995 | + var oldLx = oldHeader.Djlx ?? ""; | |
| 2996 | + var oldDjzt = oldHeader.Djzt ?? ""; | |
| 2997 | + var skipCostRollback = string.Equals(oldDjzt, "草稿", StringComparison.Ordinal) | |
| 2998 | + || string.Equals(oldDjzt, "审核不通过", StringComparison.Ordinal); | |
| 2999 | + | |
| 3000 | + // 销售类出库:非序列号品会被 DeductWtSpCostNonSerialOutboundAsync 重复扣减 | |
| 3001 | + if ((oldLx == "销售出库单" || oldLx == "零售单" || oldLx == "预售出库单" || oldLx == "委托代销发货单") | |
| 3002 | + && !skipCostRollback && oldMxList.Count > 0) | |
| 3003 | + { | |
| 3004 | + await RollbackSpCostOnDelete(oldHeader); | |
| 3005 | + } | |
| 3006 | + | |
| 3007 | + // 退货单编辑:先冲回旧明细已加回的 wt_sp_cost | |
| 3008 | + if ((string.Equals(oldLx, "销售退货单", StringComparison.Ordinal) | |
| 3009 | + || string.Equals(oldLx, "预售退货单", StringComparison.Ordinal) | |
| 3010 | + || oldLx.Contains("委托代销退货单")) | |
| 3011 | + && !skipCostRollback && oldMxList.Count > 0) | |
| 3012 | + { | |
| 3013 | + await RollbackSpCostOnDelete(oldHeader); | |
| 3014 | + // 退货单编辑:冲回旧单创建时的会员余额/积分退回,后续 TryApplyReturnMemberRefundAsync 按新明细重写 | |
| 3015 | + if (oldLx == "销售退货单" || oldLx == "预售退货单") | |
| 3016 | + await TryReverseReturnMemberRefundAsync(oldHeader, "编辑退货单"); | |
| 3017 | + } | |
| 3018 | + | |
| 3019 | + // 采购退货单编辑:先冲回旧明细的成本扣减 | |
| 3020 | + if (oldLx == "采购退货单" && !skipCostRollback && oldMxList.Count > 0) | |
| 3021 | + { | |
| 3022 | + await RollbackSpCostOnDelete(oldHeader); | |
| 3023 | + } | |
| 2613 | 3024 | |
| 2614 | 3025 | //更新销售出库单记录 |
| 2615 | 3026 | await _db.Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync(); |
| ... | ... | @@ -2661,6 +3072,17 @@ namespace NCC.Extend.WtXsckd |
| 2661 | 3072 | |
| 2662 | 3073 | //关闭事务 |
| 2663 | 3074 | _db.CommitTran(); |
| 3075 | + | |
| 3076 | + // 退货单编辑完成后:按新的退货明细重新入账会员余额/积分退回(事务外,与 Create 一致) | |
| 3077 | + if ((entity.Djlx == "销售退货单" || entity.Djlx == "预售退货单") | |
| 3078 | + && !input.isDraft | |
| 3079 | + && !string.Equals(entity.Djzt, "草稿", StringComparison.Ordinal) | |
| 3080 | + && !string.Equals(entity.Djzt, "审核不通过", StringComparison.Ordinal)) | |
| 3081 | + { | |
| 3082 | + var updatedEntity = await _db.Queryable<WtXsckdEntity>().FirstAsync(p => p.Id == id); | |
| 3083 | + if (updatedEntity != null) | |
| 3084 | + await TryApplyReturnMemberRefundAsync(updatedEntity); | |
| 3085 | + } | |
| 2664 | 3086 | } |
| 2665 | 3087 | catch (Exception) |
| 2666 | 3088 | { |
| ... | ... | @@ -2689,17 +3111,35 @@ namespace NCC.Extend.WtXsckd |
| 2689 | 3111 | { |
| 2690 | 3112 | _db.BeginTran(); |
| 2691 | 3113 | |
| 2692 | - // 退货单创建时已入账会员余额/积分;删除时先冲回(审核不通过时已冲过,避免重复) | |
| 2693 | - if ((entity.Djlx == "销售退货单" || entity.Djlx == "预售退货单") | |
| 2694 | - && !string.Equals(entity.Djzt, "审核不通过", StringComparison.Ordinal)) | |
| 2695 | - await TryReverseReturnMemberRefundAsync(entity, "删除单据"); | |
| 3114 | + // 审核不通过的单据在 RejectDocument 中已冲回所有副作用,此处仅清理记录即可 | |
| 3115 | + var isRejected = string.Equals(entity.Djzt, "审核不通过", StringComparison.Ordinal); | |
| 2696 | 3116 | |
| 2697 | - // 销售类出库:先恢复本单序列号为在库,再回退成本(与建单时先扣序列号再扣账对称,避免删单后账面与序列号不一致) | |
| 2698 | - if (IsStockOutboundDocumentForSerialRevert(entity.Djlx)) | |
| 2699 | - await RevertSerialNumbersForDeletedOutboundAsync(entity.Id); | |
| 3117 | + if (!isRejected) | |
| 3118 | + { | |
| 3119 | + // 退货单会员余额/积分冲回 | |
| 3120 | + if (entity.Djlx == "销售退货单" || entity.Djlx == "预售退货单") | |
| 3121 | + await TryReverseReturnMemberRefundAsync(entity, "删除单据"); | |
| 2700 | 3122 | |
| 2701 | - // 删除前回退成本 | |
| 2702 | - await RollbackSpCostOnDelete(entity); | |
| 3123 | + // 销售类出库:冲回会员积分/余额 + 删除导购提成 | |
| 3124 | + await TryReverseSalesOutboundMemberAndCommissionAsync(entity, "删除单据"); | |
| 3125 | + | |
| 3126 | + // 销售类出库:恢复序列号为在库 | |
| 3127 | + if (IsStockOutboundDocumentForSerialRevert(entity.Djlx)) | |
| 3128 | + await RevertSerialNumbersForDeletedOutboundAsync(entity.Id); | |
| 3129 | + | |
| 3130 | + // 退货单:将退货恢复的序列号还原为已售出(须在 DeleteWtXlhTracking 前调用) | |
| 3131 | + await RevertSerialNumbersForDeletedReturnAsync(entity); | |
| 3132 | + | |
| 3133 | + await DeleteWtXlhTrackingForDocumentAsync(entity.Id); | |
| 3134 | + | |
| 3135 | + // 回退成本 | |
| 3136 | + await RollbackSpCostOnDelete(entity); | |
| 3137 | + } | |
| 3138 | + else | |
| 3139 | + { | |
| 3140 | + // 审核不通过:仅清理残留跟踪(序列号/xlh 回退在 Reject 中已执行,再调是安全 no-op) | |
| 3141 | + await DeleteWtXlhTrackingForDocumentAsync(entity.Id); | |
| 3142 | + } | |
| 2703 | 3143 | |
| 2704 | 3144 | await _wtDjzyService.DeleteByXsckdAsync(id); |
| 2705 | 3145 | |
| ... | ... | @@ -3258,14 +3698,8 @@ ORDER BY IFNULL(MAX(pp.F_Ppmc), ''), IFNULL(MAX(s.F_Spbm), '')"; |
| 3258 | 3698 | var pid = productId.Trim(); |
| 3259 | 3699 | var wid = warehouseId.Trim(); |
| 3260 | 3700 | |
| 3261 | - var warehouseIds = await _db.Queryable<WtCkEntity>() | |
| 3262 | - .Where(c => c.Ssmd == wid || c.Id == wid) | |
| 3263 | - .Select(c => c.Id) | |
| 3264 | - .ToListAsync(); | |
| 3265 | - if (warehouseIds == null || warehouseIds.Count == 0) | |
| 3266 | - { | |
| 3267 | - warehouseIds = new List<string> { wid }; | |
| 3268 | - } | |
| 3701 | + var warehouseIds = await ResolveWarehouseIdsForSpCostFromStoreOrCkAsync(wid); | |
| 3702 | + if (warehouseIds.Count == 0) warehouseIds = new List<string> { wid }; | |
| 3269 | 3703 | |
| 3270 | 3704 | var whSet = new HashSet<string>( |
| 3271 | 3705 | warehouseIds.Where(x => !string.IsNullOrWhiteSpace(x)).Select(x => x.Trim()), |
| ... | ... | @@ -3307,6 +3741,7 @@ ORDER BY IFNULL(MAX(pp.F_Ppmc), ''), IFNULL(MAX(s.F_Spbm), '')"; |
| 3307 | 3741 | return new { success = false, restored = 0, msg = "无明细" }; |
| 3308 | 3742 | |
| 3309 | 3743 | var restored = await ApplySalesReturnSerialRestoreForEntityAsync(entity, mxList, id); |
| 3744 | + await EnsureWtXlhAfterSalesReturnCreateAsync(entity, null, mxList, id); | |
| 3310 | 3745 | return new { success = true, restored, msg = restored > 0 ? $"已回库 {restored} 条序列号" : "无待回库序列号(可能已处理或原单不匹配)" }; |
| 3311 | 3746 | } |
| 3312 | 3747 | |
| ... | ... | @@ -3325,14 +3760,8 @@ ORDER BY IFNULL(MAX(pp.F_Ppmc), ''), IFNULL(MAX(s.F_Spbm), '')"; |
| 3325 | 3760 | |
| 3326 | 3761 | try |
| 3327 | 3762 | { |
| 3328 | - var warehouseIds = await _db.Queryable<WtCkEntity>() | |
| 3329 | - .Where(c => c.Ssmd == ckOrMdId || c.Id == ckOrMdId) | |
| 3330 | - .Select(c => c.Id) | |
| 3331 | - .ToListAsync(); | |
| 3332 | - if (warehouseIds == null || warehouseIds.Count == 0) | |
| 3333 | - { | |
| 3334 | - warehouseIds = new List<string> { ckOrMdId.Trim() }; | |
| 3335 | - } | |
| 3763 | + var warehouseIds = await ResolveWarehouseIdsForSpCostFromStoreOrCkAsync(ckOrMdId); | |
| 3764 | + if (warehouseIds.Count == 0) warehouseIds = new List<string> { ckOrMdId.Trim() }; | |
| 3336 | 3765 | |
| 3337 | 3766 | var ps = new List<SugarParameter> { new SugarParameter("@spbh", spbh.Trim()) }; |
| 3338 | 3767 | for (var i = 0; i < warehouseIds.Count; i++) |
| ... | ... | @@ -3357,13 +3786,25 @@ ORDER BY IFNULL(MAX(pp.F_Ppmc), ''), IFNULL(MAX(s.F_Spbm), '')"; |
| 3357 | 3786 | } |
| 3358 | 3787 | } |
| 3359 | 3788 | |
| 3789 | + private const string PurchaseSummaryJoinFromSql = @" | |
| 3790 | +FROM wt_xsckd_mx mx | |
| 3791 | +INNER JOIN wt_xsckd d ON d.F_Id = mx.djbh | |
| 3792 | +LEFT JOIN wt_sp sp ON sp.F_Id = mx.spbh | |
| 3793 | +LEFT JOIN wt_pl pl ON pl.F_Id = sp.F_Pl | |
| 3794 | +LEFT JOIN wt_pp pp ON pp.F_Id = sp.F_Pp | |
| 3795 | +LEFT JOIN wt_wldw w ON w.F_Id = d.gys | |
| 3796 | +LEFT JOIN BASE_USER u ON u.F_Id = d.jsr | |
| 3797 | +LEFT JOIN wt_ck ck ON ck.F_Id = IFNULL(NULLIF(TRIM(mx.rkck), ''), d.rkck) | |
| 3798 | +WHERE 1 = 1"; | |
| 3799 | + | |
| 3360 | 3800 | /// <summary> |
| 3361 | - /// 商品采购订单汇总:按明细行返回过往采购记录(筛选后分页),列与业务导出表一致。 | |
| 3801 | + /// 采购汇总公共 WHERE(需配合含 sp/pl/pp 的 PurchaseSummaryJoinFromSql 使用)。 | |
| 3362 | 3802 | /// </summary> |
| 3363 | - /// <param name="input">筛选条件:时间范围、往来单位、经手人、商品、入库仓库、单据类型、分页</param> | |
| 3364 | - /// <returns>list:明细行;total:总条数</returns> | |
| 3365 | - [HttpGet("Actions/GetPurchaseSummary")] | |
| 3366 | - public async Task<dynamic> GetPurchaseSummary([FromQuery] WtPurchaseSummaryQueryInput input = null) | |
| 3803 | + private (string whereSql, List<SugarParameter> paramList) BuildPurchaseSummaryWhere( | |
| 3804 | + WtPurchaseSummaryQueryInput input, | |
| 3805 | + string scopeCategoryId, | |
| 3806 | + string scopeBrandId, | |
| 3807 | + string scopeProductSpId) | |
| 3367 | 3808 | { |
| 3368 | 3809 | input ??= new WtPurchaseSummaryQueryInput(); |
| 3369 | 3810 | var whereList = new List<string>(); |
| ... | ... | @@ -3405,34 +3846,22 @@ ORDER BY IFNULL(MAX(pp.F_Ppmc), ''), IFNULL(MAX(s.F_Spbm), '')"; |
| 3405 | 3846 | |
| 3406 | 3847 | if (DateTime.TryParse(input.StartDate, out var startDate)) |
| 3407 | 3848 | { |
| 3408 | - whereList.Add("d.djrq >= @startDate"); | |
| 3409 | - paramList.Add(new SugarParameter("@startDate", startDate.Date)); | |
| 3849 | + whereList.Add("d.djrq >= @purSumStartDate"); | |
| 3850 | + paramList.Add(new SugarParameter("@purSumStartDate", startDate.Date)); | |
| 3410 | 3851 | } |
| 3411 | 3852 | |
| 3412 | 3853 | if (DateTime.TryParse(input.EndDate, out var endDate)) |
| 3413 | 3854 | { |
| 3414 | - whereList.Add("d.djrq < @endDate"); | |
| 3415 | - paramList.Add(new SugarParameter("@endDate", endDate.Date.AddDays(1))); | |
| 3855 | + whereList.Add("d.djrq < @purSumEndDate"); | |
| 3856 | + paramList.Add(new SugarParameter("@purSumEndDate", endDate.Date.AddDays(1))); | |
| 3416 | 3857 | } |
| 3417 | 3858 | |
| 3418 | - AddInCondition("d.gys", input.ContactUnit, "contactUnit"); | |
| 3419 | - | |
| 3420 | - // 经手人:主表存用户 ID,筛选按姓名匹配 BASE_USER | |
| 3421 | - var agentNames = SplitCsv(input.Agent); | |
| 3422 | - if (agentNames.Count > 0) | |
| 3423 | - { | |
| 3424 | - var agentParamNames = new List<string>(); | |
| 3425 | - for (var i = 0; i < agentNames.Count; i++) | |
| 3426 | - { | |
| 3427 | - var p = $"@agentName{i}"; | |
| 3428 | - agentParamNames.Add(p); | |
| 3429 | - paramList.Add(new SugarParameter(p, agentNames[i])); | |
| 3430 | - } | |
| 3859 | + AddInCondition("d.gys", input.ContactUnit, "purSumContact"); | |
| 3431 | 3860 | |
| 3432 | - whereList.Add($"d.jsr IN (SELECT F_Id FROM BASE_USER WHERE F_RealName IN ({string.Join(",", agentParamNames)}))"); | |
| 3433 | - } | |
| 3861 | + // 经手人:主表 wt_xsckd.jsr 存 BASE_USER.F_Id,按用户主键 IN 筛选(与前端下拉 value 一致) | |
| 3862 | + AddInCondition("d.jsr", input.Agent, "purSumJsr"); | |
| 3434 | 3863 | |
| 3435 | - AddInCondition("IFNULL(NULLIF(TRIM(mx.rkck), ''), d.rkck)", input.Warehouse, "warehouse"); | |
| 3864 | + AddInCondition("IFNULL(NULLIF(TRIM(mx.rkck), ''), d.rkck)", input.Warehouse, "purSumWh"); | |
| 3436 | 3865 | |
| 3437 | 3866 | var billTypeValues = SplitCsv(input.BillType); |
| 3438 | 3867 | if (billTypeValues.Count == 0) |
| ... | ... | @@ -3441,7 +3870,7 @@ ORDER BY IFNULL(MAX(pp.F_Ppmc), ''), IFNULL(MAX(s.F_Spbm), '')"; |
| 3441 | 3870 | billTypeValues.Add("采购退货单"); |
| 3442 | 3871 | } |
| 3443 | 3872 | |
| 3444 | - AddInCondition("d.djlx", string.Join(",", billTypeValues), "billType"); | |
| 3873 | + AddInCondition("d.djlx", string.Join(",", billTypeValues), "purSumDjlx"); | |
| 3445 | 3874 | |
| 3446 | 3875 | var productValues = SplitCsv(input.Product); |
| 3447 | 3876 | if (productValues.Count > 0) |
| ... | ... | @@ -3449,17 +3878,182 @@ ORDER BY IFNULL(MAX(pp.F_Ppmc), ''), IFNULL(MAX(s.F_Spbm), '')"; |
| 3449 | 3878 | var productConditions = new List<string>(); |
| 3450 | 3879 | for (var i = 0; i < productValues.Count; i++) |
| 3451 | 3880 | { |
| 3452 | - var codeParam = $"@productCode{i}"; | |
| 3453 | - var nameParam = $"@productName{i}"; | |
| 3454 | - productConditions.Add($"(mx.spbh = {codeParam} OR mx.spmc LIKE {nameParam})"); | |
| 3455 | - paramList.Add(new SugarParameter(codeParam, productValues[i])); | |
| 3456 | - paramList.Add(new SugarParameter(nameParam, $"%{productValues[i]}%")); | |
| 3881 | + var pEq = $"@purProdEq{i}"; | |
| 3882 | + var pLike = $"@purProdLike{i}"; | |
| 3883 | + productConditions.Add($"(mx.spbh = {pEq} OR sp.F_Spbm = {pEq} OR mx.spmc LIKE {pLike} OR IFNULL(sp.F_Spmc, '') LIKE {pLike})"); | |
| 3884 | + paramList.Add(new SugarParameter(pEq, productValues[i])); | |
| 3885 | + paramList.Add(new SugarParameter(pLike, $"%{productValues[i]}%")); | |
| 3457 | 3886 | } |
| 3458 | 3887 | |
| 3459 | 3888 | whereList.Add($"({string.Join(" OR ", productConditions)})"); |
| 3460 | 3889 | } |
| 3461 | 3890 | |
| 3891 | + var cat = !string.IsNullOrWhiteSpace(scopeCategoryId) ? scopeCategoryId.Trim() : (input.CategoryId ?? string.Empty).Trim(); | |
| 3892 | + if (cat == "__NONE__") | |
| 3893 | + { | |
| 3894 | + whereList.Add("(sp.F_Pl IS NULL OR TRIM(IFNULL(sp.F_Pl,'')) = '')"); | |
| 3895 | + } | |
| 3896 | + else if (!string.IsNullOrEmpty(cat)) | |
| 3897 | + { | |
| 3898 | + whereList.Add("sp.F_Pl = @purSumScopeCat"); | |
| 3899 | + paramList.Add(new SugarParameter("@purSumScopeCat", cat)); | |
| 3900 | + } | |
| 3901 | + | |
| 3902 | + var brand = !string.IsNullOrWhiteSpace(scopeBrandId) ? scopeBrandId.Trim() : (input.BrandId ?? string.Empty).Trim(); | |
| 3903 | + if (!string.IsNullOrEmpty(brand)) | |
| 3904 | + { | |
| 3905 | + whereList.Add("sp.F_Pp = @purSumScopePp"); | |
| 3906 | + paramList.Add(new SugarParameter("@purSumScopePp", brand)); | |
| 3907 | + } | |
| 3908 | + | |
| 3909 | + var spId = !string.IsNullOrWhiteSpace(scopeProductSpId) ? scopeProductSpId.Trim() : (input.ProductSpId ?? string.Empty).Trim(); | |
| 3910 | + if (!string.IsNullOrEmpty(spId)) | |
| 3911 | + { | |
| 3912 | + whereList.Add("mx.spbh = @purSumScopeSp"); | |
| 3913 | + paramList.Add(new SugarParameter("@purSumScopeSp", spId)); | |
| 3914 | + } | |
| 3915 | + | |
| 3462 | 3916 | var whereSql = whereList.Count > 0 ? $" AND {string.Join(" AND ", whereList)}" : string.Empty; |
| 3917 | + return (whereSql, paramList); | |
| 3918 | + } | |
| 3919 | + | |
| 3920 | + /// <summary> | |
| 3921 | + /// 商品采购汇总(按分类聚合):数量、加权平均入库单价、采购金额。 | |
| 3922 | + /// </summary> | |
| 3923 | + [HttpGet("Actions/GetPurchaseSummaryByCategory")] | |
| 3924 | + public async Task<dynamic> GetPurchaseSummaryByCategory([FromQuery] WtPurchaseSummaryQueryInput input = null) | |
| 3925 | + { | |
| 3926 | + input ??= new WtPurchaseSummaryQueryInput(); | |
| 3927 | + var (whereSql, paramList) = BuildPurchaseSummaryWhere(input, null, null, null); | |
| 3928 | + var sql = $@" | |
| 3929 | +SELECT | |
| 3930 | + IFNULL(NULLIF(TRIM(sp.F_Pl), ''), '__NONE__') AS `分类Id`, | |
| 3931 | + IFNULL(NULLIF(TRIM(MAX(pl.F_Plmc)), ''), '无') AS `分类名称`, | |
| 3932 | + '无' AS `商品编号`, | |
| 3933 | + IFNULL(NULLIF(TRIM(MAX(pl.F_Plmc)), ''), '无') AS `商品名称`, | |
| 3934 | + SUM(CAST(mx.sl AS DECIMAL(18,4))) AS `数量`, | |
| 3935 | + CASE WHEN ABS(SUM(CAST(mx.sl AS DECIMAL(18,4)))) < 0.00000001 THEN 0 | |
| 3936 | + ELSE SUM(CAST(mx.je AS DECIMAL(18,4))) / SUM(CAST(mx.sl AS DECIMAL(18,4))) END AS `入库单价`, | |
| 3937 | + SUM(CAST(mx.je AS DECIMAL(18,4))) AS `采购金额` | |
| 3938 | +{PurchaseSummaryJoinFromSql} | |
| 3939 | +{whereSql} | |
| 3940 | +GROUP BY sp.F_Pl, pl.F_Plmc | |
| 3941 | +ORDER BY SUM(CAST(mx.je AS DECIMAL(18,4))) DESC"; | |
| 3942 | + var list = await _db.Ado.GetDataTableAsync(sql, paramList); | |
| 3943 | + return list; | |
| 3944 | + } | |
| 3945 | + | |
| 3946 | + /// <summary> | |
| 3947 | + /// 商品采购汇总(指定分类下按品牌聚合)。 | |
| 3948 | + /// </summary> | |
| 3949 | + [HttpGet("Actions/GetPurchaseSummaryByBrand")] | |
| 3950 | + public async Task<dynamic> GetPurchaseSummaryByBrand([FromQuery] string categoryId, [FromQuery] WtPurchaseSummaryQueryInput input = null) | |
| 3951 | + { | |
| 3952 | + if (string.IsNullOrWhiteSpace(categoryId)) | |
| 3953 | + { | |
| 3954 | + throw NCCException.Oh("categoryId 不能为空"); | |
| 3955 | + } | |
| 3956 | + | |
| 3957 | + input ??= new WtPurchaseSummaryQueryInput(); | |
| 3958 | + var (whereSql, paramList) = BuildPurchaseSummaryWhere(input, categoryId, null, null); | |
| 3959 | + var sql = $@" | |
| 3960 | +SELECT | |
| 3961 | + IFNULL(NULLIF(TRIM(sp.F_Pp), ''), '') AS `品牌Id`, | |
| 3962 | + IFNULL(NULLIF(TRIM(MAX(pp.F_Ppmc)), ''), '无') AS `品牌名称`, | |
| 3963 | + '无' AS `商品编号`, | |
| 3964 | + IFNULL(NULLIF(TRIM(MAX(pp.F_Ppmc)), ''), '无') AS `商品名称`, | |
| 3965 | + SUM(CAST(mx.sl AS DECIMAL(18,4))) AS `数量`, | |
| 3966 | + CASE WHEN ABS(SUM(CAST(mx.sl AS DECIMAL(18,4)))) < 0.00000001 THEN 0 | |
| 3967 | + ELSE SUM(CAST(mx.je AS DECIMAL(18,4))) / SUM(CAST(mx.sl AS DECIMAL(18,4))) END AS `入库单价`, | |
| 3968 | + SUM(CAST(mx.je AS DECIMAL(18,4))) AS `采购金额` | |
| 3969 | +{PurchaseSummaryJoinFromSql} | |
| 3970 | +{whereSql} | |
| 3971 | +GROUP BY sp.F_Pp, pp.F_Ppmc | |
| 3972 | +ORDER BY SUM(CAST(mx.je AS DECIMAL(18,4))) DESC"; | |
| 3973 | + var list = await _db.Ado.GetDataTableAsync(sql, paramList); | |
| 3974 | + return list; | |
| 3975 | + } | |
| 3976 | + | |
| 3977 | + /// <summary> | |
| 3978 | + /// 商品采购汇总(指定分类+品牌下按商品聚合)。 | |
| 3979 | + /// </summary> | |
| 3980 | + [HttpGet("Actions/GetPurchaseSummaryByProductAgg")] | |
| 3981 | + public async Task<dynamic> GetPurchaseSummaryByProductAgg([FromQuery] string categoryId, [FromQuery] string brandId, [FromQuery] WtPurchaseSummaryQueryInput input = null) | |
| 3982 | + { | |
| 3983 | + if (string.IsNullOrWhiteSpace(categoryId)) | |
| 3984 | + { | |
| 3985 | + throw NCCException.Oh("categoryId 不能为空"); | |
| 3986 | + } | |
| 3987 | + | |
| 3988 | + if (string.IsNullOrWhiteSpace(brandId)) | |
| 3989 | + { | |
| 3990 | + throw NCCException.Oh("brandId 不能为空"); | |
| 3991 | + } | |
| 3992 | + | |
| 3993 | + input ??= new WtPurchaseSummaryQueryInput(); | |
| 3994 | + var (whereSql, paramList) = BuildPurchaseSummaryWhere(input, categoryId, brandId, null); | |
| 3995 | + var sql = $@" | |
| 3996 | +SELECT | |
| 3997 | + sp.F_Id AS `商品Id`, | |
| 3998 | + IFNULL(NULLIF(TRIM(MAX(sp.F_Spbm)), ''), '无') AS `商品编号`, | |
| 3999 | + IFNULL(NULLIF(TRIM(MAX(sp.F_Spmc)), ''), '无') AS `商品名称`, | |
| 4000 | + IFNULL(NULLIF(TRIM(CONCAT_WS(' / ', NULLIF(TRIM(sp.F_Splx1), ''), NULLIF(TRIM(sp.F_Splx2), ''))), ''), '无') AS `明细分类`, | |
| 4001 | + SUM(CAST(mx.sl AS DECIMAL(18,4))) AS `数量`, | |
| 4002 | + CASE WHEN ABS(SUM(CAST(mx.sl AS DECIMAL(18,4)))) < 0.00000001 THEN 0 | |
| 4003 | + ELSE SUM(CAST(mx.je AS DECIMAL(18,4))) / SUM(CAST(mx.sl AS DECIMAL(18,4))) END AS `入库单价`, | |
| 4004 | + SUM(CAST(mx.je AS DECIMAL(18,4))) AS `采购金额` | |
| 4005 | +{PurchaseSummaryJoinFromSql} | |
| 4006 | +{whereSql} | |
| 4007 | +GROUP BY sp.F_Id, sp.F_Splx1, sp.F_Splx2 | |
| 4008 | +ORDER BY IFNULL(MAX(sp.F_Spbm), ''), IFNULL(MAX(sp.F_Spmc), '')"; | |
| 4009 | + var list = await _db.Ado.GetDataTableAsync(sql, paramList); | |
| 4010 | + return list; | |
| 4011 | + } | |
| 4012 | + | |
| 4013 | + /// <summary> | |
| 4014 | + /// 商品采购「线性列表」:指定分类下全部采购明细行(最多 2000 条),与明细列表列一致。 | |
| 4015 | + /// </summary> | |
| 4016 | + [HttpGet("Actions/GetPurchaseSummaryLinear")] | |
| 4017 | + public async Task<dynamic> GetPurchaseSummaryLinear([FromQuery] string categoryId, [FromQuery] WtPurchaseSummaryQueryInput input = null) | |
| 4018 | + { | |
| 4019 | + if (string.IsNullOrWhiteSpace(categoryId)) | |
| 4020 | + { | |
| 4021 | + throw NCCException.Oh("categoryId 不能为空"); | |
| 4022 | + } | |
| 4023 | + | |
| 4024 | + input ??= new WtPurchaseSummaryQueryInput(); | |
| 4025 | + var (whereSql, paramList) = BuildPurchaseSummaryWhere(input, categoryId, null, null); | |
| 4026 | + const int maxRows = 2000; | |
| 4027 | + var sql = $@" | |
| 4028 | +SELECT | |
| 4029 | + DATE_FORMAT(d.djrq, '%Y-%m-%d') AS `单据日期`, | |
| 4030 | + d.F_Id AS `单据编号`, | |
| 4031 | + d.djlx AS `单据类型`, | |
| 4032 | + IFNULL(NULLIF(TRIM(w.dwmc), ''), '无') AS `往来单位`, | |
| 4033 | + IFNULL(NULLIF(TRIM(u.F_RealName), ''), IFNULL(NULLIF(TRIM(d.jsr), ''), '无')) AS `经手人`, | |
| 4034 | + IFNULL(NULLIF(TRIM(ck.F_mdmc), ''), '无') AS `仓库名称`, | |
| 4035 | + IFNULL(NULLIF(TRIM(mx.spmc), ''), '无') AS `商品名称`, | |
| 4036 | + CAST(mx.sl AS DECIMAL(18,4)) AS `数量`, | |
| 4037 | + mx.dj AS `入库单价`, | |
| 4038 | + mx.je AS `采购金额` | |
| 4039 | +{PurchaseSummaryJoinFromSql} | |
| 4040 | +{whereSql} | |
| 4041 | +ORDER BY d.djrq DESC, d.F_Id, mx.F_Id | |
| 4042 | +LIMIT {maxRows}"; | |
| 4043 | + var list = await _db.Ado.GetDataTableAsync(sql, paramList); | |
| 4044 | + return list; | |
| 4045 | + } | |
| 4046 | + | |
| 4047 | + /// <summary> | |
| 4048 | + /// 商品采购订单汇总:按明细行返回过往采购记录(筛选后分页),列与业务导出表一致。 | |
| 4049 | + /// </summary> | |
| 4050 | + /// <param name="input">筛选条件:时间范围、往来单位、经手人(用户主键)、商品、入库仓库、单据类型、分页;可选 CategoryId/BrandId/ProductSpId 下钻</param> | |
| 4051 | + /// <returns>list:明细行;total:总条数</returns> | |
| 4052 | + [HttpGet("Actions/GetPurchaseSummary")] | |
| 4053 | + public async Task<dynamic> GetPurchaseSummary([FromQuery] WtPurchaseSummaryQueryInput input = null) | |
| 4054 | + { | |
| 4055 | + input ??= new WtPurchaseSummaryQueryInput(); | |
| 4056 | + var (whereSql, paramList) = BuildPurchaseSummaryWhere(input, null, null, null); | |
| 3463 | 4057 | |
| 3464 | 4058 | var page = input.CurrentPage.GetValueOrDefault(1); |
| 3465 | 4059 | if (page < 1) |
| ... | ... | @@ -3480,15 +4074,7 @@ ORDER BY IFNULL(MAX(pp.F_Ppmc), ''), IFNULL(MAX(s.F_Spbm), '')"; |
| 3480 | 4074 | |
| 3481 | 4075 | var offset = (page - 1) * pageSize; |
| 3482 | 4076 | |
| 3483 | - var fromSql = @" | |
| 3484 | -FROM wt_xsckd_mx mx | |
| 3485 | -INNER JOIN wt_xsckd d ON d.F_Id = mx.djbh | |
| 3486 | -LEFT JOIN wt_wldw w ON w.F_Id = d.gys | |
| 3487 | -LEFT JOIN BASE_USER u ON u.F_Id = d.jsr | |
| 3488 | -LEFT JOIN wt_ck ck ON ck.F_Id = IFNULL(NULLIF(TRIM(mx.rkck), ''), d.rkck) | |
| 3489 | -WHERE 1 = 1"; | |
| 3490 | - | |
| 3491 | - var countSql = "SELECT COUNT(*) " + fromSql + whereSql; | |
| 4077 | + var countSql = "SELECT COUNT(*) " + PurchaseSummaryJoinFromSql + whereSql; | |
| 3492 | 4078 | var totalObj = await _db.Ado.GetScalarAsync(countSql, paramList); |
| 3493 | 4079 | var total = Convert.ToInt32(totalObj ?? 0); |
| 3494 | 4080 | |
| ... | ... | @@ -3504,7 +4090,7 @@ SELECT |
| 3504 | 4090 | CAST(mx.sl AS DECIMAL(18,4)) AS `数量`, |
| 3505 | 4091 | mx.dj AS `入库单价`, |
| 3506 | 4092 | mx.je AS `采购金额` |
| 3507 | -{fromSql} | |
| 4093 | +{PurchaseSummaryJoinFromSql} | |
| 3508 | 4094 | {whereSql} |
| 3509 | 4095 | ORDER BY d.djrq DESC, d.F_Id, mx.F_Id |
| 3510 | 4096 | LIMIT {offset}, {pageSize}"; |
| ... | ... | @@ -3875,6 +4461,37 @@ LIMIT {offset}, {pageSize}"; |
| 3875 | 4461 | .ExecuteCommandAsync(); |
| 3876 | 4462 | } |
| 3877 | 4463 | } |
| 4464 | + | |
| 4465 | + if (!isDraft && serialNumbers != null && serialNumbers.Count > 0 && | |
| 4466 | + !string.IsNullOrEmpty(outDocumentId) && | |
| 4467 | + outDocumentType != "销售退货单" && outDocumentType != "预售退货单" && | |
| 4468 | + outDocumentType != "委托代销退货单" && outDocumentType != "采购退货单") | |
| 4469 | + { | |
| 4470 | + var spbhList = await _db.Queryable<WtSerialNumberEntity>() | |
| 4471 | + .Where(s => serialNumbers.Contains(s.SerialNumber) && s.OutDjbh == outDocumentId) | |
| 4472 | + .Select(s => s.Spbh) | |
| 4473 | + .ToListAsync(); | |
| 4474 | + foreach (var sp in spbhList.Distinct(StringComparer.OrdinalIgnoreCase)) | |
| 4475 | + { | |
| 4476 | + if (!string.IsNullOrEmpty(sp)) | |
| 4477 | + await SyncWtXlhOutboundFromSerialTableAsync(outDocumentId, outDocumentType, sp); | |
| 4478 | + } | |
| 4479 | + } | |
| 4480 | + | |
| 4481 | + if (!isDraft && serialNumbers != null && serialNumbers.Count > 0 && !string.IsNullOrEmpty(outDocumentId) && | |
| 4482 | + (outDocumentType == "销售退货单" || outDocumentType == "预售退货单" || outDocumentType == "委托代销退货单")) | |
| 4483 | + { | |
| 4484 | + var snRows = await _db.Queryable<WtSerialNumberEntity>() | |
| 4485 | + .Where(s => serialNumbers.Contains(s.SerialNumber)) | |
| 4486 | + .Select(s => new { s.SerialNumber, s.Spbh }) | |
| 4487 | + .ToListAsync(); | |
| 4488 | + foreach (var g in snRows.GroupBy(x => x.Spbh ?? "", StringComparer.OrdinalIgnoreCase)) | |
| 4489 | + { | |
| 4490 | + if (string.IsNullOrEmpty(g.Key)) continue; | |
| 4491 | + await InsertWtXlhDistinctAsync(outDocumentId, outDocumentType, g.Key, | |
| 4492 | + g.Select(x => x.SerialNumber).ToList(), "退货入库"); | |
| 4493 | + } | |
| 4494 | + } | |
| 3878 | 4495 | |
| 3879 | 4496 | return new { success = true, message = "序列号状态更新成功", created = missingSerialNumbers.Count }; |
| 3880 | 4497 | } |
| ... | ... | @@ -4441,8 +5058,50 @@ LIMIT {offset}, {pageSize}"; |
| 4441 | 5058 | return new { success = false, message = "单据不存在" }; |
| 4442 | 5059 | } |
| 4443 | 5060 | |
| 4444 | - AppendApprovalSpbzLine(row, "审核不通过", approvalRemark); | |
| 5061 | + var rowDjlx = row.Djlx ?? ""; | |
| 5062 | + var wasNotDraft = !string.Equals(row.Djzt, "草稿", StringComparison.Ordinal); | |
| 4445 | 5063 | |
| 5064 | + // ★ 审核不通过 = 单据从未生效:先按旧状态冲回所有 Create 时产生的副作用 | |
| 5065 | + if (wasNotDraft) | |
| 5066 | + { | |
| 5067 | + // 销售类出库:冲回 wt_sp_cost / 序列号 / wt_xlh / 会员 / 提成 | |
| 5068 | + if (rowDjlx == "销售出库单" || rowDjlx == "零售单" || rowDjlx == "预售出库单" || rowDjlx == "委托代销发货单") | |
| 5069 | + { | |
| 5070 | + if (IsStockOutboundDocumentForSerialRevert(rowDjlx)) | |
| 5071 | + await RevertSerialNumbersForDeletedOutboundAsync(row.Id); | |
| 5072 | + await DeleteWtXlhTrackingForDocumentAsync(row.Id); | |
| 5073 | + await RollbackSpCostOnDelete(row); | |
| 5074 | + await TryReverseSalesOutboundMemberAndCommissionAsync(row, "审核不通过"); | |
| 5075 | + } | |
| 5076 | + // 退货单:冲回 wt_sp_cost / 序列号还原 / wt_xlh / 会员退回 | |
| 5077 | + else if (rowDjlx == "销售退货单" || rowDjlx == "预售退货单" || rowDjlx.Contains("委托代销退货单")) | |
| 5078 | + { | |
| 5079 | + await RevertSerialNumbersForDeletedReturnAsync(row); | |
| 5080 | + await DeleteWtXlhTrackingForDocumentAsync(row.Id); | |
| 5081 | + await RollbackSpCostOnDelete(row); | |
| 5082 | + if (rowDjlx == "销售退货单" || rowDjlx == "预售退货单") | |
| 5083 | + await TryReverseReturnMemberRefundAsync(row, "审核不通过"); | |
| 5084 | + } | |
| 5085 | + // 采购退货单:冲回 wt_sp_cost | |
| 5086 | + else if (rowDjlx == "采购退货单") | |
| 5087 | + { | |
| 5088 | + await RollbackSpCostOnDelete(row); | |
| 5089 | + } | |
| 5090 | + // 变价调拨单:冲回变价成本 | |
| 5091 | + else if (rowDjlx == "变价调拨单") | |
| 5092 | + { | |
| 5093 | + var mxList = await _db.Queryable<WtXsckdMxEntity>().Where(d => d.Djbh == id).ToListAsync(); | |
| 5094 | + if (mxList.Count > 0) | |
| 5095 | + { | |
| 5096 | + EnsureBjsxColumn(); | |
| 5097 | + EnsureBjhcbColumn(); | |
| 5098 | + await RollbackVariablePriceTransferCost(row, mxList); | |
| 5099 | + } | |
| 5100 | + } | |
| 5101 | + } | |
| 5102 | + | |
| 5103 | + // ★ 更新状态为审核不通过 | |
| 5104 | + AppendApprovalSpbzLine(row, "审核不通过", approvalRemark); | |
| 4446 | 5105 | row.Djzt = "审核不通过"; |
| 4447 | 5106 | row.Shr = userId; |
| 4448 | 5107 | row.Shr1 = null; |
| ... | ... | @@ -4451,10 +5110,6 @@ LIMIT {offset}, {pageSize}"; |
| 4451 | 5110 | .UpdateColumns(x => new { x.Djzt, x.Spbz, x.Shr, x.Shr1, x.Shr2 }) |
| 4452 | 5111 | .ExecuteCommandAsync(); |
| 4453 | 5112 | |
| 4454 | - // 创建退货单时已写入会员余额/积分;审核不通过须冲回,避免反复退审后再退货重复扣减 | |
| 4455 | - if (row.Djlx == "销售退货单" || row.Djlx == "预售退货单") | |
| 4456 | - await TryReverseReturnMemberRefundAsync(row, "审核不通过"); | |
| 4457 | - | |
| 4458 | 5113 | _db.CommitTran(); |
| 4459 | 5114 | return new { success = true, message = "已标记为审核不通过" }; |
| 4460 | 5115 | } |
| ... | ... | @@ -4694,6 +5349,100 @@ LIMIT {offset}, {pageSize}"; |
| 4694 | 5349 | } |
| 4695 | 5350 | } |
| 4696 | 5351 | |
| 5352 | + /// <summary>门店名称去后缀简称,与 <c>wt_ck.F_mdmc</c> 前缀匹配(预售转销售库存校验用)。</summary> | |
| 5353 | + private static string StoreNameToWarehouseStemForPresaleConvert(string mdmc) | |
| 5354 | + { | |
| 5355 | + if (string.IsNullOrWhiteSpace(mdmc)) return ""; | |
| 5356 | + var s = mdmc.Trim(); | |
| 5357 | + var suffixes = new[] | |
| 5358 | + { | |
| 5359 | + "旗舰店", "专卖店", "体验店", "直营店", "加盟店", "概念店", "快闪店", | |
| 5360 | + "店", "厅", "馆", "部", "行", "中心", "超市", "商场", "广场" | |
| 5361 | + }; | |
| 5362 | + foreach (var suf in suffixes.OrderByDescending(x => x.Length)) | |
| 5363 | + { | |
| 5364 | + if (s.EndsWith(suf, StringComparison.Ordinal) && s.Length > suf.Length) | |
| 5365 | + { | |
| 5366 | + s = s.Substring(0, s.Length - suf.Length).Trim(); | |
| 5367 | + break; | |
| 5368 | + } | |
| 5369 | + } | |
| 5370 | + | |
| 5371 | + return s; | |
| 5372 | + } | |
| 5373 | + | |
| 5374 | + /// <summary>门店主键对应的 <c>wt_md.F_MdfzId</c>(无则 null)。</summary> | |
| 5375 | + private async Task<string> ResolveMdfzIdForPresaleConvertAsync(string storeIdTrimmed) | |
| 5376 | + { | |
| 5377 | + if (string.IsNullOrEmpty(storeIdTrimmed)) return null; | |
| 5378 | + var rows = await _db.Queryable<WtMdEntity>() | |
| 5379 | + .Where(m => m.Id == storeIdTrimmed) | |
| 5380 | + .Select(m => m.MdfzId) | |
| 5381 | + .Take(1) | |
| 5382 | + .ToListAsync(); | |
| 5383 | + return rows.Count > 0 ? rows[0] : null; | |
| 5384 | + } | |
| 5385 | + | |
| 5386 | + private async Task<List<string>> GetWarehouseIdsByStoreNameStemForPresaleConvertAsync(string storeId) | |
| 5387 | + { | |
| 5388 | + if (string.IsNullOrWhiteSpace(storeId)) return new List<string>(); | |
| 5389 | + var mdmc = await _db.Queryable<WtMdEntity>() | |
| 5390 | + .Where(m => m.Id == storeId) | |
| 5391 | + .Select(m => m.Mdmc) | |
| 5392 | + .FirstAsync(); | |
| 5393 | + var stem = StoreNameToWarehouseStemForPresaleConvert(mdmc); | |
| 5394 | + if (string.IsNullOrEmpty(stem) || stem.Length < 2) return new List<string>(); | |
| 5395 | + var ids = await _db.Queryable<WtCkEntity>() | |
| 5396 | + .Where(c => c.Mdmc != null && c.Mdmc.StartsWith(stem)) | |
| 5397 | + .Select(c => c.Id) | |
| 5398 | + .ToListAsync(); | |
| 5399 | + return ids | |
| 5400 | + .Where(x => !string.IsNullOrWhiteSpace(x)) | |
| 5401 | + .Select(x => x.Trim()) | |
| 5402 | + .Distinct(StringComparer.OrdinalIgnoreCase) | |
| 5403 | + .ToList(); | |
| 5404 | + } | |
| 5405 | + | |
| 5406 | + /// <summary> | |
| 5407 | + /// 预售转销售时按门店/仓库解析 <c>wt_ck</c> 主键列表(含分组 <c>F_ssmd</c>、<c>ck</c> 即仓库主键、名称前缀兜底),与商品列表库存口径一致。 | |
| 5408 | + /// </summary> | |
| 5409 | + private async Task<List<string>> ResolveWarehouseIdsForPresaleConvertAsync(string storeOrWarehouseId) | |
| 5410 | + { | |
| 5411 | + if (string.IsNullOrWhiteSpace(storeOrWarehouseId)) return new List<string>(); | |
| 5412 | + var sid = storeOrWarehouseId.Trim(); | |
| 5413 | + var byCkId = await _db.Queryable<WtCkEntity>().Where(c => c.Id == sid).Select(c => c.Id).Take(1).ToListAsync(); | |
| 5414 | + if (byCkId.Count > 0) return new List<string> { byCkId[0] }; | |
| 5415 | + | |
| 5416 | + var grp = await ResolveMdfzIdForPresaleConvertAsync(sid); | |
| 5417 | + object pars; | |
| 5418 | + string whereSql; | |
| 5419 | + if (string.IsNullOrEmpty(grp)) | |
| 5420 | + { | |
| 5421 | + whereSql = "(`F_ssmd` = @sid OR FIND_IN_SET(@sid, `F_ssmd`) > 0)"; | |
| 5422 | + pars = new { sid }; | |
| 5423 | + } | |
| 5424 | + else | |
| 5425 | + { | |
| 5426 | + whereSql = | |
| 5427 | + "( (`F_ssmd` = @sid OR FIND_IN_SET(@sid, `F_ssmd`) > 0) OR " + | |
| 5428 | + "(`F_ssmd` = @grp OR FIND_IN_SET(@grp, `F_ssmd`) > 0) )"; | |
| 5429 | + pars = new { sid, grp }; | |
| 5430 | + } | |
| 5431 | + | |
| 5432 | + var ids = await _db.Queryable<WtCkEntity>() | |
| 5433 | + .Where(whereSql, pars) | |
| 5434 | + .Select(c => c.Id) | |
| 5435 | + .ToListAsync(); | |
| 5436 | + var list = ids | |
| 5437 | + .Where(x => !string.IsNullOrWhiteSpace(x)) | |
| 5438 | + .Select(x => x.Trim()) | |
| 5439 | + .Distinct(StringComparer.OrdinalIgnoreCase) | |
| 5440 | + .ToList(); | |
| 5441 | + if (list.Count > 0) return list; | |
| 5442 | + | |
| 5443 | + return await GetWarehouseIdsByStoreNameStemForPresaleConvertAsync(sid); | |
| 5444 | + } | |
| 5445 | + | |
| 4697 | 5446 | /// <summary> |
| 4698 | 5447 | /// 预售出库单转销售出库单 |
| 4699 | 5448 | /// </summary> |
| ... | ... | @@ -4759,54 +5508,38 @@ LIMIT {offset}, {pageSize}"; |
| 4759 | 5508 | return new { success = false, message = "预售出库单明细不存在" }; |
| 4760 | 5509 | } |
| 4761 | 5510 | |
| 4762 | - // 4. 检查库存是否充足 | |
| 5511 | + // 4. 检查在库序列号是否充足(与 Create 明细序列号、商品库存口径一致:分组/门店/仓库主键、名称兜底、in_warehouse 误存门店主键) | |
| 4763 | 5512 | var insufficientStock = new List<string>(); |
| 4764 | - var outStoreId = presaleOrder.Cjck; // 出库门店 | |
| 4765 | - | |
| 4766 | - // 将门店ID转换为仓库ID列表 | |
| 4767 | - var warehouseIds = new List<string>(); | |
| 4768 | - if (!string.IsNullOrEmpty(outStoreId)) | |
| 4769 | - { | |
| 4770 | - warehouseIds = await _db.Queryable<WtCkEntity>() | |
| 4771 | - .Where(c => c.Ssmd == outStoreId) | |
| 4772 | - .Select(c => c.Id) | |
| 4773 | - .ToListAsync(); | |
| 4774 | - } | |
| 4775 | - | |
| 5513 | + var outStoreId = presaleOrder.Cjck; | |
| 5514 | + | |
| 4776 | 5515 | foreach (var detail in presaleDetails) |
| 4777 | 5516 | { |
| 4778 | - if (!string.IsNullOrEmpty(detail.Spbh) && int.TryParse(detail.Sl, out int requiredQty) && requiredQty > 0) | |
| 5517 | + if (string.IsNullOrEmpty(detail.Spbh) || !int.TryParse(detail.Sl, out int requiredQty) || requiredQty <= 0) | |
| 5518 | + continue; | |
| 5519 | + | |
| 5520 | + var detailOutStoreId = !string.IsNullOrEmpty(detail.Ckck) ? detail.Ckck : outStoreId; | |
| 5521 | + | |
| 5522 | + if (string.IsNullOrEmpty(detailOutStoreId)) | |
| 4779 | 5523 | { |
| 4780 | - // 确定出库门店(优先使用明细的ckck,否则使用主表的cjck) | |
| 4781 | - var detailOutStoreId = !string.IsNullOrEmpty(detail.Ckck) ? detail.Ckck : outStoreId; | |
| 4782 | - | |
| 4783 | - if (string.IsNullOrEmpty(detailOutStoreId)) | |
| 4784 | - { | |
| 4785 | - insufficientStock.Add($"{detail.Spmc}(未指定出库门店)"); | |
| 4786 | - continue; | |
| 4787 | - } | |
| 4788 | - | |
| 4789 | - // 查询该门店所属仓库中的可用序列号数量 | |
| 4790 | - var detailWarehouseIds = await _db.Queryable<WtCkEntity>() | |
| 4791 | - .Where(c => c.Ssmd == detailOutStoreId) | |
| 4792 | - .Select(c => c.Id) | |
| 4793 | - .ToListAsync(); | |
| 4794 | - | |
| 4795 | - if (detailWarehouseIds == null || detailWarehouseIds.Count == 0) | |
| 4796 | - { | |
| 4797 | - insufficientStock.Add($"{detail.Spmc}(门店未找到关联的仓库)"); | |
| 4798 | - continue; | |
| 4799 | - } | |
| 4800 | - | |
| 4801 | - var availableCount = await _db.Queryable<WtSerialNumberEntity>() | |
| 4802 | - .Where(s => s.Spbh == detail.Spbh && (s.Status == 0 || s.Status == 3) && detailWarehouseIds.Contains(s.InWarehouse)) | |
| 4803 | - .CountAsync(); | |
| 4804 | - | |
| 4805 | - if (availableCount < requiredQty) | |
| 4806 | - { | |
| 4807 | - insufficientStock.Add($"{detail.Spmc}(需要{requiredQty}个,可用{availableCount}个)"); | |
| 4808 | - } | |
| 5524 | + insufficientStock.Add($"{detail.Spmc}(未指定出库门店)"); | |
| 5525 | + continue; | |
| 4809 | 5526 | } |
| 5527 | + | |
| 5528 | + var detailWarehouseIds = await ResolveWarehouseIdsForPresaleConvertAsync(detailOutStoreId); | |
| 5529 | + if (detailWarehouseIds == null || detailWarehouseIds.Count == 0) | |
| 5530 | + detailWarehouseIds = new List<string> { detailOutStoreId }; | |
| 5531 | + | |
| 5532 | + var whSet = new HashSet<string>( | |
| 5533 | + detailWarehouseIds.Where(x => !string.IsNullOrWhiteSpace(x)).Select(x => x.Trim()), | |
| 5534 | + StringComparer.OrdinalIgnoreCase); | |
| 5535 | + | |
| 5536 | + var availableCount = await _db.Queryable<WtSerialNumberEntity>() | |
| 5537 | + .Where(s => s.Spbh == detail.Spbh && (s.Status == 0 || s.Status == 3) | |
| 5538 | + && (whSet.Contains(s.InWarehouse) || s.InWarehouse == detailOutStoreId)) | |
| 5539 | + .CountAsync(); | |
| 5540 | + | |
| 5541 | + if (availableCount < requiredQty) | |
| 5542 | + insufficientStock.Add($"{detail.Spmc}(需要{requiredQty}个,可用{availableCount}个)"); | |
| 4810 | 5543 | } |
| 4811 | 5544 | |
| 4812 | 5545 | if (insufficientStock.Any()) |
| ... | ... | @@ -4919,7 +5652,16 @@ LIMIT {offset}, {pageSize}"; |
| 4919 | 5652 | Skmx = presaleOrder.Skmx, |
| 4920 | 5653 | Fkmx = presaleOrder.Fkmx |
| 4921 | 5654 | }; |
| 4922 | - | |
| 5655 | + | |
| 5656 | + // 与收银台下单一致:非「后台」来源的销售出库单不走 ERP 待审(见 IsSalesOutboundSkipErpAudit),落库为已审核 | |
| 5657 | + if (IsSalesOutboundSkipErpAudit(newSalesOrder)) | |
| 5658 | + { | |
| 5659 | + var approver = userId ?? ""; | |
| 5660 | + newSalesOrder.Djzt = "已审核"; | |
| 5661 | + newSalesOrder.Shr = approver; | |
| 5662 | + newSalesOrder.Shr1 = approver; | |
| 5663 | + } | |
| 5664 | + | |
| 4923 | 5665 | var newSalesOrderEntity = await _db.Insertable(newSalesOrder).ExecuteReturnEntityAsync(); |
| 4924 | 5666 | |
| 4925 | 5667 | // 7. 创建销售出库单明细并处理序列号 |
| ... | ... | @@ -4975,6 +5717,7 @@ LIMIT {offset}, {pageSize}"; |
| 4975 | 5717 | .ExecuteCommandAsync(); |
| 4976 | 5718 | |
| 4977 | 5719 | totalUpdated += updateCount; |
| 5720 | + await SyncWtXlhOutboundFromSerialTableAsync(newSalesOrderEntity.Id, "销售出库单", newDetail.Spbh); | |
| 4978 | 5721 | } |
| 4979 | 5722 | } |
| 4980 | 5723 | } |
| ... | ... | @@ -5331,7 +6074,7 @@ LIMIT {offset}, {pageSize}"; |
| 5331 | 6074 | { |
| 5332 | 6075 | await _db.Ado.ExecuteCommandAsync( |
| 5333 | 6076 | "INSERT INTO wt_sp_cost (F_Id, spbh, ck, cbj, sl, update_time) VALUES (@id, @spbh, @ck, @cbj, @sl, NOW())", |
| 5334 | - new { id = $"{detail.Spbh}_{detailWarehouse}", spbh = detail.Spbh, ck = detailWarehouse, cbj = purchasePrice, sl = qty }); | |
| 6077 | + new { id = YitIdHelper.NextId().ToString(), spbh = detail.Spbh, ck = detailWarehouse, cbj = purchasePrice, sl = qty }); | |
| 5335 | 6078 | } |
| 5336 | 6079 | } |
| 5337 | 6080 | } |
| ... | ... | @@ -5462,7 +6205,6 @@ LIMIT {offset}, {pageSize}"; |
| 5462 | 6205 | { |
| 5463 | 6206 | if (djlx == "销售出库单" || djlx == "零售单" || djlx == "预售出库单" || djlx == "委托代销发货单") |
| 5464 | 6207 | { |
| 5465 | - // 草稿不扣减账面库存,避免未生效单据影响 wt_sp_cost | |
| 5466 | 6208 | if (isDraft || string.Equals(entity.Djzt, "草稿", StringComparison.Ordinal)) |
| 5467 | 6209 | return; |
| 5468 | 6210 | |
| ... | ... | @@ -5474,16 +6216,9 @@ LIMIT {offset}, {pageSize}"; |
| 5474 | 6216 | if (string.IsNullOrEmpty(detail.Spbh)) continue; |
| 5475 | 6217 | if (!int.TryParse(detail.Sl, out int qty) || qty <= 0) continue; |
| 5476 | 6218 | |
| 5477 | - // 兼容前端传门店ID或仓库ID:按明细仓库优先,其次主表出库仓库 | |
| 5478 | 6219 | var detailStoreOrWarehouseId = !string.IsNullOrEmpty(detail.Ckck) ? detail.Ckck : outStoreId; |
| 5479 | - var warehouseIds = await _db.Queryable<WtCkEntity>() | |
| 5480 | - .Where(c => c.Ssmd == detailStoreOrWarehouseId || c.Id == detailStoreOrWarehouseId) | |
| 5481 | - .Select(c => c.Id) | |
| 5482 | - .ToListAsync(); | |
| 5483 | - if (warehouseIds == null || warehouseIds.Count == 0) | |
| 5484 | - { | |
| 5485 | - warehouseIds = new List<string> { detailStoreOrWarehouseId }; | |
| 5486 | - } | |
| 6220 | + var warehouseIds = await ResolveWarehouseIdsForSpCostFromStoreOrCkAsync(detailStoreOrWarehouseId); | |
| 6221 | + if (warehouseIds.Count == 0) continue; | |
| 5487 | 6222 | |
| 5488 | 6223 | var costResult = await _db.Ado.SqlQueryAsync<decimal?>( |
| 5489 | 6224 | $"SELECT cbj FROM wt_sp_cost WHERE spbh = @spbh AND ck IN ({string.Join(",", warehouseIds.Select((_, i) => $"@ck{i}"))}) AND cbj > 0 LIMIT 1", |
| ... | ... | @@ -5511,48 +6246,56 @@ LIMIT {offset}, {pageSize}"; |
| 5511 | 6246 | } |
| 5512 | 6247 | else |
| 5513 | 6248 | { |
| 5514 | - // 无序列号/不入序列号管理:不能仅用「在库序列数」同步 sl,否则出库后数量不减少 | |
| 5515 | 6249 | await DeductWtSpCostNonSerialOutboundAsync(detail.Spbh, warehouseIds, qty); |
| 5516 | 6250 | } |
| 5517 | 6251 | } |
| 5518 | 6252 | } |
| 5519 | 6253 | else if (djlx == "销售退货单" || djlx == "预售退货单" || djlx == "委托代销退货单") |
| 5520 | 6254 | { |
| 5521 | - var returnWarehouseId = !string.IsNullOrEmpty(entity.Rkck) ? entity.Rkck : entity.Cjck; | |
| 5522 | - if (string.IsNullOrEmpty(returnWarehouseId)) return; | |
| 5523 | - | |
| 6255 | + // 与 ApplySalesReturnSerialRestoreForEntityAsync 一致:优先明细入库仓,避免主表 cjck/rkck 与成本行 ck 不一致导致「退货已审但 wt_sp_cost 未加回」 | |
| 6256 | + if (isDraft || string.Equals(entity.Djzt, "草稿", StringComparison.Ordinal)) | |
| 6257 | + return; | |
| 6258 | + | |
| 5524 | 6259 | foreach (var detail in mxList) |
| 5525 | 6260 | { |
| 5526 | 6261 | if (string.IsNullOrEmpty(detail.Spbh)) continue; |
| 5527 | 6262 | if (!int.TryParse(detail.Sl, out int qty) || qty <= 0) continue; |
| 5528 | - | |
| 5529 | - var existing = await _db.Ado.SqlQueryAsync<dynamic>( | |
| 5530 | - "SELECT sl FROM wt_sp_cost WHERE spbh = @spbh AND ck = @ck LIMIT 1", | |
| 5531 | - new { spbh = detail.Spbh, ck = returnWarehouseId }); | |
| 5532 | - | |
| 5533 | - if (existing != null && existing.Count > 0) | |
| 6263 | + | |
| 6264 | + var rkRaw = !string.IsNullOrEmpty(detail.Rkck) ? detail.Rkck | |
| 6265 | + : (!string.IsNullOrEmpty(detail.Ckck) ? detail.Ckck | |
| 6266 | + : (!string.IsNullOrEmpty(entity.Rkck) ? entity.Rkck : entity.Cjck)); | |
| 6267 | + if (string.IsNullOrWhiteSpace(rkRaw)) continue; | |
| 6268 | + | |
| 6269 | + var warehouseIds = await ResolveWarehouseIdsForSpCostFromStoreOrCkAsync(rkRaw); | |
| 6270 | + if (warehouseIds.Count == 0) continue; | |
| 6271 | + | |
| 6272 | + var strictSerial = await IsProductStrictSerialOutboundAsync(detail.Spbh); | |
| 6273 | + if (strictSerial) | |
| 5534 | 6274 | { |
| 5535 | - await _db.Ado.ExecuteCommandAsync( | |
| 5536 | - "UPDATE wt_sp_cost SET sl = sl + @qty, update_time = NOW() WHERE spbh = @spbh AND ck = @ck", | |
| 5537 | - new { qty, spbh = detail.Spbh, ck = returnWarehouseId }); | |
| 6275 | + foreach (var whId in warehouseIds) | |
| 6276 | + { | |
| 6277 | + var actualCount = await _db.Ado.GetIntAsync( | |
| 6278 | + "SELECT COUNT(*) FROM wt_serial_number WHERE spbh = @spbh AND in_warehouse = @ck AND (status = 0 OR status = 3)", | |
| 6279 | + new SugarParameter[] { new SugarParameter("@spbh", detail.Spbh.Trim()), new SugarParameter("@ck", whId) }); | |
| 6280 | + await _db.Ado.ExecuteCommandAsync( | |
| 6281 | + "UPDATE wt_sp_cost SET sl = @sl, update_time = NOW() WHERE spbh = @spbh AND ck = @ck", | |
| 6282 | + new { sl = actualCount, spbh = detail.Spbh.Trim(), ck = whId }); | |
| 6283 | + } | |
| 6284 | + } | |
| 6285 | + else | |
| 6286 | + { | |
| 6287 | + await RestoreWtSpCostNonSerialOutboundAsync(detail.Spbh.Trim(), warehouseIds, qty); | |
| 5538 | 6288 | } |
| 5539 | 6289 | } |
| 5540 | 6290 | } |
| 5541 | 6291 | else if (djlx == "采购退货单") |
| 5542 | 6292 | { |
| 5543 | - // 采购退货:用退货明细中的单价(即原始采购价)做反向加权平均 | |
| 5544 | 6293 | var outStoreId = entity.Cjck; |
| 5545 | 6294 | if (string.IsNullOrEmpty(outStoreId)) return; |
| 5546 | - | |
| 5547 | - var warehouseIds = await _db.Queryable<WtCkEntity>() | |
| 5548 | - .Where(c => c.Ssmd == outStoreId || c.Id == outStoreId) | |
| 5549 | - .Select(c => c.Id) | |
| 5550 | - .ToListAsync(); | |
| 5551 | - if (warehouseIds == null || warehouseIds.Count == 0) | |
| 5552 | - { | |
| 5553 | - warehouseIds = new List<string> { outStoreId }; | |
| 5554 | - } | |
| 5555 | - | |
| 6295 | + | |
| 6296 | + var warehouseIds = await ResolveWarehouseIdsForSpCostFromStoreOrCkAsync(outStoreId); | |
| 6297 | + if (warehouseIds.Count == 0) return; | |
| 6298 | + | |
| 5556 | 6299 | foreach (var detail in mxList) |
| 5557 | 6300 | { |
| 5558 | 6301 | if (string.IsNullOrEmpty(detail.Spbh)) continue; |
| ... | ... | @@ -5719,12 +6462,8 @@ LIMIT {offset}, {pageSize}"; |
| 5719 | 6462 | if (!int.TryParse(detail.Sl, out int qty) || qty <= 0) continue; |
| 5720 | 6463 | |
| 5721 | 6464 | var detailStoreOrWarehouseId = !string.IsNullOrEmpty(detail.Ckck) ? detail.Ckck : outStoreId; |
| 5722 | - var warehouseIds = await _db.Queryable<WtCkEntity>() | |
| 5723 | - .Where(c => c.Ssmd == detailStoreOrWarehouseId || c.Id == detailStoreOrWarehouseId) | |
| 5724 | - .Select(c => c.Id) | |
| 5725 | - .ToListAsync(); | |
| 5726 | - if (warehouseIds == null || warehouseIds.Count == 0) | |
| 5727 | - warehouseIds = new List<string> { detailStoreOrWarehouseId.Trim() }; | |
| 6465 | + var warehouseIds = await ResolveWarehouseIdsForSpCostFromStoreOrCkAsync(detailStoreOrWarehouseId); | |
| 6466 | + if (warehouseIds.Count == 0) continue; | |
| 5728 | 6467 | |
| 5729 | 6468 | var strictSerial = await IsProductStrictSerialOutboundAsync(detail.Spbh); |
| 5730 | 6469 | if (strictSerial) |
| ... | ... | @@ -5747,9 +6486,6 @@ LIMIT {offset}, {pageSize}"; |
| 5747 | 6486 | } |
| 5748 | 6487 | else if (djlx == "销售退货单" || djlx == "预售退货单" || djlx == "委托代销退货单") |
| 5749 | 6488 | { |
| 5750 | - var returnWarehouseId = !string.IsNullOrEmpty(entity.Rkck) ? entity.Rkck : entity.Cjck; | |
| 5751 | - if (string.IsNullOrEmpty(returnWarehouseId)) return; | |
| 5752 | - | |
| 5753 | 6489 | var mxList = await _db.Queryable<WtXsckdMxEntity>() |
| 5754 | 6490 | .Where(d => d.Djbh == id).ToListAsync(); |
| 5755 | 6491 | |
| ... | ... | @@ -5758,23 +6494,40 @@ LIMIT {offset}, {pageSize}"; |
| 5758 | 6494 | if (string.IsNullOrEmpty(detail.Spbh)) continue; |
| 5759 | 6495 | if (!int.TryParse(detail.Sl, out int qty) || qty <= 0) continue; |
| 5760 | 6496 | |
| 5761 | - await _db.Ado.ExecuteCommandAsync( | |
| 5762 | - "UPDATE wt_sp_cost SET sl = sl - @qty, update_time = NOW() WHERE spbh = @spbh AND ck = @ck", | |
| 5763 | - new { qty, spbh = detail.Spbh, ck = returnWarehouseId }); | |
| 6497 | + var rkRaw = !string.IsNullOrEmpty(detail.Rkck) ? detail.Rkck | |
| 6498 | + : (!string.IsNullOrEmpty(detail.Ckck) ? detail.Ckck | |
| 6499 | + : (!string.IsNullOrEmpty(entity.Rkck) ? entity.Rkck : entity.Cjck)); | |
| 6500 | + if (string.IsNullOrWhiteSpace(rkRaw)) continue; | |
| 6501 | + | |
| 6502 | + var warehouseIds = await ResolveWarehouseIdsForSpCostFromStoreOrCkAsync(rkRaw); | |
| 6503 | + if (warehouseIds.Count == 0) continue; | |
| 6504 | + | |
| 6505 | + var strictSerial = await IsProductStrictSerialOutboundAsync(detail.Spbh); | |
| 6506 | + if (strictSerial) | |
| 6507 | + { | |
| 6508 | + foreach (var whId in warehouseIds) | |
| 6509 | + { | |
| 6510 | + var actualCount = await _db.Ado.GetIntAsync( | |
| 6511 | + "SELECT COUNT(*) FROM wt_serial_number WHERE spbh = @spbh AND in_warehouse = @ck AND (status = 0 OR status = 3)", | |
| 6512 | + new SugarParameter[] { new SugarParameter("@spbh", detail.Spbh.Trim()), new SugarParameter("@ck", whId) }); | |
| 6513 | + await _db.Ado.ExecuteCommandAsync( | |
| 6514 | + "UPDATE wt_sp_cost SET sl = @sl, update_time = NOW() WHERE spbh = @spbh AND ck = @ck", | |
| 6515 | + new { sl = actualCount, spbh = detail.Spbh.Trim(), ck = whId }); | |
| 6516 | + } | |
| 6517 | + } | |
| 6518 | + else | |
| 6519 | + { | |
| 6520 | + await DeductWtSpCostNonSerialOutboundAsync(detail.Spbh.Trim(), warehouseIds, qty); | |
| 6521 | + } | |
| 5764 | 6522 | } |
| 5765 | 6523 | } |
| 5766 | 6524 | else if (djlx == "采购退货单") |
| 5767 | 6525 | { |
| 5768 | - // 采购退货单删除:恢复成本(反向操作,相当于再入库) | |
| 5769 | 6526 | var outStoreId = entity.Cjck; |
| 5770 | 6527 | if (string.IsNullOrEmpty(outStoreId)) return; |
| 5771 | - | |
| 5772 | - var warehouseIds = await _db.Queryable<WtCkEntity>() | |
| 5773 | - .Where(c => c.Ssmd == outStoreId || c.Id == outStoreId) | |
| 5774 | - .Select(c => c.Id) | |
| 5775 | - .ToListAsync(); | |
| 5776 | - if (warehouseIds == null || warehouseIds.Count == 0) | |
| 5777 | - warehouseIds = new List<string> { outStoreId }; | |
| 6528 | + | |
| 6529 | + var warehouseIds = await ResolveWarehouseIdsForSpCostFromStoreOrCkAsync(outStoreId); | |
| 6530 | + if (warehouseIds.Count == 0) return; | |
| 5778 | 6531 | |
| 5779 | 6532 | var mxList = await _db.Queryable<WtXsckdMxEntity>() |
| 5780 | 6533 | .Where(d => d.Djbh == id).ToListAsync(); |
| ... | ... | @@ -5850,18 +6603,13 @@ LIMIT {offset}, {pageSize}"; |
| 5850 | 6603 | } |
| 5851 | 6604 | |
| 5852 | 6605 | /// <summary> |
| 5853 | - /// 将门店ID或仓库ID解析为仓库ID列表(与同价/销售成本逻辑一致) | |
| 6606 | + /// 将门店ID或仓库ID解析为仓库ID列表(委托至统一解析方法,与商品列表展示口径一致) | |
| 5854 | 6607 | /// </summary> |
| 5855 | 6608 | private async Task<List<string>> ResolveWarehouseIdListAsync(string storeOrWarehouseId) |
| 5856 | 6609 | { |
| 5857 | 6610 | if (string.IsNullOrEmpty(storeOrWarehouseId)) return new List<string>(); |
| 5858 | - var warehouseIds = await _db.Queryable<WtCkEntity>() | |
| 5859 | - .Where(c => c.Ssmd == storeOrWarehouseId || c.Id == storeOrWarehouseId) | |
| 5860 | - .Select(c => c.Id) | |
| 5861 | - .ToListAsync(); | |
| 5862 | - if (warehouseIds == null || warehouseIds.Count == 0) | |
| 5863 | - warehouseIds = new List<string> { storeOrWarehouseId }; | |
| 5864 | - return warehouseIds; | |
| 6611 | + var ids = await ResolveWarehouseIdsForSpCostFromStoreOrCkAsync(storeOrWarehouseId.Trim()); | |
| 6612 | + return ids.Count > 0 ? ids : new List<string> { storeOrWarehouseId.Trim() }; | |
| 5865 | 6613 | } |
| 5866 | 6614 | |
| 5867 | 6615 | /// <summary> |
| ... | ... | @@ -6035,10 +6783,9 @@ LIMIT {offset}, {pageSize}"; |
| 6035 | 6783 | return; |
| 6036 | 6784 | } |
| 6037 | 6785 | |
| 6038 | - var rowId = $"{spbh}_{ck}"; | |
| 6039 | 6786 | await _db.Ado.ExecuteCommandAsync( |
| 6040 | 6787 | "INSERT INTO wt_sp_cost (F_Id, spbh, ck, cbj, sl, update_time) VALUES (@id, @spbh, @ck, @cbj, @sl, NOW())", |
| 6041 | - new { id = rowId, spbh, ck, cbj = 0m, sl = qty }); | |
| 6788 | + new { id = YitIdHelper.NextId().ToString(), spbh, ck, cbj = 0m, sl = qty }); | |
| 6042 | 6789 | } |
| 6043 | 6790 | |
| 6044 | 6791 | /// <summary> |
| ... | ... | @@ -6120,10 +6867,9 @@ LIMIT {offset}, {pageSize}"; |
| 6120 | 6867 | } |
| 6121 | 6868 | else |
| 6122 | 6869 | { |
| 6123 | - var rowId = $"{spbh}_{ck}"; | |
| 6124 | 6870 | await _db.Ado.ExecuteCommandAsync( |
| 6125 | 6871 | "INSERT INTO wt_sp_cost (F_Id, spbh, ck, cbj, sl, update_time) VALUES (@id, @spbh, @ck, @cbj, @sl, NOW())", |
| 6126 | - new { id = rowId, spbh, ck, cbj = unitPrice, sl = qty }); | |
| 6872 | + new { id = YitIdHelper.NextId().ToString(), spbh, ck, cbj = unitPrice, sl = qty }); | |
| 6127 | 6873 | } |
| 6128 | 6874 | } |
| 6129 | 6875 | ... | ... |
Antis.Erp.Plat/sy/home.html
| ... | ... | @@ -1457,7 +1457,20 @@ |
| 1457 | 1457 | |
| 1458 | 1458 | const existingItem = this.addgoodlist.find((listItem) => listItem.id === item.id); |
| 1459 | 1459 | if (existingItem) { |
| 1460 | + if (item.mdkc !== undefined && item.mdkc !== null) { | |
| 1461 | + existingItem.mdkc = item.mdkc; | |
| 1462 | + } | |
| 1460 | 1463 | existingItem.quantity += 1; |
| 1464 | + const idx = this.addgoodlist.indexOf(existingItem); | |
| 1465 | + if (!(existingItem.isPackageItem && existingItem.packageId)) { | |
| 1466 | + if (!existingItem.isPresale && this.parseMdkcNumber(existingItem.mdkc) > 0 && | |
| 1467 | + existingItem.quantity > this.parseMdkcNumber(existingItem.mdkc)) { | |
| 1468 | + if (!this.splitLineIfStockInsufficient(existingItem, idx)) { | |
| 1469 | + existingItem.quantity -= 1; | |
| 1470 | + return; | |
| 1471 | + } | |
| 1472 | + } | |
| 1473 | + } | |
| 1461 | 1474 | // 如果之前不是预售,这次又判定为预售,则补上标记 |
| 1462 | 1475 | if (isPresale) { |
| 1463 | 1476 | existingItem.isPresale = true; |
| ... | ... | @@ -2053,6 +2066,41 @@ |
| 2053 | 2066 | this.ontype = type; |
| 2054 | 2067 | this.getGoodsList() |
| 2055 | 2068 | }, |
| 2069 | + /** 解析商品列表上的门店可售库存(与 WtSp mdkc 一致,向下取整) */ | |
| 2070 | + parseMdkcNumber(mdkc) { | |
| 2071 | + const n = parseFloat(mdkc); | |
| 2072 | + if (isNaN(n) || n < 0) return 0; | |
| 2073 | + return Math.floor(n); | |
| 2074 | + }, | |
| 2075 | + /** | |
| 2076 | + * 同一行 quantity 超过门店库存时拆成两行:现货 + 预售(仅单品,不含套餐子行)。 | |
| 2077 | + * @returns {boolean} true 已拆分或无需拆分;false 用户取消确认 | |
| 2078 | + */ | |
| 2079 | + splitLineIfStockInsufficient(item, index) { | |
| 2080 | + if (!item || (item.isPackageItem && item.packageId)) return true; | |
| 2081 | + if (item.isPresale) return true; | |
| 2082 | + const cap = this.parseMdkcNumber(item.mdkc); | |
| 2083 | + const q = parseInt(item.quantity, 10) || 0; | |
| 2084 | + if (cap <= 0 || q <= cap) return true; | |
| 2085 | + const over = q - cap; | |
| 2086 | + if (!window.confirm( | |
| 2087 | + `该商品门店现货仅 ${cap} 件,您要了 ${q} 件;多出的 ${over} 件将生成「预售出库单」(到货后再出库)。\n\n是否按此拆分继续?` | |
| 2088 | + )) { | |
| 2089 | + return false; | |
| 2090 | + } | |
| 2091 | + item.quantity = cap; | |
| 2092 | + if (item.selectedSerialNumbers && item.selectedSerialNumbers.length > cap) { | |
| 2093 | + item.selectedSerialNumbers = item.selectedSerialNumbers.slice(0, cap); | |
| 2094 | + } | |
| 2095 | + const presaleLine = Object.assign({}, item, { | |
| 2096 | + quantity: over, | |
| 2097 | + isPresale: true, | |
| 2098 | + selectedSerialNumbers: [] | |
| 2099 | + }); | |
| 2100 | + this.addgoodlist.splice(index + 1, 0, presaleLine); | |
| 2101 | + this.showPosToast(`已拆分:现货 ${cap} 件 + 预售 ${over} 件`); | |
| 2102 | + return true; | |
| 2103 | + }, | |
| 2056 | 2104 | decreaseQuantity(item, index) { |
| 2057 | 2105 | if (this.addgoodlist[index].quantity > 1) { |
| 2058 | 2106 | this.addgoodlist[index].quantity--; |
| ... | ... | @@ -2060,6 +2108,14 @@ |
| 2060 | 2108 | }, |
| 2061 | 2109 | increaseQuantity(item, index) { |
| 2062 | 2110 | this.addgoodlist[index].quantity++; |
| 2111 | + const row = this.addgoodlist[index]; | |
| 2112 | + if (!row.isPackageItem || !row.packageId) { | |
| 2113 | + if (!row.isPresale && this.parseMdkcNumber(row.mdkc) > 0 && row.quantity > this.parseMdkcNumber(row.mdkc)) { | |
| 2114 | + if (!this.splitLineIfStockInsufficient(row, index)) { | |
| 2115 | + this.addgoodlist[index].quantity--; | |
| 2116 | + } | |
| 2117 | + } | |
| 2118 | + } | |
| 2063 | 2119 | }, |
| 2064 | 2120 | deleteProduct(index) { |
| 2065 | 2121 | var item = this.addgoodlist[index]; | ... | ... |
Antis.Erp.Plat/sy/login.html
| ... | ... | @@ -186,13 +186,26 @@ |
| 186 | 186 | axios({ |
| 187 | 187 | url: that.baseUrl + "/api/Extend/WtMd", |
| 188 | 188 | method: 'GET', |
| 189 | + // 列表接口分页:不传 pageSize 时后端默认 50,门店多于 50 时登录页显示不全 | |
| 190 | + params: { | |
| 191 | + currentPage: 1, | |
| 192 | + pageSize: 2000, | |
| 193 | + sort: 'asc', | |
| 194 | + sidx: 'mdmc' | |
| 195 | + }, | |
| 189 | 196 | headers: { |
| 190 | 197 | 'accept': 'text/plain', |
| 191 | 198 | 'Content-Type': 'application/json', |
| 192 | 199 | } |
| 193 | 200 | }).then((res) => { |
| 194 | 201 | if (res.data.code === 200) { |
| 195 | - that.storeList = res.data.data.list || []; | |
| 202 | + var raw = res.data.data.list || []; | |
| 203 | + // 门店主键必须当字符串用,避免 JSON 数字精度丢失导致与后台 wt_skzhb.ssmd 对不上 | |
| 204 | + that.storeList = raw.map(function (s) { | |
| 205 | + var o = Object.assign({}, s); | |
| 206 | + if (o.id != null && o.id !== '') o.id = String(o.id); | |
| 207 | + return o; | |
| 208 | + }); | |
| 196 | 209 | console.log('门店列表加载成功:', that.storeList); |
| 197 | 210 | } else { |
| 198 | 211 | console.error('获取门店列表失败:', res.data); |
| ... | ... | @@ -284,8 +297,10 @@ |
| 284 | 297 | return that.storeIdStr(store.id) === that.storeIdStr(that.selectedStore); |
| 285 | 298 | }); |
| 286 | 299 | if (selectedStoreInfo) { |
| 287 | - localStorage.setItem('selectedStore', JSON.stringify(selectedStoreInfo)); | |
| 288 | - console.log('门店信息已存储:', selectedStoreInfo); | |
| 300 | + var toSave = Object.assign({}, selectedStoreInfo); | |
| 301 | + if (toSave.id != null && toSave.id !== '') toSave.id = String(toSave.id); | |
| 302 | + localStorage.setItem('selectedStore', JSON.stringify(toSave)); | |
| 303 | + console.log('门店信息已存储:', toSave); | |
| 289 | 304 | } |
| 290 | 305 | // window.alert('登录成功') |
| 291 | 306 | axios({ |
| ... | ... | @@ -299,7 +314,7 @@ |
| 299 | 314 | if (res2.data.code === 200) { |
| 300 | 315 | // 使用用户选择的门店ID,而不是用户信息中的默认门店 |
| 301 | 316 | // 这样收银员可以选择任意门店进行收银 |
| 302 | - const storeIdToUse = that.selectedStore || res2.data.data.mdxx; | |
| 317 | + const storeIdToUse = String(that.selectedStore || res2.data.data.mdxx || '').trim(); | |
| 303 | 318 | localStorage.setItem('mdId', storeIdToUse); |
| 304 | 319 | axios({ |
| 305 | 320 | url: this.baseUrl + "/api/Extend/WtCk?pageSize=1&ssmd=" + storeIdToUse, | ... | ... |
Antis.Erp.Plat/sy/orders.html
| ... | ... | @@ -1056,8 +1056,8 @@ |
| 1056 | 1056 | {{order.djlx}} |
| 1057 | 1057 | </div> |
| 1058 | 1058 | </div> |
| 1059 | - <div class="order-status" :class="getStatusClass(order.djzt)"> | |
| 1060 | - {{order.djzt || '待审核'}} | |
| 1059 | + <div class="order-status" :class="getPresaleListStatusClass(order)"> | |
| 1060 | + {{ getPresaleListStatusText(order) }} | |
| 1061 | 1061 | </div> |
| 1062 | 1062 | </div> |
| 1063 | 1063 | |
| ... | ... | @@ -1240,7 +1240,7 @@ |
| 1240 | 1240 | </div> |
| 1241 | 1241 | <div class="detail-info-item"> |
| 1242 | 1242 | <span class="detail-info-label">单据状态:</span> |
| 1243 | - <span class="detail-info-value" :style="{color: orderDetail.djzt === '已过账' ? '#52c41a' : (orderDetail.djzt === '草稿' ? '#ff9800' : '#666')}">{{orderDetail.djzt || '待审核'}}</span> | |
| 1243 | + <span class="detail-info-value" :style="detailOrderStatusStyle">{{ detailOrderStatusText }}</span> | |
| 1244 | 1244 | </div> |
| 1245 | 1245 | <div class="detail-info-item"> |
| 1246 | 1246 | <span class="detail-info-label">出库仓库:</span> |
| ... | ... | @@ -2647,6 +2647,16 @@ |
| 2647 | 2647 | if (status === '草稿') return 'status-draft'; |
| 2648 | 2648 | return ''; |
| 2649 | 2649 | }, |
| 2650 | + /** 预售列表:已转销售的单据库内 djzt 可能仍为待审核,与 ERP「无需审核」语义对齐展示 */ | |
| 2651 | + getPresaleListStatusText(order) { | |
| 2652 | + if (!order) return '待审核'; | |
| 2653 | + if (this.parsePresaleConvertedChdId(order.bz)) return '已转销售'; | |
| 2654 | + return order.djzt || '待审核'; | |
| 2655 | + }, | |
| 2656 | + getPresaleListStatusClass(order) { | |
| 2657 | + if (this.parsePresaleConvertedChdId(order && order.bz)) return 'status-completed'; | |
| 2658 | + return this.getStatusClass(order && order.djzt); | |
| 2659 | + }, | |
| 2650 | 2660 | // ✅ 查看订单详情 |
| 2651 | 2661 | async viewDetails(order) { |
| 2652 | 2662 | this.detailModalVisible = true; |
| ... | ... | @@ -3304,6 +3314,24 @@ |
| 3304 | 3314 | if (lx !== '预售出库单' && lx !== '预售单') return ''; |
| 3305 | 3315 | return this.parsePresaleConvertedChdId(this.orderDetail.bz); |
| 3306 | 3316 | }, |
| 3317 | + /** 详情弹窗「单据状态」:已转销售预售单展示业务态,与列表一致 */ | |
| 3318 | + detailOrderStatusText() { | |
| 3319 | + if (!this.orderDetail) return '待审核'; | |
| 3320 | + const lx = String(this.orderDetail.djlx || '').trim(); | |
| 3321 | + if ((lx === '预售出库单' || lx === '预售单') && this.parsePresaleConvertedChdId(this.orderDetail.bz)) | |
| 3322 | + return '已转销售'; | |
| 3323 | + return this.orderDetail.djzt || '待审核'; | |
| 3324 | + }, | |
| 3325 | + detailOrderStatusStyle() { | |
| 3326 | + if (!this.orderDetail) return { color: '#666' }; | |
| 3327 | + const z = this.orderDetail.djzt; | |
| 3328 | + if (z === '已过账') return { color: '#52c41a' }; | |
| 3329 | + if (z === '草稿') return { color: '#ff9800' }; | |
| 3330 | + const lx = String(this.orderDetail.djlx || '').trim(); | |
| 3331 | + if ((lx === '预售出库单' || lx === '预售单') && this.parsePresaleConvertedChdId(this.orderDetail.bz)) | |
| 3332 | + return { color: '#52c41a' }; | |
| 3333 | + return { color: '#666' }; | |
| 3334 | + }, | |
| 3307 | 3335 | /** 详情底部:当前单可直接发起退货(未转销售的预售/销售出库单) */ |
| 3308 | 3336 | detailCanInitiateReturn() { |
| 3309 | 3337 | if (!this.orderDetail || this.loadingDetail) return false; | ... | ... |
Antis.Erp.Plat/sy/settlement.html
| ... | ... | @@ -4058,8 +4058,8 @@ |
| 4058 | 4058 | :class="{ 'is-selected': String(payment.skzh || '') === String(accountDictId(acc)) }" |
| 4059 | 4059 | @click.stop="selectComboPaymentAccount(index, acc)" |
| 4060 | 4060 | > |
| 4061 | - <img :src="getAccountIcon(acc.zhmc)" class="combo-account-chip-icon" alt="" /> | |
| 4062 | - <span>{{ acc.zhmc }}</span> | |
| 4061 | + <img :src="getAccountIcon(accountRowCaption(acc))" class="combo-account-chip-icon" alt="" /> | |
| 4062 | + <span>{{ accountRowCaption(acc) }}</span> | |
| 4063 | 4063 | </button> |
| 4064 | 4064 | </div> |
| 4065 | 4065 | </div> |
| ... | ... | @@ -4646,14 +4646,17 @@ |
| 4646 | 4646 | }, |
| 4647 | 4647 | /** 左侧摘要:入账账户展示名 */ |
| 4648 | 4648 | directReceiptCaption() { |
| 4649 | - if (this.lastDirectAccount && this.lastDirectAccount.zhmc) return this.lastDirectAccount.zhmc; | |
| 4649 | + if (this.lastDirectAccount) { | |
| 4650 | + var c = this.accountRowCaption(this.lastDirectAccount); | |
| 4651 | + if (c !== '无') return c; | |
| 4652 | + } | |
| 4650 | 4653 | if (this.info.skzh === '余额') return '余额'; |
| 4651 | 4654 | const sk = this.info.skzh; |
| 4652 | 4655 | if (!sk) return '无'; |
| 4653 | 4656 | const acc = (this.accountList || []).find(a => |
| 4654 | 4657 | String(this.accountDictId(a)) === String(sk) || String(a.id) === String(sk) |
| 4655 | 4658 | ); |
| 4656 | - if (acc) return acc.zhmc; | |
| 4659 | + if (acc) return this.accountRowCaption(acc); | |
| 4657 | 4660 | return sk; |
| 4658 | 4661 | } |
| 4659 | 4662 | }, |
| ... | ... | @@ -4759,7 +4762,7 @@ |
| 4759 | 4762 | if (!row || !row.skzh) return '无'; |
| 4760 | 4763 | var id = String(row.skzh); |
| 4761 | 4764 | var acc = (this.accountList || []).find(a => String(this.accountDictId(a)) === id || String(a.id) === id); |
| 4762 | - if (acc) return acc.zhmc; | |
| 4765 | + if (acc) return this.accountRowCaption(acc); | |
| 4763 | 4766 | return id; |
| 4764 | 4767 | }, |
| 4765 | 4768 | /** skmx 预览行:入账账户展示名 */ |
| ... | ... | @@ -4767,7 +4770,7 @@ |
| 4767 | 4770 | if (!row || !row.skzh) return '无'; |
| 4768 | 4771 | var id = String(row.skzh); |
| 4769 | 4772 | var acc = (this.accountList || []).find(a => String(this.accountDictId(a)) === id || String(a.id) === id); |
| 4770 | - if (acc) return acc.zhmc; | |
| 4773 | + if (acc) return this.accountRowCaption(acc); | |
| 4771 | 4774 | return id; |
| 4772 | 4775 | }, |
| 4773 | 4776 | fillLineRemaining(index) { |
| ... | ... | @@ -4890,7 +4893,9 @@ |
| 4890 | 4893 | if (!sk || sk === '组合支付' || sk === '余额') return ''; |
| 4891 | 4894 | const s = String(sk).trim(); |
| 4892 | 4895 | if (/^\d{10,}$/.test(s)) return s; |
| 4893 | - const acc = (this.accountList || []).find(a => a.zhmc === sk); | |
| 4896 | + const acc = (this.accountList || []).find(a => | |
| 4897 | + a.zhmc === sk || this.accountRowCaption(a) === sk || String(this.accountDictId(a)) === s | |
| 4898 | + ); | |
| 4894 | 4899 | return acc ? this.accountDictId(acc) : ''; |
| 4895 | 4900 | }, |
| 4896 | 4901 | /** |
| ... | ... | @@ -5023,22 +5028,25 @@ |
| 5023 | 5028 | }); |
| 5024 | 5029 | return cents / 100; |
| 5025 | 5030 | }, |
| 5026 | - // ✅ 获取当前选择的门店ID(登录时选择的门店) | |
| 5031 | + // ✅ 获取当前选择的门店ID(登录时选择的门店;统一为字符串,避免大整数精度丢失) | |
| 5027 | 5032 | getSelectedStoreId() { |
| 5028 | 5033 | try { |
| 5029 | 5034 | const selectedStore = localStorage.getItem('selectedStore'); |
| 5030 | 5035 | if (selectedStore) { |
| 5031 | 5036 | const store = JSON.parse(selectedStore); |
| 5032 | - return store.id; | |
| 5037 | + if (store && store.id != null && String(store.id).trim() !== '') return String(store.id).trim(); | |
| 5038 | + if (store && store.Id != null && String(store.Id).trim() !== '') return String(store.Id).trim(); | |
| 5033 | 5039 | } |
| 5034 | 5040 | } catch (e) { |
| 5035 | 5041 | console.warn('无法获取 selectedStore:', e); |
| 5036 | 5042 | } |
| 5037 | - // 降级方案:使用导购员的门店 | |
| 5043 | + var mdId = localStorage.getItem('mdId'); | |
| 5044 | + if (mdId != null && String(mdId).trim() !== '') return String(mdId).trim(); | |
| 5038 | 5045 | try { |
| 5039 | 5046 | const ckinfo = localStorage.getItem('ckinfo'); |
| 5040 | 5047 | if (ckinfo) { |
| 5041 | - return JSON.parse(ckinfo).id; | |
| 5048 | + const ck = JSON.parse(ckinfo); | |
| 5049 | + if (ck && ck.id != null) return String(ck.id).trim(); | |
| 5042 | 5050 | } |
| 5043 | 5051 | } catch (e) { |
| 5044 | 5052 | console.warn('无法获取 ckinfo:', e); |
| ... | ... | @@ -5081,15 +5089,9 @@ |
| 5081 | 5089 | // ✅ 加载账户列表(根据门店过滤) |
| 5082 | 5090 | async loadAccountList() { |
| 5083 | 5091 | try { |
| 5084 | - // 获取登录时选择的门店ID | |
| 5085 | 5092 | const storeId = this.getSelectedStoreId(); |
| 5086 | - | |
| 5087 | - // 调用账户核销表API,根据门店过滤 | |
| 5088 | - const params = {}; | |
| 5089 | - if (storeId) { | |
| 5090 | - params.ssmd = storeId; | |
| 5091 | - } | |
| 5092 | - | |
| 5093 | + const params = { currentPage: 1, pageSize: 500, sort: 'desc', sidx: 'id' }; | |
| 5094 | + if (storeId) params.ssmd = storeId; | |
| 5093 | 5095 | const response = await axios({ |
| 5094 | 5096 | url: this.baseUrl + "/api/Extend/WtSkzhb", |
| 5095 | 5097 | method: 'GET', |
| ... | ... | @@ -5098,11 +5100,11 @@ |
| 5098 | 5100 | Authorization: localStorage.getItem('token') |
| 5099 | 5101 | } |
| 5100 | 5102 | }); |
| 5101 | - | |
| 5102 | 5103 | if (response.data.code === 200) { |
| 5103 | - // 从分页结果中获取列表 | |
| 5104 | - this.accountList = response.data.data.list || []; | |
| 5105 | - console.log('✅ 加载账户列表成功(门店过滤):', this.accountList); | |
| 5104 | + var inner = response.data.data; | |
| 5105 | + var list = (inner && inner.list) || response.data.list || []; | |
| 5106 | + this.accountList = list; | |
| 5107 | + console.log('✅ 加载账户列表 门店=' + (storeId || '未传') + ' 条数=' + list.length, list); | |
| 5106 | 5108 | } else { |
| 5107 | 5109 | console.error('❌ 加载账户列表失败:', response.data.msg); |
| 5108 | 5110 | this.accountList = []; |
| ... | ... | @@ -5112,6 +5114,15 @@ |
| 5112 | 5114 | this.accountList = []; |
| 5113 | 5115 | } |
| 5114 | 5116 | }, |
| 5117 | + /** 入账账户卡片展示名(接口 zhmc 可能为空时兜底) */ | |
| 5118 | + accountRowCaption(acc) { | |
| 5119 | + if (!acc) return '无'; | |
| 5120 | + var z = acc.zhmc != null ? String(acc.zhmc).trim() : ''; | |
| 5121 | + if (z) return z; | |
| 5122 | + var sid = acc.skzhDictId != null ? String(acc.skzhDictId).trim() : ''; | |
| 5123 | + if (sid) return '账户 ' + sid; | |
| 5124 | + return '无'; | |
| 5125 | + }, | |
| 5115 | 5126 | |
| 5116 | 5127 | // ✅ 根据账户名称获取图标路径 |
| 5117 | 5128 | getAccountIcon(accountName) { |
| ... | ... | @@ -5141,17 +5152,18 @@ |
| 5141 | 5152 | return 'images/member16.png'; |
| 5142 | 5153 | }, |
| 5143 | 5154 | |
| 5144 | - // ✅ 处理账户点击事件 | |
| 5155 | + // ✅ 处理账户点击事件(允许接口未解析出 zhmc,只要有 skzhDictId 即可) | |
| 5145 | 5156 | selectAccount(account) { |
| 5146 | - if (!account || !account.zhmc) { | |
| 5147 | - return; | |
| 5148 | - } | |
| 5157 | + if (!account) return; | |
| 5158 | + var zhid = this.accountDictId(account); | |
| 5159 | + if (!zhid) return; | |
| 5160 | + var cap = this.accountRowCaption(account); | |
| 5149 | 5161 | this.lastDirectAccount = { |
| 5150 | 5162 | id: account.id, |
| 5151 | - zhmc: account.zhmc, | |
| 5163 | + zhmc: cap !== '无' ? cap : zhid, | |
| 5152 | 5164 | skzhDictId: account.skzhDictId |
| 5153 | 5165 | }; |
| 5154 | - this.info.skzh = account.zhmc; | |
| 5166 | + this.info.skzh = cap !== '无' ? cap : zhid; | |
| 5155 | 5167 | }, |
| 5156 | 5168 | |
| 5157 | 5169 | // 新增方法 |
| ... | ... | @@ -5743,6 +5755,21 @@ |
| 5743 | 5755 | return orders; |
| 5744 | 5756 | }; |
| 5745 | 5757 | |
| 5758 | + // ✅ 拆单前提示:仅「同一笔收款里既有现货又有预售」时确认(纯预售在收银首页加购时已提示过) | |
| 5759 | + if (presaleItems.length > 0 && inStockItems.length > 0) { | |
| 5760 | + const presaleNames = presaleItems.map(function (i) { return i.spmc || i.spbm || '商品'; }); | |
| 5761 | + var uniqNames = []; | |
| 5762 | + presaleNames.forEach(function (n) { | |
| 5763 | + if (uniqNames.indexOf(n) < 0) uniqNames.push(n); | |
| 5764 | + }); | |
| 5765 | + var nameStr = uniqNames.slice(0, 5).join('、') + (uniqNames.length > 5 ? '…' : ''); | |
| 5766 | + if (!window.confirm( | |
| 5767 | + '部分商品超过门店现货数量,本笔将同时生成「销售出库单」与「预售出库单」。\n\n预售涉及:' + nameStr + '\n\n确认按此拆单并继续收款?' | |
| 5768 | + )) { | |
| 5769 | + return; | |
| 5770 | + } | |
| 5771 | + } | |
| 5772 | + | |
| 5746 | 5773 | // ✅ 执行创建订单 |
| 5747 | 5774 | createOrders().then(async (orders) => { |
| 5748 | 5775 | if (orders.length > 0) { |
| ... | ... | @@ -5822,6 +5849,7 @@ |
| 5822 | 5849 | this.activePaymentLineIndex = this.paymentCombinations.length - 1; |
| 5823 | 5850 | this.selectedPaymentMethod = method; |
| 5824 | 5851 | this.selectedPaymentAmount = ''; |
| 5852 | + if (method === '入账账户') this.loadAccountList(); | |
| 5825 | 5853 | }, |
| 5826 | 5854 | removePaymentMethod(index) { |
| 5827 | 5855 | this.paymentCombinations.splice(index, 1); | ... | ... |