Commit 156be00df224c3a3039e33317f4d1112aa339de1

Authored by 史婷婷
1 parent 50d8f625

feat: 延期发货单-列表&筛选

  1 +import request from '@/utils/request'
  2 +import { ContentTypeEnum } from '@/utils/httpEnum';
  3 +
  4 +const baseUrl = '/delayedShipment';
  5 +// 查询列表
  6 +export function queryApi(params) {
  7 + return request({
  8 + url: baseUrl + `/query`,
  9 + method: 'get',
  10 + params
  11 + })
  12 +}
  13 +
  14 +// 根据ID查询详情数据
  15 +export function getDetailApi(id) {
  16 + return request({
  17 + url: baseUrl,
  18 + method: 'get',
  19 + params: { id }
  20 + })
  21 +}
  22 +
  23 +// 取消
  24 +export function cancelApi(id) {
  25 + return request({
  26 + url: baseUrl + '/cancel',
  27 + method: 'get',
  28 + params: { id }
  29 + })
  30 +}
  31 +
  32 +// 延期发货按钮-选择的数据查询
  33 +export function getShipmentPlanDetailApi(id) {
  34 + return request({
  35 + url: '/shipments/plan/detail',
  36 + method: 'get',
  37 + params: { id }
  38 + })
  39 +}
  40 +
  41 +// 新增保存
  42 +export function createApi(params) {
  43 + return request({
  44 + url: baseUrl,
  45 + method: 'post',
  46 + data: params,
  47 + contentType: ContentTypeEnum.JSON
  48 + })
  49 +}
  50 +
  51 +
  52 +// 修改保存
  53 +export function updateApi(params) {
  54 + return request({
  55 + url: baseUrl,
  56 + method: 'put',
  57 + data: params,
  58 + contentType: ContentTypeEnum.JSON
  59 + })
  60 +}
  61 +
... ...
... ... @@ -658,6 +658,14 @@
658 658 }
659 659 },
660 660 {
  661 + "path": "pages/delay_invoice/index",
  662 + "style": {
  663 + "navigationBarTitleText": "延期发货单",
  664 + "navigationBarBackgroundColor": "#ffffff",
  665 + "navigationBarTextStyle": "black"
  666 + }
  667 + },
  668 + {
661 669 "path": "pages/car_request_order/index",
662 670 "style": {
663 671 "navigationBarTitleText": "要车单",
... ...
  1 +<template>
  2 + <view class="page">
  3 + <view class="dev-list-fixed">
  4 + <view class="search-row">
  5 + <uni-search-bar v-model="searchKeyword" radius="6" placeholder="请输入所属办" clearButton="auto"
  6 + cancelButton="none" bgColor="#F3F3F3" textColor="rgba(0,0,0,0.4)" @confirm="search"
  7 + @input="onSearchInput" />
  8 + <view class="tool-icons">
  9 + <image v-if="$auth.hasPermi('shipping-plan-manage:replenishment-order:add')" class="tool-icon"
  10 + src="/static/images/dev_manage/add_icon.png" @click="onAdd" />
  11 + <image class="tool-icon" src="/static/images/dev_manage/filter_icon.png" @click="openFilter" />
  12 + </view>
  13 + </view>
  14 + </view>
  15 +
  16 +
  17 + <!-- 列表卡片组件 -->
  18 + <view class="list-box">
  19 + <card-list ref="cardRef" :fetch-fn="fetchList" :query="query" :extra="extraParams" row-key="id"
  20 + :enable-refresh="true" :enable-load-more="true" @loaded="onCardLoaded" @error="onCardError">
  21 + <template v-slot="{ item, selected }">
  22 + <view class="card" @click.stop="onCardClick(item)">
  23 + <view class="card-header">
  24 + <text class="title omit2">{{ item.deptName }}</text>
  25 + <text :class="['status', `status_${item.status}`]">{{ filterStatus(item.status) }}</text>
  26 + </view>
  27 + <view class="info-row">
  28 + <text>申请日期</text><text>{{ item.applyDate || '-' }}</text>
  29 + </view>
  30 + </view>
  31 + </template>
  32 + </card-list>
  33 + </view>
  34 +
  35 +
  36 +
  37 + <!-- 筛选弹框 -->
  38 + <filter-modal :visible.sync="filterVisible" :value.sync="filterForm" title="筛选" @reset="onFilterReset"
  39 + @confirm="onFilterConfirm">
  40 + <template v-slot="{ model }">
  41 + <view class="filter-form">
  42 + <view class="form-item">
  43 + <view class="label">状态</view>
  44 + <uni-data-checkbox mode="tag" :multiple="false" :value-field="'value'" :text-field="'text'"
  45 + v-model="model.status" @change="onStatusChange" :localdata="statusLocal" />
  46 + </view>
  47 + <view class="form-item">
  48 + <view class="label">申请日期</view>
  49 + <uni-datetime-picker type="daterange" v-model="model.dateRange" start="2023-01-01" />
  50 + </view>
  51 + </view>
  52 + </template>
  53 + </filter-modal>
  54 + </view>
  55 +</template>
  56 +
  57 +<script>
  58 +import CardList from '@/components/card/index.vue'
  59 +import FilterModal from '@/components/filter/index.vue'
  60 +import { workshopQueryApi } from '@/api/devManage.js'
  61 +import SingleSelectSheet from '@/components/single-select/index.vue'
  62 +import {
  63 + queryApi
  64 +} from '@/api/delay_invoice.js'
  65 +import {
  66 + getDicByCodes
  67 +} from '@/utils/dic'
  68 +
  69 +export default {
  70 + components: {
  71 + CardList,
  72 + FilterModal,
  73 + SingleSelectSheet
  74 + },
  75 + data() {
  76 + return {
  77 + searchKeyword: '',
  78 + searchKeywordDebounced: '',
  79 + tabs: [],
  80 + // 给到 card 的筛选值
  81 + query: {
  82 + status: '',
  83 + dateRange: []
  84 + },
  85 + extraParams: {},
  86 +
  87 + // 批量选择
  88 + rowKey: 'id',
  89 + currentItems: [],
  90 +
  91 + // 筛选弹框
  92 + filterVisible: false,
  93 + filterForm: {
  94 + status: '',
  95 + dateRange: []
  96 + },
  97 + dicOptions: {
  98 + AUDIT_STATUS: [],
  99 + },
  100 + statusLocal: [],
  101 + }
  102 + },
  103 + computed: {
  104 + extraCombined() {
  105 + return {
  106 + deptName: this.searchKeywordDebounced || undefined
  107 + }
  108 + }
  109 + },
  110 + watch: {
  111 + extraCombined: {
  112 + deep: true,
  113 + handler(v) {
  114 + this.extraParams = v
  115 + },
  116 + immediate: true
  117 + },
  118 +
  119 + },
  120 + created() {
  121 + this.loadAllDicData()
  122 + },
  123 + onLoad() { },
  124 + // 页面触底兜底:当页面自身滚动到底部时,转调卡片组件加载更多
  125 + onReachBottom() {
  126 + if (this.$refs && this.$refs.cardRef && this.$refs.cardRef.onLoadMore) {
  127 + this.$refs.cardRef.onLoadMore()
  128 + }
  129 + },
  130 + beforeDestroy() {
  131 + if (this.searchDebounceTimer) {
  132 + clearTimeout(this.searchDebounceTimer)
  133 + this.searchDebounceTimer = null
  134 + }
  135 + },
  136 + methods: {
  137 + onCardLoaded({
  138 + items
  139 + }) {
  140 + this.currentItems = items
  141 + },
  142 + onCardError() {
  143 + uni.showToast({
  144 + title: '列表加载失败',
  145 + icon: 'none'
  146 + })
  147 + },
  148 + // 输入实时搜索:1200ms 防抖,仅在停止输入超过阈值后刷新
  149 + onSearchInput(val) {
  150 + if (this.searchDebounceTimer) clearTimeout(this.searchDebounceTimer)
  151 + this.searchDebounceTimer = setTimeout(() => {
  152 + this.searchKeywordDebounced = this.searchKeyword
  153 + this.searchDebounceTimer = null
  154 + }, 1200)
  155 + },
  156 + // uni-search-bar 确认搜索:更新关键字并触发 CardList 刷新
  157 + search(e) {
  158 + const val = e && e.value != null ? e.value : this.searchKeyword
  159 + this.searchKeyword = val
  160 + this.searchKeywordDebounced = val
  161 + },
  162 + onAdd() {
  163 + uni.navigateTo({
  164 + url: '/pages/replenishment_order/add'
  165 + })
  166 + },
  167 + openFilter() {
  168 + this.filterVisible = true
  169 + },
  170 + onFilterReset(payload) {
  171 + this.filterForm = payload
  172 + },
  173 + onFilterConfirm(payload) {
  174 + if ((payload.status === '' || payload.status == null) && this.filterForm.status !== '') {
  175 + payload.status = this.filterForm.status
  176 + }
  177 + this.query = {
  178 + ...payload
  179 + }
  180 + },
  181 + onStatusChange(e) {
  182 + const raw = e && e.detail && e.detail.value !== undefined ?
  183 + e.detail.value :
  184 + (e && e.value !== undefined ? e.value : '')
  185 + this.filterForm.status = raw
  186 + },
  187 +
  188 + // 列表接口(真实请求)
  189 + fetchList({
  190 + pageIndex,
  191 + pageSize,
  192 + query,
  193 + extra
  194 + }) {
  195 + const params = {
  196 + pageIndex,
  197 + pageSize,
  198 + ...extra,
  199 + ...query
  200 + }
  201 + if (Array.isArray(params.dateRange) && params.dateRange.length === 2) {
  202 + params.applyDateStart = params.dateRange[0]
  203 + params.applyDateEnd = params.dateRange[1]
  204 + delete params.dateRange
  205 + }
  206 + if (this.searchKeywordDebounced) {
  207 + params.deptName = this.searchKeywordDebounced
  208 + }
  209 + return queryApi(params)
  210 + .then(res => {
  211 + const _data = res.data || {};
  212 + const records = _data.datas || [];
  213 + const totalCount = _data.totalCount || 0;
  214 + const hasNext = _data.hasNext || false
  215 + return {
  216 + records,
  217 + totalCount,
  218 + hasNext
  219 + }
  220 + })
  221 + .catch(err => {
  222 + console.error('fetchList error', err)
  223 + this.onCardError()
  224 + return {
  225 + records: [],
  226 + totalCount: 0,
  227 + hasNext: false
  228 + }
  229 + })
  230 + },
  231 + loadAllDicData() {
  232 + const dicCodes = ['AUDIT_STATUS']
  233 + return getDicByCodes(dicCodes).then(results => {
  234 + this.dicOptions.AUDIT_STATUS = results.AUDIT_STATUS.data || []
  235 + this.statusLocal = (this.dicOptions.AUDIT_STATUS || []).map(it => ({
  236 + value: it.code,
  237 + text: it.name
  238 + }))
  239 + }).catch(() => {
  240 + this.dicOptions = {
  241 + AUDIT_STATUS: [],
  242 + }
  243 + this.statusLocal = []
  244 + })
  245 + },
  246 + onCardClick(item) {
  247 + const id = (item && (item.id || item.code)) || ''
  248 + if (!id) return
  249 + const query = '?id=' + encodeURIComponent(id)
  250 + uni.navigateTo({
  251 + url: '/pages/replenishment_order/detail' + query
  252 + })
  253 + },
  254 + filterStatus(status) {
  255 + return this.statusLocal.filter(item => item.value === status)[0].text || '';
  256 + },
  257 + }
  258 +}
  259 +</script>
  260 +
  261 +<style lang="scss" scoped>
  262 +.page {
  263 + display: flex;
  264 + flex-direction: column;
  265 + height: 100vh;
  266 +}
  267 +
  268 +.dev-list-fixed {
  269 + position: fixed;
  270 + top: 96rpx;
  271 + left: 0;
  272 + right: 0;
  273 + z-index: 2;
  274 + background: #fff;
  275 +
  276 + .search-row {
  277 + display: flex;
  278 + align-items: center;
  279 + padding: 16rpx 32rpx;
  280 +
  281 + .uni-searchbar {
  282 + padding: 0;
  283 + flex: 1;
  284 + }
  285 +
  286 + .tool-icons {
  287 + display: flex;
  288 +
  289 + .tool-icon {
  290 + width: 48rpx;
  291 + height: 48rpx;
  292 + display: block;
  293 + margin-left: 32rpx;
  294 + }
  295 + }
  296 + }
  297 +
  298 +}
  299 +
  300 +/* 仅当前页覆盖 uni-search-bar 盒子高度 */
  301 +::v-deep .uni-searchbar__box {
  302 + height: 80rpx !important;
  303 + justify-content: start;
  304 +
  305 + .uni-searchbar__box-search-input {
  306 + font-size: 32rpx !important;
  307 + }
  308 +}
  309 +
  310 +.list-box {
  311 + flex: 1;
  312 + padding-top: 132rpx;
  313 +
  314 + &.pad-batch {
  315 + padding-bottom: 144rpx;
  316 + }
  317 +
  318 + .card {
  319 + position: relative;
  320 + }
  321 +
  322 + .card-header {
  323 + margin-bottom: 28rpx;
  324 + position: relative;
  325 +
  326 + .title {
  327 + font-size: 36rpx;
  328 + font-weight: 600;
  329 + line-height: 50rpx;
  330 + color: rgba(0, 0, 0, 0.9);
  331 + width: 578rpx;
  332 + }
  333 +
  334 + .status {
  335 + font-weight: 600;
  336 + position: absolute;
  337 + top: -32rpx;
  338 + right: -32rpx;
  339 + height: 48rpx;
  340 + line-height: 48rpx;
  341 + color: #fff;
  342 + font-size: 24rpx;
  343 + padding: 0 14rpx;
  344 + border-radius: 6rpx;
  345 +
  346 + // 审核中
  347 + &.status_AUDIT {
  348 + background: $theme-primary;
  349 + }
  350 +
  351 + // 审核通过
  352 + &.status_PASS {
  353 + background: #2BA471;
  354 + }
  355 +
  356 + // 已驳回
  357 + &.status_REFUSE {
  358 + background: #d54941;
  359 + }
  360 +
  361 + // 已取消
  362 + &.status_CANCEL {
  363 + background: #e7e7e7;
  364 + color: rgba(0, 0, 0, 0.6);
  365 + }
  366 +
  367 + }
  368 +
  369 + }
  370 +
  371 + .info-row {
  372 + display: flex;
  373 + align-items: center;
  374 + color: rgba(0, 0, 0, 0.6);
  375 + font-size: 28rpx;
  376 + margin-bottom: 24rpx;
  377 +
  378 + &:last-child {
  379 + margin-bottom: 0;
  380 + }
  381 +
  382 + text {
  383 + width: 60%;
  384 + line-height: 32rpx;
  385 +
  386 + &:last-child {
  387 + color: rgba(0, 0, 0, 0.9);
  388 + width: 40%;
  389 + }
  390 +
  391 + &.category {
  392 + display: inline-block;
  393 + padding: 4rpx 12rpx;
  394 + border-radius: 6rpx;
  395 + font-size: 24rpx;
  396 + width: auto;
  397 +
  398 + &.category_A {
  399 + background: #FFF0ED;
  400 + color: #D54941;
  401 + }
  402 +
  403 + &.category_B {
  404 + background: #FFF1E9;
  405 + color: #E37318;
  406 + }
  407 +
  408 + &.category_C {
  409 + background: #F2F3FF;
  410 + color: $theme-primary;
  411 + }
  412 +
  413 + &.category_D {
  414 + background: #E3F9E9;
  415 + color: #2BA471;
  416 + }
  417 + }
  418 + }
  419 +
  420 + }
  421 +}
  422 +
  423 +.filter-form {
  424 + .form-item {
  425 + margin-bottom: 24rpx;
  426 + }
  427 +
  428 + .label {
  429 + margin-bottom: 20rpx;
  430 + color: rgba(0, 0, 0, 0.9);
  431 + height: 44rpx;
  432 + line-height: 44rpx;
  433 + font-size: 30rpx;
  434 + }
  435 +
  436 + .uni-easyinput {
  437 + border: 1rpx solid #f3f3f3;
  438 + }
  439 +
  440 +}
  441 +
  442 +/* 深度覆盖 uni-data-checkbox(mode=tag)内部的 tag 展示与间距 */
  443 +::v-deep .filter-form .uni-data-checklist .checklist-group {
  444 + .checklist-box {
  445 + &.is--tag {
  446 + width: 212rpx;
  447 + margin-top: 0;
  448 + margin-bottom: 24rpx;
  449 + margin-right: 24rpx;
  450 + height: 80rpx;
  451 + padding: 0;
  452 + border-radius: 12rpx;
  453 + background-color: #f3f3f3;
  454 + border-color: #f3f3f3;
  455 +
  456 + &:nth-child(3n) {
  457 + margin-right: 0;
  458 + }
  459 +
  460 + .checklist-content {
  461 + display: flex;
  462 + justify-content: center;
  463 + }
  464 +
  465 + .checklist-text {
  466 + color: rgba(0, 0, 0, 0.9);
  467 + font-size: 28rpx;
  468 + }
  469 + }
  470 +
  471 + &.is-checked {
  472 + background-color: $theme-primary-plain-bg !important;
  473 + border-color: $theme-primary-plain-bg !important;
  474 +
  475 + .checklist-text {
  476 + color: $theme-primary !important;
  477 + }
  478 + }
  479 + }
  480 +
  481 +}
  482 +</style>
\ No newline at end of file
... ...