tangning 2 rokov pred
rodič
commit
b63993f949

+ 11 - 0
src/api/spares/index.ts

@@ -13,6 +13,7 @@ enum Api {
   allList = '/service/sale/laborCost/allList',//人工费用全部列表
   getPriceList = '/service/sale/salePersonnel/getPriceList',//根据工单号获取报价单
   addOrUpdatePriceList = '/service/sale/salePersonnel/addOrUpdatePriceList',//添加或修改报价单
+  confirmRepair = '/service/sale/customer/confirmRepair',//确认维修
   payRegister = '/service/sale/salePersonnel/payRegister',//付款登记
   sendRegister = '/service/sale/salePersonnel/sendRegister',//发货登记
   supplyOrderList = '/service/sale/supplyPersonnel/supplyOrderList',//维修备件管理 供应链 列表
@@ -189,6 +190,16 @@ enum Api {
    },
  });
 
+ export const confirmRepair = (params) =>
+ defHttp.post<Result>({
+   url: Api.confirmRepair,
+   params: params,
+   // data: params,
+   headers: {
+     // @ts-ignore
+     ignoreCancelToken: true,
+   },
+ });
 
  export const payRegister = (params) =>
  defHttp.post<Result>({

+ 340 - 0
src/views/work/confirmPriceModal.vue

@@ -0,0 +1,340 @@
+<template>
+  <BasicModal
+    v-bind="$attrs"
+    @register="register"
+    title="维修报价"
+    width="600px"
+    @cancel="clearInfo"
+    :confirmLoading="loading"
+  >
+    <template #footer>
+      <div style="text-align:center">
+        <a-button type="primary" danger @click="handleCancel">取消维修</a-button>
+        <a-button type="primary" @click="handleSubmit">确认维修</a-button>
+      </div>
+    </template>
+    <div class="pt-2px pr-3px">
+      <BasicForm @register="registerForm">
+        <template #text="{ model, field }">
+          {{ model[field] }}
+        </template>
+      </BasicForm>
+      <div class="priceCount">
+        <span>合计:</span>
+        <div class="label">总价:{{ fileFlow.priceCount || 0 }}元 </div>
+      </div>
+    </div>
+  </BasicModal>
+</template>
+<script lang="ts">
+  import { defineComponent, h, onMounted, reactive, ref } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { getPriceList, confirmRepair, allList } from '/@/api/spares'
+  import { useI18n } from '/@/hooks/web/useI18n';
+  import { RedoOutlined, } from '@ant-design/icons-vue';
+  const { t } = useI18n();
+  export default defineComponent({
+    components: { BasicModal, BasicForm, RedoOutlined },
+    props: {
+      userData: { type: Object },
+    },
+    emits: ['update', 'register'],
+    setup(props, { emit }) {
+      const n = ref(1);
+      const fileFlow = reactive({
+        file:null,
+        type:2,//2-普通发票,3-专用发票
+        count:1,//第一次报价
+        priceCount:0,//总价
+        priceLists:[],
+        priceListsPrice:{}
+      })
+      const loading = ref(false)
+      const { createMessage,createConfirm } = useMessage();
+      const schemas: FormSchema[] = [
+          {
+            field: 'id',
+            component: 'Input',
+            show:false,
+            label: '发票编号',
+          },
+          {
+            field: 'repairId',
+            component: 'Input',
+            label: '维修单号',
+            slot: 'text',
+            colProps: {
+              span: 24,
+            },
+          },{
+            field: 'deviceInfo',
+            component: 'Input',
+            label: '设备信息',
+            slot: 'text',
+            colProps: {
+              span: 18,
+            },
+          },{
+            field: 'checkResult',
+            component: 'Input',
+            label: '检测结果',
+            slot: 'text',
+            colProps: {
+              span: 18,
+            },
+          },
+      ];
+
+      const [registerForm, { validate, getFieldsValue, resetFields, setFieldsValue, removeSchemaByFiled, appendSchemaByField, updateSchema }] = useForm({
+        labelWidth: 100,
+        labelAlign:'left',
+        schemas:schemas,
+        showActionButtonGroup: false,
+        actionColOptions: {
+          span: 24,
+        },
+      });
+      onMounted(async () => {
+        let allListOption = await allList()//获取价格
+        fileFlow.priceListsPrice
+        allListOption.map(ele => {
+          fileFlow.priceListsPrice[ele.laborCostId] = ele.price
+        })
+      });
+      let addListFunc = () => {};
+      const [register, { closeModal }] = useModalInner((data) => {
+        data && onDataReceive(data);
+      });
+      async function updataRepairInfo() {
+        let { repairId } = getFieldsValue()
+        console.log('20230228171427939',repairId)
+        const { priceLists } = await getPriceList({repairId})//
+        addPriceItem(priceLists)
+        clearInfo(true)
+        setTimeout(() => {
+          updataCount()
+        }, 100);
+      }
+      async function onDataReceive(data) {
+        const { priceLists } = await getPriceList({repairId:data.repairId})//
+        addPriceItem(priceLists)
+        resetFields();
+        fileFlow.type = data.type
+        setFieldsValue({
+          ...data,
+          deviceInfo:t(`routes.scene.tableType.${data.cameraType}`)+data.cameraSnCode
+        });
+      }
+      function del(field) {
+        removeSchemaByFiled([`deviceType${field}`, `device_${field}`, `${field}`]);
+        // n.value--;
+      }
+      function add() {
+        let list = addSchemas(n.value);
+        list.map(ele => {
+          appendSchemaByField(ele,'')
+        })
+        n.value++
+      }
+      function addPriceItem(list){
+        fileFlow.priceLists = list.reverse()
+        let priceSchema = [],valueObj = {},count=0
+        list.map(ele => {
+          if(ele.count==0){
+            return
+          }
+          valueObj[`priceList${ele.priceListId}`] = ele.count || 0
+          valueObj[`priceListText${ele.priceListId}`] = `${ele.name} ${ele.price} 元/次`
+          count = count + ele.count*ele.price
+          priceSchema.unshift({
+            field: 'priceListText' + ele.priceListId,
+            component: 'InputNumber',
+            label: ele.type == 0?'备件':'人工',
+            slot: 'text',
+            // labelWidth:300,
+            // subLabel:"数量",
+            colProps: {
+              span: 12,
+            }
+          },{
+            field: 'priceList' + ele.priceListId,
+            label: '数量',//`${ele.type == 0?'备件':'人工'}:  ${ele.name} ${ele.price} 元/次`,
+            // suffix:'数量',
+            component: 'InputNumber',
+            slot: 'text',
+            defaultValue:ele.count || 0,
+            // labelWidth:300,
+            // subLabel:"数量",
+            colProps: {
+              span: 12,
+            },
+            required: true,
+            componentProps: {
+              disabled:ele.status == 1,
+              min:0,
+              max:999,
+              maxLength: 15,
+              onChange:(_) =>{
+                setTimeout(() => {
+                updataCount()
+              }, 100)
+              }
+            },
+          })
+        })
+        fileFlow.priceCount = count
+        priceSchema.map(item =>{
+          console.log('priceSchema',item)
+          appendSchemaByField(item,'')
+        })
+        console.log('addPriceItem',valueObj)
+        setTimeout(()=>{
+          setFieldsValue(valueObj)
+        },10)
+      }
+      function addSchemas(number){
+        let parentList: FormSchema[] = [
+          {
+            field: 'deviceType' + number,
+            label: '人工',
+            component: 'ApiSelect',
+            colProps: {
+              span: 12,
+            },
+            required: true,
+            componentProps: {
+              api: allList,
+              labelField: 'name',
+              valueField: 'laborCostId',
+              showSearch:true,
+              onChange:(value)=>{
+                console.log('onchange',value,arguments)
+              }
+            },
+          },
+          {
+            field: 'device_' + number,
+            label: '数量',
+            component: 'InputNumber',
+            required: true,
+            defaultValue: 1,
+            labelWidth:50,
+            componentProps: {
+              max: 999,
+              min:1,
+            },
+            colProps: {
+              span: 6,
+            },
+          },{
+            field: number.toString(),
+            component: 'Input',
+            label: '',
+            labelWidth:0,
+            colProps: {
+              span: 6,
+            },
+            slot: 'del',
+          }
+        ];
+        return parentList
+      }
+
+      const handleCancel = async (val) => {
+        console.log('handleCancel',val,arguments)
+        handleApi(true)
+      }
+
+      const handleApi = async (val) => {
+        const params = await validate(); 
+        try {
+          createConfirm({
+          iconType: 'warning',
+          title: () => h('span', '温馨提示'),
+          content: val?'确定取消维修吗':'确定报价并开始维修吗?',
+          onOk: async () => {
+            loading.value = true
+            let res = await confirmRepair({
+              repairId:params.repairId,
+              confirm:val?1:0,
+            })
+            console.log('res',res)
+            createMessage.success(t('common.optSuccess'));
+            closeModal();
+            emit('update');
+            loading.value = false
+            clearInfo(false)
+          },
+          onCancel: () => {
+            loading.value = false
+          }
+        });
+        } catch (error) {
+          loading.value = false
+          console.log('not passing', error);
+        }
+      }
+
+      const handleSubmit = async () => {
+        handleApi(false)
+      };
+      function updataCount(){
+        let fromData = getFieldsValue() ,count = 0
+        // fileFlow.priceListsPrice
+        console.log('fromData',fromData)
+        fileFlow.priceLists.map(ele => {
+          count = count + fromData[`priceList${ele.priceListId}`]*ele.price
+        })
+        for (let index = 1; index < n.value; index++) {
+          if(fromData[`deviceType${index}`] && fromData[`device_${index}`]){
+            let priceId = fromData[`deviceType${index}`]
+            let fromPrice = fromData[`device_${index}`] * fileFlow.priceListsPrice[priceId]
+            count = count +fromPrice
+          }
+        }
+        fileFlow.priceCount = count
+      }
+
+      function clearInfo(val){
+        fileFlow.priceCount = 0
+        if(!val){
+          resetFields()
+        }
+        let clearFiled = []
+        fileFlow.priceLists.map(ele =>{
+          clearFiled.push(`priceList${ele.priceListId}`,`priceListText${ele.priceListId}`)
+        })
+        removeSchemaByFiled(clearFiled);
+        n.value = 1
+      }
+
+      return {
+        register,
+        registerForm,
+        fileFlow,
+        handleSubmit,
+        handleCancel,
+        addListFunc,
+        resetFields,
+        loading,
+        clearInfo,
+        updataCount,
+        t,
+        del,
+        add,
+        updataRepairInfo,
+      };
+    },
+  });
+</script>
+
+<style lang="less" scoped>
+.priceCount{
+  padding: 20px 180px;
+  .label{
+    display: inline-block;
+  }
+}
+</style>

+ 15 - 2
src/views/work/followedList.vue

@@ -37,6 +37,11 @@
               onClick: handleQuote.bind(null, record),
             },
             {
+              label: '确认报价',
+              ifShow:getCheckPerm('work_confirmPrice') && record.status == 3 && record.receiverType == 0,
+              onClick: handleConfirmPrice.bind(null, record),
+            },
+            {
               label: '付款登记',
               ifShow:getCheckPerm('work_payments') && record.status == 9,
               onClick: handlePayLog.bind(null, record),
@@ -61,6 +66,7 @@
     <quoteModel @update="reload" @register="registerQuote" />
     <deliveryModal @update="reload" @register="registerDelivery" />
     <payLogModal @update="reload" @register="registerPayLog" />
+    <confirmPriceModal @update="reload" @register="registerConfirmPrice" />
     <!-- ifShow: getCheckPerm('device-out') && !Boolean(record.outType), -->
   </div>
 </PageWrapper>
@@ -86,7 +92,7 @@ import deliveryModal from './deliveryModal.vue';
 import payLogModal from './payLogModal.vue';
 import takingOrdersModel from './takingOrdersModel.vue';
 import remarksModal from '../spares/remarksModal.vue';
-
+import confirmPriceModal from './confirmPriceModal.vue'
 import { useModal } from '/@/components/Modal';
 import { useRouter } from 'vue-router'
 import { saleOrderList } from '/@/api/spares';
@@ -100,6 +106,7 @@ export default defineComponent({
     remarksModal,
     deliveryModal,
     payLogModal,
+    confirmPriceModal,
     quoteModel,
     PageWrapper,
     [Tabs.name]: Tabs,
@@ -176,7 +183,7 @@ export default defineComponent({
         ifShow: true,
         fixed: 'right',
         flag: 'ACTION',
-        width: 160,
+        width: 240,
       },
     ];
     const searchForm: Partial<FormProps> = {
@@ -232,6 +239,7 @@ export default defineComponent({
     };
     const [registerRecovery, { openModal }] = useModal();
     const [registerQuote, { openModal:openQuoteModal }] = useModal();
+    const [registerConfirmPrice, { openModal:openConfirmPriceModal }] = useModal();
     const [registerPayLog, { openModal:openPayLogModal }] = useModal();
     const [registerDelivery, { openModal:openDeliveryModal }] = useModal();
     const [registerTakingOrders, { openModal:openTakingOrders }] = useModal();
@@ -267,6 +275,9 @@ export default defineComponent({
     function handlePayLog(record: Recordable) {
       openPayLogModal(true,record);
     }
+    function handleConfirmPrice(record: Recordable) {
+      openConfirmPriceModal(true,record);
+    }
     function handleDelivery(record: Recordable) {
       openDeliveryModal(true,record);
     }
@@ -288,6 +299,7 @@ export default defineComponent({
       registerRemarks,
       registerPayLog,
       registerDelivery,
+      registerConfirmPrice,
       changeTable,
       handleOrder,
       getCheckPerm,
@@ -295,6 +307,7 @@ export default defineComponent({
       handleQuote,
       registerTakingOrders,
       handleRecover,
+      handleConfirmPrice,
       handlePayLog,
       handleDelivery,
       handleRemarks,