Commit d4a6cf6817655b2cd2fb2d70a0e453d170984534

Authored by “wangming”
1 parent 44ba74bd

feat(erp-plat): add '往来单位' field to forms and tables for better data representation

- Introduced a new field for '往来单位' in various forms and tables to enhance data visibility.
- Updated the backend service to support fetching and displaying '往来单位' names based on the corresponding IDs.
- Ensured consistent layout and structure across forms and tables for improved user experience.
- Removed unnecessary fields related to '制单人' to streamline the forms.

Made-with: Cursor
Antis.Erp.Plat/.cursor/rules/project_rules.mdc
... ... @@ -51,6 +51,7 @@ alwaysApply: true
51 51 - **图标显示**: 所有列表数据都要有图标,不同颜色区分类型
52 52 - **空值显示**: 没有信息的字段显示"无"
53 53 - **列表规范**: 列表数据不能换行
  54 +- **列表/报表页头部搜索区**: 须与标准业务列表页排版一致——`NCC-common-layout` → `NCC-common-layout-center` → `el-row` 使用 class `NCC-common-search-box`(建议 `:gutter="16"`);内层 `el-form` 使用 `@submit.native.prevent`(与其它列表一致,**不要**在表单上单独套一套与 `wtXsckd` / `wtCgthd` 等常规列表差异过大的自定义外层布局);筛选项默认 `el-col :span="6"`,末列放置「查询」「重置」「展开/收起」;新增或改造带搜索的页面时优先对照上述列表页复制结构再改字段。
54 55  
55 56 ### 性能要求
56 57 - 启用懒加载和代码分割
... ...
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCgrkd/Form.vue
... ... @@ -169,12 +169,6 @@
169 169 </el-input>
170 170 </el-form-item>
171 171 </el-col>
172   - <el-col :span="8" v-if="false">
173   - <el-form-item label="制单人" prop="zdr">
174   - <user-select v-model="dataForm.zdr" placeholder="请选择" clearable disabled >
175   - </user-select>
176   - </el-form-item>
177   - </el-col>
178 172 <el-col :span="8">
179 173 <el-form-item label="审核人" prop="shr">
180 174 <user-select v-model="dataForm.shr" placeholder="请选择" clearable disabled >
... ... @@ -235,7 +229,6 @@
235 229 ysje:undefined,
236 230 skzh:undefined,
237 231 skje:undefined,
238   - zdr:undefined,
239 232 shr:undefined,
240 233 gzr:undefined,
241 234 bz:undefined,
... ...
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCgrkd/index.vue
... ... @@ -40,11 +40,6 @@
40 40 </el-form-item>
41 41 </el-col>
42 42 <el-col :span="6">
43   - <el-form-item label="制单人">
44   - <userSelect v-model="query.zdr" placeholder="请选择制单人" />
45   - </el-form-item>
46   - </el-col>
47   - <el-col :span="6">
48 43 <el-form-item label="审核人">
49 44 <userSelect v-model="query.shr" placeholder="请选择审核人" />
50 45 </el-form-item>
... ... @@ -100,7 +95,6 @@
100 95 <template slot-scope="scope">{{ scope.row.skzh | dynamicText(skzhOptions) }}</template>
101 96 </el-table-column>
102 97 <el-table-column prop="skje" label="付款金额" align="left" />
103   - <el-table-column prop="zdr" label="制单人" align="left" />
104 98 <el-table-column prop="shr" label="审核人" align="left">
105 99 <template slot-scope="scope">{{ getShrDisplay(scope.row) }}</template>
106 100 </el-table-column>
... ... @@ -163,7 +157,6 @@
163 157 jsr:undefined,
164 158 skzh:undefined,
165 159 skje:undefined,
166   - zdr:undefined,
167 160 shr:undefined,
168 161 gzr:undefined,
169 162 bz:undefined,
... ... @@ -188,7 +181,6 @@
188 181 { prop: 'jsr', label: '经手人' },
189 182 { prop: 'skzh', label: '付款账户' },
190 183 { prop: 'skje', label: '付款金额' },
191   - { prop: 'zdr', label: '制单人' },
192 184 { prop: 'shr', label: '审核人' },
193 185 { prop: 'gzr', label: '过账人' },
194 186 { prop: 'bz', label: '备注' },
... ...
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCgthd/Form.vue
... ... @@ -27,6 +27,13 @@
27 27 </el-form-item>
28 28 </el-col>
29 29 <el-col :span="12">
  30 + <el-form-item label="往来单位" prop="gys">
  31 + <el-select v-model="dataForm.gys" placeholder="请选择或调原入库单带出" clearable :style='{"width":"100%"}' filterable :disabled="!!isDetail">
  32 + <el-option v-for="(item, index) in gysOptions" :key="index" :label="item.dwmc" :value="item.id" />
  33 + </el-select>
  34 + </el-form-item>
  35 + </el-col>
  36 + <el-col :span="12">
30 37 <el-form-item label="原采购入库单">
31 38 <el-button type="primary" icon="el-icon-search" @click="openPurchaseInboundOrderSelect">
32 39 调原入库单
... ... @@ -264,9 +271,11 @@
264 271 gzr:undefined,
265 272 bz:undefined,
266 273 djlx:"采购退货单",
  274 + gys: undefined,
267 275 },
268 276 rules: {
269 277 },
  278 + gysOptions: [],
270 279 cjckOptions : [],
271 280 rkckOptions : [],
272 281 rkckOptions : [],
... ... @@ -295,6 +304,7 @@
295 304 this.getckckOptions();
296 305 this.getspbhOptions();
297 306 this.getskzhOptions();
  307 + this.getgysOptions();
298 308 // 设置单据日期默认为当前日期,经手人默认为当前用户
299 309 if (!this.dataForm.id) {
300 310 this.dataForm.djrq = Date.now();
... ... @@ -337,6 +347,16 @@
337 347 this.skzhOptions = res.data.list
338 348 });
339 349 },
  350 + getgysOptions() {
  351 + return request({
  352 + url: '/api/Extend/WtWldw',
  353 + method: 'get',
  354 + data: { pageSize: 1000, currentPage: 1 }
  355 + }).then(res => {
  356 + this.gysOptions = (res.data && res.data.list) ? res.data.list : (res.data || [])
  357 + return res
  358 + })
  359 + },
340 360 goBack() {
341 361 this.$emit('refresh')
342 362 },
... ... @@ -354,6 +374,9 @@
354 374 if (mainTableInfo && mainTableInfo.rkck) {
355 375 this.dataForm.cjck = mainTableInfo.rkck
356 376 }
  377 + if (mainTableInfo && mainTableInfo.gys) {
  378 + this.dataForm.gys = mainTableInfo.gys
  379 + }
357 380 for (const detail of inboundDetails) {
358 381 const qty = parseFloat(detail.sl) || 0
359 382 const price = parseFloat(detail.dj) || 0
... ... @@ -404,6 +427,9 @@
404 427 method: 'get'
405 428 }).then(res =>{
406 429 this.dataForm = res.data;
  430 + if (res.data.gysId != null && res.data.gysId !== '') {
  431 + this.$set(this.dataForm, 'gys', res.data.gysId);
  432 + }
407 433 if (!this.dataForm.wtXsckdMxList) {
408 434 this.dataForm.wtXsckdMxList = [];
409 435 }
... ...
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCgthd/detail-view.vue
... ... @@ -61,6 +61,12 @@
61 61 {{ cellText(detail.jsr) }}
62 62 </span>
63 63 </el-descriptions-item>
  64 + <el-descriptions-item label="往来单位">
  65 + <span class="cell-nowrap">
  66 + <i class="el-icon-office-building desc-icon desc-icon--info" />
  67 + {{ cellText(detail.gys) }}
  68 + </span>
  69 + </el-descriptions-item>
64 70 </el-descriptions>
65 71  
66 72 <div class="detail-section-head">
... ...
Antis.Erp.Plat/antis-ncc-admin/src/views/wtCgthd/index.vue
... ... @@ -23,6 +23,13 @@
23 23 </el-col>
24 24 <template v-if="showAll">
25 25 <el-col :span="6">
  26 + <el-form-item label="往来单位">
  27 + <el-select v-model="query.gys" placeholder="请选择" clearable filterable style="width: 100%">
  28 + <el-option v-for="item in gysOptions" :key="item.id" :label="item.dwmc" :value="item.id" />
  29 + </el-select>
  30 + </el-form-item>
  31 + </el-col>
  32 + <el-col :span="6">
26 33 <el-form-item label="经手人">
27 34 <userSelect v-model="query.jsr" placeholder="请选择经手人" />
28 35 </el-form-item>
... ... @@ -101,6 +108,11 @@
101 108 <template slot-scope="scope">{{ scope.row.cjck | dynamicText(cjckOptions) }}</template>
102 109 </el-table-column>
103 110 <el-table-column prop="jsr" label="经手人" align="left" />
  111 + <el-table-column prop="gys" label="往来单位" align="left" min-width="120" show-overflow-tooltip>
  112 + <template slot-scope="scope">
  113 + <span class="cell-nowrap">{{ scope.row.gys || '无' }}</span>
  114 + </template>
  115 + </el-table-column>
104 116 <!-- <el-table-column prop="ysje" label="优惠金额" align="left" /> -->
105 117 <el-table-column label="退款账户" prop="skzh" align="left">
106 118 <template slot-scope="scope">{{ scope.row.skzh | dynamicText(skzhOptions) }}</template>
... ... @@ -157,6 +169,7 @@
157 169 gzr:undefined,
158 170 bz:undefined,
159 171 djlx:undefined,
  172 + gys: undefined,
160 173 },
161 174 list: [],
162 175 listLoading: true,
... ... @@ -175,6 +188,7 @@
175 188 { prop: 'djrq', label: '单据日期' },
176 189 { prop: 'cjck', label: '出库仓库' },
177 190 { prop: 'jsr', label: '经手人' },
  191 + { prop: 'gys', label: '往来单位' },
178 192 // { prop: 'ysje', label: '优惠金额' },
179 193 { prop: 'skzh', label: '退款账户' },
180 194 { prop: 'skje', label: '退款金额' },
... ... @@ -188,6 +202,7 @@
188 202 cjckOptions : [],
189 203 rkckOptions : [],
190 204 skzhOptions : [],
  205 + gysOptions: [],
191 206 }
192 207 },
193 208 computed: {},
... ... @@ -196,6 +211,7 @@
196 211 this.getcjckOptions();
197 212 this.getrkckOptions();
198 213 this.getskzhOptions();
  214 + this.getgysOptions();
199 215 },
200 216 methods: {
201 217 getcjckOptions(){
... ... @@ -213,6 +229,15 @@
213 229 this.skzhOptions = res.data.list
214 230 });
215 231 },
  232 + getgysOptions() {
  233 + request({
  234 + url: '/api/Extend/WtWldw',
  235 + method: 'get',
  236 + data: { pageSize: 1000, currentPage: 1 }
  237 + }).then(res => {
  238 + this.gysOptions = (res.data && res.data.list) ? res.data.list : (res.data || [])
  239 + })
  240 + },
216 241 initData() {
217 242 this.listLoading = true;
218 243 let _query = {
... ...
Antis.Erp.Plat/antis-ncc-admin/src/views/wtProductSummary/index.vue
1 1 <template>
2   - <div class="NCC-common-layout product-summary-page">
  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">
5   - <el-form @submit.native.prevent label-width="90px" label-position="right">
  5 + <el-form @submit.native.prevent>
6 6 <el-col :span="6">
7 7 <el-form-item label="查询日期">
8 8 <el-date-picker
... ... @@ -133,60 +133,12 @@
133 133 </el-row>
134 134  
135 135 <div class="NCC-common-layout-main NCC-flex-main">
136   - <el-row :gutter="16" class="product-summary-stats">
137   - <el-col :xs="24" :sm="12" :md="6">
138   - <div class="product-summary-stat-card product-summary-stat-card--blue">
139   - <div class="product-summary-stat-card__inner">
140   - <i class="el-icon-goods product-summary-stat-card__icon" aria-hidden="true" />
141   - <div class="product-summary-stat-card__text">
142   - <div class="product-summary-stat-card__label">商品行数</div>
143   - <div class="product-summary-stat-card__value cell-nowrap">{{ summaryStats.rowCount }}</div>
144   - </div>
145   - </div>
146   - </div>
147   - </el-col>
148   - <el-col :xs="24" :sm="12" :md="6">
149   - <div class="product-summary-stat-card product-summary-stat-card--green">
150   - <div class="product-summary-stat-card__inner">
151   - <i class="el-icon-sell product-summary-stat-card__icon" aria-hidden="true" />
152   - <div class="product-summary-stat-card__text">
153   - <div class="product-summary-stat-card__label">销售数量合计</div>
154   - <div class="product-summary-stat-card__value cell-nowrap">{{ summaryStats.totalQtyDisplay }}</div>
155   - </div>
156   - </div>
157   - </div>
158   - </el-col>
159   - <el-col :xs="24" :sm="12" :md="6">
160   - <div class="product-summary-stat-card product-summary-stat-card--orange">
161   - <div class="product-summary-stat-card__inner">
162   - <i class="el-icon-coin product-summary-stat-card__icon" aria-hidden="true" />
163   - <div class="product-summary-stat-card__text">
164   - <div class="product-summary-stat-card__label">销售金额合计</div>
165   - <div class="product-summary-stat-card__value cell-nowrap">{{ summaryStats.salesAmountDisplay }}</div>
166   - </div>
167   - </div>
168   - </div>
169   - </el-col>
170   - <el-col :xs="24" :sm="12" :md="6">
171   - <div class="product-summary-stat-card product-summary-stat-card--red">
172   - <div class="product-summary-stat-card__inner">
173   - <i class="el-icon-data-analysis product-summary-stat-card__icon" aria-hidden="true" />
174   - <div class="product-summary-stat-card__text">
175   - <div class="product-summary-stat-card__label">毛利合计</div>
176   - <div class="product-summary-stat-card__value cell-nowrap">{{ summaryStats.profitDisplay }}</div>
177   - </div>
178   - </div>
179   - </div>
180   - </el-col>
181   - </el-row>
182   -
183 136 <div class="NCC-common-head product-summary-head">
184   - <div class="product-summary-head__left">
  137 + <div>
185 138 <span class="product-summary-head__title">
186 139 <i class="el-icon-document product-summary-head__title-icon" aria-hidden="true" />
187 140 商品销售明细
188 141 </span>
189   - <span class="product-summary-head__hint">与下方列表同一筛选条件汇总</span>
190 142 </div>
191 143 <div class="NCC-common-head-right">
192 144 <el-tooltip effect="dark" content="刷新" placement="top">
... ... @@ -201,55 +153,55 @@
201 153 </div>
202 154  
203 155 <NCC-table v-loading="listLoading" :data="list" class="product-summary-table">
204   - <el-table-column prop="商品编号" label="商品编号" min-width="110" align="left" show-overflow-tooltip>
  156 + <el-table-column prop="商品编号" label="商品编号" min-width="110" align="left" show-overflow-tooltip sortable :sort-method="sortText('商品编号')">
205 157 <template slot-scope="scope">{{ displayText(scope.row['商品编号']) }}</template>
206 158 </el-table-column>
207   - <el-table-column prop="商品名称" label="商品名称" min-width="160" align="left" show-overflow-tooltip>
  159 + <el-table-column prop="商品名称" label="商品名称" min-width="160" align="left" show-overflow-tooltip sortable :sort-method="sortText('商品名称')">
208 160 <template slot-scope="scope">{{ displayText(scope.row['商品名称']) }}</template>
209 161 </el-table-column>
210   - <el-table-column prop="销售" label="销售" min-width="88" align="right" show-overflow-tooltip>
  162 + <el-table-column prop="销售" label="销售" min-width="88" align="right" show-overflow-tooltip sortable :sort-method="sortNumeric('销售')">
211 163 <template slot-scope="scope">{{ formatNumber(scope.row['销售'], 4) }}</template>
212 164 </el-table-column>
213   - <el-table-column prop="单位" label="单位" min-width="72" align="center" show-overflow-tooltip>
  165 + <el-table-column prop="单位" label="单位" min-width="72" align="center" show-overflow-tooltip sortable :sort-method="sortText('单位')">
214 166 <template slot-scope="scope">{{ displayText(scope.row['单位']) }}</template>
215 167 </el-table-column>
216   - <el-table-column prop="单价" label="单价" min-width="96" align="right" show-overflow-tooltip>
  168 + <el-table-column prop="单价" label="单价" min-width="96" align="right" show-overflow-tooltip sortable :sort-method="sortNumeric('单价')">
217 169 <template slot-scope="scope">{{ formatNumber(scope.row['单价'], 4) }}</template>
218 170 </el-table-column>
219   - <el-table-column prop="折前销售金额" label="折前销售金额" min-width="120" align="right" show-overflow-tooltip>
  171 + <el-table-column prop="折前销售金额" label="折前销售金额" min-width="120" align="right" show-overflow-tooltip sortable :sort-method="sortNumeric('折前销售金额')">
220 172 <template slot-scope="scope">{{ formatNumber(scope.row['折前销售金额'], 2) }}</template>
221 173 </el-table-column>
222   - <el-table-column prop="销售金额" label="销售金额" min-width="110" align="right" show-overflow-tooltip>
  174 + <el-table-column prop="销售金额" label="销售金额" min-width="110" align="right" show-overflow-tooltip sortable :sort-method="sortNumeric('销售金额')">
223 175 <template slot-scope="scope">{{ formatNumber(scope.row['销售金额'], 2) }}</template>
224 176 </el-table-column>
225   - <el-table-column prop="成本单价" label="成本单价" min-width="96" align="right" show-overflow-tooltip>
  177 + <el-table-column prop="成本单价" label="成本单价" min-width="96" align="right" show-overflow-tooltip sortable :sort-method="sortNumeric('成本单价')">
226 178 <template slot-scope="scope">{{ formatNumber(scope.row['成本单价'], 4) }}</template>
227 179 </el-table-column>
228   - <el-table-column prop="成本金额" label="成本金额" min-width="110" align="right" show-overflow-tooltip>
  180 + <el-table-column prop="成本金额" label="成本金额" min-width="110" align="right" show-overflow-tooltip sortable :sort-method="sortNumeric('成本金额')">
229 181 <template slot-scope="scope">{{ formatNumber(scope.row['成本金额'], 2) }}</template>
230 182 </el-table-column>
231   - <el-table-column prop="费用分摊金额" label="费用分摊金额" min-width="120" align="right" show-overflow-tooltip>
  183 + <el-table-column prop="费用分摊金额" label="费用分摊金额" min-width="120" align="right" show-overflow-tooltip sortable :sort-method="sortNumeric('费用分摊金额')">
232 184 <template slot-scope="scope">{{ formatNumber(scope.row['费用分摊金额'], 2) }}</template>
233 185 </el-table-column>
234   - <el-table-column prop="毛利" label="毛利" min-width="96" align="right" show-overflow-tooltip>
  186 + <el-table-column prop="毛利" label="毛利" min-width="96" align="right" show-overflow-tooltip sortable :sort-method="sortNumeric('毛利')">
235 187 <template slot-scope="scope">{{ formatNumber(scope.row['毛利'], 2) }}</template>
236 188 </el-table-column>
237   - <el-table-column prop="毛利率(%)" label="毛利率(%)" min-width="100" align="right" show-overflow-tooltip>
  189 + <el-table-column prop="毛利率(%)" label="毛利率(%)" min-width="100" align="right" show-overflow-tooltip sortable :sort-method="sortNumeric('毛利率(%)')">
238 190 <template slot-scope="scope">{{ formatNumber(scope.row['毛利率(%)'], 2) }}</template>
239 191 </el-table-column>
240   - <el-table-column prop="0单价数量" label="0单价数量" min-width="100" align="right" show-overflow-tooltip>
  192 + <el-table-column prop="0单价数量" label="0单价数量" min-width="100" align="right" show-overflow-tooltip sortable :sort-method="sortNumeric('0单价数量')">
241 193 <template slot-scope="scope">{{ formatNumber(scope.row['0单价数量'], 4) }}</template>
242 194 </el-table-column>
243   - <el-table-column prop="销售权重(%)" label="销售权重(%)" min-width="110" align="right" show-overflow-tooltip>
  195 + <el-table-column prop="销售权重(%)" label="销售权重(%)" min-width="110" align="right" show-overflow-tooltip sortable :sort-method="sortNumeric('销售权重(%)')">
244 196 <template slot-scope="scope">{{ formatNumber(scope.row['销售权重(%)'], 2) }}</template>
245 197 </el-table-column>
246   - <el-table-column prop="金额权重(%)" label="金额权重(%)" min-width="110" align="right" show-overflow-tooltip>
  198 + <el-table-column prop="金额权重(%)" label="金额权重(%)" min-width="110" align="right" show-overflow-tooltip sortable :sort-method="sortNumeric('金额权重(%)')">
247 199 <template slot-scope="scope">{{ formatNumber(scope.row['金额权重(%)'], 2) }}</template>
248 200 </el-table-column>
249   - <el-table-column prop="利润权重(%)" label="利润权重(%)" min-width="110" align="right" show-overflow-tooltip>
  201 + <el-table-column prop="利润权重(%)" label="利润权重(%)" min-width="110" align="right" show-overflow-tooltip sortable :sort-method="sortNumeric('利润权重(%)')">
250 202 <template slot-scope="scope">{{ formatNumber(scope.row['利润权重(%)'], 2) }}</template>
251 203 </el-table-column>
252   - <el-table-column prop="平均利润" label="平均利润" min-width="110" align="right" show-overflow-tooltip>
  204 + <el-table-column prop="平均利润" label="平均利润" min-width="110" align="right" show-overflow-tooltip sortable :sort-method="sortNumeric('平均利润')">
253 205 <template slot-scope="scope">{{ formatNumber(scope.row['平均利润'], 4) }}</template>
254 206 </el-table-column>
255 207 </NCC-table>
... ... @@ -293,26 +245,6 @@ export default {
293 245 productLoading: false
294 246 }
295 247 },
296   - computed: {
297   - summaryStats() {
298   - const rows = Array.isArray(this.list) ? this.list : []
299   - let totalQty = 0
300   - let salesAmount = 0
301   - let profit = 0
302   - for (let i = 0; i < rows.length; i++) {
303   - const r = rows[i] || {}
304   - totalQty += this.parseNum(r['销售'])
305   - salesAmount += this.parseNum(r['销售金额'])
306   - profit += this.parseNum(r['毛利'])
307   - }
308   - return {
309   - rowCount: rows.length,
310   - totalQtyDisplay: this.formatSummaryNumber(totalQty, 4),
311   - salesAmountDisplay: this.formatSummaryNumber(salesAmount, 2),
312   - profitDisplay: this.formatSummaryNumber(profit, 2)
313   - }
314   - }
315   - },
316 248 created() {
317 249 this.loadFilterOptions()
318 250 this.fetchData()
... ... @@ -332,12 +264,17 @@ export default {
332 264 maximumFractionDigits: digits
333 265 })
334 266 },
335   - formatSummaryNumber(n, digits) {
336   - if (!Number.isFinite(n)) return '无'
337   - return n.toLocaleString('zh-CN', {
338   - minimumFractionDigits: 0,
339   - maximumFractionDigits: digits
340   - })
  267 + /** 表头排序:按数值字段(含千分位字符串) */
  268 + sortNumeric(prop) {
  269 + return (a, b) => this.parseNum(a[prop]) - this.parseNum(b[prop])
  270 + },
  271 + /** 表头排序:文本字段 */
  272 + sortText(prop) {
  273 + return (a, b) => {
  274 + const sa = String(a[prop] != null ? a[prop] : '').trim()
  275 + const sb = String(b[prop] != null ? b[prop] : '').trim()
  276 + return sa.localeCompare(sb, 'zh-CN')
  277 + }
341 278 },
342 279 displayText(val) {
343 280 if (val == null || String(val).trim() === '') return '无'
... ... @@ -469,105 +406,27 @@ export default {
469 406 </script>
470 407  
471 408 <style lang="scss" scoped>
472   -.product-summary-page {
473   - .product-summary-stats {
474   - margin-bottom: 8px;
475   - }
476   -
477   - .product-summary-stat-card {
478   - height: 100px;
479   - padding: 12px;
480   - border-radius: 12px;
481   - box-sizing: border-box;
482   - margin-bottom: 16px;
483   - background: #fff;
484   - border: 1px solid #ebeef5;
485   - box-shadow: 0 2px 12px rgba(15, 23, 42, 0.06);
486   - display: flex;
487   - align-items: center;
488   - }
489   -
490   - .product-summary-stat-card__inner {
491   - display: flex;
492   - align-items: center;
493   - width: 100%;
494   - gap: 12px;
495   - }
496   -
497   - .product-summary-stat-card__icon {
498   - font-size: 28px;
499   - flex-shrink: 0;
500   - }
501   -
502   - .product-summary-stat-card__text {
503   - min-width: 0;
504   - flex: 1;
505   - }
506   -
507   - .product-summary-stat-card__label {
508   - font-size: 13px;
509   - color: #909399;
510   - line-height: 1.3;
511   - margin-bottom: 4px;
512   - }
513   -
514   - .product-summary-stat-card__value {
515   - font-size: 18px;
516   - font-weight: 700;
517   - color: #303133;
518   - line-height: 1.2;
519   - }
520   -
521   - .product-summary-stat-card--blue .product-summary-stat-card__icon {
522   - color: #409eff;
523   - }
524   -
525   - .product-summary-stat-card--green .product-summary-stat-card__icon {
526   - color: #67c23a;
527   - }
528   -
529   - .product-summary-stat-card--orange .product-summary-stat-card__icon {
530   - color: #e6a23c;
531   - }
532   -
533   - .product-summary-stat-card--red .product-summary-stat-card__icon {
534   - color: #f56c6c;
535   - }
536   -
537   - .product-summary-head {
538   - align-items: center;
539   - }
540   -
541   - .product-summary-head__left {
542   - display: flex;
543   - flex-direction: column;
544   - align-items: flex-start;
545   - gap: 4px;
546   - }
547   -
548   - .product-summary-head__title {
549   - font-size: 15px;
550   - font-weight: 600;
551   - color: #303133;
552   - display: inline-flex;
553   - align-items: center;
554   - gap: 8px;
555   - }
  409 +.product-summary-head {
  410 + align-items: center;
  411 +}
556 412  
557   - .product-summary-head__title-icon {
558   - color: #409eff;
559   - font-size: 18px;
560   - }
  413 +.product-summary-head__title {
  414 + font-size: 15px;
  415 + font-weight: 600;
  416 + color: #303133;
  417 + display: inline-flex;
  418 + align-items: center;
  419 + gap: 8px;
  420 +}
561 421  
562   - .product-summary-head__hint {
563   - font-size: 12px;
564   - color: #909399;
565   - }
  422 +.product-summary-head__title-icon {
  423 + color: #409eff;
  424 + font-size: 18px;
  425 +}
566 426  
567   - .product-summary-table {
568   - ::v-deep .el-table .cell {
569   - white-space: nowrap;
570   - }
  427 +.product-summary-table {
  428 + ::v-deep .el-table .cell {
  429 + white-space: nowrap;
571 430 }
572 431 }
573 432 </style>
... ...
Antis.Erp.Plat/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/WtXsckdInfoOutput.cs
... ... @@ -114,9 +114,14 @@ namespace NCC.Extend.Entitys.Dto.WtXsckd
114 114 public string hysjh { get; set; }
115 115  
116 116 /// <summary>
117   - /// 供应商
  117 + /// 往来单位/供应商展示名(采购类单据可能为 wt_wldw 名称)
118 118 /// </summary>
119 119 public string gys { get; set; }
  120 +
  121 + /// <summary>
  122 + /// 与 wt_xsckd.gys 一致的主键(往来单位 wt_wldw 等,供表单下拉 value)
  123 + /// </summary>
  124 + public string gysId { get; set; }
120 125  
121 126 /// <summary>
122 127 /// 单据状态
... ...
Antis.Erp.Plat/netcore/src/Modularity/Extend/NCC.Extend/WtXsckdService.cs
... ... @@ -1138,6 +1138,26 @@ namespace NCC.Extend.WtXsckd
1138 1138 output.hysjh = entity.Hysjh ?? "";
1139 1139 }
1140 1140  
  1141 + // 采购入库/采购退货等:gys 常为 wt_wldw 主键;详情表单用 gysId,展示用名称
  1142 + output.gysId = entity.Gys;
  1143 + if (!string.IsNullOrWhiteSpace(entity.Gys))
  1144 + {
  1145 + var wldwGysMc = await _db.Queryable<WtWldwEntity>()
  1146 + .Where(w => w.Id == entity.Gys)
  1147 + .Select(w => w.Dwmc)
  1148 + .FirstAsync();
  1149 + if (!string.IsNullOrWhiteSpace(wldwGysMc))
  1150 + output.gys = wldwGysMc.Trim();
  1151 + else
  1152 + {
  1153 + var legacyGysMc = await _db.Queryable<WtGysEntity>()
  1154 + .Where(g => g.Id == entity.Gys)
  1155 + .Select(g => g.Gysmc)
  1156 + .FirstAsync();
  1157 + output.gys = string.IsNullOrWhiteSpace(legacyGysMc) ? entity.Gys : legacyGysMc.Trim();
  1158 + }
  1159 + }
  1160 +
1141 1161 // ✅ 经手人/制单人/审核人/过账人:与列表一致,将用户 ID 转为姓名(详情页展示)
1142 1162 await EnrichInfoOutputUserDisplayNamesAsync(output, entity);
1143 1163  
... ... @@ -1263,6 +1283,7 @@ namespace NCC.Extend.WtXsckd
1263 1283 .WhereIF(!string.IsNullOrEmpty(input.gzr), (xsckd, hy) => xsckd.Gzr.Equals(input.gzr))
1264 1284 .WhereIF(!string.IsNullOrEmpty(input.bz), (xsckd, hy) => xsckd.Bz.Contains(input.bz))
1265 1285 .WhereIF(!string.IsNullOrEmpty(input.kh), (xsckd, hy) => xsckd.Kh.Contains(input.kh))
  1286 + .WhereIF(!string.IsNullOrEmpty(input.gys), (xsckd, hy) => xsckd.Gys == input.gys.Trim())
1266 1287 .WhereIF(!string.IsNullOrEmpty(input.hysjh), (xsckd, hy) =>
1267 1288 (xsckd.Hysjh != null && xsckd.Hysjh.Contains(input.hysjh)) ||
1268 1289 (hy.Sjh != null && hy.Sjh.Contains(input.hysjh)))
... ... @@ -1332,6 +1353,7 @@ namespace NCC.Extend.WtXsckd
1332 1353 EnrichListOutputYcddhFromRemarkIfNeeded(row);
1333 1354 await EnrichWtXsckdListWarehouseDisplayAsync(pageRows);
1334 1355 await EnrichListOutputKhDisplayAsync(pageRows);
  1356 + await EnrichListOutputGysWldwDisplayAsync(pageRows);
1335 1357 await EnrichListPersonDisplayFromMemberHyAsync(pageRows);
1336 1358 if (pageRows.Any(x => x.djlx == "销售出库单" || x.djlx == "预售出库单"))
1337 1359 await EnrichOutboundLinkedReturnBillsAsync(pageRows);
... ... @@ -1467,6 +1489,48 @@ namespace NCC.Extend.WtXsckd
1467 1489 }
1468 1490  
1469 1491 /// <summary>
  1492 + /// 列表:采购入库/采购退货等主表 <c>gys</c> 存 wt_wldw 主键时,将 <c>gys</c> 列展示为往来单位名称(原 SQL 子查 wt_gys 可能为空)。
  1493 + /// </summary>
  1494 + private async Task EnrichListOutputGysWldwDisplayAsync(List<WtXsckdListOutput> items)
  1495 + {
  1496 + if (items == null || items.Count == 0) return;
  1497 + var targets = items.Where(x => x.djlx == "采购入库单" || x.djlx == "采购退货单").ToList();
  1498 + if (targets.Count == 0) return;
  1499 + var billIds = targets.Select(x => x.id).Where(id => !string.IsNullOrEmpty(id)).Select(id => id.Trim()).Distinct().ToList();
  1500 + if (billIds.Count == 0) return;
  1501 + var heads = await _db.Queryable<WtXsckdEntity>()
  1502 + .Where(x => billIds.Contains(x.Id))
  1503 + .Select(x => new { x.Id, x.Gys })
  1504 + .ToListAsync();
  1505 + var gysByBill = heads
  1506 + .Where(h => !string.IsNullOrEmpty(h.Id))
  1507 + .ToDictionary(h => h.Id.Trim(), h => h.Gys ?? "", StringComparer.Ordinal);
  1508 + var rawGysIds = gysByBill.Values
  1509 + .Where(s => !string.IsNullOrWhiteSpace(s))
  1510 + .Select(s => s.Trim())
  1511 + .Distinct()
  1512 + .ToList();
  1513 + if (rawGysIds.Count == 0) return;
  1514 + var wldwRows = await _db.Queryable<WtWldwEntity>()
  1515 + .Where(w => rawGysIds.Contains(w.Id))
  1516 + .Select(w => new { w.Id, w.Dwmc })
  1517 + .ToListAsync();
  1518 + var wldwDwmcById = wldwRows
  1519 + .Where(x => !string.IsNullOrEmpty(x.Id))
  1520 + .ToDictionary(x => x.Id.Trim(), x => x.Dwmc ?? "", StringComparer.Ordinal);
  1521 +
  1522 + foreach (var row in targets)
  1523 + {
  1524 + var bid = row.id?.Trim();
  1525 + if (string.IsNullOrEmpty(bid) || !gysByBill.TryGetValue(bid, out var rawGys) || string.IsNullOrWhiteSpace(rawGys))
  1526 + continue;
  1527 + var key = rawGys.Trim();
  1528 + if (wldwDwmcById.TryGetValue(key, out var dwmc) && !string.IsNullOrWhiteSpace(dwmc))
  1529 + row.gys = dwmc.Trim();
  1530 + }
  1531 + }
  1532 +
  1533 + /// <summary>
1470 1534 /// 销售/预售退货单:经手人应为操作人(系统用户),非会员。
1471 1535 /// </summary>
1472 1536 private static bool IsSalesOrPresaleReturnDjlx(string? djlx) =>
... ... @@ -2268,6 +2332,7 @@ namespace NCC.Extend.WtXsckd
2268 2332 .WhereIF(!string.IsNullOrEmpty(input.gzr), (xsckd, hy) => xsckd.Gzr.Equals(input.gzr))
2269 2333 .WhereIF(!string.IsNullOrEmpty(input.bz), (xsckd, hy) => xsckd.Bz.Contains(input.bz))
2270 2334 .WhereIF(!string.IsNullOrEmpty(input.kh), (xsckd, hy) => xsckd.Kh.Contains(input.kh))
  2335 + .WhereIF(!string.IsNullOrEmpty(input.gys), (xsckd, hy) => xsckd.Gys == input.gys.Trim())
2271 2336 .WhereIF(!string.IsNullOrEmpty(input.hysjh), (xsckd, hy) =>
2272 2337 (xsckd.Hysjh != null && xsckd.Hysjh.Contains(input.hysjh)) ||
2273 2338 (hy.Sjh != null && hy.Sjh.Contains(input.hysjh)))
... ... @@ -2316,6 +2381,7 @@ namespace NCC.Extend.WtXsckd
2316 2381 EnrichListOutputYcddhFromRemarkIfNeeded(row);
2317 2382 await EnrichWtXsckdListWarehouseDisplayAsync(data);
2318 2383 await EnrichListOutputKhDisplayAsync(data);
  2384 + await EnrichListOutputGysWldwDisplayAsync(data);
2319 2385 await EnrichListPersonDisplayFromMemberHyAsync(data);
2320 2386 await EnrichOutboundLinkedReturnBillsAsync(data);
2321 2387 if (data.Any(x => x.djlx == "预售出库单"))
... ...