TravelAddressModal.tsx 9.48 KB
import React, { useEffect, useState } from "react";
import { Modal, Form, message, Select, Radio, Input, InputNumber, Space } from "antd";
import * as API from "../api";
import useInitial from "@/hooks/useInitail";
import Addrs from "./Addrs";
import ShopSelectNew from "@/components/ShopSelectNew";
import usePagination from "@/hooks/usePagination";
import { getAllPostListApi, getUnitCompanyListApi } from "@/common/api";
import { addressTypeEnum } from "@/pages/attendance/TravelSetting/TravelAddress/entity";
import PositionSelector from "@/components/PositionSelector";
import ShopSelect from "@/components/ShopSelect";
import { AddressItems, getStorageSelectApi, StorageItems, StorageParams } from "../api";

const FormItem = Form.Item;

interface Props {
  travelAddressModal: { visible: boolean; current: API.AddressItems };
  onClose: (fresh?:boolean)=>void;
  selectedRows: API.Reason;
}

const { Option } = Select;
export default function ModalIndex(props: Props) {
  const [form] = Form.useForm();

  const { onClose, travelAddressModal, selectedRows } = props;
  const { visible, current } = travelAddressModal;
  const [own, setOwn] = useState(1); //配置控制
  const [loading, setLoading] = useState(false);

  const pattern = /^(([1-9][0-9]*)|(([0]\.\d{1,2}|[1-9][0-9]*\.\d{6,})))$/;

  const { data: UnitCompany } = useInitial<CommonApi.companyVO[], CommonApi.ConmanyQueryParams>(
    getUnitCompanyListApi,
    [],
    {}
  );
  const { data: storageList } = useInitial<StorageItems[], StorageParams>(getStorageSelectApi, [], {});

  const { list: postList } = usePagination(getAllPostListApi, { pageSize: 1000 });

  useEffect(() => {
    if (visible && current.id) {
      let maxStayMinute;
      let maxStayHour;
      if ((current.maxStayMinute || 0) >= 60) {
        maxStayMinute = (current.maxStayMinute || 0) % 60;
        maxStayHour = Math.floor((current.maxStayMinute || 0) / 60)
      } else {
        maxStayMinute = (current.maxStayMinute || 0)
        maxStayHour = 0
      }
        let feildsValue: any = {
          ...current,
          maxStayHour,
          maxStayMinute,

          shops: current.shops.map((item) => ({
            ...item,
            shopShortName: item.shopName,
            label: item.shopName,
            value: item.shopId,
          })),
          location: current.address
            ? {
                //@ts-ignored;
                address: current.address || "",
                point: {
                  lng: current.lng,
                  lat: current.lat,
                },
              }
            : undefined,
          posts: current.posts.map((it) => ({
            label: it.postName,
            value: it.postId,
          })),
        };
      if (current.addressId && current.address) {
        feildsValue.place = { label: current.address, value: current.addressId };
      }
      form.setFieldsValue({ ...feildsValue });
    }
  }, [visible]);

  function submit(params: any) {
    const { posts, shops, lat, lng } = params;
  // if (selectedRows.addressType === addressTypeEnum["自定义固定地址"]) {
  //    if (!verifyLngLat(lng, lat)) {
  //      return;
  //    }
  // }
    const maxStayMinute = (params.maxStayMinute || 0)+ (params.maxStayHour || 0) * 60;
    setLoading(true);
    let _param = {
      ...params,
      type: 1,
      addressType: selectedRows.addressType,
      reasonId: selectedRows.id,
      posts: posts.map((item: any) => ({
        postId: item.value,
        postName: item.label,
      })),
      shops: shops.map((item) => ({
        shopId: item.value,
        shopName: item.label,
      })),
      id: current.id,
      maxStayMinute,
    };
    if (params.place) {
      _param.addressId = params.place.value;
      _param.address = params.place.label;
    }
    if (params.location) {
      _param.address = params.location.address;
    }
    try {
      API.addressSaveOrUpdateApi(_param)
        .then(() => {
          setLoading(false);
          form.resetFields();
          onClose && onClose(true);
          message.success("保存成功");
        })
        .catch((e) => {
          setLoading(false);

          message.error(e.message);
        });
    } catch (e: any) {
      setLoading(false);
      message.error(e.message);
    }
  }

  // 校验经纬度保留6位小数
  function verifyLngLat(lng: any, lat: any) {
    if (!pattern.test(lng)) {
      message.error("经度大于等于6位小数");
      return;
    }
    if (!pattern.test(lat)) {
      message.error("纬度大于等于6位小数");
      return;
    }
    return true;
  }
  const onAd = (e: any) => {
    form.setFieldsValue({
      lng: e.point.lng,
      lat: e.point.lat,
    });
  };

  // 选择经纬度
  function renderLongLa() {
    return (
      <>
        <FormItem name="location" label="地址" rules={[{ required: true, message: "必填" }]}>
          <PositionSelector style={{ width: "100%" }} onChange={(e: any) => onAd(e)} />
        </FormItem>
        <div
          style={{
            display: "flex",
            justifyContent: "space-between",
            width: "80%",
            marginLeft: "15%",
          }}
        >
          <FormItem name="lng" label="经度" style={{ width: "45%" }} rules={[{ required: true, message: "必填" }]}>
            <Input style={{ width: "100%" }} disabled={own === 1} />
          </FormItem>
          <FormItem name="lat" label="纬度" style={{ width: "45%" }} rules={[{ required: true, message: "必填" }]}>
            <Input style={{ width: "100%" }} disabled={own === 1} />
          </FormItem>
        </div>
      </>
    );
  }

  //选择门店
  function renderShops() {
    return (
      <FormItem label="门店地址" name="place" rules={[{ required: true, message: "请选择门店地址" }]}>
        <ShopSelect labelInValue initType={1} />
      </FormItem>
    );
  }

  // 选择往来单位地址
  function renderUnitCompany() {
    return (
      <Form.Item name="place" label="往来单位名称" rules={[{ required: true, message: "请选择往来单位" }]}>
        <Select placeholder="请选择往来单位" labelInValue showSearch optionFilterProp="children">
          {UnitCompany.map((item) => (
            <Option key={item.id} value={item.id}>
              {item.name}
            </Option>
          ))}
        </Select>
      </Form.Item>
    );
  }

  // 选择库房地址
  function renderStorageSelect() {
    return (
      <Form.Item name="place" label="库房地址" rules={[{ required: true, message: "请选择库房地址" }]}>
        <Select placeholder="请选择库房地址" labelInValue showSearch optionFilterProp="children">
          {storageList.map((item) => (
            <Option key={item.id} value={item.id}>
              {item.name}
            </Option>
          ))}
        </Select>
      </Form.Item>
    );
  }
  /**
   * 
   * "自定义固定地址" = 1,
  "门店地址",
  "库房地址",
  "往来单位地址",
  "无固定地址",
   */
  // 渲染选择出差地址
  function renderAddressSelect() {
    let res = null;
    switch (selectedRows.addressType) {
      case addressTypeEnum["自定义固定地址"]:
        res = renderLongLa();
        break;
      case addressTypeEnum["门店地址"]:
        res = renderShops();
        break;
      case addressTypeEnum["库房地址"]:
        res = renderStorageSelect();
        break;
      case addressTypeEnum["往来单位地址"]:
        res = renderUnitCompany();
        break;
      case addressTypeEnum["无固定地址"]:
        res = null;
        break;
      default:
        res = null;
        break;
    }
    return res;
  }

  return (
    <Modal
      title={`${current.id ? "编辑" : "新增"}外勤任务地址`}
      visible={visible}
      onOk={form.submit}
      onCancel={() => {
        onClose && onClose();
        form.resetFields();
      }}
      maskClosable={false}
      getContainer={false}
      width={600}
      confirmLoading={loading}
    >
      <Form
        form={form}
        onFinish={submit}
        labelCol={{ span: 6 }}
        wrapperCol={{ span: 20 }}
      >
        {/* 配置出差地址 */}
        {renderAddressSelect()}
        <Form.Item
          name="shops"
          label="适用门店"
          rules={[{ required: true, message: "请选择适用门店" }]}
        >
          <ShopSelectNew multiple />
        </Form.Item>
        <Form.Item
          name="posts"
          label="适用岗位"
          rules={[{ required: true, message: "请选择适用岗位" }]}
        >
          <Select
            placeholder="请选择适用岗位"
            labelInValue
            mode="multiple"
            showSearch
            optionFilterProp="children"
          >
            {postList.map((item) => (
              <Option key={item.id} value={item.id}>
                {item.postName}
              </Option>
            ))}
          </Select>
        </Form.Item>
        {/* <Form.Item
          name="maxStayMinute"
          label="最大停留时长"
          rules={[{ required: true, message: "请输入最大停留时长" }]}
        >
          <InputNumber addonAfter="分钟" style={{ width: "100%" }} />
        </Form.Item> */}
        <FormItem required label="最大停留时长">
          <Space>
            <FormItem name="maxStayHour" noStyle>
              <InputNumber min={0} addonAfter="小时" />
            </FormItem>
            <div>,</div>
            <FormItem name="maxStayMinute" noStyle>
              <InputNumber min={0} addonAfter="分钟" />
            </FormItem>
          </Space>
        </FormItem>
      </Form>
    </Modal>
  );
}