Commit 68bc1ff58bd62fa8e16af67f9c6d3b7a682612b3

Authored by 史婷婷
1 parent 156be00d

feat: 草稿要车单-列表&筛选

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