Commit 051dc19f60d48fa168aee824a30f1185bb06ed1c

Authored by “wangming”
1 parent 60226f15

修改了东西

Antis.Erp.Plat/antis-ncc-admin/src/views/wtBjdbd/index.vue
1 1 <template>
2   - <div class="NCC-common-layout">
  2 + <div class="NCC-common-layout wt-bjdbd-list">
3 3 <div class="NCC-common-layout-center">
4 4 <el-row class="NCC-common-search-box" :gutter="16">
5 5 <el-form @submit.native.prevent>
6 6 <el-col :span="6">
7 7 <el-form-item label="单据编号">
8   - <el-input v-model="query.id" placeholder="单据编号" clearable />
  8 + <el-input v-model="query.id" placeholder="单据编号" clearable />
9 9 </el-form-item>
10 10 </el-col>
11 11 <el-col :span="6">
12 12 <el-form-item label="单据日期">
13   - <el-date-picker v-model="query.djrq" type="daterange" value-format="timestamp" format="yyyy-MM-dd" start-placeholder="开始日期" end-placeholder="结束日期">
14   - </el-date-picker>
  13 + <el-date-picker v-model="query.djrq" type="daterange" value-format="timestamp" format="yyyy-MM-dd" start-placeholder="开始日期" end-placeholder="结束日期" />
15 14 </el-form-item>
16 15 </el-col>
17 16 <el-col :span="6">
18 17 <el-form-item label="出库仓库">
19   - <el-select v-model="query.cjck" placeholder="出库仓库" clearable >
20   - <el-option v-for="(item, index) in cjckOptions" :key="index" :label="item.F_mdmc" :value="item.F_Id" />
  18 + <el-select v-model="query.cjck" placeholder="出库仓库" clearable filterable>
  19 + <el-option v-for="(item, index) in cjckOptions" :key="index" :label="item.F_mdmc" :value="item.F_Id" />
21 20 </el-select>
22 21 </el-form-item>
23 22 </el-col>
24   - <template v-if="showAll">
25 23 <el-col :span="6">
26   - <el-form-item label="经手人">
27   - <userSelect v-model="query.jsr" placeholder="请选择经手人" />
28   - </el-form-item>
29   - </el-col>
30   - <el-col :span="6">
31   - <el-form-item label="优惠金额">
32   - <el-input v-model="query.ysje" placeholder="优惠金额" clearable />
33   - </el-form-item>
34   - </el-col>
35   - <el-col :span="6">
36   - <el-form-item label="收款账户">
37   - <el-select v-model="query.skzh" placeholder="收款账户" clearable >
38   - <el-option v-for="(item, index) in skzhOptions" :key="index" :label="item.fullName" :value="item.id" />
  24 + <el-form-item label="入库仓库">
  25 + <el-select v-model="query.rkck" placeholder="入库仓库" clearable filterable>
  26 + <el-option v-for="(item, index) in rkckOptions" :key="index" :label="item.F_mdmc" :value="item.F_Id" />
39 27 </el-select>
40 28 </el-form-item>
41 29 </el-col>
42 30 <el-col :span="6">
43   - <el-form-item label="收款金额">
44   - <el-input v-model="query.skje" placeholder="收款金额" clearable />
45   - </el-form-item>
46   - </el-col>
47   - <el-col :span="6">
48   - <el-form-item label="制单人">
49   - <userSelect v-model="query.zdr" placeholder="请选择制单人" />
50   - </el-form-item>
51   - </el-col>
52   - <el-col :span="6">
53   - <el-form-item label="审核人">
54   - <userSelect v-model="query.shr" placeholder="请选择审核人" />
55   - </el-form-item>
56   - </el-col>
57   - <el-col :span="6">
58   - <el-form-item label="过账人">
59   - <userSelect v-model="query.gzr" placeholder="请选择过账人" />
60   - </el-form-item>
61   - </el-col>
62   - <el-col :span="6">
63   - <el-form-item label="备注">
64   - <el-input v-model="query.bz" placeholder="备注" />
65   - </el-form-item>
66   - </el-col>
67   - <el-col :span="6">
68   - <el-form-item label="单据类型">
69   - <el-input v-model="query.djlx" placeholder="单据类型" clearable />
70   - </el-form-item>
71   - </el-col>
72   -
73   - <el-col :span="6">
74   - <el-form-item label="单据来源">
75   - <el-select v-model="query.ly" placeholder="单据来源" clearable >
76   - <el-option label="门店" value="门店"></el-option>
77   - <el-option label="抖音抓单" value="抖音抓单"></el-option>
  31 + <el-form-item label="单据状态">
  32 + <el-select v-model="query.djzt" placeholder="全部" clearable>
  33 + <el-option label="草稿" value="草稿" />
  34 + <el-option label="待审核" value="待审核" />
  35 + <el-option label="已审核" value="已审核" />
78 36 </el-select>
79 37 </el-form-item>
80 38 </el-col>
81   -
82   -
  39 + <template v-if="showAll">
  40 + <el-col :span="6">
  41 + <el-form-item label="经手人">
  42 + <userSelect v-model="query.jsr" placeholder="请选择经手人" />
  43 + </el-form-item>
  44 + </el-col>
  45 + <el-col :span="6">
  46 + <el-form-item label="制单人">
  47 + <userSelect v-model="query.zdr" placeholder="请选择制单人" />
  48 + </el-form-item>
  49 + </el-col>
  50 + <el-col :span="6">
  51 + <el-form-item label="备注">
  52 + <el-input v-model="query.bz" placeholder="备注" clearable />
  53 + </el-form-item>
  54 + </el-col>
  55 + <el-col :span="6">
  56 + <el-form-item label="优惠金额">
  57 + <el-input v-model="query.ysje" placeholder="优惠金额" clearable />
  58 + </el-form-item>
  59 + </el-col>
  60 + <el-col :span="6">
  61 + <el-form-item label="收款账户">
  62 + <el-select v-model="query.skzh" placeholder="收款账户" clearable>
  63 + <el-option v-for="(item, index) in skzhOptions" :key="index" :label="item.fullName" :value="item.id" />
  64 + </el-select>
  65 + </el-form-item>
  66 + </el-col>
  67 + <el-col :span="6">
  68 + <el-form-item label="收款金额">
  69 + <el-input v-model="query.skje" placeholder="收款金额" clearable />
  70 + </el-form-item>
  71 + </el-col>
  72 + <el-col :span="6">
  73 + <el-form-item label="审核人">
  74 + <userSelect v-model="query.shr" placeholder="请选择审核人" />
  75 + </el-form-item>
  76 + </el-col>
  77 + <el-col :span="6">
  78 + <el-form-item label="过账人">
  79 + <userSelect v-model="query.gzr" placeholder="请选择过账人" />
  80 + </el-form-item>
  81 + </el-col>
  82 + <el-col :span="6">
  83 + <el-form-item label="单据类型">
  84 + <el-input v-model="query.djlx" placeholder="单据类型" clearable />
  85 + </el-form-item>
  86 + </el-col>
  87 + <el-col :span="6">
  88 + <el-form-item label="单据来源">
  89 + <el-select v-model="query.ly" placeholder="单据来源" clearable>
  90 + <el-option label="门店" value="门店" />
  91 + <el-option label="抖音抓单" value="抖音抓单" />
  92 + </el-select>
  93 + </el-form-item>
  94 + </el-col>
83 95 </template>
84 96 <el-col :span="6">
85 97 <el-form-item>
86 98 <el-button type="primary" icon="el-icon-search" @click="search()">查询</el-button>
87 99 <el-button icon="el-icon-refresh-right" @click="reset()">重置</el-button>
88   - <el-button type="text" icon="el-icon-arrow-down" @click="showAll=true" v-if="!showAll">展开</el-button>
89   - <el-button type="text" icon="el-icon-arrow-up" @click="showAll=false" v-else>收起</el-button>
  100 + <el-button type="text" icon="el-icon-arrow-down" v-if="!showAll" @click="showAll = true">展开</el-button>
  101 + <el-button type="text" icon="el-icon-arrow-up" v-else @click="showAll = false">收起</el-button>
90 102 </el-form-item>
91 103 </el-col>
92 104 </el-form>
... ... @@ -105,275 +117,341 @@
105 117 <screenfull isContainer />
106 118 </div>
107 119 </div>
108   - <NCC-table v-loading="listLoading" :data="list" has-c @selection-change="handleSelectionChange">
109   - <el-table-column prop="id" label="单据编号" align="left" width="160">
  120 + <NCC-table v-loading="listLoading" :data="list" has-c class="bjd-table" @selection-change="handleSelectionChange">
  121 + <el-table-column prop="id" label="单据编号" align="left" width="168" show-overflow-tooltip>
110 122 <template slot-scope="scope">
111   - <i class="el-icon-document" style="color:#409EFF;margin-right:4px" />
112   - {{ scope.row.id || '无' }}
  123 + <span class="cell-nowrap">
  124 + <i class="el-icon-document" style="color:#409EFF;margin-right:4px" />
  125 + {{ cellText(scope.row.id) }}
  126 + </span>
113 127 </template>
114 128 </el-table-column>
115   - <el-table-column prop="djrq" label="单据日期" align="left" :formatter="ncc.tableDateFormat" />
116   - <el-table-column label="出库仓库" prop="cjck" align="left" min-width="100" show-overflow-tooltip>
117   - <template slot-scope="scope">
118   - <i class="el-icon-office-building" style="color:#909399;margin-right:4px" />
119   - {{ scope.row.cjck | dynamicText(cjckOptions) }}
120   - </template>
  129 + <el-table-column prop="djrq" label="单据日期" align="left" width="118" :formatter="ncc.tableDateFormat" show-overflow-tooltip>
  130 + <template slot="header">
  131 + <span><i class="el-icon-date" style="color:#409EFF;margin-right:4px" />单据日期</span>
  132 + </template>
121 133 </el-table-column>
122   - <el-table-column prop="bjsx" label="变价系数%" align="right" width="100">
  134 + <el-table-column label="出库仓库" prop="cjck" align="left" min-width="108" show-overflow-tooltip>
123 135 <template slot-scope="scope">
124   - <i class="el-icon-sort" style="color:#E6A23C;margin-right:4px" />
125   - {{ scope.row.bjsx != null && scope.row.bjsx !== '' ? scope.row.bjsx + '%' : '无' }}
  136 + <span class="cell-nowrap">
  137 + <i class="el-icon-upload2" style="color:#909399;margin-right:4px" />
  138 + {{ displayWarehouse(scope.row.cjck, 'cjck') }}
  139 + </span>
126 140 </template>
127 141 </el-table-column>
128   - <el-table-column prop="cbje" label="变价成本合计" align="right" width="120">
  142 + <el-table-column label="入库仓库" prop="rkck" align="left" min-width="108" show-overflow-tooltip>
129 143 <template slot-scope="scope">
130   - <i class="el-icon-coin" style="color:#67C23A;margin-right:4px" />
131   - {{ scope.row.cbje != null && scope.row.cbje !== '' ? scope.row.cbje : '无' }}
  144 + <span class="cell-nowrap">
  145 + <i class="el-icon-download" style="color:#67C23A;margin-right:4px" />
  146 + {{ displayWarehouse(scope.row.rkck, 'rkck') }}
  147 + </span>
132 148 </template>
133 149 </el-table-column>
134   - <el-table-column prop="jsr" label="经手人" align="left" />
135   - <el-table-column prop="ysje" label="优惠金额" align="left" />
136   - <el-table-column label="收款账户" prop="skzh" align="left">
137   - <template slot-scope="scope">{{ scope.row.skzh | dynamicText(skzhOptions) }}</template>
  150 + <el-table-column prop="bjsx" label="变价系数%" align="right" width="108" show-overflow-tooltip>
  151 + <template slot-scope="scope">
  152 + <span class="cell-nowrap">
  153 + <i class="el-icon-sort" style="color:#E6A23C;margin-right:4px" />
  154 + {{ formatBjsx(scope.row.bjsx) }}
  155 + </span>
  156 + </template>
138 157 </el-table-column>
139   - <el-table-column prop="skje" label="收款金额" align="left" />
140   - <el-table-column prop="zdr" label="制单人" align="left" />
141   - <el-table-column prop="shr" label="审核人" align="left" />
142   - <el-table-column prop="gzr" label="过账人" align="left" />
143   - <el-table-column prop="bz" label="备注" align="left" />
144   - <el-table-column prop="djlx" label="单据类型" align="left" />
145   - <el-table-column prop="djzt" label="单据状态" align="left" width="100">
  158 + <el-table-column prop="cbje" label="变价成本合计" align="right" width="128" show-overflow-tooltip>
  159 + <template slot-scope="scope">
  160 + <span class="cell-nowrap">
  161 + <i class="el-icon-coin" style="color:#67C23A;margin-right:4px" />
  162 + {{ formatMoney(scope.row.cbje) }}
  163 + </span>
  164 + </template>
  165 + </el-table-column>
  166 + <el-table-column prop="djzt" label="单据状态" align="center" width="100" show-overflow-tooltip>
146 167 <template slot-scope="scope">
147 168 <el-tag v-if="scope.row.djzt === '草稿'" type="info" size="mini">草稿</el-tag>
148 169 <el-tag v-else-if="scope.row.djzt === '待审核'" type="warning" size="mini">待审核</el-tag>
149 170 <el-tag v-else-if="scope.row.djzt === '已审核'" type="success" size="mini">已审核</el-tag>
150   - <el-tag v-else type="warning" size="mini">{{ scope.row.djzt || '无' }}</el-tag>
  171 + <el-tag v-else type="warning" size="mini">{{ cellText(scope.row.djzt) }}</el-tag>
151 172 </template>
152 173 </el-table-column>
153   - <el-table-column label="操作" fixed="right" width="100">
154   - <template slot-scope="scope">
155   - <el-button type="text" @click="addOrUpdateHandle(scope.row.id)" >编辑</el-button>
156   - <el-button type="text" @click="handleDel(scope.row.id)" class="NCC-table-delBtn" >删除</el-button>
  174 + <el-table-column prop="jsr" label="经手人" align="left" min-width="88" show-overflow-tooltip>
  175 + <template slot-scope="scope">
  176 + <span class="cell-nowrap">
  177 + <i class="el-icon-user" style="color:#409EFF;margin-right:4px" />
  178 + {{ cellText(scope.row.jsr) }}
  179 + </span>
  180 + </template>
  181 + </el-table-column>
  182 + <el-table-column prop="zdr" label="制单人" align="left" min-width="88" show-overflow-tooltip>
  183 + <template slot-scope="scope">
  184 + <span class="cell-nowrap">
  185 + <i class="el-icon-s-custom" style="color:#909399;margin-right:4px" />
  186 + {{ cellText(scope.row.zdr) }}
  187 + </span>
  188 + </template>
  189 + </el-table-column>
  190 + <el-table-column prop="bz" label="备注" align="left" min-width="100" show-overflow-tooltip>
  191 + <template slot-scope="scope">
  192 + <span class="cell-nowrap">
  193 + <i class="el-icon-edit-outline" style="color:#C0C4CC;margin-right:4px" />
  194 + {{ cellText(scope.row.bz) }}
  195 + </span>
  196 + </template>
  197 + </el-table-column>
  198 + <el-table-column label="操作" fixed="right" width="148">
  199 + <template slot-scope="scope">
  200 + <el-button type="text" @click="addOrUpdateHandle(scope.row.id, true)">查看</el-button>
  201 + <el-button type="text" @click="addOrUpdateHandle(scope.row.id)">编辑</el-button>
  202 + <el-button type="text" @click="handleDel(scope.row.id)" class="NCC-table-delBtn">删除</el-button>
157 203 </template>
158 204 </el-table-column>
159 205 </NCC-table>
160   - <pagination :total="total" :page.sync="listQuery.currentPage" :limit.sync="listQuery.pageSize" @pagination="initData" />
161   - </div>
162   - </div>
  206 + <pagination :total="total" :page.sync="listQuery.currentPage" :limit.sync="listQuery.pageSize" @pagination="initData" />
  207 + </div>
  208 + </div>
163 209 <NCC-Form v-if="formVisible" ref="NCCForm" @refresh="refresh" />
164 210 <ExportBox v-if="exportBoxVisible" ref="ExportBox" @download="download" />
165 211 </div>
166 212 </template>
167 213 <script>
168   - import request from '@/utils/request'
169   - import { getDictionaryDataSelector } from '@/api/systemData/dictionary'
170   - import NCCForm from './Form'
171   - import ExportBox from './ExportBox'
172   - import { previewDataInterface } from '@/api/systemData/dataInterface'
173   - export default {
174   - components: { NCCForm, ExportBox },
175   - data() {
176   - return {
177   - showAll: false,
178   - query: {
179   - id:undefined,
180   - djrq:undefined,
181   - cjck:undefined,
182   - jsr:undefined,
183   - ysje:undefined,
184   - skzh:undefined,
185   - skje:undefined,
186   - zdr:undefined,
187   - shr:undefined,
188   - gzr:undefined,
189   - bz:undefined,
190   - djlx:'变价调拨单',
191   - ly:undefined
192   - },
193   - list: [],
194   - listLoading: true,
195   - multipleSelection: [], total: 0,
196   - listQuery: {
197   - currentPage: 1,
198   - pageSize: 20,
199   - sort: "desc",
200   - sidx: "",
201   - },
202   - formVisible: false,
203   - exportBoxVisible: false,
204   - columnList: [
205   - { prop: 'id', label: '单据编号' },
206   - { prop: 'djrq', label: '单据日期' },
207   - { prop: 'cjck', label: '出库仓库' },
208   - { prop: 'bjsx', label: '变价系数%' },
209   - { prop: 'cbje', label: '变价成本合计' },
210   - { prop: 'jsr', label: '经手人' },
211   - { prop: 'ysje', label: '优惠金额' },
212   - { prop: 'skzh', label: '收款账户' },
213   - { prop: 'skje', label: '收款金额' },
214   - { prop: 'zdr', label: '制单人' },
215   - { prop: 'shr', label: '审核人' },
216   - { prop: 'gzr', label: '过账人' },
217   - { prop: 'bz', label: '备注' },
218   - { prop: 'djlx', label: '单据类型' },
219   - { prop: 'djzt', label: '单据状态' },
220   - ],
221   - cjckOptions : [],
222   - rkckOptions : [],
223   - skzhOptions : [],
  214 +import request from '@/utils/request'
  215 +import { getDictionaryDataSelector } from '@/api/systemData/dictionary'
  216 +import NCCForm from './Form'
  217 +import ExportBox from './ExportBox'
  218 +import { previewDataInterface } from '@/api/systemData/dataInterface'
  219 +
  220 +export default {
  221 + components: { NCCForm, ExportBox },
  222 + data() {
  223 + return {
  224 + showAll: false,
  225 + query: {
  226 + id: undefined,
  227 + djrq: undefined,
  228 + cjck: undefined,
  229 + rkck: undefined,
  230 + djzt: undefined,
  231 + jsr: undefined,
  232 + ysje: undefined,
  233 + skzh: undefined,
  234 + skje: undefined,
  235 + zdr: undefined,
  236 + shr: undefined,
  237 + gzr: undefined,
  238 + bz: undefined,
  239 + djlx: '变价调拨单',
  240 + ly: undefined
  241 + },
  242 + list: [],
  243 + listLoading: true,
  244 + multipleSelection: [],
  245 + total: 0,
  246 + listQuery: {
  247 + currentPage: 1,
  248 + pageSize: 20,
  249 + sort: 'desc',
  250 + sidx: ''
  251 + },
  252 + formVisible: false,
  253 + exportBoxVisible: false,
  254 + columnList: [
  255 + { prop: 'id', label: '单据编号' },
  256 + { prop: 'djrq', label: '单据日期' },
  257 + { prop: 'cjck', label: '出库仓库' },
  258 + { prop: 'rkck', label: '入库仓库' },
  259 + { prop: 'bjsx', label: '变价系数%' },
  260 + { prop: 'cbje', label: '变价成本合计' },
  261 + { prop: 'djzt', label: '单据状态' },
  262 + { prop: 'jsr', label: '经手人' },
  263 + { prop: 'zdr', label: '制单人' },
  264 + { prop: 'bz', label: '备注' },
  265 + { prop: 'ysje', label: '优惠金额' },
  266 + { prop: 'skzh', label: '收款账户' },
  267 + { prop: 'skje', label: '收款金额' },
  268 + { prop: 'shr', label: '审核人' },
  269 + { prop: 'gzr', label: '过账人' },
  270 + { prop: 'djlx', label: '单据类型' }
  271 + ],
  272 + cjckOptions: [],
  273 + rkckOptions: [],
  274 + skzhOptions: []
  275 + }
  276 + },
  277 + computed: {},
  278 + created() {
  279 + this.initData()
  280 + this.getcjckOptions()
  281 + this.getrkckOptions()
  282 + this.getskzhOptions()
  283 + },
  284 + methods: {
  285 + cellText(v) {
  286 + if (v === null || v === undefined || v === '') return '无'
  287 + return v
  288 + },
  289 + formatMoney(v) {
  290 + if (v === null || v === undefined || v === '') return '无'
  291 + const n = Number(v)
  292 + return isNaN(n) ? '无' : n.toFixed(2)
  293 + },
  294 + formatBjsx(v) {
  295 + if (v === null || v === undefined || v === '') return '无'
  296 + const n = Number(v)
  297 + return isNaN(n) ? '无' : `${n}%`
  298 + },
  299 + /** 列表接口已返回门店/仓名称时直接展示;否则用选项映射 */
  300 + displayWarehouse(val, type) {
  301 + const raw = this.cellText(val)
  302 + if (raw === '无') return '无'
  303 + const opts = type === 'rkck' ? this.rkckOptions : this.cjckOptions
  304 + const hit = (opts || []).find(o => o.F_Id === val)
  305 + return hit ? hit.F_mdmc : raw
  306 + },
  307 + getcjckOptions() {
  308 + previewDataInterface('681758216954053893').then(res => {
  309 + this.cjckOptions = res.data
  310 + })
  311 + },
  312 + getrkckOptions() {
  313 + previewDataInterface('681758216954053893').then(res => {
  314 + this.rkckOptions = res.data
  315 + })
  316 + },
  317 + getskzhOptions() {
  318 + getDictionaryDataSelector('681761709836207365').then(res => {
  319 + this.skzhOptions = res.data.list
  320 + })
  321 + },
  322 + initData() {
  323 + this.listLoading = true
  324 + const _query = {
  325 + ...this.listQuery,
  326 + ...this.query
  327 + }
  328 + const query = {}
  329 + for (const key in _query) {
  330 + if (Array.isArray(_query[key])) {
  331 + query[key] = _query[key].join()
  332 + } else {
  333 + query[key] = _query[key]
  334 + }
  335 + }
  336 + query.djlx = '变价调拨单'
  337 + request({
  338 + url: `/api/Extend/WtXsckd`,
  339 + method: 'GET',
  340 + data: query
  341 + }).then(res => {
  342 + this.list = res.data.list
  343 + this.total = res.data.pagination.total
  344 + this.listLoading = false
  345 + })
  346 + },
  347 + handleDel(id) {
  348 + this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
  349 + type: 'warning'
  350 + }).then(() => {
  351 + request({
  352 + url: `/api/Extend/WtXsckd/${id}`,
  353 + method: 'DELETE'
  354 + }).then(res => {
  355 + this.$message({
  356 + type: 'success',
  357 + message: res.msg,
  358 + onClose: () => {
  359 + this.initData()
  360 + }
  361 + })
  362 + })
  363 + }).catch(() => {})
  364 + },
  365 + handleSelectionChange(val) {
  366 + this.multipleSelection = val.map(item => item.id)
  367 + },
  368 + handleBatchRemoveDel() {
  369 + if (!this.multipleSelection.length) {
  370 + this.$message({
  371 + type: 'error',
  372 + message: '请选择一条数据',
  373 + duration: 1500
  374 + })
  375 + return
  376 + }
  377 + const ids = this.multipleSelection
  378 + this.$confirm('您确定要删除这些数据吗, 是否继续?', '提示', {
  379 + type: 'warning'
  380 + }).then(() => {
  381 + request({
  382 + url: `/api/Extend/WtXsckd/batchRemove`,
  383 + method: 'POST',
  384 + data: ids
  385 + }).then(res => {
  386 + this.$message({
  387 + type: 'success',
  388 + message: res.msg,
  389 + onClose: () => {
  390 + this.initData()
  391 + }
  392 + })
  393 + })
  394 + }).catch(() => {})
  395 + },
  396 + addOrUpdateHandle(id, isDetail) {
  397 + this.formVisible = true
  398 + this.$nextTick(() => {
  399 + this.$refs.NCCForm.init(id, isDetail)
  400 + })
  401 + },
  402 + exportData() {
  403 + this.exportBoxVisible = true
  404 + this.$nextTick(() => {
  405 + this.$refs.ExportBox.init(this.columnList)
  406 + })
  407 + },
  408 + download(data) {
  409 + const query = { ...data, ...this.listQuery, ...this.query }
  410 + request({
  411 + url: `/api/Extend/WtXsckd/Actions/Export`,
  412 + method: 'GET',
  413 + data: query
  414 + }).then(res => {
  415 + if (!res.data.url) return
  416 + window.location.href = this.define.comUrl + res.data.url
  417 + this.$refs.ExportBox.visible = false
  418 + this.exportBoxVisible = false
  419 + })
  420 + },
  421 + search() {
  422 + this.listQuery = {
  423 + currentPage: 1,
  424 + pageSize: 20,
  425 + sort: 'desc',
  426 + sidx: ''
224 427 }
225   - },
226   - computed: {},
227   - created() {
228 428 this.initData()
229   - this.getcjckOptions();
230   - this.getrkckOptions();
231   - this.getskzhOptions();
232 429 },
233   - methods: {
234   - getcjckOptions(){
235   - previewDataInterface('681758216954053893').then(res => {
236   - this.cjckOptions = res.data
237   - });
238   - },
239   - getrkckOptions(){
240   - previewDataInterface('681758216954053893').then(res => {
241   - this.rkckOptions = res.data
242   - });
243   - },
244   - getskzhOptions(){
245   - getDictionaryDataSelector('681761709836207365').then(res => {
246   - this.skzhOptions = res.data.list
247   - });
248   - },
249   - initData() {
250   - this.listLoading = true;
251   - let _query = {
252   - ...this.listQuery,
253   - ...this.query
254   - };
255   - let query = {}
256   - for (let key in _query) {
257   - if (Array.isArray(_query[key])) {
258   - query[key] = _query[key].join()
259   - } else {
260   - query[key] = _query[key]
261   - }
262   - }
263   - query.djlx='变价调拨单';
264   -
265   - request({
266   - url: `/api/Extend/WtXsckd`,
267   - method: 'GET',
268   - data: query
269   - }).then(res => {
270   - this.list = res.data.list
271   - this.total = res.data.pagination.total
272   - this.listLoading = false
273   - })
274   - },
275   - handleDel(id) {
276   - this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
277   - type: 'warning'
278   - }).then(() => {
279   - request({
280   - url: `/api/Extend/WtXsckd/${id}`,
281   - method: 'DELETE'
282   - }).then(res => {
283   - this.$message({
284   - type: 'success',
285   - message: res.msg,
286   - onClose: () => {
287   - this.initData()
288   - }
289   - });
290   - })
291   - }).catch(() => {
292   - });
293   - },
294   - handleSelectionChange(val) {
295   - const res = val.map(item => item.id)
296   - this.multipleSelection = res
297   - },
298   - handleBatchRemoveDel() {
299   - if (!this.multipleSelection.length) {
300   - this.$message({
301   - type: 'error',
302   - message: '请选择一条数据',
303   - duration: 1500,
304   - })
305   - return
306   - }
307   - const ids = this.multipleSelection
308   - this.$confirm('您确定要删除这些数据吗, 是否继续?', '提示', {
309   - type: 'warning'
310   - }).then(() => {
311   - request({
312   - url: `/api/Extend/WtXsckd/batchRemove`,
313   - method: 'POST',
314   - data: ids ,
315   - }).then(res => {
316   - this.$message({
317   - type: 'success',
318   - message: res.msg,
319   - onClose: () => {
320   - this.initData()
321   - }
322   - });
323   - })
324   - }).catch(() => { })
325   - },
326   - addOrUpdateHandle(id, isDetail) {
327   - this.formVisible = true
328   - this.$nextTick(() => {
329   - this.$refs.NCCForm.init(id, isDetail)
330   - })
331   - },
332   - exportData() {
333   - this.exportBoxVisible = true
334   - this.$nextTick(() => {
335   - this.$refs.ExportBox.init(this.columnList)
336   - })
337   - },
338   - download(data) {
339   - let query = { ...data, ...this.listQuery, ...this.query }
340   - request({
341   - url: `/api/Extend/WtXsckd/Actions/Export`,
342   - method: 'GET',
343   - data: query
344   - }).then(res => {
345   - if (!res.data.url) return
346   - window.location.href = this.define.comUrl + res.data.url
347   - this.$refs.ExportBox.visible = false
348   - this.exportBoxVisible = false
349   - })
350   - },
351   - search() {
352   - this.listQuery = {
353   - currentPage: 1,
354   - pageSize: 20,
355   - sort: "desc",
356   - sidx: "",
357   - }
358   - this.initData()
359   - },
360   - refresh(isrRefresh) {
361   - this.formVisible = false
362   - if (isrRefresh) this.reset()
363   - },
364   - reset() {
365   - for (let key in this.query) {
366   - this.query[key] = undefined
367   - }
368   - this.query.djlx = '变价调拨单'
369   - this.listQuery = {
370   - currentPage: 1,
371   - pageSize: 20,
372   - sort: "desc",
373   - sidx: "",
374   - }
375   - this.initData()
376   - }
  430 + refresh(isrRefresh) {
  431 + this.formVisible = false
  432 + if (isrRefresh) this.reset()
  433 + },
  434 + reset() {
  435 + for (const key in this.query) {
  436 + this.query[key] = undefined
  437 + }
  438 + this.query.djlx = '变价调拨单'
  439 + this.listQuery = {
  440 + currentPage: 1,
  441 + pageSize: 20,
  442 + sort: 'desc',
  443 + sidx: ''
  444 + }
  445 + this.initData()
377 446 }
378   - }
379   -</script>
380 447 \ No newline at end of file
  448 + }
  449 +}
  450 +</script>
  451 +<style scoped>
  452 +.wt-bjdbd-list .bjd-table >>> .el-table .cell {
  453 + white-space: nowrap;
  454 +}
  455 +.cell-nowrap {
  456 + white-space: nowrap;
  457 +}
  458 +</style>
... ...
Antis.Erp.Plat/antis-ncc-admin/src/views/wtTjdbd/Form.vue
1   -<template>
  1 +<template>
2 2 <el-dialog :title="!dataForm.id ? '新建' : isDetail ? '详情':'编辑'" :close-on-click-modal="false" :visible.sync="visible" class="NCC-dialog NCC-dialog_center" lock-scroll width="80%">
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">
... ... @@ -32,6 +32,11 @@
32 32 </el-select>
33 33 </el-form-item>
34 34 </el-col>
  35 + <el-col :span="12">
  36 + <el-form-item label="成本合计">
  37 + <el-input :value="tjCbjeDisplay" placeholder="保存后由系统按调出成本汇总" readonly :style='{"width":"100%"}' />
  38 + </el-form-item>
  39 + </el-col>
35 40 <el-col :span="12" v-if="false">
36 41 <el-form-item label="往来单位" prop="kh">
37 42 <el-select v-model="dataForm.kh" placeholder="请选择" clearable :style='{"width":"100%"}' filterable >
... ... @@ -117,26 +122,32 @@
117 122 </div>
118 123 </template>
119 124 </el-table-column>
120   - <el-table-column prop="sl" label="调拨数量">
  125 + <el-table-column prop="dj" label="成本单价" width="120">
121 126 <template slot-scope="scope">
122 127 <el-input
123   - v-model="scope.row.sl"
124   - placeholder="请输入"
  128 + v-model="scope.row.dj"
  129 + placeholder="参考成本,过账以服务端为准"
125 130 clearable
  131 + :readonly="!!isDetail"
126 132 @input="handleAmountChange(scope.row)"
127 133 ></el-input>
128 134 </template>
129 135 </el-table-column>
130   - <el-table-column prop="dj" label="成本单价" v-if="false">
  136 + <el-table-column prop="sl" label="调拨数量">
131 137 <template slot-scope="scope">
132 138 <el-input
133   - v-model="scope.row.dj"
  139 + v-model="scope.row.sl"
134 140 placeholder="请输入"
135 141 clearable
136 142 @input="handleAmountChange(scope.row)"
137 143 ></el-input>
138 144 </template>
139 145 </el-table-column>
  146 + <el-table-column prop="cbje" label="成本金额" width="100" show-overflow-tooltip>
  147 + <template slot-scope="scope">
  148 + <span>{{ formatMxTjdCbje(scope.row) }}</span>
  149 + </template>
  150 + </el-table-column>
140 151 <el-table-column prop="je" label="调拨金额" v-if="false">
141 152 <template slot-scope="scope">
142 153 <el-input v-model="scope.row.je" placeholder="请输入" clearable readonly></el-input>
... ... @@ -278,6 +289,7 @@
278 289 djrq:undefined,
279 290 cjck:undefined,
280 291 rkck:undefined,
  292 + cbje: undefined,
281 293 jsr:undefined,
282 294 kh:undefined,
283 295 gys:undefined,
... ... @@ -317,7 +329,21 @@
317 329 totalJe() {
318 330 return (this.dataForm.wtXsckdMxList || []).reduce((sum, row) => sum + (parseFloat(row.je) || 0), 0)
319 331 },
320   -
  332 + /** 主表成本合计:已过账用服务端 cbje;未过账用明细数量×成本单价预览 */
  333 + tjCbjeDisplay() {
  334 + const head = this.dataForm.cbje
  335 + if (head != null && head !== '') {
  336 + const n = Number(head)
  337 + return isNaN(n) ? '' : n.toFixed(2)
  338 + }
  339 + let sum = 0
  340 + ;(this.dataForm.wtXsckdMxList || []).forEach(row => {
  341 + const sl = parseInt(row.sl, 10) || 0
  342 + const dj = parseFloat(row.dj) || 0
  343 + if (sl > 0 && dj > 0) sum += sl * dj
  344 + })
  345 + return sum > 0 ? sum.toFixed(2) : ''
  346 + },
321 347 },
322 348 watch: {
323 349 // 监听主表仓库字段变化,确保编辑模式下也能触发联动
... ... @@ -996,6 +1022,7 @@
996 1022 kucun:undefined, // 库存数量
997 1023 sl:undefined,
998 1024 dj:undefined,
  1025 + cbje: undefined,
999 1026 je:undefined,
1000 1027 selectedSerialNumbers: [], // 添加序列号数组
1001 1028 loadingStock: false, // 库存加载状态
... ... @@ -1051,6 +1078,7 @@
1051 1078 if (currentRow.dj) {
1052 1079 currentRow.je = (parseFloat(currentRow.sl) * parseFloat(currentRow.dj)).toFixed(2)
1053 1080 }
  1081 + this.recalcRowCostPreview(currentRow)
1054 1082 // 更新总收款金额
1055 1083 this.calculateTotalAmount();
1056 1084  
... ... @@ -1061,6 +1089,7 @@
1061 1089 const sl = parseFloat(row.sl) || 0;
1062 1090 const dj = parseFloat(row.dj) || 0;
1063 1091 row.je = (sl * dj).toFixed(2);
  1092 + this.recalcRowCostPreview(row)
1064 1093 // 自动计算总收款金额
1065 1094 this.calculateTotalAmount();
1066 1095 // 检查数量与序列号数量是否一致
... ... @@ -1068,9 +1097,9 @@
1068 1097 const serialNumberCount = row.selectedSerialNumbers.length;
1069 1098 if (sl !== serialNumberCount) {
1070 1099 this.$message.error(`商品"${row.spmc}"的销售数量(${sl})与已选择的序列号数量(${serialNumberCount})不一致,请先调整序列号数量!`);
1071   - // 恢复为序列号数量
1072 1100 row.sl = serialNumberCount.toString();
1073 1101 row.je = (serialNumberCount * dj).toFixed(2);
  1102 + this.recalcRowCostPreview(row)
1074 1103 }
1075 1104 }
1076 1105 },
... ... @@ -1079,12 +1108,12 @@
1079 1108 handleMainWarehouseChange(value) {
1080 1109 // 同步更新所有明细行的出库仓库
1081 1110 this.syncDetailWarehouses();
1082   - // 更新所有明细行的库存
  1111 + // 更新所有明细行的库存与成本参考价
1083 1112 this.dataForm.wtXsckdMxList.forEach(row => {
1084 1113 if (row.spbh) {
1085   - this.getStockQuantity(row);
  1114 + this.getStockQuantity(row)
1086 1115 }
1087   - });
  1116 + })
1088 1117 },
1089 1118  
1090 1119 // 处理主表入库仓库变化
... ... @@ -1202,6 +1231,67 @@
1202 1231 row.loadingStock = false;
1203 1232 console.log('=== 库存查询完成 ===');
1204 1233 }
  1234 + if (row.spbh && row.ckck) {
  1235 + await this.applyOutboundCostPrice(row, true)
  1236 + }
  1237 + },
  1238 +
  1239 + /** 明细成本金额:已过账用服务端 cbje;未过账用数量×成本单价 */
  1240 + formatMxTjdCbje(row) {
  1241 + if (!row) return '无'
  1242 + if (row.cbje != null && row.cbje !== '') {
  1243 + const n = Number(row.cbje)
  1244 + return isNaN(n) ? '无' : n.toFixed(2)
  1245 + }
  1246 + const sl = parseInt(row.sl, 10)
  1247 + const dj = parseFloat(row.dj)
  1248 + if (sl > 0 && !isNaN(dj) && dj > 0) {
  1249 + return (sl * dj).toFixed(2)
  1250 + }
  1251 + return '无'
  1252 + },
  1253 +
  1254 + recalcRowCostPreview(row) {
  1255 + if (!row) return
  1256 + const sl = parseInt(row.sl, 10) || 0
  1257 + const dj = parseFloat(row.dj) || 0
  1258 + if (sl > 0 && dj > 0) {
  1259 + this.$set(row, 'cbje', Number((sl * dj).toFixed(2)))
  1260 + } else {
  1261 + this.$set(row, 'cbje', '')
  1262 + }
  1263 + },
  1264 +
  1265 + /**
  1266 + * 从 wt_sp_cost 拉取调出方成本单价并回填 dj(与过账取价一致)
  1267 + * @param {boolean} silent 无成本记录时不弹警告
  1268 + */
  1269 + async applyOutboundCostPrice(row, silent = false) {
  1270 + if (!row || !row.spbh || !row.ckck) return
  1271 + try {
  1272 + const spbh = encodeURIComponent(String(row.spbh))
  1273 + const ck = encodeURIComponent(String(row.ckck))
  1274 + const res = await request({
  1275 + url: `/api/Extend/WtXsckd/GetOutboundCostPrice?spbh=${spbh}&ckOrMdId=${ck}`,
  1276 + method: 'get'
  1277 + })
  1278 + const payload = res.data
  1279 + if (payload && payload.success && payload.data != null) {
  1280 + const p = Number(payload.data)
  1281 + if (!isNaN(p) && p > 0) {
  1282 + this.$set(row, 'dj', p.toFixed(4))
  1283 + this.recalcRowCostPreview(row)
  1284 + const sl = parseFloat(row.sl) || 0
  1285 + const dj = parseFloat(row.dj) || 0
  1286 + row.je = (sl * dj).toFixed(2)
  1287 + this.calculateTotalAmount()
  1288 + }
  1289 + } else if (!silent && payload && payload.msg) {
  1290 + this.$message.warning(payload.msg)
  1291 + }
  1292 + } catch (e) {
  1293 + if (!silent) console.error(e)
  1294 + }
1205 1295 },
1206 1296  
1207 1297 // 计算总金额
... ... @@ -1463,11 +1553,13 @@
1463 1553 sums[index] = '合计';
1464 1554 return;
1465 1555 }
1466   - if (['kucun', 'sl', 'je'].includes(column.property)) {
  1556 + if (['kucun', 'sl', 'je', 'dj', 'cbje'].includes(column.property)) {
1467 1557 sums[index] = data.reduce((total, row) => {
1468 1558 const value = parseFloat(row[column.property]);
1469 1559 return total + (isNaN(value) ? 0 : value);
1470 1560 }, 0);
  1561 + if (['dj', 'cbje'].includes(column.property) && sums[index] !== '')
  1562 + sums[index] = Number(sums[index]).toFixed(2)
1471 1563 } else {
1472 1564 sums[index] = '';
1473 1565 }
... ... @@ -1479,40 +1571,28 @@
1479 1571 const label = (option.label || '').toLowerCase();
1480 1572 return label.includes(query.toLowerCase());
1481 1573 },
1482   - handleProductChange(row) {
  1574 + async handleProductChange(row) {
1483 1575 // 选中商品后可自动回填商品名称等信息
1484 1576 const product = this.spbhOptions.find(item => item.F_Id === row.spbh);
1485 1577 if (product) {
1486 1578 row.spmc = product.F_Spmc || '';
1487   - // 选中商品后,立即加载商品信息(如序列号类型)
  1579 + this.$set(row, 'spxlhLoaded', false);
1488 1580 this.getProductInfo(row.spbh).then(productInfo => {
1489   - // 触发当前行的响应式刷新
1490 1581 this.$set(row, 'spxlhLoaded', true);
1491 1582 this.$forceUpdate();
1492 1583 if (!(productInfo && productInfo.spxlhType)) {
1493 1584 this.$message.warning('无法获取序列号类型信息');
1494 1585 }
1495   - });
1496   -
1497   - // 检查出库仓库并获取库存
1498   - console.log('商品选择变化 - 商品ID:', row.spbh, '出库仓库:', row.ckck, '主表出库仓库:', this.dataForm.cjck);
1499   -
1500   - // 如果明细行没有出库仓库,使用主表的出库仓库
  1586 + })
  1587 +
1501 1588 if (!row.ckck && this.dataForm.cjck) {
1502   - row.ckck = this.dataForm.cjck;
1503   - console.log('使用主表出库仓库:', row.ckck);
  1589 + row.ckck = this.dataForm.cjck
1504 1590 }
1505   -
1506   - // 如果主表也没有出库仓库,提示用户先选择
1507 1591 if (!row.ckck) {
1508   - console.log('出库仓库未设置,无法获取库存');
1509   - this.$message.warning('请先选择出库仓库');
1510   - return;
  1592 + this.$message.warning('请先选择出库仓库')
  1593 + return
1511 1594 }
1512   -
1513   - // 如果已选择出库仓库,自动获取库存
1514   - console.log('开始获取库存...');
1515   - this.getStockQuantity(row);
  1595 + await this.getStockQuantity(row)
1516 1596 }
1517 1597 },
1518 1598 handleProductQuery(val, scope) {
... ...
Antis.Erp.Plat/antis-ncc-admin/src/views/wtTjdbd/index.vue
1   -<template>
  1 +<template>
2 2 <div class="NCC-common-layout">
3 3 <div class="NCC-common-layout-center">
4 4 <el-row class="NCC-common-search-box" :gutter="16">
... ... @@ -105,11 +105,43 @@
105 105 <screenfull isContainer />
106 106 </div>
107 107 </div>
108   - <NCC-table v-loading="listLoading" :data="list" has-c @selection-change="handleSelectionChange">
109   - <el-table-column prop="id" label="单据编号" align="left" />
110   - <el-table-column prop="djrq" label="单据日期" align="left" :formatter="ncc.tableDateFormat" />
111   - <el-table-column label="出库仓库" prop="cjck" align="left">
112   - <template slot-scope="scope">{{ scope.row.cjck | dynamicText(cjckOptions) }}</template>
  108 + <NCC-table v-loading="listLoading" :data="list" has-c class="tjd-table" @selection-change="handleSelectionChange">
  109 + <el-table-column prop="id" label="单据编号" align="left" min-width="168" show-overflow-tooltip>
  110 + <template slot-scope="scope">
  111 + <span class="cell-nowrap">
  112 + <i class="el-icon-document" style="color:#409EFF;margin-right:4px" />
  113 + {{ cellText(scope.row.id) }}
  114 + </span>
  115 + </template>
  116 + </el-table-column>
  117 + <el-table-column prop="djrq" label="单据日期" align="left" width="118" :formatter="ncc.tableDateFormat" show-overflow-tooltip>
  118 + <template slot="header">
  119 + <span><i class="el-icon-date" style="color:#409EFF;margin-right:4px" />单据日期</span>
  120 + </template>
  121 + </el-table-column>
  122 + <el-table-column label="出库仓库" prop="cjck" align="left" min-width="108" show-overflow-tooltip>
  123 + <template slot-scope="scope">
  124 + <span class="cell-nowrap">
  125 + <i class="el-icon-upload2" style="color:#909399;margin-right:4px" />
  126 + {{ scope.row.cjck | dynamicText(cjckOptions) }}
  127 + </span>
  128 + </template>
  129 + </el-table-column>
  130 + <el-table-column label="入库仓库" prop="rkck" align="left" min-width="108" show-overflow-tooltip>
  131 + <template slot-scope="scope">
  132 + <span class="cell-nowrap">
  133 + <i class="el-icon-download" style="color:#67C23A;margin-right:4px" />
  134 + {{ scope.row.rkck | dynamicText(rkckOptions) }}
  135 + </span>
  136 + </template>
  137 + </el-table-column>
  138 + <el-table-column prop="cbje" label="成本合计" align="right" width="120" show-overflow-tooltip>
  139 + <template slot-scope="scope">
  140 + <span class="cell-nowrap">
  141 + <i class="el-icon-coin" style="color:#E6A23C;margin-right:4px" />
  142 + {{ formatTjdListCbje(scope.row.cbje) }}
  143 + </span>
  144 + </template>
113 145 </el-table-column>
114 146 <el-table-column prop="jsr" label="经手人" align="left" />
115 147 <el-table-column prop="ysje" label="优惠金额" align="left" />
... ... @@ -122,7 +154,14 @@
122 154 <el-table-column prop="gzr" label="过账人" align="left" />
123 155 <el-table-column prop="bz" label="备注" align="left" />
124 156 <el-table-column prop="djlx" label="单据类型" align="left" />
125   - <el-table-column prop="djzt" label="单据状态" align="left" />
  157 + <el-table-column prop="djzt" label="单据状态" align="center" width="100" show-overflow-tooltip>
  158 + <template slot-scope="scope">
  159 + <el-tag v-if="scope.row.djzt === '草稿'" type="info" size="mini">草稿</el-tag>
  160 + <el-tag v-else-if="scope.row.djzt === '待审核'" type="warning" size="mini">待审核</el-tag>
  161 + <el-tag v-else-if="scope.row.djzt === '已审核'" type="success" size="mini">已审核</el-tag>
  162 + <el-tag v-else type="warning" size="mini">{{ cellText(scope.row.djzt) }}</el-tag>
  163 + </template>
  164 + </el-table-column>
126 165 <el-table-column label="操作" fixed="right" width="100">
127 166 <template slot-scope="scope">
128 167 <el-button type="text" @click="addOrUpdateHandle(scope.row.id)" >编辑</el-button>
... ... @@ -178,6 +217,8 @@
178 217 { prop: 'id', label: '单据编号' },
179 218 { prop: 'djrq', label: '单据日期' },
180 219 { prop: 'cjck', label: '出库仓库' },
  220 + { prop: 'rkck', label: '入库仓库' },
  221 + { prop: 'cbje', label: '成本合计' },
181 222 { prop: 'jsr', label: '经手人' },
182 223 { prop: 'ysje', label: '优惠金额' },
183 224 { prop: 'skzh', label: '收款账户' },
... ... @@ -201,6 +242,15 @@
201 242 this.getskzhOptions();
202 243 },
203 244 methods: {
  245 + cellText(v) {
  246 + if (v === null || v === undefined || v === '') return '无'
  247 + return v
  248 + },
  249 + formatTjdListCbje(v) {
  250 + if (v === null || v === undefined || v === '') return '无'
  251 + const n = Number(v)
  252 + return isNaN(n) ? '无' : n.toFixed(2)
  253 + },
204 254 getcjckOptions(){
205 255 previewDataInterface('681758216954053893').then(res => {
206 256 this.cjckOptions = res.data
... ... @@ -335,6 +385,7 @@
335 385 for (let key in this.query) {
336 386 this.query[key] = undefined
337 387 }
  388 + this.query.djlx = '同价调拨单'
338 389 this.listQuery = {
339 390 currentPage: 1,
340 391 pageSize: 20,
... ... @@ -345,4 +396,9 @@
345 396 }
346 397 }
347 398 }
348   -</script>
349 399 \ No newline at end of file
  400 +</script>
  401 +<style scoped>
  402 +.cell-nowrap {
  403 + white-space: nowrap;
  404 +}
  405 +</style>
350 406 \ No newline at end of file
... ...
Antis.Erp.Plat/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/WtXsckdListOutput.cs
... ... @@ -23,6 +23,11 @@ namespace NCC.Extend.Entitys.Dto.WtXsckd
23 23 public string cjck { get; set; }
24 24  
25 25 /// <summary>
  26 + /// 入库仓库/门店(变价调拨单等)
  27 + /// </summary>
  28 + public string rkck { get; set; }
  29 +
  30 + /// <summary>
26 31 /// 经手人
27 32 /// </summary>
28 33 public string jsr { get; set; }
... ...
Antis.Erp.Plat/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/WtXsckdListQueryInput.cs
1   -using NCC.Common.Filter;
  1 +using NCC.Common.Filter;
2 2 using System.Collections.Generic;
3 3  
4 4 namespace NCC.Extend.Entitys.Dto.WtXsckd
... ... @@ -35,6 +35,11 @@ namespace NCC.Extend.Entitys.Dto.WtXsckd
35 35 public string cjck { get; set; }
36 36  
37 37 /// <summary>
  38 + /// 入库仓库/门店
  39 + /// </summary>
  40 + public string rkck { get; set; }
  41 +
  42 + /// <summary>
38 43 /// 经手人
39 44 /// </summary>
40 45 public string jsr { get; set; }
... ...
Antis.Erp.Plat/netcore/src/Modularity/Extend/NCC.Extend/WtXsckdService.cs
... ... @@ -168,14 +168,15 @@ namespace NCC.Extend.WtXsckd
168 168 /// <summary>
169 169 /// 获取销售出库单
170 170 /// </summary>
171   - /// <param name="id">参数</param>
172   - /// <returns></returns>
  171 + /// <param name="id">单据编号</param>
  172 + /// <returns>详情数据;单据不存在或已删除时返回 COM1005</returns>
173 173 [HttpGet("{id}")]
174 174 public async Task<dynamic> GetInfo(string id)
175 175 {
176 176 EnsureBjsxColumn();
177 177 EnsureBjhcbColumn();
178 178 var entity = await _db.Queryable<WtXsckdEntity>().FirstAsync(p => p.Id == id);
  179 + _ = entity ?? throw NCCException.Oh(ErrorCode.COM1005);
179 180 var output = entity.Adapt<WtXsckdInfoOutput>();
180 181 output.cjckId = entity.Cjck;
181 182  
... ... @@ -289,6 +290,7 @@ namespace NCC.Extend.WtXsckd
289 290 (xsckd, hy) => xsckd.Djrq <= new DateTime(endDjrq.ToDate().Year, endDjrq.ToDate().Month, endDjrq.ToDate().Day, 23,
290 291 59, 59))
291 292 .WhereIF(!string.IsNullOrEmpty(input.cjck), (xsckd, hy) => xsckd.Cjck.Equals(input.cjck))
  293 + .WhereIF(!string.IsNullOrEmpty(input.rkck), (xsckd, hy) => xsckd.Rkck.Equals(input.rkck))
292 294 .WhereIF(!string.IsNullOrEmpty(input.jsr), (xsckd, hy) => xsckd.Jsr.Equals(input.jsr))
293 295 .WhereIF(!string.IsNullOrEmpty(input.ysje), (xsckd, hy) => xsckd.Ysje.Equals(input.ysje))
294 296 .WhereIF(!string.IsNullOrEmpty(input.skzh), (xsckd, hy) => xsckd.Skzh.Equals(input.skzh))
... ... @@ -308,8 +310,9 @@ namespace NCC.Extend.WtXsckd
308 310 {
309 311 id = xsckd.Id,
310 312 djrq = xsckd.Djrq,
311   - // cjck=xsckd.Cjck,
312   - cjck = SqlFunc.Subqueryable<WtCkEntity>().Where(u => u.Id == xsckd.Cjck).Select(u => u.Mdmc),
  313 + // 先存原始 ID,查询后统一解析为门店/仓库名称(与详情页一致)
  314 + cjck = xsckd.Cjck,
  315 + rkck = xsckd.Rkck,
313 316 // jsr=xsckd.Jsr,
314 317 jsr = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == xsckd.Jsr).Select(u => u.RealName),
315 318 ydje = xsckd.Ydje,
... ... @@ -335,10 +338,58 @@ namespace NCC.Extend.WtXsckd
335 338 djlx = xsckd.Djlx,
336 339 djzt = xsckd.Djzt
337 340 }).MergeTable().OrderBy(sidx + " " + input.sort).ToPagedListAsync(input.currentPage, input.pageSize);
  341 + var pageRows = data.list?.ToList() ?? new List<WtXsckdListOutput>();
  342 + await EnrichWtXsckdListWarehouseDisplayAsync(pageRows);
338 343 return PageResult<WtXsckdListOutput>.SqlSugarPageResult(data);
339 344 }
340 345  
341 346 /// <summary>
  347 + /// 列表出库/入库字段:将主表存的门店ID或仓库ID解析为展示名称(wt_md / wt_ck)
  348 + /// </summary>
  349 + private async Task EnrichWtXsckdListWarehouseDisplayAsync(List<WtXsckdListOutput> items)
  350 + {
  351 + if (items == null || items.Count == 0) return;
  352 + var ids = items.Select(x => x.id).Where(id => !string.IsNullOrEmpty(id)).Distinct().ToList();
  353 + if (ids.Count == 0) return;
  354 +
  355 + var heads = await _db.Queryable<WtXsckdEntity>()
  356 + .Where(x => ids.Contains(x.Id))
  357 + .Select(x => new { x.Id, x.Cjck, x.Rkck })
  358 + .ToListAsync();
  359 + var headDict = heads.ToDictionary(h => h.Id, h => h);
  360 +
  361 + var allKeys = heads
  362 + .SelectMany(h => new[] { h.Cjck, h.Rkck })
  363 + .Where(k => !string.IsNullOrWhiteSpace(k))
  364 + .Distinct()
  365 + .ToList();
  366 + if (allKeys.Count == 0) return;
  367 +
  368 + var nameMap = new Dictionary<string, string>(StringComparer.Ordinal);
  369 + var ckRows = await _db.Queryable<WtCkEntity>().In(c => c.Id, allKeys).Select(c => new { c.Id, c.Mdmc }).ToListAsync();
  370 + foreach (var r in ckRows)
  371 + {
  372 + if (!string.IsNullOrEmpty(r.Id) && !string.IsNullOrEmpty(r.Mdmc))
  373 + nameMap[r.Id] = r.Mdmc;
  374 + }
  375 + var mdRows = await _db.Queryable<WtMdEntity>().In(m => m.Id, allKeys).Select(m => new { m.Id, m.Mdmc }).ToListAsync();
  376 + foreach (var r in mdRows)
  377 + {
  378 + if (!string.IsNullOrEmpty(r.Id) && !string.IsNullOrEmpty(r.Mdmc))
  379 + nameMap[r.Id] = r.Mdmc;
  380 + }
  381 +
  382 + foreach (var row in items)
  383 + {
  384 + if (!headDict.TryGetValue(row.id, out var h)) continue;
  385 + if (!string.IsNullOrEmpty(h.Cjck) && nameMap.TryGetValue(h.Cjck, out var cjName))
  386 + row.cjck = cjName;
  387 + if (!string.IsNullOrEmpty(h.Rkck) && nameMap.TryGetValue(h.Rkck, out var rkName))
  388 + row.rkck = rkName;
  389 + }
  390 + }
  391 +
  392 + /// <summary>
342 393 /// 新建销售出库单
343 394 /// </summary>
344 395 /// <param name="input">参数</param>
... ... @@ -868,43 +919,64 @@ namespace NCC.Extend.WtXsckd
868 919 [NonAction]
869 920 public async Task<dynamic> GetNoPagingList([FromQuery] WtXsckdListQueryInput input)
870 921 {
  922 + EnsureYdjeColumn();
  923 + EnsureCbjeColumn();
  924 + EnsureBjsxColumn();
871 925 var sidx = input.sidx == null ? "id" : input.sidx;
872 926 List<string> queryDjrq = input.djrq != null ? input.djrq.Split(',').ToObeject<List<string>>() : null;
873 927 DateTime? startDjrq = queryDjrq != null ? Ext.GetDateTime(queryDjrq.First()) : null;
874 928 DateTime? endDjrq = queryDjrq != null ? Ext.GetDateTime(queryDjrq.Last()) : null;
875   - var data = await _db.Queryable<WtXsckdEntity>()
876   - .WhereIF(!string.IsNullOrEmpty(input.id), p => p.Id.Contains(input.id))
877   - .WhereIF(queryDjrq != null, p => p.Djrq >= new DateTime(startDjrq.ToDate().Year, startDjrq.ToDate().Month, startDjrq.ToDate().Day, 0, 0, 0))
878   - .WhereIF(queryDjrq != null, p => p.Djrq <= new DateTime(endDjrq.ToDate().Year, endDjrq.ToDate().Month, endDjrq.ToDate().Day, 23, 59, 59))
879   - .WhereIF(!string.IsNullOrEmpty(input.cjck), p => p.Cjck.Equals(input.cjck))
880   - .WhereIF(!string.IsNullOrEmpty(input.jsr), p => p.Jsr.Equals(input.jsr))
881   - .WhereIF(!string.IsNullOrEmpty(input.ysje), p => p.Ysje.Equals(input.ysje))
882   - .WhereIF(!string.IsNullOrEmpty(input.skzh), p => p.Skzh.Equals(input.skzh))
883   - .WhereIF(!string.IsNullOrEmpty(input.skje), p => p.Skje.Equals(input.skje))
884   - .WhereIF(!string.IsNullOrEmpty(input.zdr), p => p.Zdr.Equals(input.zdr))
885   - .WhereIF(!string.IsNullOrEmpty(input.shr), p => p.Shr.Equals(input.shr))
886   - .WhereIF(!string.IsNullOrEmpty(input.gzr), p => p.Gzr.Equals(input.gzr))
887   - .WhereIF(!string.IsNullOrEmpty(input.bz), p => p.Bz.Contains(input.bz))
888   - .WhereIF(!string.IsNullOrEmpty(input.djlx), p => p.Djlx.Contains(input.djlx))
889   - .WhereIF(!string.IsNullOrEmpty(input.djzt), p => p.Djzt.Contains(input.djzt)) // 新增:支持按单据状态查询
890   - .Select(it=> new WtXsckdListOutput
891   - {
892   - id = it.Id,
893   - djrq=it.Djrq,
894   - cjck=it.Cjck,
895   - jsr=it.Jsr,
896   - ydje = it.Ydje,
897   - ysje=it.Ysje,
898   - skzh=it.Skzh,
899   - skje=it.Skje,
900   - zdr=it.Zdr,
901   - shr=it.Shr,
902   - gzr=it.Gzr,
903   - bz=it.Bz,
904   - djlx=it.Djlx,
905   - djzt=it.Djzt // 新增:返回单据状态
906   - }).MergeTable().OrderBy(sidx+" "+input.sort).ToListAsync();
907   - return data;
  929 + var data = await _db.Queryable<WtXsckdEntity, WtHyEntity>((xsckd, hy) => new JoinQueryInfos(JoinType.Left, xsckd.Kh == hy.Id))
  930 + .WhereIF(!string.IsNullOrEmpty(input.id), (xsckd, hy) => xsckd.Id.Contains(input.id))
  931 + .WhereIF(queryDjrq != null,
  932 + (xsckd, hy) => xsckd.Djrq >= new DateTime(startDjrq.ToDate().Year, startDjrq.ToDate().Month,
  933 + startDjrq.ToDate().Day, 0, 0, 0))
  934 + .WhereIF(queryDjrq != null,
  935 + (xsckd, hy) => xsckd.Djrq <= new DateTime(endDjrq.ToDate().Year, endDjrq.ToDate().Month, endDjrq.ToDate().Day, 23,
  936 + 59, 59))
  937 + .WhereIF(!string.IsNullOrEmpty(input.cjck), (xsckd, hy) => xsckd.Cjck.Equals(input.cjck))
  938 + .WhereIF(!string.IsNullOrEmpty(input.rkck), (xsckd, hy) => xsckd.Rkck.Equals(input.rkck))
  939 + .WhereIF(!string.IsNullOrEmpty(input.jsr), (xsckd, hy) => xsckd.Jsr.Equals(input.jsr))
  940 + .WhereIF(!string.IsNullOrEmpty(input.ysje), (xsckd, hy) => xsckd.Ysje.Equals(input.ysje))
  941 + .WhereIF(!string.IsNullOrEmpty(input.skzh), (xsckd, hy) => xsckd.Skzh.Equals(input.skzh))
  942 + .WhereIF(!string.IsNullOrEmpty(input.skje), (xsckd, hy) => xsckd.Skje.Equals(input.skje))
  943 + .WhereIF(!string.IsNullOrEmpty(input.zdr), (xsckd, hy) => xsckd.Zdr.Equals(input.zdr))
  944 + .WhereIF(!string.IsNullOrEmpty(input.shr), (xsckd, hy) => xsckd.Shr.Equals(input.shr))
  945 + .WhereIF(!string.IsNullOrEmpty(input.gzr), (xsckd, hy) => xsckd.Gzr.Equals(input.gzr))
  946 + .WhereIF(!string.IsNullOrEmpty(input.bz), (xsckd, hy) => xsckd.Bz.Contains(input.bz))
  947 + .WhereIF(!string.IsNullOrEmpty(input.kh), (xsckd, hy) => xsckd.Kh.Contains(input.kh))
  948 + .WhereIF(!string.IsNullOrEmpty(input.hysjh), (xsckd, hy) =>
  949 + (xsckd.Hysjh != null && xsckd.Hysjh.Contains(input.hysjh)) ||
  950 + (hy.Sjh != null && hy.Sjh.Contains(input.hysjh)))
  951 + .WhereIF(!string.IsNullOrEmpty(input.djlx), (xsckd, hy) => xsckd.Djlx.Contains(input.djlx))
  952 + .WhereIF(!string.IsNullOrEmpty(input.ly), (xsckd, hy) => xsckd.Ly.Equals(input.ly))
  953 + .WhereIF(!string.IsNullOrEmpty(input.djzt), (xsckd, hy) => xsckd.Djzt.Contains(input.djzt))
  954 + .Select((xsckd, hy) => new WtXsckdListOutput
  955 + {
  956 + id = xsckd.Id,
  957 + djrq = xsckd.Djrq,
  958 + cjck = xsckd.Cjck,
  959 + rkck = xsckd.Rkck,
  960 + jsr = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == xsckd.Jsr).Select(u => u.RealName),
  961 + ydje = xsckd.Ydje,
  962 + cbje = xsckd.Cbje,
  963 + bjsx = xsckd.Bjsx,
  964 + ysje = xsckd.Ysje,
  965 + skzh = xsckd.Skzh,
  966 + skje = xsckd.Skje,
  967 + skmx = xsckd.Skmx,
  968 + zdr = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == xsckd.Zdr).Select(u => u.RealName),
  969 + shr = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == xsckd.Shr).Select(u => u.RealName),
  970 + gzr = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == xsckd.Gzr).Select(u => u.RealName),
  971 + kh = hy.Xm,
  972 + hysjh = hy.Sjh ?? xsckd.Hysjh ?? "",
  973 + gys = SqlFunc.Subqueryable<WtGysEntity>().Where(u => u.Id == xsckd.Gys).Select(u => u.Gysmc),
  974 + bz = xsckd.Bz,
  975 + djlx = xsckd.Djlx,
  976 + djzt = xsckd.Djzt
  977 + }).MergeTable().OrderBy(sidx + " " + input.sort).ToListAsync();
  978 + await EnrichWtXsckdListWarehouseDisplayAsync(data);
  979 + return data;
908 980 }
909 981  
910 982 /// <summary>
... ... @@ -990,7 +1062,7 @@ namespace NCC.Extend.WtXsckd
990 1062 {
991 1063 exportData = await this.GetNoPagingList(input);
992 1064 }
993   - List<ParamsModel> paramList = "[{\"value\":\"单据编号\",\"field\":\"id\"},{\"value\":\"单据日期\",\"field\":\"djrq\"},{\"value\":\"出库仓库\",\"field\":\"cjck\"},{\"value\":\"变价系数%\",\"field\":\"bjsx\"},{\"value\":\"成本金额\",\"field\":\"cbje\"},{\"value\":\"经手人\",\"field\":\"jsr\"},{\"value\":\"优惠金额\",\"field\":\"ysje\"},{\"value\":\"收款账户\",\"field\":\"skzh\"},{\"value\":\"收款金额\",\"field\":\"skje\"},{\"value\":\"制单人\",\"field\":\"zdr\"},{\"value\":\"审核人\",\"field\":\"shr\"},{\"value\":\"过账人\",\"field\":\"gzr\"},{\"value\":\"备注\",\"field\":\"bz\"},{\"value\":\"单据类型\",\"field\":\"djlx\"},{\"value\":\"单据状态\",\"field\":\"djzt\"},]".ToList<ParamsModel>();
  1065 + List<ParamsModel> paramList = "[{\"value\":\"单据编号\",\"field\":\"id\"},{\"value\":\"单据日期\",\"field\":\"djrq\"},{\"value\":\"出库仓库\",\"field\":\"cjck\"},{\"value\":\"入库仓库\",\"field\":\"rkck\"},{\"value\":\"变价系数%\",\"field\":\"bjsx\"},{\"value\":\"成本金额\",\"field\":\"cbje\"},{\"value\":\"经手人\",\"field\":\"jsr\"},{\"value\":\"优惠金额\",\"field\":\"ysje\"},{\"value\":\"收款账户\",\"field\":\"skzh\"},{\"value\":\"收款金额\",\"field\":\"skje\"},{\"value\":\"制单人\",\"field\":\"zdr\"},{\"value\":\"审核人\",\"field\":\"shr\"},{\"value\":\"过账人\",\"field\":\"gzr\"},{\"value\":\"备注\",\"field\":\"bz\"},{\"value\":\"单据类型\",\"field\":\"djlx\"},{\"value\":\"单据状态\",\"field\":\"djzt\"},]".ToList<ParamsModel>();
994 1066 ExcelConfig excelconfig = new ExcelConfig();
995 1067 excelconfig.FileName = "销售出库单.xls";
996 1068 excelconfig.HeadFont = "微软雅黑";
... ... @@ -1084,6 +1156,13 @@ namespace NCC.Extend.WtXsckd
1084 1156 {
1085 1157 await RollbackVariablePriceTransferCost(oldHeader, oldMxList);
1086 1158 }
  1159 +
  1160 + if (oldHeader.Djlx == "同价调拨单"
  1161 + && !string.Equals(oldHeader.Djzt, "草稿", StringComparison.Ordinal)
  1162 + && oldMxList.Count > 0)
  1163 + {
  1164 + await RollbackSamePriceTransferCost(oldHeader, oldMxList);
  1165 + }
1087 1166  
1088 1167 //更新销售出库单记录
1089 1168 await _db.Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
... ... @@ -1397,7 +1476,7 @@ ORDER BY t.`商品编号`&quot;;
1397 1476 }
1398 1477  
1399 1478 /// <summary>
1400   - /// 按商品与出库门店/仓库查询加权成本单价(与销售出库、变价调拨过账取价逻辑一致,供前端录入参考)
  1479 + /// 按商品与出库门店/仓库查询加权成本单价(与销售出库、变价/同价调拨过账取价逻辑一致,供前端录入参考)
1401 1480 /// </summary>
1402 1481 /// <param name="spbh">商品主键 F_Id</param>
1403 1482 /// <param name="ckOrMdId">明细 ckck 或主表 cjck(可为门店ID或仓库ID)</param>
... ... @@ -2978,14 +3057,15 @@ ORDER BY t.`商品编号`;&quot;;
2978 3057 }
2979 3058  
2980 3059 /// <summary>
2981   - /// 销售/预售/变价调拨单重算并回写主表成本金额(变价调拨为明细变价后成本金额合计)
  3060 + /// 销售/预售/变价调拨单/同价调拨单重算并回写主表成本金额(调拨单为明细成本金额合计)
2982 3061 /// </summary>
2983   - /// <param name="skipForBjdDraft">变价调拨草稿时不回写主表 cbje(明细未过账)</param>
  3062 + /// <param name="skipForBjdDraft">变价/同价调拨草稿时不回写主表 cbje(明细未过账)</param>
2984 3063 private async Task RecalculateMainCbje(string djbh, string djlx, bool skipForBjdDraft = false)
2985 3064 {
2986 3065 if (string.IsNullOrEmpty(djbh)) return;
2987 3066 if (djlx == "变价调拨单" && skipForBjdDraft) return;
2988   - if (djlx != "销售出库单" && djlx != "预售出库单" && djlx != "变价调拨单") return;
  3067 + if (djlx == "同价调拨单" && skipForBjdDraft) return;
  3068 + if (djlx != "销售出库单" && djlx != "预售出库单" && djlx != "变价调拨单" && djlx != "同价调拨单") return;
2989 3069  
2990 3070 decimal cbje = 0;
2991 3071 var result = await _db.Ado.SqlQueryAsync<decimal?>(
... ... @@ -3062,6 +3142,7 @@ ORDER BY t.`商品编号`;&quot;;
3062 3142 /// 销售/预售出库 → 快照成本到明细 + 减少数量
3063 3143 /// 销售退货 → 恢复数量(成本不变)
3064 3144 /// 变价调拨单 → 调出仓按原成本加权减少,调入仓按变价后单价加权增加(草稿/ isDraft 不过账)
  3145 + /// 同价调拨单 → 调出/调入同一成本单价移仓(草稿/ isDraft 不过账)
3065 3146 /// </summary>
3066 3147 private async Task UpdateSpCostOnCreate(string djlx, WtXsckdEntity entity, List<WtXsckdMxEntity> mxList, bool isDraft = false)
3067 3148 {
... ... @@ -3084,6 +3165,23 @@ ORDER BY t.`商品编号`;&quot;;
3084 3165 }
3085 3166 return;
3086 3167 }
  3168 +
  3169 + if (djlx == "同价调拨单")
  3170 + {
  3171 + EnsureBjhcbColumn();
  3172 + if (isDraft || string.Equals(entity.Djzt, "草稿", StringComparison.Ordinal))
  3173 + return;
  3174 + try
  3175 + {
  3176 + await ApplySamePriceTransferCost(entity, mxList);
  3177 + }
  3178 + catch (Exception ex)
  3179 + {
  3180 + Console.WriteLine($"同价调拨成本过账失败: {ex.Message}");
  3181 + throw;
  3182 + }
  3183 + return;
  3184 + }
3087 3185  
3088 3186 try
3089 3187 {
... ... @@ -3420,6 +3518,14 @@ ORDER BY t.`商品编号`;&quot;;
3420 3518 if (mxList.Count > 0)
3421 3519 await RollbackVariablePriceTransferCost(entity, mxList);
3422 3520 }
  3521 + else if (djlx == "同价调拨单")
  3522 + {
  3523 + if (string.Equals(entity.Djzt, "草稿", StringComparison.Ordinal)) return;
  3524 + EnsureBjhcbColumn();
  3525 + var mxList = await _db.Queryable<WtXsckdMxEntity>().Where(d => d.Djbh == id).ToListAsync();
  3526 + if (mxList.Count > 0)
  3527 + await RollbackSamePriceTransferCost(entity, mxList);
  3528 + }
3423 3529 }
3424 3530  
3425 3531 /// <summary>
... ... @@ -3649,6 +3755,89 @@ ORDER BY t.`商品编号`;&quot;;
3649 3755 await SpCostWeightedAddAsync(detail.Spbh, outCk, qty, originalUnit);
3650 3756 }
3651 3757 }
  3758 +
  3759 + /// <summary>
  3760 + /// 同价调拨单过账:调出按快照成本扣减,调入按相同单价增加,并回写明细 cbdj/bjhcb/cbje(同价时 bjhcb 与 cbdj 一致)
  3761 + /// </summary>
  3762 + private async Task ApplySamePriceTransferCost(WtXsckdEntity entity, List<WtXsckdMxEntity> mxList)
  3763 + {
  3764 + if (string.Equals((entity.Cjck ?? "").Trim(), (entity.Rkck ?? "").Trim(), StringComparison.Ordinal))
  3765 + throw new Exception("同价调拨单出库仓与入库仓不能相同");
  3766 +
  3767 + foreach (var detail in mxList)
  3768 + {
  3769 + if (string.IsNullOrEmpty(detail.Spbh)) continue;
  3770 + if (!int.TryParse(detail.Sl, out int qty) || qty <= 0) continue;
  3771 +
  3772 + var outRef = !string.IsNullOrEmpty(detail.Ckck) ? detail.Ckck : entity.Cjck;
  3773 + var inRef = !string.IsNullOrEmpty(detail.Rkck) ? detail.Rkck : entity.Rkck;
  3774 + if (string.IsNullOrEmpty(outRef) || string.IsNullOrEmpty(inRef))
  3775 + throw new Exception($"商品 {detail.Spmc ?? detail.Spbh} 未指定完整的出库/入库仓库");
  3776 +
  3777 + var outIds = await ResolveWarehouseIdListAsync(outRef);
  3778 + string outCk;
  3779 + decimal originalUnit;
  3780 + try
  3781 + {
  3782 + var picked = await PickOutboundCostRowForTransferAsync(detail.Spbh, outIds, qty);
  3783 + outCk = picked.ck;
  3784 + originalUnit = picked.unitCost;
  3785 + }
  3786 + catch (Exception ex)
  3787 + {
  3788 + throw new Exception(ex.Message.Replace("变价调拨", "同价调拨"));
  3789 + }
  3790 +
  3791 + var inIds = await ResolveWarehouseIdListAsync(inRef);
  3792 + if (inIds == null || inIds.Count == 0)
  3793 + throw new Exception($"商品 {detail.Spbh} 未解析到入库仓库");
  3794 + var inCk = inIds[0];
  3795 +
  3796 + await SpCostWeightedRemoveAsync(detail.Spbh, outCk, qty, originalUnit);
  3797 + await SpCostWeightedAddAsync(detail.Spbh, inCk, qty, originalUnit);
  3798 +
  3799 + await _db.Ado.ExecuteCommandAsync(
  3800 + "UPDATE wt_xsckd_mx SET cbdj = @cbdj, bjhcb = @bjhcb, cbje = @cbje WHERE F_Id = @id",
  3801 + new
  3802 + {
  3803 + cbdj = originalUnit,
  3804 + bjhcb = originalUnit,
  3805 + cbje = Math.Round(originalUnit * qty, 2),
  3806 + id = detail.Id
  3807 + });
  3808 + }
  3809 + }
  3810 +
  3811 + /// <summary>
  3812 + /// 同价调拨单成本回滚:调入按过账单价扣回,调出按相同单价加回(删除/编辑前调用)
  3813 + /// </summary>
  3814 + private async Task RollbackSamePriceTransferCost(WtXsckdEntity entity, List<WtXsckdMxEntity> mxList)
  3815 + {
  3816 + foreach (var detail in mxList)
  3817 + {
  3818 + if (string.IsNullOrEmpty(detail.Spbh)) continue;
  3819 + if (!int.TryParse(detail.Sl, out int qty) || qty <= 0) continue;
  3820 +
  3821 + var outRef = !string.IsNullOrEmpty(detail.Ckck) ? detail.Ckck : entity.Cjck;
  3822 + var inRef = !string.IsNullOrEmpty(detail.Rkck) ? detail.Rkck : entity.Rkck;
  3823 + if (string.IsNullOrEmpty(outRef) || string.IsNullOrEmpty(inRef)) continue;
  3824 +
  3825 + decimal unit = detail.Cbdj ?? detail.Dj;
  3826 + if (unit <= 0 && detail.Bjhcb.HasValue && detail.Bjhcb.Value > 0)
  3827 + unit = detail.Bjhcb.Value;
  3828 + if (unit <= 0) continue;
  3829 +
  3830 + var inIds = await ResolveWarehouseIdListAsync(inRef);
  3831 + var outIds = await ResolveWarehouseIdListAsync(outRef);
  3832 + if (inIds == null || inIds.Count == 0 || outIds == null || outIds.Count == 0) continue;
  3833 + var inCk = inIds[0];
  3834 +
  3835 + await SpCostWeightedRemoveAsync(detail.Spbh, inCk, qty, unit);
  3836 +
  3837 + var outCk = await PickOutboundCkForRollbackAddAsync(detail.Spbh, outIds, unit, qty);
  3838 + await SpCostWeightedAddAsync(detail.Spbh, outCk, qty, unit);
  3839 + }
  3840 + }
3652 3841  
3653 3842 #endregion
3654 3843 }
... ...