Commit 8650cd478d7b2df6e835dd4c8975028fa7d1cc34

Authored by 史婷婷
1 parent 7d5ab104

feat: 延期发货单-编辑

... ... @@ -674,6 +674,14 @@
674 674 }
675 675 },
676 676 {
  677 + "path": "pages/delay_invoice/modify",
  678 + "style": {
  679 + "navigationBarTitleText": "编辑延期发货单",
  680 + "navigationBarBackgroundColor": "#ffffff",
  681 + "navigationBarTextStyle": "black"
  682 + }
  683 + },
  684 + {
677 685 "path": "pages/draft_order/index",
678 686 "style": {
679 687 "navigationBarTitleText": "草稿要车单",
... ...
... ... @@ -102,7 +102,7 @@ export default {
102 102 if (!id) return
103 103 uni.showModal({
104 104 title: '提示',
105   - content: '确定要取消该延发货单吗?',
  105 + content: '确定要取消该延发货单吗?',
106 106 success: async (res) => {
107 107 if (res.confirm) {
108 108 try {
... ...
  1 +<template>
  2 + <view class="page">
  3 + <scroll-view class="scroll" scroll-y>
  4 + <uni-list>
  5 + <view class="section">
  6 + <uni-list-item title="要车日期">
  7 + <template v-slot:footer>
  8 + <view class="readonly-text">{{ form.applyDate }}</view>
  9 + </template>
  10 + </uni-list-item>
  11 + <uni-list-item title="所属办">
  12 + <template v-slot:footer>
  13 + <view class="readonly-text">{{ form.deptName }}</view>
  14 + </template>
  15 + </uni-list-item>
  16 + </view>
  17 +
  18 + <!-- 产品 -->
  19 + <view class="section2">
  20 + <!-- mode="add" 允许编辑 -->
  21 + <Product mode="add" :list="initDelayedShipmentDetailList" @change="delayedShipmentDetailListChange"
  22 + :orderDate="form.orderDate" />
  23 + </view>
  24 + <view class="footer">
  25 + <button class="btn submit" type="primary" @click="onSubmit">保存</button>
  26 + </view>
  27 + </uni-list>
  28 + </scroll-view>
  29 + </view>
  30 +</template>
  31 +
  32 +<script>
  33 +import { updateApi, getDetailApi } from '@/api/delay_invoice.js'
  34 +import Product from './product.vue'
  35 +
  36 +export default {
  37 + name: 'DelayInvoiceModify',
  38 + components: { Product },
  39 + data() {
  40 + return {
  41 + form: {
  42 + id: '',
  43 + },
  44 + initDelayedShipmentDetailList: [],
  45 + }
  46 + },
  47 + onLoad(query) {
  48 + const id = (query && (query.id || query.code)) || ''
  49 + if (id) {
  50 + this.loadDetail(id)
  51 + }
  52 + },
  53 + methods: {
  54 + async loadDetail(id) {
  55 + try {
  56 + const res = await getDetailApi(id)
  57 + const m = res.data || {}
  58 + const next = { ...this.form, ...m }
  59 + // 确保ID存在
  60 + next.id = m.id || id
  61 + // 映射列表
  62 + // 注意:详情返回的是 replenishmentOrderLineList,需要赋值给 initDelayedShipmentDetailList 以便 Product 组件初始化
  63 + // 且需要处理字段兼容性,确保 Product 组件能正确显示和编辑
  64 + const lines = Array.isArray(m.delayedShipmentDetailList) ? m.delayedShipmentDetailList.map(x => ({
  65 + ...x,
  66 + // 确保 Product 组件需要的字段存在
  67 + // Product组件使用: quantity(需发), shippedQuantity(实发), supplementaryQuantity(需求补货), salesPrice(单价)
  68 + // 详情接口返回的字段应该已经包含了这些,如果有差异需要在此处转换
  69 + // 注意:add.vue中 onRelateConfirm 做了映射,这里是回显,通常直接使用即可
  70 + })) : []
  71 +
  72 + this.form = next;
  73 + this.initDelayedShipmentDetailList = lines;
  74 + } catch (e) {
  75 + uni.showToast({ title: '加载失败', icon: 'none' })
  76 + }
  77 + },
  78 + validateLineListRequired() {
  79 + const list = Array.isArray(this.form.delayedShipmentDetailList) ? this.form.delayedShipmentDetailList : []
  80 + if (list.length === 0) {
  81 + uni.showToast({ title: '请先添加产品', icon: 'none' })
  82 + return false
  83 + }
  84 + const fields = [
  85 + { key: 'applyShipmentDate', label: '现申请发货日期' },
  86 + ]
  87 + for (let i = 0; i < list.length; i++) {
  88 + const it = list[i] || {}
  89 + for (const f of fields) {
  90 + const v = it && it[f.key]
  91 + if (v === undefined || v === null || String(v).trim() === '') {
  92 + uni.showToast({ title: `产品第${i + 1}条:${f.label}不能为空!`, icon: 'none' })
  93 + return false
  94 + }
  95 + }
  96 + }
  97 + return true
  98 + },
  99 + async onSubmit() {
  100 + if (!this.validateLineListRequired()) return
  101 + const payload = { ...this.form }
  102 +
  103 + console.log('onSubmit__payload', payload)
  104 + try {
  105 + await updateApi(payload)
  106 + uni.showToast({ title: '保存成功', icon: 'success' })
  107 + setTimeout(() => { uni.redirectTo({ url: '/pages/delay_invoice/index' }) }, 300)
  108 + } catch (e) {
  109 + uni.showToast({ title: (e && e.msg) || '保存失败', icon: 'none' })
  110 + }
  111 + },
  112 + delayedShipmentDetailListChange(data) {
  113 + const list = Array.isArray(data) ? data : []
  114 + this.form.delayedShipmentDetailList = list
  115 + },
  116 + }
  117 +}
  118 +</script>
  119 +
  120 +<style lang="scss" scoped>
  121 +.page {
  122 + display: flex;
  123 + flex-direction: column;
  124 + height: 100%;
  125 +}
  126 +
  127 +.scroll {
  128 + flex: 1;
  129 + padding: 6rpx 0 400rpx;
  130 +}
  131 +
  132 +
  133 +
  134 +.title-header {
  135 + background-color: #fff;
  136 + display: flex;
  137 + align-items: center;
  138 + padding: 32rpx 32rpx 22rpx;
  139 +
  140 + .title-header_icon {
  141 + width: 32rpx;
  142 + height: 28rpx;
  143 + margin-right: 16rpx;
  144 + }
  145 +
  146 + span {
  147 + color: rgba(0, 0, 0, 0.9);
  148 + font-size: 32rpx;
  149 + line-height: 44rpx;
  150 + font-weight: 600;
  151 + }
  152 +}
  153 +
  154 +
  155 +.section {
  156 + background: #fff;
  157 + margin-bottom: 20rpx;
  158 +}
  159 +
  160 +.section2 {
  161 + background: #f1f1f1;
  162 +}
  163 +
  164 +::v-deep .uni-list {
  165 + background: transparent;
  166 +
  167 + &-item {
  168 + &__extra-text {
  169 + font-size: 32rpx;
  170 + }
  171 +
  172 + &__content-title {
  173 + font-size: 32rpx;
  174 + color: rgba(0, 0, 0, 0.9);
  175 + }
  176 +
  177 + &__container {
  178 + padding: 32rpx;
  179 + // align-items: center;
  180 +
  181 + .uni-easyinput {
  182 +
  183 + .is-disabled {
  184 + background-color: transparent !important;
  185 + }
  186 +
  187 + &__placeholder-class {
  188 + font-size: 32rpx;
  189 + color: rgba(0, 0, 0, 0.4);
  190 + }
  191 +
  192 + &__content {
  193 + border: none;
  194 +
  195 + &-input {
  196 + padding-left: 0 !important;
  197 + height: 48rpx;
  198 + line-height: 48rpx;
  199 + font-size: 32rpx;
  200 + }
  201 +
  202 + .content-clear-icon {
  203 + font-size: 44rpx !important;
  204 + }
  205 + }
  206 + }
  207 +
  208 + .amount-row {
  209 + flex: 1;
  210 + display: flex;
  211 + align-items: center;
  212 +
  213 + .uni-easyinput {
  214 + flex: 1;
  215 + }
  216 +
  217 + .unit {
  218 + margin-left: 16rpx;
  219 + color: rgba(0, 0, 0, 0.9);
  220 + }
  221 + }
  222 +
  223 + .item-title,
  224 + .uni-list-item__content {
  225 + flex: none;
  226 + min-height: 48rpx;
  227 + line-height: 48rpx;
  228 + font-size: 32rpx;
  229 + position: relative;
  230 + width: 210rpx;
  231 + margin-right: 32rpx;
  232 + color: rgba(0, 0, 0, 0.9);
  233 + padding-right: 0;
  234 +
  235 +
  236 + .required {
  237 + color: red;
  238 + position: absolute;
  239 + top: 50%;
  240 + transform: translateY(-50%);
  241 + left: -16rpx;
  242 + }
  243 + }
  244 +
  245 + }
  246 +
  247 + &.select-item {
  248 + &.is-empty {
  249 + .uni-list-item__extra-text {
  250 + color: rgba(0, 0, 0, 0.4) !important;
  251 + }
  252 + }
  253 +
  254 + &.is-filled {
  255 + .uni-list-item__extra-text {
  256 + color: rgba(0, 0, 0, 0.9) !important;
  257 + }
  258 + }
  259 +
  260 + .serial-number-row {
  261 + display: flex;
  262 + align-items: center;
  263 + }
  264 +
  265 + }
  266 +
  267 + &.mgb10 {
  268 + margin-bottom: 20rpx;
  269 + }
  270 +
  271 + }
  272 +
  273 + .title-header {
  274 + background-color: #fff;
  275 + display: flex;
  276 + align-items: center;
  277 + padding: 32rpx 32rpx 22rpx;
  278 +
  279 + &_icon {
  280 + width: 32rpx;
  281 + height: 28rpx;
  282 + margin-right: 16rpx;
  283 + }
  284 +
  285 + span {
  286 + color: rgba(0, 0, 0, 0.9);
  287 + font-size: 32rpx;
  288 + line-height: 44rpx;
  289 + font-weight: 600;
  290 + }
  291 + }
  292 +}
  293 +
  294 +/* 只读 easyinput 根据内容自适应高度 */
  295 +::v-deep .uni-list-item__container {
  296 + align-items: flex-start;
  297 +}
  298 +
  299 +/* 只读文本样式 */
  300 +.readonly-text {
  301 + color: rgba(0, 0, 0, 0.9);
  302 + font-size: 32rpx;
  303 + line-height: 48rpx;
  304 + text-align: right;
  305 + white-space: pre-wrap;
  306 + word-break: break-all;
  307 +}
  308 +
  309 +
  310 +.footer {
  311 + position: fixed;
  312 + left: 0;
  313 + right: 0;
  314 + bottom: 0;
  315 + padding: 0 32rpx 32rpx;
  316 + padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
  317 + background: #fff;
  318 + box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.06);
  319 + z-index: 10;
  320 +
  321 + .btn {
  322 + height: 80rpx;
  323 + line-height: 80rpx;
  324 + border-radius: 12rpx;
  325 + font-size: 32rpx;
  326 + }
  327 +
  328 + .submit {
  329 + background: $theme-primary;
  330 + color: #fff;
  331 + }
  332 +
  333 + .view-total {
  334 + padding: 20rpx 0;
  335 +
  336 + .head {
  337 + font-size: 32rpx;
  338 + font-weight: 600;
  339 + line-height: 50rpx;
  340 + color: rgba(0, 0, 0, 0.9);
  341 + padding-bottom: 16rpx;
  342 + margin-bottom: 24rpx;
  343 + border-bottom: 1px dashed #E7E7E7;
  344 + }
  345 +
  346 + .row {
  347 + display: flex;
  348 + margin-bottom: 24rpx;
  349 + line-height: 32rpx;
  350 +
  351 + .row2 {
  352 + width: 50%;
  353 + }
  354 +
  355 + .label {
  356 + width: 180rpx;
  357 + margin-right: 14rpx;
  358 + color: rgba(0, 0, 0, 0.6);
  359 + font-size: 28rpx;
  360 + }
  361 +
  362 + .value {
  363 + flex: 1;
  364 + color: rgba(0, 0, 0, 0.9);
  365 + font-size: 28rpx;
  366 + white-space: pre-wrap;
  367 + word-break: break-all;
  368 + }
  369 + }
  370 + }
  371 +}
  372 +</style>
\ No newline at end of file
... ...
... ... @@ -6,7 +6,7 @@
6 6 <image class="opCollapse" src="/static/images/title.png" />
7 7 <text class="title">{{ title || '产品' }}</text>
8 8 <view class="ops">
9   - <image v-if="mode === 'add'" class="opAdd" @click="onAdd" src="/static/images/plus.png" />
  9 + <!-- <image v-if="mode === 'add'" class="opAdd" @click="onAdd" src="/static/images/plus.png" /> -->
10 10 <view v-if="mode === 'view'" class="op1" @click="toggleViewCollapse">
11 11 <image class="opAdd" :src="collapsedView ? '/static/images/down.png' : '/static/images/up.png'" />
12 12 <text class="op">{{ collapsedView ? '展开' : '收起' }} </text>
... ... @@ -18,150 +18,61 @@
18 18 <view v-if="mode === 'add'" class="section">
19 19 <view v-for="(item, idx) in items" :key="'a-' + idx" class="block">
20 20 <uni-list class="edit-list">
21   - <uni-list-item title="号">
  21 + <uni-list-item title="订单编号">
22 22 <template v-slot:footer>
23   - <uni-easyinput v-model="item.brand" placeholder="请输入牌号" :inputBorder="false" />
  23 + <view class="value">{{ item.orderNo }}</view>
24 24 </template>
25 25 </uni-list-item>
26   - <uni-list-item title="厚度(mm)">
  26 + <uni-list-item title="原订单计划发货日期">
27 27 <template v-slot:footer>
28   - <uni-easyinput type="digit" v-model="item.thickness" placeholder="请输入厚度"
29   - :inputBorder="false" @input="onNonNegativeNumberInput($event, item, idx, 'thickness')"
30   - @blur="onNonNegativeNumberBlur(item, idx, 'thickness')" />
  28 + <view class="value">{{ item.deliveryDate }}</view>
31 29 </template>
32 30 </uni-list-item>
33   - <uni-list-item title="厚度公差上限(mm)">
  31 + <uni-list-item title="现申请发货日期">
34 32 <template v-slot:footer>
35   - <uni-easyinput type="number" v-model="item.thicknessTolPos" placeholder="请输入厚度公差上限"
36   - :inputBorder="false" @input="onRealNumberInput($event, item, idx, 'thicknessTolPos')"
37   - @blur="onRealNumberBlur(item, idx, 'thicknessTolPos')" />
38   - </template>
39   - </uni-list-item>
40   - <uni-list-item title="厚度公差下限(mm)">
41   - <template v-slot:footer>
42   - <uni-easyinput type="number" v-model="item.thicknessTolNeg" placeholder="请输入厚度公差下限"
43   - :inputBorder="false" @input="onRealNumberInput($event, item, idx, 'thicknessTolNeg')"
44   - @blur="onRealNumberBlur(item, idx, 'thicknessTolNeg')" />
  33 + <uni-datetime-picker type="date" v-model="item.applyShipmentDate" />
45 34 </template>
46 35 </uni-list-item>
  36 +
47 37 <view v-show="!item.collapsed">
48   - <uni-list-item title="宽度(mm)">
49   - <template v-slot:footer>
50   - <uni-easyinput type="digit" v-model="item.width" placeholder="请输入宽度"
51   - :inputBorder="false" @input="onNonNegativeNumberInput($event, item, idx, 'width')"
52   - @blur="onNonNegativeNumberBlur(item, idx, 'width')" />
53   - </template>
54   - </uni-list-item>
55   - <uni-list-item title="宽度公差上限(mm)">
56   - <template v-slot:footer>
57   - <uni-easyinput type="number" v-model="item.widthTolPos" placeholder="请输入宽度公差上限"
58   - :inputBorder="false" @input="onRealNumberInput($event, item, idx, 'widthTolPos')"
59   - @blur="onRealNumberBlur(item, idx, 'widthTolPos')" />
60   - </template>
61   - </uni-list-item>
62   - <uni-list-item title="宽度公差下限(mm)">
  38 + <uni-list-item title="申请次数">
63 39 <template v-slot:footer>
64   - <uni-easyinput type="number" v-model="item.widthTolNeg" placeholder="请输入宽度公差下限"
65   - :inputBorder="false" @input="onRealNumberInput($event, item, idx, 'widthTolNeg')"
66   - @blur="onRealNumberBlur(item, idx, 'widthTolNeg')" />
  40 + <view class="value">{{ item.applyCount }}</view>
67 41 </template>
68 42 </uni-list-item>
69   - <uni-list-item title="长度(mm)">
  43 + <uni-list-item title="订单类型">
70 44 <template v-slot:footer>
71   - <uni-easyinput type="digit" v-model="item.length" placeholder="请输入长度"
72   - :inputBorder="false" @input="onNonNegativeNumberInput($event, item, idx, 'length')"
73   - @blur="onNonNegativeNumberBlur(item, idx, 'length')" />
  45 + <view class="value">{{ item.orderType }}</view>
74 46 </template>
75 47 </uni-list-item>
76   - <uni-list-item title="长度公差上限(mm)">
  48 + <uni-list-item title="所属分厂">
77 49 <template v-slot:footer>
78   - <uni-easyinput type="number" v-model="item.lengthTolPos" placeholder="请输入长度公差上限"
79   - :inputBorder="false" @input="onRealNumberInput($event, item, idx, 'lengthTolPos')"
80   - @blur="onRealNumberBlur(item, idx, 'lengthTolPos')" />
  50 + <view class="value">{{ item.workshopName }}</view>
81 51 </template>
82 52 </uni-list-item>
83   - <uni-list-item title="长度公差下限(mm)">
  53 + <uni-list-item title="客户名称">
84 54 <template v-slot:footer>
85   - <uni-easyinput type="number" v-model="item.lengthTolNeg" placeholder="请输入长度公差下限"
86   - :inputBorder="false" @input="onRealNumberInput($event, item, idx, 'lengthTolNeg')"
87   - @blur="onRealNumberBlur(item, idx, 'lengthTolNeg')" />
  55 + <view class="value">{{ item.customerName }}</view>
88 56 </template>
89 57 </uni-list-item>
90   - <uni-list-item title="状态">
  58 + <uni-list-item title="发货数量">
91 59 <template v-slot:footer>
92   - <uni-easyinput v-model="item.status" placeholder="请输入状态" :inputBorder="false" />
  60 + <view class="value">{{ item.quantity }}</view>
93 61 </template>
94 62 </uni-list-item>
95   - <uni-list-item title="需发数量(kg)">
  63 + <uni-list-item title="延期原因">
96 64 <template v-slot:footer>
97   - <uni-easyinput type="digit" v-model="item.quantity" placeholder="请输入数量kg"
98   - :inputBorder="false"
99   - @input="onNonNegativeNumberInput($event, item, idx, 'quantity')"
100   - @blur="onNonNegativeNumberBlur(item, idx, 'quantity')" />
101   - </template>
102   - </uni-list-item>
103   - <uni-list-item title="实发数量(kg)">
104   - <template v-slot:footer>
105   - <uni-easyinput type="digit" v-model="item.shippedQuantity" placeholder="请输入实发数量kg"
106   - :inputBorder="false"
107   - @input="onNonNegativeNumberInput($event, item, idx, 'shippedQuantity')"
108   - @blur="onNonNegativeNumberBlur(item, idx, 'shippedQuantity')" />
109   - </template>
110   - </uni-list-item>
111   - <uni-list-item title="需求补货数量(kg)">
112   - <template v-slot:footer>
113   - <uni-easyinput type="digit" v-model="item.supplementaryQuantity"
114   - placeholder="请输入需求补货数量kg" :inputBorder="false"
115   - @input="onNonNegativeNumberInput($event, item, idx, 'supplementaryQuantity')"
116   - @blur="onNonNegativeNumberBlur(item, idx, 'supplementaryQuantity')" />
117   - </template>
118   - </uni-list-item>
119   - <uni-list-item class="amount-item">
120   - <template v-slot:body>
121   - <view class="item-title"><text>单价</text></view>
122   - </template>
123   - <template v-slot:footer>
124   - <view class="amount-row">
125   - <uni-easyinput type="digit" v-model="item.salesPrice" placeholder="0.00"
126   - :inputBorder="false"
127   - @input="onNonNegativeNumberInput($event, item, idx, 'salesPrice')"
128   - @blur="onNonNegativeNumberBlur(item, idx, 'salesPrice')" />
129   - <text class="unit">元</text>
130   - </view>
131   - </template>
132   - </uni-list-item>
133   - <uni-list-item class="amount-item">
134   - <template v-slot:body>
135   - <view class="item-title"><text>包装费</text></view>
136   - </template>
137   - <template v-slot:footer>
138   - <view class="amount-row">
139   - <uni-easyinput type="digit" v-model="item.packagingFee" placeholder="0.00"
140   - :inputBorder="false"
141   - @input="onNonNegativeNumberInput($event, item, idx, 'packagingFee')"
142   - @blur="onNonNegativeNumberBlur(item, idx, 'packagingFee')" />
143   - <text class="unit">元</text>
144   - </view>
145   - </template>
146   - </uni-list-item>
147   - <uni-list-item title="生产科(车间)确认交付时间">
148   - <template v-slot:footer>
149   - <view class="value">{{ item.confirmedDeliveryDate }}</view>
150   - </template>
151   - </uni-list-item>
152   - <uni-list-item title="备注">
153   - <template v-slot:footer>
154   - <uni-easyinput v-model="item.remarks" placeholder="请输入备注" :inputBorder="false" />
  65 + <uni-easyinput v-model="item.delayReason" placeholder="请输入延期原因" :inputBorder="false" />
155 66 </template>
156 67 </uni-list-item>
157 68 </view>
158 69 </uni-list>
159 70
160 71 <view class="block-ops">
161   - <div class="del" @click="onRemove(item.purchaseOrderId)">
  72 + <!-- <div class="del" @click="onRemove(item.purchaseOrderId)">
162 73 <image src="/static/images/delete.png" class="icon" />
163 74 删除
164   - </div>
  75 + </div> -->
165 76 <div class="toggle" @click="toggleItem(idx)">
166 77 <image :src="item.collapsed ? '/static/images/up.png' : '/static/images/down.png'"
167 78 class="icon" />
... ... @@ -177,13 +88,13 @@
177 88 <view class="row"><text class="label">原订单计划发货日期</text><text class="value">{{ item.deliveryDate }}</text>
178 89 </view>
179 90 <view class="row"><text class="label">现申请发货日期</text><text class="value">{{ item.applyShipmentDate
180   - }}</text>
  91 + }}</text>
181 92 </view>
182 93 <view class="row"><text class="label">申请次数</text><text class="value">{{ item.applyCount
183   - }}</text>
  94 + }}</text>
184 95 </view>
185 96 <view class="row"><text class="label">订单类型</text><text class="value">{{ item.orderType
186   - }}</text></view>
  97 + }}</text></view>
187 98 <view class="row"><text class="label">所属分厂</text><text class="value">{{ item.workshopName }}</text>
188 99 </view>
189 100 <view class="row"><text class="label">客户名称</text><text class="value">{{
... ...