Java道經 - 項目 - MyLesson - 后臺前端(四)
傳送門:JP4-7-MyLesson后臺前端(一)
傳送門:JP4-7-MyLesson后臺前端(二)
傳送門:JP4-7-MyLesson后臺前端(三)
傳送門:JP4-7-MyLesson后臺前端(四)
傳送門:JP4-7-MyLesson后臺前端(五)
文章目錄
- S05. SMS營銷服務
- E01. 通知管理模塊
- 1. 查看通知列表
- 2. 添加通知記錄
- 3. 修改通知記錄
- E02. 橫幅管理模塊
- 1. 查看橫幅列表
- 2. 添加橫幅記錄
- 3. 修改橫幅記錄
- E03. 新聞管理模塊
- 1. 查看新聞列表
- 2. 添加新聞記錄
- 3. 修改新聞記錄
- E04. 秒殺管理模塊
- 1. 查看秒殺列表
- 2. 添加秒殺記錄
- 3. 修改秒殺記錄
- 4. 查看秒殺詳情
- 5. 添加秒殺詳情
- 6. 修改秒殺詳情
- E05. 優惠卷管理模塊
- 1. 查看優惠卷列表
- 2. 添加優惠卷記錄
- 3. 修改優惠卷記錄
S05. SMS營銷服務
武技:搭建起始文件環境和對應的路由代碼。
- 創建全部相關 Vue 頁面,結構如下:
|__ views|__ sms|__ notice|__ Notice.vue|__ NoticeInsert.vue|__ NoticeUpdate.vue|__ article|__ Article.vue|__ ArticleInsert.vue|__ ArticleUpdate.vue|__ banner|__ Banner.vue|__ BannerInsert.vue|__ BannerUpdate.vue|__ seckill|__ Seckill.vue|__ SeckillInsert.vue|__ SeckillUpdate.vue|__ detail|__ SeckillDetail.vue|__ SeckillDetailInsert.vue|__ SeckillDetailUpdate.vue|__ coupons|__ Coupons.vue|__ CouponsInsert.vue|__ CouponsUpdate.vue
- 在 router/index.js 文件中開發全部相關頁面路由配置
import Notice from "../views/sms/notice/Notice.vue";
import NoticeInsert from "../views/sms/notice/NoticeInsert.vue";
import NoticeUpdate from "../views/sms/notice/NoticeUpdate.vue";
import Article from "../views/sms/article/Article.vue";
import ArticleInsert from "../views/sms/article/ArticleInsert.vue";
import ArticleUpdate from "../views/sms/article/ArticleUpdate.vue";
import Banner from "../views/sms/banner/Banner.vue";
import BannerInsert from "../views/sms/banner/BannerInsert.vue";
import BannerUpdate from "../views/sms/banner/BannerUpdate.vue";
import Seckill from "../views/sms/seckill/Seckill.vue";
import SeckillInsert from "../views/sms/seckill/SeckillInsert.vue";
import SeckillUpdate from "../views/sms/seckill/SeckillUpdate.vue";
import SeckillDetail from "../views/sms/seckill/detail/SeckillDetail.vue";
import SeckillDetailInsert from "../views/sms/seckill/detail/SeckillDetailInsert.vue";
import SeckillDetailUpdate from "../views/sms/seckill/detail/SeckillDetailUpdate.vue";
import Coupons from "../views/sms/coupons/Coupons.vue";
import CouponsInsert from "../views/sms/coupons/CouponsInsert.vue";
import CouponsUpdate from "../views/sms/coupons/CouponsUpdate.vue";const router = createRouter({history: createWebHashHistory(),routes: [{path: '/', name: 'Login', component: Login},{path: '/Main', name: 'Main', component: Main,redirect: '/Dashboard',children: [...{path: '/Notice', name: 'Notice', component: Notice},{path: '/NoticeInsert', name: 'NoticeInsert', component: NoticeInsert},{path: '/NoticeUpdate', name: 'NoticeUpdate', component: NoticeUpdate},{path: '/Article', name: 'Article', component: Article},{path: '/ArticleInsert', name: 'ArticleInsert', component: ArticleInsert},{path: '/ArticleUpdate', name: 'ArticleUpdate', component: ArticleUpdate},{path: '/Banner', name: 'Banner', component: Banner},{path: '/BannerInsert', name: 'BannerInsert', component: BannerInsert},{path: '/BannerUpdate', name: 'BannerUpdate', component: BannerUpdate},{path: '/Seckill', name: 'Seckill', component: Seckill},{path: '/SeckillInsert', name: 'SeckillInsert', component: SeckillInsert},{path: '/SeckillUpdate', name: 'SeckillUpdate', component: SeckillUpdate},{path: '/SeckillDetail', name: 'SeckillDetail', component: SeckillDetail},{path: '/SeckillDetailInsert', name: 'SeckillDetailInsert', component: SeckillDetailInsert},{path: '/SeckillDetailUpdate', name: 'SeckillDetailUpdate', component: SeckillDetailUpdate},{path: '/Coupons', name: 'Coupons', component: Coupons},{path: '/CouponsInsert', name: 'CouponsInsert', component: CouponsInsert},{path: '/CouponsUpdate', name: 'CouponsUpdate', component: CouponsUpdate},]}]
});
E01. 通知管理模塊
1. 查看通知列表
心法:查看通知列表頁面
武技:開發查看通知列表頁面 views/sms/notice/Notice.vue
<script setup>
import MyNav from "../../../components/MyNav.vue";
import MyTable from "../../../components/MyTable.vue";
import {onMounted, reactive, ref} from "vue";
import {deleteApi, deleteBatchApi, pageApi} from "../../../api/index.js";
import {myPage} from "../../../request/index.js";// 路徑導航
const navItems = [{icon: 'Goods', label: '營銷管理'},{icon: 'Opportunity', label: '通知列表'},
];
// 表格列
const columns = [{label: '序號', prop: 'idx', type: 'tag', width: 65},{label: '通知內容', prop: 'content', type: 'card', width: 500, tooltip: false},
];
// 表格數據 + 分頁數據
let records = ref();
let pageInfo = reactive({pageNum: 1, pageSize: 5, callback: page});/*** 分頁查詢** 1. 定義分頁基礎配置,包括 records, pageInfo, api, params 等。* 2. 異步發送分頁查詢請求。** @param pageNum 當前第幾頁,默認 1* @param pageSize 每頁多少條,默認 5*/
async function page(pageNum = pageInfo['pageNum'], pageSize = pageInfo['pageSize']) {let config = {api: pageApi,args: {module: 'notice'},params: {pageNum, pageSize},records, pageInfo,}await myPage(config);
}/* ==================== 加載函數 ==================== */onMounted(() => page());</script><template v-if="records"><my-nav :items="navItems"/><div style="height: 60px"/><my-table module="notice"insert-page="/NoticeInsert"update-page="/NoticeUpdate":delete-api="deleteApi":delete-batch-api="deleteBatchApi":delete-callback="page":records="records":columns="columns":page-info="pageInfo"/>
</template><style scoped lang="scss"></style>
2. 添加通知記錄
心法:添加通知記錄頁面
武技:開發添加通知記錄頁面 views/sms/notice/NoticeInsert.vue
<script setup>
import MyNav from "../../../components/MyNav.vue";
import MyForm from "../../../components/MyForm.vue";
import {reactive, ref} from "vue";
import {insertApi} from "../../../api/index.js";
import {RULE} from "../../../const/index.js";
import {ElMessage} from "element-plus";
import router from "../../../router/index.js";// 路徑導航
const navItems = [{icon: 'Goods', label: '營銷管理'},{icon: 'Opportunity', label: '通知列表', url: '/Notice'},{icon: 'Plus', label: '添加通知'},
];/* ==================== 添加表單 ==================== */// 表單項 + 表單值 + 表單規則
let items = ref([{label: '排序', prop: 'idx', type: 'number', min: 1, required: true, span: 12},{label: '內容', prop: 'content', required: true, type: 'textarea'},
]);
let params = reactive({});
let rules = {content: RULE.CONTENT};/* ==================== 添加成功后 ==================== */function insertSuccess() {ElMessage.success('添加記錄成功!');setTimeout(() => router.push('/Notice'), 1000);
}</script><template><my-nav :items="navItems"/><el-card class="notice-insert-card" header="添加通知"><my-form type="insert":items="items":rules="rules":params="params":api="insertApi":args="{module: 'notice'}":callback="insertSuccess"/></el-card>
</template><style scoped lang="scss">
.notice-insert-card {width: 60%; // 寬度margin: 65px auto 0; // 外邊距
}
</style>
3. 修改通知記錄
心法:修改通知記錄頁面
武技:開發修改通知記錄頁面 views/sms/notice/NoticeUpdate.vue
<script setup>
import MyNav from "../../../components/MyNav.vue";
import MyForm from "../../../components/MyForm.vue";
import {reactive, ref} from "vue";
import {updateApi} from "../../../api/index.js";
import {RULE} from "../../../const/index.js";
import {ElMessage} from "element-plus";
import router from "../../../router/index.js";// 獲取當前通知記錄
let notice = JSON.parse(sessionStorage.getItem('row'));
// 路徑導航
const navItems = [{icon: 'Goods', label: '營銷管理'},{icon: 'Opportunity', label: '通知列表', url: '/Notice'},{icon: 'Edit', label: '修改通知'},
];
// 表單項 + 表單值 + 表單規則
let items = ref([{label: '通知排序', prop: 'idx', type: 'number', min: 1, required: true, span: 12},{label: '通知內容', prop: 'content', required: true, type: 'textarea'},
]);
let params = reactive(notice);
let rules = {content: RULE.CONTENT};/* ==================== 修改成功后 ==================== */function updateSuccess() {ElMessage.success('修改記錄成功!');setTimeout(() => router.push('/Notice'), 1000);
}
</script><template><my-nav :items="navItems"/><el-card class="notice-update-card" header="修改通知信息"><my-form type="update":items="items":rules="rules":params="params":api="updateApi":args="{module: 'notice'}":callback="updateSuccess"/></el-card>
</template><style scoped lang="scss">
.notice-update-card {width: 60%; // 寬度margin: 65px auto 0; // 外邊距
}
</style>
E02. 橫幅管理模塊
1. 查看橫幅列表
心法:查看橫幅列表頁面
武技:開發查看橫幅列表頁面 views/sms/banner/Banner.vue
<script setup>
import MyNav from "../../../components/MyNav.vue";
import MyTable from "../../../components/MyTable.vue";
import {onMounted, reactive, ref} from "vue";
import {deleteApi, deleteBatchApi, pageApi} from "../../../api/index.js";
import {myPage} from "../../../request/index.js";
import {MINIO_BANNER} from "../../../const/index.js";// 路徑導航
const navItems = [{icon: 'Goods', label: '營銷管理'},{icon: 'Picture', label: '橫幅列表'},
];
// 表格列
const columns = [{label: '序號', prop: 'idx', type: 'tag', width: 70},{label: '橫幅圖片', prop: 'url', type: 'img', width: 100, minio: MINIO_BANNER},{label: '橫幅描述', prop: 'info', type: 'card', width: 800},
];/* ==================== 分頁查詢 ==================== */// 表格數據 + 分頁數據
let records = ref();
let pageInfo = reactive({pageNum: 1, pageSize: 5, callback: page});/*** 分頁查詢** 1. 定義分頁基礎配置,包括 records, pageInfo, api, params 等。* 2. 附加分頁查詢條件,如標題等。* 3. 異步發送分頁查詢請求。** @param pageNum 當前第幾頁,默認 1* @param pageSize 每頁多少條,默認 5*/
async function page(pageNum = pageInfo['pageNum'], pageSize = pageInfo['pageSize']) {let config = {api: pageApi,args: {module: 'banner'},params: {pageNum, pageSize},records, pageInfo,}await myPage(config);
}/* ==================== 加載函數 ==================== */onMounted(() => page());</script><template v-if="records"><my-nav :items="navItems"/><div style="height: 60px"/><my-table module="banner"insert-page="/BannerInsert"update-page="/BannerUpdate":records="records":columns="columns":delete-api="deleteApi":delete-batch-api="deleteBatchApi":delete-callback="page":page-info="pageInfo"/>
</template><style scoped lang="scss"></style>
2. 添加橫幅記錄
心法:添加橫幅記錄頁面
武技:開發添加橫幅記錄頁面 views/sms/banner/BannerInsert.vue
<script setup>
import MyNav from "../../../components/MyNav.vue";
import MyForm from "../../../components/MyForm.vue";
import {reactive, ref} from "vue";
import {insertApi} from "../../../api/index.js";
import {RULE} from "../../../const/index.js";
import router from "../../../router/index.js";
import {ElMessage} from "element-plus";// 路徑導航
const navItems = [{icon: 'Goods', label: '營銷管理'},{icon: 'Picture', label: '橫幅列表', url: '/Banner'},{icon: 'Plus', label: '添加橫幅'},
];
// 表單項 + 表單值 + 表單規則
let items = ref([{label: '橫幅排序', prop: 'idx', type: 'number', min: 1, required: true, span: 12},{label: '橫幅描述', prop: 'info', required: true, type: 'textarea'},
]);
let params = reactive({});
let rules = {info: RULE.INFO};/* ==================== 添加成功后 ==================== */function insertSuccess() {ElMessage.success('添加成功!');setTimeout(() => router.push('/Banner'), 1000);
}
</script><template><my-nav :items="navItems"/><el-card class="banner-insert-card" header="添加橫幅"><my-form type="insert":items="items":params="params":rules="rules":api="insertApi":args="{module: 'banner'}":callback="insertSuccess"/></el-card>
</template><style scoped lang="scss">
.banner-insert-card {width: 60%; // 寬度margin: 65px auto 0; // 外邊距
}
</style>
3. 修改橫幅記錄
心法:修改橫幅記錄頁面
武技:開發修改橫幅記錄頁面 views/sms/banner/BannerUpdate.vue
<script setup>
import MyNav from "../../../components/MyNav.vue";
import MyForm from "../../../components/MyForm.vue";
import MyUpload from "../../../components/MyUpload.vue";
import {MINIO_BANNER, MINIO_COURSE_SUMMARY, RULE} from "../../../const/index.js";
import {reactive, ref} from "vue";
import {updateApi} from "../../../api/index.js";
import {UPLOAD_BANNER_URL} from "../../../api/sms/banner.js";
import {ElMessage} from "element-plus";
import router from "../../../router/index.js";// 獲取當前橫幅記錄
let banner = JSON.parse(sessionStorage.getItem('row'));
let bannerUrl = ref(MINIO_BANNER(banner['url']));
// 路徑導航
const navItems = [{icon: 'Goods', label: '營銷管理'},{icon: 'Picture', label: '橫幅列表', url: '/Banner'},{icon: 'Edit', label: '修改橫幅信息'},
];
// 表單項 + 表單值 + 表單規則
let updateFormItems = ref([{label: '橫幅排序', prop: 'idx', type: 'number', min: 1, required: true, span: 12},{label: '橫幅描述', prop: 'info', required: true, type: 'textarea', rows: 18},
]);
let updateFormParams = reactive(banner);
let updateFormRules = {info: RULE.INFO,};/* ==================== 修改成功后 ==================== */function updateSuccess() {ElMessage.success('修改記錄成功!');setTimeout(() => router.push('/Banner'), 1000);
}/* ==================== 上傳成功后 ==================== */function uploadSuccess(data) {bannerUrl.value = MINIO_BANNER(data);
}
</script><template><my-nav :items="navItems"/><div class="banner-update-body"><el-row :gutter="20"><el-col :span="8"><el-card class="banner-info-card"><el-image class="banner-image" :src="bannerUrl"/></el-card><el-card class="upload-banner-card" header="上傳輪播圖片"><my-upload name="bannerFile":url="UPLOAD_BANNER_URL + '/' +banner['id']":autoUpload="true":callback="uploadSuccess"/></el-card></el-col><el-col :span="16"><el-card class="update-card" header="修改基本信息"><my-form type="update":items="updateFormItems":rules="updateFormRules":params="updateFormParams":api="updateApi":args="{module: 'banner'}":callback="updateSuccess"/></el-card></el-col></el-row></div>
</template><style scoped lang="scss">
.banner-update-body {width: 90%; // 寬度margin: 65px auto 0; // 外邊距.banner-info-card {text-align: center; // 內容居中.banner-image {height: 170px; // 高度}}.upload-banner-card {margin-top: 18px; // 上外邊距}
}
</style>
E03. 新聞管理模塊
1. 查看新聞列表
心法:查看新聞列表頁面
武技:開發查看新聞列表頁面 views/sms/article/Article.vue
<script setup>
import MyNav from "../../../components/MyNav.vue";
import MyHead from "../../../components/MyHead.vue";
import MyTable from "../../../components/MyTable.vue";
import {onMounted, reactive, ref} from "vue";
import {deleteApi, deleteBatchApi, pageApi} from "../../../api/index.js";
import {myPage} from "../../../request/index.js";
import {isNotEmpty, isNotNull} from "../../../util/index.js";// 路徑導航
const navItems = [{icon: 'Goods', label: '營銷管理'},{icon: 'WindPower', label: '新聞列表'},
];
// 數據頭
const headItems = [{type: 'ipt', span: 5, placeholder: '按標題搜索', callback: pageLikeTitle},
];
// 表格列
const columns = [{label: '序號', prop: 'idx', type: 'tag', width: 70},{label: '標題', prop: 'title', width: 300},{label: '內容', prop: 'content', type: 'card', width: 500, tooltip: false},
];/* ==================== 分頁查詢 ==================== */// 表格行 + 分頁 + 新聞標題
let records = ref();
let pageInfo = reactive({pageNum: 1, pageSize: 5, callback: page});
let title = ref();/*** 分頁查詢** 1. 定義分頁基礎配置,包括 records, pageInfo, api, params 等。* 2. 附加分頁查詢條件,如標題等。* 3. 異步發送分頁查詢請求。** @param pageNum 當前第幾頁,默認 1* @param pageSize 每頁多少條,默認 5*/
async function page(pageNum = pageInfo['pageNum'], pageSize = pageInfo['pageSize']) {let config = {api: pageApi,args: {module: 'article'},params: {pageNum, pageSize},records, pageInfo,}if (isNotEmpty(title.value)) config['params']['title'] = title.value;await myPage(config);
}/* ==================== 搜索新聞標題 ==================== *//*** 按新聞標題模糊查詢** 1. 將輸入框中的值賦值給分頁條件字段變量。* 2. 重新發送分頁請求。** @param val 輸入框中的值*/
function pageLikeTitle(val) {if (isNotNull(val) || title.value) {title.value = val;page();}
}/* ==================== 加載函數 ==================== */onMounted(() => page());
</script><template v-if="records"><my-nav :items="navItems"/><my-head :items="headItems"/><my-table module="article"insert-page="/ArticleInsert"update-page="/ArticleUpdate":delete-api="deleteApi":delete-batch-api="deleteBatchApi":delete-callback="page":records="records":columns="columns":page-info="pageInfo"/>
</template><style scoped lang="scss"></style>
2. 添加新聞記錄
心法:添加新聞記錄頁面
武技:開發添加新聞記錄頁面 views/sms/article/ArticleInsert.vue
<script setup>
import MyNav from "../../../components/MyNav.vue";
import MyForm from "../../../components/MyForm.vue";
import {reactive, ref} from "vue";
import {insertApi} from "../../../api/index.js";
import {RULE} from "../../../const/index.js";
import router from "../../../router/index.js";
import {ElMessage} from "element-plus";// 路徑導航
const navItems = [{icon: 'Goods', label: '營銷管理'},{icon: 'WindPower', label: '新聞列表', url: '/Article'},{icon: 'Plus', label: '添加新聞'},
];
// 表單項 + 表單值 + 表單規則
let items = ref([{label: '排序', prop: 'idx', type: 'number', min: 1, required: true, span: 12},{hidden: true, span: 12},{label: '標題', prop: 'title', required: true, type: 'textarea', rows: 3},{label: '內容', prop: 'content', required: true, type: 'textarea'},
]);
let params = reactive({});
let rules = {content: RULE.CONTENT};/* ==================== 添加成功后 ==================== */function insertSuccess() {ElMessage.success('添加成功!');setTimeout(() => router.push('/Article'), 1000);
}</script><template><my-nav :items="navItems"/><el-card class="article-insert-card" header="添加新聞"><my-form type="insert":items="items":rules="rules":params="params":api="insertApi":args="{module: 'article'}":callback="insertSuccess"/></el-card>
</template><style scoped lang="scss">
.article-insert-card {width: 60%; // 寬度margin: 65px auto 0; // 外邊距
}
</style>
3. 修改新聞記錄
心法:修改新聞記錄頁面
武技:開發修改新聞記錄頁面 views/sms/article/ArticleUpdate.vue
<script setup>
import MyNav from "../../../components/MyNav.vue";
import MyForm from "../../../components/MyForm.vue";
import {reactive, ref} from "vue";
import {updateApi} from "../../../api/index.js";
import {RULE} from "../../../const/index.js";
import {ElMessage} from "element-plus";
import router from "../../../router/index.js";// 獲取當前新聞記錄
let article = JSON.parse(sessionStorage.getItem('row'));
// 路徑導航
const navItems = [{icon: 'Goods', label: '營銷管理'},{icon: 'WindPower', label: '新聞列表', url: '/Article'},{icon: 'Edit', label: '修改新聞'},
];
// 表單項 + 表單值 + 表單規則
let items = ref([{label: '排序', prop: 'idx', type: 'number', min: 1, required: true, span: 12},{hidden: true, span: 12},{label: '標題', prop: 'title', required: true, type: 'textarea', rows: 3},{label: '內容', prop: 'content', required: true, type: 'textarea'},
]);
let params = reactive(article);
let rules = {content: RULE.INFO};/* ==================== 修改成功后 ==================== */function updateSuccess() {ElMessage.success('修改記錄成功!');setTimeout(() => router.push('/Article'), 1000);
}
</script><template><my-nav :items="navItems"/><el-card class="article-update-card" header="修改新聞信息"><my-form type="update":items="items":params="params":rules="rules":api="updateApi":args="{module: 'article'}":callback="updateSuccess"/></el-card>
</template><style scoped lang="scss">
.article-update-card {width: 60%; // 寬度margin: 65px auto 0; // 外邊距
}
</style>
E04. 秒殺管理模塊
1. 查看秒殺列表
心法:查看秒殺列表頁面
武技:開發查看秒殺列表頁面 views/sms/seckill/Seckill.vue
<script setup>
import MyNav from "../../../components/MyNav.vue";
import MyHead from "../../../components/MyHead.vue";
import MyTable from "../../../components/MyTable.vue";
import {onMounted, reactive, ref} from "vue";
import {deleteApi, deleteBatchApi, pageApi} from "../../../api/index.js";
import {myPage} from "../../../request/index.js";
import {dateFormat, isNotEmpty, isNotNull, seckillStatusFormat} from "../../../util/index.js";
import router from "../../../router/index.js";// 路徑導航
const navItems = [{icon: 'Goods', label: '營銷管理'},{icon: 'Stopwatch', label: '秒殺列表'},
];
// 數據頭
const headItems = [{type: 'ipt', span: 5, placeholder: '按標題搜索', callback: pageLikeTitle},
];
// 表格列
const columns = [{label: '活動標題', prop: 'title', width: 120},{label: '開始時間', prop: 'startTime', format: dateFormat},{label: '結束時間', prop: 'endTime', format: dateFormat},{label: '活動狀態', prop: 'status', type: 'tag', format: seckillStatusFormat},{label: '活動描述', prop: 'info', type: 'card', tooltip: false},
];
// 按鈕列
const buttons = [{label: '秒殺詳情', type: 'success', callback: seckillDetail},
];
// 表格數據 + 分頁數據 + 秒殺活動標題
let records = ref();
let pageInfo = reactive({pageNum: 1, pageSize: 5, callback: page});
let title = ref();/*** 分頁查詢** 1. 定義分頁基礎配置,包括 records, pageInfo, api, params 等。* 2. 附加分頁查詢條件,如標題等。* 3. 異步發送分頁查詢請求。** @param pageNum 當前第幾頁,默認 1* @param pageSize 每頁多少條,默認 5*/
async function page(pageNum = pageInfo['pageNum'], pageSize = pageInfo['pageSize']) {let config = {api: pageApi,args: {module: 'seckill'},params: {pageNum, pageSize},records, pageInfo,}if (isNotEmpty(title.value)) config['params']['title'] = title.value;await myPage(config);
}/* ==================== 搜索秒殺標題 ==================== *//*** 按秒殺標題模糊查詢** 1. 將輸入框中的值賦值給分頁條件字段變量。* 2. 重新發送分頁請求。** @param val 輸入框中的值*/
function pageLikeTitle(val) {if (isNotNull(val) || title.value) {title.value = val;page();}
}/* ==================== 秒殺詳情 ==================== */function seckillDetail(row) {sessionStorage.setItem('seckillId', row['id']);sessionStorage.setItem('seckillTitle', row['title'].toString());router.push('/SeckillDetail');
}/* ==================== 加載函數 ==================== */onMounted(() => page());</script><template v-if="records"><my-nav :items="navItems"/><my-head :items="headItems"/><my-table module="seckill"insert-page="/SeckillInsert"update-page="/SeckillUpdate":records="records":columns="columns":buttons="buttons":delete-api="deleteApi":delete-batch-api="deleteBatchApi":delete-callback="page":page-info="pageInfo"/>
</template><style scoped lang="scss"></style>
2. 添加秒殺記錄
心法:添加秒殺記錄頁面
武技:開發添加秒殺記錄頁面 views/sms/seckill/SeckillInsert.vue
<script setup>
import MyNav from "../../../components/MyNav.vue";
import MyForm from "../../../components/MyForm.vue";
import {reactive, ref} from "vue";
import {insertApi} from "../../../api/index.js";
import {RULE, SECKILL_STATUS_OPTIONS} from "../../../const/index.js";
import router from "../../../router/index.js";
import {ElMessage} from "element-plus";// 路徑導航
const navItems = [{icon: 'Goods', label: '營銷管理'},{icon: 'Stopwatch', label: '秒殺列表', url: '/Seckill'},{icon: 'Plus', label: '添加秒殺'},
];
// 表單項 + 表單值 + 表單規則
let items = ref([{label: '活動標題', prop: 'title', required: true, span: 12},{label: '活動狀態', prop: 'status', span: 12, type: 'select', required: true, options: SECKILL_STATUS_OPTIONS, placeholder: '請選擇活動狀態'},{label: '開始時間', prop: 'startTime', type: 'datetime', required: true, span: 12},{label: '結束時間', prop: 'endTime', type: 'datetime', required: true, span: 12},{label: '活動描述', prop: 'info', required: true, type: 'textarea'},
]);
let params = reactive({});
let rules = {info: RULE.INFO};/* ==================== 添加成功后 ==================== */function insertSuccess() {ElMessage.success('添加成功!');setTimeout(() => router.push('/Seckill'), 1000);
}
</script><template><my-nav :items="navItems"/><el-card class="seckill-insert-card" header="添加秒殺活動"><my-form type="insert":items="items":rules="rules":params="params":api="insertApi":args="{module: 'seckill'}":callback="insertSuccess"/></el-card>
</template><style scoped lang="scss">
.seckill-insert-card {width: 60%; // 寬度margin: 65px auto 0; // 外邊距
}
</style>
3. 修改秒殺記錄
心法:修改秒殺記錄頁面
武技:開發修改秒殺記錄頁面 views/sms/seckill/SeckillUpdate.vue
<script setup>
import MyNav from "../../../components/MyNav.vue";
import MyForm from "../../../components/MyForm.vue";
import {reactive, ref} from "vue";
import {updateApi} from "../../../api/index.js";
import {RULE, SECKILL_STATUS_OPTIONS} from "../../../const/index.js";
import router from "../../../router/index.js";
import {ElMessage} from "element-plus";// 獲取當前秒殺記錄
let seckill = JSON.parse(sessionStorage.getItem('row'));
// 路徑導航
const navItems = [{icon: 'Goods', label: '營銷管理'},{icon: 'Stopwatch', label: '秒殺列表', url: '/Seckill'},{icon: 'Edit', label: '修改秒殺'},
];
// 表單項 + 表單值 + 表單規則
let items = ref([{label: '活動標題', prop: 'title', required: true, span: 12},{label: '活動狀態', prop: 'status', span: 12, type: 'select', required: true, options: SECKILL_STATUS_OPTIONS, placeholder: '請選擇活動狀態'},{label: '開始時間', prop: 'startTime', type: 'datetime', required: true, span: 12},{label: '結束時間', prop: 'endTime', type: 'datetime', required: true, span: 12},{label: '活動描述', prop: 'info', required: true, type: 'textarea'},
]);
let params = reactive(seckill);
let rules = {info: RULE.INFO};/* ==================== 修改成功后 ==================== */function updateSuccess() {ElMessage.success('修改記錄成功!');setTimeout(() => router.push('/Seckill'), 1000);
}
</script><template><my-nav :items="navItems"/><el-card class="seckill-update-card" header="修改秒殺活動信息"><my-form type="update":items="items":rules="rules":params="params":api="updateApi":args="{module: 'seckill'}":callback="updateSuccess"/></el-card>
</template><style scoped lang="scss">
.seckill-update-card {width: 60%; // 寬度margin: 65px auto 0; // 外邊距
}
</style>
4. 查看秒殺詳情
心法:查看秒殺詳情頁面
武技:開發查看秒殺詳情頁面 views/sms/seckill/detail/SeckillDetail.vue
<script setup>
import MyNav from "../../../../components/MyNav.vue";
import MyHead from "../../../../components/MyHead.vue";
import MyTable from "../../../../components/MyTable.vue";
import {onMounted, reactive, ref} from "vue";
import {deleteApi, deleteBatchApi, pageApi} from "../../../../api/index.js";
import {isNotEmpty, isNotNull} from "../../../../util/index.js";
import {myPage} from "../../../../request/index.js";
import {MINIO_COURSE_COVER} from "../../../../const/index.js";// 所屬秒殺活動ID和秒殺活動標題
let seckillId = sessionStorage.getItem('seckillId');
let seckillTitle = sessionStorage.getItem('seckillTitle');
// 路徑導航
const navItems = [{icon: 'Goods', label: '營銷管理'},{icon: 'Stopwatch', label: '秒殺列表', url: '/Seckill'},{icon: 'Stopwatch', label: `《${seckillTitle}》活動詳情`},
];
// 數據頭
const headItems = [{type: 'ipt', span: 5, placeholder: '按標題搜索', callback: pageLikeCourseTitle},
];
// 表格列
const columns = [{label: '課程標題', prop: 'courseTitle'},{label: '課程封面', prop: 'courseCover', type: 'img', minio: MINIO_COURSE_COVER},{label: '課程原價', prop: 'coursePrice', suffix: '.00元'},{label: '課程秒殺價', prop: 'skPrice', suffix: '.00元'},{label: '課程秒殺數量', prop: 'skCount'},{label: '秒殺描述', prop: 'info', type: 'card', tooltip: false},
];
// 表格數據 + 分頁數據 + 課程標題
let records = ref();
let pageInfo = reactive({pageNum: 1, pageSize: 5, callback: page});
let courseTitle = ref();/* ==================== 分頁查詢 ==================== *//*** 分頁查詢記錄** 1. 定義分頁基礎配置,包括 records, pageInfo, api, params 等。* 2. 附加分頁查詢條件,如標題等。* 3. 異步發送分頁查詢請求。* 4. 將 seckillTitle 融入表格數據的每一項,方便進行展示。** @param pageNum 當前第幾頁,默認 1* @param pageSize 每頁多少條,默認 5*/
async function page(pageNum = pageInfo['pageNum'], pageSize = pageInfo['pageSize']) {let config = {api: pageApi,args: {module: 'seckillDetail'},params: {pageNum, pageSize, seckillId},records, pageInfo,}if (isNotEmpty(courseTitle.value)) config['params']['courseTitle'] = courseTitle.value;await myPage(config);if(isNotNull(records.value)){Object.values(records.value).forEach(seckill => seckill['seckillTitle'] = `${seckillTitle}`);}
}/* ==================== 搜索課程標題 ==================== *//*** 按秒殺詳情標題模糊查詢** 1. 將輸入框中的值賦值給分頁條件字段變量。* 2. 重新發送分頁請求。** @param val 輸入框中的值*/
function pageLikeCourseTitle(val) {if (isNotNull(val) || courseTitle.value) {courseTitle.value = val;page();}
}/* ==================== 加載函數 ==================== */onMounted(() => page());</script><template v-if="records"><my-nav :items="navItems"/><my-head :items="headItems"/><my-table module="seckillDetail"insert-page="/SeckillDetailInsert"update-page="/SeckillDetailUpdate":records="records":columns="columns":delete-api="deleteApi":delete-batch-api="deleteBatchApi":delete-callback="page":page-info="pageInfo"/>
</template><style scoped lang="scss"></style>
5. 添加秒殺詳情
心法:添加秒殺詳情頁面
武技:開發添加秒殺詳情頁面 views/sms/seckill/detail/SeckillDetailInsert.vue
<script setup>
import MyNav from "../../../../components/MyNav.vue";
import MyForm from "../../../../components/MyForm.vue";
import {onMounted, reactive, ref} from "vue";
import {insertApi, simpleListApi} from "../../../../api/index.js";
import {getResponseData} from "../../../../request/index.js";
import {RULE} from "../../../../const/index.js";
import {ElMessage} from "element-plus";
import router from "../../../../router/index.js";// 所屬秒殺活動ID和秒殺活動標題
let seckillId = sessionStorage.getItem('seckillId');
let seckillTitle = sessionStorage.getItem('seckillTitle');
// 全部課程下拉菜單選項
let courseOptions = ref([]);
// 路徑導航
const navItems = [{icon: 'Goods', label: '營銷管理'},{icon: 'Stopwatch', label: '秒殺列表', url: '/Seckill'},{icon: 'Stopwatch', label: `《${seckillTitle}》活動詳情`, url: '/SeckillDetail'},{icon: 'Plus', label: '添加活動課程'},
];/* ==================== 添加表單 ==================== */// 表單項 + 表單值 + 表單規則
let items = ref([{label: '所屬活動', prop: 'seckillTitle', disabled: true, span: 12},{label: '活動課程', prop: 'fkCourseId', required: true, span: 12, type: 'select', options: courseOptions, placeholder: '請選擇課程'},{label: '秒殺價格', prop: 'skPrice', type: 'number', min: 1, required: true, span: 12},{label: '秒殺數量', prop: 'skCount', type: 'number', min: 1, required: true, span: 12},{label: '秒殺描述', prop: 'info', required: true, type: 'textarea'},
]);
let params = reactive({seckillTitle, 'fkSeckillId': seckillId});
let rules = {info: RULE.INFO};/* ==================== 添加成功后 ==================== */function insertSuccess() {ElMessage.success('添加成功!');setTimeout(() => router.push('/SeckillDetail'), 1000);
}/* ==================== 加載函數 ==================== */onMounted(async () => {// 查詢全部課程并添加到下拉菜單選項中Object.values(getResponseData(await simpleListApi(null, {module: 'course'}))).forEach(course => {courseOptions.value.push({label: course['title'] + '(¥' + course['price'] + ')', value: course['id']});});
});
</script><template><my-nav :items="navItems"/><el-card v-if="courseOptions.length > 0" class="seckill-detail-insert-card" header="添加活動課程"><my-form type="insert":items="items":rules="rules":params="params":api="insertApi":args="{module: 'seckillDetail'}":callback="insertSuccess"/></el-card>
</template><style scoped lang="scss">
.seckill-detail-insert-card {width: 60%; // 寬度margin: 65px auto 0; // 外邊距
}
</style>
6. 修改秒殺詳情
心法:修改秒殺詳情頁面
武技:開發修改秒殺詳情頁面 views/sms/seckill/detail/SeckillDetailUpdate.vue
<script setup>
import MyNav from "../../../../components/MyNav.vue";
import MyForm from "../../../../components/MyForm.vue";
import {onMounted, reactive, ref} from "vue";
import {simpleListApi, updateApi} from "../../../../api/index.js";
import {getResponseData} from "../../../../request/index.js";
import {RULE} from "../../../../const/index.js";
import {ElMessage} from "element-plus";
import router from "../../../../router/index.js";// 獲取當前秒殺詳情記錄
let seckillDetail = JSON.parse(sessionStorage.getItem('row'));
// 所屬秒殺活動ID和秒殺活動標題
let seckillId = sessionStorage.getItem('seckillId');
let seckillTitle = sessionStorage.getItem('seckillTitle');
// 全部課程下拉菜單選項
let courseOptions = ref([]);
// 路徑導航
const navItems = [{icon: 'Goods', label: '營銷管理'},{icon: 'Stopwatch', label: '秒殺列表', url: '/Seckill'},{icon: 'Stopwatch', label: `《${seckillTitle}》活動詳情`, url: '/SeckillDetail'},{icon: 'Edit', label: '修改秒殺詳情'},
];/* ==================== 修改表單 ==================== */// 表單項 + 表單值 + 表單規則
let items = ref([{label: '所屬活動', prop: 'seckillTitle', disabled: true, span: 12},{label: '活動課程', prop: 'fkCourseId', required: true, span: 12, type: 'select', options: courseOptions, placeholder: '請選擇課程'},{label: '秒殺價格', prop: 'skPrice', type: 'number', min: 1, required: true, span: 12},{label: '秒殺數量', prop: 'skCount', type: 'number', min: 1, required: true, span: 12},{label: '秒殺描述', prop: 'info', type: 'textarea'},
]);
let params = reactive(seckillDetail);
let rules = {info: RULE.INFO};/* ==================== 修改成功后 ==================== */function updateSuccess() {ElMessage.success('添加成功!');setTimeout(() => router.push('/SeckillDetail'), 1000);
}/* ==================== 加載函數 ==================== */onMounted(async () => {// 查詢全部課程并添加到下拉菜單選項中Object.values(getResponseData(await simpleListApi(null, {module: 'course'}))).forEach(course => {courseOptions.value.push({label: course['title'] + '(¥' + course['price'] + ')', value: course['id']});});
});
</script><template><my-nav :items="navItems"/><el-card v-if="courseOptions.length > 0" class="sub-seckill-detail-update-card" header="修改秒殺詳情信息"><my-form type="update":items="items":rules="rules":params="params":api="updateApi":args="{module: 'seckillDetail'}":callback="updateSuccess"/></el-card>
</template><style scoped lang="scss">
.sub-seckill-detail-update-card {width: 60%; // 寬度margin: 65px auto 0; // 外邊距
}
</style>
E05. 優惠卷管理模塊
1. 查看優惠卷列表
心法:查看優惠卷列表頁面
武技:開發查看優惠卷列表頁面 views/sms/coupons/Coupons.vue
<script setup>
import MyNav from "../../../components/MyNav.vue";
import MyTable from "../../../components/MyTable.vue";
import MyHead from "../../../components/MyHead.vue";
import {onMounted, reactive, ref} from "vue";
import {deleteApi, deleteBatchApi, pageApi} from "../../../api/index.js";
import {myPage} from "../../../request/index.js";
import {dateFormat, isNotEmpty, isNotNull} from "../../../util/index.js";// 路徑導航
const navItems = [{icon: 'Goods', label: '營銷管理'},{icon: 'Opportunity', label: '優惠卷列表'},
];
// 數據頭
const headItems = [{type: 'ipt', span: 5, placeholder: '按標題搜索', callback: pageLikeTitle},{type: 'ipt', span: 5, placeholder: '按口令搜索', callback: pageLikeCode},
];
// 表格列
const columns = [{label: '兌換碼', prop: 'code', type: 'tag', sortable: false},{label: '標題', prop: 'title'},{label: '優惠價格', prop: 'cpPrice', suffix: '.00 元', width: 130},{label: '生效時間', prop: 'startTime', format: dateFormat, width: 150},{label: '失效時間', prop: 'endTime', format: dateFormat, width: 150},{label: '優惠卷描述', prop: 'info', type: 'card', tooltip: false},
];/* ==================== 分頁查詢 ==================== */// 表格數據 + 分頁數據 + 優惠卷標題 + 優惠卷口令
let records = ref();
let pageInfo = reactive({pageNum: 1, pageSize: 5, callback: page});
let title = ref();
let code = ref();/*** 分頁查詢** 1. 定義分頁基礎配置,包括 records, pageInfo, api, params 等。* 2. 附加分頁查詢條件,如標題,口令等。* 3. 異步發送分頁查詢請求。** @param pageNum 當前第幾頁,默認 1* @param pageSize 每頁多少條,默認 5*/
async function page(pageNum = pageInfo['pageNum'], pageSize = pageInfo['pageSize']) {let config = {api: pageApi,args: {module: 'coupons'},params: {pageNum, pageSize, pid: 0},records, pageInfo,}if (isNotEmpty(title.value)) config['params']['title'] = title.value;if (isNotEmpty(code.value)) config['params']['code'] = code.value;await myPage(config);
}/* ==================== 搜索優惠卷標題 ==================== *//*** 按優惠卷標題模糊查詢** 1. 將輸入框中的值賦值給分頁條件字段變量。* 2. 重新發送分頁請求。** @param val 輸入框中的值*/
function pageLikeTitle(val) {if (isNotNull(val) || title.value) {title.value = val;page();}
}/* ==================== 搜索優惠卷口令 ==================== *//*** 按優惠卷口令模糊查詢** 1. 將輸入框中的值賦值給分頁條件字段變量。* 2. 重新發送分頁請求。** @param val 輸入框中的值*/
function pageLikeCode(val) {if (isNotNull(val) || code.value) {code.value = val;page();}
}/* ==================== 加載函數 ==================== */onMounted(() => page());</script><template v-if="records"><my-nav :items="navItems"/><my-head :items="headItems"/><my-table module="coupons"insert-page="/CouponsInsert"update-page="/CouponsUpdate":records="records":columns="columns":delete-api="deleteApi":delete-batch-api="deleteBatchApi":delete-callback="page":page-info="pageInfo"/>
</template><style scoped lang="scss"></style>
2. 添加優惠卷記錄
心法:添加優惠卷記錄頁面
武技:開發添加優惠卷記錄頁面 views/sms/coupons/CouponsInsert.vue
<script setup>
import MyNav from "../../../components/MyNav.vue";
import MyForm from "../../../components/MyForm.vue";
import {reactive, ref} from "vue";
import {insertApi} from "../../../api/index.js";
import {RULE} from "../../../const/index.js";
import {ElMessage} from "element-plus";
import router from "../../../router/index.js";// 路徑導航
const navItems = [{icon: 'Goods', label: '營銷管理'},{icon: 'Opportunity', label: '優惠卷列表', url: '/Coupons'},{icon: 'Plus', label: '添加優惠卷'},
];
// 表單項 + 表單值 + 表單規則
let items = ref([{label: '兌換口令', prop: 'code', required: true},{label: '標題', prop: 'title', required: true, span: 12},{label: '優惠價格', prop: 'cpPrice', type: 'number', min: 1, required: true, span: 12},{label: '生效時間', prop: 'startTime', type: 'datetime', required: true, span: 12},{label: '失效時間', prop: 'endTime', type: 'datetime', required: true, span: 12},{label: '描述', prop: 'info', required: true, type: 'textarea'},
]);
let params = reactive({});
let rules = {code: RULE.CODE, title: RULE.TITLE, content: RULE.INFO,};/* ==================== 添加成功后 ==================== */function insertSuccess() {ElMessage.success('添加成功!');setTimeout(() => router.push('/Coupons'), 1000);
}
</script><template><my-nav :items="navItems"/><el-card class="coupons-insert-card" header="添加優惠卷"><my-form type="insert":items="items":rules="rules":params="params":api="insertApi":args="{module: 'coupons'}":callback="insertSuccess"/></el-card>
</template><style scoped lang="scss">
.coupons-insert-card {width: 60%; // 寬度margin: 65px auto 0; // 外邊距
}
</style>
3. 修改優惠卷記錄
心法:修改優惠卷記錄頁面
武技:開發修改優惠卷記錄頁面 views/sms/coupons/CouponsUpdate.vue
<script setup>
import MyNav from "../../../components/MyNav.vue";
import MyForm from "../../../components/MyForm.vue";
import {reactive, ref} from "vue";
import {updateApi} from "../../../api/index.js";
import {RULE} from "../../../const/index.js";
import {ElMessage} from "element-plus";
import router from "../../../router/index.js";// 獲取當前優惠卷記錄
let coupons = JSON.parse(sessionStorage.getItem('row'));
// 路徑導航
const navItems = [{icon: 'Goods', label: '營銷管理'},{icon: 'Opportunity', label: '優惠卷列表', url: '/Coupons'},{icon: 'Edit', label: '修改優惠卷'},
];
// 表單項 + 表單值 + 表單規則
let items = ref([{label: '兌換口令', prop: 'code', required: true},{label: '標題', prop: 'title', required: true, span: 12},{label: '優惠價格', prop: 'cpPrice', type: 'number', min: 1, required: true, span: 12},{label: '生效時間', prop: 'startTime', type: 'datetime', required: true, span: 12},{label: '失效時間', prop: 'endTime', type: 'datetime', required: true, span: 12},{label: '描述', prop: 'info', required: true, type: 'textarea'},
]);
let params = reactive(coupons);
let rules = {code: RULE.CODE, title: RULE.TITLE, content: RULE.INFO};/* ==================== 修改成功后 ==================== */function updateSuccess() {ElMessage.success('修改記錄成功!');setTimeout(() => router.push('/Coupons'), 1000);
}
</script><template><my-nav :items="navItems"/><el-card class="coupons-update-card" header="修改優惠卷信息"><my-form type="update":items="items":rules="rules":params="params":api="updateApi":args="{module: 'coupons'}":callback="updateSuccess"/></el-card>
</template><style scoped lang="scss">
.coupons-update-card {width: 60%; // 寬度margin: 65px auto 0; // 外邊距
}
</style>
Java道經 - 項目 - MyLesson - 后臺前端(四)
傳送門:JP4-7-MyLesson后臺前端(一)
傳送門:JP4-7-MyLesson后臺前端(二)
傳送門:JP4-7-MyLesson后臺前端(三)
傳送門:JP4-7-MyLesson后臺前端(四)
傳送門:JP4-7-MyLesson后臺前端(五)