|
@@ -0,0 +1,1513 @@
|
|
|
+<script setup>
|
|
|
+import { ref, reactive, watch, computed, onMounted } from "vue";
|
|
|
+import { useMainStore } from "@/stores/store";
|
|
|
+import { Loader } from "@googlemaps/js-api-loader";
|
|
|
+import VueDatePicker from "@vuepic/vue-datepicker";
|
|
|
+import "@vuepic/vue-datepicker/dist/main.css";
|
|
|
+import axios from "axios";
|
|
|
+import moment from "moment";
|
|
|
+import Navbar from "@/components/Navbar.vue";
|
|
|
+
|
|
|
+const store = useMainStore();
|
|
|
+const token = store.token;
|
|
|
+console.log("token", token);
|
|
|
+
|
|
|
+let step = ref(1);
|
|
|
+let stepTitle = ref("");
|
|
|
+let stepDescription = ref("");
|
|
|
+let loading = ref(false);
|
|
|
+
|
|
|
+const computedTitle = computed(() => {
|
|
|
+ switch (step.value) {
|
|
|
+ case 1:
|
|
|
+ stepTitle.value = "Step1 新增據點";
|
|
|
+ stepDescription.value = "創建課程之前,請先新增您的據點(上課地址)";
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ stepTitle.value = "Step2 工藝家教學履歷";
|
|
|
+ stepDescription.value =
|
|
|
+ "開始打造屬於您的工藝履歷,讓學徒對你印象深刻吧!";
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ stepTitle.value = "Step3 創建課程";
|
|
|
+ stepDescription.value =
|
|
|
+ "完整且清楚的課程建立,是連接工藝老師與學徒的重要橋梁!";
|
|
|
+ break;
|
|
|
+ case 4:
|
|
|
+ stepTitle.value = "恭喜您完成創建課程!";
|
|
|
+ stepDescription.value = "";
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return { stepTitle: stepTitle.value, stepDescription: stepDescription.value };
|
|
|
+});
|
|
|
+
|
|
|
+let date = reactive({
|
|
|
+ start_date: "", // 起始日期
|
|
|
+ start_time: "", // 起始時間
|
|
|
+ end_date: "", // 結束日期
|
|
|
+ end_time: "", // 結束時間
|
|
|
+ registration_start_date: "", // 報名起始日期
|
|
|
+ registration_start_time: "", // 報名起始時間
|
|
|
+ registration_end_date: "", // 報名截止日期
|
|
|
+ registration_end_time: "", // 報名截止時間
|
|
|
+});
|
|
|
+
|
|
|
+// 處理時間格式(日期+時間)
|
|
|
+function mergeAndFormatDateTime(dateString, timeInfo) {
|
|
|
+ const date = new Date(dateString);
|
|
|
+
|
|
|
+ date.setHours(timeInfo.hours);
|
|
|
+ date.setMinutes(timeInfo.minutes);
|
|
|
+ date.setSeconds(timeInfo.seconds);
|
|
|
+
|
|
|
+ const year = date.getUTCFullYear();
|
|
|
+ const month = String(date.getUTCMonth() + 1).padStart(2, "0");
|
|
|
+ const day = String(date.getUTCDate()).padStart(2, "0");
|
|
|
+ const hours = String(date.getUTCHours()).padStart(2, "0");
|
|
|
+ const minutes = String(date.getUTCMinutes()).padStart(2, "0");
|
|
|
+ const seconds = String(date.getUTCSeconds()).padStart(2, "0");
|
|
|
+
|
|
|
+ return `${year}-${month}-${day}T${hours}:${minutes}:${seconds}.000Z`;
|
|
|
+}
|
|
|
+
|
|
|
+const breadcrumbs = reactive([
|
|
|
+ {
|
|
|
+ title: "首頁",
|
|
|
+ disabled: false,
|
|
|
+ href: "/",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: "我要開課",
|
|
|
+ disabled: false,
|
|
|
+ href: "/setup-courses",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: "創建課程",
|
|
|
+ disabled: true,
|
|
|
+ },
|
|
|
+]);
|
|
|
+
|
|
|
+// Google Map
|
|
|
+const states = reactive({
|
|
|
+ google: null,
|
|
|
+ map: null,
|
|
|
+ markers: null,
|
|
|
+});
|
|
|
+
|
|
|
+const initMap = async () => {
|
|
|
+ const loader = new Loader({
|
|
|
+ apiKey: "AIzaSyAzDeviZ-TpwzT1atlnshNJRjBgndP05Mw",
|
|
|
+ version: "weekly",
|
|
|
+ libraries: ["places"],
|
|
|
+ language: "zh-TW",
|
|
|
+ });
|
|
|
+ states.google = await loader.load();
|
|
|
+ states.map = new states.google.maps.Map(document.getElementById("map"), {
|
|
|
+ center: { lat: 25.0425, lng: 121.5468 },
|
|
|
+ zoom: 11,
|
|
|
+ mapTypeControl: false,
|
|
|
+ fullscreenControl: false,
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+onMounted(async () => {
|
|
|
+ await initMap();
|
|
|
+});
|
|
|
+
|
|
|
+let location = reactive({
|
|
|
+ location_name: "",
|
|
|
+ Lng: "",
|
|
|
+ Lat: "",
|
|
|
+ address: "",
|
|
|
+ introduction: "",
|
|
|
+ email: "",
|
|
|
+ phone: "",
|
|
|
+ access_token: token,
|
|
|
+});
|
|
|
+
|
|
|
+let locationId = ref("");
|
|
|
+
|
|
|
+async function insertSchool() {
|
|
|
+ const formData = new FormData();
|
|
|
+ for (const key in location) {
|
|
|
+ formData.append(key, location[key]);
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ const response = await axios.post(
|
|
|
+ "https://cmm.ai:8088/api/insert_school",
|
|
|
+ formData
|
|
|
+ );
|
|
|
+
|
|
|
+ locationId.value = response.data.location_id;
|
|
|
+ console.log("新增據點 response", response);
|
|
|
+ } catch (error) {
|
|
|
+ console.error(error);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 新增履歷
|
|
|
+let resume = reactive({
|
|
|
+ teacher_name: "", // 老師姓名
|
|
|
+ work_type: "", // 工作性質
|
|
|
+ experience: "", // 教學經驗
|
|
|
+ expertise: "", // 專長工藝技能
|
|
|
+ license: "", // 工藝相關證照
|
|
|
+ media: "", // 社群媒體
|
|
|
+ files: [], // 作品集
|
|
|
+ introduction: "", // 老師介紹
|
|
|
+});
|
|
|
+
|
|
|
+async function insertUserResume() {
|
|
|
+ console.log("insertUserResume", resume);
|
|
|
+
|
|
|
+ if (portfolioImg.value.length) {
|
|
|
+ resume.files = portfolioImg.value;
|
|
|
+ }
|
|
|
+
|
|
|
+ const formData = new FormData();
|
|
|
+ for (const key in resume) {
|
|
|
+ if (key === "files") {
|
|
|
+ resume.files.forEach((file) => {
|
|
|
+ formData.append("files", file);
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ formData.append(key, resume[key]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ let token = store.token;
|
|
|
+
|
|
|
+ try {
|
|
|
+ const response = await axios.post(
|
|
|
+ `https://cmm.ai:8088/api/input_user_resume?access_token=${token}`,
|
|
|
+ formData
|
|
|
+ );
|
|
|
+ console.log("新增履歷 response", response);
|
|
|
+ } catch (error) {
|
|
|
+ console.error(error);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 新增課程
|
|
|
+let course = reactive({
|
|
|
+ name: "", // 課程名稱
|
|
|
+ location_id: "", // 據點編號
|
|
|
+ category: "", // 工藝類別
|
|
|
+ introduction: "", // 課程簡介
|
|
|
+ organizer: "", // 主辦單位
|
|
|
+ cover_img_file: "", // 課程圖片
|
|
|
+ group_id: 2, // 學群編號(技藝)
|
|
|
+ group_sort: "", // 學群細分
|
|
|
+ special_class_list_name: "",
|
|
|
+ recommend: 0, // 是否推薦
|
|
|
+ is_inner: 1, // 內課課程
|
|
|
+ is_check: 0, // 審核結果
|
|
|
+ access_token: token,
|
|
|
+});
|
|
|
+
|
|
|
+watch(location, (data) => {
|
|
|
+ course.organizer = data.location_name; // 據點名稱 = 主辦單位
|
|
|
+});
|
|
|
+
|
|
|
+let classNameId = ref("");
|
|
|
+
|
|
|
+async function insertClassName() {
|
|
|
+ console.log("insertClassName", course);
|
|
|
+
|
|
|
+ course.location_id = locationId.value;
|
|
|
+
|
|
|
+ if (coverImg.value !== "") {
|
|
|
+ course.cover_img_file = coverImg.value;
|
|
|
+ }
|
|
|
+
|
|
|
+ const formData = new FormData();
|
|
|
+ for (const key in course) {
|
|
|
+ formData.append(key, course[key]);
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ const response = await axios.post(
|
|
|
+ "https://cmm.ai:8088/api/insert_class_name",
|
|
|
+ formData
|
|
|
+ );
|
|
|
+
|
|
|
+ console.log("新增課程 response", response);
|
|
|
+ classNameId.value = response.data.new_class_name_id;
|
|
|
+ } catch (error) {
|
|
|
+ console.error(error);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 新增場次
|
|
|
+let event = reactive({
|
|
|
+ name_id: "", // 課程名稱編號(需先新增課程取得Id)
|
|
|
+ event: "", // 場次名稱
|
|
|
+ start_time: "", // 課程起始日
|
|
|
+ end_time: "", // 課程結束日
|
|
|
+ contact: "", // 聯絡資訊
|
|
|
+ lecturer: "", // 課程講師
|
|
|
+ location: "",
|
|
|
+ content: "", // 課程內容
|
|
|
+ URL: "", // 外部連結
|
|
|
+ people: "不拘", // 對象
|
|
|
+ fee_method: "", // 課程價格
|
|
|
+ fee_payment: "", // 收費方式
|
|
|
+ registration_way: "", // 報名方式
|
|
|
+ registration_start: "", // 報名起始日
|
|
|
+ registration_end: "", // 報名截止日
|
|
|
+ number_limit: "", // 人數限制
|
|
|
+ remark: "", // 備註
|
|
|
+ ATM_address: "", // 匯款帳號(銀行代碼+帳號)
|
|
|
+ access_token: token,
|
|
|
+});
|
|
|
+
|
|
|
+let eventType = ref("");
|
|
|
+let isOneDay = ref(true);
|
|
|
+
|
|
|
+watch(eventType, (val) => {
|
|
|
+ if (val === "週期課程(例:2023/10/1~2023/10/30 每週一三上課)") {
|
|
|
+ isOneDay.value = false;
|
|
|
+ } else {
|
|
|
+ isOneDay.value = true;
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+let eventData = reactive({
|
|
|
+ list: [],
|
|
|
+});
|
|
|
+
|
|
|
+let isRemit = ref(false); // 是否顯示匯款資訊欄位
|
|
|
+let bankCode = ref("");
|
|
|
+let bankAccount = ref("");
|
|
|
+
|
|
|
+watch(event, (data) => {
|
|
|
+ if (data.fee_payment === "匯款") {
|
|
|
+ isRemit.value = true;
|
|
|
+ } else {
|
|
|
+ isRemit.value = false;
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+function addEventData() {
|
|
|
+ // 處理時間格式
|
|
|
+ event.start_time = mergeAndFormatDateTime(date.start_date, date.start_time);
|
|
|
+ event.end_time = mergeAndFormatDateTime(date.end_date, date.end_time);
|
|
|
+ event.registration_start = mergeAndFormatDateTime(
|
|
|
+ date.registration_start_date,
|
|
|
+ date.registration_start_time
|
|
|
+ );
|
|
|
+ event.registration_end = mergeAndFormatDateTime(
|
|
|
+ date.registration_end_date,
|
|
|
+ date.registration_end_time
|
|
|
+ );
|
|
|
+
|
|
|
+ if (isRemit && bankCode.value !== "" && bankAccount.value !== "") {
|
|
|
+ event.ATM_address = `(${bankCode.value})-${bankAccount.value}`;
|
|
|
+ }
|
|
|
+ eventData.list.push(JSON.parse(JSON.stringify(event)));
|
|
|
+ sessionsDialog.value = false;
|
|
|
+}
|
|
|
+
|
|
|
+function convertDateFormat(inputDateStr) {
|
|
|
+ const inputDate = new Date(inputDateStr);
|
|
|
+ const formattedDate = inputDate.toISOString();
|
|
|
+ return formattedDate;
|
|
|
+}
|
|
|
+
|
|
|
+async function insertEvent() {
|
|
|
+ console.log("insertEvent", event);
|
|
|
+
|
|
|
+ if (classNameId.value !== "") {
|
|
|
+ event.name_id = classNameId.value;
|
|
|
+ }
|
|
|
+
|
|
|
+ event.start_time = convertDateFormat(event.start_time);
|
|
|
+ event.end_time = convertDateFormat(event.end_time);
|
|
|
+ event.registration_start = convertDateFormat(event.registration_start);
|
|
|
+ event.registration_end = convertDateFormat(event.registration_end);
|
|
|
+
|
|
|
+ console.log("檢查日期格式", event);
|
|
|
+
|
|
|
+ const formData = new FormData();
|
|
|
+ for (const key in event) {
|
|
|
+ formData.append(key, event[key]);
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ const response = await axios.post(
|
|
|
+ "https://cmm.ai:8088/api/insert_event",
|
|
|
+ formData
|
|
|
+ );
|
|
|
+
|
|
|
+ console.log("新增場次 response", response);
|
|
|
+ } catch (error) {
|
|
|
+ console.error(error);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 創建課程
|
|
|
+async function create() {
|
|
|
+ loading.value = true;
|
|
|
+
|
|
|
+ try {
|
|
|
+ await insertSchool(); // 新增據點
|
|
|
+ await insertUserResume(); // 新增履歷
|
|
|
+ await insertClassName(); // 新增課程
|
|
|
+ await insertEvent(); // 新增場次
|
|
|
+ loading.value = false;
|
|
|
+ step.value++;
|
|
|
+ } catch (error) {
|
|
|
+ console.error(error);
|
|
|
+ loading.value = false;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const getCoordinates = async () => {
|
|
|
+ const geocoder = new states.google.maps.Geocoder();
|
|
|
+ geocoder.geocode({ address: location.address }, (results, status) => {
|
|
|
+ if (status === states.google.maps.GeocoderStatus.OK) {
|
|
|
+ location.Lat = results[0].geometry.location.lat();
|
|
|
+ location.Lng = results[0].geometry.location.lng();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 將地圖中心設為取得的經緯度,並調整縮放等級
|
|
|
+ states.map.setCenter({ lat: location.Lat, lng: location.Lng });
|
|
|
+ states.map.setZoom(15);
|
|
|
+
|
|
|
+ // 設定地址圖標
|
|
|
+ const marker = new google.maps.Marker({
|
|
|
+ position: { lat: location.Lat, lng: location.Lng },
|
|
|
+ map: states.map,
|
|
|
+ title: location.address,
|
|
|
+ icon: store.getImageUrl("map-icon/icon_house05.png"),
|
|
|
+ });
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+// 上傳圖片 Input
|
|
|
+const portfolioImgRef = ref(null);
|
|
|
+const coverImgRef = ref(null);
|
|
|
+
|
|
|
+const fileInputClick = (ref) => {
|
|
|
+ if (ref === "portfolio") {
|
|
|
+ portfolioImgRef.value.click();
|
|
|
+ } else if (ref === "cover") {
|
|
|
+ coverImgRef.value.click();
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// 作品集圖片
|
|
|
+let portfolioImg = ref([]);
|
|
|
+let portfolioImgList = ref([]);
|
|
|
+
|
|
|
+const handlePortfolioImg = (files) => {
|
|
|
+ console.log("files", files);
|
|
|
+ // portfolioImgList.value = []; // 清空陣列
|
|
|
+ for (let index = 0; index < files.length; index++) {
|
|
|
+ const file = files[index];
|
|
|
+ console.log("file", file);
|
|
|
+ let url = URL.createObjectURL(file);
|
|
|
+ portfolioImgList.value.push(url);
|
|
|
+ console.log("portfolioImgList", portfolioImgList);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+watch(portfolioImg, (newFiles) => {
|
|
|
+ if (newFiles.length > 0) {
|
|
|
+ handlePortfolioImg(newFiles);
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+// 封面圖片
|
|
|
+let coverImg = ref("");
|
|
|
+let coverImgUrl = ref("");
|
|
|
+
|
|
|
+const handleCoverImg = (event) => {
|
|
|
+ const file = event.target.files[0];
|
|
|
+ console.log("選擇檔案", file);
|
|
|
+ if (file) {
|
|
|
+ coverImg.value = file;
|
|
|
+ coverImgUrl.value = URL.createObjectURL(file); // 設定圖片預覽 URL
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// let age = ref("不拘");
|
|
|
+let sessionsDialog = ref(false);
|
|
|
+
|
|
|
+const requiredRule = (value) => !!value || "此欄位為必填";
|
|
|
+
|
|
|
+const weekList = reactive(["一", "二", "三", "四", "五", "六", "日"]);
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <Navbar />
|
|
|
+
|
|
|
+ <v-container class="mb-16 pb-16">
|
|
|
+ <v-breadcrumbs
|
|
|
+ :items="breadcrumbs"
|
|
|
+ divider="/"
|
|
|
+ class="py-10"
|
|
|
+ ></v-breadcrumbs>
|
|
|
+
|
|
|
+ <v-card class="mx-auto pa-10">
|
|
|
+ <v-card-title class="step-title">
|
|
|
+ <h5>{{ computedTitle.stepTitle }}</h5>
|
|
|
+ <p class="mt-5">{{ computedTitle.stepDescription }}</p>
|
|
|
+ </v-card-title>
|
|
|
+
|
|
|
+ <v-window v-model="step">
|
|
|
+ <v-window-item :value="1">
|
|
|
+ <v-card-text>
|
|
|
+ <v-label class="d-flex align-center pb-3">
|
|
|
+ <p class="pb-5 pe-3">據點名稱<span class="mark">*</span></p>
|
|
|
+ <v-text-field
|
|
|
+ v-model="location.location_name"
|
|
|
+ :rules="[requiredRule]"
|
|
|
+ placeholder="可以是您的工作室或品牌名稱/教學單位/您的姓名"
|
|
|
+ density="compact"
|
|
|
+ variant="outlined"
|
|
|
+ counter
|
|
|
+ maxlength="60"
|
|
|
+ ></v-text-field>
|
|
|
+ </v-label>
|
|
|
+
|
|
|
+ <v-label class="d-flex align-center pb-3 w-100">
|
|
|
+ <p class="pb-5 pe-3">據點地址<span class="mark">*</span></p>
|
|
|
+ <v-text-field
|
|
|
+ v-model="location.address"
|
|
|
+ :rules="[requiredRule]"
|
|
|
+ density="compact"
|
|
|
+ variant="outlined"
|
|
|
+ placeholder="需在安全且便於學徒到達之地點開課"
|
|
|
+ ></v-text-field>
|
|
|
+ <v-btn
|
|
|
+ @click="getCoordinates"
|
|
|
+ color="purple"
|
|
|
+ variant="flat"
|
|
|
+ class="ms-3 mb-6 px-8"
|
|
|
+ >
|
|
|
+ 查詢
|
|
|
+ </v-btn>
|
|
|
+ </v-label>
|
|
|
+
|
|
|
+ <div class="d-flex flex-column justify-end ms-16 ps-5">
|
|
|
+ <div
|
|
|
+ class="map"
|
|
|
+ id="map"
|
|
|
+ style="width: 100%; height: 500px"
|
|
|
+ ></div>
|
|
|
+
|
|
|
+ <v-row class="mt-3">
|
|
|
+ <v-col cols="12" md="6">
|
|
|
+ <v-label class="d-flex align-center">
|
|
|
+ <p class="pb-5 pe-3">經度</p>
|
|
|
+ <v-text-field
|
|
|
+ v-model="location.Lng"
|
|
|
+ density="compact"
|
|
|
+ variant="outlined"
|
|
|
+ disabled
|
|
|
+ ></v-text-field>
|
|
|
+ </v-label>
|
|
|
+ </v-col>
|
|
|
+ <v-col cols="12" md="6">
|
|
|
+ <v-label class="d-flex align-center">
|
|
|
+ <p class="pb-5 pe-3">緯度</p>
|
|
|
+ <v-text-field
|
|
|
+ v-model="location.Lat"
|
|
|
+ density="compact"
|
|
|
+ variant="outlined"
|
|
|
+ disabled
|
|
|
+ ></v-text-field>
|
|
|
+ </v-label>
|
|
|
+ </v-col>
|
|
|
+ </v-row>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <v-label class="d-block">
|
|
|
+ <p class="d-flex mb-5">據點 Email<span class="mark">*</span></p>
|
|
|
+ <v-text-field
|
|
|
+ v-model="location.email"
|
|
|
+ :rules="[requiredRule]"
|
|
|
+ density="compact"
|
|
|
+ variant="outlined"
|
|
|
+ placeholder="請填寫 Email"
|
|
|
+ ></v-text-field>
|
|
|
+ </v-label>
|
|
|
+
|
|
|
+ <v-row class="mt-3">
|
|
|
+ <v-col cols="12" md="12">
|
|
|
+ <v-label class="d-block">
|
|
|
+ <p class="d-flex">公開電話<span class="mark">*</span></p>
|
|
|
+ <span class="d-block py-3 hint"
|
|
|
+ >會顯示於課程介紹中,想了解課程資訊者聯繫用途</span
|
|
|
+ >
|
|
|
+ <v-text-field
|
|
|
+ v-model="location.phone"
|
|
|
+ :rules="[requiredRule]"
|
|
|
+ density="compact"
|
|
|
+ variant="outlined"
|
|
|
+ ></v-text-field>
|
|
|
+ </v-label>
|
|
|
+ </v-col>
|
|
|
+ <!-- <v-col cols="12" md="6">
|
|
|
+ <v-label class="d-block">
|
|
|
+ <p class="d-flex">聯繫電話<span class="mark">*</span></p>
|
|
|
+ <span class="d-block py-3 hint">平台專員連繫重要事項用</span>
|
|
|
+ <v-text-field
|
|
|
+ :rules="[(v) => !!v || '請輸入電話']"
|
|
|
+ density="compact"
|
|
|
+ variant="outlined"
|
|
|
+ ></v-text-field>
|
|
|
+ </v-label>
|
|
|
+ </v-col> -->
|
|
|
+ <!-- <v-col cols="12" md="6">
|
|
|
+ <v-label class="d-block">
|
|
|
+ <p class="d-flex">上傳據點照片</p>
|
|
|
+
|
|
|
+ <v-file-input
|
|
|
+ ref="fileInputRef"
|
|
|
+ label="File input"
|
|
|
+ variant="outlined"
|
|
|
+ placeholder="選擇相片上傳"
|
|
|
+ @change="handlePortfolioImg"
|
|
|
+ style="display: none"
|
|
|
+ ></v-file-input>
|
|
|
+ </v-label>
|
|
|
+ <v-btn @click="openFileInput" color="purple" class="my-5"
|
|
|
+ >選擇相片上傳</v-btn
|
|
|
+ >
|
|
|
+ <div class="step-01 image-preview">
|
|
|
+ <img
|
|
|
+ v-if="selectedFile"
|
|
|
+ :src="selectedFileUrl"
|
|
|
+ alt="上傳圖片預覽"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </v-col> -->
|
|
|
+
|
|
|
+ <v-col cols="12" md="12">
|
|
|
+ <v-label class="d-block">
|
|
|
+ <p class="d-flex mb-5">據點簡介<span class="mark">*</span></p>
|
|
|
+ <v-textarea
|
|
|
+ v-model="location.introduction"
|
|
|
+ rows="5"
|
|
|
+ variant="outlined"
|
|
|
+ ></v-textarea>
|
|
|
+ </v-label>
|
|
|
+ </v-col>
|
|
|
+ </v-row>
|
|
|
+ </v-card-text>
|
|
|
+ </v-window-item>
|
|
|
+
|
|
|
+ <v-window-item :value="2">
|
|
|
+ <v-card-text>
|
|
|
+ <v-row>
|
|
|
+ <v-col cols="6">
|
|
|
+ <v-label class="d-flex align-center pb-3">
|
|
|
+ <p class="pb-5 pe-3">老師姓名<span class="mark">*</span></p>
|
|
|
+ <v-text-field
|
|
|
+ v-model="resume.teacher_name"
|
|
|
+ :rules="[requiredRule]"
|
|
|
+ density="compact"
|
|
|
+ variant="outlined"
|
|
|
+ ></v-text-field>
|
|
|
+ </v-label>
|
|
|
+ </v-col>
|
|
|
+
|
|
|
+ <v-col cols="6"></v-col>
|
|
|
+
|
|
|
+ <v-col cols="3">
|
|
|
+ <v-label class="d-block">
|
|
|
+ <p class="pb-5 pe-3">工作性質<span class="mark">*</span></p>
|
|
|
+ <v-radio-group v-model="resume.work_type" inline>
|
|
|
+ <v-radio label="全職" value="全職"></v-radio>
|
|
|
+ <v-radio label="兼職" value="兼職" class="ps-3"></v-radio>
|
|
|
+ </v-radio-group>
|
|
|
+ </v-label>
|
|
|
+ </v-col>
|
|
|
+
|
|
|
+ <v-col cols="9">
|
|
|
+ <v-label class="d-block">
|
|
|
+ <p class="pb-5 pe-3">教學經驗</p>
|
|
|
+ <v-radio-group v-model="resume.experience" inline>
|
|
|
+ <v-radio label="0-5 年" value="0-5 年"></v-radio>
|
|
|
+ <v-radio
|
|
|
+ label="5-10 年"
|
|
|
+ value="5-10 年"
|
|
|
+ class="ps-3"
|
|
|
+ ></v-radio>
|
|
|
+ <v-radio
|
|
|
+ label="10-20 年"
|
|
|
+ value="10-20 年"
|
|
|
+ class="ps-3"
|
|
|
+ ></v-radio>
|
|
|
+ <v-radio
|
|
|
+ label="20 年以上"
|
|
|
+ value="20 年以上"
|
|
|
+ class="ps-3"
|
|
|
+ ></v-radio>
|
|
|
+ </v-radio-group>
|
|
|
+ </v-label>
|
|
|
+ </v-col>
|
|
|
+
|
|
|
+ <v-col cols="6">
|
|
|
+ <v-label class="d-block pb-3">
|
|
|
+ <p class="pb-5 pe-3">
|
|
|
+ 專長工藝技能<span class="mark">*</span>
|
|
|
+ </p>
|
|
|
+ <v-text-field
|
|
|
+ v-model="resume.expertise"
|
|
|
+ :rules="[requiredRule]"
|
|
|
+ density="compact"
|
|
|
+ variant="outlined"
|
|
|
+ ></v-text-field>
|
|
|
+ </v-label>
|
|
|
+
|
|
|
+ <v-label class="d-block pb-3">
|
|
|
+ <p class="pb-5 pe-3">工藝相關證照</p>
|
|
|
+ <v-text-field
|
|
|
+ v-model="resume.license"
|
|
|
+ density="compact"
|
|
|
+ variant="outlined"
|
|
|
+ ></v-text-field>
|
|
|
+ </v-label>
|
|
|
+
|
|
|
+ <v-label class="d-block">
|
|
|
+ <p class="d-flex">社群媒體</p>
|
|
|
+ <span class="d-block py-3 hint"
|
|
|
+ >工藝老師經營之網站或社群媒體,可貼網址</span
|
|
|
+ >
|
|
|
+ <v-text-field
|
|
|
+ v-model="resume.media"
|
|
|
+ density="compact"
|
|
|
+ variant="outlined"
|
|
|
+ ></v-text-field>
|
|
|
+ </v-label>
|
|
|
+ </v-col>
|
|
|
+
|
|
|
+ <v-col cols="6">
|
|
|
+ <v-label class="d-block">
|
|
|
+ <p class="d-flex">講師作品集</p>
|
|
|
+
|
|
|
+ <v-file-input
|
|
|
+ multiple
|
|
|
+ v-model="portfolioImg"
|
|
|
+ ref="portfolioImgRef"
|
|
|
+ label="File input"
|
|
|
+ variant="outlined"
|
|
|
+ placeholder="選擇相片上傳"
|
|
|
+ @change="handlePortfolioImg"
|
|
|
+ style="display: none"
|
|
|
+ ></v-file-input>
|
|
|
+ </v-label>
|
|
|
+
|
|
|
+ <v-btn
|
|
|
+ @click="fileInputClick('portfolio')"
|
|
|
+ color="purple"
|
|
|
+ class="my-5"
|
|
|
+ >選擇相片上傳</v-btn
|
|
|
+ >
|
|
|
+
|
|
|
+ <v-row class="img-list">
|
|
|
+ <v-col cols="4" v-for="(item, index) in 6" :key="index">
|
|
|
+ <div v-if="!portfolioImgList.length" class="item"></div>
|
|
|
+ <div
|
|
|
+ v-else
|
|
|
+ class="item"
|
|
|
+ :style="{
|
|
|
+ backgroundImage: `url('${portfolioImgList[index]}')`,
|
|
|
+ }"
|
|
|
+ ></div>
|
|
|
+ </v-col>
|
|
|
+ </v-row>
|
|
|
+
|
|
|
+ <!-- <div class="step-02 image-preview">
|
|
|
+ <img
|
|
|
+ v-if="selectedFile"
|
|
|
+ :src="selectedFileUrl"
|
|
|
+ alt="上傳圖片預覽"
|
|
|
+ />
|
|
|
+ </div> -->
|
|
|
+ </v-col>
|
|
|
+
|
|
|
+ <v-col cols="12">
|
|
|
+ <v-label class="d-block">
|
|
|
+ <p class="d-flex mb-5">老師自我介紹</p>
|
|
|
+ <v-textarea
|
|
|
+ v-model="resume.introduction"
|
|
|
+ rows="5"
|
|
|
+ variant="outlined"
|
|
|
+ ></v-textarea>
|
|
|
+ </v-label>
|
|
|
+ </v-col>
|
|
|
+ </v-row>
|
|
|
+ </v-card-text>
|
|
|
+ </v-window-item>
|
|
|
+
|
|
|
+ <v-window-item :value="3">
|
|
|
+ <v-card-text class="mb-7">
|
|
|
+ <v-row class="justify-space-evenly">
|
|
|
+ <v-col cols="12" md="5">
|
|
|
+ <v-label class="d-block pb-3">
|
|
|
+ <p class="pb-5 pe-3">課程名稱<span class="mark">*</span></p>
|
|
|
+ <v-text-field
|
|
|
+ v-model="course.name"
|
|
|
+ :rules="[requiredRule]"
|
|
|
+ density="compact"
|
|
|
+ variant="outlined"
|
|
|
+ ></v-text-field>
|
|
|
+ </v-label>
|
|
|
+ </v-col>
|
|
|
+
|
|
|
+ <!-- <v-col cols="12" md="5">
|
|
|
+ <v-label class="d-block pb-3">
|
|
|
+ <p class="pb-5 pe-3">課程價格<span class="mark">*</span></p>
|
|
|
+ <v-text-field
|
|
|
+ :rules="[requiredRule]"
|
|
|
+ density="compact"
|
|
|
+ variant="outlined"
|
|
|
+ ></v-text-field>
|
|
|
+ </v-label>
|
|
|
+ </v-col> -->
|
|
|
+
|
|
|
+ <v-col cols="12" md="5">
|
|
|
+ <v-label class="d-block pb-3">
|
|
|
+ <p class="pb-5 pe-3">工藝類別<span class="mark">*</span></p>
|
|
|
+ <v-select
|
|
|
+ v-model="course.category"
|
|
|
+ placeholder="請選擇類別"
|
|
|
+ :items="[
|
|
|
+ '樹藝',
|
|
|
+ '漆藝',
|
|
|
+ '藍染',
|
|
|
+ '蠟雕',
|
|
|
+ '竹工藝籃',
|
|
|
+ '金工/飾品',
|
|
|
+ '蠟燭/香氛/調香',
|
|
|
+ '植栽/花藝',
|
|
|
+ '插畫/繪畫/寫字',
|
|
|
+ '皮件/皮革',
|
|
|
+ '木工/竹藝',
|
|
|
+ '陶藝/玻璃',
|
|
|
+ '編織/羊毛氈/縫紉',
|
|
|
+ '其他',
|
|
|
+ ]"
|
|
|
+ :rules="[requiredRule]"
|
|
|
+ hide-details
|
|
|
+ density="compact"
|
|
|
+ variant="outlined"
|
|
|
+ ></v-select>
|
|
|
+ </v-label>
|
|
|
+ </v-col>
|
|
|
+
|
|
|
+ <!-- <v-col cols="12" md="5">
|
|
|
+ <v-label class="d-block pb-3">
|
|
|
+ <p class="pb-5 pe-3">
|
|
|
+ 適合報名對象(年紀)<span class="mark">*</span>
|
|
|
+ </p>
|
|
|
+
|
|
|
+ <v-select
|
|
|
+ v-model="age"
|
|
|
+ :items="[
|
|
|
+ '不拘',
|
|
|
+ '7 歲以下',
|
|
|
+ '7-18 歲',
|
|
|
+ '18-65 歲',
|
|
|
+ '65 歲以上',
|
|
|
+ ]"
|
|
|
+ :rules="[requiredRule]"
|
|
|
+ density="compact"
|
|
|
+ variant="outlined"
|
|
|
+ outlined
|
|
|
+ ></v-select>
|
|
|
+ </v-label>
|
|
|
+ </v-col> -->
|
|
|
+
|
|
|
+ <v-col cols="12" md="5">
|
|
|
+ <v-label class="d-block pb-3">
|
|
|
+ <p class="pb-5 pe-3">上課地點</p>
|
|
|
+ <v-text-field
|
|
|
+ v-model="location.address"
|
|
|
+ label="自動帶入據點地址"
|
|
|
+ density="compact"
|
|
|
+ variant="outlined"
|
|
|
+ ></v-text-field>
|
|
|
+ </v-label>
|
|
|
+ </v-col>
|
|
|
+
|
|
|
+ <v-col cols="12" md="5">
|
|
|
+ <v-label class="d-block pb-3">
|
|
|
+ <p class="pb-5 pe-3">主辦單位</p>
|
|
|
+ <v-text-field
|
|
|
+ v-model="location.location_name"
|
|
|
+ label="自動帶入據點名稱"
|
|
|
+ density="compact"
|
|
|
+ variant="outlined"
|
|
|
+ ></v-text-field>
|
|
|
+ </v-label>
|
|
|
+ </v-col>
|
|
|
+
|
|
|
+ <v-col cols="12" md="11" class="px-7">
|
|
|
+ <v-label class="d-block">
|
|
|
+ <p class="d-flex">課程時間<span class="mark">*</span></p>
|
|
|
+
|
|
|
+ <!-- <v-btn color="purple" class="my-5"
|
|
|
+ >
|
|
|
+ <v-icon icon="mdi-plus" class="me-1"></v-icon>
|
|
|
+ 建立新場次</v-btn
|
|
|
+ > -->
|
|
|
+
|
|
|
+ <v-dialog v-model="sessionsDialog" persistent width="800">
|
|
|
+ <template v-slot:activator="{ props }">
|
|
|
+ <v-btn class="my-5" color="purple" v-bind="props">
|
|
|
+ <v-icon icon="mdi-plus" class="me-1"></v-icon>
|
|
|
+ 建立新場次
|
|
|
+ </v-btn>
|
|
|
+ </template>
|
|
|
+ <v-card class="sessions-card pb-3">
|
|
|
+ <v-card-title>
|
|
|
+ <span class="d-block ps-10 py-5">建立新場次</span>
|
|
|
+ </v-card-title>
|
|
|
+ <v-card-text class="pt-0 px-8">
|
|
|
+ <v-container class="py-0">
|
|
|
+ <v-row>
|
|
|
+ <v-col cols="12" sm="6" class="date-item">
|
|
|
+ <p class="mb-0 pe-3">
|
|
|
+ 起始日期<span class="mark">*</span>
|
|
|
+ </p>
|
|
|
+ <VueDatePicker
|
|
|
+ v-model="date.start_date"
|
|
|
+ :min-date="new Date()"
|
|
|
+ :enable-time-picker="false"
|
|
|
+ :format="store.datePickerFormat"
|
|
|
+ locale="cn"
|
|
|
+ ></VueDatePicker>
|
|
|
+ </v-col>
|
|
|
+
|
|
|
+ <v-col cols="12" sm="6" class="date-item">
|
|
|
+ <p class="mb-0 pe-3">
|
|
|
+ 起始時間<span class="mark">*</span>
|
|
|
+ </p>
|
|
|
+ <VueDatePicker
|
|
|
+ v-model="date.start_time"
|
|
|
+ time-picker
|
|
|
+ />
|
|
|
+ </v-col>
|
|
|
+
|
|
|
+ <v-col cols="12" sm="6" class="date-item">
|
|
|
+ <p class="mb-0 pe-3">
|
|
|
+ 結束日期<span class="mark">*</span>
|
|
|
+ </p>
|
|
|
+ <VueDatePicker
|
|
|
+ v-model="date.end_date"
|
|
|
+ :min-date="new Date()"
|
|
|
+ :enable-time-picker="false"
|
|
|
+ :format="store.datePickerFormat"
|
|
|
+ locale="cn"
|
|
|
+ ></VueDatePicker>
|
|
|
+ </v-col>
|
|
|
+
|
|
|
+ <v-col cols="12" sm="6" class="date-item">
|
|
|
+ <p class="mb-0 pe-3">
|
|
|
+ 結束時間<span class="mark">*</span>
|
|
|
+ </p>
|
|
|
+ <VueDatePicker
|
|
|
+ v-model="date.end_time"
|
|
|
+ time-picker
|
|
|
+ />
|
|
|
+ </v-col>
|
|
|
+
|
|
|
+ <v-divider class="mt-5 mb-8"></v-divider>
|
|
|
+
|
|
|
+ <v-col cols="12" sm="6" class="py-0">
|
|
|
+ <v-label class="d-flex align-center py-2">
|
|
|
+ <p class="pb-5 pe-3">
|
|
|
+ 場次名稱<span class="mark">*</span>
|
|
|
+ </p>
|
|
|
+ <v-text-field
|
|
|
+ v-model="event.event"
|
|
|
+ :rules="[requiredRule]"
|
|
|
+ density="compact"
|
|
|
+ variant="outlined"
|
|
|
+ ></v-text-field>
|
|
|
+ </v-label>
|
|
|
+ </v-col>
|
|
|
+
|
|
|
+ <v-col cols="12" sm="6" class="py-0">
|
|
|
+ <v-label class="d-flex align-center py-2">
|
|
|
+ <p class="pb-5 pe-3">
|
|
|
+ 課程講師<span class="mark">*</span>
|
|
|
+ </p>
|
|
|
+ <v-text-field
|
|
|
+ v-model="event.lecturer"
|
|
|
+ :rules="[requiredRule]"
|
|
|
+ density="compact"
|
|
|
+ variant="outlined"
|
|
|
+ ></v-text-field>
|
|
|
+ </v-label>
|
|
|
+ </v-col>
|
|
|
+
|
|
|
+ <v-col cols="12" class="py-0">
|
|
|
+ <v-label class="d-flex align-center py-2">
|
|
|
+ <p class="pb-5 pe-3">
|
|
|
+ 聯絡資訊<span class="mark">*</span>
|
|
|
+ </p>
|
|
|
+ <v-text-field
|
|
|
+ v-model="event.contact"
|
|
|
+ :rules="[requiredRule]"
|
|
|
+ density="compact"
|
|
|
+ variant="outlined"
|
|
|
+ ></v-text-field>
|
|
|
+ </v-label>
|
|
|
+ </v-col>
|
|
|
+
|
|
|
+ <v-col cols="12" class="py-0">
|
|
|
+ <v-label class="d-flex align-center py-2">
|
|
|
+ <p class="pb-5 pe-3">
|
|
|
+ 收費方式<span class="mark">*</span>
|
|
|
+ </p>
|
|
|
+
|
|
|
+ <v-select
|
|
|
+ v-model="event.fee_payment"
|
|
|
+ :items="['現場收費', '匯款']"
|
|
|
+ :rules="[requiredRule]"
|
|
|
+ density="compact"
|
|
|
+ variant="outlined"
|
|
|
+ outlined
|
|
|
+ ></v-select>
|
|
|
+ </v-label>
|
|
|
+ </v-col>
|
|
|
+
|
|
|
+ <v-col cols="12" class="py-0">
|
|
|
+ <v-label
|
|
|
+ v-if="isRemit"
|
|
|
+ class="d-flex align-center py-2"
|
|
|
+ >
|
|
|
+ <p class="pb-5 pe-3">
|
|
|
+ 匯款資訊<span class="mark">*</span>
|
|
|
+ </p>
|
|
|
+
|
|
|
+ <div class="d-flex w-100">
|
|
|
+ <v-text-field
|
|
|
+ v-model="bankCode"
|
|
|
+ label="銀行代碼"
|
|
|
+ :rules="[requiredRule]"
|
|
|
+ density="compact"
|
|
|
+ variant="outlined"
|
|
|
+ style="width: 30%"
|
|
|
+ class="me-3"
|
|
|
+ ></v-text-field>
|
|
|
+ <v-text-field
|
|
|
+ v-model="bankAccount"
|
|
|
+ label="匯款帳號 (10-16 碼)"
|
|
|
+ :rules="[requiredRule]"
|
|
|
+ density="compact"
|
|
|
+ variant="outlined"
|
|
|
+ style="width: 70%"
|
|
|
+ ></v-text-field>
|
|
|
+ </div>
|
|
|
+ </v-label>
|
|
|
+ </v-col>
|
|
|
+
|
|
|
+ <v-col cols="12" sm="6" class="py-0">
|
|
|
+ <v-label class="d-flex align-center py-2">
|
|
|
+ <p class="pb-5 pe-3">
|
|
|
+ 課程價格<span class="mark">*</span>
|
|
|
+ </p>
|
|
|
+ <v-text-field
|
|
|
+ v-model="event.fee_method"
|
|
|
+ :rules="[requiredRule]"
|
|
|
+ density="compact"
|
|
|
+ variant="outlined"
|
|
|
+ ></v-text-field>
|
|
|
+ </v-label>
|
|
|
+ </v-col>
|
|
|
+
|
|
|
+ <v-col cols="12" sm="6" class="py-0">
|
|
|
+ <v-label class="d-flex align-center">
|
|
|
+ <p class="pb-3 pe-5">
|
|
|
+ 適合報名<br />對象<span class="mark pb-4"
|
|
|
+ >*</span
|
|
|
+ >
|
|
|
+ </p>
|
|
|
+ <v-select
|
|
|
+ v-model="event.people"
|
|
|
+ :items="[
|
|
|
+ '不拘',
|
|
|
+ '7 歲以下',
|
|
|
+ '7-18 歲',
|
|
|
+ '18-65 歲',
|
|
|
+ '65 歲以上',
|
|
|
+ ]"
|
|
|
+ :rules="[requiredRule]"
|
|
|
+ density="compact"
|
|
|
+ variant="outlined"
|
|
|
+ outlined
|
|
|
+ ></v-select>
|
|
|
+ <!-- <v-text-field
|
|
|
+ :rules="[requiredRule]"
|
|
|
+ density="compact"
|
|
|
+ variant="outlined"
|
|
|
+ ></v-text-field> -->
|
|
|
+ </v-label>
|
|
|
+ </v-col>
|
|
|
+
|
|
|
+ <v-col cols="12" class="py-0 position-relative">
|
|
|
+ <v-label class="d-flex align-center py-2">
|
|
|
+ <p class="pb-3 pe-3">
|
|
|
+ 課程類型<span class="mark pb-4">*</span>
|
|
|
+ </p>
|
|
|
+ <v-select
|
|
|
+ v-model="eventType"
|
|
|
+ :items="[
|
|
|
+ '一日課程(例:2023/10/2 週一上課)',
|
|
|
+ '週期課程(例:2023/10/1~2023/10/30 每週一三上課)',
|
|
|
+ ]"
|
|
|
+ :rules="[requiredRule]"
|
|
|
+ density="compact"
|
|
|
+ variant="outlined"
|
|
|
+ outlined
|
|
|
+ ></v-select>
|
|
|
+ </v-label>
|
|
|
+
|
|
|
+ <!-- <small
|
|
|
+ v-show="eventType !== ''"
|
|
|
+ class="type-hint"
|
|
|
+ >{{
|
|
|
+ isOneDay
|
|
|
+ ? "例:2023/10/2 週一上課"
|
|
|
+ : "例:2023/10/1~2023/10/30 每週一三上課"
|
|
|
+ }}</small
|
|
|
+ > -->
|
|
|
+ </v-col>
|
|
|
+
|
|
|
+ <v-col
|
|
|
+ v-if="!isOneDay"
|
|
|
+ cols="12"
|
|
|
+ class="d-flex py-0"
|
|
|
+ >
|
|
|
+ <p class="pt-1 pe-3">
|
|
|
+ 重複週期<span class="mark pb-4">*</span>
|
|
|
+ </p>
|
|
|
+
|
|
|
+ <ul class="d-flex week-list">
|
|
|
+ <li
|
|
|
+ v-for="(item, index) in weekList"
|
|
|
+ :key="index"
|
|
|
+ >
|
|
|
+ <button>
|
|
|
+ {{ item }}
|
|
|
+ </button>
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </v-col>
|
|
|
+
|
|
|
+ <v-col
|
|
|
+ v-if="!isOneDay"
|
|
|
+ cols="12"
|
|
|
+ class="time-item pt-5 pb-7"
|
|
|
+ >
|
|
|
+ <p class="mb-0">
|
|
|
+ 課程時間<span class="mark">*</span>
|
|
|
+ </p>
|
|
|
+ <div class="d-flex w-100">
|
|
|
+ <VueDatePicker
|
|
|
+ v-model="date.end_time"
|
|
|
+ time-picker
|
|
|
+ />
|
|
|
+ <span class="d-flex align-center mx-2">~</span>
|
|
|
+ <VueDatePicker
|
|
|
+ v-model="date.end_time"
|
|
|
+ time-picker
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </v-col>
|
|
|
+
|
|
|
+ <v-col cols="12" class="py-0">
|
|
|
+ <v-label class="d-flex align-center py-2">
|
|
|
+ <p class="pe-3">備註</p>
|
|
|
+ <v-text-field
|
|
|
+ v-model="event.remark"
|
|
|
+ density="compact"
|
|
|
+ variant="outlined"
|
|
|
+ hide-details
|
|
|
+ ></v-text-field>
|
|
|
+ </v-label>
|
|
|
+ </v-col>
|
|
|
+
|
|
|
+ <v-divider class="my-8"></v-divider>
|
|
|
+
|
|
|
+ <v-col cols="12" sm="6" class="date-item">
|
|
|
+ <p class="mb-0 pe-3">
|
|
|
+ 報名日期<span class="mark pb-4">*</span>
|
|
|
+ </p>
|
|
|
+ <VueDatePicker
|
|
|
+ v-model="date.registration_start_date"
|
|
|
+ :min-date="new Date()"
|
|
|
+ :enable-time-picker="false"
|
|
|
+ :format="store.datePickerFormat"
|
|
|
+ locale="cn"
|
|
|
+ ></VueDatePicker>
|
|
|
+ </v-col>
|
|
|
+
|
|
|
+ <v-col cols="12" sm="6" class="date-item">
|
|
|
+ <p class="mb-0 pe-3">
|
|
|
+ 報名時間<span class="mark pb-4">*</span>
|
|
|
+ </p>
|
|
|
+ <VueDatePicker
|
|
|
+ v-model="date.registration_start_time"
|
|
|
+ time-picker
|
|
|
+ />
|
|
|
+ </v-col>
|
|
|
+
|
|
|
+ <v-col cols="12" sm="6" class="date-item">
|
|
|
+ <p class="mb-0 pe-3">
|
|
|
+ 報名截止<span class="mark pb-4">*</span>
|
|
|
+ </p>
|
|
|
+ <VueDatePicker
|
|
|
+ v-model="date.registration_end_date"
|
|
|
+ :min-date="new Date()"
|
|
|
+ :enable-time-picker="false"
|
|
|
+ :format="store.datePickerFormat"
|
|
|
+ locale="cn"
|
|
|
+ ></VueDatePicker>
|
|
|
+ </v-col>
|
|
|
+
|
|
|
+ <v-col cols="12" sm="6" class="date-item">
|
|
|
+ <p class="mb-0 pe-3">
|
|
|
+ 截止時間<span class="mark pb-4">*</span>
|
|
|
+ </p>
|
|
|
+ <VueDatePicker
|
|
|
+ v-model="date.registration_end_time"
|
|
|
+ time-picker
|
|
|
+ />
|
|
|
+ </v-col>
|
|
|
+ </v-row>
|
|
|
+ </v-container>
|
|
|
+ </v-card-text>
|
|
|
+
|
|
|
+ <v-card-actions class="justify-center pt-10 pb-5">
|
|
|
+ <v-btn
|
|
|
+ color="gray"
|
|
|
+ variant="tonal"
|
|
|
+ class="me-3 px-10"
|
|
|
+ @click="sessionsDialog = false"
|
|
|
+ >
|
|
|
+ 取消
|
|
|
+ </v-btn>
|
|
|
+ <v-btn
|
|
|
+ color="purple"
|
|
|
+ variant="flat"
|
|
|
+ @click="addEventData()"
|
|
|
+ class="px-10"
|
|
|
+ >
|
|
|
+ 新增
|
|
|
+ </v-btn>
|
|
|
+ </v-card-actions>
|
|
|
+ </v-card>
|
|
|
+ </v-dialog>
|
|
|
+
|
|
|
+ <div v-if="eventData.list.length" class="main-table">
|
|
|
+ <h6 class="table-title">場次資訊</h6>
|
|
|
+ <table>
|
|
|
+ <thead>
|
|
|
+ <tr>
|
|
|
+ <th>名稱</th>
|
|
|
+ <th>日期</th>
|
|
|
+ <th width="20%">課程講師</th>
|
|
|
+ <th width="20%">收費方式</th>
|
|
|
+ </tr>
|
|
|
+ </thead>
|
|
|
+ <tbody>
|
|
|
+ <tr
|
|
|
+ v-for="(item, index) in eventData.list"
|
|
|
+ :key="index"
|
|
|
+ >
|
|
|
+ <td>{{ item.event }}</td>
|
|
|
+ <td>
|
|
|
+ {{
|
|
|
+ moment(`${item.start_time}`).format("YYYY/MM/DD")
|
|
|
+ }}
|
|
|
+ <br />
|
|
|
+ ~
|
|
|
+ <br />
|
|
|
+ {{
|
|
|
+ moment(`${item.end_time}`).format("YYYY/MM/DD")
|
|
|
+ }}
|
|
|
+ </td>
|
|
|
+ <td>{{ item.lecturer }}</td>
|
|
|
+ <td>{{ item.fee_method }}</td>
|
|
|
+ </tr>
|
|
|
+ </tbody>
|
|
|
+ </table>
|
|
|
+ </div>
|
|
|
+ </v-label>
|
|
|
+ </v-col>
|
|
|
+
|
|
|
+ <v-col cols="12" md="11" class="px-7">
|
|
|
+ <v-label class="d-block">
|
|
|
+ <p class="d-flex">課程簡介<span class="mark">*</span></p>
|
|
|
+ <small class="d-block text-gray my-2"
|
|
|
+ >內容不得少於 100 字元,且不得含有工藝無關之資訊</small
|
|
|
+ >
|
|
|
+ <v-textarea
|
|
|
+ v-model="course.introduction"
|
|
|
+ rows="5"
|
|
|
+ variant="outlined"
|
|
|
+ ></v-textarea>
|
|
|
+ </v-label>
|
|
|
+ </v-col>
|
|
|
+
|
|
|
+ <v-col cols="12" md="6" class="me-auto ms-3 ps-16">
|
|
|
+ <v-label class="d-block">
|
|
|
+ <p class="d-flex">上傳課程封面<span class="mark">*</span></p>
|
|
|
+
|
|
|
+ <v-file-input
|
|
|
+ multiple
|
|
|
+ v-model="coverImg"
|
|
|
+ ref="coverImgRef"
|
|
|
+ label="File input"
|
|
|
+ variant="outlined"
|
|
|
+ placeholder="選擇相片上傳"
|
|
|
+ @change="handleCoverImg"
|
|
|
+ style="display: none"
|
|
|
+ ></v-file-input>
|
|
|
+ </v-label>
|
|
|
+
|
|
|
+ <v-btn
|
|
|
+ @click="fileInputClick('cover')"
|
|
|
+ color="purple"
|
|
|
+ class="my-5"
|
|
|
+ >選擇相片上傳</v-btn
|
|
|
+ >
|
|
|
+
|
|
|
+ <div class="step-01 image-preview">
|
|
|
+ <img v-if="coverImg" :src="coverImgUrl" alt="上傳圖片預覽" />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- <v-row class="img-list">
|
|
|
+ <v-col cols="4" v-for="(item, index) in 6" :key="index">
|
|
|
+ <div v-if="!portfolioImgList.length" class="item"></div>
|
|
|
+ <div
|
|
|
+ v-else
|
|
|
+ class="item"
|
|
|
+ :style="{
|
|
|
+ backgroundImage: `url('${portfolioImgList[index]}')`,
|
|
|
+ }"
|
|
|
+ ></div>
|
|
|
+ </v-col>
|
|
|
+ </v-row> -->
|
|
|
+ </v-col>
|
|
|
+ </v-row>
|
|
|
+ </v-card-text>
|
|
|
+ </v-window-item>
|
|
|
+
|
|
|
+ <v-window-item :value="4">
|
|
|
+ <v-card-text class="mb-7 finish-step">
|
|
|
+ <p>
|
|
|
+ 請等待後台人員確認您的課程資訊 <br />
|
|
|
+ 待您收到開課完成的 Email <br />
|
|
|
+ 就可以前往
|
|
|
+ <router-link to="/user/courses">【我的開課】</router-link>
|
|
|
+ 觀看及修改您的
|
|
|
+ </p>
|
|
|
+ <ul>
|
|
|
+ <li>(1) 據點資訊</li>
|
|
|
+ <li>(2) 工藝家履歷</li>
|
|
|
+ <li>(3) 課程清單</li>
|
|
|
+ </ul>
|
|
|
+ </v-card-text>
|
|
|
+ </v-window-item>
|
|
|
+ </v-window>
|
|
|
+
|
|
|
+ <v-divider></v-divider>
|
|
|
+
|
|
|
+ <v-card-actions class="justify-center mt-7">
|
|
|
+ <v-btn
|
|
|
+ v-if="step > 1 && step !== 4"
|
|
|
+ color="gray"
|
|
|
+ variant="outlined"
|
|
|
+ @click="step--"
|
|
|
+ class="px-7 me-2"
|
|
|
+ >
|
|
|
+ 上一步
|
|
|
+ </v-btn>
|
|
|
+ <v-spacer></v-spacer>
|
|
|
+ <v-btn
|
|
|
+ v-if="step < 3"
|
|
|
+ color="purple"
|
|
|
+ variant="flat"
|
|
|
+ @click="step++"
|
|
|
+ class="px-7"
|
|
|
+ >
|
|
|
+ 下一步
|
|
|
+ </v-btn>
|
|
|
+ <v-btn
|
|
|
+ v-if="step === 3"
|
|
|
+ color="purple"
|
|
|
+ variant="flat"
|
|
|
+ @click="create()"
|
|
|
+ :loading="loading"
|
|
|
+ class="px-7"
|
|
|
+ >
|
|
|
+ 創建
|
|
|
+ </v-btn>
|
|
|
+ <v-btn v-if="step === 4" color="purple" variant="outlined" class="me-3">
|
|
|
+ <router-link to="/" class="px-7">回到首頁</router-link>
|
|
|
+ </v-btn>
|
|
|
+ <v-btn v-if="step === 4" color="purple" variant="flat">
|
|
|
+ <router-link to="/user/courses" class="px-7"
|
|
|
+ >前往開課專區</router-link
|
|
|
+ >
|
|
|
+ </v-btn>
|
|
|
+ </v-card-actions>
|
|
|
+ </v-card>
|
|
|
+ </v-container>
|
|
|
+</template>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.step-title {
|
|
|
+ text-align: center;
|
|
|
+ h5 {
|
|
|
+ font-size: 28px;
|
|
|
+ font-weight: 500;
|
|
|
+ letter-spacing: 2px;
|
|
|
+ }
|
|
|
+ p {
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: 400;
|
|
|
+ letter-spacing: 1px;
|
|
|
+ color: #919191;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.step-01 {
|
|
|
+ &.image-preview {
|
|
|
+ height: 285px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.step-02 {
|
|
|
+ &.image-preview {
|
|
|
+ height: 235px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.image-preview {
|
|
|
+ img {
|
|
|
+ height: 100%;
|
|
|
+ object-fit: contain;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.flex-grow-1 {
|
|
|
+ display: none !important;
|
|
|
+}
|
|
|
+
|
|
|
+.img-list {
|
|
|
+ .item {
|
|
|
+ height: 105px;
|
|
|
+ border-radius: 5px;
|
|
|
+ background-color: #ccc; // 預設灰底
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ background-position: center;
|
|
|
+ background-size: cover;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.sessions-card {
|
|
|
+ border-radius: 30px 5px 5px 30px !important;
|
|
|
+
|
|
|
+ .v-label {
|
|
|
+ p {
|
|
|
+ width: 95px;
|
|
|
+ text-align: end;
|
|
|
+ line-height: 22px;
|
|
|
+ @media (max-width: 600px) {
|
|
|
+ width: 123px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.date-item {
|
|
|
+ display: flex;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ p {
|
|
|
+ width: 114px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: end;
|
|
|
+ white-space: nowrap;
|
|
|
+ line-height: 22px;
|
|
|
+ @media (max-width: 600px) {
|
|
|
+ width: 125px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.main-table {
|
|
|
+ margin: 50px 0;
|
|
|
+ .table-title {
|
|
|
+ background-color: var(--purple);
|
|
|
+ }
|
|
|
+
|
|
|
+ table {
|
|
|
+ thead {
|
|
|
+ border-bottom: 2px solid var(--purple);
|
|
|
+ }
|
|
|
+ tbody {
|
|
|
+ td {
|
|
|
+ border-bottom: 1px solid var(--purple);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.finish-step {
|
|
|
+ line-height: 50px;
|
|
|
+ font-size: 22px;
|
|
|
+ text-align: center;
|
|
|
+ letter-spacing: 1px;
|
|
|
+}
|
|
|
+
|
|
|
+.type-hint {
|
|
|
+ width: 100%;
|
|
|
+ display: block;
|
|
|
+ position: absolute;
|
|
|
+ bottom: 1px;
|
|
|
+ left: 105px;
|
|
|
+ color: var(--gray);
|
|
|
+}
|
|
|
+
|
|
|
+.week-list {
|
|
|
+ height: 70%;
|
|
|
+ align-items: center;
|
|
|
+ li {
|
|
|
+ margin: 0 5px;
|
|
|
+ button {
|
|
|
+ color: var(--purple);
|
|
|
+ padding: 10px;
|
|
|
+ border-radius: 100px;
|
|
|
+ border: 1px solid var(--purple);
|
|
|
+ transition: all 0.3s;
|
|
|
+ &:hover {
|
|
|
+ color: #fff;
|
|
|
+ background-color: var(--purple);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.time-item {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ p {
|
|
|
+ width: 97px;
|
|
|
+ flex-wrap: nowrap;
|
|
|
+ display: flex;
|
|
|
+ white-space: nowrap;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|