Showing
6 changed files
with
887 additions
and
1 deletions
| ... | ... | @@ -8,3 +8,37 @@ export function salesmanQuotationPeerQueryApi(params) { |
| 8 | 8 | params |
| 9 | 9 | }) |
| 10 | 10 | } |
| 11 | + | |
| 12 | +export function salesmanQuotationPeerSaveApi(data) { | |
| 13 | + return request({ | |
| 14 | + url: '/procurement/salesmanQuotationPeer', | |
| 15 | + method: 'post', | |
| 16 | + data, | |
| 17 | + contentType: ContentTypeEnum.JSON | |
| 18 | + }) | |
| 19 | +} | |
| 20 | + | |
| 21 | +export function salesmanQuotationPeerGetApi(id) { | |
| 22 | + return request({ | |
| 23 | + url: '/procurement/salesmanQuotationPeer', | |
| 24 | + method: 'get', | |
| 25 | + params: { id } | |
| 26 | + }) | |
| 27 | +} | |
| 28 | + | |
| 29 | +export function salesmanQuotationPeerUpdateApi(data) { | |
| 30 | + return request({ | |
| 31 | + url: '/procurement/salesmanQuotationPeer', | |
| 32 | + method: 'put', | |
| 33 | + data, | |
| 34 | + contentType: ContentTypeEnum.JSON | |
| 35 | + }) | |
| 36 | +} | |
| 37 | + | |
| 38 | +export function salesmanQuotationPeerDeleteApi(id) { | |
| 39 | + return request({ | |
| 40 | + url: '/procurement/salesmanQuotationPeer', | |
| 41 | + method: 'delete', | |
| 42 | + params: { id } | |
| 43 | + }) | |
| 44 | +} | ... | ... |
| ... | ... | @@ -341,6 +341,30 @@ |
| 341 | 341 | } |
| 342 | 342 | }, |
| 343 | 343 | { |
| 344 | + "path": "pages/peer-info/add", | |
| 345 | + "style": { | |
| 346 | + "navigationBarTitleText": "新增同行信息", | |
| 347 | + "navigationBarBackgroundColor": "#ffffff", | |
| 348 | + "navigationBarTextStyle": "black" | |
| 349 | + } | |
| 350 | + }, | |
| 351 | + { | |
| 352 | + "path": "pages/peer-info/modify", | |
| 353 | + "style": { | |
| 354 | + "navigationBarTitleText": "编辑同行信息", | |
| 355 | + "navigationBarBackgroundColor": "#ffffff", | |
| 356 | + "navigationBarTextStyle": "black" | |
| 357 | + } | |
| 358 | + }, | |
| 359 | + { | |
| 360 | + "path": "pages/peer-info/detail", | |
| 361 | + "style": { | |
| 362 | + "navigationBarTitleText": "查看同行信息", | |
| 363 | + "navigationBarBackgroundColor": "#ffffff", | |
| 364 | + "navigationBarTextStyle": "black" | |
| 365 | + } | |
| 366 | + }, | |
| 367 | + { | |
| 344 | 368 | "path": "pages/order_list/index", |
| 345 | 369 | "style": { |
| 346 | 370 | "navigationBarTitleText": "订货单列表", | ... | ... |
pages/peer-info/add.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <view class="page"> | |
| 3 | + <scroll-view class="scroll" scroll-y> | |
| 4 | + <uni-list> | |
| 5 | + <uni-list-item> | |
| 6 | + <template v-slot:body> | |
| 7 | + <view class="item-title"><text class="required">*</text><text>同行名称</text></view> | |
| 8 | + </template> | |
| 9 | + <template v-slot:footer> | |
| 10 | + <uni-easyinput v-model="form.peerName" placeholder="请输入同行名称" :inputBorder="false" /> | |
| 11 | + </template> | |
| 12 | + </uni-list-item> | |
| 13 | + | |
| 14 | + <uni-list-item class="select-item" :class="form.peerProductName ? 'is-filled' : 'is-empty'" clickable | |
| 15 | + @click="openSheet('peerProductId')" :rightText="displayLabel('peerProductName')" showArrow> | |
| 16 | + <template v-slot:body> | |
| 17 | + <view class="item-title"><text class="required">*</text><text>同行品种</text></view> | |
| 18 | + </template> | |
| 19 | + </uni-list-item> | |
| 20 | + | |
| 21 | + <uni-list-item> | |
| 22 | + <template v-slot:body> | |
| 23 | + <view class="item-title"><text class="required">*</text><text>同行报价</text></view> | |
| 24 | + </template> | |
| 25 | + <template v-slot:footer> | |
| 26 | + <uni-easyinput type="digit" v-model="form.peerPrice" placeholder="请输入同行报价" :inputBorder="false" /> | |
| 27 | + </template> | |
| 28 | + </uni-list-item> | |
| 29 | + </uni-list> | |
| 30 | + </scroll-view> | |
| 31 | + | |
| 32 | + <view class="footer"> | |
| 33 | + <button class="btn submit" type="primary" :disabled="submitting" @click="onSubmit">{{ submitting ? '提交中...' : '提交' }}</button> | |
| 34 | + </view> | |
| 35 | + | |
| 36 | + <SingleSelectSheet :visible.sync="sheet.visible" :title="sheet.title" :options="sheet.options" v-model="sheet.value" | |
| 37 | + @confirm="onSheetConfirm" /> | |
| 38 | + </view> | |
| 39 | +</template> | |
| 40 | + | |
| 41 | +<script> | |
| 42 | +import SingleSelectSheet from '@/components/single-select/index.vue' | |
| 43 | +import { breedRelationshipQueryApi } from '@/api/procure-manage/salesmanQuotation.js' | |
| 44 | +import { salesmanQuotationPeerSaveApi } from '@/api/procure-manage/salesmanQuotationPeer.js' | |
| 45 | + | |
| 46 | +export default { | |
| 47 | + name: 'PeerInfoAdd', | |
| 48 | + components: { SingleSelectSheet }, | |
| 49 | + data() { | |
| 50 | + return { | |
| 51 | + submitting: false, | |
| 52 | + productVarietyList: [], | |
| 53 | + sheet: { visible: false, title: '请选择', options: [], field: '', value: '' }, | |
| 54 | + form: { | |
| 55 | + peerName: '', | |
| 56 | + peerProductId: '', | |
| 57 | + peerProductName: '', | |
| 58 | + peerPrice: '' | |
| 59 | + } | |
| 60 | + } | |
| 61 | + }, | |
| 62 | + created() { | |
| 63 | + this.loadProductVariety() | |
| 64 | + }, | |
| 65 | + methods: { | |
| 66 | + async loadProductVariety() { | |
| 67 | + try { | |
| 68 | + const res = await breedRelationshipQueryApi({ pageIndex: 1, pageSize: 9999 }) | |
| 69 | + const _data = res && res.data ? res.data : {} | |
| 70 | + const list = _data.datas || _data.list || _data.records || [] | |
| 71 | + this.productVarietyList = list.map(it => ({ | |
| 72 | + label: it.productName || it.name || '', | |
| 73 | + value: it.productId || it.id || '' | |
| 74 | + })).filter(it => it.value) | |
| 75 | + } catch (e) { | |
| 76 | + this.productVarietyList = [] | |
| 77 | + } | |
| 78 | + }, | |
| 79 | + displayLabel(field) { | |
| 80 | + const map = { peerProductName: '请选择同行品种' } | |
| 81 | + const val = this.form[field] | |
| 82 | + return val ? String(val) : (map[field] || '请选择') | |
| 83 | + }, | |
| 84 | + openSheet(field) { | |
| 85 | + if (field === 'peerProductId') { | |
| 86 | + const current = this.form.peerProductId | |
| 87 | + const match = (this.productVarietyList || []).find(o => String(o.value) === String(current)) | |
| 88 | + this.sheet = { | |
| 89 | + visible: true, | |
| 90 | + title: '同行品种', | |
| 91 | + options: this.productVarietyList || [], | |
| 92 | + field, | |
| 93 | + value: match ? match.value : '' | |
| 94 | + } | |
| 95 | + } | |
| 96 | + }, | |
| 97 | + onSheetConfirm({ value, label }) { | |
| 98 | + const field = this.sheet.field | |
| 99 | + if (!field) return | |
| 100 | + if (field === 'peerProductId') { | |
| 101 | + this.form.peerProductId = value || '' | |
| 102 | + this.form.peerProductName = label || '' | |
| 103 | + } | |
| 104 | + }, | |
| 105 | + validate() { | |
| 106 | + const checks = [ | |
| 107 | + { key: 'peerName', label: '同行名称' }, | |
| 108 | + { key: 'peerProductId', label: '同行品种' }, | |
| 109 | + { key: 'peerPrice', label: '同行报价' } | |
| 110 | + ] | |
| 111 | + for (const it of checks) { | |
| 112 | + const val = this.form[it.key] | |
| 113 | + const empty = (val === undefined || val === null || (typeof val === 'string' && String(val).trim() === '')) | |
| 114 | + if (empty) { | |
| 115 | + uni.showToast({ title: `${it.label}必填`, icon: 'none' }) | |
| 116 | + return false | |
| 117 | + } | |
| 118 | + } | |
| 119 | + return true | |
| 120 | + }, | |
| 121 | + buildPayload() { | |
| 122 | + return { | |
| 123 | + peerName: this.form.peerName, | |
| 124 | + peerProductId: this.form.peerProductId, | |
| 125 | + peerPrice: this.form.peerPrice | |
| 126 | + } | |
| 127 | + }, | |
| 128 | + async onSubmit() { | |
| 129 | + if (this.submitting) return | |
| 130 | + if (!this.validate()) return | |
| 131 | + this.submitting = true | |
| 132 | + const payload = this.buildPayload() | |
| 133 | + try { | |
| 134 | + await salesmanQuotationPeerSaveApi(payload) | |
| 135 | + uni.showToast({ title: '保存成功', icon: 'success' }) | |
| 136 | + try { uni.setStorageSync('PEER_INFO_LIST_NEED_REFRESH', '1') } catch (e) {} | |
| 137 | + setTimeout(() => { uni.redirectTo({ url: '/pages/peer-info/index' }) }, 300) | |
| 138 | + } catch (e) { | |
| 139 | + uni.showToast({ title: (e && e.msg) || '保存失败', icon: 'none' }) | |
| 140 | + } finally { | |
| 141 | + this.submitting = false | |
| 142 | + } | |
| 143 | + } | |
| 144 | + } | |
| 145 | +} | |
| 146 | +</script> | |
| 147 | + | |
| 148 | +<style lang="scss" scoped> | |
| 149 | +.page { | |
| 150 | + display: flex; | |
| 151 | + flex-direction: column; | |
| 152 | + height: 100%; | |
| 153 | +} | |
| 154 | + | |
| 155 | +.scroll { | |
| 156 | + flex: 1; | |
| 157 | + padding: 0rpx 0 160rpx; | |
| 158 | + background-color: #f3f3f3; | |
| 159 | +} | |
| 160 | + | |
| 161 | +.footer { | |
| 162 | + position: fixed; | |
| 163 | + left: 0; | |
| 164 | + right: 0; | |
| 165 | + bottom: 0; | |
| 166 | + padding: 32rpx; | |
| 167 | + padding-bottom: calc(32rpx + env(safe-area-inset-bottom)); | |
| 168 | + background: #fff; | |
| 169 | + box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.06); | |
| 170 | + z-index: 10; | |
| 171 | + | |
| 172 | + .btn { | |
| 173 | + height: 80rpx; | |
| 174 | + line-height: 80rpx; | |
| 175 | + border-radius: 12rpx; | |
| 176 | + font-size: 32rpx; | |
| 177 | + } | |
| 178 | + | |
| 179 | + .submit { | |
| 180 | + background: $theme-primary; | |
| 181 | + color: #fff; | |
| 182 | + } | |
| 183 | +} | |
| 184 | + | |
| 185 | +.title-header { | |
| 186 | + display: flex; | |
| 187 | + align-items: center; | |
| 188 | + padding: 24rpx 32rpx 12rpx; | |
| 189 | + background-color: #ffffff; | |
| 190 | + | |
| 191 | + .title-header_icon { | |
| 192 | + width: 36rpx; | |
| 193 | + height: 36rpx; | |
| 194 | + margin-right: 12rpx; | |
| 195 | + } | |
| 196 | + | |
| 197 | + span { | |
| 198 | + font-size: 34rpx; | |
| 199 | + font-weight: 600; | |
| 200 | + color: rgba(0, 0, 0, 0.9); | |
| 201 | + } | |
| 202 | +} | |
| 203 | + | |
| 204 | +.mgb10 { | |
| 205 | + margin-bottom: 20rpx; | |
| 206 | +} | |
| 207 | + | |
| 208 | +::v-deep .uni-list { | |
| 209 | + .uni-easyinput { | |
| 210 | + display: flex; | |
| 211 | + | |
| 212 | + .uni-input-input { | |
| 213 | + color: rgba(0, 0, 0, 0.9); | |
| 214 | + } | |
| 215 | + } | |
| 216 | + | |
| 217 | + .uni-input-placeholder { | |
| 218 | + z-index: 1; | |
| 219 | + } | |
| 220 | + | |
| 221 | + .uni-input-input { | |
| 222 | + background-color: #ffffff; | |
| 223 | + } | |
| 224 | + | |
| 225 | + background: transparent; | |
| 226 | + | |
| 227 | + &-item { | |
| 228 | + &__extra-text { | |
| 229 | + font-size: 32rpx; | |
| 230 | + } | |
| 231 | + | |
| 232 | + &__content-title { | |
| 233 | + font-size: 32rpx; | |
| 234 | + color: rgba(0, 0, 0, 0.9); | |
| 235 | + } | |
| 236 | + | |
| 237 | + &__container { | |
| 238 | + padding: 32rpx; | |
| 239 | + | |
| 240 | + .uni-easyinput { | |
| 241 | + &__placeholder-class { | |
| 242 | + font-size: 32rpx; | |
| 243 | + color: rgba(0, 0, 0, 0.4); | |
| 244 | + } | |
| 245 | + | |
| 246 | + &__content { | |
| 247 | + border: none; | |
| 248 | + background-color: #ffffff !important; | |
| 249 | + | |
| 250 | + &-input { | |
| 251 | + padding-left: 0 !important; | |
| 252 | + height: 48rpx; | |
| 253 | + line-height: 48rpx; | |
| 254 | + font-size: 32rpx; | |
| 255 | + } | |
| 256 | + | |
| 257 | + .content-clear-icon { | |
| 258 | + font-size: 44rpx !important; | |
| 259 | + } | |
| 260 | + } | |
| 261 | + } | |
| 262 | + | |
| 263 | + .item-title, | |
| 264 | + .uni-list-item__content { | |
| 265 | + flex: none; | |
| 266 | + min-height: 48rpx; | |
| 267 | + line-height: 48rpx; | |
| 268 | + font-size: 32rpx; | |
| 269 | + position: relative; | |
| 270 | + width: 210rpx; | |
| 271 | + margin-right: 32rpx; | |
| 272 | + color: rgba(0, 0, 0, 0.9); | |
| 273 | + | |
| 274 | + .required { | |
| 275 | + color: red; | |
| 276 | + position: absolute; | |
| 277 | + top: 50%; | |
| 278 | + transform: translateY(-50%); | |
| 279 | + left: -16rpx; | |
| 280 | + } | |
| 281 | + } | |
| 282 | + } | |
| 283 | + | |
| 284 | + &.select-item { | |
| 285 | + &.is-empty { | |
| 286 | + .uni-list-item__extra-text { | |
| 287 | + color: rgba(0, 0, 0, 0.4) !important; | |
| 288 | + } | |
| 289 | + } | |
| 290 | + | |
| 291 | + &.is-filled { | |
| 292 | + .uni-list-item__extra-text { | |
| 293 | + color: rgba(0, 0, 0, 0.9) !important; | |
| 294 | + } | |
| 295 | + } | |
| 296 | + } | |
| 297 | + | |
| 298 | + &.mgb10 { | |
| 299 | + margin-bottom: 20rpx; | |
| 300 | + } | |
| 301 | + } | |
| 302 | +} | |
| 303 | +</style> | ... | ... |
pages/peer-info/detail.vue
0 → 100644
| 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">{{ safeText(form.peerName) }}</text> | |
| 7 | + <view class="row"><text class="label">同行品种</text><text class="value">{{ safeText(form.peerProductName) }}</text></view> | |
| 8 | + <view class="row"><text class="label">同行报价</text><text class="value">{{ safeText(form.peerPrice) }}</text></view> | |
| 9 | + <view class="row"><text class="label">创建人</text><text class="value">{{ safeText(form.createBy) }}</text></view> | |
| 10 | + <view class="row"><text class="label">创建时间</text><text class="value">{{ formatDateTime(form.createTime) }}</text></view> | |
| 11 | + </view> | |
| 12 | + </view> | |
| 13 | + </scroll-view> | |
| 14 | + <detail-buttons :buttons="displayButtons" @click="handleButtonClick" /> | |
| 15 | + </view> | |
| 16 | +</template> | |
| 17 | + | |
| 18 | +<script> | |
| 19 | +import DetailButtons from '@/components/detail-buttons/index.vue' | |
| 20 | +import { salesmanQuotationPeerGetApi, salesmanQuotationPeerDeleteApi } from '@/api/procure-manage/salesmanQuotationPeer.js' | |
| 21 | + | |
| 22 | +export default { | |
| 23 | + name: 'PeerInfoDetail', | |
| 24 | + components: { DetailButtons }, | |
| 25 | + data() { | |
| 26 | + return { | |
| 27 | + id: '', | |
| 28 | + loading: false, | |
| 29 | + form: {}, | |
| 30 | + buttons: [ | |
| 31 | + { text: '编辑', visible: true, variant: 'outline', event: 'edit' }, | |
| 32 | + { text: '删除', visible: true, variant: 'danger', event: 'delete' } | |
| 33 | + ] | |
| 34 | + } | |
| 35 | + }, | |
| 36 | + computed: { | |
| 37 | + displayButtons() { | |
| 38 | + const isToday = this.isToday(this.form.createTime); | |
| 39 | + return [ | |
| 40 | + { ...this.buttons[0], visible: isToday && this.$auth.hasPermi('procure-manage:peer-info:modify') }, | |
| 41 | + { ...this.buttons[1], visible: isToday && this.$auth.hasPermi('procure-manage:peer-info:delete') } | |
| 42 | + ] | |
| 43 | + } | |
| 44 | + }, | |
| 45 | + onShow() { | |
| 46 | + const options = (this.$route && this.$route.query) ? this.$route.query : {} | |
| 47 | + const id = options && options.id ? String(options.id) : '' | |
| 48 | + if (id && id !== this.id) { | |
| 49 | + this.id = id | |
| 50 | + } | |
| 51 | + if (this.id) this.loadDetail() | |
| 52 | + }, | |
| 53 | + methods: { | |
| 54 | + isToday(dateStr) { | |
| 55 | + if (!dateStr) return false; | |
| 56 | + const date = new Date(dateStr); | |
| 57 | + const today = new Date(); | |
| 58 | + return ( | |
| 59 | + date.getFullYear() === today.getFullYear() && | |
| 60 | + date.getMonth() === today.getMonth() && | |
| 61 | + date.getDate() === today.getDate() | |
| 62 | + ); | |
| 63 | + }, | |
| 64 | + safeText(v) { | |
| 65 | + const s = v == null ? '' : String(v) | |
| 66 | + return s.trim() ? s : '' | |
| 67 | + }, | |
| 68 | + formatDateTime(v) { | |
| 69 | + const s = v == null ? '' : String(v).trim() | |
| 70 | + if (!s) return '-' | |
| 71 | + if (s.length >= 16) return s.slice(0, 16) | |
| 72 | + if (s.length >= 10) return s.slice(0, 10) | |
| 73 | + return s | |
| 74 | + }, | |
| 75 | + handleButtonClick(btn) { | |
| 76 | + if (!btn || btn.disabled) return | |
| 77 | + const e = btn.event || '' | |
| 78 | + if (e === 'edit') return this.onEdit() | |
| 79 | + if (e === 'delete') return this.onDelete() | |
| 80 | + }, | |
| 81 | + onEdit() { | |
| 82 | + uni.navigateTo({ url: '/pages/peer-info/modify?id=' + this.id }) | |
| 83 | + }, | |
| 84 | + onDelete() { | |
| 85 | + const id = this.id || (this.form && this.form.id) || '' | |
| 86 | + if (!id) return | |
| 87 | + uni.showModal({ | |
| 88 | + title: '系统提示', | |
| 89 | + content: '是否确定删除该同行信息?', | |
| 90 | + confirmText: '确定', | |
| 91 | + cancelText: '取消', | |
| 92 | + success: (res) => { | |
| 93 | + if (res && res.confirm) { | |
| 94 | + salesmanQuotationPeerDeleteApi(id).then(() => { | |
| 95 | + uni.showToast({ title: '已删除', icon: 'none' }) | |
| 96 | + try { uni.setStorageSync('PEER_INFO_LIST_NEED_REFRESH', '1') } catch (e) {} | |
| 97 | + setTimeout(() => { uni.redirectTo({ url: '/pages/peer-info/index' }) }, 300) | |
| 98 | + }).catch((e) => { | |
| 99 | + uni.showToast({ title: (e && e.msg) || '删除失败', icon: 'none' }) | |
| 100 | + }) | |
| 101 | + } | |
| 102 | + } | |
| 103 | + }) | |
| 104 | + }, | |
| 105 | + async loadDetail() { | |
| 106 | + this.loading = true | |
| 107 | + try { | |
| 108 | + const res = await salesmanQuotationPeerGetApi(this.id) | |
| 109 | + this.form = (res && res.data) ? res.data : {} | |
| 110 | + } catch (e) { | |
| 111 | + this.form = {} | |
| 112 | + uni.showToast({ title: '详情加载失败', icon: 'none' }) | |
| 113 | + } finally { | |
| 114 | + this.loading = false | |
| 115 | + } | |
| 116 | + } | |
| 117 | + } | |
| 118 | +} | |
| 119 | +</script> | |
| 120 | + | |
| 121 | +<style lang="scss" scoped> | |
| 122 | +.page { | |
| 123 | + display: flex; | |
| 124 | + flex-direction: column; | |
| 125 | + height: 100%; | |
| 126 | +} | |
| 127 | + | |
| 128 | +.scroll { | |
| 129 | + flex: 1; | |
| 130 | + padding: 8rpx 0 144rpx; | |
| 131 | +} | |
| 132 | + | |
| 133 | +.detail-page { | |
| 134 | + background: #f3f3f3; | |
| 135 | +} | |
| 136 | + | |
| 137 | +.section { | |
| 138 | + padding: 32rpx; | |
| 139 | + background: #fff; | |
| 140 | + margin-bottom: 20rpx; | |
| 141 | +} | |
| 142 | + | |
| 143 | +.row { | |
| 144 | + display: flex; | |
| 145 | + margin-bottom: 28rpx; | |
| 146 | + | |
| 147 | + &:last-child { | |
| 148 | + margin-bottom: 0; | |
| 149 | + } | |
| 150 | + | |
| 151 | + &.company { | |
| 152 | + font-size: 36rpx; | |
| 153 | + font-weight: 600; | |
| 154 | + color: rgba(0, 0, 0, 0.9); | |
| 155 | + padding-top: 8rpx; | |
| 156 | + line-height: 50rpx; | |
| 157 | + margin-bottom: 28rpx; | |
| 158 | + } | |
| 159 | + | |
| 160 | + .label { | |
| 161 | + max-width: 420rpx; | |
| 162 | + margin-right: 20rpx; | |
| 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 | + word-break: break-all; | |
| 175 | + | |
| 176 | + &.pre { | |
| 177 | + white-space: pre-wrap; | |
| 178 | + } | |
| 179 | + } | |
| 180 | +} | |
| 181 | +</style> | ... | ... |
| ... | ... | @@ -6,6 +6,7 @@ |
| 6 | 6 | cancelButton="none" bgColor="#F3F3F3" textColor="rgba(0,0,0,0.4)" @confirm="search" |
| 7 | 7 | @input="onSearchInput" /> |
| 8 | 8 | <view class="tool-icons"> |
| 9 | + <image class="tool-icon" src="/static/images/dev_manage/add_icon.png" @click="onAdd" /> | |
| 9 | 10 | <image class="tool-icon" src="/static/images/dev_manage/filter_icon.png" @click="openFilter" /> |
| 10 | 11 | </view> |
| 11 | 12 | </view> |
| ... | ... | @@ -121,6 +122,9 @@ export default { |
| 121 | 122 | if (s.length >= 10) return s.slice(0, 10) |
| 122 | 123 | return s |
| 123 | 124 | }, |
| 125 | + onAdd() { | |
| 126 | + uni.navigateTo({ url: '/pages/peer-info/add' }) | |
| 127 | + }, | |
| 124 | 128 | onCardLoaded({ items }) { |
| 125 | 129 | this.currentItems = items |
| 126 | 130 | }, |
| ... | ... | @@ -187,7 +191,7 @@ export default { |
| 187 | 191 | }) |
| 188 | 192 | }, |
| 189 | 193 | onCardClick(item) { |
| 190 | - // 暂无详情页 | |
| 194 | + uni.navigateTo({ url: '/pages/peer-info/detail?id=' + item.id }) | |
| 191 | 195 | } |
| 192 | 196 | } |
| 193 | 197 | } | ... | ... |
pages/peer-info/modify.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <view class="page"> | |
| 3 | + <scroll-view class="scroll" scroll-y> | |
| 4 | + <uni-list> | |
| 5 | + <view class="title-header"> | |
| 6 | + <image class="title-header_icon" src="/static/images/title.png" /> | |
| 7 | + <span>同行信息</span> | |
| 8 | + </view> | |
| 9 | + | |
| 10 | + <uni-list-item> | |
| 11 | + <template v-slot:body> | |
| 12 | + <view class="item-title"><text class="required">*</text><text>同行名称</text></view> | |
| 13 | + </template> | |
| 14 | + <template v-slot:footer> | |
| 15 | + <uni-easyinput v-model="form.peerName" placeholder="请输入同行名称" :inputBorder="false" /> | |
| 16 | + </template> | |
| 17 | + </uni-list-item> | |
| 18 | + | |
| 19 | + <uni-list-item class="select-item" :class="form.peerProductName ? 'is-filled' : 'is-empty'" clickable | |
| 20 | + @click="openSheet('peerProductId')" :rightText="displayLabel('peerProductName')" showArrow> | |
| 21 | + <template v-slot:body> | |
| 22 | + <view class="item-title"><text class="required">*</text><text>同行品种</text></view> | |
| 23 | + </template> | |
| 24 | + </uni-list-item> | |
| 25 | + | |
| 26 | + <uni-list-item> | |
| 27 | + <template v-slot:body> | |
| 28 | + <view class="item-title"><text class="required">*</text><text>同行报价</text></view> | |
| 29 | + </template> | |
| 30 | + <template v-slot:footer> | |
| 31 | + <uni-easyinput type="digit" v-model="form.peerPrice" placeholder="请输入同行报价" :inputBorder="false" /> | |
| 32 | + </template> | |
| 33 | + </uni-list-item> | |
| 34 | + </uni-list> | |
| 35 | + </scroll-view> | |
| 36 | + | |
| 37 | + <view class="footer"> | |
| 38 | + <button class="btn submit" type="primary" :disabled="submitting" @click="onSubmit">{{ submitting ? '提交中...' : '提交' }}</button> | |
| 39 | + </view> | |
| 40 | + | |
| 41 | + <SingleSelectSheet :visible.sync="sheet.visible" :title="sheet.title" :options="sheet.options" v-model="sheet.value" | |
| 42 | + @confirm="onSheetConfirm" /> | |
| 43 | + </view> | |
| 44 | +</template> | |
| 45 | + | |
| 46 | +<script> | |
| 47 | +import SingleSelectSheet from '@/components/single-select/index.vue' | |
| 48 | +import { breedRelationshipQueryApi } from '@/api/procure-manage/salesmanQuotation.js' | |
| 49 | +import { salesmanQuotationPeerGetApi, salesmanQuotationPeerUpdateApi } from '@/api/procure-manage/salesmanQuotationPeer.js' | |
| 50 | + | |
| 51 | +export default { | |
| 52 | + name: 'PeerInfoModify', | |
| 53 | + components: { SingleSelectSheet }, | |
| 54 | + data() { | |
| 55 | + return { | |
| 56 | + id: '', | |
| 57 | + submitting: false, | |
| 58 | + loading: false, | |
| 59 | + productVarietyList: [], | |
| 60 | + sheet: { visible: false, title: '请选择', options: [], field: '', value: '' }, | |
| 61 | + form: { | |
| 62 | + id: '', | |
| 63 | + peerName: '', | |
| 64 | + peerProductId: '', | |
| 65 | + peerProductName: '', | |
| 66 | + peerPrice: '' | |
| 67 | + } | |
| 68 | + } | |
| 69 | + }, | |
| 70 | + onLoad(query) { | |
| 71 | + this.id = (query && query.id) ? String(query.id) : '' | |
| 72 | + }, | |
| 73 | + created() { | |
| 74 | + this.loadProductVariety() | |
| 75 | + if (this.id) this.loadDetail() | |
| 76 | + }, | |
| 77 | + methods: { | |
| 78 | + async loadProductVariety() { | |
| 79 | + try { | |
| 80 | + const res = await breedRelationshipQueryApi({ pageIndex: 1, pageSize: 9999 }) | |
| 81 | + const _data = res && res.data ? res.data : {} | |
| 82 | + const list = _data.datas || _data.list || _data.records || [] | |
| 83 | + this.productVarietyList = list.map(it => ({ | |
| 84 | + label: it.productName || it.name || '', | |
| 85 | + value: it.productId || it.id || '' | |
| 86 | + })).filter(it => it.value) | |
| 87 | + } catch (e) { | |
| 88 | + this.productVarietyList = [] | |
| 89 | + } | |
| 90 | + }, | |
| 91 | + async loadDetail() { | |
| 92 | + this.loading = true | |
| 93 | + try { | |
| 94 | + const res = await salesmanQuotationPeerGetApi(this.id) | |
| 95 | + const data = (res && res.data) ? res.data : {} | |
| 96 | + this.form = { | |
| 97 | + id: data.id || this.id, | |
| 98 | + peerName: data.peerName || '', | |
| 99 | + peerProductId: data.peerProductId || '', | |
| 100 | + peerProductName: data.peerProductName || this.getOptionLabel(this.productVarietyList, data.peerProductId), | |
| 101 | + peerPrice: data.peerPrice != null ? String(data.peerPrice) : '' | |
| 102 | + } | |
| 103 | + } catch (e) { | |
| 104 | + uni.showToast({ title: '加载失败', icon: 'none' }) | |
| 105 | + } finally { | |
| 106 | + this.loading = false | |
| 107 | + } | |
| 108 | + }, | |
| 109 | + getOptionLabel(options, value) { | |
| 110 | + const v = value != null ? String(value) : '' | |
| 111 | + if (!v) return '' | |
| 112 | + const match = (options || []).find(o => String(o.value) === v) | |
| 113 | + return match ? String(match.label || '') : '' | |
| 114 | + }, | |
| 115 | + displayLabel(field) { | |
| 116 | + const map = { peerProductName: '请选择同行品种' } | |
| 117 | + const val = this.form[field] | |
| 118 | + return val ? String(val) : (map[field] || '请选择') | |
| 119 | + }, | |
| 120 | + openSheet(field) { | |
| 121 | + if (field === 'peerProductId') { | |
| 122 | + const current = this.form.peerProductId | |
| 123 | + const match = (this.productVarietyList || []).find(o => String(o.value) === String(current)) | |
| 124 | + this.sheet = { | |
| 125 | + visible: true, | |
| 126 | + title: '同行品种', | |
| 127 | + options: this.productVarietyList || [], | |
| 128 | + field, | |
| 129 | + value: match ? match.value : '' | |
| 130 | + } | |
| 131 | + } | |
| 132 | + }, | |
| 133 | + onSheetConfirm({ value, label }) { | |
| 134 | + const field = this.sheet.field | |
| 135 | + if (!field) return | |
| 136 | + if (field === 'peerProductId') { | |
| 137 | + this.form.peerProductId = value || '' | |
| 138 | + this.form.peerProductName = label || '' | |
| 139 | + } | |
| 140 | + }, | |
| 141 | + validate() { | |
| 142 | + const checks = [ | |
| 143 | + { key: 'peerName', label: '同行名称' }, | |
| 144 | + { key: 'peerProductId', label: '同行品种' }, | |
| 145 | + { key: 'peerPrice', label: '同行报价' } | |
| 146 | + ] | |
| 147 | + for (const it of checks) { | |
| 148 | + const val = this.form[it.key] | |
| 149 | + const empty = (val === undefined || val === null || (typeof val === 'string' && String(val).trim() === '')) | |
| 150 | + if (empty) { | |
| 151 | + uni.showToast({ title: `${it.label}必填`, icon: 'none' }) | |
| 152 | + return false | |
| 153 | + } | |
| 154 | + } | |
| 155 | + return true | |
| 156 | + }, | |
| 157 | + buildPayload() { | |
| 158 | + return { | |
| 159 | + id: this.form.id, | |
| 160 | + peerName: this.form.peerName, | |
| 161 | + peerProductId: this.form.peerProductId, | |
| 162 | + peerPrice: this.form.peerPrice | |
| 163 | + } | |
| 164 | + }, | |
| 165 | + async onSubmit() { | |
| 166 | + if (this.submitting) return | |
| 167 | + if (!this.validate()) return | |
| 168 | + this.submitting = true | |
| 169 | + const payload = this.buildPayload() | |
| 170 | + try { | |
| 171 | + await salesmanQuotationPeerUpdateApi(payload) | |
| 172 | + uni.showToast({ title: '保存成功', icon: 'success' }) | |
| 173 | + try { uni.setStorageSync('PEER_INFO_LIST_NEED_REFRESH', '1') } catch (e) {} | |
| 174 | + setTimeout(() => { uni.redirectTo({ url: '/pages/peer-info/index' }) }, 300) | |
| 175 | + } catch (e) { | |
| 176 | + uni.showToast({ title: (e && e.msg) || '保存失败', icon: 'none' }) | |
| 177 | + } finally { | |
| 178 | + this.submitting = false | |
| 179 | + } | |
| 180 | + } | |
| 181 | + } | |
| 182 | +} | |
| 183 | +</script> | |
| 184 | + | |
| 185 | +<style lang="scss" scoped> | |
| 186 | +.page { | |
| 187 | + display: flex; | |
| 188 | + flex-direction: column; | |
| 189 | + height: 100%; | |
| 190 | +} | |
| 191 | + | |
| 192 | +.scroll { | |
| 193 | + flex: 1; | |
| 194 | + padding: 0rpx 0 160rpx; | |
| 195 | + background-color: #f3f3f3; | |
| 196 | +} | |
| 197 | + | |
| 198 | +.footer { | |
| 199 | + position: fixed; | |
| 200 | + left: 0; | |
| 201 | + right: 0; | |
| 202 | + bottom: 0; | |
| 203 | + padding: 32rpx; | |
| 204 | + padding-bottom: calc(32rpx + env(safe-area-inset-bottom)); | |
| 205 | + background: #fff; | |
| 206 | + box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.06); | |
| 207 | + z-index: 10; | |
| 208 | + | |
| 209 | + .btn { | |
| 210 | + height: 80rpx; | |
| 211 | + line-height: 80rpx; | |
| 212 | + border-radius: 12rpx; | |
| 213 | + font-size: 32rpx; | |
| 214 | + } | |
| 215 | + | |
| 216 | + .submit { | |
| 217 | + background: $theme-primary; | |
| 218 | + color: #fff; | |
| 219 | + } | |
| 220 | +} | |
| 221 | + | |
| 222 | +.title-header { | |
| 223 | + display: flex; | |
| 224 | + align-items: center; | |
| 225 | + padding: 24rpx 32rpx 12rpx; | |
| 226 | + background-color: #ffffff; | |
| 227 | + | |
| 228 | + .title-header_icon { | |
| 229 | + width: 36rpx; | |
| 230 | + height: 36rpx; | |
| 231 | + margin-right: 12rpx; | |
| 232 | + } | |
| 233 | + | |
| 234 | + span { | |
| 235 | + font-size: 34rpx; | |
| 236 | + font-weight: 600; | |
| 237 | + color: rgba(0, 0, 0, 0.9); | |
| 238 | + } | |
| 239 | +} | |
| 240 | + | |
| 241 | +.mgb10 { | |
| 242 | + margin-bottom: 20rpx; | |
| 243 | +} | |
| 244 | + | |
| 245 | +::v-deep .uni-list { | |
| 246 | + .uni-easyinput { | |
| 247 | + display: flex; | |
| 248 | + | |
| 249 | + .uni-input-input { | |
| 250 | + color: rgba(0, 0, 0, 0.9); | |
| 251 | + } | |
| 252 | + } | |
| 253 | + | |
| 254 | + .uni-input-placeholder { | |
| 255 | + z-index: 1; | |
| 256 | + } | |
| 257 | + | |
| 258 | + .uni-input-input { | |
| 259 | + background-color: #ffffff; | |
| 260 | + } | |
| 261 | + | |
| 262 | + background: transparent; | |
| 263 | + | |
| 264 | + &-item { | |
| 265 | + &__extra-text { | |
| 266 | + font-size: 32rpx; | |
| 267 | + } | |
| 268 | + | |
| 269 | + &__content-title { | |
| 270 | + font-size: 32rpx; | |
| 271 | + color: rgba(0, 0, 0, 0.9); | |
| 272 | + } | |
| 273 | + | |
| 274 | + &__container { | |
| 275 | + padding: 32rpx; | |
| 276 | + | |
| 277 | + .uni-easyinput { | |
| 278 | + &__placeholder-class { | |
| 279 | + font-size: 32rpx; | |
| 280 | + color: rgba(0, 0, 0, 0.4); | |
| 281 | + } | |
| 282 | + | |
| 283 | + &__content { | |
| 284 | + border: none; | |
| 285 | + background-color: #ffffff !important; | |
| 286 | + | |
| 287 | + &-input { | |
| 288 | + padding-left: 0 !important; | |
| 289 | + height: 48rpx; | |
| 290 | + line-height: 48rpx; | |
| 291 | + font-size: 32rpx; | |
| 292 | + } | |
| 293 | + | |
| 294 | + .content-clear-icon { | |
| 295 | + font-size: 44rpx !important; | |
| 296 | + } | |
| 297 | + } | |
| 298 | + } | |
| 299 | + | |
| 300 | + .item-title, | |
| 301 | + .uni-list-item__content { | |
| 302 | + flex: none; | |
| 303 | + min-height: 48rpx; | |
| 304 | + line-height: 48rpx; | |
| 305 | + font-size: 32rpx; | |
| 306 | + position: relative; | |
| 307 | + width: 210rpx; | |
| 308 | + margin-right: 32rpx; | |
| 309 | + color: rgba(0, 0, 0, 0.9); | |
| 310 | + | |
| 311 | + .required { | |
| 312 | + color: red; | |
| 313 | + position: absolute; | |
| 314 | + top: 50%; | |
| 315 | + transform: translateY(-50%); | |
| 316 | + left: -16rpx; | |
| 317 | + } | |
| 318 | + } | |
| 319 | + } | |
| 320 | + | |
| 321 | + &.select-item { | |
| 322 | + &.is-empty { | |
| 323 | + .uni-list-item__extra-text { | |
| 324 | + color: rgba(0, 0, 0, 0.4) !important; | |
| 325 | + } | |
| 326 | + } | |
| 327 | + | |
| 328 | + &.is-filled { | |
| 329 | + .uni-list-item__extra-text { | |
| 330 | + color: rgba(0, 0, 0, 0.9) !important; | |
| 331 | + } | |
| 332 | + } | |
| 333 | + } | |
| 334 | + | |
| 335 | + &.mgb10 { | |
| 336 | + margin-bottom: 20rpx; | |
| 337 | + } | |
| 338 | + } | |
| 339 | +} | |
| 340 | +</style> | ... | ... |