키오스크 영수증(티켓)발권

박영은·2024년 10월 29일
0
import { render } from 'react-thermal-printer';
import { DrinkTicket } from '../../components';

const drinkPrint = ({ children }: { children: React.ReactNode }) => {
  const onClickPrint = async () => {
    let port: SerialPort | null = null;
    let writer: WritableStreamDefaultWriter<Uint8Array> | null = null;

    try {
      // ========== 티켓 발권
      const ports = await navigator.serial.getPorts();
      port = ports[0];

      // 연결 포트 없으면 포트 요청
      if (!port) {
        port = await navigator.serial.requestPort({
          filters: [], // 필요하면 특정 프린터 필터 추가
        });
      }

      // 포트 닫혀있으면 가져옴.
      if (!port.writable) {
        await port.open({ baudRate: 9600 });
      }

      writer = port.writable!.getWriter();
      try {
        // 티켓 인쇄
        
        
        // ===== 티켓-교환권처럼 연속해서 다른 것 인쇄 시 
         try {
          // ===== 입장권 출력
          const printTicket = await render(Ticket(countArray));
          const ticketArray = new Uint8Array(printTicket);
          await writer.write(ticketArray);

          // ===== drinkCheck && 음료교환권 출력
          if (drinkCheck) {
            const printDrinkTicket = await render(DrinkTicket());
            const drinkArray = new Uint8Array(printDrinkTicket);
            await writer.write(drinkArray);
          }

          // 연속 인쇄 시 대기
          await new Promise((resolve) => setTimeout(resolve, 1500));
        } catch (error) {
          setIsModal('printFail');
          navigate('/');
        }
        
        
        // ===== 1장만 인쇄 시 
        try {
          const printData = await render(DrinkTicket());

          // 데이터 변환 및 전송
          const uint8Array = new Uint8Array(printData);
          await writer.write(uint8Array);

          // 연속 인쇄 시 대기
          await new Promise((resolve) => setTimeout(resolve, 1500));
          
          
          
          
          // ===== 선택한 갯수만큼 인쇄 시
        // 티켓 인쇄
        for (let i = 0; i < ticketId().count; i++) {
          try {
            const printData = await render(
              Ticket({
                data: data[i],
                count: i + 1,
              })
            );

            // 데이터 변환 및 전송
            const uint8Array = new Uint8Array(printData);
            await writer.write(uint8Array);

            // 연속 인쇄 시 대기
            await new Promise((resolve) => setTimeout(resolve, 1500));
          } catch (e) {
            setIsModal('printFail');
            navigate('/');
          }
        }


        } catch (e) {
          console.log('error');
        }
      } catch (e) {
        console.log('error');
      }
    } finally {
      // 리소스 정리
      if (writer) {
        writer.releaseLock();
      }
      if (port?.writable) {
        await port.close();
      }
    }
  };

  return <button onClick={onClickPrint}>{children}</button>;
};

export default drinkPrint;
// 영수증 구성
import { Br, Cut, Line, Printer, Row, Text } from 'react-thermal-printer';
import useGetDate from '../../../utils/hooks/useGetDate';

const DrinkTicket = () => {
  const companyInfo = [
    { label: '사업자번호', content: '111-11-11111' },
    { label: '상호', content: '(주)가나다라마바사' },
    { label: '주소', content: '서울시 성동구 왕십리' },
    { label: '대표자', content: '뚜뚜' },
  ];

  return (
    <Printer type="epson" width={42} characterSet="korea">
      <li>
        {/* === title === */}
        <Text align="center" size={{ width: 2, height: 2 }}>
          음료 교환권
        </Text>
        <Br />
        <Br />
        <Row
          left={
            <Text bold size={{ width: 1, height: 1 }}>
              발권 일시
            </Text>
          }
          right={useGetDate()}
        />
        <Line />

        {/* === 사업장 정보 === */}
        {companyInfo.map((info, index) => (
          <Row
            key={index}
            left={
              <Text bold size={{ width: 1, height: 1 }}>
                {info.label}
              </Text>
            }
            right={info.content}
          />
        ))}

        <Br />

        {/* === 티켓 내역 === */}
        <Line />
        <Row
          left={
            <Text bold size={{ width: 1, height: 1 }}>
              옵션명
            </Text>
          }
          right={
            <Text bold size={{ width: 1, height: 1 }}>
              수량
            </Text>
          }
        />
        <Line />
          // 임시 옵션
        <Row left="뚜뚜-건강검진" right={`${1}`} />
        <Row left="뚜뚜-심장사상충약-넥스가드" right={`${2}`} />
        <Br />
        <Line />
        <Br />

        {/*  === 문의 및 교환권 안내 === */}
        <Row
          left={
            <Text bold size={{ width: 1, height: 1 }}>
              문의
            </Text>
          }
          right="1661-3624"
        />
        <Br />
        <Text align="left" size={{ width: 1, height: 1 }}>
          뚜뚜 건강하세요
        </Text>

        {/* === cut === */}
        <Cut />
      </li>
    </Printer>
  );
};

export default DrinkTicket;
profile
Front-end

0개의 댓글