├── .gitignore ├── README.md ├── backend ├── .gitignore ├── Dockerfile ├── Makefile ├── README.md ├── app │ ├── agent │ │ ├── .env │ │ ├── .gitignore │ │ ├── README.md │ │ ├── cmd │ │ │ ├── einoagent │ │ │ │ └── agent │ │ │ │ │ ├── agent.go │ │ │ │ │ └── web │ │ │ │ │ └── script.js │ │ │ ├── einoagentcli │ │ │ │ └── main.go │ │ │ └── knowledgeindexing │ │ │ │ ├── eino-docs │ │ │ │ ├── _index.md │ │ │ │ └── agent_llm_with_tools.md │ │ │ │ └── main.go │ │ ├── docker-compose.yml │ │ ├── eino │ │ │ ├── eino_agent.json │ │ │ ├── einoagent │ │ │ │ ├── embedding.go │ │ │ │ ├── flow.go │ │ │ │ ├── lambda_func.go │ │ │ │ ├── model.go │ │ │ │ ├── orchestration.go │ │ │ │ ├── prompt.go │ │ │ │ ├── retriever.go │ │ │ │ ├── tool.go │ │ │ │ └── types.go │ │ │ ├── knowledge_indexing.json │ │ │ └── knowledgeindexing │ │ │ │ ├── embedding.go │ │ │ │ ├── indexer.go │ │ │ │ ├── loader.go │ │ │ │ ├── orchestration.go │ │ │ │ └── transformer.go │ │ ├── go.mod │ │ ├── go.sum │ │ └── pkg │ │ │ ├── mem │ │ │ └── simple.go │ │ │ ├── redis │ │ │ └── redis.go │ │ │ └── tool │ │ │ ├── cart │ │ │ └── cart.go │ │ │ ├── einotool │ │ │ ├── einotool.go │ │ │ └── templates │ │ │ │ ├── http_agent │ │ │ │ ├── README.md │ │ │ │ ├── client │ │ │ │ │ └── main.go │ │ │ │ └── main.go │ │ │ │ ├── react_agent │ │ │ │ └── main.go │ │ │ │ └── simple_llm │ │ │ │ └── main.go │ │ │ ├── gitclone │ │ │ └── gitclone.go │ │ │ ├── open │ │ │ └── open.go │ │ │ ├── orderlookup │ │ │ └── orderlookup.go │ │ │ ├── payment │ │ │ └── payment.go │ │ │ ├── productlist │ │ │ └── productlist.go │ │ │ └── task │ │ │ ├── README.md │ │ │ ├── storage.go │ │ │ └── task.go │ ├── cart │ │ ├── .env │ │ ├── .gitignore │ │ ├── biz │ │ │ ├── dal │ │ │ │ ├── init.go │ │ │ │ ├── mysql │ │ │ │ │ └── init.go │ │ │ │ └── redis │ │ │ │ │ └── init.go │ │ │ ├── model │ │ │ │ ├── base.go │ │ │ │ └── cart.go │ │ │ └── service │ │ │ │ ├── add_item.go │ │ │ │ ├── add_item_test.go │ │ │ │ ├── change_qty.go │ │ │ │ ├── change_qty_test.go │ │ │ │ ├── empty_cart.go │ │ │ │ ├── empty_cart_test.go │ │ │ │ ├── get_cart.go │ │ │ │ └── get_cart_test.go │ │ ├── build.sh │ │ ├── conf │ │ │ ├── conf.go │ │ │ ├── dev │ │ │ │ └── conf.yaml │ │ │ ├── online │ │ │ │ └── conf.yaml │ │ │ └── test │ │ │ │ └── conf.yaml │ │ ├── docker-compose.yaml │ │ ├── go.mod │ │ ├── go.sum │ │ ├── handler.go │ │ ├── infra │ │ │ └── rpc │ │ │ │ └── client.go │ │ ├── kitex_info.yaml │ │ ├── main.go │ │ ├── readme.md │ │ ├── script │ │ │ └── bootstrap.sh │ │ └── utils │ │ │ ├── constant.go │ │ │ ├── errors.go │ │ │ └── function.go │ ├── checkout │ │ ├── .env │ │ ├── .gitignore │ │ ├── biz │ │ │ ├── dal │ │ │ │ ├── init.go │ │ │ │ ├── mysql │ │ │ │ │ └── init.go │ │ │ │ └── redis │ │ │ │ │ └── init.go │ │ │ └── service │ │ │ │ ├── checkout.go │ │ │ │ └── checkout_test.go │ │ ├── build.sh │ │ ├── conf │ │ │ ├── conf.go │ │ │ ├── dev │ │ │ │ └── conf.yaml │ │ │ ├── online │ │ │ │ └── conf.yaml │ │ │ └── test │ │ │ │ └── conf.yaml │ │ ├── docker-compose.yaml │ │ ├── go.mod │ │ ├── go.sum │ │ ├── handler.go │ │ ├── infra │ │ │ ├── mq │ │ │ │ └── nats.go │ │ │ └── rpc │ │ │ │ └── client.go │ │ ├── kitex_info.yaml │ │ ├── main.go │ │ ├── readme.md │ │ ├── script │ │ │ └── bootstrap.sh │ │ └── utils │ │ │ └── errors.go │ ├── email │ │ ├── .env │ │ ├── .gitignore │ │ ├── biz │ │ │ ├── consumer │ │ │ │ ├── consumer.go │ │ │ │ └── email │ │ │ │ │ ├── email.go │ │ │ │ │ └── email_test.go │ │ │ ├── dal │ │ │ │ ├── init.go │ │ │ │ ├── mysql │ │ │ │ │ └── init.go │ │ │ │ └── redis │ │ │ │ │ └── init.go │ │ │ └── service │ │ │ │ ├── send.go │ │ │ │ └── send_test.go │ │ ├── build.sh │ │ ├── conf │ │ │ ├── conf.go │ │ │ ├── dev │ │ │ │ └── conf.yaml │ │ │ ├── online │ │ │ │ └── conf.yaml │ │ │ └── test │ │ │ │ └── conf.yaml │ │ ├── docker-compose.yaml │ │ ├── go.mod │ │ ├── go.sum │ │ ├── handler.go │ │ ├── infra │ │ │ ├── mq │ │ │ │ └── nats.go │ │ │ └── notify │ │ │ │ └── email.go │ │ ├── kitex_info.yaml │ │ ├── main.go │ │ ├── readme.md │ │ └── script │ │ │ └── bootstrap.sh │ ├── frontend │ │ ├── .env │ │ ├── .gitignore │ │ ├── .hz │ │ ├── biz │ │ │ ├── dal │ │ │ │ ├── init.go │ │ │ │ ├── mysql │ │ │ │ │ └── init.go │ │ │ │ └── redis │ │ │ │ │ └── init.go │ │ │ ├── handler │ │ │ │ ├── about │ │ │ │ │ ├── about_service.go │ │ │ │ │ └── about_service_test.go │ │ │ │ ├── agent │ │ │ │ │ ├── agent_service.go │ │ │ │ │ └── agent_service_test.go │ │ │ │ ├── auth │ │ │ │ │ ├── auth_service.go │ │ │ │ │ └── auth_service_test.go │ │ │ │ ├── cart │ │ │ │ │ ├── cart_service.go │ │ │ │ │ └── cart_service_test.go │ │ │ │ ├── category │ │ │ │ │ ├── category_service.go │ │ │ │ │ └── category_service_test.go │ │ │ │ ├── checkout │ │ │ │ │ ├── checkout_service.go │ │ │ │ │ └── checkout_service_test.go │ │ │ │ ├── home │ │ │ │ │ ├── hello_service.go │ │ │ │ │ └── hello_service_test.go │ │ │ │ ├── merchant │ │ │ │ │ ├── merchant_service.go │ │ │ │ │ └── merchant_service_test.go │ │ │ │ ├── order │ │ │ │ │ ├── order_service.go │ │ │ │ │ └── order_service_test.go │ │ │ │ ├── oss │ │ │ │ │ ├── oss_service.go │ │ │ │ │ └── oss_service_test.go │ │ │ │ ├── payment │ │ │ │ │ ├── payment_service.go │ │ │ │ │ └── payment_service_test.go │ │ │ │ ├── product │ │ │ │ │ ├── product_service.go │ │ │ │ │ └── product_service_test.go │ │ │ │ └── user │ │ │ │ │ ├── user_service.go │ │ │ │ │ └── user_service_test.go │ │ │ ├── router │ │ │ │ ├── about │ │ │ │ │ ├── about.go │ │ │ │ │ └── middleware.go │ │ │ │ ├── agent │ │ │ │ │ ├── agent.go │ │ │ │ │ └── middleware.go │ │ │ │ ├── auth │ │ │ │ │ ├── auth_page.go │ │ │ │ │ └── middleware.go │ │ │ │ ├── cart │ │ │ │ │ ├── cart_page.go │ │ │ │ │ └── middleware.go │ │ │ │ ├── category │ │ │ │ │ ├── category_page.go │ │ │ │ │ └── middleware.go │ │ │ │ ├── checkout │ │ │ │ │ ├── checkout_page.go │ │ │ │ │ └── middleware.go │ │ │ │ ├── home │ │ │ │ │ ├── home.go │ │ │ │ │ └── middleware.go │ │ │ │ ├── merchant │ │ │ │ │ ├── merchant_gateway.go │ │ │ │ │ └── middleware.go │ │ │ │ ├── order │ │ │ │ │ ├── middleware.go │ │ │ │ │ └── order_page.go │ │ │ │ ├── oss │ │ │ │ │ ├── middleware.go │ │ │ │ │ └── oss.go │ │ │ │ ├── payment │ │ │ │ │ ├── middleware.go │ │ │ │ │ └── payment_page.go │ │ │ │ ├── product │ │ │ │ │ ├── middleware.go │ │ │ │ │ └── product_page.go │ │ │ │ ├── register.go │ │ │ │ └── user │ │ │ │ │ ├── middleware.go │ │ │ │ │ └── user_page.go │ │ │ ├── service │ │ │ │ ├── about.go │ │ │ │ ├── add_cart_item.go │ │ │ │ ├── alipay.go │ │ │ │ ├── category.go │ │ │ │ ├── change_qty.go │ │ │ │ ├── checkout.go │ │ │ │ ├── checkout_result.go │ │ │ │ ├── checkout_waiting.go │ │ │ │ ├── delete_user.go │ │ │ │ ├── empty_cart.go │ │ │ │ ├── get_cart.go │ │ │ │ ├── get_product.go │ │ │ │ ├── handle_chat.go │ │ │ │ ├── home.go │ │ │ │ ├── login.go │ │ │ │ ├── logout.go │ │ │ │ ├── merchant_add_product.go │ │ │ │ ├── merchant_auth.go │ │ │ │ ├── merchant_delete_product.go │ │ │ │ ├── merchant_get_product_detail.go │ │ │ │ ├── merchant_get_product_list.go │ │ │ │ ├── merchant_ping.go │ │ │ │ ├── merchant_register.go │ │ │ │ ├── merchant_update_product.go │ │ │ │ ├── order_list.go │ │ │ │ ├── payresult.go │ │ │ │ ├── paysuccess.go │ │ │ │ ├── query_user.go │ │ │ │ ├── register.go │ │ │ │ ├── search_products.go │ │ │ │ ├── update.go │ │ │ │ ├── upload_image.go │ │ │ │ └── upload_video.go │ │ │ └── utils │ │ │ │ ├── jwt.go │ │ │ │ ├── oss.go │ │ │ │ ├── resp.go │ │ │ │ └── type.go │ │ ├── build.sh │ │ ├── conf │ │ │ ├── conf.go │ │ │ ├── dev │ │ │ │ └── conf.yaml │ │ │ ├── online │ │ │ │ └── conf.yaml │ │ │ └── test │ │ │ │ └── conf.yaml │ │ ├── data │ │ │ └── task │ │ │ │ └── tasks.jsonl │ │ ├── docker-compose.yaml │ │ ├── go.mod │ │ ├── go.sum │ │ ├── hertz_gen │ │ │ ├── api │ │ │ │ └── api.pb.go │ │ │ ├── frontend │ │ │ │ ├── about │ │ │ │ │ └── about.pb.go │ │ │ │ ├── agent │ │ │ │ │ └── agent.pb.go │ │ │ │ ├── auth │ │ │ │ │ └── auth_page.pb.go │ │ │ │ ├── cart │ │ │ │ │ └── cart_page.pb.go │ │ │ │ ├── category │ │ │ │ │ └── category_page.pb.go │ │ │ │ ├── checkout │ │ │ │ │ └── checkout_page.pb.go │ │ │ │ ├── common │ │ │ │ │ └── common.pb.go │ │ │ │ ├── home │ │ │ │ │ └── home.pb.go │ │ │ │ ├── merchant │ │ │ │ │ └── merchant_gateway.pb.go │ │ │ │ ├── order │ │ │ │ │ └── order_page.pb.go │ │ │ │ ├── oss │ │ │ │ │ └── oss.pb.go │ │ │ │ ├── payment │ │ │ │ │ └── payment_page.pb.go │ │ │ │ ├── product │ │ │ │ │ └── product_page.pb.go │ │ │ │ └── user │ │ │ │ │ └── user_page.pb.go │ │ │ └── frontend_oss │ │ │ │ └── oss.pb.go │ │ ├── infra │ │ │ └── rpc │ │ │ │ └── client.go │ │ ├── main.go │ │ ├── middleware │ │ │ ├── auth.go │ │ │ ├── jwt.go │ │ │ └── middleware.go │ │ ├── readme.md │ │ ├── script │ │ │ └── bootstrap.sh │ │ ├── static │ │ │ ├── css │ │ │ │ ├── bootstrap-grid.css │ │ │ │ ├── bootstrap-grid.css.map │ │ │ │ ├── bootstrap-grid.min.css │ │ │ │ ├── bootstrap-grid.min.css.map │ │ │ │ ├── bootstrap-grid.rtl.css │ │ │ │ ├── bootstrap-grid.rtl.css.map │ │ │ │ ├── bootstrap-grid.rtl.min.css │ │ │ │ ├── bootstrap-grid.rtl.min.css.map │ │ │ │ ├── bootstrap-reboot.css │ │ │ │ ├── bootstrap-reboot.css.map │ │ │ │ ├── bootstrap-reboot.min.css │ │ │ │ ├── bootstrap-reboot.min.css.map │ │ │ │ ├── bootstrap-reboot.rtl.css │ │ │ │ ├── bootstrap-reboot.rtl.css.map │ │ │ │ ├── bootstrap-reboot.rtl.min.css │ │ │ │ ├── bootstrap-reboot.rtl.min.css.map │ │ │ │ ├── bootstrap-utilities.css │ │ │ │ ├── bootstrap-utilities.css.map │ │ │ │ ├── bootstrap-utilities.min.css │ │ │ │ ├── bootstrap-utilities.min.css.map │ │ │ │ ├── bootstrap-utilities.rtl.css │ │ │ │ ├── bootstrap-utilities.rtl.css.map │ │ │ │ ├── bootstrap-utilities.rtl.min.css │ │ │ │ ├── bootstrap-utilities.rtl.min.css.map │ │ │ │ ├── bootstrap.css │ │ │ │ ├── bootstrap.css.map │ │ │ │ ├── bootstrap.min.css │ │ │ │ ├── bootstrap.min.css.map │ │ │ │ ├── bootstrap.rtl.css │ │ │ │ ├── bootstrap.rtl.css.map │ │ │ │ ├── bootstrap.rtl.min.css │ │ │ │ └── bootstrap.rtl.min.css.map │ │ │ ├── image │ │ │ │ ├── logo.jpg │ │ │ │ ├── mouse-pad.jpeg │ │ │ │ ├── notebook.jpeg │ │ │ │ ├── sweatshirt.jpeg │ │ │ │ ├── t-shirt-1.jpeg │ │ │ │ ├── t-shirt-2.jpeg │ │ │ │ ├── t-shirt.jpeg │ │ │ │ ├── toiletry-bag.jpg │ │ │ │ └── toothbrush-cup.jpg │ │ │ ├── img │ │ │ │ ├── logo.png │ │ │ │ ├── t-shirt-1.jpg │ │ │ │ ├── t-shirt-2.jpg │ │ │ │ ├── t-shirt-3.jpg │ │ │ │ ├── t-shirt-4.jpg │ │ │ │ ├── t-shirt-5.jpg │ │ │ │ └── t-shirt-6.jpg │ │ │ └── js │ │ │ │ ├── bootstrap.bundle.js │ │ │ │ ├── bootstrap.bundle.js.map │ │ │ │ ├── bootstrap.bundle.min.js │ │ │ │ ├── bootstrap.bundle.min.js.map │ │ │ │ ├── bootstrap.esm.js │ │ │ │ ├── bootstrap.esm.js.map │ │ │ │ ├── bootstrap.esm.min.js │ │ │ │ ├── bootstrap.esm.min.js.map │ │ │ │ ├── bootstrap.js │ │ │ │ ├── bootstrap.js.map │ │ │ │ ├── bootstrap.min.js │ │ │ │ └── bootstrap.min.js.map │ │ ├── template │ │ │ ├── about.tmpl │ │ │ ├── cart-num.tmpl │ │ │ ├── cart.tmpl │ │ │ ├── category.tmpl │ │ │ ├── checkout.tmpl │ │ │ ├── footer.tmpl │ │ │ ├── header.tmpl │ │ │ ├── header1.tmpl │ │ │ ├── home.tmpl │ │ │ ├── order.tmpl │ │ │ ├── product.tmpl │ │ │ ├── required.tmpl │ │ │ ├── result.tmpl │ │ │ ├── search.tmpl │ │ │ ├── sign-in.tmpl │ │ │ ├── sign-up.tmpl │ │ │ └── waiting.tmpl │ │ ├── types │ │ │ └── order.go │ │ └── utils │ │ │ ├── constant.go │ │ │ ├── corn.go │ │ │ ├── corn_test.go │ │ │ ├── errors.go │ │ │ ├── function.go │ │ │ └── type.go │ ├── merchant │ │ ├── .env │ │ ├── .gitignore │ │ ├── biz │ │ │ ├── dal │ │ │ │ ├── init.go │ │ │ │ ├── mysql │ │ │ │ │ └── init.go │ │ │ │ └── redis │ │ │ │ │ └── init.go │ │ │ ├── model │ │ │ │ ├── base.go │ │ │ │ ├── cache_utils.go │ │ │ │ ├── category.go │ │ │ │ ├── merchant.go │ │ │ │ ├── product.go │ │ │ │ └── product_cache_dao.go │ │ │ ├── service │ │ │ │ ├── add_merchant.go │ │ │ │ ├── add_merchant_test.go │ │ │ │ ├── add_product.go │ │ │ │ ├── add_product_test.go │ │ │ │ ├── delete_product.go │ │ │ │ ├── delete_product_test.go │ │ │ │ ├── get_merchant.go │ │ │ │ ├── get_merchant_test.go │ │ │ │ ├── main_test.go │ │ │ │ ├── product_detail.go │ │ │ │ ├── product_detail_test.go │ │ │ │ ├── search_products.go │ │ │ │ ├── search_products_test.go │ │ │ │ ├── update_product.go │ │ │ │ └── update_product_test.go │ │ │ └── util │ │ │ │ └── random.go │ │ ├── build.sh │ │ ├── conf │ │ │ ├── conf.go │ │ │ ├── dev │ │ │ │ └── conf.yaml │ │ │ ├── online │ │ │ │ └── conf.yaml │ │ │ └── test │ │ │ │ └── conf.yaml │ │ ├── docker-compose.yaml │ │ ├── go.mod │ │ ├── go.sum │ │ ├── handler.go │ │ ├── infra │ │ │ └── mq │ │ │ │ ├── nats.go │ │ │ │ ├── nats_processor.go │ │ │ │ └── nats_test.go │ │ ├── kitex_info.yaml │ │ ├── main.go │ │ ├── readme.md │ │ └── script │ │ │ └── bootstrap.sh │ ├── order │ │ ├── .env │ │ ├── .gitignore │ │ ├── biz │ │ │ ├── consumer │ │ │ │ ├── consumer.go │ │ │ │ └── order │ │ │ │ │ ├── order.go │ │ │ │ │ └── order_test.go │ │ │ ├── dal │ │ │ │ ├── init.go │ │ │ │ ├── mysql │ │ │ │ │ └── init.go │ │ │ │ └── redis │ │ │ │ │ └── init.go │ │ │ ├── model │ │ │ │ ├── order.go │ │ │ │ └── order_item.go │ │ │ └── service │ │ │ │ ├── change_order_status.go │ │ │ │ ├── change_order_status_test.go │ │ │ │ ├── list_oder.go │ │ │ │ ├── list_oder_test.go │ │ │ │ ├── place_order.go │ │ │ │ └── place_order_test.go │ │ ├── build.sh │ │ ├── conf │ │ │ ├── conf.go │ │ │ ├── dev │ │ │ │ └── conf.yaml │ │ │ ├── online │ │ │ │ └── conf.yaml │ │ │ └── test │ │ │ │ └── conf.yaml │ │ ├── docker-compose.yaml │ │ ├── go.mod │ │ ├── go.sum │ │ ├── handler.go │ │ ├── infra │ │ │ └── mq │ │ │ │ └── nats.go │ │ ├── kitex_info.yaml │ │ ├── main.go │ │ ├── readme.md │ │ ├── script │ │ │ └── bootstrap.sh │ │ └── utils │ │ │ ├── corn.go │ │ │ └── corn_test.go │ ├── payment │ │ ├── .env │ │ ├── .gitignore │ │ ├── biz │ │ │ ├── dal │ │ │ │ ├── init.go │ │ │ │ ├── mysql │ │ │ │ │ └── init.go │ │ │ │ └── redis │ │ │ │ │ └── init.go │ │ │ ├── model │ │ │ │ ├── base.go │ │ │ │ └── payment.go │ │ │ └── service │ │ │ │ ├── alipay.go │ │ │ │ ├── alipay_test.go │ │ │ │ ├── charge.go │ │ │ │ └── charge_test.go │ │ ├── build.sh │ │ ├── conf │ │ │ ├── conf.go │ │ │ ├── dev │ │ │ │ └── conf.yaml │ │ │ ├── online │ │ │ │ └── conf.yaml │ │ │ └── test │ │ │ │ └── conf.yaml │ │ ├── docker-compose.yaml │ │ ├── go.mod │ │ ├── go.sum │ │ ├── handler.go │ │ ├── kitex_info.yaml │ │ ├── main.go │ │ ├── readme.md │ │ └── script │ │ │ └── bootstrap.sh │ ├── product │ │ ├── .env │ │ ├── .gitignore │ │ ├── biz │ │ │ ├── dal │ │ │ │ ├── init.go │ │ │ │ ├── mysql │ │ │ │ │ └── init.go │ │ │ │ └── redis │ │ │ │ │ └── init.go │ │ │ ├── model │ │ │ │ ├── base.go │ │ │ │ ├── cache_utils.go │ │ │ │ ├── category.go │ │ │ │ ├── database_test.go │ │ │ │ ├── main_test.go │ │ │ │ ├── merchant.go │ │ │ │ ├── product.go │ │ │ │ ├── product_cache_dao.go │ │ │ │ ├── product_test.go │ │ │ │ └── redis_test.go │ │ │ ├── service │ │ │ │ ├── get_product.go │ │ │ │ ├── get_product_test.go │ │ │ │ ├── list_products.go │ │ │ │ ├── list_products_test.go │ │ │ │ ├── search_products.go │ │ │ │ └── search_products_test.go │ │ │ └── util │ │ │ │ └── random.go │ │ ├── build.sh │ │ ├── conf │ │ │ ├── conf.go │ │ │ ├── dev │ │ │ │ └── conf.yaml │ │ │ ├── online │ │ │ │ └── conf.yaml │ │ │ └── test │ │ │ │ └── conf.yaml │ │ ├── docker-compose.yaml │ │ ├── go.mod │ │ ├── go.sum │ │ ├── handler.go │ │ ├── infra │ │ │ └── mq │ │ │ │ ├── nats.go │ │ │ │ ├── nats_processor.go │ │ │ │ └── nats_test.go │ │ ├── kitex_info.yaml │ │ ├── main.go │ │ ├── readme.md │ │ └── script │ │ │ └── bootstrap.sh │ └── user │ │ ├── .env │ │ ├── .gitignore │ │ ├── biz │ │ ├── dal │ │ │ ├── init.go │ │ │ ├── mysql │ │ │ │ └── init.go │ │ │ └── redis │ │ │ │ └── init.go │ │ ├── model │ │ │ ├── cache_utils.go │ │ │ ├── user.go │ │ │ ├── userCache_unused.go │ │ │ └── user_cache_dao.go │ │ └── service │ │ │ ├── delete.go │ │ │ ├── delete_test.go │ │ │ ├── login.go │ │ │ ├── login_test.go │ │ │ ├── main_test.go │ │ │ ├── query.go │ │ │ ├── query_test.go │ │ │ ├── register.go │ │ │ ├── register_test.go │ │ │ ├── update.go │ │ │ └── update_test.go │ │ ├── build.sh │ │ ├── conf │ │ ├── conf.go │ │ ├── dev │ │ │ └── conf.yaml │ │ ├── online │ │ │ └── conf.yaml │ │ └── test │ │ │ └── conf.yaml │ │ ├── docker-compose.yaml │ │ ├── go.mod │ │ ├── go.sum │ │ ├── handler.go │ │ ├── infra │ │ └── mq │ │ │ ├── nats.go │ │ │ ├── nats_processor.go │ │ │ └── nats_test.go │ │ ├── kitex_info.yaml │ │ ├── main.go │ │ ├── readme.md │ │ └── script │ │ └── bootstrap.sh ├── common │ ├── clientsuite │ │ └── clientsuite.go │ ├── go.mod │ ├── go.sum │ ├── mtl │ │ ├── metrics.go │ │ └── tracing.go │ └── serversuite │ │ └── serversuite.go ├── cwgo.help ├── db │ └── sql │ │ └── ini │ │ ├── README.md │ │ └── databases.sql ├── deploy │ ├── .env.example │ ├── Dockerfile.frontend │ ├── Dockerfile.svc │ ├── config │ │ ├── loki.yml │ │ ├── prometheus.yml │ │ └── promtail.yml │ ├── docker-compose-svc.yaml │ ├── gomall-dev-app.yaml │ ├── gomall-dev-base.yaml │ ├── gomall-dev-cluster.yaml │ └── grafana.json ├── docker-compose.yaml ├── go.work ├── go.work.sum ├── idl │ ├── api.proto │ ├── cart.proto │ ├── checkout.proto │ ├── echo.proto │ ├── echo.thrift │ ├── email.proto │ ├── frontend │ │ ├── about.proto │ │ ├── agent.proto │ │ ├── auth_page.proto │ │ ├── cart_page.proto │ │ ├── category_page.proto │ │ ├── checkout_page.proto │ │ ├── common.proto │ │ ├── home.proto │ │ ├── merchant_gateway.proto │ │ ├── order_page.proto │ │ ├── oss.proto │ │ ├── payment_page.proto │ │ ├── product_page.proto │ │ └── user_page.proto │ ├── merchant.proto │ ├── order.proto │ ├── payment.proto │ ├── product.proto │ └── user.proto ├── kill_service.sh ├── load_lib.sh ├── rpc_gen │ ├── go.mod │ ├── go.sum │ ├── kitex_gen │ │ ├── api │ │ │ ├── api.pb.fast.go │ │ │ └── api.pb.go │ │ ├── cart │ │ │ ├── cart.pb.fast.go │ │ │ ├── cart.pb.go │ │ │ └── cartservice │ │ │ │ ├── cartservice.go │ │ │ │ ├── client.go │ │ │ │ ├── invoker.go │ │ │ │ └── server.go │ │ ├── checkout │ │ │ ├── checkout.pb.fast.go │ │ │ ├── checkout.pb.go │ │ │ └── checkoutservice │ │ │ │ ├── checkoutservice.go │ │ │ │ ├── client.go │ │ │ │ ├── invoker.go │ │ │ │ └── server.go │ │ ├── email │ │ │ ├── email.pb.fast.go │ │ │ ├── email.pb.go │ │ │ └── emailservice │ │ │ │ ├── client.go │ │ │ │ ├── emailservice.go │ │ │ │ ├── invoker.go │ │ │ │ └── server.go │ │ ├── merchant │ │ │ ├── merchant.pb.fast.go │ │ │ ├── merchant.pb.go │ │ │ └── merchantservice │ │ │ │ ├── client.go │ │ │ │ ├── invoker.go │ │ │ │ ├── merchantservice.go │ │ │ │ └── server.go │ │ ├── order │ │ │ ├── order.pb.fast.go │ │ │ ├── order.pb.go │ │ │ └── orderservice │ │ │ │ ├── client.go │ │ │ │ ├── invoker.go │ │ │ │ ├── orderservice.go │ │ │ │ └── server.go │ │ ├── payment │ │ │ ├── payment.pb.fast.go │ │ │ ├── payment.pb.go │ │ │ └── paymentservice │ │ │ │ ├── client.go │ │ │ │ ├── invoker.go │ │ │ │ ├── paymentservice.go │ │ │ │ └── server.go │ │ ├── product │ │ │ ├── product.pb.fast.go │ │ │ ├── product.pb.go │ │ │ └── productcatalogservice │ │ │ │ ├── client.go │ │ │ │ ├── invoker.go │ │ │ │ ├── productcatalogservice.go │ │ │ │ └── server.go │ │ └── user │ │ │ ├── user.pb.fast.go │ │ │ ├── user.pb.go │ │ │ └── userservice │ │ │ ├── client.go │ │ │ ├── invoker.go │ │ │ ├── server.go │ │ │ └── userservice.go │ └── rpc │ │ ├── cart │ │ ├── cart_client.go │ │ ├── cart_default.go │ │ └── cart_init.go │ │ ├── checkout │ │ ├── checkout_client.go │ │ ├── checkout_default.go │ │ └── checkout_init.go │ │ ├── email │ │ ├── email_client.go │ │ ├── email_default.go │ │ └── email_init.go │ │ ├── merchant │ │ ├── merchant_client.go │ │ ├── merchant_default.go │ │ └── merchant_init.go │ │ ├── order │ │ ├── order_client.go │ │ ├── order_default.go │ │ └── order_init.go │ │ ├── payment │ │ ├── payment_client.go │ │ ├── payment_default.go │ │ └── payment_init.go │ │ ├── product │ │ ├── product_client.go │ │ ├── product_default.go │ │ └── product_init.go │ │ └── user │ │ ├── user_client.go │ │ ├── user_default.go │ │ └── user_init.go └── start_service.sh └── frontend ├── .gitignore ├── README.md ├── babel.config.js ├── jsconfig.json ├── package-lock.json ├── package.json ├── public ├── favicon.ico ├── index.html └── static │ └── image │ ├── logo.jpg │ ├── mouse-pad.jpeg │ ├── notebook.jpeg │ ├── sweatshirt.jpeg │ ├── t-shirt-1.jpeg │ ├── t-shirt-2.jpeg │ ├── t-shirt.jpeg │ ├── toiletry-bag.jpg │ └── toothbrush-cup.jpg ├── src ├── App.vue ├── assets │ └── logo.png ├── components │ ├── ChatDialog.vue │ ├── HelloWorld.vue │ ├── Layout.vue │ ├── ProductCard.vue │ ├── UserDropdown.vue │ └── merchant │ │ ├── Footer.vue │ │ ├── Functions.vue │ │ ├── Header.vue │ │ └── Left.vue ├── main.js ├── router │ └── index.js ├── store │ ├── index.js │ └── modules │ │ ├── auth.js │ │ ├── cart.js │ │ ├── category.js │ │ ├── merchant.js │ │ └── search.js └── views │ ├── AboutView.vue │ ├── CartView.vue │ ├── CategoryView.vue │ ├── HomeView.vue │ ├── LoginView.vue │ ├── MerchantAddProductView.vue │ ├── MerchantProductDetail.vue │ ├── MerchantProductListView.vue │ ├── OrdersView.vue │ ├── PaymentView.vue │ ├── ProductView.vue │ ├── RegisterView.vue │ └── SearchView.vue └── vue.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | tmp/ 2 | .idea/ 3 | .vscode/ 4 | log/ 5 | .DS_Store/ 6 | *.log 7 | *.exe 8 | *.so 9 | /backend/data/redis/ 10 | /backend/data/mysql/ 11 | -------------------------------------------------------------------------------- /backend/.gitignore: -------------------------------------------------------------------------------- 1 | tmp/ 2 | .idea/ 3 | .vscode/ 4 | log/ 5 | *.log 6 | *.exe 7 | *.so -------------------------------------------------------------------------------- /backend/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.23.1 2 | 3 | WORKDIR /usr/src/gomall 4 | 5 | ENV GOPROXY=https://goproxy.io,direct 6 | 7 | COPY app/frontend/go.mod app/frontend/go.sum ./app/frontend/ 8 | COPY rpc_gen rpc_gen 9 | COPY common common 10 | 11 | RUN cd app/frontend && go mod download && go mod verify 12 | 13 | COPY app/frontend app/frontend 14 | 15 | RUN cd app/frontend && go build -v -o /opt/gomall/frontend/server 16 | 17 | COPY app/frontend/conf /opt/gomall/frontend/conf 18 | COPY app/frontend/static /opt/gomall/frontend/static 19 | COPY app/frontend/template /opt/gomall/frontend/template 20 | 21 | 22 | WORKDIR /opt/gomall/frontend 23 | EXPOSE 8080 24 | CMD ["/opt/gomall/frontend/server"] -------------------------------------------------------------------------------- /backend/app/agent/.env: -------------------------------------------------------------------------------- 1 | # ark model: https://console.volcengine.com/ark 2 | # 必填, 3 | # 火山云方舟 ChatModel 的 Endpoint ID 4 | export ARK_CHAT_MODEL="ep-20250218215910-52sr2" 5 | # 火山云方舟 向量化模型的 Endpoint ID 6 | export ARK_EMBEDDING_MODEL="ep-20250218220954-wgqd4" 7 | # 火山云方舟的 API Key 8 | export ARK_API_KEY="67af9008-9918-4535-bfc2-a9d2e6cbc9c8" 9 | 10 | # langfuse: https://cloud.langfuse.com/ 11 | # 下面两个环境变量如果为空,则不开启 langfuse callback 12 | # Langfuse Project 的 Public Key 13 | export LANGFUSE_PUBLIC_KEY="" 14 | # Langfuse Project 的 Secret Key。 注意,Secret Key 仅可在被创建时查看一次 15 | export LANGFUSE_SECRET_KEY="" 16 | 17 | # Redis Server 的地址,不填写时,默认是 localhost:6379 18 | export REDIS_ADDR= 19 | -------------------------------------------------------------------------------- /backend/app/agent/docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | redis-stack: 3 | image: redis/redis-stack:latest 4 | container_name: redis-stack 5 | ports: 6 | - "6379:6379" # Redis port 7 | - "8001:8001" # RedisInsight port 8 | volumes: 9 | - ./data/redis:/data 10 | environment: 11 | - REDIS_ARGS=--dir /data --appendonly no --save 1800 1 12 | restart: unless-stopped 13 | healthcheck: 14 | test: [ "CMD", "redis-cli", "ping" ] 15 | interval: 10s 16 | timeout: 5s 17 | retries: 3 18 | -------------------------------------------------------------------------------- /backend/app/agent/eino/einoagent/types.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2025 CloudWeGo Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package einoagent 18 | 19 | import "github.com/cloudwego/eino/schema" 20 | 21 | type UserMessage struct { 22 | ID string `json:"id"` 23 | Query string `json:"query"` 24 | History []*schema.Message `json:"history"` 25 | } 26 | -------------------------------------------------------------------------------- /backend/app/agent/pkg/tool/einotool/templates/http_agent/README.md: -------------------------------------------------------------------------------- 1 | # http_agent 2 | 3 | ## 简介 4 | 5 | http_agent 是一个基于 eino 的 http 服务构建的一个简单的 llm 应用。 6 | 7 | ## 使用 8 | 9 | ### 启动 http server 10 | 11 | ```bash 12 | go run main.go -model=ep-xxxx -apikey=xxx 13 | ``` 14 | 15 | ### 使用 curl 访问 http server 16 | 17 | ```bash 18 | curl 'http://127.0.0.1:8888/chat?id=123&msg=hello' 19 | ``` 20 | > 注意,由于采用了 sse 的格式,结果中会有 `data:` 前缀 21 | 22 | ### 使用 client 23 | 24 | client 是一个简单的交互式客户端,可以与 http server 进行交互,并打印结果。 25 | 26 | ```bash 27 | go run client/main.go 28 | ``` 29 | -------------------------------------------------------------------------------- /backend/app/cart/.env: -------------------------------------------------------------------------------- 1 | MYSQL_USER=root 2 | MYSQL_PASSWORD=K8#tP2@y!mL9 3 | MYSQL_HOST=127.0.0.1 4 | SESSION_SECRET="KJLAJKLJLSF" -------------------------------------------------------------------------------- /backend/app/cart/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.a 3 | *.so 4 | _obj 5 | _test 6 | *.[568vq] 7 | [568vq].out 8 | *.cgo1.go 9 | *.cgo2.c 10 | _cgo_defun.c 11 | _cgo_gotypes.go 12 | _cgo_export.* 13 | _testmain.go 14 | *.exe 15 | *.exe~ 16 | *.test 17 | *.prof 18 | *.rar 19 | *.zip 20 | *.gz 21 | *.psd 22 | *.bmd 23 | *.cfg 24 | *.pptx 25 | *.log 26 | *nohup.out 27 | *settings.pyc 28 | *.sublime-project 29 | *.sublime-workspace 30 | !.gitkeep 31 | .DS_Store 32 | /.idea 33 | /.vscode 34 | /output 35 | *.local.yml 36 | -------------------------------------------------------------------------------- /backend/app/cart/biz/dal/init.go: -------------------------------------------------------------------------------- 1 | package dal 2 | 3 | import ( 4 | "github.com/tiktokmall/backend/app/cart/biz/dal/mysql" 5 | "github.com/tiktokmall/backend/app/cart/biz/dal/redis" 6 | ) 7 | 8 | func Init() { 9 | redis.Init() 10 | mysql.Init() 11 | } 12 | -------------------------------------------------------------------------------- /backend/app/cart/biz/dal/mysql/init.go: -------------------------------------------------------------------------------- 1 | package mysql 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | 7 | "github.com/tiktokmall/backend/app/cart/biz/model" 8 | "github.com/tiktokmall/backend/app/cart/conf" 9 | 10 | "gorm.io/driver/mysql" 11 | "gorm.io/gorm" 12 | "gorm.io/plugin/opentelemetry/tracing" 13 | ) 14 | 15 | var ( 16 | DB *gorm.DB 17 | err error 18 | ) 19 | 20 | func Init() { 21 | dsn := fmt.Sprintf(conf.GetConf().MySQL.DSN, os.Getenv("MYSQL_USER"), os.Getenv("MYSQL_PASSWORD"), os.Getenv("MYSQL_HOST")) 22 | DB, err = gorm.Open(mysql.Open(dsn), 23 | &gorm.Config{ 24 | PrepareStmt: true, 25 | SkipDefaultTransaction: true, 26 | }, 27 | ) 28 | if err != nil { 29 | panic(err) 30 | } 31 | if err := DB.Use(tracing.NewPlugin(tracing.WithoutMetrics())); err != nil { 32 | panic(err) 33 | } 34 | if os.Getenv("GO_ENV") != "online" { 35 | DB.AutoMigrate( 36 | &model.Cart{}, 37 | ) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /backend/app/cart/biz/dal/redis/init.go: -------------------------------------------------------------------------------- 1 | package redis 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/redis/go-redis/v9" 7 | "github.com/tiktokmall/backend/app/cart/conf" 8 | ) 9 | 10 | var ( 11 | RedisClient *redis.Client 12 | ) 13 | 14 | func Init() { 15 | RedisClient = redis.NewClient(&redis.Options{ 16 | Addr: conf.GetConf().Redis.Address, 17 | Username: conf.GetConf().Redis.Username, 18 | Password: conf.GetConf().Redis.Password, 19 | DB: conf.GetConf().Redis.DB, 20 | }) 21 | if err := RedisClient.Ping(context.Background()).Err(); err != nil { 22 | panic(err) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /backend/app/cart/biz/model/base.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "time" 4 | 5 | type Base struct { 6 | ID int `gorm:"primarykey"` 7 | CreatedAt time.Time 8 | UpdatedAt time.Time 9 | } 10 | -------------------------------------------------------------------------------- /backend/app/cart/biz/service/add_item_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | cart "github.com/tiktokmall/backend/rpc_gen/kitex_gen/cart" 8 | ) 9 | 10 | func TestAddItem_Run(t *testing.T) { 11 | ctx := context.Background() 12 | s := NewAddItemService(ctx) 13 | // init req and assert value 14 | 15 | req := &cart.AddItemReq{} 16 | resp, err := s.Run(req) 17 | t.Logf("err: %v", err) 18 | t.Logf("resp: %v", resp) 19 | 20 | // todo: edit your unit test 21 | 22 | } 23 | -------------------------------------------------------------------------------- /backend/app/cart/biz/service/change_qty_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | cart "github.com/tiktokmall/backend/rpc_gen/kitex_gen/cart" 7 | ) 8 | 9 | func TestChangeQty_Run(t *testing.T) { 10 | ctx := context.Background() 11 | s := NewChangeQtyService(ctx) 12 | // init req and assert value 13 | 14 | req := &cart.ChangeQtyReq{} 15 | resp, err := s.Run(req) 16 | t.Logf("err: %v", err) 17 | t.Logf("resp: %v", resp) 18 | 19 | // todo: edit your unit test 20 | 21 | } 22 | -------------------------------------------------------------------------------- /backend/app/cart/biz/service/empty_cart.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/tiktokmall/backend/app/cart/biz/dal/mysql" 7 | "github.com/tiktokmall/backend/app/cart/biz/model" 8 | cart "github.com/tiktokmall/backend/rpc_gen/kitex_gen/cart" 9 | 10 | "github.com/cloudwego/kitex/pkg/kerrors" 11 | ) 12 | 13 | type EmptyCartService struct { 14 | ctx context.Context 15 | } // NewEmptyCartService new EmptyCartService 16 | func NewEmptyCartService(ctx context.Context) *EmptyCartService { 17 | return &EmptyCartService{ctx: ctx} 18 | } 19 | 20 | // Run create note info 21 | func (s *EmptyCartService) Run(req *cart.EmptyCartReq) (resp *cart.EmptyCartResp, err error) { 22 | // Finish your business logic. 23 | if req.UserId == 0 { 24 | return nil, kerrors.NewBizStatusError(40004, "user_id is required") 25 | } 26 | err = model.EmptyCart(s.ctx, mysql.DB, req.UserId) 27 | if err != nil { 28 | return nil, kerrors.NewBizStatusError(50000, err.Error()) 29 | } 30 | return &cart.EmptyCartResp{}, nil 31 | } 32 | -------------------------------------------------------------------------------- /backend/app/cart/biz/service/empty_cart_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | cart "github.com/tiktokmall/backend/rpc_gen/kitex_gen/cart" 8 | ) 9 | 10 | func TestEmptyCart_Run(t *testing.T) { 11 | ctx := context.Background() 12 | s := NewEmptyCartService(ctx) 13 | // init req and assert value 14 | 15 | req := &cart.EmptyCartReq{} 16 | resp, err := s.Run(req) 17 | t.Logf("err: %v", err) 18 | t.Logf("resp: %v", resp) 19 | 20 | // todo: edit your unit test 21 | 22 | } 23 | -------------------------------------------------------------------------------- /backend/app/cart/biz/service/get_cart_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | cart "github.com/tiktokmall/backend/rpc_gen/kitex_gen/cart" 8 | ) 9 | 10 | func TestGetCart_Run(t *testing.T) { 11 | ctx := context.Background() 12 | s := NewGetCartService(ctx) 13 | // init req and assert value 14 | 15 | req := &cart.GetCartReq{} 16 | resp, err := s.Run(req) 17 | t.Logf("err: %v", err) 18 | t.Logf("resp: %v", resp) 19 | 20 | // todo: edit your unit test 21 | 22 | } 23 | -------------------------------------------------------------------------------- /backend/app/cart/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | RUN_NAME="cart" 3 | mkdir -p output/bin output/conf 4 | cp script/* output/ 5 | cp -r conf/* output/conf 6 | chmod +x output/bootstrap.sh 7 | go build -o output/bin/${RUN_NAME} 8 | -------------------------------------------------------------------------------- /backend/app/cart/conf/dev/conf.yaml: -------------------------------------------------------------------------------- 1 | kitex: 2 | service: "cart" 3 | address: ":8883" 4 | metrics_port: ":9993" 5 | log_level: info 6 | log_file_name: "log/kitex.log" 7 | log_max_size: 10 8 | log_max_age: 3 9 | log_max_backups: 50 10 | 11 | registry: 12 | registry_address: 13 | - consul:8500 14 | username: "" 15 | password: "" 16 | 17 | mysql: 18 | dsn: "%s:%s@tcp(%s:3306)/cart?charset=utf8mb4&parseTime=True&loc=Local" 19 | 20 | redis: 21 | address: "redis:6379" 22 | username: "" 23 | password: "" 24 | db: 0 25 | -------------------------------------------------------------------------------- /backend/app/cart/conf/online/conf.yaml: -------------------------------------------------------------------------------- 1 | kitex: 2 | service: "cart" 3 | address: ":8883" 4 | metrics_port: ":9993" 5 | log_level: info 6 | log_file_name: "log/kitex.log" 7 | log_max_size: 10 8 | log_max_age: 3 9 | log_max_backups: 50 10 | 11 | registry: 12 | registry_address: 13 | - consul:8500 14 | username: "" 15 | password: "" 16 | 17 | mysql: 18 | dsn: "%s:%s@tcp(%s:3306)/cart?charset=utf8mb4&parseTime=True&loc=Local" 19 | 20 | redis: 21 | address: "redis:6379" 22 | username: "" 23 | password: "" 24 | db: 0 25 | -------------------------------------------------------------------------------- /backend/app/cart/conf/test/conf.yaml: -------------------------------------------------------------------------------- 1 | kitex: 2 | service: "cart" 3 | address: ":8883" 4 | metrics_port: ":9993" 5 | log_level: info 6 | log_file_name: "log/kitex.log" 7 | log_max_size: 10 8 | log_max_age: 3 9 | log_max_backups: 50 10 | 11 | registry: 12 | registry_address: 13 | - 127.0.0.1:8500 14 | username: "" 15 | password: "" 16 | 17 | mysql: 18 | dsn: "%s:%s@tcp(%s:3306)/cart?charset=utf8mb4&parseTime=True&loc=Local" 19 | 20 | redis: 21 | address: "127.0.0.1:6379" 22 | username: "" 23 | password: "" 24 | db: 0 25 | -------------------------------------------------------------------------------- /backend/app/cart/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | mysql: 4 | image: 'mysql:latest' 5 | ports: 6 | - 3306:3306 7 | environment: 8 | - MYSQL_DATABASE=gorm 9 | - MYSQL_USER=gorm 10 | - MYSQL_PASSWORD=gorm 11 | - MYSQL_RANDOM_ROOT_PASSWORD="yes" 12 | redis: 13 | image: 'redis:latest' 14 | ports: 15 | - 6379:6379 16 | -------------------------------------------------------------------------------- /backend/app/cart/infra/rpc/client.go: -------------------------------------------------------------------------------- 1 | package rpc 2 | 3 | import ( 4 | "sync" 5 | 6 | "github.com/tiktokmall/backend/common/clientsuite" 7 | "github.com/tiktokmall/backend/rpc_gen/kitex_gen/product/productcatalogservice" 8 | 9 | "github.com/tiktokmall/backend/app/cart/conf" 10 | cartUtils "github.com/tiktokmall/backend/app/cart/utils" 11 | 12 | "github.com/cloudwego/kitex/client" 13 | ) 14 | 15 | // client 进行服务发现 16 | 17 | var ( 18 | ProductClient productcatalogservice.Client 19 | once sync.Once 20 | err error 21 | registryAddr string 22 | serviceName string 23 | ) 24 | 25 | func Init() { 26 | once.Do(func() { 27 | registryAddr = conf.GetConf().Registry.RegistryAddress[0] 28 | serviceName = conf.GetConf().Kitex.Service 29 | initProductClient() 30 | }) 31 | } 32 | 33 | func initProductClient() { 34 | opts := []client.Option{ 35 | client.WithSuite(clientsuite.CommonServerSuite{ 36 | RegistryAddr: registryAddr, 37 | CurrentServiceName: serviceName, 38 | }), 39 | } 40 | ProductClient, err = productcatalogservice.NewClient("product", opts...) 41 | cartUtils.MustHandleError(err) 42 | } 43 | -------------------------------------------------------------------------------- /backend/app/cart/kitex_info.yaml: -------------------------------------------------------------------------------- 1 | kitexinfo: 2 | ServiceName: 'cart' 3 | ToolVersion: 'v0.9.1' 4 | -------------------------------------------------------------------------------- /backend/app/cart/readme.md: -------------------------------------------------------------------------------- 1 | # *** Project 2 | 3 | ## introduce 4 | 5 | - Use the [Kitex](https://github.com/cloudwego/kitex/) framework 6 | - Generating the base code for unit tests. 7 | - Provides basic config functions 8 | - Provides the most basic MVC code hierarchy. 9 | 10 | ## Directory structure 11 | 12 | | catalog | introduce | 13 | | ---- | ---- | 14 | | conf | Configuration files | 15 | | main.go | Startup file | 16 | | handler.go | Used for request processing return of response. | 17 | | kitex_gen | kitex generated code | 18 | | biz/service | The actual business logic. | 19 | | biz/dal | Logic for operating the storage layer | 20 | 21 | ## How to run 22 | 23 | ```shell 24 | sh build.sh 25 | sh output/bootstrap.sh 26 | ``` 27 | -------------------------------------------------------------------------------- /backend/app/cart/script/bootstrap.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | CURDIR=$(cd $(dirname $0); pwd) 3 | echo "$CURDIR/bin/cart" 4 | exec "$CURDIR/bin/cart" 5 | -------------------------------------------------------------------------------- /backend/app/cart/utils/constant.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | type SessionUserIdKey string 4 | 5 | const SessionUserId SessionUserIdKey = "user_id" 6 | -------------------------------------------------------------------------------- /backend/app/cart/utils/errors.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "github.com/cloudwego/kitex/pkg/klog" 5 | ) 6 | 7 | func MustHandleError(err error) { 8 | if err != nil { 9 | klog.Fatal(err) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /backend/app/cart/utils/function.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | ) 7 | 8 | func GetUserIdFromCtx(ctx context.Context) int32 { 9 | userId := ctx.Value(SessionUserId) 10 | if userId == nil { 11 | return 0 12 | } 13 | fmt.Println("userId", userId) 14 | 15 | return userId.(int32) 16 | } 17 | -------------------------------------------------------------------------------- /backend/app/checkout/.env: -------------------------------------------------------------------------------- 1 | MYSQL_USER=root 2 | MYSQL_PASSWORD=K8#tP2@y!mL9 3 | MYSQL_HOST=127.0.0.1 4 | SESSION_SECRET="KJLAJKLJLSF" -------------------------------------------------------------------------------- /backend/app/checkout/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.a 3 | *.so 4 | _obj 5 | _test 6 | *.[568vq] 7 | [568vq].out 8 | *.cgo1.go 9 | *.cgo2.c 10 | _cgo_defun.c 11 | _cgo_gotypes.go 12 | _cgo_export.* 13 | _testmain.go 14 | *.exe 15 | *.exe~ 16 | *.test 17 | *.prof 18 | *.rar 19 | *.zip 20 | *.gz 21 | *.psd 22 | *.bmd 23 | *.cfg 24 | *.pptx 25 | *.log 26 | *nohup.out 27 | *settings.pyc 28 | *.sublime-project 29 | *.sublime-workspace 30 | !.gitkeep 31 | .DS_Store 32 | /.idea 33 | /.vscode 34 | /output 35 | *.local.yml 36 | -------------------------------------------------------------------------------- /backend/app/checkout/biz/dal/init.go: -------------------------------------------------------------------------------- 1 | package dal 2 | 3 | import ( 4 | "github.com/tiktokmall/backend/app/checkout/biz/dal/mysql" 5 | "github.com/tiktokmall/backend/app/checkout/biz/dal/redis" 6 | ) 7 | 8 | func Init() { 9 | redis.Init() 10 | mysql.Init() 11 | } 12 | -------------------------------------------------------------------------------- /backend/app/checkout/biz/dal/mysql/init.go: -------------------------------------------------------------------------------- 1 | package mysql 2 | 3 | import ( 4 | "github.com/tiktokmall/backend/app/checkout/conf" 5 | 6 | "gorm.io/driver/mysql" 7 | "gorm.io/gorm" 8 | ) 9 | 10 | var ( 11 | DB *gorm.DB 12 | err error 13 | ) 14 | 15 | func Init() { 16 | DB, err = gorm.Open(mysql.Open(conf.GetConf().MySQL.DSN), 17 | &gorm.Config{ 18 | PrepareStmt: true, 19 | SkipDefaultTransaction: true, 20 | }, 21 | ) 22 | if err != nil { 23 | panic(err) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /backend/app/checkout/biz/dal/redis/init.go: -------------------------------------------------------------------------------- 1 | package redis 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/redis/go-redis/v9" 7 | "github.com/tiktokmall/backend/app/checkout/conf" 8 | ) 9 | 10 | var ( 11 | RedisClient *redis.Client 12 | ) 13 | 14 | func Init() { 15 | RedisClient = redis.NewClient(&redis.Options{ 16 | Addr: conf.GetConf().Redis.Address, 17 | Username: conf.GetConf().Redis.Username, 18 | Password: conf.GetConf().Redis.Password, 19 | DB: conf.GetConf().Redis.DB, 20 | }) 21 | if err := RedisClient.Ping(context.Background()).Err(); err != nil { 22 | panic(err) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /backend/app/checkout/biz/service/checkout_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | checkout "github.com/tiktokmall/backend/rpc_gen/kitex_gen/checkout" 8 | ) 9 | 10 | func TestCheckout_Run(t *testing.T) { 11 | ctx := context.Background() 12 | s := NewCheckoutService(ctx) 13 | // init req and assert value 14 | 15 | req := &checkout.CheckoutReq{} 16 | resp, err := s.Run(req) 17 | t.Logf("err: %v", err) 18 | t.Logf("resp: %v", resp) 19 | 20 | // todo: edit your unit test 21 | 22 | } 23 | -------------------------------------------------------------------------------- /backend/app/checkout/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | RUN_NAME="checkout" 3 | mkdir -p output/bin output/conf 4 | cp script/* output/ 5 | cp -r conf/* output/conf 6 | chmod +x output/bootstrap.sh 7 | go build -o output/bin/${RUN_NAME} 8 | -------------------------------------------------------------------------------- /backend/app/checkout/conf/dev/conf.yaml: -------------------------------------------------------------------------------- 1 | kitex: 2 | service: "checkout" 3 | address: ":8885" 4 | metrics_port: ":9995" 5 | log_level: info 6 | log_file_name: "log/kitex.log" 7 | log_max_size: 10 8 | log_max_age: 3 9 | log_max_backups: 50 10 | 11 | registry: 12 | registry_address: 13 | - consul:8500 14 | username: "" 15 | password: "" 16 | 17 | mysql: 18 | dsn: "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8mb4&parseTime=True&loc=Local" 19 | 20 | redis: 21 | address: "redis:6379" 22 | username: "" 23 | password: "" 24 | db: 0 25 | 26 | nats: 27 | address: "nats://nats:4222" 28 | -------------------------------------------------------------------------------- /backend/app/checkout/conf/online/conf.yaml: -------------------------------------------------------------------------------- 1 | kitex: 2 | service: "checkout" 3 | address: ":8885" 4 | metrics_port: ":9995" 5 | log_level: info 6 | log_file_name: "log/kitex.log" 7 | log_max_size: 10 8 | log_max_age: 3 9 | log_max_backups: 50 10 | 11 | registry: 12 | registry_address: 13 | - consul:8500 14 | username: "" 15 | password: "" 16 | 17 | mysql: 18 | dsn: "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8mb4&parseTime=True&loc=Local" 19 | 20 | redis: 21 | address: "redis:6379" 22 | username: "" 23 | password: "" 24 | db: 0 25 | 26 | nats: 27 | address: "nats://nats:4222" 28 | -------------------------------------------------------------------------------- /backend/app/checkout/conf/test/conf.yaml: -------------------------------------------------------------------------------- 1 | kitex: 2 | service: "checkout" 3 | address: ":8885" 4 | metrics_port: ":9995" 5 | log_level: info 6 | log_file_name: "log/kitex.log" 7 | log_max_size: 10 8 | log_max_age: 3 9 | log_max_backups: 50 10 | 11 | registry: 12 | registry_address: 13 | - 127.0.0.1:8500 14 | username: "" 15 | password: "" 16 | 17 | mysql: 18 | dsn: "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8mb4&parseTime=True&loc=Local" 19 | 20 | redis: 21 | address: "127.0.0.1:6379" 22 | username: "" 23 | password: "" 24 | db: 0 25 | 26 | nats: 27 | address: "nats://127.0.0.1:4222" -------------------------------------------------------------------------------- /backend/app/checkout/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | mysql: 4 | image: 'mysql:latest' 5 | ports: 6 | - 3306:3306 7 | environment: 8 | - MYSQL_DATABASE=gorm 9 | - MYSQL_USER=gorm 10 | - MYSQL_PASSWORD=gorm 11 | - MYSQL_RANDOM_ROOT_PASSWORD="yes" 12 | redis: 13 | image: 'redis:latest' 14 | ports: 15 | - 6379:6379 16 | -------------------------------------------------------------------------------- /backend/app/checkout/handler.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/tiktokmall/backend/app/checkout/biz/service" 7 | checkout "github.com/tiktokmall/backend/rpc_gen/kitex_gen/checkout" 8 | ) 9 | 10 | // CheckoutServiceImpl implements the last service interface defined in the IDL. 11 | type CheckoutServiceImpl struct{} 12 | 13 | // Checkout implements the CheckoutServiceImpl interface. 14 | func (s *CheckoutServiceImpl) Checkout(ctx context.Context, req *checkout.CheckoutReq) (resp *checkout.CheckoutResp, err error) { 15 | resp, err = service.NewCheckoutService(ctx).Run(req) 16 | 17 | return resp, err 18 | } 19 | -------------------------------------------------------------------------------- /backend/app/checkout/infra/mq/nats.go: -------------------------------------------------------------------------------- 1 | package mq 2 | 3 | import ( 4 | "github.com/tiktokmall/backend/app/checkout/conf" 5 | 6 | "github.com/nats-io/nats.go" 7 | ) 8 | 9 | var ( 10 | Nc *nats.Conn 11 | err error 12 | ) 13 | 14 | func Init() { 15 | Nc, err = nats.Connect(conf.GetConf().Nats.Address) 16 | if err != nil { 17 | panic(err) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /backend/app/checkout/kitex_info.yaml: -------------------------------------------------------------------------------- 1 | kitexinfo: 2 | ServiceName: 'checkout' 3 | ToolVersion: 'v0.9.1' 4 | -------------------------------------------------------------------------------- /backend/app/checkout/readme.md: -------------------------------------------------------------------------------- 1 | # *** Project 2 | 3 | ## introduce 4 | 5 | - Use the [Kitex](https://github.com/cloudwego/kitex/) framework 6 | - Generating the base code for unit tests. 7 | - Provides basic config functions 8 | - Provides the most basic MVC code hierarchy. 9 | 10 | ## Directory structure 11 | 12 | | catalog | introduce | 13 | | ---- | ---- | 14 | | conf | Configuration files | 15 | | main.go | Startup file | 16 | | handler.go | Used for request processing return of response. | 17 | | kitex_gen | kitex generated code | 18 | | biz/service | The actual business logic. | 19 | | biz/dal | Logic for operating the storage layer | 20 | 21 | ## How to run 22 | 23 | ```shell 24 | sh build.sh 25 | sh output/bootstrap.sh 26 | ``` 27 | -------------------------------------------------------------------------------- /backend/app/checkout/script/bootstrap.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | CURDIR=$(cd $(dirname $0); pwd) 3 | echo "$CURDIR/bin/checkout" 4 | exec "$CURDIR/bin/checkout" 5 | -------------------------------------------------------------------------------- /backend/app/checkout/utils/errors.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "github.com/cloudwego/kitex/pkg/klog" 5 | ) 6 | 7 | func MustHandleError(err error) { 8 | if err != nil { 9 | klog.Fatal(err) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /backend/app/email/.env: -------------------------------------------------------------------------------- 1 | MYSQL_USER=root 2 | MYSQL_PASSWORD=K8#tP2@y!mL9 3 | MYSQL_HOST=127.0.0.1 4 | SESSION_SECRET="KJLAJKLJLSF" -------------------------------------------------------------------------------- /backend/app/email/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.a 3 | *.so 4 | _obj 5 | _test 6 | *.[568vq] 7 | [568vq].out 8 | *.cgo1.go 9 | *.cgo2.c 10 | _cgo_defun.c 11 | _cgo_gotypes.go 12 | _cgo_export.* 13 | _testmain.go 14 | *.exe 15 | *.exe~ 16 | *.test 17 | *.prof 18 | *.rar 19 | *.zip 20 | *.gz 21 | *.psd 22 | *.bmd 23 | *.cfg 24 | *.pptx 25 | *.log 26 | *nohup.out 27 | *settings.pyc 28 | *.sublime-project 29 | *.sublime-workspace 30 | !.gitkeep 31 | .DS_Store 32 | /.idea 33 | /.vscode 34 | /output 35 | *.local.yml 36 | -------------------------------------------------------------------------------- /backend/app/email/biz/consumer/consumer.go: -------------------------------------------------------------------------------- 1 | package consumer 2 | 3 | import "github.com/tiktokmall/backend/app/email/biz/consumer/email" 4 | 5 | func Init() { 6 | email.ConsumerInit() 7 | } 8 | -------------------------------------------------------------------------------- /backend/app/email/biz/consumer/email/email_test.go: -------------------------------------------------------------------------------- 1 | package email 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "os" 7 | "testing" 8 | "time" 9 | 10 | "github.com/tiktokmall/backend/app/email/infra/mq" 11 | "github.com/tiktokmall/backend/rpc_gen/kitex_gen/email" 12 | "google.golang.org/protobuf/proto" 13 | ) 14 | 15 | func TestConsumerInit(t *testing.T) { 16 | os.Chdir("../../../") 17 | mq.Init() 18 | go ConsumerInit() 19 | time.Sleep(time.Second) 20 | go func() { 21 | count := 1 22 | for { 23 | req := email.EmailReq{ 24 | Content: fmt.Sprintf("%v", count), 25 | } 26 | data, err := proto.Marshal(&req) 27 | if err != nil { 28 | log.Printf("marshal err: %v", err) 29 | continue 30 | } 31 | log.Printf("publish msg, %+v", req) 32 | mq.Nc.Publish("email", data) 33 | count++ 34 | time.Sleep(time.Second) 35 | } 36 | }() 37 | time.Sleep(10 * time.Second) 38 | } 39 | -------------------------------------------------------------------------------- /backend/app/email/biz/dal/init.go: -------------------------------------------------------------------------------- 1 | package dal 2 | 3 | import ( 4 | "github.com/tiktokmall/backend/app/email/biz/dal/mysql" 5 | "github.com/tiktokmall/backend/app/email/biz/dal/redis" 6 | ) 7 | 8 | func Init() { 9 | redis.Init() 10 | mysql.Init() 11 | } 12 | -------------------------------------------------------------------------------- /backend/app/email/biz/dal/mysql/init.go: -------------------------------------------------------------------------------- 1 | package mysql 2 | 3 | import ( 4 | "github.com/tiktokmall/backend/app/email/conf" 5 | 6 | "gorm.io/driver/mysql" 7 | "gorm.io/gorm" 8 | ) 9 | 10 | var ( 11 | DB *gorm.DB 12 | err error 13 | ) 14 | 15 | func Init() { 16 | DB, err = gorm.Open(mysql.Open(conf.GetConf().MySQL.DSN), 17 | &gorm.Config{ 18 | PrepareStmt: true, 19 | SkipDefaultTransaction: true, 20 | }, 21 | ) 22 | if err != nil { 23 | panic(err) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /backend/app/email/biz/dal/redis/init.go: -------------------------------------------------------------------------------- 1 | package redis 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/redis/go-redis/v9" 7 | "github.com/tiktokmall/backend/app/email/conf" 8 | ) 9 | 10 | var ( 11 | RedisClient *redis.Client 12 | ) 13 | 14 | func Init() { 15 | RedisClient = redis.NewClient(&redis.Options{ 16 | Addr: conf.GetConf().Redis.Address, 17 | Username: conf.GetConf().Redis.Username, 18 | Password: conf.GetConf().Redis.Password, 19 | DB: conf.GetConf().Redis.DB, 20 | }) 21 | if err := RedisClient.Ping(context.Background()).Err(); err != nil { 22 | panic(err) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /backend/app/email/biz/service/send.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | email "github.com/tiktokmall/backend/rpc_gen/kitex_gen/email" 7 | ) 8 | 9 | type SendService struct { 10 | ctx context.Context 11 | } // NewSendService new SendService 12 | func NewSendService(ctx context.Context) *SendService { 13 | return &SendService{ctx: ctx} 14 | } 15 | 16 | // Run create note info 17 | func (s *SendService) Run(req *email.EmailReq) (resp *email.EmailResp, err error) { 18 | // Finish your business logic. 19 | 20 | return 21 | } 22 | -------------------------------------------------------------------------------- /backend/app/email/biz/service/send_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | email "github.com/tiktokmall/backend/rpc_gen/kitex_gen/email" 8 | ) 9 | 10 | func TestSend_Run(t *testing.T) { 11 | ctx := context.Background() 12 | s := NewSendService(ctx) 13 | // init req and assert value 14 | 15 | req := &email.EmailReq{} 16 | resp, err := s.Run(req) 17 | t.Logf("err: %v", err) 18 | t.Logf("resp: %v", resp) 19 | 20 | // todo: edit your unit test 21 | 22 | } 23 | -------------------------------------------------------------------------------- /backend/app/email/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | RUN_NAME="email" 3 | mkdir -p output/bin output/conf 4 | cp script/* output/ 5 | cp -r conf/* output/conf 6 | chmod +x output/bootstrap.sh 7 | go build -o output/bin/${RUN_NAME} 8 | -------------------------------------------------------------------------------- /backend/app/email/conf/dev/conf.yaml: -------------------------------------------------------------------------------- 1 | kitex: 2 | service: "email" 3 | address: ":8887" 4 | metrics_port: ":9997" 5 | log_level: info 6 | log_file_name: "log/kitex.log" 7 | log_max_size: 10 8 | log_max_age: 3 9 | log_max_backups: 50 10 | 11 | registry: 12 | registry_address: 13 | - consul:8500 14 | username: "" 15 | password: "" 16 | 17 | mysql: 18 | dsn: "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8mb4&parseTime=True&loc=Local" 19 | 20 | redis: 21 | address: "redis:6379" 22 | username: "" 23 | password: "" 24 | db: 0 25 | 26 | nats: 27 | address: "nats://nats:4222" 28 | -------------------------------------------------------------------------------- /backend/app/email/conf/online/conf.yaml: -------------------------------------------------------------------------------- 1 | kitex: 2 | service: "email" 3 | address: ":8887" 4 | metrics_port: ":9997" 5 | log_level: info 6 | log_file_name: "log/kitex.log" 7 | log_max_size: 10 8 | log_max_age: 3 9 | log_max_backups: 50 10 | 11 | registry: 12 | registry_address: 13 | - consul:8500 14 | username: "" 15 | password: "" 16 | 17 | mysql: 18 | dsn: "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8mb4&parseTime=True&loc=Local" 19 | 20 | redis: 21 | address: "redis:6379" 22 | username: "" 23 | password: "" 24 | db: 0 25 | 26 | nats: 27 | address: "nats://nats:4222" -------------------------------------------------------------------------------- /backend/app/email/conf/test/conf.yaml: -------------------------------------------------------------------------------- 1 | kitex: 2 | service: "email" 3 | address: ":8887" 4 | metrics_port: ":9997" 5 | log_level: info 6 | log_file_name: "log/kitex.log" 7 | log_max_size: 10 8 | log_max_age: 3 9 | log_max_backups: 50 10 | 11 | registry: 12 | registry_address: 13 | - 127.0.0.1:8500 14 | username: "" 15 | password: "" 16 | 17 | mysql: 18 | dsn: "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8mb4&parseTime=True&loc=Local" 19 | 20 | redis: 21 | address: "127.0.0.1:6379" 22 | username: "" 23 | password: "" 24 | db: 0 25 | 26 | nats: 27 | address: "nats://127.0.0.1:4222" -------------------------------------------------------------------------------- /backend/app/email/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | mysql: 4 | image: 'mysql:latest' 5 | ports: 6 | - 3306:3306 7 | environment: 8 | - MYSQL_DATABASE=gorm 9 | - MYSQL_USER=gorm 10 | - MYSQL_PASSWORD=gorm 11 | - MYSQL_RANDOM_ROOT_PASSWORD="yes" 12 | redis: 13 | image: 'redis:latest' 14 | ports: 15 | - 6379:6379 16 | 17 | -------------------------------------------------------------------------------- /backend/app/email/handler.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/tiktokmall/backend/app/email/biz/service" 7 | email "github.com/tiktokmall/backend/rpc_gen/kitex_gen/email" 8 | ) 9 | 10 | // EmailServiceImpl implements the last service interface defined in the IDL. 11 | type EmailServiceImpl struct{} 12 | 13 | // Send implements the EmailServiceImpl interface. 14 | func (s *EmailServiceImpl) Send(ctx context.Context, req *email.EmailReq) (resp *email.EmailResp, err error) { 15 | resp, err = service.NewSendService(ctx).Run(req) 16 | 17 | return resp, err 18 | } 19 | -------------------------------------------------------------------------------- /backend/app/email/infra/mq/nats.go: -------------------------------------------------------------------------------- 1 | package mq 2 | 3 | import ( 4 | "github.com/tiktokmall/backend/app/email/conf" 5 | 6 | "github.com/nats-io/nats.go" 7 | ) 8 | 9 | var ( 10 | Nc *nats.Conn 11 | err error 12 | ) 13 | 14 | func Init() { 15 | Nc, err = nats.Connect(conf.GetConf().Nats.Address) 16 | if err != nil { 17 | panic(err) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /backend/app/email/infra/notify/email.go: -------------------------------------------------------------------------------- 1 | package notify 2 | 3 | import ( 4 | "github.com/tiktokmall/backend/rpc_gen/kitex_gen/email" 5 | 6 | "github.com/kr/pretty" 7 | ) 8 | 9 | type NoopEmail struct{} 10 | 11 | func (e *NoopEmail) Send(req *email.EmailReq) error { 12 | // 处理,只是打印一下 req 13 | pretty.Printf("%v\n", req) 14 | return nil 15 | } 16 | 17 | func NewNoopEmail() NoopEmail { 18 | return NoopEmail{} 19 | } 20 | -------------------------------------------------------------------------------- /backend/app/email/kitex_info.yaml: -------------------------------------------------------------------------------- 1 | kitexinfo: 2 | ServiceName: 'email' 3 | ToolVersion: 'v0.9.1' 4 | -------------------------------------------------------------------------------- /backend/app/email/readme.md: -------------------------------------------------------------------------------- 1 | # *** Project 2 | 3 | ## introduce 4 | 5 | - Use the [Kitex](https://github.com/cloudwego/kitex/) framework 6 | - Generating the base code for unit tests. 7 | - Provides basic config functions 8 | - Provides the most basic MVC code hierarchy. 9 | 10 | ## Directory structure 11 | 12 | | catalog | introduce | 13 | | ---- | ---- | 14 | | conf | Configuration files | 15 | | main.go | Startup file | 16 | | handler.go | Used for request processing return of response. | 17 | | kitex_gen | kitex generated code | 18 | | biz/service | The actual business logic. | 19 | | biz/dal | Logic for operating the storage layer | 20 | 21 | ## How to run 22 | 23 | ```shell 24 | sh build.sh 25 | sh output/bootstrap.sh 26 | ``` 27 | -------------------------------------------------------------------------------- /backend/app/email/script/bootstrap.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | CURDIR=$(cd $(dirname $0); pwd) 3 | echo "$CURDIR/bin/email" 4 | exec "$CURDIR/bin/email" 5 | -------------------------------------------------------------------------------- /backend/app/frontend/.env: -------------------------------------------------------------------------------- 1 | MYSQL_USER=root 2 | MYSQL_PASSWORD=K8#tP2@y!mL9 3 | MYSQL_HOST=127.0.0.1 4 | SESSION_SECRET="KJLAJKLJLSF" 5 | SecretKey="tiktokmall" 6 | IdentityKey = "id" 7 | 8 | OSS_ACCESS_KEY_ID="LTAI5tC3VZ1hcwKsSuA4ZniM" 9 | OSS_ACCESS_KEY_SECRET="tRXb4YVzHr1jIebfxs3i5dGtbJ9LdV" 10 | 11 | # ark model: https://console.volcengine.com/ark 12 | # 必填, 13 | # 火山云方舟 ChatModel 的 Endpoint ID 14 | ARK_CHAT_MODEL="ep-20250218215910-52sr2" 15 | # 火山云方舟 向量化模型的 Endpoint ID 16 | ARK_EMBEDDING_MODEL="ep-20250218220954-wgqd4" 17 | # 火山云方舟的 API Key 18 | ARK_API_KEY="67af9008-9918-4535-bfc2-a9d2e6cbc9c8" 19 | 20 | # langfuse: https://cloud.langfuse.com/ 21 | # 下面两个环境变量如果为空,则不开启 langfuse callback 22 | # Langfuse Project 的 Public Key 23 | LANGFUSE_PUBLIC_KEY="pk-lf-0e8ef1b4-ff48-418e-a51a-ef4083f111ec" 24 | # Langfuse Project 的 Secret Key。 注意,Secret Key 仅可在被创建时查看一次 25 | LANGFUSE_SECRET_KEY="sk-lf-6d61a49e-311b-43fa-8405-5d583c40cfab" 26 | 27 | # Redis Server 的地址,不填写时,默认是 localhost:6379 28 | # export REDIS_ADDR= -------------------------------------------------------------------------------- /backend/app/frontend/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.a 3 | *.so 4 | _obj 5 | _test 6 | *.[568vq] 7 | [568vq].out 8 | *.cgo1.go 9 | *.cgo2.c 10 | _cgo_defun.c 11 | _cgo_gotypes.go 12 | _cgo_export.* 13 | _testmain.go 14 | *.exe 15 | *.exe~ 16 | *.test 17 | *.prof 18 | *.rar 19 | *.zip 20 | *.gz 21 | *.psd 22 | *.bmd 23 | *.cfg 24 | *.pptx 25 | *.log 26 | *.jsonl 27 | *nohup.out 28 | *settings.pyc 29 | *.sublime-project 30 | *.sublime-workspace 31 | !.gitkeep 32 | .DS_Store 33 | /.idea 34 | /.vscode 35 | /output 36 | *.local.yml -------------------------------------------------------------------------------- /backend/app/frontend/.hz: -------------------------------------------------------------------------------- 1 | // Code generated by hz. DO NOT EDIT. 2 | 3 | hz version: v0.8.1 4 | handlerDir: "" 5 | modelDir: hertz_gen 6 | routerDir: "" 7 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/dal/init.go: -------------------------------------------------------------------------------- 1 | package dal 2 | 3 | import ( 4 | "github.com/tiktokmall/backend/app/frontend/biz/dal/mysql" 5 | "github.com/tiktokmall/backend/app/frontend/biz/dal/redis" 6 | ) 7 | 8 | func Init() { 9 | redis.Init() 10 | mysql.Init() 11 | } 12 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/dal/mysql/init.go: -------------------------------------------------------------------------------- 1 | package mysql 2 | 3 | import ( 4 | "github.com/tiktokmall/backend/app/frontend/conf" 5 | "gorm.io/driver/mysql" 6 | "gorm.io/gorm" 7 | ) 8 | 9 | var ( 10 | DB *gorm.DB 11 | err error 12 | ) 13 | 14 | func Init() { 15 | DB, err = gorm.Open(mysql.Open(conf.GetConf().MySQL.DSN), 16 | &gorm.Config{ 17 | PrepareStmt: true, 18 | SkipDefaultTransaction: true, 19 | }, 20 | ) 21 | if err != nil { 22 | panic(err) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/dal/redis/init.go: -------------------------------------------------------------------------------- 1 | package redis 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/redis/go-redis/v9" 7 | "github.com/tiktokmall/backend/app/frontend/conf" 8 | ) 9 | 10 | var RedisClient *redis.Client 11 | 12 | func Init() { 13 | RedisClient = redis.NewClient(&redis.Options{ 14 | Addr: conf.GetConf().Redis.Address, 15 | Username: conf.GetConf().Redis.Username, 16 | Password: conf.GetConf().Redis.Password, 17 | DB: conf.GetConf().Redis.DB, 18 | }) 19 | if err := RedisClient.Ping(context.Background()).Err(); err != nil { 20 | panic(err) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/handler/about/about_service_test.go: -------------------------------------------------------------------------------- 1 | package about 2 | 3 | import ( 4 | "bytes" 5 | "testing" 6 | 7 | "github.com/cloudwego/hertz/pkg/app/server" 8 | //"github.com/cloudwego/hertz/pkg/common/test/assert" 9 | "github.com/cloudwego/hertz/pkg/common/ut" 10 | ) 11 | 12 | func TestAbout(t *testing.T) { 13 | h := server.Default() 14 | h.GET("/about", About) 15 | path := "/about" // todo: you can customize query 16 | body := &ut.Body{Body: bytes.NewBufferString(""), Len: 1} // todo: you can customize body 17 | header := ut.Header{} // todo: you can customize header 18 | w := ut.PerformRequest(h.Engine, "GET", path, body, header) 19 | resp := w.Result() 20 | t.Log(string(resp.Body())) 21 | 22 | // todo edit your unit test. 23 | // assert.DeepEqual(t, 200, resp.StatusCode()) 24 | // assert.DeepEqual(t, "null", string(resp.Body())) 25 | } 26 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/handler/agent/agent_service.go: -------------------------------------------------------------------------------- 1 | package agent 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/cloudwego/hertz/pkg/app" 7 | "github.com/cloudwego/hertz/pkg/protocol/consts" 8 | "github.com/tiktokmall/backend/app/frontend/biz/service" 9 | "github.com/tiktokmall/backend/app/frontend/biz/utils" 10 | common "github.com/tiktokmall/backend/app/frontend/hertz_gen/frontend/common" 11 | ) 12 | 13 | // HandleChat . 14 | // @router api/chat [GET] 15 | func HandleChat(ctx context.Context, c *app.RequestContext) { 16 | var err error 17 | var req common.Empty 18 | err = c.BindAndValidate(&req) 19 | if err != nil { 20 | utils.SendErrResponse(ctx, c, consts.StatusOK, err) 21 | return 22 | } 23 | 24 | // resp := &common.Empty{} 25 | _, err = service.NewHandleChatService(ctx, c).Run(&req) 26 | if err != nil { 27 | utils.SendErrResponse(ctx, c, consts.StatusOK, err) 28 | return 29 | } 30 | 31 | // utils.SendSuccessResponse(ctx, c, consts.StatusOK, resp) 32 | // c.JSON(consts.StatusOK, map[string]any{}) 33 | } 34 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/handler/agent/agent_service_test.go: -------------------------------------------------------------------------------- 1 | package agent 2 | 3 | import ( 4 | "bytes" 5 | "testing" 6 | 7 | "github.com/cloudwego/hertz/pkg/app/server" 8 | //"github.com/cloudwego/hertz/pkg/common/test/assert" 9 | "github.com/cloudwego/hertz/pkg/common/ut" 10 | ) 11 | 12 | func TestHandleChat(t *testing.T) { 13 | h := server.Default() 14 | h.GET("api/chat", HandleChat) 15 | path := "api/chat" // todo: you can customize query 16 | body := &ut.Body{Body: bytes.NewBufferString(""), Len: 1} // todo: you can customize body 17 | header := ut.Header{} // todo: you can customize header 18 | w := ut.PerformRequest(h.Engine, "GET", path, body, header) 19 | resp := w.Result() 20 | t.Log(string(resp.Body())) 21 | 22 | // todo edit your unit test. 23 | // assert.DeepEqual(t, 200, resp.StatusCode()) 24 | // assert.DeepEqual(t, "null", string(resp.Body())) 25 | } 26 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/handler/category/category_service_test.go: -------------------------------------------------------------------------------- 1 | package category 2 | 3 | import ( 4 | "bytes" 5 | "testing" 6 | 7 | "github.com/cloudwego/hertz/pkg/app/server" 8 | //"github.com/cloudwego/hertz/pkg/common/test/assert" 9 | "github.com/cloudwego/hertz/pkg/common/ut" 10 | ) 11 | 12 | func TestCategory(t *testing.T) { 13 | h := server.Default() 14 | h.GET("/category/:category", Category) 15 | path := "/category/:category" // todo: you can customize query 16 | body := &ut.Body{Body: bytes.NewBufferString(""), Len: 1} // todo: you can customize body 17 | header := ut.Header{} // todo: you can customize header 18 | w := ut.PerformRequest(h.Engine, "GET", path, body, header) 19 | resp := w.Result() 20 | t.Log(string(resp.Body())) 21 | 22 | // todo edit your unit test. 23 | // assert.DeepEqual(t, 200, resp.StatusCode()) 24 | // assert.DeepEqual(t, "null", string(resp.Body())) 25 | } 26 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/handler/home/hello_service_test.go: -------------------------------------------------------------------------------- 1 | package home 2 | 3 | import ( 4 | "bytes" 5 | "testing" 6 | 7 | "github.com/cloudwego/hertz/pkg/app/server" 8 | //"github.com/cloudwego/hertz/pkg/common/test/assert" 9 | "github.com/cloudwego/hertz/pkg/common/ut" 10 | ) 11 | 12 | func TestHome(t *testing.T) { 13 | h := server.Default() 14 | h.GET("/", Home) 15 | path := "/" // todo: you can customize query 16 | body := &ut.Body{Body: bytes.NewBufferString(""), Len: 1} // todo: you can customize body 17 | header := ut.Header{} // todo: you can customize header 18 | w := ut.PerformRequest(h.Engine, "GET", path, body, header) 19 | resp := w.Result() 20 | t.Log(string(resp.Body())) 21 | 22 | // todo edit your unit test. 23 | // assert.DeepEqual(t, 200, resp.StatusCode()) 24 | // assert.DeepEqual(t, "null", string(resp.Body())) 25 | } 26 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/handler/order/order_service.go: -------------------------------------------------------------------------------- 1 | package order 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/tiktokmall/backend/app/frontend/biz/service" 7 | "github.com/tiktokmall/backend/app/frontend/biz/utils" 8 | common "github.com/tiktokmall/backend/app/frontend/hertz_gen/frontend/common" 9 | 10 | "github.com/cloudwego/hertz/pkg/app" 11 | "github.com/cloudwego/hertz/pkg/protocol/consts" 12 | ) 13 | 14 | // OrderList . 15 | // @router /order [GET] 16 | func OrderList(ctx context.Context, c *app.RequestContext) { 17 | var err error 18 | var req common.Empty 19 | err = c.BindAndValidate(&req) 20 | if err != nil { 21 | c.JSON(consts.StatusBadRequest, map[string]any{ 22 | "code": 400, 23 | "message": err.Error(), 24 | }) 25 | return 26 | } 27 | 28 | resp, err := service.NewOrderListService(ctx, c).Run(&req) 29 | if err != nil { 30 | c.JSON(consts.StatusInternalServerError, map[string]any{ 31 | "code": 500, 32 | "message": err.Error(), 33 | }) 34 | return 35 | } 36 | 37 | resp["code"] = 200 38 | resp["message"] = "ok" 39 | c.JSON(consts.StatusOK, utils.WarpResponse(ctx, c, resp)) 40 | } 41 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/handler/order/order_service_test.go: -------------------------------------------------------------------------------- 1 | package order 2 | 3 | import ( 4 | "bytes" 5 | "testing" 6 | 7 | "github.com/cloudwego/hertz/pkg/app/server" 8 | //"github.com/cloudwego/hertz/pkg/common/test/assert" 9 | "github.com/cloudwego/hertz/pkg/common/ut" 10 | ) 11 | 12 | func TestOrderList(t *testing.T) { 13 | h := server.Default() 14 | h.GET("/order", OrderList) 15 | path := "/order" // todo: you can customize query 16 | body := &ut.Body{Body: bytes.NewBufferString(""), Len: 1} // todo: you can customize body 17 | header := ut.Header{} // todo: you can customize header 18 | w := ut.PerformRequest(h.Engine, "GET", path, body, header) 19 | resp := w.Result() 20 | t.Log(string(resp.Body())) 21 | 22 | // todo edit your unit test. 23 | // assert.DeepEqual(t, 200, resp.StatusCode()) 24 | // assert.DeepEqual(t, "null", string(resp.Body())) 25 | } 26 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/router/about/about.go: -------------------------------------------------------------------------------- 1 | // Code generated by hertz generator. DO NOT EDIT. 2 | 3 | package about 4 | 5 | import ( 6 | about "github.com/tiktokmall/backend/app/frontend/biz/handler/about" 7 | "github.com/cloudwego/hertz/pkg/app/server" 8 | ) 9 | 10 | /* 11 | This file will register all the routes of the services in the master idl. 12 | And it will update automatically when you use the "update" command for the idl. 13 | So don't modify the contents of the file, or your code will be deleted when it is updated. 14 | */ 15 | 16 | // Register register routes based on the IDL 'api.${HTTP Method}' annotation. 17 | func Register(r *server.Hertz) { 18 | 19 | root := r.Group("/", rootMw()...) 20 | root.GET("/about", append(_aboutMw(), about.About)...) 21 | } 22 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/router/about/middleware.go: -------------------------------------------------------------------------------- 1 | // Code generated by hertz generator. 2 | 3 | package about 4 | 5 | import ( 6 | "github.com/cloudwego/hertz/pkg/app" 7 | ) 8 | 9 | func rootMw() []app.HandlerFunc { 10 | // your code... 11 | return nil 12 | } 13 | 14 | func _aboutMw() []app.HandlerFunc { 15 | // your code... 16 | return nil 17 | } 18 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/router/agent/agent.go: -------------------------------------------------------------------------------- 1 | // Code generated by hertz generator. DO NOT EDIT. 2 | 3 | package agent 4 | 5 | import ( 6 | "github.com/cloudwego/hertz/pkg/app/server" 7 | agent "github.com/tiktokmall/backend/app/frontend/biz/handler/agent" 8 | ) 9 | 10 | /* 11 | This file will register all the routes of the services in the master idl. 12 | And it will update automatically when you use the "update" command for the idl. 13 | So don't modify the contents of the file, or your code will be deleted when it is updated. 14 | */ 15 | 16 | // Register register routes based on the IDL 'api.${HTTP Method}' annotation. 17 | func Register(r *server.Hertz) { 18 | 19 | root := r.Group("/", rootMw()...) 20 | { 21 | _agent := root.Group("/agent", _agentMw()...) 22 | { 23 | _api := _agent.Group("/api", _apiMw()...) 24 | _api.POST("/chat", append(_handlechatMw(), agent.HandleChat)...) 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/router/agent/middleware.go: -------------------------------------------------------------------------------- 1 | // Code generated by hertz generator. 2 | 3 | package agent 4 | 5 | import ( 6 | "github.com/cloudwego/hertz/pkg/app" 7 | ) 8 | 9 | func rootMw() []app.HandlerFunc { 10 | // your code... 11 | return nil 12 | } 13 | 14 | func _apiMw() []app.HandlerFunc { 15 | // your code... 16 | return nil 17 | } 18 | 19 | func _handlechatMw() []app.HandlerFunc { 20 | // your code... 21 | return nil 22 | } 23 | 24 | func _agentMw() []app.HandlerFunc { 25 | // your code... 26 | return nil 27 | } 28 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/router/auth/auth_page.go: -------------------------------------------------------------------------------- 1 | // Code generated by hertz generator. DO NOT EDIT. 2 | 3 | package auth 4 | 5 | import ( 6 | auth "github.com/tiktokmall/backend/app/frontend/biz/handler/auth" 7 | "github.com/cloudwego/hertz/pkg/app/server" 8 | ) 9 | 10 | /* 11 | This file will register all the routes of the services in the master idl. 12 | And it will update automatically when you use the "update" command for the idl. 13 | So don't modify the contents of the file, or your code will be deleted when it is updated. 14 | */ 15 | 16 | // Register register routes based on the IDL 'api.${HTTP Method}' annotation. 17 | func Register(r *server.Hertz) { 18 | 19 | root := r.Group("/", rootMw()...) 20 | { 21 | _auth := root.Group("/auth", _authMw()...) 22 | _auth.POST("/login", append(_loginMw(), auth.Login)...) 23 | _auth.POST("/logout", append(_logoutMw(), auth.Logout)...) 24 | _auth.POST("/register", append(_registerMw(), auth.Register)...) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/router/auth/middleware.go: -------------------------------------------------------------------------------- 1 | // Code generated by hertz generator. 2 | 3 | package auth 4 | 5 | import ( 6 | "github.com/cloudwego/hertz/pkg/app" 7 | ) 8 | 9 | func rootMw() []app.HandlerFunc { 10 | // your code... 11 | return nil 12 | } 13 | 14 | func _authMw() []app.HandlerFunc { 15 | // your code... 16 | return nil 17 | } 18 | 19 | func _loginMw() []app.HandlerFunc { 20 | // your code... 21 | return nil 22 | } 23 | 24 | func _registerMw() []app.HandlerFunc { 25 | // your code... 26 | return nil 27 | } 28 | 29 | func _logoutMw() []app.HandlerFunc { 30 | // your code... 31 | return nil 32 | } 33 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/router/cart/cart_page.go: -------------------------------------------------------------------------------- 1 | // Code generated by hertz generator. DO NOT EDIT. 2 | 3 | package cart 4 | 5 | import ( 6 | "github.com/cloudwego/hertz/pkg/app/server" 7 | cart "github.com/tiktokmall/backend/app/frontend/biz/handler/cart" 8 | ) 9 | 10 | /* 11 | This file will register all the routes of the services in the master idl. 12 | And it will update automatically when you use the "update" command for the idl. 13 | So don't modify the contents of the file, or your code will be deleted when it is updated. 14 | */ 15 | 16 | // Register register routes based on the IDL 'api.${HTTP Method}' annotation. 17 | func Register(r *server.Hertz) { 18 | 19 | root := r.Group("/", rootMw()...) 20 | root.POST("/cart", append(_addcartitemMw(), cart.AddCartItem)...) 21 | root.GET("/cart", append(_getcartMw(), cart.GetCart)...) 22 | root.POST("/changeqty", append(_changeqtyMw(), cart.ChangeQty)...) 23 | root.GET("/emptycart", append(_emptycartMw(), cart.EmptyCart)...) 24 | } 25 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/router/cart/middleware.go: -------------------------------------------------------------------------------- 1 | // Code generated by hertz generator. 2 | 3 | package cart 4 | 5 | import ( 6 | "github.com/tiktokmall/backend/app/frontend/middleware" 7 | 8 | "github.com/cloudwego/hertz/pkg/app" 9 | ) 10 | 11 | func rootMw() []app.HandlerFunc { 12 | // your code... 13 | return []app.HandlerFunc{middleware.Jwt()} 14 | } 15 | 16 | func _addcartitemMw() []app.HandlerFunc { 17 | // your code... 18 | return nil 19 | } 20 | 21 | func _getcartMw() []app.HandlerFunc { 22 | // your code... 23 | return nil 24 | } 25 | 26 | func _emptycartMw() []app.HandlerFunc { 27 | // your code... 28 | return nil 29 | } 30 | 31 | func _changeqtyMw() []app.HandlerFunc { 32 | // your code... 33 | return nil 34 | } 35 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/router/category/category_page.go: -------------------------------------------------------------------------------- 1 | // Code generated by hertz generator. DO NOT EDIT. 2 | 3 | package category 4 | 5 | import ( 6 | category "github.com/tiktokmall/backend/app/frontend/biz/handler/category" 7 | "github.com/cloudwego/hertz/pkg/app/server" 8 | ) 9 | 10 | /* 11 | This file will register all the routes of the services in the master idl. 12 | And it will update automatically when you use the "update" command for the idl. 13 | So don't modify the contents of the file, or your code will be deleted when it is updated. 14 | */ 15 | 16 | // Register register routes based on the IDL 'api.${HTTP Method}' annotation. 17 | func Register(r *server.Hertz) { 18 | 19 | root := r.Group("/", rootMw()...) 20 | { 21 | _category := root.Group("/category", _categoryMw()...) 22 | _category.GET("/:category", append(_category0Mw(), category.Category)...) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/router/category/middleware.go: -------------------------------------------------------------------------------- 1 | // Code generated by hertz generator. 2 | 3 | package category 4 | 5 | import ( 6 | "github.com/cloudwego/hertz/pkg/app" 7 | ) 8 | 9 | func rootMw() []app.HandlerFunc { 10 | // your code... 11 | return nil 12 | } 13 | 14 | func _categoryMw() []app.HandlerFunc { 15 | // your code... 16 | return nil 17 | } 18 | 19 | func _category0Mw() []app.HandlerFunc { 20 | // your code... 21 | return nil 22 | } 23 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/router/checkout/checkout_page.go: -------------------------------------------------------------------------------- 1 | // Code generated by hertz generator. DO NOT EDIT. 2 | 3 | package checkout 4 | 5 | import ( 6 | checkout "github.com/tiktokmall/backend/app/frontend/biz/handler/checkout" 7 | "github.com/cloudwego/hertz/pkg/app/server" 8 | ) 9 | 10 | /* 11 | This file will register all the routes of the services in the master idl. 12 | And it will update automatically when you use the "update" command for the idl. 13 | So don't modify the contents of the file, or your code will be deleted when it is updated. 14 | */ 15 | 16 | // Register register routes based on the IDL 'api.${HTTP Method}' annotation. 17 | func Register(r *server.Hertz) { 18 | 19 | root := r.Group("/", rootMw()...) 20 | root.GET("/checkout", append(_checkout0Mw(), checkout.Checkout)...) 21 | _checkout := root.Group("/checkout", _checkoutMw()...) 22 | _checkout.GET("/result", append(_checkoutresultMw(), checkout.CheckoutResult)...) 23 | _checkout.POST("/waiting", append(_checkoutwaitingMw(), checkout.CheckoutWaiting)...) 24 | } 25 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/router/checkout/middleware.go: -------------------------------------------------------------------------------- 1 | // Code generated by hertz generator. 2 | 3 | package checkout 4 | 5 | import ( 6 | "github.com/tiktokmall/backend/app/frontend/middleware" 7 | 8 | "github.com/cloudwego/hertz/pkg/app" 9 | ) 10 | 11 | func rootMw() []app.HandlerFunc { 12 | // your code... 13 | // 给路由添加中间件 14 | return []app.HandlerFunc{middleware.Jwt()} 15 | } 16 | 17 | func _checkoutMw() []app.HandlerFunc { 18 | // your code... 19 | return nil 20 | } 21 | 22 | func _checkout0Mw() []app.HandlerFunc { 23 | // your code... 24 | return nil 25 | } 26 | 27 | func _checkoutresultMw() []app.HandlerFunc { 28 | // your code... 29 | return nil 30 | } 31 | 32 | func _checkoutwaitingMw() []app.HandlerFunc { 33 | // your code... 34 | return nil 35 | } 36 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/router/home/home.go: -------------------------------------------------------------------------------- 1 | // Code generated by hertz generator. DO NOT EDIT. 2 | 3 | package home 4 | 5 | import ( 6 | home "github.com/tiktokmall/backend/app/frontend/biz/handler/home" 7 | "github.com/cloudwego/hertz/pkg/app/server" 8 | ) 9 | 10 | /* 11 | This file will register all the routes of the services in the master idl. 12 | And it will update automatically when you use the "update" command for the idl. 13 | So don't modify the contents of the file, or your code will be deleted when it is updated. 14 | */ 15 | 16 | // Register register routes based on the IDL 'api.${HTTP Method}' annotation. 17 | func Register(r *server.Hertz) { 18 | 19 | root := r.Group("/", rootMw()...) 20 | root.GET("/", append(_homeMw(), home.Home)...) 21 | } 22 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/router/home/middleware.go: -------------------------------------------------------------------------------- 1 | // Code generated by hertz generator. 2 | 3 | package home 4 | 5 | import ( 6 | "github.com/cloudwego/hertz/pkg/app" 7 | ) 8 | 9 | func rootMw() []app.HandlerFunc { 10 | // your code... 11 | return nil 12 | } 13 | 14 | func _homeMw() []app.HandlerFunc { 15 | // your code... 16 | return nil 17 | } 18 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/router/order/middleware.go: -------------------------------------------------------------------------------- 1 | // Code generated by hertz generator. 2 | 3 | package order 4 | 5 | import ( 6 | "github.com/cloudwego/hertz/pkg/app" 7 | ) 8 | 9 | func rootMw() []app.HandlerFunc { 10 | // your code... 11 | return nil 12 | } 13 | 14 | func _orderlistMw() []app.HandlerFunc { 15 | // your code... 16 | return nil 17 | } 18 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/router/order/order_page.go: -------------------------------------------------------------------------------- 1 | // Code generated by hertz generator. DO NOT EDIT. 2 | 3 | package order 4 | 5 | import ( 6 | order "github.com/tiktokmall/backend/app/frontend/biz/handler/order" 7 | "github.com/cloudwego/hertz/pkg/app/server" 8 | ) 9 | 10 | /* 11 | This file will register all the routes of the services in the master idl. 12 | And it will update automatically when you use the "update" command for the idl. 13 | So don't modify the contents of the file, or your code will be deleted when it is updated. 14 | */ 15 | 16 | // Register register routes based on the IDL 'api.${HTTP Method}' annotation. 17 | func Register(r *server.Hertz) { 18 | 19 | root := r.Group("/", rootMw()...) 20 | root.GET("/order", append(_orderlistMw(), order.OrderList)...) 21 | } 22 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/router/oss/middleware.go: -------------------------------------------------------------------------------- 1 | // Code generated by hertz generator. 2 | 3 | package oss 4 | 5 | import ( 6 | "github.com/cloudwego/hertz/pkg/app" 7 | "github.com/tiktokmall/backend/app/frontend/middleware" 8 | ) 9 | 10 | func rootMw() []app.HandlerFunc { 11 | // your code... 12 | return []app.HandlerFunc{middleware.Jwt()} 13 | } 14 | 15 | func _uploadimageMw() []app.HandlerFunc { 16 | // your code... 17 | return nil 18 | } 19 | 20 | func _uploadvideoMw() []app.HandlerFunc { 21 | // your code... 22 | return nil 23 | } 24 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/router/oss/oss.go: -------------------------------------------------------------------------------- 1 | // Code generated by hertz generator. DO NOT EDIT. 2 | 3 | package oss 4 | 5 | import ( 6 | "github.com/cloudwego/hertz/pkg/app/server" 7 | oss "github.com/tiktokmall/backend/app/frontend/biz/handler/oss" 8 | ) 9 | 10 | /* 11 | This file will register all the routes of the services in the master idl. 12 | And it will update automatically when you use the "update" command for the idl. 13 | So don't modify the contents of the file, or your code will be deleted when it is updated. 14 | */ 15 | 16 | // Register register routes based on the IDL 'api.${HTTP Method}' annotation. 17 | func Register(r *server.Hertz) { 18 | 19 | root := r.Group("/", rootMw()...) 20 | root.POST("/uploadImage", append(_uploadimageMw(), oss.UploadImage)...) 21 | root.POST("/uploadVideo", append(_uploadvideoMw(), oss.UploadVideo)...) 22 | } 23 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/router/payment/middleware.go: -------------------------------------------------------------------------------- 1 | // Code generated by hertz generator. 2 | 3 | package payment 4 | 5 | import ( 6 | "github.com/cloudwego/hertz/pkg/app" 7 | ) 8 | 9 | func rootMw() []app.HandlerFunc { 10 | // your code... 11 | return nil 12 | } 13 | 14 | func _alipayMw() []app.HandlerFunc { 15 | // your code... 16 | return nil 17 | } 18 | 19 | func _payresultMw() []app.HandlerFunc { 20 | // your code... 21 | return nil 22 | } 23 | 24 | func _paysuccessMw() []app.HandlerFunc { 25 | // your code... 26 | return nil 27 | } 28 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/router/payment/payment_page.go: -------------------------------------------------------------------------------- 1 | // Code generated by hertz generator. DO NOT EDIT. 2 | 3 | package payment 4 | 5 | import ( 6 | "github.com/cloudwego/hertz/pkg/app/server" 7 | payment "github.com/tiktokmall/backend/app/frontend/biz/handler/payment" 8 | ) 9 | 10 | /* 11 | This file will register all the routes of the services in the master idl. 12 | And it will update automatically when you use the "update" command for the idl. 13 | So don't modify the contents of the file, or your code will be deleted when it is updated. 14 | */ 15 | 16 | // Register register routes based on the IDL 'api.${HTTP Method}' annotation. 17 | func Register(r *server.Hertz) { 18 | 19 | root := r.Group("/", rootMw()...) 20 | root.POST("/alipay", append(_alipayMw(), payment.Alipay)...) 21 | root.POST("/payresult", append(_payresultMw(), payment.Payresult)...) 22 | root.GET("/paysuccess", append(_paysuccessMw(), payment.Paysuccess)...) 23 | } 24 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/router/product/middleware.go: -------------------------------------------------------------------------------- 1 | // Code generated by hertz generator. 2 | 3 | package product 4 | 5 | import ( 6 | "github.com/cloudwego/hertz/pkg/app" 7 | ) 8 | 9 | func rootMw() []app.HandlerFunc { 10 | // your code... 11 | return nil 12 | } 13 | 14 | func _getproductMw() []app.HandlerFunc { 15 | // your code... 16 | return nil 17 | } 18 | 19 | func _searchproductsMw() []app.HandlerFunc { 20 | // your code... 21 | return nil 22 | } 23 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/router/product/product_page.go: -------------------------------------------------------------------------------- 1 | // Code generated by hertz generator. DO NOT EDIT. 2 | 3 | package product 4 | 5 | import ( 6 | product "github.com/tiktokmall/backend/app/frontend/biz/handler/product" 7 | "github.com/cloudwego/hertz/pkg/app/server" 8 | ) 9 | 10 | /* 11 | This file will register all the routes of the services in the master idl. 12 | And it will update automatically when you use the "update" command for the idl. 13 | So don't modify the contents of the file, or your code will be deleted when it is updated. 14 | */ 15 | 16 | // Register register routes based on the IDL 'api.${HTTP Method}' annotation. 17 | func Register(r *server.Hertz) { 18 | 19 | root := r.Group("/", rootMw()...) 20 | root.GET("/product", append(_getproductMw(), product.GetProduct)...) 21 | root.GET("/search", append(_searchproductsMw(), product.SearchProducts)...) 22 | } 23 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/router/user/middleware.go: -------------------------------------------------------------------------------- 1 | // Code generated by hertz generator. 2 | 3 | package user 4 | 5 | import ( 6 | "github.com/cloudwego/hertz/pkg/app" 7 | "github.com/tiktokmall/backend/app/frontend/middleware" 8 | ) 9 | 10 | func rootMw() []app.HandlerFunc { 11 | // your code... 12 | return []app.HandlerFunc{middleware.Jwt()} 13 | } 14 | 15 | func _userMw() []app.HandlerFunc { 16 | // your code... 17 | return nil 18 | } 19 | 20 | func _updateMw() []app.HandlerFunc { 21 | // your code... 22 | return nil 23 | } 24 | 25 | func _deleteMw() []app.HandlerFunc { 26 | // your code... 27 | return nil 28 | } 29 | 30 | func _deleteuserMw() []app.HandlerFunc { 31 | // your code... 32 | return nil 33 | } 34 | 35 | func _queryMw() []app.HandlerFunc { 36 | // your code... 37 | return nil 38 | } 39 | 40 | func _queryuserMw() []app.HandlerFunc { 41 | // your code... 42 | return nil 43 | } 44 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/router/user/user_page.go: -------------------------------------------------------------------------------- 1 | // Code generated by hertz generator. DO NOT EDIT. 2 | 3 | package user 4 | 5 | import ( 6 | "github.com/cloudwego/hertz/pkg/app/server" 7 | user "github.com/tiktokmall/backend/app/frontend/biz/handler/user" 8 | ) 9 | 10 | /* 11 | This file will register all the routes of the services in the master idl. 12 | And it will update automatically when you use the "update" command for the idl. 13 | So don't modify the contents of the file, or your code will be deleted when it is updated. 14 | */ 15 | 16 | // Register register routes based on the IDL 'api.${HTTP Method}' annotation. 17 | func Register(r *server.Hertz) { 18 | 19 | root := r.Group("/", rootMw()...) 20 | { 21 | _user := root.Group("/user", _userMw()...) 22 | _user.GET("/delete", append(_deleteuserMw(), user.DeleteUser)...) 23 | _user.GET("/query", append(_queryuserMw(), user.QueryUser)...) 24 | _user.POST("/update", append(_updateMw(), user.Update)...) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/service/about.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | common "github.com/tiktokmall/backend/app/frontend/hertz_gen/frontend/common" 7 | 8 | "github.com/cloudwego/hertz/pkg/app" 9 | ) 10 | 11 | type AboutService struct { 12 | RequestContext *app.RequestContext 13 | Context context.Context 14 | } 15 | 16 | func NewAboutService(Context context.Context, RequestContext *app.RequestContext) *AboutService { 17 | return &AboutService{RequestContext: RequestContext, Context: Context} 18 | } 19 | 20 | func (h *AboutService) Run(req *common.Empty) (resp map[string]any, err error) { 21 | return map[string]any{ 22 | "title": "About", 23 | }, nil 24 | } 25 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/service/category.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "log" 6 | 7 | category "github.com/tiktokmall/backend/app/frontend/hertz_gen/frontend/category" 8 | "github.com/tiktokmall/backend/app/frontend/infra/rpc" 9 | "github.com/tiktokmall/backend/rpc_gen/kitex_gen/product" 10 | 11 | "github.com/cloudwego/hertz/pkg/app" 12 | ) 13 | 14 | type CategoryService struct { 15 | RequestContext *app.RequestContext 16 | Context context.Context 17 | } 18 | 19 | func NewCategoryService(Context context.Context, RequestContext *app.RequestContext) *CategoryService { 20 | return &CategoryService{RequestContext: RequestContext, Context: Context} 21 | } 22 | 23 | func (h *CategoryService) Run(req *category.CategoryReq) (resp map[string]any, err error) { 24 | p, err := rpc.ProductClient.ListProducts(h.Context, &product.ListProductsReq{CategoryName: req.Category}) 25 | if err != nil { 26 | return nil, err 27 | } 28 | log.Printf("category=%v, items=%v", req.Category, p.Products) 29 | return map[string]any{ 30 | "title": "Category", 31 | "items": p.Products, 32 | }, nil 33 | } 34 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/service/checkout_result.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | common "github.com/tiktokmall/backend/app/frontend/hertz_gen/frontend/common" 7 | 8 | "github.com/cloudwego/hertz/pkg/app" 9 | ) 10 | 11 | type CheckoutResultService struct { 12 | RequestContext *app.RequestContext 13 | Context context.Context 14 | } 15 | 16 | func NewCheckoutResultService(Context context.Context, RequestContext *app.RequestContext) *CheckoutResultService { 17 | return &CheckoutResultService{RequestContext: RequestContext, Context: Context} 18 | } 19 | 20 | func (h *CheckoutResultService) Run(req *common.Empty) (resp map[string]any, err error) { 21 | return map[string]any{}, nil 22 | } 23 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/service/empty_cart.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "github.com/tiktokmall/backend/app/frontend/infra/rpc" 6 | frontendUtils "github.com/tiktokmall/backend/app/frontend/utils" 7 | rpccart "github.com/tiktokmall/backend/rpc_gen/kitex_gen/cart" 8 | 9 | "github.com/cloudwego/hertz/pkg/app" 10 | common "github.com/tiktokmall/backend/app/frontend/hertz_gen/frontend/common" 11 | ) 12 | 13 | type EmptyCartService struct { 14 | RequestContext *app.RequestContext 15 | Context context.Context 16 | } 17 | 18 | func NewEmptyCartService(Context context.Context, RequestContext *app.RequestContext) *EmptyCartService { 19 | return &EmptyCartService{RequestContext: RequestContext, Context: Context} 20 | } 21 | 22 | func (h *EmptyCartService) Run(req *common.Empty) (resp map[string]any, err error) { 23 | _, err = rpc.CartClient.EmptyCart(h.Context, &rpccart.EmptyCartReq{ 24 | UserId: frontendUtils.GetUserIdFromCtx(h.Context), 25 | }) 26 | return map[string]any{ 27 | "message": "success", 28 | }, err 29 | } 30 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/service/get_product.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | product "github.com/tiktokmall/backend/app/frontend/hertz_gen/frontend/product" 7 | "github.com/tiktokmall/backend/app/frontend/infra/rpc" 8 | 9 | "github.com/cloudwego/hertz/pkg/common/utils" 10 | 11 | rpcproduct "github.com/tiktokmall/backend/rpc_gen/kitex_gen/product" 12 | 13 | "github.com/cloudwego/hertz/pkg/app" 14 | ) 15 | 16 | type GetProductService struct { 17 | RequestContext *app.RequestContext 18 | Context context.Context 19 | } 20 | 21 | func NewGetProductService(Context context.Context, RequestContext *app.RequestContext) *GetProductService { 22 | return &GetProductService{RequestContext: RequestContext, Context: Context} 23 | } 24 | 25 | func (h *GetProductService) Run(req *product.ProductReq) (resp map[string]any, err error) { 26 | 27 | p, err := rpc.ProductClient.GetProduct(h.Context, &rpcproduct.GetProductReq{Id: req.Id}) 28 | if err != nil { 29 | return nil, err 30 | } 31 | 32 | return utils.H{ 33 | "item": p.Product, 34 | }, nil 35 | } 36 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/service/home.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | common "github.com/tiktokmall/backend/app/frontend/hertz_gen/frontend/common" 7 | "github.com/tiktokmall/backend/app/frontend/infra/rpc" 8 | "github.com/tiktokmall/backend/rpc_gen/kitex_gen/product" 9 | 10 | "github.com/cloudwego/hertz/pkg/app" 11 | ) 12 | 13 | type HomeService struct { 14 | RequestContext *app.RequestContext 15 | Context context.Context 16 | } 17 | 18 | func NewHomeService(Context context.Context, RequestContext *app.RequestContext) *HomeService { 19 | return &HomeService{RequestContext: RequestContext, Context: Context} 20 | } 21 | 22 | func (h *HomeService) Run(req *common.Empty) (resp map[string]any, err error) { 23 | products, err := rpc.ProductClient.ListProducts(h.Context, &product.ListProductsReq{}) 24 | if err != nil { 25 | return nil, err 26 | } 27 | return map[string]any{ 28 | "title": "Hot Sale", 29 | "items": products.Products, 30 | }, nil 31 | } 32 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/service/logout.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | common "github.com/tiktokmall/backend/app/frontend/hertz_gen/frontend/common" 7 | 8 | "github.com/cloudwego/hertz/pkg/app" 9 | "github.com/hertz-contrib/sessions" 10 | ) 11 | 12 | type LogoutService struct { 13 | RequestContext *app.RequestContext 14 | Context context.Context 15 | } 16 | 17 | func NewLogoutService(Context context.Context, RequestContext *app.RequestContext) *LogoutService { 18 | return &LogoutService{RequestContext: RequestContext, Context: Context} 19 | } 20 | 21 | func (h *LogoutService) Run(req *common.Empty) (resp *common.Empty, err error) { 22 | //defer func() { 23 | // hlog.CtxInfof(h.Context, "req = %+v", req) 24 | // hlog.CtxInfof(h.Context, "resp = %+v", resp) 25 | //}() 26 | // todo edit your code 27 | session := sessions.Default(h.RequestContext) 28 | session.Clear() 29 | 30 | err = session.Save() 31 | if err != nil { 32 | return nil, err 33 | } 34 | return 35 | } 36 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/service/merchant_ping.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/cloudwego/hertz/pkg/app" 7 | common "github.com/tiktokmall/backend/app/frontend/hertz_gen/frontend/common" 8 | "github.com/tiktokmall/backend/app/frontend/utils" 9 | ) 10 | 11 | type MerchantPingService struct { 12 | RequestContext *app.RequestContext 13 | Context context.Context 14 | } 15 | 16 | func NewMerchantPingService(Context context.Context, RequestContext *app.RequestContext) *MerchantPingService { 17 | return &MerchantPingService{RequestContext: RequestContext, Context: Context} 18 | } 19 | 20 | func (h *MerchantPingService) Run(req *common.Empty) (resp utils.H, err error) { 21 | //defer func() { 22 | // hlog.CtxInfof(h.Context, "req = %+v", req) 23 | // hlog.CtxInfof(h.Context, "resp = %+v", resp) 24 | //}() 25 | // todo edit your code 26 | return 27 | } 28 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/service/search_products.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | product "github.com/tiktokmall/backend/app/frontend/hertz_gen/frontend/product" 7 | "github.com/tiktokmall/backend/app/frontend/infra/rpc" 8 | rpcproduct "github.com/tiktokmall/backend/rpc_gen/kitex_gen/product" 9 | 10 | "github.com/cloudwego/hertz/pkg/app" 11 | ) 12 | 13 | type SearchProductsService struct { 14 | RequestContext *app.RequestContext 15 | Context context.Context 16 | } 17 | 18 | func NewSearchProductsService(Context context.Context, RequestContext *app.RequestContext) *SearchProductsService { 19 | return &SearchProductsService{RequestContext: RequestContext, Context: Context} 20 | } 21 | 22 | func (h *SearchProductsService) Run(req *product.SearchProductsReq) (resp map[string]any, err error) { 23 | products, err := rpc.ProductClient.SearchProducts(h.Context, &rpcproduct.SearchProductsReq{ 24 | Query: req.Q, 25 | }) 26 | if err != nil { 27 | return nil, err 28 | } 29 | return map[string]any{ 30 | "items": products.Results, 31 | "q": req.Q, 32 | }, nil 33 | } 34 | -------------------------------------------------------------------------------- /backend/app/frontend/biz/utils/type.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | type H map[string]any 4 | -------------------------------------------------------------------------------- /backend/app/frontend/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | RUN_NAME=frontend 3 | mkdir -p output/bin output/conf 4 | cp script/bootstrap.sh output 2>/dev/null 5 | chmod +x output/bootstrap.sh 6 | cp -r conf/* output/conf 7 | go build -o output/bin/${RUN_NAME} -------------------------------------------------------------------------------- /backend/app/frontend/conf/dev/conf.yaml: -------------------------------------------------------------------------------- 1 | hertz: 2 | service: "frontend" 3 | address: ":8080" 4 | metrics_port: ":8090" 5 | enable_pprof: true 6 | enable_gzip: true 7 | enable_access_log: true 8 | log_level: info 9 | log_file_name: "log/hertz.log" 10 | log_max_size: 10 11 | log_max_age: 3 12 | log_max_backups: 50 13 | registry_addr: "127.0.0.1:8500" 14 | 15 | # mysql 没用 16 | mysql: 17 | dsn: "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8mb4&parseTime=True&loc=Local" 18 | 19 | redis: 20 | address: "127.0.0.1:6379" 21 | username: "" 22 | password: "" 23 | db: 0 -------------------------------------------------------------------------------- /backend/app/frontend/conf/online/conf.yaml: -------------------------------------------------------------------------------- 1 | hertz: 2 | service: "frontend" 3 | address: ":8080" 4 | metrics_port: ":8090" 5 | enable_pprof: true 6 | enable_gzip: true 7 | enable_access_log: true 8 | log_level: info 9 | log_file_name: "log/hertz.log" 10 | log_max_size: 10 11 | log_max_age: 3 12 | log_max_backups: 50 13 | registry_addr: "127.0.0.1:8500" 14 | 15 | # mysql 没用 16 | mysql: 17 | dsn: "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8mb4&parseTime=True&loc=Local" 18 | 19 | redis: 20 | address: "127.0.0.1:6379" 21 | username: "" 22 | password: "" 23 | db: 0 -------------------------------------------------------------------------------- /backend/app/frontend/conf/test/conf.yaml: -------------------------------------------------------------------------------- 1 | hertz: 2 | service: "frontend" 3 | address: ":8080" 4 | metrics_port: ":8090" 5 | enable_pprof: true 6 | enable_gzip: true 7 | enable_access_log: true 8 | log_level: info 9 | log_file_name: "log/hertz.log" 10 | log_max_size: 10 11 | log_max_age: 3 12 | log_max_backups: 50 13 | registry_addr: "127.0.0.1:8500" 14 | 15 | # mysql 没用 16 | mysql: 17 | dsn: "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8mb4&parseTime=True&loc=Local" 18 | 19 | redis: 20 | address: "127.0.0.1:6379" 21 | username: "" 22 | password: "" 23 | db: 0 -------------------------------------------------------------------------------- /backend/app/frontend/data/task/tasks.jsonl: -------------------------------------------------------------------------------- 1 | {"id":"39811745-e74c-4bdc-a36d-77c0fe62eccc","title":"明天下午三点吃饭任务","content":"吃饭","completed":false,"deadline":"2025-02-20 15:00:00","is_deleted":false,"created_at":"2025-02-19T05:30:22+08:00"} 2 | -------------------------------------------------------------------------------- /backend/app/frontend/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | mysql: 4 | image: 'mysql:latest' 5 | ports: 6 | - 3306:3306 7 | environment: 8 | - MYSQL_DATABASE=gorm 9 | - MYSQL_USER=gorm 10 | - MYSQL_PASSWORD=gorm 11 | - MYSQL_RANDOM_ROOT_PASSWORD="yes" 12 | redis: 13 | image: 'redis:latest' 14 | ports: 15 | - 6379:6379 -------------------------------------------------------------------------------- /backend/app/frontend/middleware/middleware.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | import "github.com/cloudwego/hertz/pkg/app/server" 4 | 5 | func Register(h *server.Hertz) { 6 | h.Use(GlobalAuth()) 7 | } 8 | -------------------------------------------------------------------------------- /backend/app/frontend/readme.md: -------------------------------------------------------------------------------- 1 | # *** Project 2 | 3 | ## introduce 4 | 5 | - Use the [Hertz](https://github.com/cloudwego/hertz/) framework 6 | - Integration of pprof, cors, recovery, access_log, gzip and other extensions of Hertz. 7 | - Generating the base code for unit tests. 8 | - Provides basic profile functions. 9 | - Provides the most basic MVC code hierarchy. 10 | 11 | ## Directory structure 12 | 13 | | catalog | introduce | 14 | | ---- | ---- | 15 | | conf | Configuration files | 16 | | main.go | Startup file | 17 | | hertz_gen | Hertz generated model | 18 | | biz/handler | Used for request processing, validation and return of response. | 19 | | biz/service | The actual business logic. | 20 | | biz/dal | Logic for operating the storage layer | 21 | | biz/route | Routing and middleware registration | 22 | | biz/utils | Wrapped some common methods | 23 | 24 | ## How to run 25 | 26 | ```shell 27 | sh build.sh 28 | sh output/bootstrap.sh 29 | ``` -------------------------------------------------------------------------------- /backend/app/frontend/script/bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | CURDIR=$(cd $(dirname $0); pwd) 3 | BinaryName=frontend 4 | echo "$CURDIR/bin/${BinaryName}" 5 | exec $CURDIR/bin/${BinaryName} -------------------------------------------------------------------------------- /backend/app/frontend/static/image/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzulihrs/TikTokMall/22bdae6c52c13b4818af407f3cb59f5b8fca506b/backend/app/frontend/static/image/logo.jpg -------------------------------------------------------------------------------- /backend/app/frontend/static/image/mouse-pad.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzulihrs/TikTokMall/22bdae6c52c13b4818af407f3cb59f5b8fca506b/backend/app/frontend/static/image/mouse-pad.jpeg -------------------------------------------------------------------------------- /backend/app/frontend/static/image/notebook.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzulihrs/TikTokMall/22bdae6c52c13b4818af407f3cb59f5b8fca506b/backend/app/frontend/static/image/notebook.jpeg -------------------------------------------------------------------------------- /backend/app/frontend/static/image/sweatshirt.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzulihrs/TikTokMall/22bdae6c52c13b4818af407f3cb59f5b8fca506b/backend/app/frontend/static/image/sweatshirt.jpeg -------------------------------------------------------------------------------- /backend/app/frontend/static/image/t-shirt-1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzulihrs/TikTokMall/22bdae6c52c13b4818af407f3cb59f5b8fca506b/backend/app/frontend/static/image/t-shirt-1.jpeg -------------------------------------------------------------------------------- /backend/app/frontend/static/image/t-shirt-2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzulihrs/TikTokMall/22bdae6c52c13b4818af407f3cb59f5b8fca506b/backend/app/frontend/static/image/t-shirt-2.jpeg -------------------------------------------------------------------------------- /backend/app/frontend/static/image/t-shirt.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzulihrs/TikTokMall/22bdae6c52c13b4818af407f3cb59f5b8fca506b/backend/app/frontend/static/image/t-shirt.jpeg -------------------------------------------------------------------------------- /backend/app/frontend/static/image/toiletry-bag.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzulihrs/TikTokMall/22bdae6c52c13b4818af407f3cb59f5b8fca506b/backend/app/frontend/static/image/toiletry-bag.jpg -------------------------------------------------------------------------------- /backend/app/frontend/static/image/toothbrush-cup.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzulihrs/TikTokMall/22bdae6c52c13b4818af407f3cb59f5b8fca506b/backend/app/frontend/static/image/toothbrush-cup.jpg -------------------------------------------------------------------------------- /backend/app/frontend/static/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzulihrs/TikTokMall/22bdae6c52c13b4818af407f3cb59f5b8fca506b/backend/app/frontend/static/img/logo.png -------------------------------------------------------------------------------- /backend/app/frontend/static/img/t-shirt-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzulihrs/TikTokMall/22bdae6c52c13b4818af407f3cb59f5b8fca506b/backend/app/frontend/static/img/t-shirt-1.jpg -------------------------------------------------------------------------------- /backend/app/frontend/static/img/t-shirt-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzulihrs/TikTokMall/22bdae6c52c13b4818af407f3cb59f5b8fca506b/backend/app/frontend/static/img/t-shirt-2.jpg -------------------------------------------------------------------------------- /backend/app/frontend/static/img/t-shirt-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzulihrs/TikTokMall/22bdae6c52c13b4818af407f3cb59f5b8fca506b/backend/app/frontend/static/img/t-shirt-3.jpg -------------------------------------------------------------------------------- /backend/app/frontend/static/img/t-shirt-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzulihrs/TikTokMall/22bdae6c52c13b4818af407f3cb59f5b8fca506b/backend/app/frontend/static/img/t-shirt-4.jpg -------------------------------------------------------------------------------- /backend/app/frontend/static/img/t-shirt-5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzulihrs/TikTokMall/22bdae6c52c13b4818af407f3cb59f5b8fca506b/backend/app/frontend/static/img/t-shirt-5.jpg -------------------------------------------------------------------------------- /backend/app/frontend/static/img/t-shirt-6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzulihrs/TikTokMall/22bdae6c52c13b4818af407f3cb59f5b8fca506b/backend/app/frontend/static/img/t-shirt-6.jpg -------------------------------------------------------------------------------- /backend/app/frontend/template/about.tmpl: -------------------------------------------------------------------------------- 1 | {{ define "about" }} 2 | {{ template "header" . }} 3 |
4 |
5 |
6 |
7 | ... 8 |

This is a community driven project

9 |
10 |
11 |
12 |
13 | {{ template "footer" . }} 14 | {{ end }} -------------------------------------------------------------------------------- /backend/app/frontend/template/cart-num.tmpl: -------------------------------------------------------------------------------- 1 | {{define "cart-num"}} 2 | 3 | 4 | 5 | {{ if $.cart_num}} 6 | 7 | {{ $.cart_num }} 8 | {{ end }} 9 | 10 | 11 | {{end}} -------------------------------------------------------------------------------- /backend/app/frontend/template/category.tmpl: -------------------------------------------------------------------------------- 1 | {{ define "category" }} 2 | {{ template "header" . }} 3 |
4 | {{ range $.items}} 5 |
6 | 7 |
8 | ... 10 |
11 |
12 | {{ .Name }} 13 |
14 |
${{ .Price }}
15 |
16 |
17 |
18 |
19 | {{ end}} 20 |
21 | {{ template "footer" . }} 22 | {{ end }} -------------------------------------------------------------------------------- /backend/app/frontend/template/footer.tmpl: -------------------------------------------------------------------------------- 1 | {{ define "footer" }} 2 | 3 | 4 | 9 | 12 | 13 | 14 | 15 | {{ end }} -------------------------------------------------------------------------------- /backend/app/frontend/template/home.tmpl: -------------------------------------------------------------------------------- 1 | {{ define "home" }} 2 | {{ template "header" . }} 3 |
4 | 5 | {{ range .items }} 6 | 7 | 8 | 9 |
10 | 11 | ... 12 |
13 |

{{.Name}}

14 |
¥{{.Price}}
15 |
16 |
17 |
18 | {{end}} 19 |
20 | {{ template "footer" . }} 21 | {{ end }} -------------------------------------------------------------------------------- /backend/app/frontend/template/required.tmpl: -------------------------------------------------------------------------------- 1 | {{ define "required" }} 2 | * 3 | {{ end }} -------------------------------------------------------------------------------- /backend/app/frontend/template/result.tmpl: -------------------------------------------------------------------------------- 1 | {{ define "result" }} 2 | {{ template "header" . }} 3 |
4 | 5 |
6 | Congratulations, you have successfully placed an order. 7 |
8 |
9 |
10 | Check Order 11 | Back to Home 12 |
13 | {{ template "footer" . }} 14 | {{ end }} -------------------------------------------------------------------------------- /backend/app/frontend/template/sign-in.tmpl: -------------------------------------------------------------------------------- 1 | {{ define "sign-in" }} 2 | 3 | {{ template "header" . }} 4 |
5 |
6 |
7 |
8 | 9 | 10 | 11 |
12 |
13 | 14 | 15 |
16 |
17 | Don't have account, click here to Sign Up 18 |
19 | 20 |
21 |
22 |
23 | {{ template "footer" . }} 24 | {{ end }} -------------------------------------------------------------------------------- /backend/app/frontend/types/order.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | type OrderItem struct { 4 | ProductName string 5 | Picture string 6 | Qty int32 7 | Cost float32 8 | } 9 | 10 | type Order struct { 11 | OrderId string 12 | OrderStatus uint32 13 | CreatedDate string 14 | Cost float32 15 | Items []OrderItem 16 | } 17 | -------------------------------------------------------------------------------- /backend/app/frontend/utils/constant.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | const ServiceName = "frontend" 4 | 5 | type SessionUserIdKey string 6 | 7 | const UserIdKey = SessionUserIdKey("user_id") 8 | const UsernameKey = SessionUserIdKey("username") 9 | const EmailKey = SessionUserIdKey("email") 10 | const MerchantIdKey = SessionUserIdKey("merchant_id") 11 | -------------------------------------------------------------------------------- /backend/app/frontend/utils/errors.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import "github.com/cloudwego/hertz/pkg/common/hlog" 4 | 5 | func MustHandleError(err error) { 6 | if err != nil { 7 | hlog.Fatal(err) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /backend/app/frontend/utils/type.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | type H map[string]any 4 | -------------------------------------------------------------------------------- /backend/app/merchant/.env: -------------------------------------------------------------------------------- 1 | MYSQL_USER=root 2 | MYSQL_PASSWORD=K8#tP2@y!mL9 3 | MYSQL_HOST=127.0.0.1 4 | SESSION_SECRET="KJLAJKLJLSF" -------------------------------------------------------------------------------- /backend/app/merchant/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.a 3 | *.so 4 | _obj 5 | _test 6 | *.[568vq] 7 | [568vq].out 8 | *.cgo1.go 9 | *.cgo2.c 10 | _cgo_defun.c 11 | _cgo_gotypes.go 12 | _cgo_export.* 13 | _testmain.go 14 | *.exe 15 | *.exe~ 16 | *.test 17 | *.prof 18 | *.rar 19 | *.zip 20 | *.gz 21 | *.psd 22 | *.bmd 23 | *.cfg 24 | *.pptx 25 | *.log 26 | *nohup.out 27 | *settings.pyc 28 | *.sublime-project 29 | *.sublime-workspace 30 | !.gitkeep 31 | .DS_Store 32 | /.idea 33 | /.vscode 34 | /output 35 | *.local.yml 36 | -------------------------------------------------------------------------------- /backend/app/merchant/biz/dal/init.go: -------------------------------------------------------------------------------- 1 | package dal 2 | 3 | import ( 4 | "github.com/tiktokmall/backend/app/merchant/biz/dal/mysql" 5 | "github.com/tiktokmall/backend/app/merchant/biz/dal/redis" 6 | ) 7 | 8 | func Init() { 9 | redis.Init() 10 | mysql.Init() 11 | } 12 | -------------------------------------------------------------------------------- /backend/app/merchant/biz/dal/redis/init.go: -------------------------------------------------------------------------------- 1 | package redis 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/redis/go-redis/v9" 7 | "github.com/tiktokmall/backend/app/merchant/conf" 8 | ) 9 | 10 | var ( 11 | RedisClient *redis.Client 12 | ) 13 | 14 | func Init() { 15 | RedisClient = redis.NewClient(&redis.Options{ 16 | Addr: conf.GetConf().Redis.Address, 17 | Username: conf.GetConf().Redis.Username, 18 | Password: conf.GetConf().Redis.Password, 19 | DB: conf.GetConf().Redis.DB, 20 | }) 21 | if err := RedisClient.Ping(context.Background()).Err(); err != nil { 22 | panic(err) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /backend/app/merchant/biz/model/base.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type Base struct { 8 | ID int `gorm:"primaryKey"` 9 | CreatedAt time.Time 10 | UpdatedAt time.Time 11 | DeletedAt *time.Time 12 | } 13 | -------------------------------------------------------------------------------- /backend/app/merchant/biz/model/product_cache_dao.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "context" 5 | "sync" 6 | 7 | "github.com/redis/go-redis/v9" 8 | "gorm.io/gorm" 9 | ) 10 | 11 | // 暂时没用 12 | type ProductDAO struct { 13 | ctx context.Context 14 | db *gorm.DB 15 | redis *redis.Client 16 | locks *sync.Map // 用于缓存击穿防护的互斥锁 17 | // bloomFilter *BloomFilter // 布隆过滤器 18 | } 19 | 20 | func NewProductDAO(ctx context.Context, db *gorm.DB, redis *redis.Client) *ProductDAO { 21 | return &ProductDAO{ 22 | ctx: ctx, 23 | db: db, 24 | redis: redis, 25 | locks: GetProductLocks(), 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /backend/app/merchant/biz/service/add_merchant_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/require" 8 | merchant "github.com/tiktokmall/backend/rpc_gen/kitex_gen/merchant" 9 | ) 10 | 11 | func TestAddMerchant_Run(t *testing.T) { 12 | ctx := context.Background() 13 | s := NewAddMerchantService(ctx) 14 | // init req and assert value 15 | 16 | // todo: edit your unit test 17 | testCases := []struct { 18 | caseName string 19 | args merchant.AddMerchantReq 20 | }{ 21 | { 22 | caseName: "test", 23 | args: merchant.AddMerchantReq{ 24 | Uid: 100, 25 | Username: "test", 26 | Email: "EMA", 27 | }, 28 | }, 29 | } 30 | 31 | for i := range testCases { 32 | tc := testCases[i] 33 | t.Run(tc.caseName, func(t *testing.T) { 34 | resp, err := s.Run(&tc.args) 35 | t.Logf("err: %v", err) 36 | t.Logf("resp: %v", resp) 37 | // 若 uid 或者 Email重复,则报错 38 | require.Error(t, err) 39 | }) 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /backend/app/merchant/biz/service/delete_product_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | merchant "github.com/tiktokmall/backend/rpc_gen/kitex_gen/merchant" 8 | ) 9 | 10 | func TestDeleteProduct_Run(t *testing.T) { 11 | ctx := context.Background() 12 | s := NewDeleteProductService(ctx) 13 | // init req and assert value 14 | 15 | merchantId := int64(1) 16 | productId := int64(8) 17 | 18 | req := &merchant.DeleteProductReq{ 19 | MerchantId: merchantId, 20 | Pid: productId, 21 | } 22 | resp, err := s.Run(req) 23 | t.Logf("err: %v", err) 24 | t.Logf("resp: %v", resp) 25 | 26 | // todo: edit your unit test 27 | 28 | } 29 | -------------------------------------------------------------------------------- /backend/app/merchant/biz/service/get_merchant.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/tiktokmall/backend/app/merchant/biz/dal/mysql" 7 | "github.com/tiktokmall/backend/app/merchant/biz/model" 8 | merchant "github.com/tiktokmall/backend/rpc_gen/kitex_gen/merchant" 9 | ) 10 | 11 | type GetMerchantService struct { 12 | ctx context.Context 13 | } // NewGetMerchantService new GetMerchantService 14 | func NewGetMerchantService(ctx context.Context) *GetMerchantService { 15 | return &GetMerchantService{ctx: ctx} 16 | } 17 | 18 | // Run create note info 19 | func (s *GetMerchantService) Run(req *merchant.GetMerchantReq) (resp *merchant.GetMerchantResp, err error) { 20 | // Finish your business logic. 21 | 22 | m, err := model.NewMerchantQuery(s.ctx, mysql.DB).GetByUid(int(req.GetId())) 23 | if err != nil { 24 | return nil, err 25 | } 26 | 27 | resp = &merchant.GetMerchantResp{ 28 | Id: int64(m.ID), 29 | Username: m.Username, 30 | Email: m.Email, 31 | } 32 | return 33 | } 34 | -------------------------------------------------------------------------------- /backend/app/merchant/biz/service/get_merchant_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | merchant "github.com/tiktokmall/backend/rpc_gen/kitex_gen/merchant" 8 | ) 9 | 10 | func TestGetMerchant_Run(t *testing.T) { 11 | ctx := context.Background() 12 | s := NewGetMerchantService(ctx) 13 | // init req and assert value 14 | 15 | req := &merchant.GetMerchantReq{ 16 | Id: 1, 17 | } 18 | resp, err := s.Run(req) 19 | t.Logf("err: %v", err) 20 | t.Logf("resp: %v", resp) 21 | 22 | // todo: edit your unit test 23 | 24 | } 25 | -------------------------------------------------------------------------------- /backend/app/merchant/biz/service/main_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "log" 5 | "os" 6 | "testing" 7 | 8 | "github.com/joho/godotenv" 9 | "github.com/tiktokmall/backend/app/merchant/biz/dal" 10 | "github.com/tiktokmall/backend/app/merchant/biz/dal/mysql" 11 | ) 12 | 13 | func TestMain(m *testing.M) { 14 | os.Chdir("../../") 15 | _ = godotenv.Load() 16 | dal.Init() 17 | os.Exit(m.Run()) 18 | } 19 | 20 | func TestDB(t *testing.T) { 21 | log.Printf("%v", mysql.DB) 22 | } 23 | -------------------------------------------------------------------------------- /backend/app/merchant/biz/service/product_detail_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | merchant "github.com/tiktokmall/backend/rpc_gen/kitex_gen/merchant" 8 | ) 9 | 10 | func TestProductDetail_Run(t *testing.T) { 11 | ctx := context.Background() 12 | s := NewProductDetailService(ctx) 13 | // init req and assert value 14 | 15 | req := &merchant.ProductDetailReq{ 16 | MerchantId: 1, 17 | Pid: 7, 18 | } 19 | resp, err := s.Run(req) 20 | t.Logf("err: %v", err) 21 | t.Logf("resp: %v", resp) 22 | 23 | // todo: edit your unit test 24 | 25 | } 26 | -------------------------------------------------------------------------------- /backend/app/merchant/biz/service/search_products_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | merchant "github.com/tiktokmall/backend/rpc_gen/kitex_gen/merchant" 8 | ) 9 | 10 | func TestSearchProducts_Run(t *testing.T) { 11 | ctx := context.Background() 12 | s := NewSearchProductsService(ctx) 13 | // init req and assert value 14 | 15 | req := &merchant.SearchProductsReq{ 16 | MerchantId: 1, 17 | Name: "t", 18 | MinPrice: 5.0, 19 | MaxPrice: 10.0, 20 | } 21 | resp, err := s.Run(req) 22 | t.Logf("err: %v", err) 23 | t.Logf("resp: %v", resp) 24 | 25 | // todo: edit your unit test 26 | 27 | } 28 | -------------------------------------------------------------------------------- /backend/app/merchant/biz/service/update_product_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | merchant "github.com/tiktokmall/backend/rpc_gen/kitex_gen/merchant" 8 | ) 9 | 10 | func TestUpdateProduct_Run(t *testing.T) { 11 | ctx := context.Background() 12 | s := NewUpdateProductService(ctx) 13 | // init req and assert value 14 | 15 | req := &merchant.UpdateProductReq{ 16 | MerchantId: 1, 17 | Product: &merchant.MerchantProductDetailInfo{ 18 | Id: 9, 19 | Name: "test", 20 | }, 21 | } 22 | resp, err := s.Run(req) 23 | t.Logf("err: %v", err) 24 | t.Logf("resp: %v", resp) 25 | 26 | // todo: edit your unit test 27 | 28 | } 29 | -------------------------------------------------------------------------------- /backend/app/merchant/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | RUN_NAME="merchant" 3 | mkdir -p output/bin output/conf 4 | cp script/* output/ 5 | cp -r conf/* output/conf 6 | chmod +x output/bootstrap.sh 7 | go build -o output/bin/${RUN_NAME} 8 | -------------------------------------------------------------------------------- /backend/app/merchant/conf/dev/conf.yaml: -------------------------------------------------------------------------------- 1 | kitex: 2 | service: "merchant" 3 | address: ":8881" 4 | metrics_port: ":9991" 5 | log_level: info 6 | log_file_name: "log/kitex.log" 7 | log_max_size: 10 8 | log_max_age: 3 9 | log_max_backups: 50 10 | 11 | registry: 12 | registry_address: 13 | - 127.0.0.1:8500 14 | username: "" 15 | password: "" 16 | 17 | mysql: 18 | dsn: "%s:%s@tcp(%s:3306)/product?charset=utf8mb4&parseTime=True&loc=Local" 19 | 20 | redis: 21 | address: "127.0.0.1:6379" 22 | username: "" 23 | password: "" 24 | db: 0 25 | 26 | nats: 27 | address: "nats://127.0.0.1:4222" -------------------------------------------------------------------------------- /backend/app/merchant/conf/online/conf.yaml: -------------------------------------------------------------------------------- 1 | kitex: 2 | service: "merchant" 3 | address: ":8881" 4 | metrics_port: ":9991" 5 | log_level: info 6 | log_file_name: "log/kitex.log" 7 | log_max_size: 10 8 | log_max_age: 3 9 | log_max_backups: 50 10 | 11 | registry: 12 | registry_address: 13 | - 127.0.0.1:8500 14 | username: "" 15 | password: "" 16 | 17 | mysql: 18 | dsn: "%s:%s@tcp(%s:3306)/product?charset=utf8mb4&parseTime=True&loc=Local" 19 | 20 | redis: 21 | address: "127.0.0.1:6379" 22 | username: "" 23 | password: "" 24 | db: 0 25 | 26 | nats: 27 | address: "nats://127.0.0.1:4222" -------------------------------------------------------------------------------- /backend/app/merchant/conf/test/conf.yaml: -------------------------------------------------------------------------------- 1 | kitex: 2 | service: "merchant" 3 | address: ":8881" 4 | metrics_port: ":9991" 5 | log_level: info 6 | log_file_name: "log/kitex.log" 7 | log_max_size: 10 8 | log_max_age: 3 9 | log_max_backups: 50 10 | 11 | registry: 12 | registry_address: 13 | - 127.0.0.1:8500 14 | username: "" 15 | password: "" 16 | 17 | mysql: 18 | dsn: "%s:%s@tcp(%s:3306)/product?charset=utf8mb4&parseTime=True&loc=Local" 19 | 20 | redis: 21 | address: "127.0.0.1:6379" 22 | username: "" 23 | password: "" 24 | db: 0 25 | 26 | nats: 27 | address: "nats://127.0.0.1:4222" -------------------------------------------------------------------------------- /backend/app/merchant/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | mysql: 4 | image: 'mysql:latest' 5 | ports: 6 | - 3306:3306 7 | environment: 8 | - MYSQL_DATABASE=gorm 9 | - MYSQL_USER=gorm 10 | - MYSQL_PASSWORD=gorm 11 | - MYSQL_RANDOM_ROOT_PASSWORD="yes" 12 | redis: 13 | image: 'redis:latest' 14 | ports: 15 | - 6379:6379 16 | -------------------------------------------------------------------------------- /backend/app/merchant/infra/mq/nats.go: -------------------------------------------------------------------------------- 1 | package mq 2 | 3 | import ( 4 | "github.com/tiktokmall/backend/app/merchant/biz/dal/redis" 5 | "github.com/tiktokmall/backend/app/merchant/conf" 6 | 7 | "github.com/nats-io/nats.go" 8 | ) 9 | 10 | var ( 11 | Nc *nats.Conn 12 | err error 13 | Natscp *NatsCacheProcessor 14 | ) 15 | 16 | func Init() { 17 | // 需要提前初始化 redis 18 | Nc, err = nats.Connect(conf.GetConf().Nats.Address) 19 | 20 | if err != nil { 21 | panic(err) 22 | } 23 | Natscp = InitNatsCacheProcessor(Nc, redis.RedisClient) 24 | Natscp.StartProcessor() 25 | } 26 | -------------------------------------------------------------------------------- /backend/app/merchant/infra/mq/nats_test.go: -------------------------------------------------------------------------------- 1 | package mq 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "os" 7 | "testing" 8 | "time" 9 | 10 | "github.com/nats-io/nats.go" 11 | "github.com/tiktokmall/backend/app/merchant/conf" 12 | ) 13 | 14 | func TestPublishAndScribe(t *testing.T) { 15 | Nc, err = nats.Connect("nats://127.0.0.1:4222") 16 | if err != nil { 17 | log.Fatal(err) 18 | } 19 | go func() { 20 | for i := 0; i < 10; i++ { 21 | Nc.Publish("testCount", []byte(fmt.Sprintf("%v", i))) 22 | time.Sleep(time.Millisecond) 23 | } 24 | }() 25 | 26 | go func() { 27 | 28 | Nc.Subscribe("testCount", func(msg *nats.Msg) { 29 | data := msg.Data 30 | fmt.Printf("%v\n", string(data)) 31 | }) 32 | 33 | }() 34 | time.Sleep(5 * time.Second) 35 | } 36 | 37 | func TestNats(t *testing.T) { 38 | os.Chdir("../../") 39 | // 空的话,是 127.0.0.1:4222 40 | Nc, err = nats.Connect("") 41 | log.Println("empty string", Nc.ConnectedAddr()) 42 | Nc, err = nats.Connect(conf.GetConf().Nats.Address) 43 | log.Println("config string", Nc.ConnectedAddr()) 44 | } 45 | -------------------------------------------------------------------------------- /backend/app/merchant/kitex_info.yaml: -------------------------------------------------------------------------------- 1 | kitexinfo: 2 | ServiceName: 'merchant' 3 | ToolVersion: 'v0.9.1' 4 | -------------------------------------------------------------------------------- /backend/app/merchant/readme.md: -------------------------------------------------------------------------------- 1 | # *** Project 2 | 3 | ## introduce 4 | 5 | - Use the [Kitex](https://github.com/cloudwego/kitex/) framework 6 | - Generating the base code for unit tests. 7 | - Provides basic config functions 8 | - Provides the most basic MVC code hierarchy. 9 | 10 | ## Directory structure 11 | 12 | | catalog | introduce | 13 | | ---- | ---- | 14 | | conf | Configuration files | 15 | | main.go | Startup file | 16 | | handler.go | Used for request processing return of response. | 17 | | kitex_gen | kitex generated code | 18 | | biz/service | The actual business logic. | 19 | | biz/dal | Logic for operating the storage layer | 20 | 21 | ## How to run 22 | 23 | ```shell 24 | sh build.sh 25 | sh output/bootstrap.sh 26 | ``` 27 | -------------------------------------------------------------------------------- /backend/app/merchant/script/bootstrap.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | CURDIR=$(cd $(dirname $0); pwd) 3 | echo "$CURDIR/bin/merchant" 4 | exec "$CURDIR/bin/merchant" 5 | -------------------------------------------------------------------------------- /backend/app/order/.env: -------------------------------------------------------------------------------- 1 | MYSQL_USER=root 2 | MYSQL_PASSWORD=K8#tP2@y!mL9 3 | MYSQL_HOST=127.0.0.1 4 | SESSION_SECRET="KJLAJKLJLSF" -------------------------------------------------------------------------------- /backend/app/order/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.a 3 | *.so 4 | _obj 5 | _test 6 | *.[568vq] 7 | [568vq].out 8 | *.cgo1.go 9 | *.cgo2.c 10 | _cgo_defun.c 11 | _cgo_gotypes.go 12 | _cgo_export.* 13 | _testmain.go 14 | *.exe 15 | *.exe~ 16 | *.test 17 | *.prof 18 | *.rar 19 | *.zip 20 | *.gz 21 | *.psd 22 | *.bmd 23 | *.cfg 24 | *.pptx 25 | *.log 26 | *nohup.out 27 | *settings.pyc 28 | *.sublime-project 29 | *.sublime-workspace 30 | !.gitkeep 31 | .DS_Store 32 | /.idea 33 | /.vscode 34 | /output 35 | *.local.yml 36 | -------------------------------------------------------------------------------- /backend/app/order/biz/consumer/consumer.go: -------------------------------------------------------------------------------- 1 | package consumer 2 | 3 | import ( 4 | "github.com/tiktokmall/backend/app/order/biz/consumer/order" 5 | ) 6 | 7 | func Init() { 8 | order.ConsumerInit() 9 | } 10 | -------------------------------------------------------------------------------- /backend/app/order/biz/consumer/order/order_test.go: -------------------------------------------------------------------------------- 1 | package order 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestConsumerInit(t *testing.T) { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /backend/app/order/biz/dal/init.go: -------------------------------------------------------------------------------- 1 | package dal 2 | 3 | import ( 4 | "github.com/tiktokmall/backend/app/order/biz/dal/mysql" 5 | "github.com/tiktokmall/backend/app/order/biz/dal/redis" 6 | ) 7 | 8 | func Init() { 9 | redis.Init() 10 | mysql.Init() 11 | } 12 | -------------------------------------------------------------------------------- /backend/app/order/biz/dal/mysql/init.go: -------------------------------------------------------------------------------- 1 | package mysql 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | 7 | "github.com/tiktokmall/backend/app/order/biz/model" 8 | "github.com/tiktokmall/backend/app/order/conf" 9 | 10 | "github.com/cloudwego/kitex/pkg/klog" 11 | "gorm.io/driver/mysql" 12 | "gorm.io/gorm" 13 | "gorm.io/plugin/opentelemetry/tracing" 14 | ) 15 | 16 | var ( 17 | DB *gorm.DB 18 | err error 19 | ) 20 | 21 | func Init() { 22 | dsn := fmt.Sprintf(conf.GetConf().MySQL.DSN, os.Getenv("MYSQL_USER"), os.Getenv("MYSQL_PASSWORD"), os.Getenv("MYSQL_HOST")) 23 | DB, err = gorm.Open(mysql.Open(dsn), 24 | &gorm.Config{ 25 | PrepareStmt: true, 26 | SkipDefaultTransaction: true, 27 | }, 28 | ) 29 | if err != nil { 30 | panic(err) 31 | } 32 | if err := DB.Use(tracing.NewPlugin(tracing.WithoutMetrics())); err != nil { 33 | panic(err) 34 | } 35 | if os.Getenv("GO_ENV") != "online" { 36 | if err := DB.AutoMigrate( 37 | &model.Order{}, 38 | &model.OrderItem{}, 39 | ); err != nil { 40 | klog.Error(err) 41 | } 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /backend/app/order/biz/dal/redis/init.go: -------------------------------------------------------------------------------- 1 | package redis 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/redis/go-redis/v9" 7 | "github.com/tiktokmall/backend/app/order/conf" 8 | ) 9 | 10 | var ( 11 | RedisClient *redis.Client 12 | ) 13 | 14 | func Init() { 15 | RedisClient = redis.NewClient(&redis.Options{ 16 | Addr: conf.GetConf().Redis.Address, 17 | Username: conf.GetConf().Redis.Username, 18 | Password: conf.GetConf().Redis.Password, 19 | DB: conf.GetConf().Redis.DB, 20 | }) 21 | if err := RedisClient.Ping(context.Background()).Err(); err != nil { 22 | panic(err) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /backend/app/order/biz/model/order_item.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "gorm.io/gorm" 4 | 5 | type OrderItem struct { 6 | gorm.Model 7 | ProductId uint32 `gorm:"type:int(11)"` 8 | OrderIdRefer string `gorm:"type:varchar(100);index"` 9 | Quantity int32 `gorm:"type:int(11)"` 10 | Cost float32 `gorm:"type:decimal(10,2)"` 11 | } 12 | 13 | func (OrderItem) TableName() string { 14 | return "order_item" 15 | } 16 | -------------------------------------------------------------------------------- /backend/app/order/biz/service/change_order_status.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "github.com/tiktokmall/backend/app/order/biz/dal/mysql" 6 | "github.com/tiktokmall/backend/app/order/biz/model" 7 | order "github.com/tiktokmall/backend/rpc_gen/kitex_gen/order" 8 | ) 9 | 10 | type ChangeOrderStatusService struct { 11 | ctx context.Context 12 | } // NewChangeOrderStatusService new ChangeOrderStatusService 13 | func NewChangeOrderStatusService(ctx context.Context) *ChangeOrderStatusService { 14 | return &ChangeOrderStatusService{ctx: ctx} 15 | } 16 | 17 | // Run create note info 18 | func (s *ChangeOrderStatusService) Run(req *order.ChangeOrderStatusReq) (resp *order.ChangeOrderStatusResp, err error) { 19 | err = model.ChangeOrderStatus(mysql.DB, s.ctx, req.OrderId, req.OrderStatus) 20 | return &order.ChangeOrderStatusResp{}, err 21 | } 22 | -------------------------------------------------------------------------------- /backend/app/order/biz/service/change_order_status_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | order "github.com/tiktokmall/backend/rpc_gen/kitex_gen/order" 6 | "testing" 7 | ) 8 | 9 | func TestChangeOrderStatus_Run(t *testing.T) { 10 | ctx := context.Background() 11 | s := NewChangeOrderStatusService(ctx) 12 | // init req and assert value 13 | 14 | req := &order.ChangeOrderStatusReq{} 15 | resp, err := s.Run(req) 16 | t.Logf("err: %v", err) 17 | t.Logf("resp: %v", resp) 18 | 19 | // todo: edit your unit test 20 | 21 | } 22 | -------------------------------------------------------------------------------- /backend/app/order/biz/service/list_oder_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | order "github.com/tiktokmall/backend/rpc_gen/kitex_gen/order" 8 | ) 9 | 10 | func TestListOder_Run(t *testing.T) { 11 | ctx := context.Background() 12 | s := NewListOderService(ctx) 13 | // init req and assert value 14 | 15 | req := &order.ListOrderReq{} 16 | resp, err := s.Run(req) 17 | t.Logf("err: %v", err) 18 | t.Logf("resp: %v", resp) 19 | 20 | // todo: edit your unit test 21 | 22 | } 23 | -------------------------------------------------------------------------------- /backend/app/order/biz/service/place_order_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | order "github.com/tiktokmall/backend/rpc_gen/kitex_gen/order" 8 | ) 9 | 10 | func TestPlaceOrder_Run(t *testing.T) { 11 | ctx := context.Background() 12 | s := NewPlaceOrderService(ctx) 13 | // init req and assert value 14 | 15 | req := &order.PlaceOrderReq{} 16 | resp, err := s.Run(req) 17 | t.Logf("err: %v", err) 18 | t.Logf("resp: %v", resp) 19 | 20 | // todo: edit your unit test 21 | 22 | } 23 | -------------------------------------------------------------------------------- /backend/app/order/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | RUN_NAME="order" 3 | mkdir -p output/bin output/conf 4 | cp script/* output/ 5 | cp -r conf/* output/conf 6 | chmod +x output/bootstrap.sh 7 | go build -o output/bin/${RUN_NAME} 8 | -------------------------------------------------------------------------------- /backend/app/order/conf/dev/conf.yaml: -------------------------------------------------------------------------------- 1 | kitex: 2 | service: "order" 3 | address: ":8884" 4 | metrics_port: ":9994" 5 | log_level: info 6 | log_file_name: "log/kitex.log" 7 | log_max_size: 10 8 | log_max_age: 3 9 | log_max_backups: 50 10 | 11 | registry: 12 | registry_address: 13 | - consul:8500 14 | username: "" 15 | password: "" 16 | 17 | mysql: 18 | dsn: "%s:%s@tcp(%s:3306)/order?charset=utf8mb4&parseTime=True&loc=Local" 19 | 20 | redis: 21 | address: "redis:6379" 22 | username: "" 23 | password: "" 24 | db: 0 25 | 26 | nats: 27 | address: "nats://nats:4222" -------------------------------------------------------------------------------- /backend/app/order/conf/online/conf.yaml: -------------------------------------------------------------------------------- 1 | kitex: 2 | service: "order" 3 | address: ":8884" 4 | metrics_port: ":9994" 5 | log_level: info 6 | log_file_name: "log/kitex.log" 7 | log_max_size: 10 8 | log_max_age: 3 9 | log_max_backups: 50 10 | 11 | registry: 12 | registry_address: 13 | - consul:8500 14 | username: "" 15 | password: "" 16 | 17 | mysql: 18 | dsn: "%s:%s@tcp(%s:3306)/order?charset=utf8mb4&parseTime=True&loc=Local" 19 | 20 | redis: 21 | address: "redis:6379" 22 | username: "" 23 | password: "" 24 | db: 0 25 | 26 | nats: 27 | address: "nats://nats:4222" -------------------------------------------------------------------------------- /backend/app/order/conf/test/conf.yaml: -------------------------------------------------------------------------------- 1 | kitex: 2 | service: "order" 3 | address: ":8884" 4 | metrics_port: ":9994" 5 | log_level: info 6 | log_file_name: "log/kitex.log" 7 | log_max_size: 10 8 | log_max_age: 3 9 | log_max_backups: 50 10 | 11 | registry: 12 | registry_address: 13 | - 127.0.0.1:8500 14 | username: "" 15 | password: "" 16 | 17 | mysql: 18 | dsn: "%s:%s@tcp(%s:3306)/order?charset=utf8mb4&parseTime=True&loc=Local" 19 | 20 | redis: 21 | address: "127.0.0.1:6379" 22 | username: "" 23 | password: "" 24 | db: 0 25 | 26 | nats: 27 | address: "nats://127.0.0.1:4222" -------------------------------------------------------------------------------- /backend/app/order/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | mysql: 4 | image: 'mysql:latest' 5 | ports: 6 | - 3306:3306 7 | environment: 8 | - MYSQL_DATABASE=gorm 9 | - MYSQL_USER=gorm 10 | - MYSQL_PASSWORD=gorm 11 | - MYSQL_RANDOM_ROOT_PASSWORD="yes" 12 | redis: 13 | image: 'redis:latest' 14 | ports: 15 | - 6379:6379 16 | -------------------------------------------------------------------------------- /backend/app/order/infra/mq/nats.go: -------------------------------------------------------------------------------- 1 | package mq 2 | 3 | import ( 4 | "github.com/nats-io/nats.go" 5 | "github.com/tiktokmall/backend/app/order/conf" 6 | ) 7 | 8 | var ( 9 | Nc *nats.Conn 10 | err error 11 | ) 12 | 13 | func Init() { 14 | Nc, err = nats.Connect(conf.GetConf().Nats.Address) 15 | if err != nil { 16 | panic(err) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /backend/app/order/kitex_info.yaml: -------------------------------------------------------------------------------- 1 | kitexinfo: 2 | ServiceName: 'order' 3 | ToolVersion: 'v0.9.1' 4 | -------------------------------------------------------------------------------- /backend/app/order/readme.md: -------------------------------------------------------------------------------- 1 | # *** Project 2 | 3 | ## introduce 4 | 5 | - Use the [Kitex](https://github.com/cloudwego/kitex/) framework 6 | - Generating the base code for unit tests. 7 | - Provides basic config functions 8 | - Provides the most basic MVC code hierarchy. 9 | 10 | ## Directory structure 11 | 12 | | catalog | introduce | 13 | | ---- | ---- | 14 | | conf | Configuration files | 15 | | main.go | Startup file | 16 | | handler.go | Used for request processing return of response. | 17 | | kitex_gen | kitex generated code | 18 | | biz/service | The actual business logic. | 19 | | biz/dal | Logic for operating the storage layer | 20 | 21 | ## How to run 22 | 23 | ```shell 24 | sh build.sh 25 | sh output/bootstrap.sh 26 | ``` 27 | -------------------------------------------------------------------------------- /backend/app/order/script/bootstrap.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | CURDIR=$(cd $(dirname $0); pwd) 3 | echo "$CURDIR/bin/order" 4 | exec "$CURDIR/bin/order" 5 | -------------------------------------------------------------------------------- /backend/app/payment/.env: -------------------------------------------------------------------------------- 1 | MYSQL_USER=root 2 | MYSQL_PASSWORD=K8#tP2@y!mL9 3 | MYSQL_HOST=127.0.0.1 4 | SESSION_SECRET="KJLAJKLJLSF" -------------------------------------------------------------------------------- /backend/app/payment/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.a 3 | *.so 4 | _obj 5 | _test 6 | *.[568vq] 7 | [568vq].out 8 | *.cgo1.go 9 | *.cgo2.c 10 | _cgo_defun.c 11 | _cgo_gotypes.go 12 | _cgo_export.* 13 | _testmain.go 14 | *.exe 15 | *.exe~ 16 | *.test 17 | *.prof 18 | *.rar 19 | *.zip 20 | *.gz 21 | *.psd 22 | *.bmd 23 | *.cfg 24 | *.pptx 25 | *.log 26 | *nohup.out 27 | *settings.pyc 28 | *.sublime-project 29 | *.sublime-workspace 30 | !.gitkeep 31 | .DS_Store 32 | /.idea 33 | /.vscode 34 | /output 35 | *.local.yml 36 | -------------------------------------------------------------------------------- /backend/app/payment/biz/dal/init.go: -------------------------------------------------------------------------------- 1 | package dal 2 | 3 | import ( 4 | "github.com/tiktokmall/backend/app/payment/biz/dal/mysql" 5 | "github.com/tiktokmall/backend/app/payment/biz/dal/redis" 6 | ) 7 | 8 | func Init() { 9 | redis.Init() 10 | mysql.Init() 11 | } 12 | -------------------------------------------------------------------------------- /backend/app/payment/biz/dal/mysql/init.go: -------------------------------------------------------------------------------- 1 | package mysql 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | 7 | "github.com/tiktokmall/backend/app/payment/biz/model" 8 | "github.com/tiktokmall/backend/app/payment/conf" 9 | 10 | "gorm.io/driver/mysql" 11 | "gorm.io/gorm" 12 | "gorm.io/plugin/opentelemetry/tracing" 13 | ) 14 | 15 | var ( 16 | DB *gorm.DB 17 | err error 18 | ) 19 | 20 | func Init() { 21 | dsn := fmt.Sprintf(conf.GetConf().MySQL.DSN, os.Getenv("MYSQL_USER"), os.Getenv("MYSQL_PASSWORD"), os.Getenv("MYSQL_HOST")) 22 | DB, err = gorm.Open(mysql.Open(dsn), 23 | &gorm.Config{ 24 | PrepareStmt: true, 25 | SkipDefaultTransaction: true, 26 | }, 27 | ) 28 | if err != nil { 29 | panic(err) 30 | } 31 | if err := DB.Use(tracing.NewPlugin(tracing.WithoutMetrics())); err != nil { 32 | panic(err) 33 | } 34 | if os.Getenv("GO_ENV") != "online" { 35 | DB.AutoMigrate( //nolint:errcheck 36 | &model.PaymentLog{}, 37 | ) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /backend/app/payment/biz/dal/redis/init.go: -------------------------------------------------------------------------------- 1 | package redis 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/redis/go-redis/v9" 7 | "github.com/tiktokmall/backend/app/payment/conf" 8 | ) 9 | 10 | var ( 11 | RedisClient *redis.Client 12 | ) 13 | 14 | func Init() { 15 | RedisClient = redis.NewClient(&redis.Options{ 16 | Addr: conf.GetConf().Redis.Address, 17 | Username: conf.GetConf().Redis.Username, 18 | Password: conf.GetConf().Redis.Password, 19 | DB: conf.GetConf().Redis.DB, 20 | }) 21 | if err := RedisClient.Ping(context.Background()).Err(); err != nil { 22 | panic(err) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /backend/app/payment/biz/model/base.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "time" 4 | 5 | type Base struct { 6 | ID int `gorm:"primarykey"` 7 | CreatedAt time.Time 8 | UpdatedAt time.Time 9 | } 10 | -------------------------------------------------------------------------------- /backend/app/payment/biz/model/payment.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "context" 5 | "time" 6 | 7 | "gorm.io/gorm" 8 | ) 9 | 10 | type PaymentLog struct { 11 | Base 12 | UserId uint32 `json:"user_id"` 13 | OrderId string `json:"order_id"` 14 | TransactionId string `json:"transaction_id"` 15 | Amount float32 `json:"amount"` 16 | PayAt time.Time `json:"pay_at"` 17 | } 18 | 19 | func (PaymentLog) TableName() string { 20 | return "payment" 21 | } 22 | 23 | func CreatePaymentLog(db *gorm.DB, ctx context.Context, payment *PaymentLog) error { 24 | return db.WithContext(ctx).Model(&PaymentLog{}).Create(payment).Error 25 | } 26 | -------------------------------------------------------------------------------- /backend/app/payment/biz/service/alipay_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | payment "github.com/tiktokmall/backend/rpc_gen/kitex_gen/payment" 7 | ) 8 | 9 | func TestAlipay_Run(t *testing.T) { 10 | ctx := context.Background() 11 | s := NewAlipayService(ctx) 12 | // init req and assert value 13 | 14 | req := &payment.AlipayReq{} 15 | resp, err := s.Run(req) 16 | t.Logf("err: %v", err) 17 | t.Logf("resp: %v", resp) 18 | 19 | // todo: edit your unit test 20 | 21 | } 22 | -------------------------------------------------------------------------------- /backend/app/payment/biz/service/charge_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | payment "github.com/tiktokmall/backend/rpc_gen/kitex_gen/payment" 8 | ) 9 | 10 | func TestCharge_Run(t *testing.T) { 11 | ctx := context.Background() 12 | s := NewChargeService(ctx) 13 | // init req and assert value 14 | 15 | req := &payment.ChargeReq{} 16 | resp, err := s.Run(req) 17 | t.Logf("err: %v", err) 18 | t.Logf("resp: %v", resp) 19 | 20 | // todo: edit your unit test 21 | 22 | } 23 | -------------------------------------------------------------------------------- /backend/app/payment/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | RUN_NAME="payment" 3 | mkdir -p output/bin output/conf 4 | cp script/* output/ 5 | cp -r conf/* output/conf 6 | chmod +x output/bootstrap.sh 7 | go build -o output/bin/${RUN_NAME} 8 | -------------------------------------------------------------------------------- /backend/app/payment/conf/dev/conf.yaml: -------------------------------------------------------------------------------- 1 | kitex: 2 | service: "payment" 3 | address: ":8886" 4 | metrics_port: ":9996" 5 | log_level: info 6 | log_file_name: "log/kitex.log" 7 | log_max_size: 10 8 | log_max_age: 3 9 | log_max_backups: 50 10 | 11 | registry: 12 | registry_address: 13 | - consul:8500 14 | username: "" 15 | password: "" 16 | 17 | mysql: 18 | dsn: "%s:%s@tcp(%s:3306)/payment?charset=utf8mb4&parseTime=True&loc=Local" 19 | 20 | redis: 21 | address: "redis:6379" 22 | username: "" 23 | password: "" 24 | db: 0 25 | -------------------------------------------------------------------------------- /backend/app/payment/conf/online/conf.yaml: -------------------------------------------------------------------------------- 1 | kitex: 2 | service: "payment" 3 | address: ":8886" 4 | metrics_port: ":9996" 5 | log_level: info 6 | log_file_name: "log/kitex.log" 7 | log_max_size: 10 8 | log_max_age: 3 9 | log_max_backups: 50 10 | 11 | registry: 12 | registry_address: 13 | - consul:8500 14 | username: "" 15 | password: "" 16 | 17 | mysql: 18 | dsn: "%s:%s@tcp(%s:3306)/payment?charset=utf8mb4&parseTime=True&loc=Local" 19 | 20 | redis: 21 | address: "redis:6379" 22 | username: "" 23 | password: "" 24 | db: 0 25 | -------------------------------------------------------------------------------- /backend/app/payment/conf/test/conf.yaml: -------------------------------------------------------------------------------- 1 | kitex: 2 | service: "payment" 3 | address: ":8886" 4 | metrics_port: ":9996" 5 | log_level: info 6 | log_file_name: "log/kitex.log" 7 | log_max_size: 10 8 | log_max_age: 3 9 | log_max_backups: 50 10 | 11 | registry: 12 | registry_address: 13 | - 127.0.0.1:8500 14 | username: "" 15 | password: "" 16 | 17 | mysql: 18 | dsn: "%s:%s@tcp(%s:3306)/payment?charset=utf8mb4&parseTime=True&loc=Local" 19 | 20 | redis: 21 | address: "127.0.0.1:6379" 22 | username: "" 23 | password: "" 24 | db: 0 25 | -------------------------------------------------------------------------------- /backend/app/payment/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | mysql: 4 | image: 'mysql:latest' 5 | ports: 6 | - 3306:3306 7 | environment: 8 | - MYSQL_DATABASE=gorm 9 | - MYSQL_USER=gorm 10 | - MYSQL_PASSWORD=gorm 11 | - MYSQL_RANDOM_ROOT_PASSWORD="yes" 12 | redis: 13 | image: 'redis:latest' 14 | ports: 15 | - 6379:6379 16 | -------------------------------------------------------------------------------- /backend/app/payment/handler.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/tiktokmall/backend/app/payment/biz/service" 7 | payment "github.com/tiktokmall/backend/rpc_gen/kitex_gen/payment" 8 | ) 9 | 10 | // PaymentServiceImpl implements the last service interface defined in the IDL. 11 | type PaymentServiceImpl struct{} 12 | 13 | // Charge implements the PaymentServiceImpl interface. 14 | func (s *PaymentServiceImpl) Charge(ctx context.Context, req *payment.ChargeReq) (resp *payment.ChargeResp, err error) { 15 | resp, err = service.NewChargeService(ctx).Run(req) 16 | 17 | return resp, err 18 | } 19 | 20 | // Alipay implements the PaymentServiceImpl interface. 21 | func (s *PaymentServiceImpl) Alipay(ctx context.Context, req *payment.AlipayReq) (resp *payment.AlipayResp, err error) { 22 | resp, err = service.NewAlipayService(ctx).Run(req) 23 | 24 | return resp, err 25 | } 26 | -------------------------------------------------------------------------------- /backend/app/payment/kitex_info.yaml: -------------------------------------------------------------------------------- 1 | kitexinfo: 2 | ServiceName: 'payment' 3 | ToolVersion: 'v0.9.1' 4 | -------------------------------------------------------------------------------- /backend/app/payment/readme.md: -------------------------------------------------------------------------------- 1 | # *** Project 2 | 3 | ## introduce 4 | 5 | - Use the [Kitex](https://github.com/cloudwego/kitex/) framework 6 | - Generating the base code for unit tests. 7 | - Provides basic config functions 8 | - Provides the most basic MVC code hierarchy. 9 | 10 | ## Directory structure 11 | 12 | | catalog | introduce | 13 | | ---- | ---- | 14 | | conf | Configuration files | 15 | | main.go | Startup file | 16 | | handler.go | Used for request processing return of response. | 17 | | kitex_gen | kitex generated code | 18 | | biz/service | The actual business logic. | 19 | | biz/dal | Logic for operating the storage layer | 20 | 21 | ## How to run 22 | 23 | ```shell 24 | sh build.sh 25 | sh output/bootstrap.sh 26 | ``` 27 | -------------------------------------------------------------------------------- /backend/app/payment/script/bootstrap.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | CURDIR=$(cd $(dirname $0); pwd) 3 | echo "$CURDIR/bin/payment" 4 | exec "$CURDIR/bin/payment" 5 | -------------------------------------------------------------------------------- /backend/app/product/.env: -------------------------------------------------------------------------------- 1 | MYSQL_USER=root 2 | MYSQL_PASSWORD=K8#tP2@y!mL9 3 | MYSQL_HOST=127.0.0.1 4 | SESSION_SECRET="KJLAJKLJLSF" 5 | 6 | OSS_ACCESS_KEY_ID="LTAI5tC3VZ1hcwKsSuA4ZniM" 7 | OSS_ACCESS_KEY_SECRET="tRXb4YVzHr1jIebfxs3i5dGtbJ9LdV" -------------------------------------------------------------------------------- /backend/app/product/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.a 3 | *.so 4 | _obj 5 | _test 6 | *.[568vq] 7 | [568vq].out 8 | *.cgo1.go 9 | *.cgo2.c 10 | _cgo_defun.c 11 | _cgo_gotypes.go 12 | _cgo_export.* 13 | _testmain.go 14 | *.exe 15 | *.exe~ 16 | *.test 17 | *.prof 18 | *.rar 19 | *.zip 20 | *.gz 21 | *.psd 22 | *.bmd 23 | *.cfg 24 | *.pptx 25 | *.log 26 | *nohup.out 27 | *settings.pyc 28 | *.sublime-project 29 | *.sublime-workspace 30 | !.gitkeep 31 | .DS_Store 32 | /.idea 33 | /.vscode 34 | /output 35 | *.local.yml 36 | -------------------------------------------------------------------------------- /backend/app/product/biz/dal/init.go: -------------------------------------------------------------------------------- 1 | package dal 2 | 3 | import ( 4 | "github.com/tiktokmall/backend/app/product/biz/dal/mysql" 5 | "github.com/tiktokmall/backend/app/product/biz/dal/redis" 6 | ) 7 | 8 | func Init() { 9 | redis.Init() 10 | mysql.Init() 11 | } 12 | -------------------------------------------------------------------------------- /backend/app/product/biz/dal/redis/init.go: -------------------------------------------------------------------------------- 1 | package redis 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/redis/go-redis/v9" 7 | "github.com/tiktokmall/backend/app/product/conf" 8 | ) 9 | 10 | var ( 11 | RedisClient *redis.Client 12 | ) 13 | 14 | func Init() { 15 | RedisClient = redis.NewClient(&redis.Options{ 16 | Addr: conf.GetConf().Redis.Address, 17 | Username: conf.GetConf().Redis.Username, 18 | Password: conf.GetConf().Redis.Password, 19 | DB: conf.GetConf().Redis.DB, 20 | }) 21 | if err := RedisClient.Ping(context.Background()).Err(); err != nil { 22 | panic(err) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /backend/app/product/biz/model/base.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "time" 4 | 5 | type Base struct { 6 | ID int `gorm:"primaryKey"` 7 | CreatedAt time.Time 8 | UpdatedAt time.Time 9 | DeletedAt time.Time 10 | } 11 | -------------------------------------------------------------------------------- /backend/app/product/biz/model/category.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "context" 5 | 6 | "gorm.io/gorm" 7 | ) 8 | 9 | type Category struct { 10 | Base 11 | Name string `json:"name"` 12 | Description string `json:"description"` 13 | Products []Product `json:"product" gorm:"many2many:product_category;"` 14 | } 15 | 16 | func (Category) TableName() string { 17 | return "category" 18 | } 19 | 20 | type CategoryQuery struct { 21 | ctx context.Context 22 | db *gorm.DB 23 | } 24 | 25 | func (c *CategoryQuery) GetProductByCategoryName(name string) (categories []Category, err error) { 26 | err = c.db.WithContext(c.ctx).Model(Category{}).Where(&Category{Name: name}). 27 | Preload("Products").Find(&categories).Error 28 | return 29 | } 30 | func (c *CategoryQuery) InsertMany(categories []Category) (err error) { 31 | err = c.db.WithContext(c.ctx).Model(&Category{}).Create(&categories).Error 32 | return 33 | } 34 | 35 | func NewCategoryQuery(ctx context.Context, db *gorm.DB) *CategoryQuery { 36 | return &CategoryQuery{ 37 | ctx: ctx, 38 | db: db, 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /backend/app/product/biz/model/product_test.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "context" 5 | "log" 6 | "testing" 7 | ) 8 | 9 | func TestProductQuery_SearchProducts(t *testing.T) { 10 | productQuery := NewProductQuery(context.Background(), testDB) 11 | product, err := productQuery.SearchProducts("test") 12 | log.Println(product, err) 13 | 14 | } 15 | -------------------------------------------------------------------------------- /backend/app/product/biz/service/get_product_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | product "github.com/tiktokmall/backend/rpc_gen/kitex_gen/product" 8 | ) 9 | 10 | func TestGetProduct_Run(t *testing.T) { 11 | ctx := context.Background() 12 | s := NewGetProductService(ctx) 13 | // init req and assert value 14 | 15 | req := &product.GetProductReq{} 16 | resp, err := s.Run(req) 17 | t.Logf("err: %v", err) 18 | t.Logf("resp: %v", resp) 19 | 20 | // todo: edit your unit test 21 | 22 | } 23 | -------------------------------------------------------------------------------- /backend/app/product/biz/service/list_products_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | product "github.com/tiktokmall/backend/rpc_gen/kitex_gen/product" 8 | ) 9 | 10 | func TestListProducts_Run(t *testing.T) { 11 | ctx := context.Background() 12 | s := NewListProductsService(ctx) 13 | // init req and assert value 14 | 15 | req := &product.ListProductsReq{} 16 | resp, err := s.Run(req) 17 | t.Logf("err: %v", err) 18 | t.Logf("resp: %v", resp) 19 | 20 | // todo: edit your unit test 21 | 22 | } 23 | -------------------------------------------------------------------------------- /backend/app/product/biz/service/search_products_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | product "github.com/tiktokmall/backend/rpc_gen/kitex_gen/product" 8 | ) 9 | 10 | func TestSearchProducts_Run(t *testing.T) { 11 | ctx := context.Background() 12 | s := NewSearchProductsService(ctx) 13 | // init req and assert value 14 | 15 | req := &product.SearchProductsReq{} 16 | resp, err := s.Run(req) 17 | t.Logf("err: %v", err) 18 | t.Logf("resp: %v", resp) 19 | 20 | // todo: edit your unit test 21 | 22 | } 23 | -------------------------------------------------------------------------------- /backend/app/product/biz/util/random.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "strings" 7 | "time" 8 | ) 9 | 10 | // 定义一些常用的邮箱域名 11 | var emailDomains = []string{ 12 | "gmail.com", 13 | "yahoo.com", 14 | "hotmail.com", 15 | "outlook.com", 16 | "163.com", 17 | "qq.com", 18 | "sohu.com", 19 | "sina.com", 20 | } 21 | 22 | // 生成随机字符串作为邮箱用户名 23 | func GenerateRandomString(length int) string { 24 | 25 | // 定义可用的字符集 26 | const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" 27 | seededRand := rand.New(rand.NewSource(time.Now().UnixNano())) 28 | var sb strings.Builder 29 | for i := 0; i < length; i++ { 30 | sb.WriteByte(charset[seededRand.Intn(len(charset))]) 31 | } 32 | return sb.String() 33 | } 34 | 35 | // 生成随机邮箱 36 | func GenerateRandomEmail(usernameLength int) string { 37 | // 生成随机用户名 38 | username := GenerateRandomString(usernameLength) 39 | // 随机选择一个邮箱域名 40 | domain := emailDomains[rand.Intn(len(emailDomains))] 41 | return fmt.Sprintf("%s@%s", username, domain) 42 | } 43 | -------------------------------------------------------------------------------- /backend/app/product/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | RUN_NAME="product" 3 | mkdir -p output/bin output/conf 4 | cp script/* output/ 5 | cp -r conf/* output/conf 6 | chmod +x output/bootstrap.sh 7 | go build -o output/bin/${RUN_NAME} 8 | -------------------------------------------------------------------------------- /backend/app/product/conf/dev/conf.yaml: -------------------------------------------------------------------------------- 1 | kitex: 2 | service: "product" 3 | address: ":8882" 4 | metrics_port: ":9992" 5 | log_level: info 6 | log_file_name: "log/kitex.log" 7 | log_max_size: 10 8 | log_max_age: 3 9 | log_max_backups: 50 10 | 11 | registry: 12 | registry_address: 13 | - consul:8500 14 | username: "" 15 | password: "" 16 | 17 | mysql: 18 | dsn: "%s:%s@tcp(%s:3306)/product?charset=utf8mb4&parseTime=True&loc=Local" 19 | 20 | redis: 21 | address: "redis:6379" 22 | username: "" 23 | password: "" 24 | db: 0 25 | 26 | nats: 27 | address: "nats://127.0.0.1:4222" -------------------------------------------------------------------------------- /backend/app/product/conf/online/conf.yaml: -------------------------------------------------------------------------------- 1 | kitex: 2 | service: "product" 3 | address: ":8882" 4 | metrics_port: ":9992" 5 | log_level: info 6 | log_file_name: "log/kitex.log" 7 | log_max_size: 10 8 | log_max_age: 3 9 | log_max_backups: 50 10 | 11 | registry: 12 | registry_address: 13 | - consul:8500 14 | username: "" 15 | password: "" 16 | 17 | mysql: 18 | dsn: "%s:%s@tcp(%s:3306)/product?charset=utf8mb4&parseTime=True&loc=Local" 19 | 20 | redis: 21 | address: "redis:6379" 22 | username: "" 23 | password: "" 24 | db: 0 25 | 26 | nats: 27 | address: "nats://127.0.0.1:4222" 28 | -------------------------------------------------------------------------------- /backend/app/product/conf/test/conf.yaml: -------------------------------------------------------------------------------- 1 | kitex: 2 | service: "product" 3 | address: ":8882" 4 | metrics_port: ":9992" 5 | log_level: info 6 | log_file_name: "log/kitex.log" 7 | log_max_size: 10 8 | log_max_age: 3 9 | log_max_backups: 50 10 | 11 | registry: 12 | registry_address: 13 | - 127.0.0.1:8500 14 | username: "" 15 | password: "" 16 | 17 | mysql: 18 | dsn: "%s:%s@tcp(%s:3306)/product?charset=utf8mb4&parseTime=True&loc=Local" 19 | 20 | redis: 21 | address: "127.0.0.1:6379" 22 | username: "" 23 | password: "" 24 | db: 0 25 | 26 | nats: 27 | address: "nats://127.0.0.1:4222" -------------------------------------------------------------------------------- /backend/app/product/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | mysql: 4 | image: 'mysql:latest' 5 | ports: 6 | - 3306:3306 7 | environment: 8 | - MYSQL_DATABASE=gorm 9 | - MYSQL_USER=gorm 10 | - MYSQL_PASSWORD=gorm 11 | - MYSQL_RANDOM_ROOT_PASSWORD="yes" 12 | redis: 13 | image: 'redis:latest' 14 | ports: 15 | - 6379:6379 16 | -------------------------------------------------------------------------------- /backend/app/product/infra/mq/nats.go: -------------------------------------------------------------------------------- 1 | package mq 2 | 3 | import ( 4 | "github.com/nats-io/nats.go" 5 | ) 6 | 7 | var ( 8 | Nc *nats.Conn 9 | err error 10 | Natscp *NatsCacheProcessor 11 | ) 12 | 13 | func Init() { 14 | // 需要提前初始化 redis 15 | // Nc, err = nats.Connect(conf.GetConf().Nats.Address) 16 | // if err != nil { 17 | // panic(err) 18 | // } 19 | // Natscp = InitNatsCacheProcessor(Nc, redis.RedisClient) 20 | // Natscp.StartProcessor() 21 | } 22 | -------------------------------------------------------------------------------- /backend/app/product/infra/mq/nats_test.go: -------------------------------------------------------------------------------- 1 | package mq 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "testing" 7 | "time" 8 | 9 | "github.com/nats-io/nats.go" 10 | ) 11 | 12 | func TestPublishAndScribe(t *testing.T) { 13 | Nc, err = nats.Connect("nats://127.0.0.1:4222") 14 | if err != nil { 15 | log.Fatal(err) 16 | } 17 | go func() { 18 | for i := 0; i < 10; i++ { 19 | Nc.Publish("testCount", []byte(fmt.Sprintf("%v", i))) 20 | time.Sleep(time.Millisecond) 21 | } 22 | }() 23 | 24 | go func() { 25 | 26 | Nc.Subscribe("testCount", func(msg *nats.Msg) { 27 | data := msg.Data 28 | fmt.Printf("%v\n", string(data)) 29 | }) 30 | 31 | }() 32 | time.Sleep(5 * time.Second) 33 | } 34 | -------------------------------------------------------------------------------- /backend/app/product/kitex_info.yaml: -------------------------------------------------------------------------------- 1 | kitexinfo: 2 | ServiceName: 'product' 3 | ToolVersion: 'v0.9.1' 4 | -------------------------------------------------------------------------------- /backend/app/product/readme.md: -------------------------------------------------------------------------------- 1 | # *** Project 2 | 3 | ## introduce 4 | 5 | - Use the [Kitex](https://github.com/cloudwego/kitex/) framework 6 | - Generating the base code for unit tests. 7 | - Provides basic config functions 8 | - Provides the most basic MVC code hierarchy. 9 | 10 | ## Directory structure 11 | 12 | | catalog | introduce | 13 | | ---- | ---- | 14 | | conf | Configuration files | 15 | | main.go | Startup file | 16 | | handler.go | Used for request processing return of response. | 17 | | kitex_gen | kitex generated code | 18 | | biz/service | The actual business logic. | 19 | | biz/dal | Logic for operating the storage layer | 20 | 21 | ## How to run 22 | 23 | ```shell 24 | sh build.sh 25 | sh output/bootstrap.sh 26 | ``` 27 | -------------------------------------------------------------------------------- /backend/app/product/script/bootstrap.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | CURDIR=$(cd $(dirname $0); pwd) 3 | echo "$CURDIR/bin/product" 4 | exec "$CURDIR/bin/product" 5 | -------------------------------------------------------------------------------- /backend/app/user/.env: -------------------------------------------------------------------------------- 1 | MYSQL_USER=root 2 | MYSQL_PASSWORD=K8#tP2@y!mL9 3 | MYSQL_HOST=127.0.0.1 4 | SESSION_SECRET="KJLAJKLJLSF" -------------------------------------------------------------------------------- /backend/app/user/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.a 3 | *.so 4 | _obj 5 | _test 6 | *.[568vq] 7 | [568vq].out 8 | *.cgo1.go 9 | *.cgo2.c 10 | _cgo_defun.c 11 | _cgo_gotypes.go 12 | _cgo_export.* 13 | _testmain.go 14 | *.exe 15 | *.exe~ 16 | *.test 17 | *.prof 18 | *.rar 19 | *.zip 20 | *.gz 21 | *.psd 22 | *.bmd 23 | *.cfg 24 | *.pptx 25 | *.log 26 | *nohup.out 27 | *settings.pyc 28 | *.sublime-project 29 | *.sublime-workspace 30 | !.gitkeep 31 | .DS_Store 32 | /.idea 33 | /.vscode 34 | /output 35 | *.local.yml 36 | -------------------------------------------------------------------------------- /backend/app/user/biz/dal/init.go: -------------------------------------------------------------------------------- 1 | package dal 2 | 3 | import ( 4 | "github.com/tiktokmall/backend/app/user/biz/dal/mysql" 5 | "github.com/tiktokmall/backend/app/user/biz/dal/redis" 6 | ) 7 | 8 | func Init() { 9 | redis.Init() 10 | mysql.Init() 11 | } 12 | -------------------------------------------------------------------------------- /backend/app/user/biz/dal/redis/init.go: -------------------------------------------------------------------------------- 1 | package redis 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/redis/go-redis/v9" 7 | "github.com/tiktokmall/backend/app/user/conf" 8 | ) 9 | 10 | var ( 11 | RedisClient *redis.Client 12 | ) 13 | 14 | func Init() { 15 | RedisClient = redis.NewClient(&redis.Options{ 16 | Addr: conf.GetConf().Redis.Address, 17 | Username: conf.GetConf().Redis.Username, 18 | Password: conf.GetConf().Redis.Password, 19 | DB: conf.GetConf().Redis.DB, 20 | }) 21 | if err := RedisClient.Ping(context.Background()).Err(); err != nil { 22 | panic(err) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /backend/app/user/biz/model/cache_utils.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "sync" 5 | "time" 6 | ) 7 | 8 | const ( 9 | // 互斥锁超时时间 10 | // lockTimeout = 3 * time.Second 11 | cacheDuration = 30 * time.Minute // 正常缓存时间 12 | emptyCacheDuration = 5 * time.Minute // 空值缓存时间(防穿透) 13 | cacheKeyPrefix = "user_email:" // Redis键前缀 14 | ) 15 | 16 | var ( 17 | UserLocks *sync.Map // 全局锁的实例,缓存击穿时,只放行一个进入 MYSQL 18 | onceUserLocks sync.Once 19 | ) 20 | 21 | func GetUserLocks() *sync.Map { 22 | onceUserLocks.Do(func() { 23 | UserLocks = &sync.Map{} 24 | }) 25 | return UserLocks 26 | } 27 | 28 | func getUserEmailKey(email string) string { 29 | return "user_email:" + email 30 | } 31 | 32 | func getCachedExpiration(baseDuration, randomDuration time.Duration) time.Duration { 33 | // 生成一个随机的时间偏移量 34 | offset := time.Duration(randomDuration) * time.Second 35 | // 返回基础时间加上随机偏移量的结果 36 | return baseDuration + offset 37 | } 38 | -------------------------------------------------------------------------------- /backend/app/user/biz/service/delete.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/tiktokmall/backend/app/user/biz/dal/mysql" 7 | "github.com/tiktokmall/backend/app/user/biz/dal/redis" 8 | "github.com/tiktokmall/backend/app/user/biz/model" 9 | 10 | user "github.com/tiktokmall/backend/rpc_gen/kitex_gen/user" 11 | ) 12 | 13 | type DeleteService struct { 14 | ctx context.Context 15 | } // NewDeleteService new DeleteService 16 | func NewDeleteService(ctx context.Context) *DeleteService { 17 | return &DeleteService{ctx: ctx} 18 | } 19 | 20 | // Run create note info 21 | func (s *DeleteService) Run(req *user.DeleteUserReq) (resp *user.DeleteUserResp, err error) { 22 | // Finish your business logic. 23 | if err = model.DeleteUser(mysql.DB, s.ctx, req.UserId); err != nil { 24 | return nil, err 25 | } 26 | err = model.NewUserDAO(s.ctx, mysql.DB, redis.RedisClient).DeleteByID(int(req.UserId)) 27 | 28 | return 29 | } 30 | -------------------------------------------------------------------------------- /backend/app/user/biz/service/delete_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | user "github.com/tiktokmall/backend/rpc_gen/kitex_gen/user" 7 | ) 8 | 9 | func TestDelete_Run(t *testing.T) { 10 | ctx := context.Background() 11 | s := NewDeleteService(ctx) 12 | // init req and assert value 13 | 14 | req := &user.DeleteUserReq{} 15 | resp, err := s.Run(req) 16 | t.Logf("err: %v", err) 17 | t.Logf("resp: %v", resp) 18 | 19 | // todo: edit your unit test 20 | 21 | } 22 | -------------------------------------------------------------------------------- /backend/app/user/biz/service/login_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | user "github.com/tiktokmall/backend/rpc_gen/kitex_gen/user" 8 | ) 9 | 10 | func TestLogin_Run(t *testing.T) { 11 | ctx := context.Background() 12 | s := NewLoginService(ctx) 13 | // init req and assert value 14 | 15 | req := &user.LoginReq{ 16 | Email: "test@test.com", 17 | Password: "123456", 18 | } 19 | resp, err := s.Run(req) 20 | t.Logf("err: %v", err) 21 | t.Logf("resp: %v", resp) 22 | 23 | // todo: edit your unit test 24 | 25 | } 26 | -------------------------------------------------------------------------------- /backend/app/user/biz/service/query.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/tiktokmall/backend/app/user/biz/dal/mysql" 7 | "github.com/tiktokmall/backend/app/user/biz/model" 8 | user "github.com/tiktokmall/backend/rpc_gen/kitex_gen/user" 9 | ) 10 | 11 | type QueryService struct { 12 | ctx context.Context 13 | } // NewQueryService new QueryService 14 | func NewQueryService(ctx context.Context) *QueryService { 15 | return &QueryService{ctx: ctx} 16 | } 17 | 18 | // Run create note info 19 | func (s *QueryService) Run(req *user.QueryUserReq) (resp *user.QueryUserResp, err error) { 20 | // Finish your business logic. 21 | // TODO: 暂无缓存逻辑 22 | u := &model.User{} 23 | if u, err = model.QueryUser(mysql.DB, s.ctx, req.UserId); err != nil { 24 | return nil, err 25 | } 26 | resp = &user.QueryUserResp{ 27 | User: &user.User{ 28 | UserId: int64(u.ID), 29 | Email: u.Email, 30 | Username: u.Username, 31 | Avator: u.Avator, 32 | }, 33 | } 34 | return 35 | } 36 | -------------------------------------------------------------------------------- /backend/app/user/biz/service/query_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | user "github.com/tiktokmall/backend/rpc_gen/kitex_gen/user" 7 | ) 8 | 9 | func TestQuery_Run(t *testing.T) { 10 | ctx := context.Background() 11 | s := NewQueryService(ctx) 12 | // init req and assert value 13 | 14 | req := &user.QueryUserReq{} 15 | resp, err := s.Run(req) 16 | t.Logf("err: %v", err) 17 | t.Logf("resp: %v", resp) 18 | 19 | // todo: edit your unit test 20 | 21 | } 22 | -------------------------------------------------------------------------------- /backend/app/user/biz/service/register_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | user "github.com/tiktokmall/backend/rpc_gen/kitex_gen/user" 8 | ) 9 | 10 | func TestRegister_Run(t *testing.T) { 11 | ctx := context.Background() 12 | s := NewRegisterService(ctx) 13 | // init req and assert value 14 | 15 | req := &user.RegisterReq{ 16 | Email: "test@test.com", 17 | Password: "123456", 18 | ConfirmPassword: "123456", 19 | } 20 | resp, err := s.Run(req) 21 | t.Logf("err: %v", err) 22 | t.Logf("resp: %v", resp) 23 | 24 | // todo: edit your unit test 25 | 26 | } 27 | -------------------------------------------------------------------------------- /backend/app/user/biz/service/update_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "testing" 7 | 8 | user "github.com/tiktokmall/backend/rpc_gen/kitex_gen/user" 9 | ) 10 | 11 | func TestUpdate_Run(t *testing.T) { 12 | ctx := context.Background() 13 | s := NewUpdateService(ctx) 14 | // init req and assert value 15 | 16 | req := &user.UpdateUserReq{} 17 | resp, err := s.Run(req) 18 | t.Logf("err: %v", err) 19 | t.Logf("resp: %v", resp) 20 | 21 | // todo: edit your unit test 22 | 23 | } 24 | 25 | func TestCrypt(t *testing.T) { 26 | // Test case 1: Normal password 27 | password1 := "123456" 28 | hashedPassword1, _ := crypt(password1) 29 | // assert.NoError(t, err1) 30 | // assert.NotEmpty(t, hashedPassword1) 31 | fmt.Println(hashedPassword1) 32 | } 33 | -------------------------------------------------------------------------------- /backend/app/user/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | RUN_NAME="user" 3 | mkdir -p output/bin output/conf 4 | cp script/* output/ 5 | cp -r conf/* output/conf 6 | chmod +x output/bootstrap.sh 7 | go build -o output/bin/${RUN_NAME} 8 | -------------------------------------------------------------------------------- /backend/app/user/conf/dev/conf.yaml: -------------------------------------------------------------------------------- 1 | kitex: 2 | service: "user" 3 | address: ":8888" 4 | metrics_port: ":9998" 5 | log_level: info 6 | log_file_name: "log/kitex.log" 7 | log_max_size: 10 8 | log_max_age: 3 9 | log_max_backups: 50 10 | 11 | registry: 12 | registry_address: 13 | - consul:8500 14 | username: "" 15 | password: "" 16 | 17 | mysql: 18 | # dsn: "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8mb4&parseTime=True&loc=Local" 19 | dsn: "%s:%s@tcp(%s:3306)/user?charset=utf8mb4&parseTime=True&loc=Local" 20 | 21 | redis: 22 | address: "redis:6379" 23 | username: "" 24 | password: "" 25 | db: 0 26 | 27 | nats: 28 | address: "nats://127.0.0.1:4222" -------------------------------------------------------------------------------- /backend/app/user/conf/online/conf.yaml: -------------------------------------------------------------------------------- 1 | kitex: 2 | service: "user" 3 | address: ":8888" 4 | metrics_port: ":9998" 5 | log_level: info 6 | log_file_name: "log/kitex.log" 7 | log_max_size: 10 8 | log_max_age: 3 9 | log_max_backups: 50 10 | 11 | registry: 12 | registry_address: 13 | - consul:8500 14 | username: "" 15 | password: "" 16 | 17 | mysql: 18 | # dsn: "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8mb4&parseTime=True&loc=Local" 19 | dsn: "%s:%s@tcp(%s:3306)/user?charset=utf8mb4&parseTime=True&loc=Local" 20 | 21 | redis: 22 | address: "redis:6379" 23 | username: "" 24 | password: "" 25 | db: 0 26 | 27 | nats: 28 | address: "nats://127.0.0.1:4222" -------------------------------------------------------------------------------- /backend/app/user/conf/test/conf.yaml: -------------------------------------------------------------------------------- 1 | kitex: 2 | service: "user" 3 | address: ":8888" 4 | metrics_port: ":9998" 5 | log_level: info 6 | log_file_name: "log/kitex.log" 7 | log_max_size: 10 8 | log_max_age: 3 9 | log_max_backups: 50 10 | 11 | registry: 12 | registry_address: 13 | - 127.0.0.1:8500 14 | username: "" 15 | password: "" 16 | 17 | mysql: 18 | # dsn: "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8mb4&parseTime=True&loc=Local" 19 | dsn: "%s:%s@tcp(%s:3306)/user?charset=utf8mb4&parseTime=True&loc=Local" 20 | 21 | redis: 22 | address: "127.0.0.1:6379" 23 | username: "" 24 | password: "" 25 | db: 0 26 | 27 | nats: 28 | address: "nats://127.0.0.1:4222" 29 | -------------------------------------------------------------------------------- /backend/app/user/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | mysql: 4 | image: 'mysql:latest' 5 | ports: 6 | - 3306:3306 7 | environment: 8 | - MYSQL_DATABASE=gorm 9 | - MYSQL_USER=gorm 10 | - MYSQL_PASSWORD=gorm 11 | - MYSQL_RANDOM_ROOT_PASSWORD="yes" 12 | redis: 13 | image: 'redis:latest' 14 | ports: 15 | - 6379:6379 16 | -------------------------------------------------------------------------------- /backend/app/user/infra/mq/nats.go: -------------------------------------------------------------------------------- 1 | package mq 2 | 3 | import ( 4 | "github.com/tiktokmall/backend/app/user/biz/dal/redis" 5 | "github.com/tiktokmall/backend/app/user/conf" 6 | 7 | "github.com/nats-io/nats.go" 8 | ) 9 | 10 | var ( 11 | Nc *nats.Conn 12 | err error 13 | Natscp *NatsCacheProcessor 14 | ) 15 | 16 | func Init() { 17 | // 需要提前初始化 redis 18 | Nc, err = nats.Connect(conf.GetConf().Nats.Address) 19 | if err != nil { 20 | panic(err) 21 | } 22 | Natscp = InitNatsCacheProcessor(Nc, redis.RedisClient) 23 | Natscp.StartProcessor() 24 | } 25 | -------------------------------------------------------------------------------- /backend/app/user/infra/mq/nats_test.go: -------------------------------------------------------------------------------- 1 | package mq 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "testing" 7 | "time" 8 | 9 | "github.com/nats-io/nats.go" 10 | ) 11 | 12 | func TestPublishAndScribe(t *testing.T) { 13 | Nc, err = nats.Connect("nats://127.0.0.1:4222") 14 | if err != nil { 15 | log.Fatal(err) 16 | } 17 | go func() { 18 | for i := 0; i < 10; i++ { 19 | Nc.Publish("testCount", []byte(fmt.Sprintf("%v", i))) 20 | time.Sleep(time.Millisecond) 21 | } 22 | }() 23 | 24 | Nc.Subscribe("testCount", func(msg *nats.Msg) { 25 | data := msg.Data 26 | fmt.Printf("%v\n", string(data)) 27 | }) 28 | time.Sleep(5 * time.Second) 29 | } 30 | -------------------------------------------------------------------------------- /backend/app/user/kitex_info.yaml: -------------------------------------------------------------------------------- 1 | kitexinfo: 2 | ServiceName: 'user' 3 | ToolVersion: 'v0.9.1' 4 | -------------------------------------------------------------------------------- /backend/app/user/readme.md: -------------------------------------------------------------------------------- 1 | # *** Project 2 | 3 | ## introduce 4 | 5 | - Use the [Kitex](https://github.com/cloudwego/kitex/) framework 6 | - Generating the base code for unit tests. 7 | - Provides basic config functions 8 | - Provides the most basic MVC code hierarchy. 9 | 10 | ## Directory structure 11 | 12 | | catalog | introduce | 13 | | ---- | ---- | 14 | | conf | Configuration files | 15 | | main.go | Startup file | 16 | | handler.go | Used for request processing return of response. | 17 | | kitex_gen | kitex generated code | 18 | | biz/service | The actual business logic. | 19 | | biz/dal | Logic for operating the storage layer | 20 | 21 | ## How to run 22 | 23 | ```shell 24 | sh build.sh 25 | sh output/bootstrap.sh 26 | ``` 27 | -------------------------------------------------------------------------------- /backend/app/user/script/bootstrap.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | CURDIR=$(cd $(dirname $0); pwd) 3 | echo "$CURDIR/bin/user" 4 | exec "$CURDIR/bin/user" 5 | -------------------------------------------------------------------------------- /backend/common/clientsuite/clientsuite.go: -------------------------------------------------------------------------------- 1 | package clientsuite 2 | 3 | import ( 4 | "github.com/cloudwego/kitex/client" 5 | "github.com/cloudwego/kitex/pkg/rpcinfo" 6 | "github.com/cloudwego/kitex/pkg/transmeta" 7 | "github.com/cloudwego/kitex/transport" 8 | "github.com/kitex-contrib/obs-opentelemetry/tracing" 9 | consul "github.com/kitex-contrib/registry-consul" 10 | ) 11 | 12 | type CommonServerSuite struct { 13 | CurrentServiceName string 14 | RegistryAddr string 15 | } 16 | 17 | func (s CommonServerSuite) Options() []client.Option { 18 | r, err := consul.NewConsulResolver(s.RegistryAddr) 19 | if err != nil { 20 | panic(err) 21 | } 22 | opts := []client.Option{ 23 | client.WithSuite(tracing.NewClientSuite()), 24 | client.WithResolver(r), 25 | client.WithClientBasicInfo(&rpcinfo.EndpointBasicInfo{ 26 | ServiceName: s.CurrentServiceName, 27 | }), 28 | client.WithMetaHandler(transmeta.ClientHTTP2Handler), 29 | client.WithTransportProtocol(transport.GRPC), 30 | } 31 | return opts 32 | } 33 | -------------------------------------------------------------------------------- /backend/common/mtl/tracing.go: -------------------------------------------------------------------------------- 1 | package mtl 2 | 3 | import ( 4 | "github.com/kitex-contrib/obs-opentelemetry/provider" 5 | ) 6 | 7 | func InitTracing(serviceName string) provider.OtelProvider { 8 | p := provider.NewOpenTelemetryProvider( 9 | provider.WithServiceName(serviceName), 10 | // 默认值 11 | // provider.WithExportEndpoint("localhost:4317"), 12 | provider.WithInsecure(), 13 | provider.WithEnableMetrics(false), 14 | ) 15 | return p 16 | 17 | } 18 | -------------------------------------------------------------------------------- /backend/cwgo.help: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzulihrs/TikTokMall/22bdae6c52c13b4818af407f3cb59f5b8fca506b/backend/cwgo.help -------------------------------------------------------------------------------- /backend/db/sql/ini/README.md: -------------------------------------------------------------------------------- 1 | ## INI SQL 2 | Execute before preparing the development environment -------------------------------------------------------------------------------- /backend/db/sql/ini/databases.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE IF NOT EXISTS `cart` 2 | DEFAULT CHARACTER SET = 'utf8mb4';; 3 | 4 | CREATE DATABASE IF NOT EXISTS `checkout` 5 | DEFAULT CHARACTER SET = 'utf8mb4'; 6 | 7 | CREATE DATABASE IF NOT EXISTS `order` 8 | DEFAULT CHARACTER SET = 'utf8mb4'; 9 | 10 | CREATE DATABASE IF NOT EXISTS `payment` 11 | DEFAULT CHARACTER SET = 'utf8mb4'; 12 | 13 | CREATE DATABASE IF NOT EXISTS `product` 14 | DEFAULT CHARACTER SET = 'utf8mb4'; 15 | 16 | CREATE DATABASE IF NOT EXISTS `user` 17 | DEFAULT CHARACTER SET = 'utf8mb4'; -------------------------------------------------------------------------------- /backend/deploy/.env.example: -------------------------------------------------------------------------------- 1 | MYSQL_USER=root 2 | MYSQL_PASSWORD=K8#tP2@y!mL9 3 | MYSQL_HOST=mysql 4 | SESSION_SECRET="KJLAJKLJLSF" 5 | OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://jaeger-all-in-one:4317 6 | OTEL_EXPORTER_OTLP_INSECURE=true 7 | GO_ENV=dev -------------------------------------------------------------------------------- /backend/deploy/Dockerfile.svc: -------------------------------------------------------------------------------- 1 | FROM golang:1.23.1 AS builder 2 | 3 | ARG SVC 4 | 5 | WORKDIR /usr/src/gomall 6 | 7 | # Set the GOPROXY environment variable to use the goproxy.io proxy (for China) 8 | ENV GOPROXY=https://goproxy.io,direct 9 | 10 | # pre-copy/cache go.mod for pre-downloading dependencies and only redownloading them in subsequent builds if they change 11 | COPY app/${SVC}/go.mod app/${SVC}/go.sum ./app/${SVC}/ 12 | COPY rpc_gen rpc_gen 13 | COPY common common 14 | 15 | RUN cd rpc_gen/ && go mod download && go mod verify 16 | RUN cd common/ && go mod download && go mod verify 17 | 18 | COPY app/${SVC} app/${SVC} 19 | RUN cd app/${SVC}/ && go mod tidy 20 | 21 | RUN cd app/${SVC}/ && CGO_ENABLED=0 go build -v -o /opt/gomall/${SVC}/server 22 | 23 | FROM busybox 24 | 25 | ARG SVC 26 | 27 | COPY --from=builder /opt/gomall/${SVC}/server /opt/gomall/${SVC}/server 28 | 29 | COPY app/${SVC}/conf /opt/gomall/${SVC}/conf 30 | 31 | WORKDIR /opt/gomall/${SVC} 32 | 33 | CMD ["./server"] -------------------------------------------------------------------------------- /backend/deploy/config/loki.yml: -------------------------------------------------------------------------------- 1 | # config.yml 2 | auth_enabled: false 3 | 4 | server: 5 | http_listen_port: 3100 6 | grpc_listen_port: 9096 7 | 8 | common: 9 | instance_addr: 127.0.0.1 10 | path_prefix: /tmp/loki 11 | storage: 12 | filesystem: 13 | chunks_directory: /tmp/loki/chunks 14 | rules_directory: /tmp/loki/rules 15 | replication_factor: 1 16 | ring: 17 | kvstore: 18 | store: inmemory 19 | 20 | query_range: 21 | results_cache: 22 | cache: 23 | embedded_cache: 24 | enabled: true 25 | max_size_mb: 100 26 | 27 | schema_config: 28 | configs: 29 | - from: 2020-10-24 30 | store: tsdb 31 | object_store: filesystem 32 | schema: v11 33 | index: 34 | prefix: index_ 35 | period: 24h -------------------------------------------------------------------------------- /backend/deploy/config/prometheus.yml: -------------------------------------------------------------------------------- 1 | global: 2 | scrape_interval: 15s 3 | # 从 consul 配置中心获取 prometheus 监控目标 4 | scrape_configs: 5 | - job_name: "consul" 6 | consul_sd_configs: 7 | - server: consul:8500 8 | services: 9 | - prometheus 10 | relabel_configs: 11 | - source_labels: [ __meta_consul_tags ] 12 | action: replace 13 | target_label: service 14 | regex: ".*service:(.*?),.*" 15 | replacement: "$1" 16 | 17 | - source_labels: [ __meta_consul_service_id ] 18 | target_label: __metrics_path__ 19 | replacement: /metrics 20 | -------------------------------------------------------------------------------- /backend/deploy/config/promtail.yml: -------------------------------------------------------------------------------- 1 | # config.yml 2 | server: 3 | http_listen_port: 9080 4 | grpc_listen_port: 0 5 | 6 | positions: 7 | filename: /tmp/positions.yaml 8 | 9 | clients: 10 | - url: http://loki:3100/loki/api/v1/push 11 | 12 | scrape_configs: 13 | - job_name: hertz 14 | pipeline_stages: 15 | - json: 16 | expressions: 17 | level: level 18 | - labels: 19 | level: 20 | static_configs: 21 | - targets: 22 | - localhost 23 | labels: 24 | app: frontend 25 | __path__: /logs/frontend/hertz.log -------------------------------------------------------------------------------- /backend/deploy/gomall-dev-cluster.yaml: -------------------------------------------------------------------------------- 1 | kind: Cluster 2 | apiVersion: kind.x-k8s.io/v1alpha4 3 | name: gomall-dev 4 | nodes: 5 | - role: control-plane 6 | image: kindest/node:v1.30.0 7 | extraMounts: 8 | - hostPath: ./db/sql/ini 9 | containerPath: /opt/gomall/db/sql/ini 10 | - hostPath: ./deploy/config 11 | containerPath: /opt/gomall/deploy/config 12 | 13 | - role: worker 14 | image: kindest/node:v1.30.0 15 | extraMounts: 16 | - hostPath: ./db/sql/ini 17 | containerPath: /opt/gomall/db/sql/ini 18 | - hostPath: ./deploy/config 19 | containerPath: /opt/gomall/deploy/config 20 | 21 | # image for China: registry.cn-hangzhou.aliyuncs.com/kindest/node:v1.30.0 22 | - role: worker 23 | image: kindest/node:v1.30.0 24 | extraMounts: 25 | - hostPath: ./db/sql/ini 26 | containerPath: /opt/gomall/db/sql/ini 27 | - hostPath: ./deploy/config 28 | containerPath: /opt/gomall/deploy/config 29 | -------------------------------------------------------------------------------- /backend/go.work: -------------------------------------------------------------------------------- 1 | go 1.23.1 2 | 3 | use ( 4 | ./app/agent 5 | ./app/cart 6 | ./app/checkout 7 | ./app/email 8 | ./app/frontend 9 | ./app/merchant 10 | ./app/order 11 | ./app/payment 12 | ./app/product 13 | ./app/user 14 | ./common 15 | ./rpc_gen 16 | ) 17 | -------------------------------------------------------------------------------- /backend/idl/cart.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package cart; 4 | 5 | option go_package = '/cart'; 6 | 7 | service CartService { 8 | rpc AddItem(AddItemReq) returns (AddItemResp) {} 9 | rpc GetCart(GetCartReq) returns (GetCartResp) {} 10 | rpc EmptyCart(EmptyCartReq) returns (EmptyCartResp) {} 11 | rpc ChangeQty(ChangeQtyReq) returns (ChangeQtyResp){} 12 | } 13 | 14 | message CartItem { 15 | uint32 product_id = 1; 16 | uint32 quantity = 2; 17 | } 18 | 19 | message AddItemReq { 20 | uint32 user_id = 1; 21 | CartItem item = 2; 22 | } 23 | 24 | message AddItemResp {} 25 | 26 | message GetCartReq { 27 | uint32 user_id = 1; 28 | } 29 | 30 | message Cart { 31 | uint32 user_id = 1; 32 | repeated CartItem items = 2; 33 | } 34 | 35 | message GetCartResp { 36 | Cart cart = 1; 37 | } 38 | 39 | // 新增 40 | message EmptyCartReq { 41 | uint32 user_id = 1; 42 | } 43 | 44 | // 新增 45 | message EmptyCartResp {} 46 | 47 | // 新增 48 | message ChangeQtyReq{ 49 | uint32 user_id = 1; 50 | CartItem item = 2; 51 | } 52 | 53 | // 新增 54 | message ChangeQtyResp{} 55 | -------------------------------------------------------------------------------- /backend/idl/checkout.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package checkout; 4 | 5 | import "payment.proto"; 6 | 7 | option go_package = "/checkout"; 8 | 9 | service CheckoutService { 10 | rpc Checkout(CheckoutReq) returns (CheckoutResp) {} 11 | } 12 | 13 | message Address { 14 | string street_address = 1; 15 | string city = 2; 16 | string state = 3; 17 | string country = 4; 18 | string zip_code = 5; 19 | } 20 | 21 | message CheckoutReq { 22 | uint32 user_id = 1; 23 | string firstname = 2; 24 | string lastname = 3; 25 | string email = 4; 26 | string payment_method = 5; // 支付方式 card-银行卡 alipay-支付宝 27 | Address address = 6; 28 | payment.CreditCardInfo credit_card = 7; 29 | } 30 | 31 | message CheckoutResp { 32 | string order_id = 1; 33 | string transaction_id = 2; 34 | } -------------------------------------------------------------------------------- /backend/idl/echo.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package pbapi; 4 | 5 | option go_package = "/pbapi"; 6 | 7 | message EchoRequest { 8 | string message = 1; 9 | } 10 | 11 | message EchoResponse { 12 | string message = 1; 13 | } 14 | 15 | service EchoService { 16 | rpc EchoMethod (EchoRequest) returns (EchoResponse) {} 17 | } -------------------------------------------------------------------------------- /backend/idl/echo.thrift: -------------------------------------------------------------------------------- 1 | namespace go api 2 | 3 | struct EchoReq { 4 | 1: string Message (api.query="message"); // 添加 api 注解为方便进行参数绑定 5 | } 6 | 7 | struct EchoResp { 8 | 1: string Message; 9 | } 10 | 11 | service Echo { 12 | EchoResp EchoMethod(1: EchoReq req) (api.get="/echo") 13 | } -------------------------------------------------------------------------------- /backend/idl/email.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package email; 4 | 5 | option go_package = "/email"; 6 | 7 | message EmailReq { 8 | string from = 1; 9 | string to = 2; 10 | string context_type = 3; 11 | string subject = 4; 12 | string content = 5; 13 | } 14 | 15 | message EmailResp {} 16 | 17 | service EmailService { 18 | rpc Send(EmailReq) returns (EmailResp) {}; 19 | } -------------------------------------------------------------------------------- /backend/idl/frontend/about.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package frontend.about; 4 | 5 | import "api.proto"; 6 | import "frontend/common.proto"; 7 | 8 | option go_package = "/frontend/about"; 9 | 10 | service AboutService { 11 | rpc About(common.Empty) returns (common.Empty) { 12 | option (api.get) = "/about"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /backend/idl/frontend/agent.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package frontend.agent; 4 | 5 | import "api.proto"; 6 | import "frontend/common.proto"; 7 | 8 | option go_package = "frontend/agent"; 9 | 10 | // 聊天服务定义 11 | service AgentService { 12 | // 发送聊天消息 13 | rpc HandleChat(common.Empty) returns (common.Empty) { 14 | option (api.post) = "agent/api/chat"; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /backend/idl/frontend/auth_page.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package frontend.auth; 4 | 5 | import "frontend/common.proto"; 6 | import "api.proto"; 7 | 8 | option go_package = "frontend/auth"; 9 | 10 | message LoginReq { 11 | string email = 1 [(api.form)="email"]; 12 | string password = 2 [(api.form)="password"]; 13 | string next = 3 [(api.query)="next"]; 14 | } 15 | 16 | 17 | message RegisterReq { 18 | string email = 1 [(api.form)="email"]; 19 | string password = 2 [(api.form)="password"]; 20 | string confirmPassword = 3 [(api.form)="confirm_password"]; 21 | } 22 | 23 | service AuthService { 24 | rpc login(LoginReq) returns (common.Empty) { 25 | option (api.post) = "/auth/login"; 26 | }; 27 | rpc register(RegisterReq) returns (common.Empty) { 28 | option (api.post) = "/auth/register"; 29 | } 30 | rpc logout(common.Empty) returns (common.Empty) { 31 | option (api.post) = "/auth/logout"; 32 | } 33 | } -------------------------------------------------------------------------------- /backend/idl/frontend/cart_page.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package frontend.cart; 4 | 5 | import "api.proto"; 6 | import "frontend/common.proto"; 7 | 8 | option go_package = "frontend/cart"; 9 | 10 | 11 | service CartService { 12 | rpc AddCartItem(AddCartItemReq) returns (common.Empty) { 13 | option (api.post) = "/cart"; 14 | } 15 | 16 | rpc GetCart(common.Empty) returns (common.Empty) { 17 | option (api.get) = "/cart"; 18 | } 19 | 20 | rpc EmptyCart(common.Empty) returns (common.Empty) { 21 | option (api.get) = "/emptycart"; // 新增 22 | } 23 | 24 | rpc ChangeQty(ChangeQtyReq) returns (common.Empty) { 25 | option (api.post) = "/changeqty"; // 新增 26 | } 27 | 28 | } 29 | 30 | // AddCartReq变成AddCartItemReq 31 | message AddCartItemReq { 32 | uint32 product_id = 1 [(api.form) = "product_id"]; 33 | int32 product_num = 2 [(api.form) = "product_num"]; 34 | } 35 | 36 | // 新增 37 | message ChangeQtyReq{ 38 | uint32 product_id = 1 [(api.form) = "product_id"]; 39 | int32 product_num = 2 [(api.form) = "product_num"]; 40 | 41 | } -------------------------------------------------------------------------------- /backend/idl/frontend/category_page.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package frontend.category; 4 | 5 | import "api.proto"; 6 | import "frontend/common.proto"; 7 | 8 | option go_package = "frontend/category"; 9 | 10 | service CategoryService { 11 | rpc Category(CategoryReq) returns (common.Empty) { 12 | option (api.get) = "/category/:category"; 13 | } 14 | } 15 | 16 | message CategoryReq { 17 | string category = 1 [(api.path) = "category"]; 18 | } -------------------------------------------------------------------------------- /backend/idl/frontend/common.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package frontend.common; 4 | 5 | option go_package = "frontend/common"; 6 | 7 | message Empty {} -------------------------------------------------------------------------------- /backend/idl/frontend/home.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package frontend.home; 4 | 5 | option go_package = "frontend/home"; 6 | 7 | import "api.proto"; 8 | import "frontend/common.proto"; 9 | 10 | service HelloService { 11 | rpc Home(common.Empty) returns(common.Empty) { 12 | option (api.get) = "/"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /backend/idl/frontend/order_page.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package frontend.order; 4 | 5 | import "api.proto"; 6 | import "frontend/common.proto"; 7 | 8 | option go_package = "/frontend/order"; 9 | 10 | service OrderService { 11 | rpc OrderList(common.Empty) returns (common.Empty) { 12 | option (api.get) = "/order"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /backend/idl/frontend/oss.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package frontend.oss; 4 | 5 | import "api.proto"; 6 | option go_package = "/frontend/oss"; 7 | 8 | // 定义Oss服务 9 | service OssService { 10 | // 上传图片 11 | rpc UploadImage (UploadFileRequest) returns (UploadResponse) { 12 | option (api.post) = "/uploadImage"; 13 | } 14 | 15 | // 上传视频 16 | rpc UploadVideo (UploadFileRequest) returns (UploadResponse) { 17 | option (api.post) = "/uploadVideo"; 18 | } 19 | } 20 | 21 | // 请求上传文件的结构(通过form-data传递文件,参数file) 22 | message UploadFileRequest { 23 | } 24 | 25 | // 响应上传结果的结构 26 | message UploadResponse { 27 | string hashed_name = 1; // 哈希文件名,防止重复 28 | string url = 2; // 完整访问URL 29 | } 30 | 31 | -------------------------------------------------------------------------------- /backend/idl/frontend/payment_page.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package frontend.payment; 4 | 5 | import "api.proto"; 6 | import "frontend/common.proto"; 7 | 8 | option go_package = "frontend/payment"; 9 | 10 | 11 | service PaymentService { 12 | 13 | rpc Alipay(AlipayReq) returns (common.Empty) { 14 | option (api.post) = "/alipay"; 15 | } 16 | 17 | // 给支付宝调用的,收到/payresult,去修改订单状态 18 | rpc Payresult(PayresultReq) returns (common.Empty) { 19 | option (api.post) = "/payresult"; 20 | } 21 | 22 | // 给支付宝调用的,收到/paysuccess,直接跳转到支付成功页面 23 | rpc Paysuccess(common.Empty) returns (common.Empty) { 24 | option (api.get) = "/paysuccess"; 25 | } 26 | 27 | } 28 | 29 | message AlipayReq{ 30 | string transaction_id = 1 [(api.form) = "transaction_id"]; 31 | string total_amount = 2 [(api.form) = "total_amount"]; 32 | } 33 | 34 | // 异步通知,根据结果修改订单状态 35 | message PayresultReq{ 36 | 37 | } 38 | -------------------------------------------------------------------------------- /backend/idl/frontend/product_page.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package frontend.product; 4 | 5 | import "api.proto"; 6 | import "frontend/common.proto"; 7 | 8 | option go_package = "/frontend/product"; 9 | 10 | service ProductService { 11 | rpc GetProduct(ProductReq) returns (common.Empty) { 12 | option (api.get) = "/product"; 13 | } 14 | 15 | rpc SearchProducts(SearchProductsReq) returns (common.Empty) { 16 | option (api.get) = "/search"; 17 | } 18 | } 19 | 20 | message ProductReq { 21 | uint32 id = 1 [(api.query) = "id"]; 22 | } 23 | 24 | message SearchProductsReq { 25 | string q = 1 [(api.query) = "q"]; 26 | } 27 | -------------------------------------------------------------------------------- /backend/idl/payment.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package payment; 4 | 5 | option go_package = "payment"; 6 | 7 | service PaymentService { 8 | rpc Charge(ChargeReq) returns (ChargeResp) {} 9 | rpc Alipay(AlipayReq) returns (AlipayResp) {} 10 | } 11 | 12 | message CreditCardInfo { 13 | string credit_cart_number = 1; 14 | int32 credit_card_cvv = 2; 15 | int32 credit_card_expiration_year = 3; 16 | int32 credit_card_expiration_month = 4; 17 | } 18 | 19 | message ChargeReq { 20 | float amount = 1; 21 | CreditCardInfo credit_card = 2; 22 | string order_id = 3; 23 | uint32 user_id = 4; 24 | } 25 | 26 | message ChargeResp { 27 | string transaction_id = 1; 28 | } 29 | 30 | message AlipayReq{ 31 | string transaction_id = 1; 32 | string total_amount = 2; 33 | } 34 | 35 | message AlipayResp{ 36 | string payUrl = 1; 37 | } -------------------------------------------------------------------------------- /backend/kill_service.sh: -------------------------------------------------------------------------------- 1 | killall -9 air -------------------------------------------------------------------------------- /backend/load_lib.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # backend目录执行 4 | 5 | ROOT_PATH=$PWD 6 | declare -a MODULES=("common" "rpc_gen") 7 | # 启动所有微服务 8 | for module in "${MODULES[@]}"; do 9 | echo "Tidying $module" 10 | # 进入微服务目录 11 | pushd "$ROOT_PATH/$module" > /dev/null 12 | # 检查是否成功进入目录 13 | if [ $? -ne 0 ]; then 14 | echo "Failed to enter directory for $module. Skipping..." 15 | continue 16 | fi 17 | go mod tidy 18 | echo "$module tidied." 19 | echo "===================" 20 | done 21 | 22 | APP_PATH=$ROOT_PATH/app 23 | # 声明一个数组,存储所有微服务的目录名称 24 | declare -a SERVICES=("cart" "checkout" "email" "frontend" "order" "payment" "product" "user") 25 | for service in "${SERVICES[@]}"; do 26 | echo "Tidying $service" 27 | # 进入微服务目录 28 | pushd "$APP_PATH/$service" > /dev/null 29 | # 检查是否成功进入目录 30 | if [ $? -ne 0 ]; then 31 | echo "Failed to enter directory for $service. Skipping..." 32 | continue 33 | fi 34 | go mod tidy 35 | echo "$service tidied." 36 | echo "===================" 37 | done -------------------------------------------------------------------------------- /backend/rpc_gen/kitex_gen/api/api.pb.fast.go: -------------------------------------------------------------------------------- 1 | // Code generated by Fastpb v0.0.2. DO NOT EDIT. 2 | 3 | package api 4 | 5 | import ( 6 | fmt "fmt" 7 | fastpb "github.com/cloudwego/fastpb" 8 | descriptorpb "google.golang.org/protobuf/types/descriptorpb" 9 | ) 10 | 11 | var ( 12 | _ = fmt.Errorf 13 | _ = fastpb.Skip 14 | ) 15 | var _ = descriptorpb.File_google_protobuf_descriptor_proto 16 | -------------------------------------------------------------------------------- /backend/rpc_gen/kitex_gen/cart/cartservice/invoker.go: -------------------------------------------------------------------------------- 1 | // Code generated by Kitex v0.9.1. DO NOT EDIT. 2 | 3 | package cartservice 4 | 5 | import ( 6 | server "github.com/cloudwego/kitex/server" 7 | cart "github.com/tiktokmall/backend/rpc_gen/kitex_gen/cart" 8 | ) 9 | 10 | // NewInvoker creates a server.Invoker with the given handler and options. 11 | func NewInvoker(handler cart.CartService, opts ...server.Option) server.Invoker { 12 | var options []server.Option 13 | 14 | options = append(options, opts...) 15 | 16 | s := server.NewInvoker(options...) 17 | if err := s.RegisterService(serviceInfo(), handler); err != nil { 18 | panic(err) 19 | } 20 | if err := s.Init(); err != nil { 21 | panic(err) 22 | } 23 | return s 24 | } 25 | -------------------------------------------------------------------------------- /backend/rpc_gen/kitex_gen/cart/cartservice/server.go: -------------------------------------------------------------------------------- 1 | // Code generated by Kitex v0.9.1. DO NOT EDIT. 2 | package cartservice 3 | 4 | import ( 5 | server "github.com/cloudwego/kitex/server" 6 | cart "github.com/tiktokmall/backend/rpc_gen/kitex_gen/cart" 7 | ) 8 | 9 | // NewServer creates a server.Server with the given handler and options. 10 | func NewServer(handler cart.CartService, opts ...server.Option) server.Server { 11 | var options []server.Option 12 | 13 | options = append(options, opts...) 14 | 15 | svr := server.NewServer(options...) 16 | if err := svr.RegisterService(serviceInfo(), handler); err != nil { 17 | panic(err) 18 | } 19 | return svr 20 | } 21 | 22 | func RegisterService(svr server.Server, handler cart.CartService, opts ...server.RegisterOption) error { 23 | return svr.RegisterService(serviceInfo(), handler, opts...) 24 | } 25 | -------------------------------------------------------------------------------- /backend/rpc_gen/kitex_gen/checkout/checkoutservice/invoker.go: -------------------------------------------------------------------------------- 1 | // Code generated by Kitex v0.9.1. DO NOT EDIT. 2 | 3 | package checkoutservice 4 | 5 | import ( 6 | server "github.com/cloudwego/kitex/server" 7 | checkout "github.com/tiktokmall/backend/rpc_gen/kitex_gen/checkout" 8 | ) 9 | 10 | // NewInvoker creates a server.Invoker with the given handler and options. 11 | func NewInvoker(handler checkout.CheckoutService, opts ...server.Option) server.Invoker { 12 | var options []server.Option 13 | 14 | options = append(options, opts...) 15 | 16 | s := server.NewInvoker(options...) 17 | if err := s.RegisterService(serviceInfo(), handler); err != nil { 18 | panic(err) 19 | } 20 | if err := s.Init(); err != nil { 21 | panic(err) 22 | } 23 | return s 24 | } 25 | -------------------------------------------------------------------------------- /backend/rpc_gen/kitex_gen/checkout/checkoutservice/server.go: -------------------------------------------------------------------------------- 1 | // Code generated by Kitex v0.9.1. DO NOT EDIT. 2 | package checkoutservice 3 | 4 | import ( 5 | server "github.com/cloudwego/kitex/server" 6 | checkout "github.com/tiktokmall/backend/rpc_gen/kitex_gen/checkout" 7 | ) 8 | 9 | // NewServer creates a server.Server with the given handler and options. 10 | func NewServer(handler checkout.CheckoutService, opts ...server.Option) server.Server { 11 | var options []server.Option 12 | 13 | options = append(options, opts...) 14 | 15 | svr := server.NewServer(options...) 16 | if err := svr.RegisterService(serviceInfo(), handler); err != nil { 17 | panic(err) 18 | } 19 | return svr 20 | } 21 | 22 | func RegisterService(svr server.Server, handler checkout.CheckoutService, opts ...server.RegisterOption) error { 23 | return svr.RegisterService(serviceInfo(), handler, opts...) 24 | } 25 | -------------------------------------------------------------------------------- /backend/rpc_gen/kitex_gen/email/emailservice/invoker.go: -------------------------------------------------------------------------------- 1 | // Code generated by Kitex v0.9.1. DO NOT EDIT. 2 | 3 | package emailservice 4 | 5 | import ( 6 | server "github.com/cloudwego/kitex/server" 7 | email "github.com/tiktokmall/backend/rpc_gen/kitex_gen/email" 8 | ) 9 | 10 | // NewInvoker creates a server.Invoker with the given handler and options. 11 | func NewInvoker(handler email.EmailService, opts ...server.Option) server.Invoker { 12 | var options []server.Option 13 | 14 | options = append(options, opts...) 15 | 16 | s := server.NewInvoker(options...) 17 | if err := s.RegisterService(serviceInfo(), handler); err != nil { 18 | panic(err) 19 | } 20 | if err := s.Init(); err != nil { 21 | panic(err) 22 | } 23 | return s 24 | } 25 | -------------------------------------------------------------------------------- /backend/rpc_gen/kitex_gen/email/emailservice/server.go: -------------------------------------------------------------------------------- 1 | // Code generated by Kitex v0.9.1. DO NOT EDIT. 2 | package emailservice 3 | 4 | import ( 5 | server "github.com/cloudwego/kitex/server" 6 | email "github.com/tiktokmall/backend/rpc_gen/kitex_gen/email" 7 | ) 8 | 9 | // NewServer creates a server.Server with the given handler and options. 10 | func NewServer(handler email.EmailService, opts ...server.Option) server.Server { 11 | var options []server.Option 12 | 13 | options = append(options, opts...) 14 | 15 | svr := server.NewServer(options...) 16 | if err := svr.RegisterService(serviceInfo(), handler); err != nil { 17 | panic(err) 18 | } 19 | return svr 20 | } 21 | 22 | func RegisterService(svr server.Server, handler email.EmailService, opts ...server.RegisterOption) error { 23 | return svr.RegisterService(serviceInfo(), handler, opts...) 24 | } 25 | -------------------------------------------------------------------------------- /backend/rpc_gen/kitex_gen/merchant/merchantservice/invoker.go: -------------------------------------------------------------------------------- 1 | // Code generated by Kitex v0.9.1. DO NOT EDIT. 2 | 3 | package merchantservice 4 | 5 | import ( 6 | server "github.com/cloudwego/kitex/server" 7 | merchant "github.com/tiktokmall/backend/rpc_gen/kitex_gen/merchant" 8 | ) 9 | 10 | // NewInvoker creates a server.Invoker with the given handler and options. 11 | func NewInvoker(handler merchant.MerchantService, opts ...server.Option) server.Invoker { 12 | var options []server.Option 13 | 14 | options = append(options, opts...) 15 | 16 | s := server.NewInvoker(options...) 17 | if err := s.RegisterService(serviceInfo(), handler); err != nil { 18 | panic(err) 19 | } 20 | if err := s.Init(); err != nil { 21 | panic(err) 22 | } 23 | return s 24 | } 25 | -------------------------------------------------------------------------------- /backend/rpc_gen/kitex_gen/merchant/merchantservice/server.go: -------------------------------------------------------------------------------- 1 | // Code generated by Kitex v0.9.1. DO NOT EDIT. 2 | package merchantservice 3 | 4 | import ( 5 | server "github.com/cloudwego/kitex/server" 6 | merchant "github.com/tiktokmall/backend/rpc_gen/kitex_gen/merchant" 7 | ) 8 | 9 | // NewServer creates a server.Server with the given handler and options. 10 | func NewServer(handler merchant.MerchantService, opts ...server.Option) server.Server { 11 | var options []server.Option 12 | 13 | options = append(options, opts...) 14 | 15 | svr := server.NewServer(options...) 16 | if err := svr.RegisterService(serviceInfo(), handler); err != nil { 17 | panic(err) 18 | } 19 | return svr 20 | } 21 | 22 | func RegisterService(svr server.Server, handler merchant.MerchantService, opts ...server.RegisterOption) error { 23 | return svr.RegisterService(serviceInfo(), handler, opts...) 24 | } 25 | -------------------------------------------------------------------------------- /backend/rpc_gen/kitex_gen/order/orderservice/invoker.go: -------------------------------------------------------------------------------- 1 | // Code generated by Kitex v0.9.1. DO NOT EDIT. 2 | 3 | package orderservice 4 | 5 | import ( 6 | server "github.com/cloudwego/kitex/server" 7 | order "github.com/tiktokmall/backend/rpc_gen/kitex_gen/order" 8 | ) 9 | 10 | // NewInvoker creates a server.Invoker with the given handler and options. 11 | func NewInvoker(handler order.OrderService, opts ...server.Option) server.Invoker { 12 | var options []server.Option 13 | 14 | options = append(options, opts...) 15 | 16 | s := server.NewInvoker(options...) 17 | if err := s.RegisterService(serviceInfo(), handler); err != nil { 18 | panic(err) 19 | } 20 | if err := s.Init(); err != nil { 21 | panic(err) 22 | } 23 | return s 24 | } 25 | -------------------------------------------------------------------------------- /backend/rpc_gen/kitex_gen/order/orderservice/server.go: -------------------------------------------------------------------------------- 1 | // Code generated by Kitex v0.9.1. DO NOT EDIT. 2 | package orderservice 3 | 4 | import ( 5 | server "github.com/cloudwego/kitex/server" 6 | order "github.com/tiktokmall/backend/rpc_gen/kitex_gen/order" 7 | ) 8 | 9 | // NewServer creates a server.Server with the given handler and options. 10 | func NewServer(handler order.OrderService, opts ...server.Option) server.Server { 11 | var options []server.Option 12 | 13 | options = append(options, opts...) 14 | 15 | svr := server.NewServer(options...) 16 | if err := svr.RegisterService(serviceInfo(), handler); err != nil { 17 | panic(err) 18 | } 19 | return svr 20 | } 21 | 22 | func RegisterService(svr server.Server, handler order.OrderService, opts ...server.RegisterOption) error { 23 | return svr.RegisterService(serviceInfo(), handler, opts...) 24 | } 25 | -------------------------------------------------------------------------------- /backend/rpc_gen/kitex_gen/payment/paymentservice/invoker.go: -------------------------------------------------------------------------------- 1 | // Code generated by Kitex v0.9.1. DO NOT EDIT. 2 | 3 | package paymentservice 4 | 5 | import ( 6 | server "github.com/cloudwego/kitex/server" 7 | payment "github.com/tiktokmall/backend/rpc_gen/kitex_gen/payment" 8 | ) 9 | 10 | // NewInvoker creates a server.Invoker with the given handler and options. 11 | func NewInvoker(handler payment.PaymentService, opts ...server.Option) server.Invoker { 12 | var options []server.Option 13 | 14 | options = append(options, opts...) 15 | 16 | s := server.NewInvoker(options...) 17 | if err := s.RegisterService(serviceInfo(), handler); err != nil { 18 | panic(err) 19 | } 20 | if err := s.Init(); err != nil { 21 | panic(err) 22 | } 23 | return s 24 | } 25 | -------------------------------------------------------------------------------- /backend/rpc_gen/kitex_gen/payment/paymentservice/server.go: -------------------------------------------------------------------------------- 1 | // Code generated by Kitex v0.9.1. DO NOT EDIT. 2 | package paymentservice 3 | 4 | import ( 5 | server "github.com/cloudwego/kitex/server" 6 | payment "github.com/tiktokmall/backend/rpc_gen/kitex_gen/payment" 7 | ) 8 | 9 | // NewServer creates a server.Server with the given handler and options. 10 | func NewServer(handler payment.PaymentService, opts ...server.Option) server.Server { 11 | var options []server.Option 12 | 13 | options = append(options, opts...) 14 | 15 | svr := server.NewServer(options...) 16 | if err := svr.RegisterService(serviceInfo(), handler); err != nil { 17 | panic(err) 18 | } 19 | return svr 20 | } 21 | 22 | func RegisterService(svr server.Server, handler payment.PaymentService, opts ...server.RegisterOption) error { 23 | return svr.RegisterService(serviceInfo(), handler, opts...) 24 | } 25 | -------------------------------------------------------------------------------- /backend/rpc_gen/kitex_gen/product/productcatalogservice/invoker.go: -------------------------------------------------------------------------------- 1 | // Code generated by Kitex v0.9.1. DO NOT EDIT. 2 | 3 | package productcatalogservice 4 | 5 | import ( 6 | server "github.com/cloudwego/kitex/server" 7 | product "github.com/tiktokmall/backend/rpc_gen/kitex_gen/product" 8 | ) 9 | 10 | // NewInvoker creates a server.Invoker with the given handler and options. 11 | func NewInvoker(handler product.ProductCatalogService, opts ...server.Option) server.Invoker { 12 | var options []server.Option 13 | 14 | options = append(options, opts...) 15 | 16 | s := server.NewInvoker(options...) 17 | if err := s.RegisterService(serviceInfo(), handler); err != nil { 18 | panic(err) 19 | } 20 | if err := s.Init(); err != nil { 21 | panic(err) 22 | } 23 | return s 24 | } 25 | -------------------------------------------------------------------------------- /backend/rpc_gen/kitex_gen/product/productcatalogservice/server.go: -------------------------------------------------------------------------------- 1 | // Code generated by Kitex v0.9.1. DO NOT EDIT. 2 | package productcatalogservice 3 | 4 | import ( 5 | server "github.com/cloudwego/kitex/server" 6 | product "github.com/tiktokmall/backend/rpc_gen/kitex_gen/product" 7 | ) 8 | 9 | // NewServer creates a server.Server with the given handler and options. 10 | func NewServer(handler product.ProductCatalogService, opts ...server.Option) server.Server { 11 | var options []server.Option 12 | 13 | options = append(options, opts...) 14 | 15 | svr := server.NewServer(options...) 16 | if err := svr.RegisterService(serviceInfo(), handler); err != nil { 17 | panic(err) 18 | } 19 | return svr 20 | } 21 | 22 | func RegisterService(svr server.Server, handler product.ProductCatalogService, opts ...server.RegisterOption) error { 23 | return svr.RegisterService(serviceInfo(), handler, opts...) 24 | } 25 | -------------------------------------------------------------------------------- /backend/rpc_gen/kitex_gen/user/userservice/invoker.go: -------------------------------------------------------------------------------- 1 | // Code generated by Kitex v0.9.1. DO NOT EDIT. 2 | 3 | package userservice 4 | 5 | import ( 6 | server "github.com/cloudwego/kitex/server" 7 | user "github.com/tiktokmall/backend/rpc_gen/kitex_gen/user" 8 | ) 9 | 10 | // NewInvoker creates a server.Invoker with the given handler and options. 11 | func NewInvoker(handler user.UserService, opts ...server.Option) server.Invoker { 12 | var options []server.Option 13 | 14 | options = append(options, opts...) 15 | 16 | s := server.NewInvoker(options...) 17 | if err := s.RegisterService(serviceInfo(), handler); err != nil { 18 | panic(err) 19 | } 20 | if err := s.Init(); err != nil { 21 | panic(err) 22 | } 23 | return s 24 | } 25 | -------------------------------------------------------------------------------- /backend/rpc_gen/kitex_gen/user/userservice/server.go: -------------------------------------------------------------------------------- 1 | // Code generated by Kitex v0.9.1. DO NOT EDIT. 2 | package userservice 3 | 4 | import ( 5 | server "github.com/cloudwego/kitex/server" 6 | user "github.com/tiktokmall/backend/rpc_gen/kitex_gen/user" 7 | ) 8 | 9 | // NewServer creates a server.Server with the given handler and options. 10 | func NewServer(handler user.UserService, opts ...server.Option) server.Server { 11 | var options []server.Option 12 | 13 | options = append(options, opts...) 14 | 15 | svr := server.NewServer(options...) 16 | if err := svr.RegisterService(serviceInfo(), handler); err != nil { 17 | panic(err) 18 | } 19 | return svr 20 | } 21 | 22 | func RegisterService(svr server.Server, handler user.UserService, opts ...server.RegisterOption) error { 23 | return svr.RegisterService(serviceInfo(), handler, opts...) 24 | } 25 | -------------------------------------------------------------------------------- /backend/rpc_gen/rpc/cart/cart_init.go: -------------------------------------------------------------------------------- 1 | package cart 2 | 3 | import ( 4 | "sync" 5 | 6 | "github.com/cloudwego/kitex/client" 7 | ) 8 | 9 | var ( 10 | // todo edit custom config 11 | defaultClient RPCClient 12 | defaultDstService = "cart" 13 | defaultClientOpts = []client.Option{ 14 | client.WithHostPorts("127.0.0.1:8888"), 15 | } 16 | once sync.Once 17 | ) 18 | 19 | func init() { 20 | DefaultClient() 21 | } 22 | 23 | func DefaultClient() RPCClient { 24 | once.Do(func() { 25 | defaultClient = newClient(defaultDstService, defaultClientOpts...) 26 | }) 27 | return defaultClient 28 | } 29 | 30 | func newClient(dstService string, opts ...client.Option) RPCClient { 31 | c, err := NewRPCClient(dstService, opts...) 32 | if err != nil { 33 | panic("failed to init client: " + err.Error()) 34 | } 35 | return c 36 | } 37 | 38 | func InitClient(dstService string, opts ...client.Option) { 39 | defaultClient = newClient(dstService, opts...) 40 | } 41 | -------------------------------------------------------------------------------- /backend/rpc_gen/rpc/checkout/checkout_default.go: -------------------------------------------------------------------------------- 1 | package checkout 2 | 3 | import ( 4 | "context" 5 | "github.com/cloudwego/kitex/client/callopt" 6 | "github.com/cloudwego/kitex/pkg/klog" 7 | checkout "github.com/tiktokmall/backend/rpc_gen/kitex_gen/checkout" 8 | ) 9 | 10 | func Checkout(ctx context.Context, req *checkout.CheckoutReq, callOptions ...callopt.Option) (resp *checkout.CheckoutResp, err error) { 11 | resp, err = defaultClient.Checkout(ctx, req, callOptions...) 12 | if err != nil { 13 | klog.CtxErrorf(ctx, "Checkout call failed,err =%+v", err) 14 | return nil, err 15 | } 16 | return resp, nil 17 | } 18 | -------------------------------------------------------------------------------- /backend/rpc_gen/rpc/checkout/checkout_init.go: -------------------------------------------------------------------------------- 1 | package checkout 2 | 3 | import ( 4 | "sync" 5 | 6 | "github.com/cloudwego/kitex/client" 7 | ) 8 | 9 | var ( 10 | // todo edit custom config 11 | defaultClient RPCClient 12 | defaultDstService = "checkout" 13 | defaultClientOpts = []client.Option{ 14 | client.WithHostPorts("127.0.0.1:8888"), 15 | } 16 | once sync.Once 17 | ) 18 | 19 | func init() { 20 | DefaultClient() 21 | } 22 | 23 | func DefaultClient() RPCClient { 24 | once.Do(func() { 25 | defaultClient = newClient(defaultDstService, defaultClientOpts...) 26 | }) 27 | return defaultClient 28 | } 29 | 30 | func newClient(dstService string, opts ...client.Option) RPCClient { 31 | c, err := NewRPCClient(dstService, opts...) 32 | if err != nil { 33 | panic("failed to init client: " + err.Error()) 34 | } 35 | return c 36 | } 37 | 38 | func InitClient(dstService string, opts ...client.Option) { 39 | defaultClient = newClient(dstService, opts...) 40 | } 41 | -------------------------------------------------------------------------------- /backend/rpc_gen/rpc/email/email_default.go: -------------------------------------------------------------------------------- 1 | package email 2 | 3 | import ( 4 | "context" 5 | email "github.com/tiktokmall/backend/rpc_gen/kitex_gen/email" 6 | "github.com/cloudwego/kitex/client/callopt" 7 | "github.com/cloudwego/kitex/pkg/klog" 8 | ) 9 | 10 | func Send(ctx context.Context, req *email.EmailReq, callOptions ...callopt.Option) (resp *email.EmailResp, err error) { 11 | resp, err = defaultClient.Send(ctx, req, callOptions...) 12 | if err != nil { 13 | klog.CtxErrorf(ctx, "Send call failed,err =%+v", err) 14 | return nil, err 15 | } 16 | return resp, nil 17 | } 18 | -------------------------------------------------------------------------------- /backend/rpc_gen/rpc/email/email_init.go: -------------------------------------------------------------------------------- 1 | package email 2 | 3 | import ( 4 | "sync" 5 | 6 | "github.com/cloudwego/kitex/client" 7 | ) 8 | 9 | var ( 10 | // todo edit custom config 11 | defaultClient RPCClient 12 | defaultDstService = "email" 13 | defaultClientOpts = []client.Option{ 14 | client.WithHostPorts("127.0.0.1:8888"), 15 | } 16 | once sync.Once 17 | ) 18 | 19 | func init() { 20 | DefaultClient() 21 | } 22 | 23 | func DefaultClient() RPCClient { 24 | once.Do(func() { 25 | defaultClient = newClient(defaultDstService, defaultClientOpts...) 26 | }) 27 | return defaultClient 28 | } 29 | 30 | func newClient(dstService string, opts ...client.Option) RPCClient { 31 | c, err := NewRPCClient(dstService, opts...) 32 | if err != nil { 33 | panic("failed to init client: " + err.Error()) 34 | } 35 | return c 36 | } 37 | 38 | func InitClient(dstService string, opts ...client.Option) { 39 | defaultClient = newClient(dstService, opts...) 40 | } 41 | -------------------------------------------------------------------------------- /backend/rpc_gen/rpc/merchant/merchant_init.go: -------------------------------------------------------------------------------- 1 | package merchant 2 | 3 | import ( 4 | "sync" 5 | 6 | "github.com/cloudwego/kitex/client" 7 | ) 8 | 9 | var ( 10 | // todo edit custom config 11 | defaultClient RPCClient 12 | defaultDstService = "merchant" 13 | defaultClientOpts = []client.Option{ 14 | client.WithHostPorts("127.0.0.1:8888"), 15 | } 16 | once sync.Once 17 | ) 18 | 19 | func init() { 20 | DefaultClient() 21 | } 22 | 23 | func DefaultClient() RPCClient { 24 | once.Do(func() { 25 | defaultClient = newClient(defaultDstService, defaultClientOpts...) 26 | }) 27 | return defaultClient 28 | } 29 | 30 | func newClient(dstService string, opts ...client.Option) RPCClient { 31 | c, err := NewRPCClient(dstService, opts...) 32 | if err != nil { 33 | panic("failed to init client: " + err.Error()) 34 | } 35 | return c 36 | } 37 | 38 | func InitClient(dstService string, opts ...client.Option) { 39 | defaultClient = newClient(dstService, opts...) 40 | } 41 | -------------------------------------------------------------------------------- /backend/rpc_gen/rpc/order/order_init.go: -------------------------------------------------------------------------------- 1 | package order 2 | 3 | import ( 4 | "sync" 5 | 6 | "github.com/cloudwego/kitex/client" 7 | ) 8 | 9 | var ( 10 | // todo edit custom config 11 | defaultClient RPCClient 12 | defaultDstService = "order" 13 | defaultClientOpts = []client.Option{ 14 | client.WithHostPorts("127.0.0.1:8888"), 15 | } 16 | once sync.Once 17 | ) 18 | 19 | func init() { 20 | DefaultClient() 21 | } 22 | 23 | func DefaultClient() RPCClient { 24 | once.Do(func() { 25 | defaultClient = newClient(defaultDstService, defaultClientOpts...) 26 | }) 27 | return defaultClient 28 | } 29 | 30 | func newClient(dstService string, opts ...client.Option) RPCClient { 31 | c, err := NewRPCClient(dstService, opts...) 32 | if err != nil { 33 | panic("failed to init client: " + err.Error()) 34 | } 35 | return c 36 | } 37 | 38 | func InitClient(dstService string, opts ...client.Option) { 39 | defaultClient = newClient(dstService, opts...) 40 | } 41 | -------------------------------------------------------------------------------- /backend/rpc_gen/rpc/payment/payment_default.go: -------------------------------------------------------------------------------- 1 | package payment 2 | 3 | import ( 4 | "context" 5 | "github.com/cloudwego/kitex/client/callopt" 6 | "github.com/cloudwego/kitex/pkg/klog" 7 | payment "github.com/tiktokmall/backend/rpc_gen/kitex_gen/payment" 8 | ) 9 | 10 | func Charge(ctx context.Context, req *payment.ChargeReq, callOptions ...callopt.Option) (resp *payment.ChargeResp, err error) { 11 | resp, err = defaultClient.Charge(ctx, req, callOptions...) 12 | if err != nil { 13 | klog.CtxErrorf(ctx, "Charge call failed,err =%+v", err) 14 | return nil, err 15 | } 16 | return resp, nil 17 | } 18 | 19 | func Alipay(ctx context.Context, req *payment.AlipayReq, callOptions ...callopt.Option) (resp *payment.AlipayResp, err error) { 20 | resp, err = defaultClient.Alipay(ctx, req, callOptions...) 21 | if err != nil { 22 | klog.CtxErrorf(ctx, "Alipay call failed,err =%+v", err) 23 | return nil, err 24 | } 25 | return resp, nil 26 | } 27 | -------------------------------------------------------------------------------- /backend/rpc_gen/rpc/payment/payment_init.go: -------------------------------------------------------------------------------- 1 | package payment 2 | 3 | import ( 4 | "sync" 5 | 6 | "github.com/cloudwego/kitex/client" 7 | ) 8 | 9 | var ( 10 | // todo edit custom config 11 | defaultClient RPCClient 12 | defaultDstService = "payment" 13 | defaultClientOpts = []client.Option{ 14 | client.WithHostPorts("127.0.0.1:8888"), 15 | } 16 | once sync.Once 17 | ) 18 | 19 | func init() { 20 | DefaultClient() 21 | } 22 | 23 | func DefaultClient() RPCClient { 24 | once.Do(func() { 25 | defaultClient = newClient(defaultDstService, defaultClientOpts...) 26 | }) 27 | return defaultClient 28 | } 29 | 30 | func newClient(dstService string, opts ...client.Option) RPCClient { 31 | c, err := NewRPCClient(dstService, opts...) 32 | if err != nil { 33 | panic("failed to init client: " + err.Error()) 34 | } 35 | return c 36 | } 37 | 38 | func InitClient(dstService string, opts ...client.Option) { 39 | defaultClient = newClient(dstService, opts...) 40 | } 41 | -------------------------------------------------------------------------------- /backend/rpc_gen/rpc/product/product_init.go: -------------------------------------------------------------------------------- 1 | package product 2 | 3 | import ( 4 | "sync" 5 | 6 | "github.com/cloudwego/kitex/client" 7 | ) 8 | 9 | var ( 10 | // todo edit custom config 11 | defaultClient RPCClient 12 | defaultDstService = "product" 13 | defaultClientOpts = []client.Option{ 14 | client.WithHostPorts("127.0.0.1:8888"), 15 | } 16 | once sync.Once 17 | ) 18 | 19 | func init() { 20 | DefaultClient() 21 | } 22 | 23 | func DefaultClient() RPCClient { 24 | once.Do(func() { 25 | defaultClient = newClient(defaultDstService, defaultClientOpts...) 26 | }) 27 | return defaultClient 28 | } 29 | 30 | func newClient(dstService string, opts ...client.Option) RPCClient { 31 | c, err := NewRPCClient(dstService, opts...) 32 | if err != nil { 33 | panic("failed to init client: " + err.Error()) 34 | } 35 | return c 36 | } 37 | 38 | func InitClient(dstService string, opts ...client.Option) { 39 | defaultClient = newClient(dstService, opts...) 40 | } 41 | -------------------------------------------------------------------------------- /backend/rpc_gen/rpc/user/user_init.go: -------------------------------------------------------------------------------- 1 | package user 2 | 3 | import ( 4 | "sync" 5 | 6 | "github.com/cloudwego/kitex/client" 7 | ) 8 | 9 | var ( 10 | // todo edit custom config 11 | defaultClient RPCClient 12 | defaultDstService = "user" 13 | defaultClientOpts = []client.Option{ 14 | client.WithHostPorts("127.0.0.1:8888"), 15 | } 16 | once sync.Once 17 | ) 18 | 19 | func init() { 20 | DefaultClient() 21 | } 22 | 23 | func DefaultClient() RPCClient { 24 | once.Do(func() { 25 | defaultClient = newClient(defaultDstService, defaultClientOpts...) 26 | }) 27 | return defaultClient 28 | } 29 | 30 | func newClient(dstService string, opts ...client.Option) RPCClient { 31 | c, err := NewRPCClient(dstService, opts...) 32 | if err != nil { 33 | panic("failed to init client: " + err.Error()) 34 | } 35 | return c 36 | } 37 | 38 | func InitClient(dstService string, opts ...client.Option) { 39 | defaultClient = newClient(dstService, opts...) 40 | } 41 | -------------------------------------------------------------------------------- /frontend/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # Editor directories and files 17 | .idea 18 | .vscode 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.sw? 24 | -------------------------------------------------------------------------------- /frontend/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /frontend/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "esnext", 5 | "baseUrl": "./", 6 | "moduleResolution": "node", 7 | "paths": { 8 | "@/*": [ 9 | "src/*" 10 | ] 11 | }, 12 | "lib": [ 13 | "esnext", 14 | "dom", 15 | "dom.iterable", 16 | "scripthost" 17 | ] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mall-frontend", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build" 8 | }, 9 | "dependencies": { 10 | "@element-plus/icons-vue": "^2.3.1", 11 | "@popperjs/core": "^2.11.8", 12 | "axios": "^1.7.9", 13 | "core-js": "^3.8.3", 14 | "element-plus": "^2.9.3", 15 | "js-cookie": "^3.0.5", 16 | "marked": "^15.0.7", 17 | "vue": "^3.2.13", 18 | "vue-router": "^4.0.3", 19 | "vuex": "^4.0.0" 20 | }, 21 | "devDependencies": { 22 | "@vue/cli-plugin-babel": "~5.0.0", 23 | "@vue/cli-plugin-router": "~5.0.0", 24 | "@vue/cli-plugin-vuex": "~5.0.0", 25 | "@vue/cli-service": "~5.0.0" 26 | }, 27 | "browserslist": [ 28 | "> 1%", 29 | "last 2 versions", 30 | "not dead", 31 | "not ie 11" 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /frontend/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzulihrs/TikTokMall/22bdae6c52c13b4818af407f3cb59f5b8fca506b/frontend/public/favicon.ico -------------------------------------------------------------------------------- /frontend/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%= htmlWebpackPlugin.options.title %> 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /frontend/public/static/image/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzulihrs/TikTokMall/22bdae6c52c13b4818af407f3cb59f5b8fca506b/frontend/public/static/image/logo.jpg -------------------------------------------------------------------------------- /frontend/public/static/image/mouse-pad.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzulihrs/TikTokMall/22bdae6c52c13b4818af407f3cb59f5b8fca506b/frontend/public/static/image/mouse-pad.jpeg -------------------------------------------------------------------------------- /frontend/public/static/image/notebook.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzulihrs/TikTokMall/22bdae6c52c13b4818af407f3cb59f5b8fca506b/frontend/public/static/image/notebook.jpeg -------------------------------------------------------------------------------- /frontend/public/static/image/sweatshirt.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzulihrs/TikTokMall/22bdae6c52c13b4818af407f3cb59f5b8fca506b/frontend/public/static/image/sweatshirt.jpeg -------------------------------------------------------------------------------- /frontend/public/static/image/t-shirt-1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzulihrs/TikTokMall/22bdae6c52c13b4818af407f3cb59f5b8fca506b/frontend/public/static/image/t-shirt-1.jpeg -------------------------------------------------------------------------------- /frontend/public/static/image/t-shirt-2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzulihrs/TikTokMall/22bdae6c52c13b4818af407f3cb59f5b8fca506b/frontend/public/static/image/t-shirt-2.jpeg -------------------------------------------------------------------------------- /frontend/public/static/image/t-shirt.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzulihrs/TikTokMall/22bdae6c52c13b4818af407f3cb59f5b8fca506b/frontend/public/static/image/t-shirt.jpeg -------------------------------------------------------------------------------- /frontend/public/static/image/toiletry-bag.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzulihrs/TikTokMall/22bdae6c52c13b4818af407f3cb59f5b8fca506b/frontend/public/static/image/toiletry-bag.jpg -------------------------------------------------------------------------------- /frontend/public/static/image/toothbrush-cup.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzulihrs/TikTokMall/22bdae6c52c13b4818af407f3cb59f5b8fca506b/frontend/public/static/image/toothbrush-cup.jpg -------------------------------------------------------------------------------- /frontend/src/App.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 23 | 24 | 27 | -------------------------------------------------------------------------------- /frontend/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zzulihrs/TikTokMall/22bdae6c52c13b4818af407f3cb59f5b8fca506b/frontend/src/assets/logo.png -------------------------------------------------------------------------------- /frontend/src/components/merchant/Footer.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 18 | -------------------------------------------------------------------------------- /frontend/src/components/merchant/Functions.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 19 | 20 | -------------------------------------------------------------------------------- /frontend/src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import App from './App.vue' 3 | import router from './router' 4 | import store from './store' 5 | import ElementPlus from 'element-plus' 6 | import 'element-plus/dist/index.css' 7 | import marked from 'marked'; 8 | const markedMixin = { 9 | methods: { 10 | md: function (input) { 11 | return marked (input); 12 | }, 13 | }, 14 | }; 15 | 16 | const app = createApp(App).mixin(markedMixin) 17 | 18 | app.use(store) 19 | // Initialize auth state 20 | store.dispatch('auth/initialize') 21 | app.use(router) 22 | app.use(ElementPlus) 23 | 24 | app.mount('#app') 25 | -------------------------------------------------------------------------------- /frontend/src/store/modules/category.js: -------------------------------------------------------------------------------- 1 | export default { 2 | namespaced: true, 3 | 4 | state: () => ({ 5 | category: 'All', 6 | categories: [ 7 | { 8 | id: 0, 9 | name: 'All', 10 | description: 'All' 11 | }, 12 | { 13 | id: 1, 14 | name: 'T-Shirt', 15 | description: 'T-Shirt' 16 | }, 17 | { 18 | id: 2, 19 | name: 'Sticker', 20 | description: 'Sticker' 21 | } 22 | ] 23 | }), 24 | 25 | getters: { 26 | // 获取搜索结果 27 | categories: state => state.categories, 28 | category: state => state.category 29 | }, 30 | 31 | mutations: { 32 | Update_Category(state, payload) { 33 | state.category = payload; 34 | } 35 | }, 36 | 37 | actions: { 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /frontend/src/views/AboutView.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /frontend/vue.config.js: -------------------------------------------------------------------------------- 1 | const { defineConfig } = require('@vue/cli-service') 2 | module.exports = defineConfig({ 3 | transpileDependencies: true, 4 | devServer: { 5 | port: 8000, 6 | proxy: { 7 | '/api': { 8 | // 通过 VUE_ENV 来判断是否是线上环境 9 | target: process.env.VUE_ENV === 'online' 10 | ? 'http://62.234.20.127:8080/' // 线上服务器地址 11 | : 'http://localhost:8080/', 12 | changeOrigin: true, // 允许跨域 13 | pathRewrite: { 14 | '^/api': '' // 重写路径 15 | } 16 | } 17 | }, 18 | client: { 19 | overlay: false // 自适应窗口大小时webpack会报错 20 | }, 21 | } 22 | }) 23 | --------------------------------------------------------------------------------