Commit d46e60e310721ca30417a619e304315ebdb0cf34

Authored by 史婷婷
1 parent 8317df12

feat: 订货单详情-暂存

... ... @@ -164,6 +164,13 @@
164 164 "navigationBarBackgroundColor": "#ffffff",
165 165 "navigationBarTextStyle": "black"
166 166 }
  167 + },{
  168 + "path": "pages/order_list/detail",
  169 + "style": {
  170 + "navigationBarTitleText": "查看订货单",
  171 + "navigationBarBackgroundColor": "#ffffff",
  172 + "navigationBarTextStyle": "black"
  173 + }
167 174 },
168 175 {
169 176 "path": "pages/revoke_list/index",
... ...
  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.status}`]" />
  8 + <view class="row"><text class="label">审核状态</text><text class="value act">{{ getDicName('AUDIT_STATUS',
  9 + form.examineStatus, dicOptions.AUDIT_STATUS) }}</text></view>
  10 + <view class="row"><text class="label">供货单位</text><text class="value">{{ getDicName('SUPPLIER',
  11 + form.supplyUnit, dicOptions.SUPPLIER) }}</text></view>
  12 + <view class="row"><text class="label">订货单位</text><text class="value">{{ form.orderingUnitName }}</text>
  13 + </view>
  14 + <view class="row"><text class="label">订货日期</text><text class="value">{{ form.orderDate }}</text></view>
  15 + <view class="row"><text class="label">生产厂</text><text class="value">{{ form.workshopName }}</text></view>
  16 + <view class="row"><text class="label">结算方式或期限</text><text class="value">{{ form.settlementTerms }}</text></view>
  17 + <view class="row"><text class="label">交货方式</text><text class="value">{{ form.deliveryMethod }}</text></view>
  18 + </view>
  19 +
  20 + <!-- 产品 -->
  21 + <view class="mgb10">
  22 + <Product mode="view" :options="genderOptions" :list="form.purchaseOrderLineList" :totalQuantity="form.totalQuantity || '-'" />
  23 + </view>
  24 +
  25 + <view class="section">
  26 + <view class="row"><text class="label">价格表编号</text><text class="value">{{ form.priceListNo }}</text></view>
  27 + <view class="row"><text class="label">开票情况</text><text class="value">{{ form.invoicingStatus }}</text></view>
  28 + <view class="row"><text class="label">运费</text><text class="value">{{ form.shippingCost }}</text></view>
  29 + <view class="row"><text class="label">包装费</text><text class="value">{{ form.packagingFee }}</text></view>
  30 + <view class="row"><text class="label">执行标准</text><text class="value">{{ getDicName('APPLICABLE_STANDARD',
  31 + form.executionStandard, dicOptions.APPLICABLE_STANDARD) }}</text></view>
  32 + </view>
  33 +
  34 + <view class="title-header">
  35 + <image class="title-header_icon" src="/static/images/title.png" />
  36 + <span>具体质量要求</span>
  37 + </view>
  38 + <view class="section">
  39 + <view class="row"><text class="label">件重条头</text><text class="value">{{ form.pieceWeightHeader }}</text></view>
  40 + <view class="row"><text class="label">表面</text><text class="value">{{ form.surface }}</text></view>
  41 + <view class="row"><text class="label">公差</text><text class="value">{{ form.tolerance }}</text></view>
  42 + <view class="row"><text class="label">性能</text><text class="value">{{ form.performance }}</text></view>
  43 + <view class="row"><text class="label">成分</text><text class="value">{{ form.element }}</text></view>
  44 + <view class="row"><text class="label">包装</text><text class="value">{{ form.packaging }}</text></view>
  45 + <view class="row"><text class="label">备注</text><text class="value">{{ form.remarks }}</text></view>
  46 + </view>
  47 +
  48 + </view>
  49 + </scroll-view>
  50 + <detail-buttons :buttons="displayButtons" @click="handleButtonClick" />
  51 + </view>
  52 +</template>
  53 +
  54 +<script>
  55 +import { getDetailApi, cancelApi } from '@/api/order_list.js'
  56 +import Product from './product.vue'
  57 +import DetailButtons from '@/components/detail-buttons/index.vue'
  58 +import {
  59 + getDicName
  60 +} from '@/utils/dic.js'
  61 +import {
  62 + getDicByCodes
  63 +} from '@/utils/dic'
  64 +
  65 +export default {
  66 + name: 'OrderListDetail',
  67 + components: { Product, DetailButtons },
  68 + data() {
  69 + return {
  70 + form: {},
  71 + enterpriseTypeOptions: [],
  72 + genderOptions: [],
  73 + categoryOptions: [],
  74 + historyList: [],
  75 + showExamine: false,
  76 + buttons: [
  77 + { text: '编辑', visible: true, variant: 'outline', event: 'edit' },
  78 + { text: '审核详情', visible: true, variant: 'outline', event: 'auditDetail' },
  79 + { text: '审核', visible: true, variant: 'primary', event: 'audit' },
  80 + { text: '申请变更', visible: true, variant: 'outline', event: 'changeApply' },
  81 + { text: '取消', visible: true, variant: 'outline', event: 'cancel', style: { color: 'rgba(0,0,0,0.9)', border: '1px solid #DCDCDC' } },
  82 + ],
  83 + dicOptions: {
  84 + AUDIT_STATUS: [],
  85 + SUPPLIER: [],
  86 + APPLICABLE_STANDARD: [],
  87 + },
  88 + }
  89 + },
  90 + computed: {
  91 + statusFlags() {
  92 + const s = String((this.form && this.form.status) || '')
  93 + return {
  94 + isRefuse: s === 'REFUSE',
  95 + isPass: s === 'PASS',
  96 + isAudit: s === 'AUDIT',
  97 + canExamine: !!this.showExamine,
  98 + }
  99 + },
  100 + displayButtons() {
  101 + const f = this.statusFlags
  102 + return [
  103 + { ...this.buttons[0], visible: f.isRefuse },
  104 + { ...this.buttons[1], visible: true },
  105 + { ...this.buttons[2], visible: f.isAudit && f.canExamine },
  106 + { ...this.buttons[3], visible: f.isPass },
  107 + { ...this.buttons[4], visible: f.isRefuse },
  108 + ]
  109 + }
  110 + },
  111 + created() {
  112 + this.loadAllDicData()
  113 + },
  114 + onLoad(query) {
  115 + const id = (query && (query.id || query.code)) || ''
  116 + const se = (query && (query.todoType === 'WAIT' || query.showExamine === '1' || query.showExamine === true)) || false
  117 + this.showExamine = !!se
  118 + if (id) this.loadDetail(id)
  119 + },
  120 + methods: {
  121 + async loadDetail(id) {
  122 + try {
  123 + const res = await getDetailApi(id)
  124 + const data = res.data || {}
  125 + this.form = { ...data }
  126 + } catch (e) {
  127 + this.form = {}
  128 + }
  129 + },
  130 + onViewHistory(item) {
  131 + const id = item && (item.id)
  132 + if (!id) return
  133 + const query = '?id=' + encodeURIComponent(id)
  134 + uni.navigateTo({ url: '/pages/credit_manage/history_detail' + query })
  135 + },
  136 + handleButtonClick(btn) {
  137 + if (!btn || btn.disabled) return
  138 + const map = {
  139 + edit: () => this.onEdit(),
  140 + auditDetail: () => this.onAuditDetail(),
  141 + audit: () => this.onAudit(),
  142 + changeApply: () => this.onChangeApply(),
  143 + cancel: () => this.onCancel(),
  144 + }
  145 + const fn = map[btn.event]
  146 + if (typeof fn === 'function') fn()
  147 + },
  148 + getBusinessId() {
  149 + return (this.form && (this.form.id || this.form.code)) || ''
  150 + },
  151 + onEdit() {
  152 + const id = this.getBusinessId()
  153 + const query = id ? ('?id=' + encodeURIComponent(id)) : ''
  154 + uni.navigateTo({ url: '/pages/credit_manage/modify' + query })
  155 + },
  156 + onAuditDetail() {
  157 + const CACHE_KEY = 'sourceBusinessId'
  158 + uni.setStorageSync(CACHE_KEY, this.getBusinessId())
  159 + uni.navigateTo({ url: '/pages/flow/audit_detail' })
  160 + },
  161 + onAudit() {
  162 + const CACHE_KEY = 'sourceBusinessId'
  163 + uni.setStorageSync(CACHE_KEY, this.getBusinessId())
  164 + uni.navigateTo({ url: '/pages/flow/audit' })
  165 + },
  166 + onChangeApply() {
  167 + const id = this.getBusinessId()
  168 + const query = id ? ('?id=' + encodeURIComponent(id)) : ''
  169 + uni.navigateTo({ url: '/pages/credit_manage/change' + query })
  170 + },
  171 + onCancel() {
  172 + const id = this.getBusinessId()
  173 + if (!id) return
  174 + uni.showModal({
  175 + title: '系统提示',
  176 + content: '是否确定取消该流程?',
  177 + confirmText: '确定',
  178 + cancelText: '取消',
  179 + success: (res) => {
  180 + if (res && res.confirm) {
  181 + cancelApi(id).then(() => {
  182 + uni.showToast({ title: '已取消', icon: 'none' })
  183 + setTimeout(() => { uni.redirectTo({ url: '/pages/credit_manage/index' }) }, 300)
  184 + }).catch(() => {
  185 + uni.showToast({ title: '取消失败', icon: 'none' })
  186 + })
  187 + }
  188 + }
  189 + })
  190 + },
  191 + getCategoryClass(categoryName) {
  192 + if (!categoryName) return ''
  193 + if (categoryName.includes('A') || categoryName.includes('a')) {
  194 + return 'category_A'
  195 + } else if (categoryName.includes('B') || categoryName.includes('b')) {
  196 + return 'category_B'
  197 + } else if (categoryName.includes('C') || categoryName.includes('c')) {
  198 + return 'category_C'
  199 + } else if (categoryName.includes('D') || categoryName.includes('d')) {
  200 + return 'category_D'
  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 + // 已下发
  255 + &_ISSUED {
  256 + background-image: url('~@/static/images/order_list/status_ISSUED.png');
  257 + }
  258 +
  259 + // 待发货
  260 + &_WAIT {
  261 + background-image: url('~@/static/images/order_list/status_WAIT.png');
  262 + }
  263 +
  264 + // 部分发货
  265 + &_TRANSIT {
  266 + background-image: url('~@/static/images/order_list/status_TRANSIT.png');
  267 + }
  268 +
  269 + // 发货完成
  270 + &_SHIPPED {
  271 + background-image: url('~@/static/images/order_list/status_SHIPPED.png');
  272 + }
  273 +
  274 + // 已签收
  275 + &_DELIVERED {
  276 + background-image: url('~@/static/images/order_list/status_DELIVERED.png');
  277 + }
  278 +
  279 + }
  280 +}
  281 +
  282 +.mgb10 {
  283 + margin-bottom: 20rpx;
  284 +}
  285 +
  286 +.row {
  287 + display: flex;
  288 + margin-bottom: 28rpx;
  289 +
  290 + &:last-child {
  291 + margin-bottom: 0;
  292 + }
  293 +
  294 + &.company {
  295 + font-size: 36rpx;
  296 + font-weight: 600;
  297 + color: rgba(0, 0, 0, 0.9);
  298 + padding-top: 32rpx;
  299 + line-height: 50rpx;
  300 + }
  301 +
  302 + .label {
  303 + max-width: 420rpx;
  304 + line-height: 32rpx;
  305 + font-size: 28rpx;
  306 + color: rgba(0, 0, 0, 0.6);
  307 + }
  308 +
  309 + .value {
  310 + flex: 1;
  311 + line-height: 32rpx;
  312 + font-size: 28rpx;
  313 + color: rgba(0, 0, 0, 0.9);
  314 + text-align: right;
  315 +
  316 + &.act {
  317 + color: $theme-primary;
  318 + }
  319 +
  320 + .category {
  321 + display: inline-block;
  322 + padding: 4rpx 12rpx;
  323 + border-radius: 6rpx;
  324 + font-size: 24rpx;
  325 + width: auto;
  326 +
  327 + &.category_A {
  328 + background: #FFF0ED;
  329 + color: #D54941;
  330 + }
  331 +
  332 + &.category_B {
  333 + background: #FFF1E9;
  334 + color: #E37318;
  335 + }
  336 +
  337 + &.category_C {
  338 + background: #F2F3FF;
  339 + color: $theme-primary;
  340 + }
  341 +
  342 + &.category_D {
  343 + background: #E3F9E9;
  344 + color: #2BA471;
  345 + }
  346 + }
  347 + }
  348 +}
  349 +
  350 +.card {
  351 + padding: 16rpx 0 8rpx;
  352 + border-top: 1rpx solid #f0f0f0;
  353 +}
  354 +
  355 +.history-header {
  356 + display: flex;
  357 + background: #F7F7F7;
  358 + padding: 20rpx 52rpx 20rpx 32rpx;
  359 +
  360 + .col {
  361 + font-size: 28rpx;
  362 + color: rgba(0, 0, 0, 0.9);
  363 + line-height: 40rpx;
  364 + }
  365 +
  366 + .col1 {
  367 + width: 20%;
  368 + }
  369 +
  370 + .col2 {
  371 + width: 50%;
  372 + text-align: center;
  373 + }
  374 +
  375 + .col3 {
  376 + width: 30%;
  377 + text-align: right;
  378 + }
  379 +}
  380 +
  381 +.history-row {
  382 + display: flex;
  383 + padding: 20rpx 52rpx 20rpx 32rpx;
  384 + border-bottom: 1rpx solid #f7f7f7;
  385 +
  386 + .col {
  387 + font-size: 28rpx;
  388 + color: rgba(0, 0, 0, 0.9);
  389 + line-height: 40rpx;
  390 + }
  391 +
  392 + .col1 {
  393 + width: 20%;
  394 + }
  395 +
  396 + .col2 {
  397 + width: 50%;
  398 + text-align: center;
  399 + }
  400 +
  401 + .col3 {
  402 + width: 30%;
  403 + text-align: right;
  404 + }
  405 +
  406 + .link {
  407 + color: $theme-primary;
  408 + }
  409 +}
  410 +
  411 +.title-header {
  412 + background-color: #fff;
  413 + display: flex;
  414 + align-items: center;
  415 + padding: 32rpx 32rpx 22rpx;
  416 + border-bottom: 1rpx dashed #f0f0f0;
  417 +
  418 + &_icon {
  419 + width: 32rpx;
  420 + height: 28rpx;
  421 + margin-right: 16rpx;
  422 + }
  423 +
  424 + span {
  425 + color: rgba(0, 0, 0, 0.9);
  426 + font-size: 32rpx;
  427 + line-height: 44rpx;
  428 + font-weight: 600;
  429 + }
  430 +}
  431 +</style>
\ No newline at end of file
... ...
... ... @@ -19,11 +19,11 @@
19 19 <CardList ref="cardRef" :fetchFn="fetchList" :query="query" :extra="extraParams" :enable-refresh="true"
20 20 :enable-load-more="true" row-key="id" @loaded="onLoaded" @error="onError">
21 21 <template v-slot="{ item }">
22   - <view class="card">
  22 + <view class="card" @click.stop="onCardClick(item)">
23 23 <view class="card-header">
24 24 <text class="title omit2">{{ item.orderingUnitName }}</text>
25 25 <text v-if="item.status" :class="['status', `status_${item.status}`]">{{ filterStatus(item.status)
26   - }}</text>
  26 + }}</text>
27 27 </view>
28 28 <view class="info-row"><text>订单编号</text><text>{{ item.orderNo }}</text></view>
29 29 <view class="info-row"><text>生产厂</text><text>{{ item.workshopName }}</text></view>
... ... @@ -218,6 +218,14 @@ export default {
218 218 filterStatus(status) {
219 219 return this.statusOptions.filter(item => item.value === status)[0].text || '';
220 220 },
  221 + onCardClick(item) {
  222 + const id = (item && (item.id || item.code)) || ''
  223 + if (!id) return
  224 + const query = '?id=' + encodeURIComponent(id)
  225 + uni.navigateTo({
  226 + url: '/pages/order_list/detail' + query
  227 + })
  228 + },
221 229 }
222 230 }
223 231 </script>
... ...
  1 +<template>
  2 + <view class="core-personnel" :class="{ 'history': mode == 'history' }">
  3 +
  4 + <!-- 新增&详情-产品 -->
  5 + <view class="header" :class="{ 'bp': mode !== 'add' }">
  6 + <image class="opCollapse" src="/static/images/title.png" />
  7 + <text class="title">产品</text>
  8 + <view class="ops">
  9 + <image v-if="mode === 'add'" class="opAdd" @click="onAdd" src="/static/images/plus.png" />
  10 + <view v-if="mode === 'view'" class="op1" @click="toggleViewCollapse">
  11 + <image class="opAdd" :src="collapsedView ? '/static/images/down.png' : '/static/images/up.png'" />
  12 + <text class="op">{{ collapsedView ? '展开' : '收起' }} </text>
  13 + </view>
  14 +
  15 + </view>
  16 + </view>
  17 +
  18 + <view v-if="mode === 'add'" class="add-list">
  19 + <view v-for="(item, idx) in items" :key="idx" class="block">
  20 + <uni-list v-show="item.collapsed">
  21 + <uni-list-item title="姓名">
  22 + <template v-slot:footer>
  23 + <uni-easyinput v-model="item.name" :inputBorder="false" placeholder="请输入姓名" />
  24 + </template>
  25 + </uni-list-item>
  26 + <uni-list-item class="select-item" :class="item.sexName ? 'is-filled' : 'is-empty'" clickable
  27 + @click="openProductSheet(idx)" :rightText="item.sexName || '请选择性别'" showArrow>
  28 + <template v-slot:body>
  29 + <view class="item-title"><text>性别</text></view>
  30 + </template>
  31 + </uni-list-item>
  32 + </uni-list>
  33 + <uni-list v-show="!item.collapsed">
  34 + <uni-list-item title="姓名">
  35 + <template v-slot:footer>
  36 + <uni-easyinput v-model="item.name" :inputBorder="false" placeholder="请输入姓名" />
  37 + </template>
  38 + </uni-list-item>
  39 + <uni-list-item class="select-item" :class="item.sexName ? 'is-filled' : 'is-empty'" clickable
  40 + @click="openProductSheet(idx)" :rightText="item.sexName || '请选择性别'" showArrow>
  41 + <template v-slot:body>
  42 + <view class="item-title"><text>性别</text></view>
  43 + </template>
  44 + </uni-list-item>
  45 + <uni-list-item title="籍贯">
  46 + <template v-slot:footer>
  47 + <uni-easyinput v-model="item.nativePlace" :inputBorder="false" placeholder="请输入籍贯" />
  48 + </template>
  49 + </uni-list-item>
  50 + <uni-list-item title="年龄">
  51 + <template v-slot:footer>
  52 + <uni-easyinput v-model="item.age" :inputBorder="false" placeholder="请输入年龄" />
  53 + </template>
  54 + </uni-list-item>
  55 + <uni-list-item title="职务">
  56 + <template v-slot:footer>
  57 + <uni-easyinput v-model="item.position" :inputBorder="false" placeholder="请输入职务" />
  58 + </template>
  59 + </uni-list-item>
  60 + <uni-list-item title="手机">
  61 + <template v-slot:footer>
  62 + <uni-easyinput v-model="item.mobile" :inputBorder="false" placeholder="请输入手机" />
  63 + </template>
  64 + </uni-list-item>
  65 + <uni-list-item title="固定电话">
  66 + <template v-slot:footer>
  67 + <uni-easyinput v-model="item.phone" :inputBorder="false" placeholder="请输入固定电话" />
  68 + </template>
  69 + </uni-list-item>
  70 + <uni-list-item title="邮箱地址">
  71 + <template v-slot:footer>
  72 + <uni-easyinput v-model="item.email" :inputBorder="false" placeholder="请输入邮箱地址" />
  73 + </template>
  74 + </uni-list-item>
  75 + <uni-list-item title="现住址">
  76 + <template v-slot:footer>
  77 + <uni-easyinput v-model="item.address" :inputBorder="false" placeholder="请输入现住址" />
  78 + </template>
  79 + </uni-list-item>
  80 + </uni-list>
  81 + <view class="block-ops">
  82 + <div class="del" @click="onRemove(item.personId)">
  83 + <image src="/static/images/delete.png" class="icon" />
  84 + 删除
  85 + </div>
  86 + <div class="toggle" @click="toggleItem(idx)">
  87 + <image :src="item.collapsed ? '/static/images/up.png' : '/static/images/down.png'"
  88 + class="icon" />
  89 + {{ item.collapsed ? '展开' : '收起' }}
  90 + </div>
  91 + </view>
  92 + </view>
  93 + </view>
  94 +
  95 + <view v-else-if="mode === 'view'" class="view-list" v-show="!collapsedView">
  96 + <view v-for="(item, idx) in items" :key="'v-' + idx" class="card">
  97 + <view class="row"><text class="label">行业</text><text class="value">{{ item.industry }}</text></view>
  98 + <view class="row"><text class="label">品质</text><text class="value">{{ item.quality }}</text></view>
  99 + <view class="row"><text class="label">牌号</text><text class="value">{{ item.brand }}</text></view>
  100 + <!-- 厚(公差) * 宽(公差) * 长(公差) -->
  101 + <view class="row row-spec"><text class="label">规格</text>
  102 + <view class="value value-spec">
  103 + <view class="value-spec_val">{{ item.thickness }}</view>
  104 + <view class="value-spec_box">
  105 + <view class="value-spec_box_1">+{{ item.thicknessTolPos }}</view>
  106 + <view class="value-spec_box_2">-{{ item.thicknessTolNeg }}</view>
  107 + </view>
  108 + <view class="value-spec_val p12">*</view>
  109 + <view class="value-spec_val">{{ item.width }}</view>
  110 + <view class="value-spec_box">
  111 + <view class="value-spec_box_1">+{{ item.widthTolPos }}</view>
  112 + <view class="value-spec_box_2">-{{ item.widthTolNeg }}</view>
  113 + </view>
  114 + <view class="value-spec_val p12">*</view>
  115 + <view class="value-spec_val">{{ item.length }}</view>
  116 + <view class="value-spec_box">
  117 + <view class="value-spec_box_1">+{{ item.lengthTolPos }}</view>
  118 + <view class="value-spec_box_2">-{{ item.lengthTolNeg }}</view>
  119 + </view>
  120 + </view>
  121 + </view>
  122 + <view class="row"><text class="label">状态</text><text class="value">{{ item.status }}</text></view>
  123 + <view class="row"><text class="label">数量kg</text><text class="value">{{ item.quantity }}</text></view>
  124 + <!-- showSalesPrice 判断是否显示 -->
  125 + <view class="row" v-if="item.showSalesPrice"><text class="label">销售价格</text><text class="value">{{
  126 + item.salesPrice }}</text></view>
  127 + <view class="row"><text class="label">发货日期</text><text class="value">{{ item.deliveryDate }}</text>
  128 + </view>
  129 + <view class="row"><text class="label">考核超协</text><text class="value">{{ item.assessmentExceedsAgreement
  130 + }}</text></view>
  131 + </view>
  132 + <view class="view-total">
  133 + <view class="head">合计</view>
  134 + <view class="row">
  135 + <text class="label">总数量</text><text class="value">{{ totalQuantity }}</text>
  136 + </view>
  137 + </view>
  138 + </view>
  139 +
  140 + </view>
  141 +</template>
  142 +<script>
  143 +import { uuid } from '@/utils/uuid.js'
  144 +export default {
  145 + name: 'Product',
  146 + props: {
  147 + title: { type: String, default: '' },
  148 + mode: { type: String, default: 'add' },
  149 + list: { type: Array, default: () => [] },
  150 + max: { type: Number, default: 8 },
  151 + options: { type: Array, default: () => [] },
  152 + totalQuantity: { type: String, default: '' }
  153 + },
  154 + data() {
  155 + return {
  156 + items: [],
  157 + collapsedView: false,
  158 + sheet: { visible: false, title: '请选择性别', options: [], value: '', idx: -1 }
  159 + }
  160 + },
  161 + computed: {
  162 + selectOptions() {
  163 + const list = Array.isArray(this.options) ? this.options : []
  164 + return list.map(o => ({
  165 + label: o.label != null ? o.label : (o.text != null ? o.text : (o.name != null ? o.name : '')),
  166 + value: o.value != null ? o.value : (o.code != null ? o.code : (o.id != null ? o.id : o.productId))
  167 + }))
  168 + }
  169 + },
  170 + watch: {
  171 + items: {
  172 + handler() { this.emitChange() },
  173 + deep: true
  174 + },
  175 + list: {
  176 + handler(v) {
  177 + const arr = Array.isArray(v) ? v : []
  178 + const opts = this.selectOptions
  179 + this.items = arr.map(x => {
  180 + const it = { ...this.defaultItem(), ...x, collapsed: true }
  181 + const m = opts.find(o => String(o.value) === String(it.sex))
  182 + it.sexName = m ? (m.label || '') : it.sexName
  183 + return it
  184 + })
  185 + },
  186 + deep: true
  187 + },
  188 + options: {
  189 + handler() { this.refreshSexNames() }
  190 + }
  191 + },
  192 + created() {
  193 + const init = Array.isArray(this.list) && this.list.length > 0 ? this.list.map(v => ({ ...this.defaultItem(), ...v, collapsed: false })) : [{ ...this.defaultItem(), collapsed: false }]
  194 + this.items = init
  195 + },
  196 + methods: {
  197 + defaultItem() {
  198 + return { personId: uuid(), name: '', sex: '', sexName: '', nativePlace: '', age: '', position: '', mobile: '', phone: '', email: '', address: '', collapsed: false }
  199 + },
  200 + getSexName(item) {
  201 + const opts = this.selectOptions
  202 + const v = item && item.sex
  203 + const m = opts.find(o => String(o.value) === String(v))
  204 + return m ? (m.label || '') : ((item && item.sexName) || '')
  205 + },
  206 + refreshSexNames() {
  207 + const opts = this.selectOptions
  208 + this.items = (this.items || []).map(it => {
  209 + const m = opts.find(o => String(o.value) === String(it.sex))
  210 + return { ...it, sexName: m ? (m.label || '') : it.sexName }
  211 + })
  212 + },
  213 + openProductSheet(idx) {
  214 + const opts = this.selectOptions
  215 + const current = this.items[idx] && this.items[idx].sex
  216 + const match = opts.find(o => o.value === current)
  217 + this.sheet = { ...this.sheet, visible: true, title: '请选择性别', options: opts, idx, value: match ? match.value : '' }
  218 + },
  219 + onProductConfirm({ value, label }) {
  220 + const idx = this.sheet.idx
  221 + const it = this.items[idx]
  222 + if (!it) { this.sheet.visible = false; return }
  223 + it.sex = value
  224 + it.sexName = label || ''
  225 + this.$set(this.items, idx, it)
  226 + this.sheet.visible = false
  227 + this.emitChange()
  228 + },
  229 + onAdd() {
  230 + if (this.items.length >= this.max) return uni.showToast({ title: `最多添加${this.max}个`, icon: 'none' })
  231 + const obj = this.defaultItem()
  232 + obj.collapsed = true
  233 + this.items.push(obj)
  234 + this.emitChange()
  235 + },
  236 + onRemove(id) {
  237 + if (!id) return
  238 + uni.showModal({
  239 + title: '系统提示',
  240 + content: '是否确定删除选中的产品?',
  241 + confirmText: '确定',
  242 + cancelText: '取消',
  243 + success: (res) => {
  244 + if (res && res.confirm) {
  245 + const i = this.items.findIndex(it => String(it.personId) === String(id))
  246 + if (i >= 0) {
  247 + this.items.splice(i, 1)
  248 + this.emitChange()
  249 + }
  250 + }
  251 + }
  252 + })
  253 + },
  254 + toggleItem(idx) {
  255 + const it = this.items[idx]
  256 + if (!it) return
  257 + it.collapsed = !it.collapsed
  258 + this.$set(this.items, idx, it)
  259 + },
  260 + emitChange() {
  261 + const out = this.items.map(it => ({ ...it }))
  262 + this.$emit('input', out)
  263 + this.$emit('update:value', out)
  264 + this.$emit('change', out)
  265 + },
  266 + toggleViewCollapse() {
  267 + this.collapsedView = !this.collapsedView
  268 + }
  269 + }
  270 +}
  271 +</script>
  272 +<style lang="scss" scoped>
  273 +.core-personnel {
  274 + margin-top: 10px;
  275 +
  276 + &.history {
  277 + margin-top: 0;
  278 +
  279 + .header {
  280 + padding: 32rpx 0 0 32rpx;
  281 + }
  282 + }
  283 +}
  284 +
  285 +.header {
  286 + background-color: #fff;
  287 + display: flex;
  288 + align-items: center;
  289 + padding: 24rpx 32rpx;
  290 +
  291 + &.bp {
  292 + border-bottom: 1rpx dashed #f0f0f0;
  293 + }
  294 +}
  295 +
  296 +.dot {
  297 + width: 16rpx;
  298 + height: 16rpx;
  299 + background: #3D48A3;
  300 + border-radius: 50%;
  301 + margin-right: 12rpx;
  302 +}
  303 +
  304 +.title {
  305 + font-size: 32rpx;
  306 + color: rgba(0, 0, 0, 0.9);
  307 + font-weight: 600;
  308 +}
  309 +
  310 +.ops {
  311 + margin-left: auto;
  312 +}
  313 +
  314 +.op {
  315 + color: $theme-primary;
  316 + font-size: 28rpx;
  317 + margin-left: 8rpx;
  318 +}
  319 +
  320 +.op1 {
  321 + display: flex;
  322 + align-items: center;
  323 +}
  324 +
  325 +.opAdd {
  326 + color: rgba(0, 0, 0, 0.6);
  327 + width: 40rpx;
  328 + height: 40rpx;
  329 +}
  330 +
  331 +.opCollapse {
  332 + color: rgba(0, 0, 0, 0.6);
  333 + width: 32rpx;
  334 + height: 28rpx;
  335 + margin-right: 16rpx;
  336 +}
  337 +
  338 +
  339 +.block {
  340 + background: #fff;
  341 + margin-bottom: 20rpx;
  342 +}
  343 +
  344 +::v-deep .uni-list-item__content {
  345 + display: flex;
  346 + justify-content: center;
  347 +}
  348 +
  349 +::v-deep .uni-list {
  350 + background: transparent;
  351 +
  352 + &-item {
  353 + &__container {
  354 + padding: 32rpx;
  355 + }
  356 +
  357 + &__content-title {
  358 + font-size: 28rpx;
  359 + color: rgba(0, 0, 0, 0.9);
  360 + }
  361 +
  362 + &__extra-text {
  363 + font-size: 32rpx;
  364 + }
  365 +
  366 + .uni-easyinput {
  367 + width: 100%;
  368 +
  369 + &__placeholder-class {
  370 + font-size: 32rpx;
  371 + color: rgba(0, 0, 0, 0.4);
  372 + }
  373 +
  374 + &__content {
  375 + border: none;
  376 + display: flex;
  377 +
  378 + &-input {
  379 + padding-left: 0 !important;
  380 + height: 48rpx;
  381 + line-height: 48rpx;
  382 + font-size: 32rpx;
  383 + }
  384 + }
  385 +
  386 + .uni-input-placeholder {
  387 + // z-index: 2;
  388 + }
  389 + }
  390 + }
  391 +}
  392 +
  393 +.block-ops {
  394 + display: flex;
  395 + padding: 20rpx 32rpx 20rpx;
  396 + justify-content: space-around;
  397 +}
  398 +
  399 +.del {
  400 + color: #D54941;
  401 + font-size: 28rpx;
  402 + display: flex;
  403 + align-items: center;
  404 +
  405 + image {
  406 + width: 40rpx;
  407 + height: 40rpx;
  408 + }
  409 +}
  410 +
  411 +.toggle {
  412 + color: $theme-primary;
  413 + font-size: 28rpx;
  414 + display: flex;
  415 + align-items: center;
  416 +
  417 + image {
  418 + width: 40rpx;
  419 + height: 40rpx;
  420 + }
  421 +}
  422 +
  423 +.view-list {
  424 + padding: 26rpx 32rpx;
  425 + background: #ffffff;
  426 +
  427 + .card {
  428 + background: #f3f3f3;
  429 + border-radius: 16rpx;
  430 + padding: 32rpx 44rpx;
  431 + margin-bottom: 20rpx;
  432 +
  433 + &:last-child {
  434 + margin-bottom: 0;
  435 + }
  436 + }
  437 +
  438 + .row {
  439 + display: flex;
  440 + margin-bottom: 24rpx;
  441 + line-height: 32rpx;
  442 +
  443 + &.row-spec {
  444 + height: 60rpx;
  445 + align-items: center;
  446 + }
  447 + }
  448 +
  449 + .row:last-child {
  450 + margin-bottom: 0;
  451 + }
  452 +
  453 + .label {
  454 + width: 180rpx;
  455 + margin-right: 14rpx;
  456 + color: rgba(0, 0, 0, 0.6);
  457 + font-size: 28rpx;
  458 + }
  459 +
  460 + .value {
  461 + flex: 1;
  462 + color: rgba(0, 0, 0, 0.9);
  463 + font-size: 28rpx;
  464 + white-space: pre-wrap;
  465 + word-break: break-all;
  466 + }
  467 +
  468 + .value-spec {
  469 + height: 60rpx;
  470 + display: flex;
  471 + align-items: center;
  472 + color: #000000;
  473 +
  474 + &_box {
  475 + position: relative;
  476 + width: 60rpx;
  477 + height: 60rpx;
  478 +
  479 + &_1 {
  480 + font-size: 16rpx;
  481 + position: absolute;
  482 + top: 0;
  483 + left: 0;
  484 + }
  485 +
  486 + &_2 {
  487 + font-size: 16rpx;
  488 + position: absolute;
  489 + bottom: 0;
  490 + left: 0;
  491 + }
  492 + }
  493 +
  494 + &_val {
  495 + font-size: 28rpx;
  496 +
  497 + &.p12 {
  498 + padding-right: 12rpx;
  499 + }
  500 + }
  501 + }
  502 +
  503 + .view-total {
  504 + padding-top: 20rpx;
  505 +
  506 + .head {
  507 + font-size: 32rpx;
  508 + font-weight: 600;
  509 + line-height: 50rpx;
  510 + color: rgba(0, 0, 0, 0.9);
  511 + padding-bottom: 16rpx;
  512 + margin-bottom: 24rpx;
  513 + ;
  514 + border-bottom: 1px dashed #E7E7E7;
  515 + }
  516 +
  517 + .row {
  518 + display: flex;
  519 + margin-bottom: 24rpx;
  520 + line-height: 32rpx;
  521 +
  522 + .label {
  523 + width: 180rpx;
  524 + margin-right: 14rpx;
  525 + color: rgba(0, 0, 0, 0.6);
  526 + font-size: 28rpx;
  527 + }
  528 +
  529 + .value {
  530 + flex: 1;
  531 + color: rgba(0, 0, 0, 0.9);
  532 + font-size: 28rpx;
  533 + white-space: pre-wrap;
  534 + word-break: break-all;
  535 + }
  536 + }
  537 + }
  538 +}
  539 +
  540 +.history-list {
  541 + padding: 20rpx 32rpx;
  542 + background: #ffffff;
  543 +
  544 + .card {
  545 + background: #f3f3f3;
  546 + border-radius: 16rpx;
  547 + padding: 32rpx 44rpx;
  548 + margin-bottom: 20rpx;
  549 +
  550 + &:last-child {
  551 + margin-bottom: 0;
  552 + }
  553 + }
  554 +
  555 + .row {
  556 + display: flex;
  557 + margin-bottom: 24rpx;
  558 + line-height: 32rpx;
  559 + }
  560 +
  561 + .row:last-child {
  562 + margin-bottom: 0;
  563 + }
  564 +
  565 + .label {
  566 + width: 180rpx;
  567 + margin-right: 14rpx;
  568 + color: rgba(0, 0, 0, 0.6);
  569 + font-size: 28rpx;
  570 + }
  571 +
  572 + .value {
  573 + flex: 1;
  574 + color: rgba(0, 0, 0, 0.9);
  575 + font-size: 28rpx;
  576 + white-space: pre-wrap;
  577 + word-break: break-all;
  578 +
  579 + &.change {
  580 + color: $theme-primary;
  581 + }
  582 + }
  583 +}
  584 +</style>
... ...