li.shaoyi hai 1 ano
pai
achega
ac6eefdec7

+ 2 - 1
src/business/login/index.ts

@@ -2,7 +2,7 @@ import { shallowRef, reactive } from 'vue'
 import { v4 } from 'uuid'
 import { timerTask } from '@/utils/timer'
 import { wsLogin, httpLogin, queryLoginId } from '@/services/api/account'
-import { useGlobalStore, useLoginStore, useEnumStore, useErrorInfoStore, useUserStore, useFuturesStore, useAccountStore,useDeliveryRelationStore } from '@/stores'
+import { useGlobalStore, useLoginStore, useEnumStore, useErrorInfoStore, useUserStore, useFuturesStore, useAccountStore, useDeliveryRelationStore } from '@/stores'
 import service from '@/services'
 import quoteSocket from '@/services/websocket/quote'
 import tradeSocket from '@/services/websocket/trade'
@@ -41,6 +41,7 @@ export function useLogin(persist = false) {
         await Promise.all([
             errorInfoStore.getErrorInfoList(),
             enumStore.getAllEnumList(),
+            userStore.getSystemParams()
         ])
     }
 

+ 21 - 7
src/packages/mobile/components/layouts/login/index.vue

@@ -36,10 +36,14 @@
       <div class="login-footer__trem">
         <Checkbox shape="square" icon-size="16px" v-model="checked">{{ $t('user.login.checked') }}</Checkbox>
         <span @click="routerTo('rules-zcxy')">{{ $t('user.login.ruleszcxy') }}</span>
-        <span>、</span>
-        <span @click="routerTo('rules-yhkhfxgzs')" v-if="showYhkhfxgzs">{{ $t('user.login.rulesyhkhfxgzs') }}</span>
-        <span v-if="showYhkhfxgzs">、</span>
-        <span @click="routerTo('rules-yszc')">{{ $t('user.login.rulesyszc') }}</span>
+        <template v-if="showYhkhfxgzs">
+          <span>、</span>
+          <span @click="routerTo('rules-yhkhfxgzs')">{{ $t('user.login.rulesyhkhfxgzs') }}</span>
+        </template>
+        <template v-if="showYszc">
+          <span>、</span>
+          <span @click="routerTo('rules-yszc')">{{ $t('user.login.rulesyszc') }}</span>
+        </template>
       </div>
       <div class="login-footer__version">
         <span>v1.0.{{ appVersion }}</span>
@@ -60,7 +64,7 @@ import SliderVerify from '@/components/base/slider-verify/index.vue' // 临时
 import logoImage from '../../../assets/images/login-logo.png'
 import AppLuanguage from '@mobile/components/modules/luanguage/index.vue'
 
-defineProps({
+const props = defineProps({
   logoSrc: {
     type: String,
     default: logoImage
@@ -68,12 +72,20 @@ defineProps({
   showYhkhfxgzs: {
     type: Boolean,
     default: true
+  },
+  showYszc: {
+    type: Boolean,
+    default: true
+  },
+  showReport: {
+    type: Boolean,
+    default: true
   }
 })
 
 const { global: { t } } = i18n
 const globalStore = useGlobalStore()
-const { setGlobalUrlParams, routerTo } = useNavigation()
+const { setGlobalUrlParams, routerTo, routerBack } = useNavigation()
 const { formData, userLogin } = useLogin()
 const checked = shallowRef(false) // 是否同意协议管理
 const showSliderVerify = shallowRef(true) // 验证滑块组件重载
@@ -114,8 +126,10 @@ const formSubmit = () => {
               setGlobalUrlParams({ forcedPasswordChange })
               routerTo('user-password', true)
             })
-          } else {
+          } else if (props.showReport) {
             routerTo('report', true)
+          } else {
+            routerBack()
           }
         }).catch((err) => {
           showSliderVerify.value = false

+ 38 - 22
src/packages/mobile/views/user/register/Index.vue

@@ -5,10 +5,10 @@
     </template>
     <Form ref="formRef" class="g-form__container register__form" @submit="formSubmit">
       <CellGroup inset>
-        <Field v-model="formData.mobilephone" type="tel" name="mobilephone" :label="$t('user.register.mobile')" :placeholder="$t('common.required')"
-          :rules="formRules.mobilephone" />
-        <Field v-model="formData.vcode" type="digit" name="vcode" :label="$t('user.register.vcode')" :placeholder="$t('common.required')"
-          :rules="formRules.vcode">
+        <Field v-model="formData.mobilephone" type="tel" name="mobilephone" :label="$t('user.register.mobile')"
+          :placeholder="$t('common.required')" :rules="formRules.mobilephone" />
+        <Field v-model="formData.vcode" type="digit" name="vcode" :label="$t('user.register.vcode')"
+          :placeholder="$t('common.required')" :rules="formRules.vcode">
           <template #button>
             <Button size="small" type="danger" :disabled="isCountdown" @click="sendVerifyCode">
               <span v-if="isCountdown">{{ $t('user.register.sendagain') }}({{ currentTime.seconds }})</span>
@@ -18,11 +18,12 @@
         </Field>
       </CellGroup>
       <CellGroup inset>
-        <Field v-model="formData.loginpwd" name="loginpwd" type="password" :label="$t('user.register.logipwd')" :placeholder="$t('common.required')"
-          :rules="formRules.loginpwd" />
-        <Field v-model="confirmpassword" name="confirmpassword" type="password" :label="$t('user.register.confirmpwd')" :placeholder="$t('common.required')"
-          :rules="formRules.confirmpassword" />
-        <Field v-model="formData.refernum" name="refernum" :label="$t('user.register.registercode')" :placeholder="registrationCodeRule ? $t('common.required') : $t('common.optional')"
+        <Field v-model="formData.loginpwd" name="loginpwd" type="password" :label="$t('user.register.logipwd')"
+          :placeholder="$t('common.required')" :rules="formRules.loginpwd" />
+        <Field v-model="confirmpassword" name="confirmpassword" type="password" :label="$t('user.register.confirmpwd')"
+          :placeholder="$t('common.required')" :rules="formRules.confirmpassword" />
+        <Field v-model="formData.refernum" name="refernum" :label="$t('user.register.registercode')"
+          :placeholder="registrationCodeRule ? $t('common.required') : $t('common.optional')"
           :rules="formRules.refernum" v-if="registrationCodeRule > -1">
           <!-- <template #button>
             <app-qrcode-scan @success="onScanSuccess">
@@ -35,9 +36,15 @@
         <Cell>
           <template #title>
             <div style="display: flex;align-items: center;font-size: 12px;">
-              <Checkbox shape="square" icon-size="16px" v-model="checked">{{ $t('user.register.checked') }}</Checkbox>
-              <span @click="routerTo('rules-zcxy')" style="color:#E92020">{{ $t('user.register.ruleszcxy') }}</span>
-              <span @click="routerTo('rules-yhkhfxgzs')" style="color:#E92020">{{ $t('user.register.rulesfxgzs') }}</span>
+              <Checkbox shape="square" icon-size="16px" v-model="checked">
+                {{ $t('user.register.checked') }}
+              </Checkbox>
+              <span @click="routerTo('rules-zcxy')" style="color:#E92020">
+                {{ $t('user.register.ruleszcxy') }}
+              </span>
+              <span @click="routerTo('rules-yhkhfxgzs')" style="color:#E92020" v-if="showYhkhfxgzs">
+                {{ $t('user.register.rulesfxgzs') }}
+              </span>
             </div>
           </template>
         </Cell>
@@ -47,13 +54,14 @@
       <div class="g-form__footer inset">
         <Button type="danger" @click="formRef?.submit" round block>{{ $t('user.register.freeregister') }}</Button>
       </div>
-      <app-reward :show="showReward" :value="redEnvelope" :title="$t('user.register.registersuccess')" @click="router.back()" />
+      <app-reward :show="showReward" :value="redEnvelope" :title="$t('user.register.registersuccess')"
+        @click="router.back()" />
     </template>
   </app-view>
 </template>
 
 <script lang="ts" setup>
-import { reactive, ref, computed, onMounted, shallowRef } from 'vue'
+import { reactive, ref, computed, onMounted } from 'vue'
 import { CellGroup, Cell, Button, Field, Form, FormInstance, Checkbox, showFailToast, showToast, FieldRule } from 'vant'
 import { useCountDown } from '@vant/use'
 import { fullloading, dialog } from '@/utils/vant'
@@ -66,6 +74,13 @@ import plus from '@/utils/h5plus'
 import AppReward from '@mobile/components/modules/reward/index.vue'
 // import AppQrcodeScan from '@mobile/components/base/qrcode-scan/index.vue'
 
+defineProps({
+  showYhkhfxgzs: {
+    type: Boolean,
+    default: true
+  }
+})
+
 const { router, routerTo } = useNavigation()
 const globalStore = useGlobalStore()
 const registrationCodeRule = globalStore.getSystemInfo('registrationCodeRule')
@@ -76,7 +91,8 @@ const showReward = ref(false) // 显示红包
 const redEnvelope = ref(0) // 红包金额
 
 const { getSystemParamValue } = useUserStore()
-const system_1010 = shallowRef(getSystemParamValue('1010') ?? '1')
+const param1010 = getSystemParamValue('1010') ?? '1'
+const param1013 = getSystemParamValue('1013') ?? '30'
 
 const { global: { t } } = i18n
 
@@ -84,7 +100,7 @@ const confirmpassword = ref('') // 确认密码
 
 // 倒计时函数
 const countdown = useCountDown({
-  time: 30 * 1000,
+  time: +param1013 * 1000,
   onFinish: () => {
     countdown.reset()
     isCountdown.value = false
@@ -114,17 +130,17 @@ const formRules: { [key: string]: FieldRule[] } = {
     message: t('user.register.tips1'),
     validator: (val) => {
       /// 值为”0“ 时 只校验长度20位,不限字符
-      if (system_1010.value === '0') {
-          if (val.length <= 20) {
-              return true
-          }
-          return t('banksign.tips6')
+      if (param1010 === '0') {
+        if (val.length <= 20) {
+          return true
+        }
+        return t('banksign.tips6')
       } else {
         if (validateRules.phone.validate(val)) {
           return true
         }
         return validateRules.phone.message
-      } 
+      }
     }
   }],
   loginpwd: [{

+ 3 - 0
src/packages/tss/router/index.ts

@@ -90,6 +90,9 @@ const routes: Array<RouteRecordRaw> = [
         meta: {
           ignoreAuth: true,
         },
+        props: {
+          showYhkhfxgzs: false
+        }
       },
       {
         path: 'forget',

+ 124 - 31
src/packages/tss/views/order/position/Index.vue

@@ -2,45 +2,138 @@
     <app-view>
         <template #header>
             <app-navbar :title="$t('position.title')">
-                <template #right v-if="selectedComponent.detail">
-                    <div class="button-more" @click="openComponent(selectedComponent.name)">
-                        <span>{{ $t('position.holddetail') }}</span>
-                    </div>
-                </template>
+                <!-- <template #footer>
+                    <Tabs>
+                        <Tab title="全款订单" :name="1" />
+                        <Tab title="预付款订单" :name="2" />
+                    </Tabs>
+                </template> -->
             </app-navbar>
         </template>
-        <Tabs class="van-tabs--list" v-model:active="active" :swipe-threshold="4">
-            <template v-for="(item, index) in components" :key="index">
-                <Tab :title="item.title" :name="index">
-                    <component :is="item.component" />
-                </Tab>
-            </template>
-        </Tabs>
-        <component ref="componentRef" :is="selectedComponent.detail" @closed="closeComponent" v-bind="{ onlyDelivery }"
-            v-if="componentId && selectedComponent.detail" />
+        <app-pull-refresh ref="pullRefreshRef" v-model:loading="loading" v-model:error="error"
+            @refresh="getSBYJMyOrders">
+            <div class="order-list">
+                <div class="order-list__box" v-for="(item, index) in orderComputedList" :key="index">
+                    <div class="order-list__titlebar">
+                        <div class="left">
+                            <b>订单号:{{ item.tHDetailEx.tradeID }}</b>
+                        </div>
+                        <div class="right">
+                            <b :class="!item.tHDetailEx.buyOrSell ? 'g-price-up' : 'g-price-down'">
+                                {{ getBuyOrSellName(item.tHDetailEx.buyOrSell) }}
+                            </b>
+                        </div>
+                    </div>
+                    <div class="order-list__content">
+                        <div class="left">
+                            <Image width="100" height="100" radius="4" :src="getImageUrl(item.thumurls)" />
+                        </div>
+                        <div class="right">
+                            <ul>
+                                <li>
+                                    <span>商品代码:</span>
+                                    <span>{{ item.goodsCode }}</span>
+                                </li>
+                                <li>
+                                    <span>{{ $t('position.goods.holddetail.holderqty') }}:</span>
+                                    <span>{{ enableqty(item) + getGoodsUnitName(item.goodsUnitID) }}</span>
+                                </li>
+                                <!-- <li>
+                                    <span>{{ $t('position.goods.holddetail.freezeqty') }}</span>
+                                    <span>{{ item.tHDetailEx.freezeQty }}</span>
+                                </li> -->
+                                <li>
+                                    <span>{{ $t('position.goods.holddetail.holderprice') }}:</span>
+                                    <span>{{ formatDecimal(item.tHDetailEx.holderPrice, item.decimalPlace) }}</span>
+                                </li>
+                                <li>
+                                    <span>{{ $t('position.goods.holddetail.holderamount') }}:</span>
+                                    <span>{{ formatDecimal(item.tHDetailEx.holderAmount, item.decimalPlace) }}</span>
+                                </li>
+                                <li>
+                                    <span>{{ $t('position.goods.holddetail.usedMargin') }}:</span>
+                                    <span>{{ formatDecimal(item.tHDetailEx.payedDeposit +
+                                        item.tHDetailEx.restockDeposit,
+                                        item.decimalPlace) }}</span>
+                                </li>
+                                <!-- <li>
+                                    <span>{{ $t('position.goods.holddetail.profitLoss') }}</span>
+                                    <span :class="handlePriceColor(item.tHDetailEx.floatPL)">
+                                        {{ formatDecimal(item.tHDetailEx.floatPL) }}
+                                    </span>
+                                </li> -->
+                                <!-- <li>
+                                    <span>{{ $t('position.goods.holddetail.riskRate') }}</span>
+                                    <span :class="item.tHDetailEx.depositRate >= item.tHDetailEx.promptDepositRate ? 'g-price-up' : ''">
+                                        {{ parsePercent(item.tHDetailEx.riskRate) }}
+                                    </span>
+                                </li> -->
+                                <li>
+                                    <span>{{ $t('position.goods.holddetail.tradetime') }}:</span>
+                                    <span>{{ formatDate(item.tHDetailEx.tradeTime) }}</span>
+                                </li>
+                            </ul>
+                        </div>
+                    </div>
+                    <div class="order-list__btnbar" v-if="item.tHDetailEx.holderQty">
+                        <Button size="small" v-if="enableqty(item)" @click="showComponent('close', item)" round>
+                            {{ $t('operation.close') }}
+                        </Button>
+                        <Button size="small" @click="showComponent('delivery', item)" round>
+                            {{ $t('operation.delivery') }}
+                        </Button>
+                    </div>
+                </div>
+            </div>
+        </app-pull-refresh>
+        <component ref="componentRef" v-bind="{ selectedRow }" :is="componentMap.get(componentId)"
+            @closed="closeComponent" v-if="componentId" />
     </app-view>
 </template>
 
 <script lang="ts" setup>
-import { shallowRef, computed, defineAsyncComponent } from 'vue'
-import { Tab, Tabs } from 'vant'
+import { shallowRef, defineAsyncComponent } from 'vue'
+import { Tabs, Tab, Button, Image } from 'vant'
+import { getFileUrl } from '@/filters'
 import { useComponent } from '@/hooks/component'
-import { i18n } from '@/stores'
+import { getBuyOrSellName } from '@/constants/order'
+import { formatDecimal, formatDate } from '@/filters'
+import { getGoodsUnitName } from '@/constants/unit'
+import { useSBYJOrderStore } from '@/stores'
+import AppPullRefresh from '@mobile/components/base/pull-refresh/index.vue'
+
+const { getSBYJMyOrders, $toRefs } = useSBYJOrderStore()
+const { orderComputedList, loading, error } = $toRefs()
+
+const componentMap = new Map<string, unknown>([
+    ['close', 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'))],
+])
+
+const selectedRow = shallowRef<Model.SBYJMyOrderRsp>()
+const pullRefreshRef = shallowRef()
+
+const { componentRef, componentId, openComponent, closeComponent } = useComponent(() => {
+    pullRefreshRef.value?.refresh()
+})
 
-const { global: { t } } = i18n
+const showComponent = (componentName: string, row: Model.SBYJMyOrderRsp) => {
+    selectedRow.value = row
+    openComponent(componentName)
+}
 
-const onlyDelivery = shallowRef(false)
+// 可用重量
+const enableqty = (item: Model.SBYJMyOrderRsp) => {
+    const { tHDetailEx, agreeUnit } = item
+    return (tHDetailEx.holderQty - tHDetailEx.freezeQty) * agreeUnit
+}
 
-const components = [
-    {
-        name: 'pricing',
-        title: t('position.pricing.title'),
-        component: defineAsyncComponent(() => import('@mobile/views/order/position/components/pricing/list/Index.vue')),
-        detail: defineAsyncComponent(() => import('@mobile/views/order/position/components/pricing/detail2/Index.vue')),
-    },
-]
+const getImageUrl = (url: string) => {
+    const [firstImg] = url.split(',')
+    return firstImg ? getFileUrl(firstImg) : ''
+}
+</script>
 
-const active = shallowRef(0)
-const selectedComponent = computed(() => components[active.value])
-const { componentRef, componentId, openComponent, closeComponent } = useComponent()
-</script>
+<style lang="less">
+@import './index.less';
+</style>

+ 48 - 0
src/packages/tss/views/order/position/index.less

@@ -0,0 +1,48 @@
+.order-list {
+    padding: 10px;
+    padding-bottom: 0;
+
+    &__box {
+        &:not(:first-child) {
+            margin-top: 12px;
+        }
+
+        background-color: #fff;
+        border-radius: 8px;
+        padding: 16px;
+    }
+
+    &__titlebar {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        margin-bottom: 12px;
+    }
+
+    &__content {
+        display: flex;
+
+        .left {
+            margin-right: 12px;
+        }
+
+        .right {
+            flex: 1;
+            font-size: 13px;
+            line-height: 1.6;
+            color: #777;
+        }
+    }
+
+    &__btnbar {
+        display: flex;
+        justify-content: flex-end;
+        gap: 8px;
+        margin-top: 10px;
+
+        .van-button {
+            width: 80px;
+            border-width: 1px;
+        }
+    }
+}

+ 1 - 1
src/packages/tss/views/product/list/index.vue

@@ -15,7 +15,7 @@
 <script lang="ts" setup>
 import { computed } from 'vue'
 import { Image } from 'vant'
-import { getFileUrl } from "@/filters"
+import { getFileUrl } from '@/filters'
 import { useUserStore } from '@/stores'
 
 const userStore = useUserStore()

+ 16 - 3
src/packages/tss/views/user/login/Index.vue

@@ -1,15 +1,28 @@
 <template>
-  <AppLogin :logo-src="logoImage" />
+  <AppLogin :logo-src="logoImage" :show-yhkhfxgzs="false" :show-yszc="false" :show-report="false" />
 </template>
 
 <script lang="ts" setup>
 import { onMounted, onUnmounted } from 'vue'
+import { dialog } from '@/utils/vant'
+import { i18n } from '@/stores'
 import plus from '@/utils/h5plus'
 import AppLogin from '@mobile/components/layouts/login/index.vue'
 import logoImage from '../../../assets/images/login-logo.png'
 
-onMounted(() => plus.setStatusBarStyle('dark'))
-onUnmounted(() => plus.setStatusBarStyle('light'))
+const { t } = i18n.global
+
+onMounted(() => {
+  plus.setStatusBarStyle('dark')
+})
+
+onUnmounted(() => {
+  plus.setStatusBarStyle('light')
+
+  setTimeout(() => {
+    dialog({ message: t('user.login.tips7'), confirmButtonText: t('operation.confirm') })
+  }, 500)
+})
 </script>
 
 <style lang="less">

+ 10 - 0
src/services/api/common/index.ts

@@ -290,4 +290,14 @@ export function getDivisions(config: RequestConfig = {}) {
         url: '/Common/GetDivisions',
         params: config.data,
     })
+}
+
+/**
+ * 获取系统参数信息
+ */
+export function fetchSystemParams(config: RequestConfig = {}) {
+    return http.commonRequest<Model.SystemParam[]>({
+        url: '/Common/GetSystemParams',
+        params: config.data,
+    })
 }

+ 18 - 0
src/services/worker/index.ts

@@ -0,0 +1,18 @@
+const workerUrl = new URL('./quote.js', import.meta.url).toString();
+
+// 创建Web Worker实例  
+const worker = new Worker(workerUrl);  
+  
+// 监听来自Worker的消息  
+worker.onmessage = (event: MessageEvent) => {  
+  console.log('接收工作线程消息:', event.data);  
+};  
+  
+// 监听来自Worker的错误  
+worker.onerror = (error: ErrorEvent) => {  
+  console.error('Error from worker:', error.message);  
+};  
+  
+// 发送WebSocket URL给Worker  
+const websocketUrl = 'wss://your-websocket-server-url';  
+worker.postMessage({ type: 'connect', url: websocketUrl });

+ 15 - 0
src/services/worker/quote.js

@@ -0,0 +1,15 @@
+// 监听来自主线程的消息
+self.onmessage = (e) => {
+    console.log('接收主线程消息', e.data);
+
+    // 处理数据(这里只是简单地将数据返回)  
+    const result = e.data.url.split('').reverse().join('');
+
+    // 将结果发送回主线程  
+    self.postMessage(result);
+}
+
+// 错误处理
+self.onerror = (error) => {
+    console.error('Worker error:', error);
+}

+ 14 - 3
src/stores/modules/user.ts

@@ -1,5 +1,6 @@
 import { reactive, computed, toRefs } from 'vue'
 import { getFileUrl } from '@/filters'
+import { fetchSystemParams } from '@/services/api/common'
 import { queryLoginData } from '@/services/api/account'
 import { useLoginStore } from './login'
 import { defineStore } from '../store'
@@ -22,11 +23,11 @@ export const useUserStore = defineStore(() => {
             goodsgroups: [],
             loginAccount: {},
             markets: [],
-            systemParams: [],
             userAccount: {},
             userInfo: {},
             username: '',
         }),
+        systemParams: <Model.SystemParam[]>[]
     })
 
     // 用户信息
@@ -71,6 +72,15 @@ export const useUserStore = defineStore(() => {
         return userAccount?.memberuserid ?? 0
     })
 
+    // 获取系统参数
+    const getSystemParams = async () => {
+        if (!state.systemParams.length) {
+            const res = await fetchSystemParams()
+            state.systemParams = res.data
+        }
+        return Promise.resolve()
+    }
+
     // 获取用户数据
     const getUserData = async () => {
         try {
@@ -93,7 +103,7 @@ export const useUserStore = defineStore(() => {
     }
 
     // 获取市场名称
-    const getMarketName = ( marketid: number) => {
+    const getMarketName = (marketid: number) => {
         const { marketname } = state.userData.markets.find(obj => obj.marketid === marketid) ?? {}
         return marketname ?? ''
     }
@@ -110,7 +120,7 @@ export const useUserStore = defineStore(() => {
 
     // 获取对应系统参数的对应值
     const getSystemParamValue = (paramcode: string) => {
-        const { systemParams } = state.userData
+        const { systemParams = state.systemParams } = state.userData
         return systemParams.find(obj => {
             return obj.paramcode === paramcode
         })?.paramvalue
@@ -131,6 +141,7 @@ export const useUserStore = defineStore(() => {
         memberUserId,
         getUserData,
         getUserDataInfo,
+        getSystemParams,
         getSystemParamValue,
         userChangeNtf,
         getMarketId,

+ 1 - 0
src/types/model/order.d.ts

@@ -1576,6 +1576,7 @@ declare namespace Model {
         quoteMinUnit: number;
         /// 单位名称
         goodsUnit: string;
+        thumurls: string; // 缩略图片(1:1)(逗号分隔)
     }
 
     /* 查询我的交收 请求*/