Pārlūkot izejas kodu

商品合约 合约汇总 添加 按单平仓

huangbin 4 gadi atpakaļ
vecāks
revīzija
28dbd021fd

+ 380 - 0
src/views/order/commodity_contract/components/commodity_contract_summary/components/commodity_contract_summary_order_closed/index.vue

@@ -0,0 +1,380 @@
+<template>
+  <!-- 按单平仓-->
+  <Drawer :title="'按单平仓'"
+          :placement="'right'"
+          class="bottom486"
+          :visible="visible"
+          @cancel="cancel">
+    <div class="listed c_c_s_s">
+      <a-form class="inlineForm dialogForm"
+              ref="formRef"
+              :model="formState"
+              :rules="rules">
+        <div class="formBar">
+          <div class="formtop">
+            <div class="firstTitle">
+              <span>合约:{{selectedRow.goodscode}}/{{selectedRow.goodsname}}</span>
+            </div>
+            <div class="secondLine">
+              <div class="left">持仓单号/方向</div>
+              <div class="middle">数量/价格/金额</div>
+              <div class="right">到期日/盈亏</div>
+            </div>
+            <a-checkbox-group class="commonCheckboxGroup"
+                              v-model:value="checked"
+                              @change="checkGroupChange">
+              <div class="lineBar"
+                   v-for="item in tableList"
+                   :key="item.tradeid">
+                <div class="line1">
+                  <div class>
+                    <a-checkbox @change="checkboxChange(item)"
+                                :value="item.tradeid"></a-checkbox>
+                  </div>
+                  <div class="name">{{item.tradeid}}</div>
+                  <div class="date">{{formatTime(item.tradetime, 'd')}}</div>
+                </div>
+                <div class="line2">
+                  <div class="left">{{item.buyorsell === BuyOrSell.buy ? '买入' : '卖出'}}</div>
+                  <div class="middle">
+                    <div>{{item.holderqty}}</div>
+                    <div>{{item.holderprice}}</div>
+                    <div>{{item.holderamount}}</div>
+                  </div>
+                  <div class="right red">+100</div>
+                </div>
+              </div>
+            </a-checkbox-group>
+          </div>
+        </div>
+        <div class="fixedBtns">
+          <a-row :gutter="24">
+            <a-col :span="24"
+                   class="mt12">
+              <a-form-item label="估算价"
+                           name="price"
+                           class="inputIconBox mb10 not-copy">
+                <a-input-number class="commonInput not-copy"
+                                v-model:value="formState.price"
+                                style="width: 200px"
+                                :min="0" />
+                <MinusOutlined @click="decreasePrice" />
+                <PlusOutlined @click="increasePirce" />
+              </a-form-item>
+            </a-col>
+            <a-col :span="24">
+              <a-form-item label="估算金额"
+                           class="mb10 not-copy ">
+                <span class="white">50400.20</span>
+              </a-form-item>
+            </a-col>
+          </a-row>
+          <a-form-item class="btnCenter mt10">
+            <a-button class="listedBtn"
+                      :loading="loading"
+                      :disabled="loading"
+                      @click="submit">提交</a-button>
+            <a-button class="ml10 cancelBtn"
+                      @click="cancel">取消</a-button>
+          </a-form-item>
+        </div>
+      </a-form>
+    </div>
+  </Drawer>
+</template>
+
+<script lang="ts">
+import Drawer from '@/common/components/drawer/index.vue';
+import UploadImg from '@/common/components/uploadImg/index.vue';
+import { BuyOrSell } from '@/common/constants/enumCommon';
+import { ModalEnum } from '@/common/constants/modalNameEnum';
+import { requestResultLoadingAndInfo } from '@/common/methods/request/resultInfo';
+import { validateAction } from '@/common/setup/form';
+import { _closeModal } from '@/common/setup/modal/modal';
+import { queryTableList } from '@/common/setup/table';
+import { getUserId } from '@/services/bus/account';
+import { geLoginID_number } from '@/services/bus/login';
+import { QueryTradePositionRsp } from '@/services/go/ermcp/order/interface';
+import { queryTradeHolderDetail } from '@/services/go/order';
+import { QueryTradeHolderDetailReq } from '@/services/go/order/interface';
+import { tradeHoldTransferApply } from '@/services/proto/warehousetrade';
+import { TradeHoldTransferApplyReq } from '@/services/proto/warehousetrade/interface';
+import { MinusOutlined, PlusOutlined } from '@ant-design/icons-vue';
+import { message } from 'ant-design-vue';
+import Long from 'long';
+import { defineComponent, PropType } from 'vue';
+import { BargainList, FormState } from './interface';
+import { handleForm, useCheckd, usePrice } from './setup';
+import { formatTime } from '@/common/methods';
+
+export default defineComponent({
+    name: ModalEnum.commodity_contract_summary_settlement,
+    components: { Drawer, UploadImg, PlusOutlined, MinusOutlined },
+    emits: ['cancel', 'update'],
+    props: {
+        selectedRow: {
+            type: Object as PropType<QueryTradePositionRsp>,
+            default: {},
+        },
+        buyOrSell: {
+            type: Number as PropType<BuyOrSell>,
+            default: BuyOrSell.buy,
+        },
+    },
+    setup(props, context) {
+        const { visible, cancel } = _closeModal(context);
+        const { rules, formState, formRef } = handleForm();
+        // 选中逻辑
+        const { checked, selected, checkGroupChange, checkboxChange } = useCheckd();
+
+        // 表格列表数据
+        const { loading, tableList, queryTable } = queryTableList<BargainList>();
+        const param: QueryTradeHolderDetailReq = {
+            buyorsell: props.selectedRow.buyorsell,
+            userid: getUserId(),
+            goodsid: props.selectedRow.goodsid,
+        };
+        queryTable(queryTradeHolderDetail, param).then((res) => {
+            tableList.value = res.map((e, i) => {
+                if (i) {
+                    return { ...e, checked: false };
+                } else {
+                    // 默认勾选第一个
+                    checked.value = e.tradeid;
+                    const result = { ...e, checked: true };
+                    selected.value = result;
+                    return result;
+                }
+            });
+        });
+
+        const toFixed0 = (value: number) => +value.toFixed(0);
+
+        function submit() {
+            if (!selected.value) {
+                message.warn('请选择持仓');
+                return;
+            }
+            validateAction<FormState>(formRef, formState).then((res) => {
+                const param: TradeHoldTransferApplyReq = {
+                    TradeID: Long.fromString(selected.value!.tradeid),
+                    BuyorSell: selected.value!.buyorsell,
+                    TransferPrice: res.price,
+                    ApplySrc: 2,
+                    ApplicantID: geLoginID_number()!,
+                    Remark: '',
+                };
+                requestResultLoadingAndInfo(tradeHoldTransferApply, param, loading, ['协议平仓成功', '协议平仓失败:']).then(() => {
+                    cancel(true);
+                });
+            });
+        }
+        return {
+            visible,
+            cancel,
+            submit,
+            tableList,
+            loading,
+            toFixed0,
+            rules,
+            formState,
+            formRef,
+            ...usePrice(formState),
+            checked,
+            checkGroupChange,
+            checkboxChange,
+            BuyOrSell,
+            formatTime,
+        };
+    },
+});
+</script>
+
+<style lang="less" scoped>
+.c_c_s_s {
+    background: @m-black40;
+    width: 100%;
+    height: 100%;
+    position: relative;
+    .formBar {
+        padding: 0;
+        height: calc(100% - 170px);
+        background: @m-black41;
+        .formtop {
+            width: 100%;
+            padding: 0 20px;
+            .flex;
+            flex-direction: column;
+            .firstTitle {
+                width: calc(100% + 40px);
+                height: 40px;
+                line-height: 40px;
+                margin-left: -20px;
+                padding: 0 20px;
+                font-size: 14px;
+                color: @m-white6;
+                border-bottom: 1px solid @m-black42;
+            }
+            .secondLine {
+                width: 100%;
+                height: 40px;
+                line-height: 40px;
+                display: inline-flex;
+                > div {
+                    flex: 1;
+                    font-size: 14px;
+                    color: @m-grey1;
+                }
+                .left {
+                    text-align: left;
+                }
+                .middle {
+                    text-align: center;
+                }
+                .right {
+                    text-align: right;
+                }
+            }
+            .lineBar {
+                width: 100%;
+                min-height: 100px;
+                padding-left: 15px;
+                padding-right: 10px;
+                background: @m-blue19;
+                margin-bottom: 10px;
+                .rounded-corners(5px);
+                .line1 {
+                    display: inline-flex;
+                    user-select: none;
+                    width: 100%;
+                    height: 40px;
+                    line-height: 40px;
+                    font-size: 16px;
+                    color: @m-white6;
+                    white-space: nowrap;
+                    text-overflow: ellipsis;
+                    overflow: hidden;
+                    border-bottom: 1px solid @m-blue20;
+                    > div {
+                        align-self: center;
+                        align-items: center;
+                    }
+                    .name {
+                        margin-left: 10px;
+                    }
+                    .date {
+                        flex: 1;
+                        text-align: right;
+                        font-size: 14px;
+                        color: @m-grey1;
+                    }
+                }
+                .line2 {
+                    width: 100%;
+                    user-select: none;
+                    padding: 12px 0 14px 0;
+                    display: inline-flex;
+                    .left {
+                        width: 25%;
+                        color: @m-white6;
+                        font-size: 14px;
+                        white-space: nowrap;
+                        text-overflow: ellipsis;
+                        overflow: hidden;
+                        line-height: 34px;
+                        // }
+                    }
+                    .middle {
+                        width: 50%;
+                        display: inline-flex;
+                        justify-content: space-between;
+                        padding: 0 10px;
+                        font-size: 16px;
+                        color: @m-white6;
+                        line-height: 34px;
+                        > div {
+                            white-space: nowrap;
+                        }
+                    }
+                    .right {
+                        width: 25%;
+                        font-size: 16px;
+                        text-align: right;
+                        line-height: 34px;
+                        white-space: nowrap;
+                    }
+                }
+            }
+        }
+    }
+    .fixedBtns {
+        padding-top: 0;
+        left: 0;
+        right: 0;
+        padding-left: 20px;
+        padding-right: 20px;
+    }
+    .formbottom {
+        width: 100%;
+        .flex;
+        flex-direction: column;
+        background: @m-black40;
+        padding: 0 18px 0 20px;
+        .line1 {
+            width: 100%;
+            padding: 0 12px 0 16px;
+            height: 36px;
+            line-height: 36px;
+            display: inline-flex;
+            justify-content: space-between;
+            color: @m-grey1;
+            font-size: 14px;
+        }
+        .line2 {
+            width: 100%;
+            height: 35px;
+            line-height: 34px;
+            padding-left: 15px;
+            padding-right: 10px;
+            background: @m-black43;
+            .rounded-corners(5px);
+            font-size: 14px;
+            color: @m-grey1;
+            display: inline-flex;
+            justify-content: space-between;
+            > div {
+                align-self: baseline;
+                align-items: baseline;
+            }
+            .right {
+                display: inline-flex;
+                color: @m-yellow6;
+                div:last-child {
+                    font-size: 16px;
+                    margin-left: 2px;
+                }
+            }
+        }
+        .line3 {
+            margin-top: 16px;
+            width: 100%;
+            height: 15px;
+            line-height: 15px;
+            font-size: 14px;
+            text-align: right;
+            color: @m-white6;
+        }
+    }
+    .inputIconBox {
+        .ant-form-item-children {
+            .anticon-plus {
+                right: 156px;
+            }
+        }
+    }
+}
+</style>;
+
+function queryTradeHolderDetail(queryTradeHolderDetail: any, param: { applytype: number; }) {
+  throw new Error('Function not implemented.');
+}

+ 10 - 0
src/views/order/commodity_contract/components/commodity_contract_summary/components/commodity_contract_summary_order_closed/interface.ts

@@ -0,0 +1,10 @@
+import { QueryTradeHolderDetailRsp } from "@/services/go/order/interface";
+
+export interface FormState {
+    price: number,
+}
+
+
+export interface BargainList extends QueryTradeHolderDetailRsp {
+    checked: boolean
+}

+ 55 - 0
src/views/order/commodity_contract/components/commodity_contract_summary/components/commodity_contract_summary_order_closed/setup.ts

@@ -0,0 +1,55 @@
+import { validateCommon } from "@/common/setup/validate";
+import { RuleObject } from "ant-design-vue/lib/form/interface";
+import { reactive, ref, UnwrapRef } from "vue";
+import { BargainList, FormState } from "./interface";
+
+export function handleForm() {
+    const formRef = ref();
+    const v_num = async (rule: RuleObject, value: number) => {
+        return validateCommon(value, '请输入协议价');
+    };
+    const formState: UnwrapRef<FormState> = reactive({
+        price: 0,
+    })
+    const rules = {
+        price: [
+            { require, message: '请输入协议价', trigger: 'blur', type: 'number', validator: v_num },
+        ],
+    }
+    return { rules, formState, formRef }
+}
+
+export function usePrice(formState: UnwrapRef<FormState>) {
+    function increasePirce() {
+        formState.price++
+    }
+    function decreasePrice() {
+        if (formState.price) {
+            formState.price--
+        }
+    }
+    return { increasePirce, decreasePrice }
+}
+
+export function useCheckd() {
+    const checked = ref<string>();
+    const selected = ref<BargainList>()
+    function checkGroupChange(checkedValue: string[]) {
+        checked.value = checkedValue[checkedValue.length - 1];
+    }
+    function checkboxChange(item: BargainList) {
+        selected.value = item;
+    }
+    return { checked, selected, checkGroupChange, checkboxChange }
+}
+
+// 计算盈亏
+export function useProfit(item: BargainList) {
+    const { buyorsell, holderprice, agreeunit, holderqty } = item
+    // let result = '--'
+    // if(buyorsell === BuyOrSell.buy) {
+
+    // } else {
+
+    // }
+}

+ 7 - 5
src/views/order/commodity_contract/components/commodity_contract_summary/index.vue

@@ -72,6 +72,7 @@ export default defineComponent({
         [ModalEnum.commodity_contract_summary_settlement]: defineAsyncComponent(() => import('./components/commodity_contract_summary_settlement/index.vue')),
         [ModalEnum.commodity_contract_summary_transfer]: defineAsyncComponent(() => import('./components/commodity_contract_summary_transfer/index.vue')),
         commodity_contract_summary_deal_closed: defineAsyncComponent(() => import('./components/commodity_contract_summary_deal_closed/index.vue')),
+        commodity_contract_summary_order_closed: defineAsyncComponent(() => import('./components/commodity_contract_summary_order_closed/index.vue')),
     },
     setup() {
         // 表格列表数据
@@ -102,11 +103,12 @@ export default defineComponent({
         }
 
         function handleBtnList(record: QueryTradePositionRsp, btnList: BtnListType[]) {
-            if (findGoodsTradeModeById(record.goodsid) === TradeMode.DiaoQi) {
-                return btnList.filter((e) => e.code === 'commodity_contract_summary_deal_closed');
-            } else {
-                return btnList.filter((e) => e.code !== 'commodity_contract_summary_deal_closed');
-            }
+            // 挂牌点选
+            const listing = ['commodity_contract_summary_transfer', 'commodity_contract_summary_settlement'];
+            // 贸易圈
+            const diaoqi = ['commodity_contract_summary_deal_closed', 'commodity_contract_summary_order_closed'];
+            const arr = findGoodsTradeModeById(record.goodsid) === TradeMode.DiaoQi ? diaoqi : listing;
+            return btnList.filter((e) => arr.includes(e.code));
         }
         return {
             ...handleComposeOrderTable<QueryTradePositionRsp>(param),