Handy_Cao 1 jaar geleden
bovenliggende
commit
a9d732362b

+ 6 - 0
oem/tss/locales/extras/en-US.json

@@ -3,6 +3,12 @@
         "name": "TCE",
         "slogan": "TCE Spot Pre Order Platform"
     },
+    "home": {
+        "product": "Products",
+        "pricing": "Price",
+        "pickup": "Reservation",
+        "delivery": "Delivery"
+    },
     "tabbar": {
         "trade": "Reservation"
     },

+ 6 - 0
oem/tss/locales/extras/th-TH.json

@@ -3,6 +3,12 @@
         "name": "TCE",
         "slogan": "แพลตฟอร์มการสั่งซื้อล่วงหน้าสปอตร์"
     },
+    "home": {
+        "product": "ผลิตภัณฑ์",
+        "pricing": "ราคา",
+        "pickup": "จองไว้",
+        "delivery": "กำลังตัด"
+    },
     "tabbar": {
         "trade": "การจอง"
     },

+ 6 - 0
oem/tss/locales/extras/zh-CN.json

@@ -3,6 +3,12 @@
         "name": "TCE",
         "slogan": "泰国商品交易所\r\n现货预订平台"
     },
+    "home": {
+        "product": "产品",
+        "pricing": "价格",
+        "pickup": "预定",
+        "delivery": "交收"
+    },
     "tabbar": {
         "trade": "预订"
     },

+ 6 - 0
oem/tss/locales/extras/zh-TW.json

@@ -3,6 +3,12 @@
         "name": "TCE",
         "slogan": "泰國商品交易所\r\n現貨預訂平臺"
     },
+    "home": {
+        "product": "產品",
+        "pricing": "價格",
+        "pickup": "預定",
+        "delivery": "交收"
+    },
     "tabbar": {
         "trade": "預訂"
     },

+ 2 - 0
src/packages/mobile/views/order/position/components/pricing/detail2/Index.vue

@@ -64,6 +64,7 @@
                         </div>
                         <div class="g-order-list__btnbar" v-if="item.tHDetailEx.holderQty">
                             <Button size="small" v-if="enableqty(item) != 0" @click="showComponent('close', item)" round>{{ $t('operation.close') }}</Button>
+                            <Button size="small" @click="showComponent('delivery', item)" round>{{ $t('operation.delivery') }}</Button>
                         </div>
                     </div>
                 </div>
@@ -94,6 +95,7 @@ const { orderComputedList, loading, error } = $toRefs()
 
 const componentMap = new Map<string, unknown>([
     ['close', defineAsyncComponent(() => import('./components/transfer/Index.vue'))],
+    ['delivery', defineAsyncComponent(() => import('./components/delivery/Index.vue'))],
 ])
 
 const selectedRow = shallowRef<Model.SBYJMyOrderRsp>()

+ 160 - 0
src/packages/mobile/views/order/position/components/pricing/detail2/components/delivery/Index.vue

@@ -0,0 +1,160 @@
+<!-- 我的订单- 挂牌点价 - 订单明细 - 交收 -->
+<template>
+    <app-modal direction="right-top" height="100%" width="100%" v-model:show="showModal" :refresh="refresh">
+        <app-view class="g-form">
+            <template #header>
+                <app-navbar :title="$t('operation.delivery')" @back="closed" />
+            </template>
+            <Form ref="formRef" class="g-form__container" @submit="onDeliverySumit">
+                <CellGroup :title="$t('position.goods.subtitle')" inset>
+                    <Cell :title="$t('position.goods.goodsname')" :value="`${selectedRow.goodsCode}`" />
+                    <Cell :title="$t('position.goods.buyorsell')" :value="getBuyOrSellName(selectedRow.tHDetailEx.buyOrSell)" />
+                    <Cell :title="$t('position.goods.curholderamount')" :value="formatDecimal(selectedRow.tHDetailEx.holderAmount, selectedRow.decimalPlace)" />
+                    <Cell :title="$t('position.goods.curpositionqty')" :value="selectedRow.tHDetailEx.holderQty*selectedRow.agreeUnit + getGoodsUnitName(selectedRow.goodsUnitID)" />
+                    <Cell :title="$t('position.goods.frozenqty')" :value="selectedRow.tHDetailEx.freezeQty*selectedRow.agreeUnit + getGoodsUnitName(selectedRow.goodsUnitID)" />
+                    <Cell :title="$t('position.goods.enableqty')" :value="enableqty" />
+                    <Cell :title="$t('position.goods.mindeliverylot')" :value="mindeliverylot" />
+                    <Cell :title="$t('position.goods.closepl')">
+                        <template #value>
+                            <span :class="handlePriceColor(selectedRow.tHDetailEx.floatPL)">
+                                {{ formatDecimal(selectedRow.tHDetailEx.floatPL, selectedRow.decimalPlace) }}
+                            </span>
+                        </template>
+                    </Cell>
+                    <Cell :title="$t('position.goods.tradetime')" :value="selectedRow.tHDetailEx.tradeTime" />
+                </CellGroup>
+                <CellGroup :title="$t('position.goods.subtitle2')" inset>
+                    <Field name="DeliveryLot" type="digit" :rules="formRules.DeliveryLot" :label="$t('position.goods.deliverylot')">
+                        <template #input>
+                            <Stepper v-model="formData.DeliveryLot" theme="round" button-size="22" :min="0"
+                                :max="enableqty" :auto-fixed="false" integer />
+                        </template>
+                    </Field>
+                    <Cell :title="$t('position.goods.deliveryqty')" :value="((formData.DeliveryLot ?? 0) * selectedRow.agreeUnit) + selectedRow.goodsUnit" />
+                    <Field name="DeliveryInfo" v-model="formData.DeliveryInfo" type="textarea" autosize clearable
+                        :rules="formRules.DeliveryInfo" maxlength="50"
+                        :label="selectedRow.tHDetailEx.buyOrSell === BuyOrSell.Buy ? $t('position.goods.address') : $t('position.goods.deliveryinfo')" :placeholder="$t('common.required')">
+                        <template #right-icon v-if="selectedRow.tHDetailEx.buyOrSell === BuyOrSell.Buy">
+                            <Icon name="add-o" @click="showContact = true" />
+                        </template>
+                    </Field>
+                </CellGroup>
+            </Form>
+            <app-contact v-model:show="showContact" @change="contactChange" />
+            <template #footer>
+                <div class="g-form__footer inset">
+                    <Button :disabled="enableqty === 0" block square type="danger" @click="formRef?.submit">{{ $t('operation.delivery') }}</Button>
+                </div>
+            </template>
+        </app-view>
+    </app-modal>
+</template>
+
+<script lang="ts" setup>
+import { shallowRef, PropType, computed } from 'vue'
+import { CellGroup, Cell, Button, FieldRule, Form, Field, Stepper, FormInstance, Icon } from 'vant'
+import { getBuyOrSellName, BuyOrSell } from '@/constants/order'
+import { formatDecimal, handlePriceColor, handleRequestBigNumber } from '@/filters'
+import { useOfflineDelivery } from '@/business/trade'
+import { dialog, fullloading } from '@/utils/vant'
+import { i18n, useFuturesStore } from '@/stores'
+import { getGoodsUnitName } from '@/constants/unit'
+import AppModal from '@/components/base/modal/index.vue'
+import AppContact from '@mobile/components/modules/contact/index.vue'
+
+const props = defineProps({
+    selectedRow: {
+        type: Object as PropType<Model.SBYJMyOrderRsp & {
+            closepl: number; // 浮动盈亏
+            closeplColor: string; // 浮动盈亏颜色
+        }>,
+        required: true,
+    }
+})
+
+const { global: { t } } = i18n
+const showModal = shallowRef(true)
+// 是否刷新父组件数据
+const refresh = shallowRef(false)
+const formRef = shallowRef<FormInstance>()
+const showContact = shallowRef(false) // 显示联系人选择列表
+const { formSubmit, formData } = useOfflineDelivery()
+const futuresStore = useFuturesStore()
+const goods = futuresStore.getGoods(props.selectedRow.goodsCode)
+const { mindeliverylot = 0 } = goods ?? {}
+
+// 表单验证规则
+const formRules: { [key: string]: FieldRule[] } = {
+    DeliveryLot: [{
+        message: t('position.goods.tips7'),
+        validator: (val) => {
+            if (val >= mindeliverylot) {
+                return true
+            }
+            return t('position.goods.tips8') + `${mindeliverylot}`
+        }
+    }],
+    DeliveryInfo: [{
+        required: true,
+        message: props.selectedRow.tHDetailEx.buyOrSell === BuyOrSell.Buy ? t('position.goods.tips9') : t('position.goods.tips10'),
+        validator: () => {
+            return !!formData.DeliveryInfo
+        }
+    }],
+}
+
+// 可用重量
+const enableqty = computed(() => {
+    const { tHDetailEx, agreeUnit } = props.selectedRow
+    return (tHDetailEx.holderQty - tHDetailEx.freezeQty) * agreeUnit
+}) 
+
+// 选择联系信息
+const contactChange = (item: Model.UserReceiveInfoRsp) => {
+    const contact = `${item.receivername} ${item.phonenum}`
+    const address = `${item.provincename} ${item.cityname} ${item.districtname} ${item.address}`
+    formData.DeliveryInfo = [contact, address].join('\n')
+    formRef.value?.validate('Region')
+}
+
+const onDeliverySumit = () => {
+    dialog({
+        message: t('position.goods.tips5'),
+        showCancelButton: true,
+    }).then(() => {
+        const { buyOrSell, tradeID } = props.selectedRow.tHDetailEx
+        const { goodsCode } = props.selectedRow
+        const { marketid, goodsid } = goods ?? {}
+        /// 市场ID
+        formData.Header = { MarketID: marketid, GoodsID: goodsid }
+        formData.GoodsCode = goodsCode
+        formData.GoodsID = goodsid
+        formData.BuyOrSell = buyOrSell
+        formData.TradeID = handleRequestBigNumber(tradeID)
+        /// loding....
+        fullloading((hideLoading) => {
+            formSubmit().then(() => {
+                hideLoading(t('position.goods.tips6'), 'success')
+                closed(true)
+            }).catch((err) => {
+                hideLoading(err, 'fail')
+            })
+        })
+    })
+}
+
+// 关闭弹窗
+const closed = (isRefresh = false) => {
+    refresh.value = isRefresh
+    if (showContact.value) {
+        showContact.value = false
+    } else {
+        showModal.value = false
+    }
+}
+
+// 暴露组件属性给父组件调用
+defineExpose({
+    closed,
+})
+</script>

+ 1 - 1
src/packages/mobile/views/pricing/trade/Index.vue

@@ -252,7 +252,7 @@ const components = [
     
 const componentMap = new Map<string, unknown>([
     ['detail', defineAsyncComponent(() => import('./components/detail/Index.vue'))],
-    ['transfer', defineAsyncComponent(() => import('@mobile/views/order/position/components/pricing/detail2/components/transfer/Index.vue'))]
+    ['transfer', defineAsyncComponent(() => import('@mobile/views/order/position/components/pricing/detail2/components/transfer/Index.vue'))],
 ])
 
 // // const sl = shallowRef(false) // 止损

+ 5 - 4
src/packages/mobile/views/pricing/trade/holdlb2/Index.vue

@@ -57,8 +57,9 @@
                         </li> -->
                     </ul>
                 </div>
-                <div class="g-order-list__btnbar" v-if="enableqty(item) != 0">
-                    <Button size="small" @click="callBack(item)" round>{{ $t('operation.close') }}</Button>
+                <div class="g-order-list__btnbar">
+                    <Button v-if="enableqty(item) != 0" size="small" @click="callBack(item, 'close')" round>{{ $t('operation.close') }}</Button>
+                    <Button size="small" @click="callBack(item, 'delivery')" round>{{ $t('operation.delivery') }}</Button>
                 </div>
             </div>
         </div>
@@ -94,8 +95,8 @@ const dataList = computed(() => {
 const pullRefreshRef = shallowRef()
 
 const emit = defineEmits(['callBack'])
-const callBack = (item: Model.SBYJMyOrderRsp) => {
-    emit('callBack', 2, item.tHDetailEx.buyOrSell, item.tHDetailEx.tradeID, item)
+const callBack = (item: Model.SBYJMyOrderRsp, ids: string) => {
+    emit('callBack', ids === 'close' ? 2 : 3, item.tHDetailEx.buyOrSell, item.tHDetailEx.tradeID, item)
 }
 
 // 可用重量

+ 33 - 17
src/packages/mobile/views/pricing/trade/v2/Index.vue

@@ -1,7 +1,11 @@
 <template>
     <app-view class="pricing-trade">
         <template #header>
-            <app-navbar :title="quote ? `${quote.goodscode}` : $t('quote.pricing.title')" >
+            <app-navbar>
+                <app-select v-model="goodsCode" :options="goodsList" :optionProps="{ label: 'goodscode', value: 'goodscode' }" @confirm="onConfirm" >
+                    {{ quote ? `${quote.goodscode}` : $t('quote.pricing.title') }}
+                    <Icon name="arrow-down" size="16" style="padding-left: 5px;" />
+                </app-select>
                 <template #right>
                     <Icon v-if="system_1012 != '0'" name="bars" size="20px" @click="openComponent('detail')" />
                 </template>
@@ -97,28 +101,31 @@ import { fullloading, dialog } from '@/utils/vant'
 import { formatDecimal, handleNumberValue } from '@/filters'
 import Stepper from '@mobile/components/base/stepper/index.vue'
 import eventBus from '@/services/bus'
+import AppSelect from '@mobile/components/base/select/index.vue'
 
 const { getQueryString, getQueryStringToNumber } = useNavigation()
 const { global: { t } } = i18n
 
-const goodsCode = getQueryString('goodscode') ?? ''
-const goodsid = getQueryStringToNumber('goodsid')
+const goodsCode = shallowRef(getQueryString('goodscode') ?? '')
+const goodsid = shallowRef(getQueryStringToNumber('goodsid'))
 const buyOrSell = getQueryStringToNumber('buyOrSell')
 const buildType = getQueryStringToNumber('buildType')
 const orderQty = getQueryStringToNumber('orderQty')
 const futuresStore = useFuturesStore()
-const quote = futuresStore.getGoodsQuote(goodsCode)
-const { pictureurl } = futuresStore.getGoods(goodsCode) ?? {}
+const quote = shallowRef<Model.GoodsQuote>()
 // 小数位以及步进值
 const { decimalplace = 0.0 } = quote.value ?? {}
 const quoteminunit = quote.value?.quoteminunit ?? 1.0
 const decimalvalue = Math.pow(10.0, -decimalplace)*(quoteminunit == 0 ? 1 : quoteminunit)
 const isTrademode16 = computed(() => quote.value?.trademode === 16)
-
-const selectedRow = shallowRef<Model.SBYJMyOrderRsp>()
-
 const { getSystemParamValue } = useUserStore()
 const system_1012 = getSystemParamValue('1012') ?? '1'
+// 选中的单据数据
+const selectedRow = shallowRef<Model.SBYJMyOrderRsp>()
+
+const pictureurl = computed(() => {
+    return futuresStore.getGoods(goodsCode.value)?.pictureurl ?? {}
+})
 
 const { formData, formSubmit } = useOrder()
 const formRef = shallowRef<FormInstance>()
@@ -133,26 +140,33 @@ const fromTrade = true
 // 持仓汇总
 const position = shallowRef<Model.TradePositionRsp[]>([]) 
 
+const goodsList = computed(() => {
+    return futuresStore.getGoodsListByTradeMode(10)
+})
+
+const onConfirm = (() => {
+    selectedRow.value = undefined
+    quote.value = futuresStore.getGoodsQuote(goodsCode.value).value
+    goodsid.value = quote.value?.goodsid ?? 0
+})
+
 // 点击返回
 const itemBack = (isPosition: number, buyorsell: BuyOrSell, tradeId: string, item: Model.SBYJMyOrderRsp) => {
     formData.BuyOrSell = buyorsell === BuyOrSell.Buy ? BuyOrSell.Sell : BuyOrSell.Buy
-    if (isPosition === 2) { 
-        selectedRow.value = item
-        // 打开退订
-        openComponent('transfer')
-    }
+    selectedRow.value = item
+    // 打开退订
+    openComponent(isPosition === 2 ? 'transfer' : 'delivery')
 }
 
+const active = shallowRef(pictureurl.value != '' ? 'images' : 'cancel')
 const { componentRef, componentId, openComponent, closeComponent } = useComponent()
 
-const active = shallowRef(pictureurl != '' ? 'images' : 'cancel')
-
 const components = [
     {
         name: 'images',
         title: t('operation.details'),
         component: defineAsyncComponent(() => import('../images/Index.vue')),
-        show: pictureurl != ''
+        show: pictureurl.value != ''
     },
     {
         name: 'cancel',
@@ -177,7 +191,8 @@ const components = [
     
 const componentMap = new Map<string, unknown>([
     ['detail', defineAsyncComponent(() => import('../components/detail/Index.vue'))],
-    ['transfer', defineAsyncComponent(() => import('@mobile/views/order/position/components/pricing/detail2/components/transfer/Index.vue'))]
+    ['transfer', defineAsyncComponent(() => import('@mobile/views/order/position/components/pricing/detail2/components/transfer/Index.vue'))],
+    ['delivery', defineAsyncComponent(() => import('@mobile/views/order/position/components/pricing/detail2/components/delivery/Index.vue'))]
 ])
 
 // 计算市价
@@ -268,6 +283,7 @@ const onRadioChange = (value: number) => {
 }
 
  onMounted(() => {
+    quote.value = futuresStore.getGoodsQuote(goodsCode.value).value
     formData.BuyOrSell = BuyOrSell.Buy
     formData.BuildType = BuildType.Open
     formData.PriceMode = PriceMode.Market

+ 0 - 27
src/packages/mobile/views/pricing/trade/v2/index.css

@@ -1,27 +0,0 @@
-.pricing-trade__form {
-  background-color: #fff;
-  border-radius: 8px;
-  margin: 15px 15px 0px 15px;
-  margin-bottom: 0;
-}
-.pricing-trade__form .form-buyorsell {
-  margin: 5px 8px;
-}
-.pricing-trade__form .form-price {
-  display: flex;
-  padding: 16px 0;
-}
-.pricing-trade__form .form-price dl {
-  flex: 1;
-  text-align: center;
-}
-.pricing-trade__form .form-price dl dt {
-  margin-bottom: 5px;
-}
-.pricing-trade__form .form-price dl dd {
-  font-size: 28px;
-  font-weight: bold;
-}
-.pricing-trade .g-form__footer {
-  margin-bottom: 10px;
-}

+ 14 - 6
src/packages/tss/views/home/main/index.vue

@@ -15,16 +15,16 @@
       <app-block class="home-main__iconbar">
         <ul>
           <li @click="$router.push({ name: 'product' })">
-            <Iconfont label-direction="bottom" icon="g-icon-swap--line">产品</Iconfont>
+            <Iconfont label-direction="bottom" icon="g-icon-swap--line">{{ $t('home.product') }}</Iconfont>
           </li>
           <li @click="$router.push({ name: 'pricing-list' })">
-            <Iconfont label-direction="bottom" icon="g-icon-spot--line">价格</Iconfont>
+            <Iconfont label-direction="bottom" icon="g-icon-spot--line">{{ $t('home.pricing') }}</Iconfont>
           </li>
           <li @click="$router.push({ name: 'pricing-trade', query: {} })">
-            <Iconfont label-direction="bottom" icon="g-icon-pickup--line">预定</Iconfont>
+            <Iconfont label-direction="bottom" icon="g-icon-pickup--line">{{ $t('home.pickup') }}</Iconfont>
           </li>
-          <li @click="$router.push({ name: 'pricing-trade', query: {} })">
-            <Iconfont label-direction="bottom" icon="g-icon-pricing--line">交收</Iconfont>
+          <li @click="openComponent('detail2')">
+            <Iconfont label-direction="bottom" icon="g-icon-pricing--line">{{ $t('home.delivery') }}</Iconfont>
           </li>
         </ul>
       </app-block>
@@ -44,16 +44,18 @@
         <ProductList />
       </app-block>
     </PullRefresh>
+    <component ref="componentRef" :is="componentMap.get(componentId)" v-bind="{ onlyDelivery }" @closed="closeComponent" v-if="componentId" />
   </app-view>
 </template>
 
 <script lang="ts" setup>
-import { shallowRef } from 'vue'
+import { shallowRef, defineAsyncComponent } from 'vue'
 import { Cell, CellGroup, PullRefresh, Badge } from 'vant'
 import { formatDate } from "@/filters"
 import { queryImageConfigs } from "@/services/api/common"
 import { queryNewTitles } from "@/services/api/news"
 import { useLoginStore, useNoticeStore, useGlobalStore } from '@/stores'
+import { useComponent } from '@/hooks/component'
 import Banner from '@mobile/components/base/banner/index.vue'
 import Iconfont from '@/components/base/iconfont/index.vue'
 import ProductList from '../../product/list/index.vue'
@@ -65,6 +67,12 @@ const refreshing = shallowRef(false) // 是否处于加载中状态
 const topBanners = shallowRef<string[]>([]); // 轮播图列表
 const newsList = shallowRef<Model.NewTitlesRsp[]>([]) // 资讯列表
 
+const onlyDelivery = shallowRef(true)
+const componentMap = new Map<string, unknown>([
+    ['detail2', defineAsyncComponent(() => import('@mobile/views/order/position/components/pricing/detail2/Index.vue'))]
+])
+const { componentRef, componentId, openComponent, closeComponent } = useComponent()
+
 // 下拉刷新
 const onRefresh = () => {
   if (!topBanners.value.length) {