li.shaoyi 2 년 전
부모
커밋
7e98f83aad

+ 1 - 3
src/business/trade/index.ts

@@ -253,7 +253,6 @@ export function useWrListingCancelOrder() {
 export function useWrOutInApply(holdlb?: Model.HoldLBRsp) {
     const loading = shallowRef(false)
     const orderQty = shallowRef(0.0)
-    const checked = shallowRef(3)
 
     const formData = reactive<Partial<Proto.WROutApplyReq>>({
         AppointmentRemark: '',
@@ -262,8 +261,8 @@ export function useWrOutInApply(holdlb?: Model.HoldLBRsp) {
         CreatorID: loginId.value,         // 创建人ID
         WRStandardID: holdlb?.wrstandardid,
         WarehouseID: holdlb?.warehouseid,
+        AppointmentModel: 1,
         ClientSerialID: new Date().getTime(),    // 客户端流水号
-        AppointmentModel: checked.value,
         AppointmentDate: formatDate(new Date().toISOString(), 'YYYY-MM-DD'),
     })
 
@@ -289,7 +288,6 @@ export function useWrOutInApply(holdlb?: Model.HoldLBRsp) {
         formData,
         applySubmit,
         orderQty,
-        checked
     }
 }
 

+ 4 - 1
src/packages/mobile/App.vue

@@ -17,7 +17,10 @@ eventBus.$on('LogoutNotify', (msg) => {
     if (msg) {
       dialog({
         message: msg as string,
-      }).finally(() => {
+      }).then(() => {
+        // ---待处理---
+        // 登出后应该回退到首页,如果回退后非首页,会导致路由拦截而跳转到登录页面,此时因为 tabIndex = 0 的问题,登录页被 replace 成首页,导致路由还能继续后退
+        // 临时解决方案是先退回首页后再进行登出操作
         backHome()
       })
     } else {

+ 7 - 2
src/packages/mobile/components/base/region/index.vue

@@ -11,7 +11,7 @@
 </template>
 
 <script lang="ts" setup>
-import { shallowRef, computed } from 'vue'
+import { shallowRef, computed, watch } from 'vue'
 import { Popup, Cascader, CascaderOption } from 'vant'
 import axios from 'axios'
 
@@ -37,7 +37,7 @@ const props = defineProps({
     },
 })
 
-const emit = defineEmits(['update:modelValue', 'change', 'finish'])
+const emit = defineEmits(['update:modelValue', 'update:label', 'change', 'finish'])
 const show = shallowRef(false) // 是否弹出选择器
 const inputValue = shallowRef(props.label)
 const options = shallowRef<CascaderOption[]>([])
@@ -66,6 +66,7 @@ const onFinish = ({ selectedOptions }: { selectedOptions: CascaderOption[] }) =>
     inputValue.value = selectedOptions.map((option) => option.text).join(' ')
 
     emit('update:modelValue', [...selection].pop())
+    emit('update:label', inputValue.value)
     emit('finish', selection)
 }
 
@@ -88,6 +89,10 @@ const arrayToTree = (list: Model.Region[]) => {
     return getChildren('0086')
 }
 
+watch(() => props.label, (val) => {
+    inputValue.value = val
+})
+
 axios('./config/address.json').then((res) => {
     options.value = arrayToTree(res.data)
 })

+ 12 - 2
src/packages/mobile/router/animateRouter.ts

@@ -6,6 +6,7 @@ interface HistoryState {
     excludeViews: string[]; // 不缓存的页面
     actionName: '' | 'push' | 'replace' | 'forward' | 'back'; // 当前路由动作
     transitionName: '' | 'route-out' | 'route-in'; // 前进后退动画
+    goStep: number; // 前进后退步数
 }
 
 export default new (class {
@@ -16,6 +17,7 @@ export default new (class {
         excludeViews: [],
         actionName: '',
         transitionName: '',
+        goStep: 0,
     })
 
     /** 只读状态 */
@@ -37,7 +39,7 @@ export default new (class {
     create = (options: RouterOptions) => {
         const router = createRouter(options);
         const { push, replace, go, forward, back } = router;
-        const { actionName } = toRefs(this._state.value);
+        const { actionName, goStep } = toRefs(this._state.value);
 
         // 添加
         router.push = (to: RouteRecordRaw) => {
@@ -53,6 +55,7 @@ export default new (class {
 
         // 前进后退
         router.go = (delta: number) => {
+            goStep.value = delta;
             if (delta > 0) {
                 actionName.value = 'forward';
             }
@@ -91,7 +94,7 @@ export default new (class {
      * @param route 
      */
     private addHistory = (route: RouteLocationNormalized) => {
-        const { history, excludeViews, actionName, transitionName } = toRefs(this._state.value);
+        const { history, excludeViews, actionName, transitionName, goStep } = toRefs(this._state.value);
 
         // 如果是替换动作,必定是前进
         if (actionName.value === 'replace') {
@@ -131,6 +134,12 @@ export default new (class {
                     transitionName.value = 'route-out'; //后退动画
                 }
             } else {
+                if (goStep.value < 0) {
+                    const start = history.value.length + goStep.value
+                    if (start) {
+                        history.value.splice(start)
+                    }
+                }
                 // 忽略重定向的页面
                 if (route.redirectedFrom) {
                     transitionName.value = 'route-in'; // 前进动画
@@ -144,6 +153,7 @@ export default new (class {
         }
 
         actionName.value = '';
+        goStep.value = 0
         sessionStorage.setItem(this.storageKey, JSON.stringify(this._state.value));
     }
 })

+ 81 - 61
src/packages/mobile/views/mine/wareorder/components/pickup/index.vue

@@ -1,63 +1,66 @@
 <template>
     <app-modal direction="right" height="100%" v-model:show="showModal" :refresh="refresh">
-        <app-view class="g-form">
-            <template #header>
-                <app-navbar title="提货" @back="closed" />
-            </template>
-            <Form ref="formRef" class="g-form__container" @submit="formSubmit">
-                <CellGroup inset>
-                    <Field label="商品" readonly>
-                        <template #input>
-                            {{ selectedRow.wrstandardname }}
-                        </template>
-                    </Field>
-                    <Field label="仓库" readonly>
-                        <template #input>
-                            {{ selectedRow.warehousename }}
-                        </template>
-                    </Field>
-                    <Field name="OrderQty" label="提货数量" v-model="orderQty" placeholder="请输入提货数量"
-                        :rules="formRules.orderQty" />
+        <template #default="{ animation }">
+            <app-view class="g-form">
+                <template #header>
+                    <app-navbar title="提货" @back="closed" />
+                </template>
+                <Form ref="formRef" class="g-form__container" @submit="formSubmit">
+                    <CellGroup inset>
+                        <Field label="商品" readonly>
+                            <template #input>
+                                {{ selectedRow.wrstandardname }}
+                            </template>
+                        </Field>
+                        <Field label="仓库" readonly>
+                            <template #input>
+                                {{ selectedRow.warehousename }}
+                            </template>
+                        </Field>
+                        <Field name="OrderQty" label="提货数量" v-model="orderQty" placeholder="请输入提货数量"
+                            :rules="formRules.orderQty" />
 
-                    <Field label="提货方式" readonly>
-                        <template #input>
-                            <RadioGroup v-model="checked" direction="horizontal">
-                                <Radio :name="3">代办运输</Radio>
-                                <Radio :name="2">自提</Radio>
-                            </RadioGroup>
-                        </template>
-                    </Field>
-                    <Field name="ContractName" label="联系人" v-model="formData.ContactName" placeholder="请输入联系人"
-                        :rules="formRules.ContactName">
-                        <template #button>
-                            <Button size="normal" icon="add-o" @click="showContact = true" />
-                        </template>
-                    </Field>
-                    <Field name="ContactNum" label="联系方式" v-model="formData.ContactNum" placeholder="请输入联系方式"
-                        :rules="formRules.ContactNum" />
-                    <Field name="Address" label="目的地地址" v-model="formData.Address" placeholder="请输入目的地地址"
-                        :rules="formRules.Address" v-if="checked === 3" />
-                    <Field name="AppointmentRemark" label="发票信息" rows="10" autosize v-model="formData.AppointmentRemark"
-                        placeholder="请填入发票信息" :rules="formRules.AppointmentRemark">
-                        <template #button>
-                            <Button size="normal" icon="add-o" @click="showReceipt = true" />
+                        <Field label="提货方式" readonly>
+                            <template #input>
+                                <RadioGroup v-model="formData.AppointmentModel" direction="horizontal">
+                                    <Radio :name="1">代办运输</Radio>
+                                    <Radio :name="3">自提</Radio>
+                                </RadioGroup>
+                            </template>
+                        </Field>
+                        <Field name="ContractName" label="联系人" v-model="formData.ContactName" placeholder="请输入联系人"
+                            :rules="formRules.ContactName" right-icon="add-o" @click-right-icon="showContact = true" />
+                        <Field name="ContactNum" label="联系方式" v-model="formData.ContactNum" placeholder="请输入联系方式"
+                            :rules="formRules.ContactNum" />
+                        <template v-if="formData.AppointmentModel === 1">
+                            <Field :rules="formRules.Region" name="Region" label="目的地地区" is-link v-if="!animation">
+                                <template #input>
+                                    <component :is="AppRegion" v-model="formData.DistrictID" v-model:label="regionName"
+                                        @finish="onRegionFinish" />
+                                </template>
+                            </Field>
+                            <Field name="Address" type="textarea" label="目的地地址" row="2" v-model="formData.Address"
+                                placeholder="请输入目的地地址" :rules="formRules.Address" />
                         </template>
-                    </Field>
-                </CellGroup>
-            </Form>
-            <template #footer>
-                <div class="g-form__footer">
-                    <Button type="primary" round block @click="formRef?.submit()">提货</Button>
-                </div>
-            </template>
-        </app-view>
-        <app-contact v-model:show="showContact" @change="contactChange" />
-        <app-receipt v-model:show="showReceipt" @change="receiptChange" />
+                        <Field name="AppointmentRemark" type="textarea" label="发票信息" rows="2" autosize
+                            v-model="formData.AppointmentRemark" placeholder="请填入发票信息" :rules="formRules.AppointmentRemark"
+                            right-icon="add-o" @click-right-icon="showReceipt = true" />
+                    </CellGroup>
+                </Form>
+                <template #footer>
+                    <div class="g-form__footer">
+                        <Button type="primary" round block @click="formRef?.submit()">提货</Button>
+                    </div>
+                </template>
+            </app-view>
+            <app-contact v-model:show="showContact" @change="contactChange" />
+            <app-receipt v-model:show="showReceipt" @change="receiptChange" />
+        </template>
     </app-modal>
 </template>
 
 <script lang="ts" setup>
-import { shallowRef, PropType } from 'vue'
+import { shallowRef, PropType, defineAsyncComponent } from 'vue'
 import { CellGroup, Button, Field, Form, FormInstance, FieldRule, showFailToast, Radio, RadioGroup } from 'vant'
 import { useWrOutInApply } from "@/business/trade";
 import { fullloading, dialog } from '@/utils/vant'
@@ -67,6 +70,9 @@ import AppModal from '@/components/base/modal/index.vue'
 import AppContact from '@mobile/components/modules/contact/index.vue'
 import AppReceipt from '@mobile/components/modules/receipt/index.vue'
 
+// 地区选择
+const AppRegion = defineAsyncComponent(() => import('@mobile/components/base/region/index.vue'))
+
 const props = defineProps({
     selectedRow: {
         type: Object as PropType<Model.HoldLBRsp>,
@@ -79,11 +85,12 @@ const showContact = shallowRef(false) // 显示联系人选择列表
 const showReceipt = shallowRef(false) // 显示发票选择列表
 const showModal = shallowRef(true)
 const refresh = shallowRef(false) // 是否刷新父组件数据
+const regionName = shallowRef('') // 地区名称
 
-const { formData, applySubmit, orderQty, checked } = useWrOutInApply(props.selectedRow)
+const { formData, applySubmit, orderQty } = useWrOutInApply(props.selectedRow)
 
 // 表单验证规则
-const formRules: { [key in keyof Proto.WROutApplyReq | 'orderQty']?: FieldRule[] } = {
+const formRules: { [key in keyof Proto.WROutApplyReq | 'orderQty' | 'Region']?: FieldRule[] } = {
     orderQty: [{
         required: true,
         message: '请输入提货数量',
@@ -102,8 +109,14 @@ const formRules: { [key in keyof Proto.WROutApplyReq | 'orderQty']?: FieldRule[]
             return validateRules.phone.message
         }
     }],
+    Region: [{
+        message: '请选择目的地地区',
+        validator: () => {
+            return !!formData.ProvinceID && !!formData.CityID && !!formData.DistrictID
+        }
+    }],
     Address: [{
-        required: checked.value === 3,
+        required: true,
         message: '请输入目的地地址',
     }],
     AppointmentRemark: [{
@@ -112,16 +125,23 @@ const formRules: { [key in keyof Proto.WROutApplyReq | 'orderQty']?: FieldRule[]
     }],
 }
 
+// 选择地区
+const onRegionFinish = ([province, city, district]: number[]) => {
+    formData.ProvinceID = province
+    formData.CityID = city
+    formData.DistrictID = district
+    formRef.value?.validate('Region')
+}
+
 // 选择联系信息
 const contactChange = (item: Model.UserReceiveInfoRsp) => {
     formData.ContactName = item.receivername
     formData.ContactNum = item.phonenum
-
-    if (checked.value === 3) {
-        formData.Address = [item.provincename, item.cityname, item.districtname, item.address].join(' ')
-    } else {
-        formData.Address = ''
-    }
+    formData.ProvinceID = item.provinceid
+    formData.CityID = item.cityid
+    formData.DistrictID = item.districtid
+    formData.Address = item.address
+    regionName.value = [item.provincename, item.cityname, item.districtname].join(' ')
 }
 
 // 选择发票信息

+ 13 - 4
src/utils/vant/index.ts

@@ -1,4 +1,4 @@
-import { showNotify, NotifyType, showLoadingToast, showDialog, DialogOptions } from 'vant'
+import { showNotify, NotifyType, showToast, showLoadingToast, showDialog, DialogOptions, ToastType } from 'vant'
 import { timerInterceptor } from '@/utils/timer'
 import plus from '@/utils/h5plus'
 
@@ -24,13 +24,22 @@ export function notify(message?: string, type?: NotifyType, duration = 2000) {
  * @param callback 
  * @returns 
  */
-export function showLoading(message = '加载中...', callback?: (hideLoading: () => void) => void,) {
+export function showLoading(message = '加载中...', callback?: (hideLoading: (msg?: string, type?: ToastType) => void) => void,) {
     const toast = showLoadingToast({
         message,
         duration: 0,
         forbidClick: true,
     })
-    callback && callback(toast.close)
+    callback && callback((msg, type) => {
+        if (msg) {
+            showToast({
+                message: msg,
+                type,
+            })
+        } else {
+            toast.close()
+        }
+    })
     return toast
 }
 
@@ -39,7 +48,7 @@ export function showLoading(message = '加载中...', callback?: (hideLoading: (
  * @param callback 
  * @param message 
  */
-export function fullloading(callback: (hideLoading: () => void) => void, message = '提交中...') {
+export function fullloading(callback: (hideLoading: (msg?: string, type?: ToastType) => void) => void, message = '提交中...') {
     return showLoading(message, callback)
 }
 

+ 7 - 0
vue.config.js

@@ -22,6 +22,13 @@ module.exports = defineConfig({
   css: {
     extract: true, // 是否使用css分离插件 ExtractTextPlugin
     sourceMap: false,
+    loaderOptions: {
+      postcss: {
+        postcssOptions: {
+          config: process.env.VUE_APP_ROOT, // 自定义 postcss.config.js 文件路径,https://webpack.docschina.org/loaders/postcss-loader/#postcss-options
+        }
+      }
+    }
   },
   chainWebpack: (config) => {
     config.resolve.alias