li.shaoyi 2 years ago
parent
commit
a79f622020

+ 20 - 10
src/packages/mobile/components/base/select/index.vue

@@ -4,7 +4,13 @@
             <input class="'app-select__input'" v-model="inputValue" :placeholder="placeholder" readonly />
         </slot>
         <Popup v-model:show="show" position="bottom" teleport="body" round>
-            <Picker :columns="columns" @cancel="onCancel" @confirm="onConfirm" />
+            <Picker :columns="columns" @cancel="onCancel" @confirm="onConfirm">
+                <template #option="{ text, index }">
+                    <slot name="option" :row="options[index]" :index="index">
+                        {{ text }}
+                    </slot>
+                </template>
+            </Picker>
         </Popup>
     </div>
 </template>
@@ -23,10 +29,7 @@ const props = defineProps({
     },
     optionProps: {
         type: Object as PropType<{ label?: string; value?: string; }>,
-        default: () => ({
-            label: 'label',
-            value: 'value'
-        })
+        default: () => ({})
     },
     readonly: {
         type: Boolean,
@@ -43,11 +46,18 @@ const fieldRef = shallowRef<FieldInstance>()
 const show = shallowRef(false) // 是否弹出选择器
 const selectedIndex = shallowRef(-1)
 
+const customFieldName = {
+    label: 'label',
+    value: 'value',
+    ...props.optionProps
+}
+
 const columns = computed(() => {
     if (props.options) {
-        return props.options.map((e) => ({
-            text: e[props.optionProps.label],
-            value: e[props.optionProps.value],
+        return props.options.map((e, i) => ({
+            text: e[customFieldName.label],
+            value: e[customFieldName.value],
+            index: i
         }))
     }
     return []
@@ -57,7 +67,7 @@ const columns = computed(() => {
 const inputValue = computed(() => {
     const item = props.options[selectedIndex.value]
     if (item) {
-        return item[props.optionProps.label] ?? ''
+        return item[customFieldName.label] ?? ''
     }
     return ''
 })
@@ -85,7 +95,7 @@ const onConfirm = ({ selectedIndexes: [index], selectedValues: [value] }: Picker
 }
 
 watch(() => [props.modelValue, props.options], ([value, items]) => {
-    selectedIndex.value = items.findIndex((e) => e[props.optionProps.value]?.toString() === value?.toString())
+    selectedIndex.value = items.findIndex((e) => e[customFieldName.value]?.toString() === value?.toString())
 }, {
     immediate: true
 })

+ 90 - 19
src/packages/mobile/views/order/inout/components/add/index.vue

@@ -7,7 +7,41 @@
             <Form ref="formRef" class="g-form__container" @submit="formSubmit">
                 <CellGroup inset>
                     <Field v-model="formData.InUserID" :rules="formRules.InUserID" name="InUserID" label="转入客户"
-                        placeholder="必填" />
+                        right-icon="arrow" clickable @click="showSearch = true">
+                        <template #input>
+                            <input placeholder="请选择" :value="selectedUser?.customername" readonly />
+                        </template>
+                    </Field>
+                    <Field name="GoodsID" label="转让商品" :rules="formRules.GoodsID" is-link>
+                        <template #input>
+                            <app-select v-model="formData.GoodsID" :options="goodsList" :optionProps="{ value: 'goodsid' }"
+                                @confirm="onGoodsChange" />
+                        </template>
+                    </Field>
+                    <Field label="可用数量">
+                        <template #input>
+                            <span>{{ enableqty }}</span>
+                        </template>
+                    </Field>
+                    <Field name="Qty" :rules="formRules.Qty" label="转让数量">
+                        <template #input>
+                            <Stepper v-model="formData.Qty" theme="round" :min="0" :max="enableqty" :default-value="0"
+                                :auto-fixed="false" button-size="22" />
+                        </template>
+                    </Field>
+                    <Field name="TransferPrice" :rules="formRules.TransferPrice" label="转让价格">
+                        <template #input>
+                            <Stepper v-model="formData.TransferPrice" theme="round" :min="0"
+                                :decimal-length="selectedGoods?.decimalplace" :default-value="0" :auto-fixed="false"
+                                button-size="22" />
+                        </template>
+                    </Field>
+                    <Field name="FreezeDays" :rules="formRules.FreezeDays" label="冻结天数">
+                        <template #input>
+                            <Stepper v-model="formData.FreezeDays" theme="round" :min="0" :default-value="0"
+                                :auto-fixed="false" button-size="22" />
+                        </template>
+                    </Field>
                 </CellGroup>
             </Form>
             <template #footer>
@@ -16,31 +50,39 @@
                 </div>
             </template>
         </app-view>
+        <Search v-model:show="showSearch" @change="onUserChange" />
     </app-modal>
 </template>
 
 <script lang="ts" setup>
-import { shallowRef, reactive, computed } from 'vue'
-import { CellGroup, Button, Field, Form, FormInstance, FieldRule } from 'vant'
-import { fullloading, dialog } from '@/utils/vant'
+import { shallowRef, reactive, computed, defineAsyncComponent } from 'vue'
+import { CellGroup, Button, Field, Form, Stepper, FieldRule } from 'vant'
+import { fullloading } from '@/utils/vant'
 import { BuyOrSell } from '@/constants/order'
-import { useRequest } from '@/hooks/request'
 import { holderTransferApply } from '@/services/api/trade'
-import { getUserInfo } from '@/services/api/user'
 import { usePosition } from '@/business/position'
 import { useLoginStore } from '@/stores'
 import AppModal from '@/components/base/modal/index.vue'
+import AppSelect from '@mobile/components/base/select/index.vue'
+
+// 搜索客户
+const Search = defineAsyncComponent(() => import('./serach/index.vue'))
 
 const showModal = shallowRef(true)
+const showSearch = shallowRef(false) // 弹出客户搜索界面
 const refresh = shallowRef(false) // 是否刷新父组件数据
 const formRef = shallowRef()
 const loginStore = useLoginStore()
 const { positionList } = usePosition(16)
+const selectedUser = shallowRef<Model.UserInfoRsp>() // 当前选择的转入客户
 
 // 可用商品列表
-const goodsList = computed(() => positionList.value.filter((e) => e.enableqty > 0))
+const goodsList = computed(() => positionList.value.filter((e) => e.enableqty > 0).map((e) => ({
+    ...e,
+    label: `${e.goodscode}/${e.goodsname}`
+})))
 // 选中的商品
-const selectedGoods = shallowRef<Model.TradePositionRsp>()
+const selectedGoods = computed(() => goodsList.value.find((e) => e.goodsid === formData.GoodsID))
 //可用数量
 const enableqty = computed(() => selectedGoods.value?.enableqty ?? 0)
 
@@ -52,30 +94,54 @@ const formData = reactive<Partial<Proto.HolderTransferDetail>>({
 
 // 表单验证规则
 const formRules: { [key: string]: FieldRule[] } = {
-    ReceiverName: [{
-        required: true,
-        message: '请输入收货人',
+    InUserID: [{
+        message: '请输入客户编号或手机号',
+        validator: () => !!formData.InUserID
+    }],
+    GoodsID: [{
+        message: '请选择转让商品',
+        validator: () => !!selectedGoods.value
     }],
-    Address: [{
-        required: true,
-        message: '请输入详细地址',
+    TransferPrice: [{
+        message: '请输入转让价格',
+        validator: () => formData.TransferPrice ? !!Number(formData.TransferPrice) : false
     }],
+    Qty: [{
+        message: '请输入转让数量',
+        validator: () => !!formData.Qty
+    }],
+    FreezeDays: [{
+        message: '请输入冻结天数',
+        required: true
+    }]
+}
+
+// 选择商品时触发
+const onGoodsChange = () => {
+    if ((formData.Qty ?? 0) > enableqty.value) {
+        formData.Qty = enableqty.value
+    }
+    formRef.value?.validate('GoodsID')
+}
+
+// 选择客户时触发
+const onUserChange = (item: Model.UserInfoRsp) => {
+    formData.InUserID = Number(item.userid)
+    selectedUser.value = item
 }
 
 // 表单提交
 const formSubmit = () => {
     fullloading((hideLoading) => {
-        const { marketid, goodsid } = selectedGoods.value ?? {}
-        formData.GoodsID = goodsid
         holderTransferApply({
             data: {
                 Header: {
-                    MarketID: marketid
+                    MarketID: selectedGoods.value?.marketid ?? 0
                 },
                 HolderTransferDetails: [formData]
             }
         }).then(() => {
-            hideLoading()
+            hideLoading('提交成功,请稍后查询结果', 'success')
             closed(true)
         }).catch((err) => {
             hideLoading(err, 'fail')
@@ -86,7 +152,12 @@ const formSubmit = () => {
 // 关闭弹窗
 const closed = (isRefresh = false) => {
     refresh.value = isRefresh
-    showModal.value = false
+    if (showSearch.value) {
+        showSearch.value = false
+    } else {
+        refresh.value = isRefresh
+        showModal.value = false
+    }
 }
 
 // 暴露组件属性给父组件调用

+ 78 - 0
src/packages/mobile/views/order/inout/components/add/serach/index.vue

@@ -0,0 +1,78 @@
+<template>
+    <app-modal direction="right" height="100%" v-model:show="showModal">
+        <app-view class="g-form">
+            <template #header>
+                <app-navbar title="选择客户">
+                    <template #footer>
+                        <Form action="/">
+                            <Search placeholder="请输入客户编号或手机号" v-model="keyword" @search="onSearch" />
+                        </Form>
+                    </template>
+                </app-navbar>
+            </template>
+            <RadioGroup v-model="checked" v-if="dataList.length">
+                <CellGroup title="选择客户" inset>
+                    <template v-for="(item, index) in dataList" :key="index">
+                        <Cell :title="item.customername" clickable @click="onChange(item)">
+                            <template #right-icon>
+                                <Radio :name="item.userid" />
+                            </template>
+                        </Cell>
+                    </template>
+                </CellGroup>
+            </RadioGroup>
+            <Empty description="暂无数据" v-else />
+        </app-view>
+    </app-modal>
+</template>
+
+<script lang="ts" setup>
+import { shallowRef, computed } from 'vue'
+import { CellGroup, Cell, RadioGroup, Radio, Form, Search, Empty } from 'vant'
+import { fullloading } from '@/utils/vant'
+import { useRequest } from '@/hooks/request'
+import { getUserInfo } from '@/services/api/user'
+import { useLoginStore } from '@/stores'
+import AppModal from '@/components/base/modal/index.vue'
+
+const props = defineProps({
+    show: {
+        type: Boolean,
+        default: false
+    }
+})
+
+const emit = defineEmits(['update:show', 'change'])
+const loginStore = useLoginStore()
+const keyword = shallowRef('')
+const checked = shallowRef(0)
+
+const showModal = computed({
+    get: () => props.show,
+    set: (val) => emit('update:show', val)
+})
+
+const { dataList, runAsync } = useRequest(getUserInfo, {
+    manual: true
+})
+
+const onSearch = (val: string) => {
+    if (val) {
+        fullloading((hideLoading) => {
+            runAsync({
+                param: val
+            }).then((res) => {
+                dataList.value = res.data.filter((e) => e.userid !== loginStore.userId)
+            }).finally(() => {
+                hideLoading()
+            })
+        }, '搜索中...')
+    }
+}
+
+const onChange = (item: Model.UserInfoRsp) => {
+    checked.value = item.userid
+    showModal.value = false
+    emit('change', item)
+}
+</script>

+ 14 - 7
src/packages/pc/views/footer/inout/out/add/index.vue

@@ -4,15 +4,15 @@
         <el-form ref="formRef" class="el-form--horizontal" label-width="100px" :model="formData" :rules="formRules"
             @submit.prevent>
             <el-form-item prop="InUserID" label="转入客户">
-                <el-select placeholder="请输入" v-model="formData.InUserID" :loading="searchLoading"
+                <el-select placeholder="请输入客户编号或手机号" v-model="formData.InUserID" :loading="searchLoading"
                     :remote-method="remoteMethod" filterable remote clearable>
-                    <template v-for="(item, index) in userList" :key="index">
+                    <template v-for="(item, index) in dataList" :key="index">
                         <el-option :label="item.customername" :value="item.userid" />
                     </template>
                 </el-select>
             </el-form-item>
             <el-form-item prop="GoodsID" label="转让商品">
-                <el-select placeholder="请选择" v-model="selectedGoods" value-key="goodsid">
+                <el-select placeholder="请选择" v-model="selectedGoods" value-key="goodsid" @change="onGoodsChange">
                     <template v-for="(item, index) in goodsList" :key="index">
                         <el-option :label="`${item.goodscode}/${item.goodsname}`" :value="item" />
                     </template>
@@ -72,7 +72,7 @@ const formData = reactive<Partial<Proto.HolderTransferDetail>>({
 
 const formRules: FormRules = {
     InUserID: [{
-        message: '请输入转入客户',
+        message: '请输入客户编号或手机号',
         validator: () => !!formData.InUserID
     }],
     GoodsID: [{
@@ -94,21 +94,28 @@ const formRules: FormRules = {
     }]
 }
 
-const { loading: searchLoading, dataList, run: searchUser } = useRequest(getUserInfo, {
+const { loading: searchLoading, dataList, runAsync: searchUser } = useRequest(getUserInfo, {
     manual: true
 })
 
-const userList = computed(() => dataList.value.filter((e) => e.userid !== loginStore.userId))
-
 // 远程搜索转入客户
 const remoteMethod = (query: string) => {
     if (query) {
         searchUser({
             param: query
+        }).then((res) => {
+            dataList.value = res.data.filter((e) => e.userid !== loginStore.userId)
         })
     }
 }
 
+// 选择商品时触发
+const onGoodsChange = () => {
+    if ((formData.Qty ?? 0) > enableqty.value) {
+        formData.Qty = enableqty.value
+    }
+}
+
 const onCancel = (isRefresh = false) => {
     show.value = false
     refresh.value = isRefresh