Commit cf7b802df8408960ff3dec1ee7ca8da4cb003493

Authored by 史婷婷
1 parent 75f1c35b

feat: 撤销单-暂存

... ... @@ -195,6 +195,27 @@
195 195 "navigationBarBackgroundColor": "#ffffff",
196 196 "navigationBarTextStyle": "black"
197 197 }
  198 + },{
  199 + "path": "pages/revoke_list/add",
  200 + "style": {
  201 + "navigationBarTitleText": "新增撤销单",
  202 + "navigationBarBackgroundColor": "#ffffff",
  203 + "navigationBarTextStyle": "black"
  204 + }
  205 + },{
  206 + "path": "pages/revoke_list/detail",
  207 + "style": {
  208 + "navigationBarTitleText": "查看撤销单",
  209 + "navigationBarBackgroundColor": "#ffffff",
  210 + "navigationBarTextStyle": "black"
  211 + }
  212 + },{
  213 + "path": "pages/revoke_list/modify",
  214 + "style": {
  215 + "navigationBarTitleText": "编辑撤销单",
  216 + "navigationBarBackgroundColor": "#ffffff",
  217 + "navigationBarTextStyle": "black"
  218 + }
198 219 },
199 220 {
200 221 "path": "pages/change_list/index",
... ...
  1 +<template>
  2 + <view class="page">
  3 + <scroll-view class="scroll" scroll-y>
  4 + <uni-list>
  5 + <view class="section">
  6 + <uni-list-item class="select-item" :class="form.orderNo ? 'is-filled' : 'is-empty'" clickable
  7 + @click="openRelate('orderNo')" :rightText="form.orderNo || '请选择订单编号'" showArrow>
  8 + <template v-slot:body>
  9 + <view class="item-title"><text class="required">*</text><text>订单编号</text></view>
  10 + </template>
  11 + </uni-list-item>
  12 + <uni-list-item title="供货单位">
  13 + <template v-slot:footer>
  14 + <view class="readonly-text">{{ getDicName('SUPPLIER', form.supplyUnit, dicOptions.SUPPLIER) }}</view>
  15 + </template>
  16 + </uni-list-item>
  17 + <uni-list-item title="订货单位">
  18 + <template v-slot:footer>
  19 + <view class="readonly-text">{{ form.orderingUnitName }}</view>
  20 + </template>
  21 + </uni-list-item>
  22 + <uni-list-item title="订货日期">
  23 + <template v-slot:footer>
  24 + <view class="readonly-text">{{ form.orderDate }}</view>
  25 + </template>
  26 + </uni-list-item>
  27 + <uni-list-item title="生产厂">
  28 + <template v-slot:footer>
  29 + <view class="readonly-text">{{ form.workshopName }}</view>
  30 + </template>
  31 + </uni-list-item>
  32 + <uni-list-item title="结算方式或期限">
  33 + <template v-slot:footer>
  34 + <view class="readonly-text">{{ form.settlementTerms }}</view>
  35 + </template>
  36 + </uni-list-item>
  37 +
  38 + <uni-list-item title="交货方式">
  39 + <template v-slot:footer>
  40 + <uni-easyinput v-model="form.deliveryMethod" placeholder="请输入交货方式" :inputBorder="false" />
  41 + </template>
  42 + </uni-list-item>
  43 + </view>
  44 +
  45 + <!-- 产品 -->
  46 + <view class="section2">
  47 + <Product mode="add" :list="initPurchaseOrderLineList" @change="purchaseOrderLineListChange" />
  48 + </view>
  49 +
  50 + <view class="section">
  51 + <uni-list-item title="价格表编号">
  52 + <template v-slot:footer>
  53 + <uni-easyinput v-model="form.priceListNo" placeholder="请输入价格表编号" :inputBorder="false" />
  54 + </template>
  55 + </uni-list-item>
  56 + <uni-list-item title="开票情况">
  57 + <template v-slot:footer>
  58 + <uni-easyinput v-model="form.invoicingStatus" placeholder="请输入开票情况" :inputBorder="false" />
  59 + </template>
  60 + </uni-list-item>
  61 + <uni-list-item class="amount-item">
  62 + <template v-slot:body>
  63 + <view class="item-title"><text>运费</text></view>
  64 + </template>
  65 + <template v-slot:footer>
  66 + <view class="amount-row">
  67 + <uni-easyinput type="number" v-model="form.shippingCost" placeholder="0.00" :inputBorder="false" />
  68 + <text class="unit">元</text>
  69 + </view>
  70 + </template>
  71 + </uni-list-item>
  72 + <uni-list-item class="amount-item">
  73 + <template v-slot:body>
  74 + <view class="item-title"><text>包装费</text></view>
  75 + </template>
  76 + <template v-slot:footer>
  77 + <view class="amount-row">
  78 + <uni-easyinput type="number" v-model="form.packagingFee" placeholder="0.00" :inputBorder="false" />
  79 + <text class="unit">元</text>
  80 + </view>
  81 + </template>
  82 + </uni-list-item>
  83 + <uni-list-item class="select-item" :class="form.executionStandardName ? 'is-filled' : 'is-empty'" clickable
  84 + @click="openSheet('executionStandard')" :rightText="form.executionStandardName || '请选择'" showArrow>
  85 + <template v-slot:body>
  86 + <view class="item-title"><text>执行标准</text></view>
  87 + </template>
  88 + </uni-list-item>
  89 + </view>
  90 +
  91 +
  92 + <view class="title-header">
  93 + <image class="title-header_icon" src="/static/images/title.png" />
  94 + <span>具体质量要求</span>
  95 + </view>
  96 +
  97 + <uni-list-item title="件重条头">
  98 + <template v-slot:footer>
  99 + <uni-easyinput type="textarea" v-model="form.pieceWeightHeader" placeholder="请输入件重条头"
  100 + :inputBorder="false" />
  101 + </template>
  102 + </uni-list-item>
  103 + <uni-list-item title="表面">
  104 + <template v-slot:footer>
  105 + <uni-easyinput type="textarea" v-model="form.surface" placeholder="请输入表面" :inputBorder="false" />
  106 + </template>
  107 + </uni-list-item>
  108 + <uni-list-item title="公差">
  109 + <template v-slot:footer>
  110 + <uni-easyinput type="textarea" v-model="form.tolerance" placeholder="请输入公差" :inputBorder="false" />
  111 + </template>
  112 + </uni-list-item>
  113 + <uni-list-item title="性能">
  114 + <template v-slot:footer>
  115 + <uni-easyinput type="textarea" v-model="form.performance" placeholder="请输入性能" :inputBorder="false" />
  116 + </template>
  117 + </uni-list-item>
  118 + <uni-list-item title="成分">
  119 + <template v-slot:footer>
  120 + <uni-easyinput type="textarea" v-model="form.element" placeholder="请输入成分" :inputBorder="false" />
  121 + </template>
  122 + </uni-list-item>
  123 + <uni-list-item title="包装">
  124 + <template v-slot:footer>
  125 + <uni-easyinput type="textarea" v-model="form.packaging" placeholder="请输入包装" :inputBorder="false" />
  126 + </template>
  127 + </uni-list-item>
  128 + <uni-list-item title="备注">
  129 + <template v-slot:footer>
  130 + <uni-easyinput type="textarea" v-model="form.remarks" placeholder="请输入备注" :inputBorder="false" />
  131 + </template>
  132 + </uni-list-item>
  133 +
  134 +
  135 + </uni-list>
  136 + </scroll-view>
  137 +
  138 + <view class="footer">
  139 + <view class="view-total">
  140 + <view class="head">合计</view>
  141 + <view class="row">
  142 + <text class="label">总数量</text><text class="value">{{ form.afterTotalQuantity }}</text>
  143 + </view>
  144 + </view>
  145 + <button class="btn submit" type="primary" @click="onSubmit">提交</button>
  146 + </view>
  147 + <SingleSelectSheet :visible.sync="sheet.visible" :title="sheet.title" :options="sheet.options" v-model="sheet.value"
  148 + @confirm="onSheetConfirm" />
  149 + <RelateSelectSheet :visible.sync="relate.visible" :title="relate.title" :source="relate.source"
  150 + :display-fields="relate.display" :multiple="relate.multiple" :row-key="relate.rowKey"
  151 + :selectedKeys.sync="relate.selectedKeys" :source-extra="{ queryType: 'CHANGE' }" @confirm="onRelateConfirm" />
  152 + </view>
  153 +</template>
  154 +
  155 +<script>
  156 +import { createApi, loadOrderApi } from '@/api/change_list.js'
  157 +import Product from './product.vue'
  158 +import SingleSelectSheet from '@/components/single-select/index.vue'
  159 +import RelateSelectSheet from '@/components/relate-select/index.vue'
  160 +import { getDicName } from '@/utils/dic.js'
  161 +import { getDicByCodes } from '@/utils/dic'
  162 +
  163 +export default {
  164 + name: 'ChangeListAdd',
  165 + components: { Product, SingleSelectSheet, RelateSelectSheet },
  166 + data() {
  167 + return {
  168 + form: {
  169 + orderNo: '',
  170 + orderId: '',
  171 + supplyUnit: '',
  172 + orderingUnit: '',
  173 + orderDate: '',
  174 + workshopId: '',
  175 + settlementTerms: '',
  176 + deliveryMethod: '',
  177 + priceListNo: '',
  178 + invoicingStatus: '',
  179 + shippingCost: '',
  180 + packagingFee: '',
  181 + executionStandard: '',
  182 + executionStandardRemarks: '',
  183 + totalQuantity: '',
  184 + afterTotalQuantity: '',
  185 + pieceWeightHeader: '',
  186 + surface: '',
  187 + tolerance: '',
  188 + performance: '',
  189 + element: '',
  190 + packaging: '',
  191 + remarks: '',
  192 + // 默认当前日期 格式为 yyyy-MM-dd
  193 + orderDate: new Date().toISOString().substring(0, 10),
  194 +
  195 + },
  196 + initPurchaseOrderLineList: [],
  197 + dicOptions: { SUPPLIER: [], APPLICABLE_STANDARD: [] },
  198 + sheet: { visible: false, title: '请选择', options: [], value: '', field: '' },
  199 + relate: { visible: false, title: '选择', source: '', display: [], multiple: false, rowKey: 'id', selectedKeys: [], fieldKey: '' }
  200 + }
  201 + },
  202 + onLoad() {
  203 + this.loadDicOptions()
  204 + },
  205 + methods: {
  206 + loadDicOptions() {
  207 + const dicCodes = ['SUPPLIER', 'APPLICABLE_STANDARD']
  208 + return getDicByCodes(dicCodes).then(results => {
  209 + this.dicOptions.SUPPLIER = results.SUPPLIER && results.SUPPLIER.data ? results.SUPPLIER.data : []
  210 + this.dicOptions.APPLICABLE_STANDARD = results.APPLICABLE_STANDARD && results.APPLICABLE_STANDARD.data ? results.APPLICABLE_STANDARD.data : []
  211 + this.refreshStandardName()
  212 + }).catch(() => { this.dicOptions = { SUPPLIER: [], APPLICABLE_STANDARD: [] } })
  213 + },
  214 + async loadDetail(id) {
  215 + try {
  216 + const res = await getDetailApi(id)
  217 + const m = res.data || {}
  218 + const next = { ...this.form, ...m }
  219 + next.id = m.id || m.code || id
  220 + next.purchaseOrderLineList = Array.isArray(m.purchaseOrderLineList) ? m.purchaseOrderLineList.map(x => ({ ...x })) : []
  221 + this.form = next;
  222 + this.initPurchaseOrderLineList = next.purchaseOrderLineList || [];
  223 + this.refreshStandardName()
  224 + } catch (e) {
  225 + uni.showToast({ title: '加载失败', icon: 'none' })
  226 + }
  227 + },
  228 + refreshStandardName() {
  229 + const est = (this.dicOptions.APPLICABLE_STANDARD || []).find(o => String(o.code) === String(this.form.executionStandard))
  230 + this.form.executionStandardName = est ? (est.name || '') : (this.form.executionStandardName || '')
  231 + },
  232 + openSheet(field) {
  233 + if (field === 'executionStandard') {
  234 + const options = (this.dicOptions.APPLICABLE_STANDARD || []).map(it => ({ label: it.name || '', value: it.code || '' }))
  235 + const current = this.form.executionStandard
  236 + const match = options.find(o => String(o.value) === String(current))
  237 + this.sheet = { ...this.sheet, visible: true, title: '执行标准', options, field, value: match ? match.value : '' }
  238 + }
  239 + },
  240 + onSheetConfirm({ value, label }) {
  241 + const field = this.sheet.field
  242 + if (field === 'executionStandard') {
  243 + this.form.executionStandard = value || ''
  244 + this.form.executionStandardName = label || ''
  245 + }
  246 + this.sheet.visible = false
  247 + },
  248 + openRelate(fieldKey) {
  249 + let config = {}
  250 + if (fieldKey === 'orderNo') {
  251 + config = {
  252 + title: '订单',
  253 + source: 'orderAssoc',
  254 + rowKey: 'id',
  255 + multiple: false,
  256 + display: [
  257 + { label: '订单编号', field: 'orderNo' },
  258 + { label: '订货单位', field: 'orderingUnitName' },
  259 + { label: '生产厂', field: 'workshopName' },
  260 + { label: '办事处', field: 'deptName' },
  261 + { label: '总数量(kg)', field: 'totalQuantity' },
  262 + { label: '订货日期', field: 'orderDate' },
  263 + { label: '下单人', field: 'contractCreateByName' }
  264 + ]
  265 + }
  266 + }
  267 + const currentId = this.form && (this.form.id || this.form.code)
  268 + const selectedKeys = currentId ? [currentId] : []
  269 + this.sheet.visible = false
  270 + this.relate.title = config.title
  271 + this.relate.source = config.source
  272 + this.relate.display = config.display
  273 + this.relate.multiple = config.multiple
  274 + this.relate.rowKey = config.rowKey
  275 + this.relate.selectedKeys = selectedKeys
  276 + this.relate.fieldKey = fieldKey
  277 + this.$nextTick(() => { this.relate.visible = true })
  278 + },
  279 + async onRelateConfirm({ items }) {
  280 + const _fieldKey = this.relate.fieldKey
  281 + const first = (items && items.length > 0) ? items[0] : null
  282 + if (_fieldKey === 'orderNo') {
  283 + const id = first && (first.id || first.code)
  284 + if (id) {
  285 + try {
  286 + const res = await loadOrderApi([id])
  287 + const data = res && res.data ? res.data : null
  288 + const item = Array.isArray(data) ? (data[0] || {}) : (data || {})
  289 + const next = { ...this.form, ...item }
  290 + next.orderNo = next.orderNo || ((first && (first.orderNo || first.code)) || '');
  291 + next.orderId = next.id || '';
  292 + delete next.id
  293 + this.form = next
  294 + const lines = Array.isArray(item.purchaseOrderLineList) ? item.purchaseOrderLineList.map(x => ({ ...x, purchaseOrderId: x.id, id: '' })) : []
  295 + this.initPurchaseOrderLineList = lines
  296 + const sum = lines.reduce((acc, it) => {
  297 + const v = Number(it && it.quantity)
  298 + return acc + (isNaN(v) ? 0 : v)
  299 + }, 0)
  300 + this.form.afterTotalQuantity = sum
  301 + this.refreshStandardName()
  302 + } catch (e) {
  303 + this.form.orderNo = (first && (first.orderNo || first.code)) || ''
  304 + }
  305 + } else {
  306 + this.form.orderNo = (first && (first.orderNo || first.code)) || ''
  307 + }
  308 + }
  309 + },
  310 + getDicName: getDicName,
  311 + validateRequired() {
  312 + const checks = [
  313 + { key: 'orderNo', label: '订单编号' }
  314 + ]
  315 + for (const it of checks) {
  316 + const val = this.form[it.key]
  317 + if (val === undefined || val === null || String(val).trim() === '') {
  318 + uni.showToast({ title: `请先选择${it.label}`, icon: 'none' })
  319 + return false
  320 + }
  321 + }
  322 + return true
  323 + },
  324 + validateLineListRequired() {
  325 + const list = Array.isArray(this.form.purchaseOrderLineList) ? this.form.purchaseOrderLineList : []
  326 + if (list.length === 0) {
  327 + uni.showToast({ title: '请先添加产品', icon: 'none' })
  328 + return false
  329 + }
  330 + const fields = [
  331 + { key: 'industry', label: '行业' },
  332 + { key: 'quality', label: '品质' },
  333 + { key: 'brand', label: '牌号' },
  334 + { key: 'quantity', label: '数量' },
  335 + { key: 'salesPrice', label: '销售价格' },
  336 + { key: 'deliveryDate', label: '发货日期' },
  337 + ]
  338 + for (let i = 0; i < list.length; i++) {
  339 + const it = list[i] || {}
  340 + for (const f of fields) {
  341 + const v = it && it[f.key]
  342 + if (v === undefined || v === null || String(v).trim() === '') {
  343 + uni.showToast({ title: `产品第${i + 1}条:${f.label}不能为空!`, icon: 'none' })
  344 + return false
  345 + }
  346 + }
  347 + }
  348 + return true
  349 + },
  350 + async onSubmit() {
  351 + if (!this.validateRequired()) return
  352 + if (!this.validateLineListRequired()) return
  353 + const payload = { ...this.form }
  354 + payload.orderSpecList = payload.purchaseOrderLineList || [];
  355 + delete payload.purchaseOrderLineList;
  356 + console.log('onSubmit__payload', payload)
  357 + try {
  358 + await createApi(payload)
  359 + uni.showToast({ title: '保存成功', icon: 'success' })
  360 + setTimeout(() => { uni.redirectTo({ url: '/pages/order_list/index' }) }, 300)
  361 + } catch (e) {
  362 + uni.showToast({ title: (e && e.msg) || '保存失败', icon: 'none' })
  363 + }
  364 + },
  365 + purchaseOrderLineListChange(data) {
  366 + const list = Array.isArray(data) ? data : []
  367 + this.form.purchaseOrderLineList = list
  368 + const sum = list.reduce((acc, it) => {
  369 + const v = Number(it && it.quantity)
  370 + return acc + (isNaN(v) ? 0 : v)
  371 + }, 0)
  372 + this.form.afterTotalQuantity = sum
  373 + },
  374 + }
  375 +}
  376 +</script>
  377 +
  378 +<style lang="scss" scoped>
  379 +.page {
  380 + display: flex;
  381 + flex-direction: column;
  382 + height: 100%;
  383 +}
  384 +
  385 +.scroll {
  386 + flex: 1;
  387 + padding: 6rpx 0 310rpx;
  388 +}
  389 +
  390 +
  391 +
  392 +.title-header {
  393 + background-color: #fff;
  394 + display: flex;
  395 + align-items: center;
  396 + padding: 32rpx 32rpx 22rpx;
  397 +
  398 + .title-header_icon {
  399 + width: 32rpx;
  400 + height: 28rpx;
  401 + margin-right: 16rpx;
  402 + }
  403 +
  404 + span {
  405 + color: rgba(0, 0, 0, 0.9);
  406 + font-size: 32rpx;
  407 + line-height: 44rpx;
  408 + font-weight: 600;
  409 + }
  410 +}
  411 +
  412 +
  413 +.section {
  414 + background: #fff;
  415 + margin-bottom: 20rpx;
  416 +}
  417 +
  418 +.section2 {
  419 + background: #f1f1f1;
  420 +}
  421 +
  422 +::v-deep .uni-list {
  423 + background: transparent;
  424 +
  425 + &-item {
  426 + &__extra-text {
  427 + font-size: 32rpx;
  428 + }
  429 +
  430 + &__content-title {
  431 + font-size: 32rpx;
  432 + color: rgba(0, 0, 0, 0.9);
  433 + }
  434 +
  435 + &__container {
  436 + padding: 32rpx;
  437 + // align-items: center;
  438 +
  439 + .uni-easyinput {
  440 +
  441 + .is-disabled {
  442 + background-color: transparent !important;
  443 + }
  444 +
  445 + &__placeholder-class {
  446 + font-size: 32rpx;
  447 + color: rgba(0, 0, 0, 0.4);
  448 + }
  449 +
  450 + &__content {
  451 + border: none;
  452 +
  453 + &-input {
  454 + padding-left: 0 !important;
  455 + height: 48rpx;
  456 + line-height: 48rpx;
  457 + font-size: 32rpx;
  458 + }
  459 +
  460 + .content-clear-icon {
  461 + font-size: 44rpx !important;
  462 + }
  463 + }
  464 + }
  465 +
  466 + .amount-row {
  467 + flex: 1;
  468 + display: flex;
  469 + align-items: center;
  470 +
  471 + .uni-easyinput {
  472 + flex: 1;
  473 + }
  474 +
  475 + .unit {
  476 + margin-left: 16rpx;
  477 + color: rgba(0, 0, 0, 0.9);
  478 + }
  479 + }
  480 +
  481 + .item-title,
  482 + .uni-list-item__content {
  483 + flex: none;
  484 + min-height: 48rpx;
  485 + line-height: 48rpx;
  486 + font-size: 32rpx;
  487 + position: relative;
  488 + width: 162rpx;
  489 + margin-right: 32rpx;
  490 + color: rgba(0, 0, 0, 0.9);
  491 + padding-right: 0;
  492 +
  493 +
  494 + .required {
  495 + color: red;
  496 + position: absolute;
  497 + top: 50%;
  498 + transform: translateY(-50%);
  499 + left: -16rpx;
  500 + }
  501 + }
  502 +
  503 + }
  504 +
  505 + &.select-item {
  506 + &.is-empty {
  507 + .uni-list-item__extra-text {
  508 + color: rgba(0, 0, 0, 0.4) !important;
  509 + }
  510 + }
  511 +
  512 + &.is-filled {
  513 + .uni-list-item__extra-text {
  514 + color: rgba(0, 0, 0, 0.9) !important;
  515 + }
  516 + }
  517 +
  518 + .serial-number-row {
  519 + display: flex;
  520 + align-items: center;
  521 + }
  522 +
  523 + }
  524 +
  525 + &.mgb10 {
  526 + margin-bottom: 20rpx;
  527 + }
  528 +
  529 + }
  530 +
  531 + .title-header {
  532 + background-color: #fff;
  533 + display: flex;
  534 + align-items: center;
  535 + padding: 32rpx 32rpx 22rpx;
  536 +
  537 + &_icon {
  538 + width: 32rpx;
  539 + height: 28rpx;
  540 + margin-right: 16rpx;
  541 + }
  542 +
  543 + span {
  544 + color: rgba(0, 0, 0, 0.9);
  545 + font-size: 32rpx;
  546 + line-height: 44rpx;
  547 + font-weight: 600;
  548 + }
  549 + }
  550 +}
  551 +
  552 +/* 只读 easyinput 根据内容自适应高度 */
  553 +::v-deep .uni-list-item__container {
  554 + align-items: flex-start;
  555 +}
  556 +
  557 +/* 只读文本样式 */
  558 +.readonly-text {
  559 + color: rgba(0, 0, 0, 0.9);
  560 + font-size: 32rpx;
  561 + line-height: 44rpx;
  562 + text-align: right;
  563 + white-space: pre-wrap;
  564 + word-break: break-all;
  565 +}
  566 +
  567 +
  568 +.footer {
  569 + position: fixed;
  570 + left: 0;
  571 + right: 0;
  572 + bottom: 0;
  573 + padding: 0 32rpx 32rpx;
  574 + padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
  575 + background: #fff;
  576 + box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.06);
  577 +
  578 + .btn {
  579 + height: 80rpx;
  580 + line-height: 80rpx;
  581 + border-radius: 12rpx;
  582 + font-size: 32rpx;
  583 + }
  584 +
  585 + .submit {
  586 + background: $theme-primary;
  587 + color: #fff;
  588 + }
  589 +
  590 + .view-total {
  591 + padding: 20rpx 0;
  592 +
  593 + .head {
  594 + font-size: 32rpx;
  595 + font-weight: 600;
  596 + line-height: 50rpx;
  597 + color: rgba(0, 0, 0, 0.9);
  598 + padding-bottom: 16rpx;
  599 + margin-bottom: 24rpx;
  600 + ;
  601 + border-bottom: 1px dashed #E7E7E7;
  602 + }
  603 +
  604 + .row {
  605 + display: flex;
  606 + margin-bottom: 24rpx;
  607 + line-height: 32rpx;
  608 +
  609 + .label {
  610 + width: 180rpx;
  611 + margin-right: 14rpx;
  612 + color: rgba(0, 0, 0, 0.6);
  613 + font-size: 28rpx;
  614 + }
  615 +
  616 + .value {
  617 + flex: 1;
  618 + color: rgba(0, 0, 0, 0.9);
  619 + font-size: 28rpx;
  620 + white-space: pre-wrap;
  621 + word-break: break-all;
  622 + }
  623 + }
  624 + }
  625 +}
  626 +</style>
... ...
  1 +<template>
  2 + <view class="page">
  3 + <scroll-view class="scroll" scroll-y>
  4 + <view class="detail-page">
  5 + <view class="section">
  6 + <text class="row company">{{ form.orderNo }}</text>
  7 + <view :class="['status', `status_${form.examineStatus}`]" />
  8 + <view class="row"><text class="label">供货单位</text><text class="value">{{ getDicName('SUPPLIER',
  9 + form.supplyUnit, dicOptions.SUPPLIER) }}</text></view>
  10 + <view class="row"><text class="label">订货单位</text><text class="value">{{ form.orderingUnitName }}</text>
  11 + </view>
  12 + <view class="row"><text class="label">订货日期</text><text class="value">{{ form.orderDate }}</text></view>
  13 + <view class="row"><text class="label">生产厂</text><text class="value">{{ form.workshopName }}</text></view>
  14 + <view class="row"><text class="label">结算方式或期限</text><text class="value">{{ form.settlementTerms }}</text></view>
  15 + <view class="row"><text class="label">交货方式</text><text class="value">{{ form.deliveryMethod }}</text></view>
  16 + </view>
  17 +
  18 + <!-- 产品-变更前 -->
  19 + <view class="mgb10">
  20 + <Product title="变更前" mode="view" :options="genderOptions" :list="form.beforeChangeSpecList" :totalQuantity="form.totalQuantity || 0" />
  21 + </view>
  22 +
  23 + <!-- 产品-变更后 -->
  24 + <view class="mgb10">
  25 + <Product title="变更后" mode="view" :options="genderOptions" :list="form.afterChangeSpecList" :totalQuantity="form.afterTotalQuantity || 0" />
  26 + </view>
  27 +
  28 + <view class="section">
  29 + <view class="row"><text class="label">价格表编号</text><text class="value">{{ form.priceListNo }}</text></view>
  30 + <view class="row"><text class="label">开票情况</text><text class="value">{{ form.invoicingStatus }}</text></view>
  31 + <view class="row"><text class="label">运费</text><text class="value">{{ form.shippingCost }}</text></view>
  32 + <view class="row"><text class="label">包装费</text><text class="value">{{ form.packagingFee }}</text></view>
  33 + <view class="row"><text class="label">执行标准</text><text class="value">{{ getDicName('APPLICABLE_STANDARD',
  34 + form.executionStandard, dicOptions.APPLICABLE_STANDARD) }}</text></view>
  35 + </view>
  36 +
  37 + <view class="title-header">
  38 + <image class="title-header_icon" src="/static/images/title.png" />
  39 + <span>具体质量要求</span>
  40 + </view>
  41 + <view class="section">
  42 + <view class="row"><text class="label">件重条头</text><text class="value">{{ form.pieceWeightHeader }}</text></view>
  43 + <view class="row"><text class="label">表面</text><text class="value">{{ form.surface }}</text></view>
  44 + <view class="row"><text class="label">公差</text><text class="value">{{ form.tolerance }}</text></view>
  45 + <view class="row"><text class="label">性能</text><text class="value">{{ form.performance }}</text></view>
  46 + <view class="row"><text class="label">成分</text><text class="value">{{ form.element }}</text></view>
  47 + <view class="row"><text class="label">包装</text><text class="value">{{ form.packaging }}</text></view>
  48 + <view class="row"><text class="label">备注</text><text class="value">{{ form.remarks }}</text></view>
  49 + </view>
  50 +
  51 + </view>
  52 + </scroll-view>
  53 + <detail-buttons :buttons="displayButtons" @click="handleButtonClick" />
  54 + </view>
  55 +</template>
  56 +
  57 +<script>
  58 +import { getDetailApi, cancelApi, confirmApi } from '@/api/change_list.js'
  59 +import Product from './product.vue'
  60 +import DetailButtons from '@/components/detail-buttons/index.vue'
  61 +import {
  62 + getDicName
  63 +} from '@/utils/dic.js'
  64 +import {
  65 + getDicByCodes
  66 +} from '@/utils/dic'
  67 +
  68 +export default {
  69 + name: 'ChangeListDetail',
  70 + components: { Product, DetailButtons },
  71 + data() {
  72 + return {
  73 + form: {},
  74 + enterpriseTypeOptions: [],
  75 + genderOptions: [],
  76 + categoryOptions: [],
  77 + historyList: [],
  78 + buttons: [
  79 + { text: '编辑', visible: true, variant: 'outline', event: 'edit' },
  80 + { text: '审核详情', visible: true, variant: 'outline', event: 'auditDetail' },
  81 + { text: '审核', visible: true, variant: 'primary', event: 'audit' },
  82 + { text: '确认变更', visible: true, variant: 'outline', event: 'confirmChange' },
  83 + { text: '取消', visible: true, variant: 'outline', event: 'cancel', style: { color: 'rgba(0,0,0,0.9)', border: '1px solid #DCDCDC' } },
  84 + ],
  85 + dicOptions: {
  86 + AUDIT_STATUS: [],
  87 + SUPPLIER: [],
  88 + APPLICABLE_STANDARD: [],
  89 + },
  90 + }
  91 + },
  92 + computed: {
  93 + statusFlags() {
  94 + const m = this.form || {}
  95 + const e = String(m.examineStatus || '')
  96 + return {
  97 + isRefuse: e === 'REFUSE',
  98 + isAudit: e === 'AUDIT',
  99 + canEdit: e === 'REFUSE' && !!m.changeCreateBy,
  100 + canAudit: e === 'AUDIT' && !!m.showExamine,
  101 + canCancel: e === 'REFUSE',
  102 + canConfirmChange: e === 'REFUSE' && !!m.output
  103 + }
  104 + },
  105 + displayButtons() {
  106 + const f = this.statusFlags
  107 + return [
  108 + { ...this.buttons[0], visible: f.canEdit },
  109 + { ...this.buttons[1], visible: true },
  110 + { ...this.buttons[2], visible: f.canAudit },
  111 + { ...this.buttons[3], visible: f.canConfirmChange },
  112 + { ...this.buttons[4], visible: f.canCancel },
  113 + ]
  114 + }
  115 + },
  116 + created() {
  117 + this.loadAllDicData()
  118 + },
  119 + onLoad(query) {
  120 + const id = (query && (query.id || query.code)) || ''
  121 + if (id) this.loadDetail(id)
  122 + },
  123 + methods: {
  124 + async loadDetail(id) {
  125 + try {
  126 + const res = await getDetailApi(id)
  127 + const data = res.data || {}
  128 + this.form = { ...data }
  129 + } catch (e) {
  130 + this.form = {}
  131 + }
  132 + },
  133 + handleButtonClick(btn) {
  134 + if (!btn || btn.disabled) return
  135 + const map = {
  136 + edit: () => this.onEdit(),
  137 + auditDetail: () => this.onAuditDetail(),
  138 + audit: () => this.onAudit(),
  139 + confirmChange: () => this.onConfirmChange(),
  140 + cancel: () => this.onCancel(),
  141 + }
  142 + const fn = map[btn.event]
  143 + if (typeof fn === 'function') fn()
  144 + },
  145 + getBusinessId() {
  146 + return (this.form && (this.form.id || this.form.code)) || ''
  147 + },
  148 + onEdit() {
  149 + const id = this.getBusinessId()
  150 + const query = id ? ('?id=' + encodeURIComponent(id)) : ''
  151 + uni.navigateTo({ url: '/pages/change_list/modify' + query })
  152 + },
  153 + onAuditDetail() {
  154 + const CACHE_KEY = 'sourceBusinessId'
  155 + uni.setStorageSync(CACHE_KEY, this.getBusinessId())
  156 + uni.navigateTo({ url: '/pages/flow/audit_detail' })
  157 + },
  158 + onAudit() {
  159 + const CACHE_KEY = 'sourceBusinessId'
  160 + uni.setStorageSync(CACHE_KEY, this.getBusinessId())
  161 + uni.navigateTo({ url: '/pages/flow/audit' })
  162 + },
  163 + onConfirmChange() {
  164 + const id = this.getBusinessId();
  165 + if (!id) return
  166 + uni.showModal({
  167 + title: '系统提示',
  168 + content: '是否确定确认变更?',
  169 + confirmText: '确定',
  170 + cancelText: '取消',
  171 + success: (res) => {
  172 + if (res && res.confirm) {
  173 + confirmApi(id).then(() => {
  174 + uni.showToast({ title: '已确认变更', icon: 'none' })
  175 + setTimeout(() => { uni.redirectTo({ url: '/pages/change_list/index' }) }, 300)
  176 + }).catch(() => {
  177 + uni.showToast({ title: '确认变更失败', icon: 'none' })
  178 + })
  179 + }
  180 + }
  181 + })
  182 + },
  183 + onCancel() {
  184 + const id = this.getBusinessId()
  185 + if (!id) return
  186 + uni.showModal({
  187 + title: '系统提示',
  188 + content: '是否确定取消该流程?',
  189 + confirmText: '确定',
  190 + cancelText: '取消',
  191 + success: (res) => {
  192 + if (res && res.confirm) {
  193 + cancelApi(id).then(() => {
  194 + uni.showToast({ title: '已取消', icon: 'none' })
  195 + setTimeout(() => { uni.redirectTo({ url: '/pages/change_list/index' }) }, 300)
  196 + }).catch(() => {
  197 + uni.showToast({ title: '取消失败', icon: 'none' })
  198 + })
  199 + }
  200 + }
  201 + })
  202 + },
  203 + loadAllDicData() {
  204 + const dicCodes = ['AUDIT_STATUS', 'SUPPLIER', 'APPLICABLE_STANDARD']
  205 + return getDicByCodes(dicCodes).then(results => {
  206 + this.dicOptions.AUDIT_STATUS = results.AUDIT_STATUS.data || []
  207 + this.dicOptions.SUPPLIER = results.SUPPLIER.data || []
  208 + this.dicOptions.APPLICABLE_STANDARD = results.APPLICABLE_STANDARD.data || []
  209 + }).catch(() => {
  210 + this.dicOptions = {
  211 + AUDIT_STATUS: [],
  212 + SUPPLIER: [],
  213 + APPLICABLE_STANDARD: [],
  214 + }
  215 + })
  216 + },
  217 + getDicName: getDicName,
  218 + }
  219 +}
  220 +</script>
  221 +
  222 +<style lang="scss" scoped>
  223 +.page {
  224 + display: flex;
  225 + flex-direction: column;
  226 + height: 100%;
  227 +}
  228 +
  229 +.scroll {
  230 + flex: 1;
  231 + padding: 8rpx 0 144rpx 0;
  232 +}
  233 +
  234 +.detail-page {
  235 + background: #f3f3f3;
  236 +}
  237 +
  238 +.section {
  239 + padding: 32rpx;
  240 + background: #fff;
  241 + margin-bottom: 20rpx;
  242 + position: relative;
  243 +
  244 + .status {
  245 + position: absolute;
  246 + top: 16rpx;
  247 + right: 52rpx;
  248 + width: 180rpx;
  249 + height: 146rpx;
  250 + background-repeat: no-repeat;
  251 + background-size: 100% 100%;
  252 + background-position: center;
  253 +
  254 + &_AUDIT {
  255 + background-image: url('~@/static/images/dev_manage/status_1.png');
  256 + }
  257 +
  258 + &_PASS {
  259 + background-image: url('~@/static/images/dev_manage/status_2.png');
  260 + }
  261 +
  262 + &_REFUSE {
  263 + background-image: url('~@/static/images/dev_manage/status_3.png');
  264 + }
  265 +
  266 + &_CANCEL {
  267 + background-image: url('~@/static/images/dev_manage/status_4.png');
  268 + }
  269 +
  270 + }
  271 +}
  272 +
  273 +.mgb10 {
  274 + margin-bottom: 20rpx;
  275 +}
  276 +
  277 +.row {
  278 + display: flex;
  279 + margin-bottom: 28rpx;
  280 +
  281 + &:last-child {
  282 + margin-bottom: 0;
  283 + }
  284 +
  285 + &.company {
  286 + font-size: 36rpx;
  287 + font-weight: 600;
  288 + color: rgba(0, 0, 0, 0.9);
  289 + padding-top: 32rpx;
  290 + line-height: 50rpx;
  291 + }
  292 +
  293 + .label {
  294 + max-width: 420rpx;
  295 + line-height: 32rpx;
  296 + font-size: 28rpx;
  297 + color: rgba(0, 0, 0, 0.6);
  298 + }
  299 +
  300 + .value {
  301 + flex: 1;
  302 + line-height: 32rpx;
  303 + font-size: 28rpx;
  304 + color: rgba(0, 0, 0, 0.9);
  305 + text-align: right;
  306 +
  307 + &.act {
  308 + color: $theme-primary;
  309 + }
  310 +
  311 + .category {
  312 + display: inline-block;
  313 + padding: 4rpx 12rpx;
  314 + border-radius: 6rpx;
  315 + font-size: 24rpx;
  316 + width: auto;
  317 +
  318 + &.category_A {
  319 + background: #FFF0ED;
  320 + color: #D54941;
  321 + }
  322 +
  323 + &.category_B {
  324 + background: #FFF1E9;
  325 + color: #E37318;
  326 + }
  327 +
  328 + &.category_C {
  329 + background: #F2F3FF;
  330 + color: $theme-primary;
  331 + }
  332 +
  333 + &.category_D {
  334 + background: #E3F9E9;
  335 + color: #2BA471;
  336 + }
  337 + }
  338 + }
  339 +}
  340 +
  341 +.card {
  342 + padding: 16rpx 0 8rpx;
  343 + border-top: 1rpx solid #f0f0f0;
  344 +}
  345 +
  346 +.history-header {
  347 + display: flex;
  348 + background: #F7F7F7;
  349 + padding: 20rpx 52rpx 20rpx 32rpx;
  350 +
  351 + .col {
  352 + font-size: 28rpx;
  353 + color: rgba(0, 0, 0, 0.9);
  354 + line-height: 40rpx;
  355 + }
  356 +
  357 + .col1 {
  358 + width: 20%;
  359 + }
  360 +
  361 + .col2 {
  362 + width: 50%;
  363 + text-align: center;
  364 + }
  365 +
  366 + .col3 {
  367 + width: 30%;
  368 + text-align: right;
  369 + }
  370 +}
  371 +
  372 +.history-row {
  373 + display: flex;
  374 + padding: 20rpx 52rpx 20rpx 32rpx;
  375 + border-bottom: 1rpx solid #f7f7f7;
  376 +
  377 + .col {
  378 + font-size: 28rpx;
  379 + color: rgba(0, 0, 0, 0.9);
  380 + line-height: 40rpx;
  381 + }
  382 +
  383 + .col1 {
  384 + width: 20%;
  385 + }
  386 +
  387 + .col2 {
  388 + width: 50%;
  389 + text-align: center;
  390 + }
  391 +
  392 + .col3 {
  393 + width: 30%;
  394 + text-align: right;
  395 + }
  396 +
  397 + .link {
  398 + color: $theme-primary;
  399 + }
  400 +}
  401 +
  402 +.title-header {
  403 + background-color: #fff;
  404 + display: flex;
  405 + align-items: center;
  406 + padding: 32rpx 32rpx 22rpx;
  407 + border-bottom: 1rpx dashed #f0f0f0;
  408 +
  409 + &_icon {
  410 + width: 32rpx;
  411 + height: 28rpx;
  412 + margin-right: 16rpx;
  413 + }
  414 +
  415 + span {
  416 + color: rgba(0, 0, 0, 0.9);
  417 + font-size: 32rpx;
  418 + line-height: 44rpx;
  419 + font-weight: 600;
  420 + }
  421 +}
  422 +</style>
... ...
  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.orderNo }}</view>
  9 + </template>
  10 + </uni-list-item>
  11 + <uni-list-item title="供货单位">
  12 + <template v-slot:footer>
  13 + <view class="readonly-text">{{ getDicName('SUPPLIER', form.supplyUnit, dicOptions.SUPPLIER) }}</view>
  14 + </template>
  15 + </uni-list-item>
  16 + <uni-list-item title="订货单位">
  17 + <template v-slot:footer>
  18 + <view class="readonly-text">{{ form.orderingUnitName }}</view>
  19 + </template>
  20 + </uni-list-item>
  21 + <uni-list-item title="订货日期">
  22 + <template v-slot:footer>
  23 + <view class="readonly-text">{{ form.orderDate }}</view>
  24 + </template>
  25 + </uni-list-item>
  26 + <uni-list-item title="生产厂">
  27 + <template v-slot:footer>
  28 + <view class="readonly-text">{{ form.workshopName }}</view>
  29 + </template>
  30 + </uni-list-item>
  31 + <uni-list-item title="结算方式或期限">
  32 + <template v-slot:footer>
  33 + <view class="readonly-text">{{ form.settlementTerms }}</view>
  34 + </template>
  35 + </uni-list-item>
  36 +
  37 + <uni-list-item title="交货方式">
  38 + <template v-slot:footer>
  39 + <uni-easyinput v-model="form.deliveryMethod" placeholder="请输入交货方式" :inputBorder="false" />
  40 + </template>
  41 + </uni-list-item>
  42 + </view>
  43 +
  44 + <!-- 产品 -->
  45 + <view class="section2">
  46 + <Product mode="add" :list="initPurchaseOrderLineList" @change="purchaseOrderLineListChange" />
  47 + </view>
  48 +
  49 + <view class="section">
  50 + <uni-list-item title="价格表编号">
  51 + <template v-slot:footer>
  52 + <uni-easyinput v-model="form.priceListNo" placeholder="请输入价格表编号" :inputBorder="false" />
  53 + </template>
  54 + </uni-list-item>
  55 + <uni-list-item title="开票情况">
  56 + <template v-slot:footer>
  57 + <uni-easyinput v-model="form.invoicingStatus" placeholder="请输入开票情况" :inputBorder="false" />
  58 + </template>
  59 + </uni-list-item>
  60 + <uni-list-item class="amount-item">
  61 + <template v-slot:body>
  62 + <view class="item-title"><text>运费</text></view>
  63 + </template>
  64 + <template v-slot:footer>
  65 + <view class="amount-row">
  66 + <uni-easyinput type="number" v-model="form.shippingCost" placeholder="0.00" :inputBorder="false" />
  67 + <text class="unit">元</text>
  68 + </view>
  69 + </template>
  70 + </uni-list-item>
  71 + <uni-list-item class="amount-item">
  72 + <template v-slot:body>
  73 + <view class="item-title"><text>包装费</text></view>
  74 + </template>
  75 + <template v-slot:footer>
  76 + <view class="amount-row">
  77 + <uni-easyinput type="number" v-model="form.packagingFee" placeholder="0.00" :inputBorder="false" />
  78 + <text class="unit">元</text>
  79 + </view>
  80 + </template>
  81 + </uni-list-item>
  82 + <uni-list-item class="select-item" :class="form.executionStandardName ? 'is-filled' : 'is-empty'" clickable
  83 + @click="openSheet('executionStandard')" :rightText="form.executionStandardName || '请选择'" showArrow>
  84 + <template v-slot:body>
  85 + <view class="item-title"><text>执行标准</text></view>
  86 + </template>
  87 + </uni-list-item>
  88 + </view>
  89 +
  90 +
  91 + <view class="title-header">
  92 + <image class="title-header_icon" src="/static/images/title.png" />
  93 + <span>具体质量要求</span>
  94 + </view>
  95 +
  96 + <uni-list-item title="件重条头">
  97 + <template v-slot:footer>
  98 + <uni-easyinput type="textarea" v-model="form.pieceWeightHeader" placeholder="请输入件重条头"
  99 + :inputBorder="false" />
  100 + </template>
  101 + </uni-list-item>
  102 + <uni-list-item title="表面">
  103 + <template v-slot:footer>
  104 + <uni-easyinput type="textarea" v-model="form.surface" placeholder="请输入表面" :inputBorder="false" />
  105 + </template>
  106 + </uni-list-item>
  107 + <uni-list-item title="公差">
  108 + <template v-slot:footer>
  109 + <uni-easyinput type="textarea" v-model="form.tolerance" placeholder="请输入公差" :inputBorder="false" />
  110 + </template>
  111 + </uni-list-item>
  112 + <uni-list-item title="性能">
  113 + <template v-slot:footer>
  114 + <uni-easyinput type="textarea" v-model="form.performance" placeholder="请输入性能" :inputBorder="false" />
  115 + </template>
  116 + </uni-list-item>
  117 + <uni-list-item title="成分">
  118 + <template v-slot:footer>
  119 + <uni-easyinput type="textarea" v-model="form.element" placeholder="请输入成分" :inputBorder="false" />
  120 + </template>
  121 + </uni-list-item>
  122 + <uni-list-item title="包装">
  123 + <template v-slot:footer>
  124 + <uni-easyinput type="textarea" v-model="form.packaging" placeholder="请输入包装" :inputBorder="false" />
  125 + </template>
  126 + </uni-list-item>
  127 + <uni-list-item title="备注">
  128 + <template v-slot:footer>
  129 + <uni-easyinput type="textarea" v-model="form.remarks" placeholder="请输入备注" :inputBorder="false" />
  130 + </template>
  131 + </uni-list-item>
  132 +
  133 +
  134 + </uni-list>
  135 + </scroll-view>
  136 +
  137 + <view class="footer">
  138 + <view class="view-total">
  139 + <view class="head">合计</view>
  140 + <view class="row">
  141 + <text class="label">总数量</text><text class="value">{{ form.afterTotalQuantity }}</text>
  142 + </view>
  143 + </view>
  144 + <button class="btn submit" type="primary" @click="onSubmit">提交</button>
  145 + </view>
  146 + <SingleSelectSheet :visible.sync="sheet.visible" :title="sheet.title" :options="sheet.options" v-model="sheet.value"
  147 + @confirm="onSheetConfirm" />
  148 + </view>
  149 +</template>
  150 +
  151 +<script>
  152 +import { getDetailApi, updateApi } from '@/api/change_list.js'
  153 +import Product from './product.vue'
  154 +import SingleSelectSheet from '@/components/single-select/index.vue'
  155 +import { getDicName } from '@/utils/dic.js'
  156 +import { getDicByCodes } from '@/utils/dic'
  157 +
  158 +export default {
  159 + name: 'ChangeListModify',
  160 + components: { Product, SingleSelectSheet },
  161 + data() {
  162 + return {
  163 + id: '',
  164 + form: {
  165 + orderId: '',
  166 + purchaseOrderId: '',
  167 + orderNo: '',
  168 + supplyUnit: '',
  169 + orderingUnit: '',
  170 + orderDate: new Date().toISOString().substring(0, 10),
  171 + workshopId: '',
  172 + settlementTerms: '',
  173 + deliveryMethod: '',
  174 + priceListNo: '',
  175 + invoicingStatus: '',
  176 + shippingCost: '',
  177 + packagingFee: '',
  178 + executionStandard: '',
  179 + executionStandardRemarks: '',
  180 + totalQuantity: '',
  181 + afterTotalQuantity: '',
  182 + pieceWeightHeader: '',
  183 + surface: '',
  184 + tolerance: '',
  185 + performance: '',
  186 + element: '',
  187 + packaging: '',
  188 + remarks: '',
  189 + },
  190 + initPurchaseOrderLineList: [],
  191 + dicOptions: { SUPPLIER: [], APPLICABLE_STANDARD: [] },
  192 + sheet: { visible: false, title: '请选择', options: [], value: '', field: '' }
  193 + }
  194 + },
  195 + onLoad(query) {
  196 + this.id = (query && (query.id || query.code)) || ''
  197 + if (this.id) this.loadDetail(this.id)
  198 + this.loadDicOptions()
  199 + },
  200 + methods: {
  201 + loadDicOptions() {
  202 + const dicCodes = ['SUPPLIER', 'APPLICABLE_STANDARD']
  203 + return getDicByCodes(dicCodes).then(results => {
  204 + this.dicOptions.SUPPLIER = results.SUPPLIER && results.SUPPLIER.data ? results.SUPPLIER.data : []
  205 + this.dicOptions.APPLICABLE_STANDARD = results.APPLICABLE_STANDARD && results.APPLICABLE_STANDARD.data ? results.APPLICABLE_STANDARD.data : []
  206 + this.refreshStandardName()
  207 + }).catch(() => { this.dicOptions = { SUPPLIER: [], APPLICABLE_STANDARD: [] } })
  208 + },
  209 + async loadDetail(id) {
  210 + try {
  211 + const res = await getDetailApi(id)
  212 + const m = res.data || {}
  213 + const next = { ...this.form, ...m }
  214 + next.id = m.id || m.code || id;
  215 + next.purchaseOrderId = m.orderId || '';
  216 + next.purchaseOrderLineList = Array.isArray(m.afterChangeSpecList) ? m.afterChangeSpecList.map(x => ({ ...x })) : []
  217 + this.form = next;
  218 + this.initPurchaseOrderLineList = next.purchaseOrderLineList || [];
  219 + this.refreshStandardName()
  220 + } catch (e) {
  221 + uni.showToast({ title: '加载失败', icon: 'none' })
  222 + }
  223 + },
  224 + refreshStandardName() {
  225 + const est = (this.dicOptions.APPLICABLE_STANDARD || []).find(o => String(o.code) === String(this.form.executionStandard))
  226 + this.form.executionStandardName = est ? (est.name || '') : (this.form.executionStandardName || '')
  227 + },
  228 + openSheet(field) {
  229 + if (field === 'executionStandard') {
  230 + const options = (this.dicOptions.APPLICABLE_STANDARD || []).map(it => ({ label: it.name || '', value: it.code || '' }))
  231 + const current = this.form.executionStandard
  232 + const match = options.find(o => String(o.value) === String(current))
  233 + this.sheet = { ...this.sheet, visible: true, title: '执行标准', options, field, value: match ? match.value : '' }
  234 + }
  235 + },
  236 + onSheetConfirm({ value, label }) {
  237 + const field = this.sheet.field
  238 + if (field === 'executionStandard') {
  239 + this.form.executionStandard = value || ''
  240 + this.form.executionStandardName = label || ''
  241 + }
  242 + this.sheet.visible = false
  243 + },
  244 + getDicName: getDicName,
  245 + validateLineListRequired() {
  246 + const list = Array.isArray(this.form.purchaseOrderLineList) ? this.form.purchaseOrderLineList : []
  247 + if (list.length === 0) {
  248 + uni.showToast({ title: '请先添加产品', icon: 'none' })
  249 + return false
  250 + }
  251 + const fields = [
  252 + { key: 'industry', label: '行业' },
  253 + { key: 'quality', label: '品质' },
  254 + { key: 'brand', label: '牌号' },
  255 + { key: 'quantity', label: '数量' },
  256 + { key: 'salesPrice', label: '销售价格' },
  257 + { key: 'deliveryDate', label: '发货日期' },
  258 + ]
  259 + for (let i = 0; i < list.length; i++) {
  260 + const it = list[i] || {}
  261 + for (const f of fields) {
  262 + const v = it && it[f.key]
  263 + if (v === undefined || v === null || String(v).trim() === '') {
  264 + uni.showToast({ title: `产品第${i + 1}条:${f.label}不能为空!`, icon: 'none' })
  265 + return false
  266 + }
  267 + }
  268 + }
  269 + return true
  270 + },
  271 + async onSubmit() {
  272 + if (!this.validateLineListRequired()) return
  273 + const payload = { ...this.form }
  274 + payload.orderSpecList = payload.purchaseOrderLineList || [];
  275 + delete payload.purchaseOrderLineList
  276 + console.log('onSubmit__payload', payload)
  277 + try {
  278 + await updateApi(payload)
  279 + uni.showToast({ title: '保存成功', icon: 'success' })
  280 + setTimeout(() => { uni.redirectTo({ url: '/pages/change_list/index' }) }, 300)
  281 + } catch (e) {
  282 + uni.showToast({ title: (e && e.msg) || '保存失败', icon: 'none' })
  283 + }
  284 + },
  285 + purchaseOrderLineListChange(data) {
  286 + const list = Array.isArray(data) ? data : []
  287 + this.form.purchaseOrderLineList = list
  288 + const sum = list.reduce((acc, it) => {
  289 + const v = Number(it && it.quantity)
  290 + return acc + (isNaN(v) ? 0 : v)
  291 + }, 0)
  292 + this.form.afterTotalQuantity = sum
  293 + },
  294 + }
  295 +}
  296 +</script>
  297 +
  298 +<style lang="scss" scoped>
  299 +.page {
  300 + display: flex;
  301 + flex-direction: column;
  302 + height: 100%;
  303 +}
  304 +
  305 +.scroll {
  306 + flex: 1;
  307 + padding: 6rpx 0 310rpx;
  308 +}
  309 +
  310 +
  311 +
  312 +.title-header {
  313 + background-color: #fff;
  314 + display: flex;
  315 + align-items: center;
  316 + padding: 32rpx 32rpx 22rpx;
  317 +
  318 + .title-header_icon {
  319 + width: 32rpx;
  320 + height: 28rpx;
  321 + margin-right: 16rpx;
  322 + }
  323 +
  324 + span {
  325 + color: rgba(0, 0, 0, 0.9);
  326 + font-size: 32rpx;
  327 + line-height: 44rpx;
  328 + font-weight: 600;
  329 + }
  330 +}
  331 +
  332 +
  333 +.section {
  334 + background: #fff;
  335 + margin-bottom: 20rpx;
  336 +}
  337 +
  338 +.section2 {
  339 + background: #f1f1f1;
  340 +}
  341 +
  342 +::v-deep .uni-list {
  343 + background: transparent;
  344 +
  345 + &-item {
  346 + &__extra-text {
  347 + font-size: 32rpx;
  348 + }
  349 +
  350 + &__content-title {
  351 + font-size: 32rpx;
  352 + color: rgba(0, 0, 0, 0.9);
  353 + }
  354 +
  355 + &__container {
  356 + padding: 32rpx;
  357 + // align-items: center;
  358 +
  359 + .uni-easyinput {
  360 +
  361 + .is-disabled {
  362 + background-color: transparent !important;
  363 + }
  364 +
  365 + &__placeholder-class {
  366 + font-size: 32rpx;
  367 + color: rgba(0, 0, 0, 0.4);
  368 + }
  369 +
  370 + &__content {
  371 + border: none;
  372 +
  373 + &-input {
  374 + padding-left: 0 !important;
  375 + height: 48rpx;
  376 + line-height: 48rpx;
  377 + font-size: 32rpx;
  378 + }
  379 +
  380 + .content-clear-icon {
  381 + font-size: 44rpx !important;
  382 + }
  383 + }
  384 + }
  385 +
  386 + .amount-row {
  387 + flex: 1;
  388 + display: flex;
  389 + align-items: center;
  390 +
  391 + .uni-easyinput {
  392 + flex: 1;
  393 + }
  394 +
  395 + .unit {
  396 + margin-left: 16rpx;
  397 + color: rgba(0, 0, 0, 0.9);
  398 + }
  399 + }
  400 +
  401 + .item-title,
  402 + .uni-list-item__content {
  403 + flex: none;
  404 + min-height: 48rpx;
  405 + line-height: 48rpx;
  406 + font-size: 32rpx;
  407 + position: relative;
  408 + width: 162rpx;
  409 + margin-right: 32rpx;
  410 + color: rgba(0, 0, 0, 0.9);
  411 + padding-right: 0;
  412 +
  413 +
  414 + .required {
  415 + color: red;
  416 + position: absolute;
  417 + top: 50%;
  418 + transform: translateY(-50%);
  419 + left: -16rpx;
  420 + }
  421 + }
  422 +
  423 + }
  424 +
  425 + &.select-item {
  426 + &.is-empty {
  427 + .uni-list-item__extra-text {
  428 + color: rgba(0, 0, 0, 0.4) !important;
  429 + }
  430 + }
  431 +
  432 + &.is-filled {
  433 + .uni-list-item__extra-text {
  434 + color: rgba(0, 0, 0, 0.9) !important;
  435 + }
  436 + }
  437 +
  438 + .serial-number-row {
  439 + display: flex;
  440 + align-items: center;
  441 + }
  442 +
  443 + }
  444 +
  445 + &.mgb10 {
  446 + margin-bottom: 20rpx;
  447 + }
  448 +
  449 + }
  450 +
  451 + .title-header {
  452 + background-color: #fff;
  453 + display: flex;
  454 + align-items: center;
  455 + padding: 32rpx 32rpx 22rpx;
  456 +
  457 + &_icon {
  458 + width: 32rpx;
  459 + height: 28rpx;
  460 + margin-right: 16rpx;
  461 + }
  462 +
  463 + span {
  464 + color: rgba(0, 0, 0, 0.9);
  465 + font-size: 32rpx;
  466 + line-height: 44rpx;
  467 + font-weight: 600;
  468 + }
  469 + }
  470 +}
  471 +
  472 +/* 只读 easyinput 根据内容自适应高度 */
  473 +::v-deep .uni-list-item__container {
  474 + align-items: flex-start;
  475 +}
  476 +
  477 +/* 只读文本样式 */
  478 +.readonly-text {
  479 + color: rgba(0, 0, 0, 0.9);
  480 + font-size: 32rpx;
  481 + line-height: 44rpx;
  482 + text-align: right;
  483 + white-space: pre-wrap;
  484 + word-break: break-all;
  485 +}
  486 +
  487 +
  488 +.footer {
  489 + position: fixed;
  490 + left: 0;
  491 + right: 0;
  492 + bottom: 0;
  493 + padding: 0 32rpx 32rpx;
  494 + padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
  495 + background: #fff;
  496 + box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.06);
  497 +
  498 + .btn {
  499 + height: 80rpx;
  500 + line-height: 80rpx;
  501 + border-radius: 12rpx;
  502 + font-size: 32rpx;
  503 + }
  504 +
  505 + .submit {
  506 + background: $theme-primary;
  507 + color: #fff;
  508 + }
  509 +
  510 + .view-total {
  511 + padding: 20rpx 0;
  512 +
  513 + .head {
  514 + font-size: 32rpx;
  515 + font-weight: 600;
  516 + line-height: 50rpx;
  517 + color: rgba(0, 0, 0, 0.9);
  518 + padding-bottom: 16rpx;
  519 + margin-bottom: 24rpx;
  520 + ;
  521 + border-bottom: 1px dashed #E7E7E7;
  522 + }
  523 +
  524 + .row {
  525 + display: flex;
  526 + margin-bottom: 24rpx;
  527 + line-height: 32rpx;
  528 +
  529 + .label {
  530 + width: 180rpx;
  531 + margin-right: 14rpx;
  532 + color: rgba(0, 0, 0, 0.6);
  533 + font-size: 28rpx;
  534 + }
  535 +
  536 + .value {
  537 + flex: 1;
  538 + color: rgba(0, 0, 0, 0.9);
  539 + font-size: 28rpx;
  540 + white-space: pre-wrap;
  541 + word-break: break-all;
  542 + }
  543 + }
  544 + }
  545 +}
  546 +</style>
... ...
  1 +<template>
  2 + <view class="product" :class="{ 'history': mode == 'history' }">
  3 +
  4 + <!-- 新增&详情-产品 -->
  5 + <view class="header bp">
  6 + <image class="opCollapse" src="/static/images/title.png" />
  7 + <text class="title">产品</text>
  8 + <view class="ops">
  9 + <view v-if="mode === 'view'" class="op1" @click="toggleViewCollapse">
  10 + <image class="opAdd" :src="collapsedView ? '/static/images/down.png' : '/static/images/up.png'" />
  11 + <text class="op">{{ collapsedView ? '展开' : '收起' }} </text>
  12 + </view>
  13 +
  14 + </view>
  15 + </view>
  16 +
  17 + <view v-if="mode === 'add'" class="section">
  18 + <view v-for="(item, idx) in items" :key="'a-' + idx" class="block">
  19 + <view class="row"><text class="label">行业</text><text class="value">{{ item.industry }}</text></view>
  20 + <view class="row"><text class="label">品质</text><text class="value">{{ item.quality }}</text></view>
  21 + <view class="row"><text class="label">牌号</text><text class="value">{{ item.brand }}</text></view>
  22 +
  23 + <view v-show="!item.collapsed">
  24 + <!-- 厚(公差) * 宽(公差) * 长(公差) -->
  25 + <view class="row row-spec"><text class="label">规格(mm)</text>
  26 + <view class="value value-spec">
  27 + <view v-if="item.thickness" class="value-spec_val">{{ item.thickness }}</view>
  28 + <view v-if="item.thickness" class="value-spec_box">
  29 + <view v-if="item.thicknessTolPos" class="value-spec_box_1">+{{ item.thicknessTolPos }}
  30 + </view>
  31 + <view v-if="item.thicknessTolNeg" class="value-spec_box_2">-{{ item.thicknessTolNeg }}
  32 + </view>
  33 + </view>
  34 + <view v-if="item.width" class="value-spec_val p12">*</view>
  35 + <view v-if="item.width" class="value-spec_val">{{ item.width }}</view>
  36 + <view v-if="item.width" class="value-spec_box">
  37 + <view v-if="item.widthTolPos" class="value-spec_box_1">+{{ item.widthTolPos }}</view>
  38 + <view v-if="item.widthTolNeg" class="value-spec_box_2">-{{ item.widthTolNeg }}</view>
  39 + </view>
  40 + <view v-if="item.length" class="value-spec_val p12">*</view>
  41 + <view v-if="item.length" class="value-spec_val">{{ item.length }}</view>
  42 + <view v-if="item.length" class="value-spec_box">
  43 + <view v-if="item.lengthTolPos" class="value-spec_box_1">+{{ item.lengthTolPos }}</view>
  44 + <view v-if="item.lengthTolNeg" class="value-spec_box_2">-{{ item.lengthTolNeg }}</view>
  45 + </view>
  46 + </view>
  47 + </view>
  48 + <view class="row"><text class="label">状态</text><text class="value">{{ item.status }}</text></view>
  49 + <view class="row" :class="{ 'noneStyle': !item.showSalesPrice }"><text
  50 + class="label">数量kg</text><text class="value">{{ item.quantity }}</text>
  51 + </view>
  52 + <view class="row" :class="{ 'noneStyle': item.showSalesPrice }" v-if="item.showSalesPrice"><text
  53 + class="label">销售价格</text><text class="value">{{
  54 + item.salesPrice }}</text></view>
  55 +
  56 + <uni-list class="edit-list">
  57 + <uni-list-item title="发货日期">
  58 + <template v-slot:footer>
  59 + <uni-datetime-picker type="date" v-model="item.deliveryDate" />
  60 + </template>
  61 + </uni-list-item>
  62 + <uni-list-item title="考核超协">
  63 + <template v-slot:footer>
  64 + <uni-easyinput v-model="item.assessmentExceedsAgreement" placeholder="请输入考核超协"
  65 + :inputBorder="false" />
  66 + </template>
  67 + </uni-list-item>
  68 + </uni-list>
  69 + </view>
  70 +
  71 + <view class="block-ops">
  72 + <div class="toggle" @click="toggleItem(idx)">
  73 + <image :src="item.collapsed ? '/static/images/up.png' : '/static/images/down.png'"
  74 + class="icon" />
  75 + {{ item.collapsed ? '展开' : '收起' }}
  76 + </div>
  77 + </view>
  78 + </view>
  79 + </view>
  80 +
  81 + <view v-else-if="mode === 'view'" class="view-list" v-show="!collapsedView">
  82 + <view v-for="(item, idx) in items" :key="'v-' + idx" class="card">
  83 + <view class="row"><text class="label">行业</text><text class="value">{{ item.industry }}</text></view>
  84 + <view class="row"><text class="label">品质</text><text class="value">{{ item.quality }}</text></view>
  85 + <view class="row"><text class="label">牌号</text><text class="value">{{ item.brand }}</text></view>
  86 + <!-- 厚(公差) * 宽(公差) * 长(公差) -->
  87 + <view class="row row-spec"><text class="label">规格(mm)</text>
  88 + <view class="value value-spec">
  89 + <view v-if="item.thickness" class="value-spec_val">{{ item.thickness }}</view>
  90 + <view v-if="item.thickness" class="value-spec_box">
  91 + <view v-if="item.thicknessTolPos" class="value-spec_box_1">+{{ item.thicknessTolPos }}
  92 + </view>
  93 + <view v-if="item.thicknessTolNeg" class="value-spec_box_2">-{{ item.thicknessTolNeg }}
  94 + </view>
  95 + </view>
  96 + <view v-if="item.width" class="value-spec_val p12">*</view>
  97 + <view v-if="item.width" class="value-spec_val">{{ item.width }}</view>
  98 + <view v-if="item.width" class="value-spec_box">
  99 + <view v-if="item.widthTolPos" class="value-spec_box_1">+{{ item.widthTolPos }}</view>
  100 + <view v-if="item.widthTolNeg" class="value-spec_box_2">-{{ item.widthTolNeg }}</view>
  101 + </view>
  102 + <view v-if="item.length" class="value-spec_val p12">*</view>
  103 + <view v-if="item.length" class="value-spec_val">{{ item.length }}</view>
  104 + <view v-if="item.length" class="value-spec_box">
  105 + <view v-if="item.lengthTolPos" class="value-spec_box_1">+{{ item.lengthTolPos }}</view>
  106 + <view v-if="item.lengthTolNeg" class="value-spec_box_2">-{{ item.lengthTolNeg }}</view>
  107 + </view>
  108 + </view>
  109 + </view>
  110 + <view class="row"><text class="label">状态</text><text class="value">{{ item.status }}</text></view>
  111 + <view class="row"><text class="label">数量kg</text><text class="value">{{ item.quantity }}</text></view>
  112 + <!-- showSalesPrice 判断是否显示 -->
  113 + <view class="row" v-if="item.showSalesPrice"><text class="label">销售价格</text><text class="value">{{
  114 + item.salesPrice }}</text></view>
  115 + <view class="row"><text class="label">发货日期</text><text class="value">{{ item.deliveryDate }}</text>
  116 + </view>
  117 + <view class="row"><text class="label">考核超协</text><text class="value">{{ item.assessmentExceedsAgreement
  118 + }}</text></view>
  119 + </view>
  120 + <view class="view-total">
  121 + <view class="head">合计</view>
  122 + <view class="row">
  123 + <text class="label">总数量</text><text class="value">{{ totalQuantity }}</text>
  124 + </view>
  125 + </view>
  126 + </view>
  127 +
  128 + </view>
  129 +</template>
  130 +<script>
  131 +import { uuid } from '@/utils/uuid.js'
  132 +export default {
  133 + name: 'Product',
  134 + props: {
  135 + title: { type: String, default: '' },
  136 + mode: { type: String, default: 'add' },
  137 + list: { type: Array, default: () => [] },
  138 + max: { type: Number, default: 8 },
  139 + options: { type: Array, default: () => [] },
  140 + totalQuantity: { type: Number, default: 0 }
  141 + },
  142 + data() {
  143 + return {
  144 + items: [],
  145 + collapsedView: false,
  146 + sheet: { visible: false, title: '请选择性别', options: [], value: '', idx: -1 }
  147 + }
  148 + },
  149 + computed: {
  150 + selectOptions() {
  151 + const list = Array.isArray(this.options) ? this.options : []
  152 + return list.map(o => ({
  153 + label: o.label != null ? o.label : (o.text != null ? o.text : (o.name != null ? o.name : '')),
  154 + value: o.value != null ? o.value : (o.code != null ? o.code : (o.id != null ? o.id : o.productId))
  155 + }))
  156 + }
  157 + },
  158 + watch: {
  159 + items: {
  160 + handler() { this.emitChange() },
  161 + deep: true
  162 + },
  163 + list: {
  164 + handler(v) {
  165 + const arr = Array.isArray(v) ? v : []
  166 + const opts = this.selectOptions
  167 + this.items = arr.map(x => {
  168 + const it = { ...this.defaultItem(), ...x, collapsed: true }
  169 + const m = opts.find(o => String(o.value) === String(it.sex))
  170 + it.sexName = m ? (m.label || '') : it.sexName
  171 + return it
  172 + })
  173 + },
  174 + deep: true
  175 + },
  176 + options: {
  177 + handler() { this.refreshSexNames() }
  178 + }
  179 + },
  180 + created() {
  181 + const init = Array.isArray(this.list) && this.list.length > 0 ? this.list.map(v => ({ ...this.defaultItem(), ...v, collapsed: false })) : [{ ...this.defaultItem(), collapsed: false }]
  182 + this.items = init
  183 + },
  184 + methods: {
  185 + defaultItem() {
  186 + return { personId: uuid(), name: '', sex: '', sexName: '', nativePlace: '', age: '', position: '', mobile: '', phone: '', email: '', address: '', collapsed: false }
  187 + },
  188 + getSexName(item) {
  189 + const opts = this.selectOptions
  190 + const v = item && item.sex
  191 + const m = opts.find(o => String(o.value) === String(v))
  192 + return m ? (m.label || '') : ((item && item.sexName) || '')
  193 + },
  194 + refreshSexNames() {
  195 + const opts = this.selectOptions
  196 + this.items = (this.items || []).map(it => {
  197 + const m = opts.find(o => String(o.value) === String(it.sex))
  198 + return { ...it, sexName: m ? (m.label || '') : it.sexName }
  199 + })
  200 + },
  201 + toggleItem(idx) {
  202 + const it = this.items[idx]
  203 + if (!it) return
  204 + it.collapsed = !it.collapsed
  205 + this.$set(this.items, idx, it)
  206 + },
  207 + emitChange() {
  208 + const out = this.items.map(it => ({ ...it }))
  209 + this.$emit('input', out)
  210 + this.$emit('update:value', out)
  211 + this.$emit('change', out)
  212 + },
  213 + toggleViewCollapse() {
  214 + this.collapsedView = !this.collapsedView
  215 + }
  216 + }
  217 +}
  218 +</script>
  219 +<style lang="scss" scoped>
  220 +.header {
  221 + background-color: #fff;
  222 + display: flex;
  223 + align-items: center;
  224 + padding: 24rpx 32rpx;
  225 +
  226 + &.bp {
  227 + border-bottom: 1px solid #f0f0f0;
  228 + }
  229 +}
  230 +
  231 +.dot {
  232 + width: 16rpx;
  233 + height: 16rpx;
  234 + background: #3D48A3;
  235 + border-radius: 50%;
  236 + margin-right: 12rpx;
  237 +}
  238 +
  239 +.title {
  240 + font-size: 32rpx;
  241 + color: rgba(0, 0, 0, 0.9);
  242 + font-weight: 600;
  243 +}
  244 +
  245 +.ops {
  246 + margin-left: auto;
  247 +}
  248 +
  249 +.op {
  250 + color: $theme-primary;
  251 + font-size: 28rpx;
  252 + margin-left: 8rpx;
  253 +}
  254 +
  255 +.op1 {
  256 + display: flex;
  257 + align-items: center;
  258 +}
  259 +
  260 +.opAdd {
  261 + color: rgba(0, 0, 0, 0.6);
  262 + width: 40rpx;
  263 + height: 40rpx;
  264 +}
  265 +
  266 +.opCollapse {
  267 + color: rgba(0, 0, 0, 0.6);
  268 + width: 32rpx;
  269 + height: 28rpx;
  270 + margin-right: 16rpx;
  271 +}
  272 +
  273 +
  274 +::v-deep .uni-list {
  275 + background: transparent;
  276 +
  277 + &-item {
  278 + &__extra-text {
  279 + font-size: 32rpx;
  280 + }
  281 +
  282 + &__content-title {
  283 + font-size: 32rpx;
  284 + color: rgba(0, 0, 0, 0.9);
  285 + }
  286 +
  287 + &__container {
  288 + padding: 32rpx;
  289 +
  290 + .uni-easyinput {
  291 +
  292 + .is-disabled {
  293 + background-color: transparent !important;
  294 + }
  295 +
  296 + &__placeholder-class {
  297 + font-size: 32rpx;
  298 + color: rgba(0, 0, 0, 0.4);
  299 + }
  300 +
  301 + &__content {
  302 + border: none;
  303 +
  304 + &-input {
  305 + padding-left: 0 !important;
  306 + height: 48rpx;
  307 + line-height: 48rpx;
  308 + font-size: 32rpx;
  309 + }
  310 +
  311 + .content-clear-icon {
  312 + font-size: 44rpx !important;
  313 + }
  314 + }
  315 + }
  316 +
  317 + .amount-row {
  318 + flex: 1;
  319 + display: flex;
  320 + align-items: center;
  321 +
  322 + .uni-easyinput {
  323 + flex: 1;
  324 + }
  325 +
  326 + .unit {
  327 + margin-left: 16rpx;
  328 + color: rgba(0, 0, 0, 0.9);
  329 + }
  330 + }
  331 +
  332 + .item-title,
  333 + .uni-list-item__content {
  334 + flex: none;
  335 + min-height: 48rpx;
  336 + line-height: 48rpx;
  337 + font-size: 32rpx;
  338 + position: relative;
  339 + width: 162rpx;
  340 + margin-right: 32rpx;
  341 + color: rgba(0, 0, 0, 0.9);
  342 + padding-right: 0;
  343 +
  344 +
  345 + .required {
  346 + color: red;
  347 + position: absolute;
  348 + top: 50%;
  349 + transform: translateY(-50%);
  350 + left: -16rpx;
  351 + }
  352 + }
  353 +
  354 + }
  355 +
  356 + &.select-item {
  357 + &.is-empty {
  358 + .uni-list-item__extra-text {
  359 + color: rgba(0, 0, 0, 0.4) !important;
  360 + }
  361 + }
  362 +
  363 + &.is-filled {
  364 + .uni-list-item__extra-text {
  365 + color: rgba(0, 0, 0, 0.9) !important;
  366 + }
  367 + }
  368 +
  369 + .serial-number-row {
  370 + display: flex;
  371 + align-items: center;
  372 + }
  373 +
  374 + }
  375 +
  376 + &.mgb10 {
  377 + margin-bottom: 20rpx;
  378 + }
  379 +
  380 + }
  381 +
  382 + .title-header {
  383 + background-color: #fff;
  384 + display: flex;
  385 + align-items: center;
  386 + padding: 32rpx 32rpx 22rpx;
  387 +
  388 + &_icon {
  389 + width: 32rpx;
  390 + height: 28rpx;
  391 + margin-right: 16rpx;
  392 + }
  393 +
  394 + span {
  395 + color: rgba(0, 0, 0, 0.9);
  396 + font-size: 32rpx;
  397 + line-height: 44rpx;
  398 + font-weight: 600;
  399 + }
  400 + }
  401 +}
  402 +
  403 +/* 只读 easyinput 根据内容自适应高度 */
  404 +::v-deep .uni-list-item__container {
  405 + align-items: flex-start;
  406 +}
  407 +
  408 +.block-ops {
  409 + display: flex;
  410 + padding: 20rpx 32rpx 20rpx;
  411 + justify-content: space-around;
  412 +}
  413 +
  414 +.del {
  415 + color: #D54941;
  416 + font-size: 28rpx;
  417 + display: flex;
  418 + align-items: center;
  419 +
  420 + image {
  421 + width: 40rpx;
  422 + height: 40rpx;
  423 + }
  424 +}
  425 +
  426 +.toggle {
  427 + color: $theme-primary;
  428 + font-size: 28rpx;
  429 + display: flex;
  430 + align-items: center;
  431 +
  432 + image {
  433 + width: 40rpx;
  434 + height: 40rpx;
  435 + }
  436 +}
  437 +
  438 +.section {
  439 + background: #f1f1f1;
  440 + margin-bottom: 20rpx;
  441 +
  442 + .block {
  443 + background: #ffffff;
  444 + padding: 32rpx 0;
  445 + margin-bottom: 20rpx;
  446 +
  447 + &:last-child {
  448 + margin-bottom: 0;
  449 + }
  450 + }
  451 +
  452 + .row {
  453 + display: flex;
  454 + // margin-bottom: 24rpx;
  455 + line-height: 32rpx;
  456 + padding: 32rpx;
  457 + border-bottom: 1rpx solid #f2f2f2;
  458 +
  459 +
  460 + &.noneStyle {
  461 + border-bottom: 0;
  462 + border-bottom: none;
  463 + }
  464 +
  465 + &.row-spec {
  466 + align-items: center;
  467 + }
  468 + }
  469 +
  470 + .row:last-child {
  471 + margin-bottom: 0;
  472 + }
  473 +
  474 + .label {
  475 + width: 162rpx;
  476 + margin-right: 32rpx;
  477 + color: rgba(0, 0, 0, 0.9);
  478 + font-size: 32rpx;
  479 + line-height: 48rpx;
  480 + }
  481 +
  482 + .value {
  483 + flex: 1;
  484 + color: rgba(0, 0, 0, 0.9);
  485 + font-size: 32rpx;
  486 + white-space: pre-wrap;
  487 + word-break: break-all;
  488 + line-height: 48rpx;
  489 + }
  490 +
  491 + .value-spec {
  492 + height: 48rpx;
  493 + display: flex;
  494 + align-items: center;
  495 + color: #000000;
  496 +
  497 + &_box {
  498 + position: relative;
  499 + width: 60rpx;
  500 + height: 48rpx;
  501 +
  502 + &_1 {
  503 + font-size: 16rpx;
  504 + position: absolute;
  505 + top: -10rpx;
  506 + left: 0;
  507 + }
  508 +
  509 + &_2 {
  510 + font-size: 16rpx;
  511 + position: absolute;
  512 + bottom: -10rpx;
  513 + left: 0;
  514 + }
  515 + }
  516 +
  517 + &_val {
  518 + font-size: 28rpx;
  519 +
  520 + &.p12 {
  521 + padding-right: 12rpx;
  522 + }
  523 + }
  524 + }
  525 +
  526 + .view-total {
  527 + padding-top: 20rpx;
  528 +
  529 + .head {
  530 + font-size: 32rpx;
  531 + font-weight: 600;
  532 + line-height: 50rpx;
  533 + color: rgba(0, 0, 0, 0.9);
  534 + padding-bottom: 16rpx;
  535 + margin-bottom: 24rpx;
  536 + ;
  537 + border-bottom: 1px dashed #E7E7E7;
  538 + }
  539 +
  540 + .row {
  541 + display: flex;
  542 + margin-bottom: 24rpx;
  543 + line-height: 32rpx;
  544 +
  545 + .label {
  546 + width: 180rpx;
  547 + margin-right: 14rpx;
  548 + color: rgba(0, 0, 0, 0.6);
  549 + font-size: 28rpx;
  550 + }
  551 +
  552 + .value {
  553 + flex: 1;
  554 + color: rgba(0, 0, 0, 0.9);
  555 + font-size: 28rpx;
  556 + white-space: pre-wrap;
  557 + word-break: break-all;
  558 + }
  559 + }
  560 + }
  561 +}
  562 +
  563 +.view-list {
  564 + padding: 26rpx 32rpx;
  565 + background: #ffffff;
  566 +
  567 + .card {
  568 + background: #f3f3f3;
  569 + border-radius: 16rpx;
  570 + padding: 32rpx 44rpx;
  571 + margin-bottom: 20rpx;
  572 +
  573 + &:last-child {
  574 + margin-bottom: 0;
  575 + }
  576 + }
  577 +
  578 + .row {
  579 + display: flex;
  580 + margin-bottom: 24rpx;
  581 + line-height: 32rpx;
  582 +
  583 + &.row-spec {
  584 + height: 60rpx;
  585 + align-items: center;
  586 + }
  587 + }
  588 +
  589 + .row:last-child {
  590 + margin-bottom: 0;
  591 + }
  592 +
  593 + .label {
  594 + width: 140rpx;
  595 + margin-right: 14rpx;
  596 + color: rgba(0, 0, 0, 0.6);
  597 + font-size: 28rpx;
  598 + }
  599 +
  600 + .value {
  601 + flex: 1;
  602 + color: rgba(0, 0, 0, 0.9);
  603 + font-size: 28rpx;
  604 + white-space: pre-wrap;
  605 + word-break: break-all;
  606 + }
  607 +
  608 + .value-spec {
  609 + height: 60rpx;
  610 + display: flex;
  611 + align-items: center;
  612 + color: #000000;
  613 +
  614 + &_box {
  615 + position: relative;
  616 + width: 60rpx;
  617 + height: 60rpx;
  618 +
  619 + &_1 {
  620 + font-size: 16rpx;
  621 + position: absolute;
  622 + top: 0;
  623 + left: 0;
  624 + }
  625 +
  626 + &_2 {
  627 + font-size: 16rpx;
  628 + position: absolute;
  629 + bottom: 0;
  630 + left: 0;
  631 + }
  632 + }
  633 +
  634 + &_val {
  635 + font-size: 28rpx;
  636 +
  637 + &.p12 {
  638 + padding-right: 12rpx;
  639 + }
  640 + }
  641 + }
  642 +
  643 + .view-total {
  644 + padding-top: 20rpx;
  645 +
  646 + .head {
  647 + font-size: 32rpx;
  648 + font-weight: 600;
  649 + line-height: 50rpx;
  650 + color: rgba(0, 0, 0, 0.9);
  651 + padding-bottom: 16rpx;
  652 + margin-bottom: 24rpx;
  653 + ;
  654 + border-bottom: 1px dashed #E7E7E7;
  655 + }
  656 +
  657 + .row {
  658 + display: flex;
  659 + margin-bottom: 24rpx;
  660 + line-height: 32rpx;
  661 +
  662 + .label {
  663 + width: 180rpx;
  664 + margin-right: 14rpx;
  665 + color: rgba(0, 0, 0, 0.6);
  666 + font-size: 28rpx;
  667 + }
  668 +
  669 + .value {
  670 + flex: 1;
  671 + color: rgba(0, 0, 0, 0.9);
  672 + font-size: 28rpx;
  673 + white-space: pre-wrap;
  674 + word-break: break-all;
  675 + }
  676 + }
  677 + }
  678 +}
  679 +</style>
... ...
  1 +<template>
  2 + <view class="detail-page">
  3 + <view class="section">
  4 + <text class="row company">{{ form.orderNo }}</text>
  5 + <view class="row"><text class="label">供货单位</text><text class="value">{{ getDicName('SUPPLIER',
  6 + form.supplyUnit, dicOptions.SUPPLIER) }}</text></view>
  7 + <view class="row"><text class="label">订货单位</text><text class="value">{{ form.orderingUnitName }}</text>
  8 + </view>
  9 + <view class="row"><text class="label">订货日期</text><text class="value">{{ form.orderDate }}</text></view>
  10 + <view class="row"><text class="label">生产厂</text><text class="value">{{ form.workshopName }}</text></view>
  11 + <view class="row"><text class="label">结算方式或期限</text><text class="value">{{ form.settlementTerms }}</text>
  12 + </view>
  13 + <view class="row"><text class="label">交货方式</text><text class="value">{{ form.deliveryMethod }}</text></view>
  14 + </view>
  15 +
  16 + <!-- 产品-变更前 -->
  17 + <view class="mgb10">
  18 + <Product title="变更前" mode="view" :options="genderOptions" :list="form.beforeChangeSpecList"
  19 + :totalQuantity="form.totalQuantity || 0" />
  20 + </view>
  21 +
  22 + <!-- 产品-变更后 -->
  23 + <view class="mgb10">
  24 + <Product title="变更后" mode="view" :options="genderOptions" :list="form.afterChangeSpecList"
  25 + :totalQuantity="form.afterTotalQuantity || 0" />
  26 + </view>
  27 +
  28 + <view class="section">
  29 + <view class="row"><text class="label">价格表编号</text><text class="value">{{ form.priceListNo }}</text></view>
  30 + <view class="row"><text class="label">开票情况</text><text class="value">{{ form.invoicingStatus }}</text></view>
  31 + <view class="row"><text class="label">运费</text><text class="value">{{ form.shippingCost }}</text></view>
  32 + <view class="row"><text class="label">包装费</text><text class="value">{{ form.packagingFee }}</text></view>
  33 + <view class="row"><text class="label">执行标准</text><text class="value">{{ getDicName('APPLICABLE_STANDARD',
  34 + form.executionStandard, dicOptions.APPLICABLE_STANDARD) }}</text></view>
  35 + </view>
  36 +
  37 + <view class="title-header">
  38 + <image class="title-header_icon" src="/static/images/title.png" />
  39 + <span>具体质量要求</span>
  40 + </view>
  41 + <view class="section">
  42 + <view class="row"><text class="label">件重条头</text><text class="value">{{ form.pieceWeightHeader }}</text>
  43 + </view>
  44 + <view class="row"><text class="label">表面</text><text class="value">{{ form.surface }}</text></view>
  45 + <view class="row"><text class="label">公差</text><text class="value">{{ form.tolerance }}</text></view>
  46 + <view class="row"><text class="label">性能</text><text class="value">{{ form.performance }}</text></view>
  47 + <view class="row"><text class="label">成分</text><text class="value">{{ form.element }}</text></view>
  48 + <view class="row"><text class="label">包装</text><text class="value">{{ form.packaging }}</text></view>
  49 + <view class="row"><text class="label">备注</text><text class="value">{{ form.remarks }}</text></view>
  50 + </view>
  51 +
  52 + </view>
  53 +</template>
  54 +
  55 +<script>
  56 +import { getDetailApi } from '@/api/change_list.js'
  57 +import Product from './product.vue'
  58 +import {
  59 + getDicName
  60 +} from '@/utils/dic.js'
  61 +import {
  62 + getDicByCodes
  63 +} from '@/utils/dic'
  64 +
  65 +export default {
  66 + name: 'ChangeListViewer',
  67 + components: { Product },
  68 + props: { id: { type: [String, Number], default: '' } },
  69 + data() {
  70 + return {
  71 + form: {},
  72 + enterpriseTypeOptions: [],
  73 + genderOptions: [],
  74 + categoryOptions: [],
  75 + historyList: [],
  76 + dicOptions: {
  77 + AUDIT_STATUS: [],
  78 + SUPPLIER: [],
  79 + APPLICABLE_STANDARD: [],
  80 + },
  81 + }
  82 + },
  83 + watch: {
  84 + id: {
  85 + immediate: true,
  86 + handler(val) {
  87 + const v = (val !== undefined && val !== null) ? String(val) : ''
  88 + if (v) this.loadDetail(v)
  89 + }
  90 + }
  91 + },
  92 + created() {
  93 + this.loadAllDicData()
  94 + },
  95 + methods: {
  96 + async loadDetail(id) {
  97 + try {
  98 + const res = await getDetailApi(id)
  99 + const data = res.data || {}
  100 + this.form = { ...data }
  101 + } catch (e) {
  102 + this.form = {}
  103 + }
  104 + },
  105 + loadAllDicData() {
  106 + const dicCodes = ['AUDIT_STATUS', 'SUPPLIER', 'APPLICABLE_STANDARD']
  107 + return getDicByCodes(dicCodes).then(results => {
  108 + this.dicOptions.AUDIT_STATUS = results.AUDIT_STATUS.data || []
  109 + this.dicOptions.SUPPLIER = results.SUPPLIER.data || []
  110 + this.dicOptions.APPLICABLE_STANDARD = results.APPLICABLE_STANDARD.data || []
  111 + }).catch(() => {
  112 + this.dicOptions = {
  113 + AUDIT_STATUS: [],
  114 + SUPPLIER: [],
  115 + APPLICABLE_STANDARD: [],
  116 + }
  117 + })
  118 + },
  119 + getDicName: getDicName,
  120 + getFormValues() {
  121 + const m = this.form || {}
  122 + return JSON.parse(JSON.stringify(m))
  123 + }
  124 + }
  125 +}
  126 +</script>
  127 +
  128 +<style lang="scss" scoped>
  129 +.detail-page {
  130 + background: #f3f3f3;
  131 +}
  132 +
  133 +.section {
  134 + padding: 32rpx;
  135 + background: #fff;
  136 + margin-bottom: 20rpx;
  137 + position: relative;
  138 +
  139 +}
  140 +
  141 +.mgb10 {
  142 + margin-bottom: 20rpx;
  143 +}
  144 +
  145 +.row {
  146 + display: flex;
  147 + margin-bottom: 28rpx;
  148 +
  149 + &:last-child {
  150 + margin-bottom: 0;
  151 + }
  152 +
  153 + &.company {
  154 + font-size: 36rpx;
  155 + font-weight: 600;
  156 + color: rgba(0, 0, 0, 0.9);
  157 + padding-top: 32rpx;
  158 + line-height: 50rpx;
  159 + }
  160 +
  161 + .label {
  162 + max-width: 420rpx;
  163 + line-height: 32rpx;
  164 + font-size: 28rpx;
  165 + color: rgba(0, 0, 0, 0.6);
  166 + }
  167 +
  168 + .value {
  169 + flex: 1;
  170 + line-height: 32rpx;
  171 + font-size: 28rpx;
  172 + color: rgba(0, 0, 0, 0.9);
  173 + text-align: right;
  174 +
  175 + &.act {
  176 + color: $theme-primary;
  177 + }
  178 +
  179 + .category {
  180 + display: inline-block;
  181 + padding: 4rpx 12rpx;
  182 + border-radius: 6rpx;
  183 + font-size: 24rpx;
  184 + width: auto;
  185 +
  186 + &.category_A {
  187 + background: #FFF0ED;
  188 + color: #D54941;
  189 + }
  190 +
  191 + &.category_B {
  192 + background: #FFF1E9;
  193 + color: #E37318;
  194 + }
  195 +
  196 + &.category_C {
  197 + background: #F2F3FF;
  198 + color: $theme-primary;
  199 + }
  200 +
  201 + &.category_D {
  202 + background: #E3F9E9;
  203 + color: #2BA471;
  204 + }
  205 + }
  206 + }
  207 +}
  208 +
  209 +.card {
  210 + padding: 16rpx 0 8rpx;
  211 + border-top: 1rpx solid #f0f0f0;
  212 +}
  213 +
  214 +.history-header {
  215 + display: flex;
  216 + background: #F7F7F7;
  217 + padding: 20rpx 52rpx 20rpx 32rpx;
  218 +
  219 + .col {
  220 + font-size: 28rpx;
  221 + color: rgba(0, 0, 0, 0.9);
  222 + line-height: 40rpx;
  223 + }
  224 +
  225 + .col1 {
  226 + width: 20%;
  227 + }
  228 +
  229 + .col2 {
  230 + width: 50%;
  231 + text-align: center;
  232 + }
  233 +
  234 + .col3 {
  235 + width: 30%;
  236 + text-align: right;
  237 + }
  238 +}
  239 +
  240 +.history-row {
  241 + display: flex;
  242 + padding: 20rpx 52rpx 20rpx 32rpx;
  243 + border-bottom: 1rpx solid #f7f7f7;
  244 +
  245 + .col {
  246 + font-size: 28rpx;
  247 + color: rgba(0, 0, 0, 0.9);
  248 + line-height: 40rpx;
  249 + }
  250 +
  251 + .col1 {
  252 + width: 20%;
  253 + }
  254 +
  255 + .col2 {
  256 + width: 50%;
  257 + text-align: center;
  258 + }
  259 +
  260 + .col3 {
  261 + width: 30%;
  262 + text-align: right;
  263 + }
  264 +
  265 + .link {
  266 + color: $theme-primary;
  267 + }
  268 +}
  269 +
  270 +.title-header {
  271 + background-color: #fff;
  272 + display: flex;
  273 + align-items: center;
  274 + padding: 32rpx 32rpx 22rpx;
  275 + border-bottom: 1rpx dashed #f0f0f0;
  276 +
  277 + &_icon {
  278 + width: 32rpx;
  279 + height: 28rpx;
  280 + margin-right: 16rpx;
  281 + }
  282 +
  283 + span {
  284 + color: rgba(0, 0, 0, 0.9);
  285 + font-size: 32rpx;
  286 + line-height: 44rpx;
  287 + font-weight: 600;
  288 + }
  289 +}
  290 +</style>
... ...