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营销服务

武技:搭建起始文件环境和对应的路由代码。

  1. 创建全部相关 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
  1. 在 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后台前端(五)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/921730.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/921730.shtml
英文地址,请注明出处:http://en.pswp.cn/news/921730.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux control group笔记

Linux CGroup&#xff08;Control Groups&#xff09;是一个强大的内核功能&#xff0c;用于限制、记录和隔离进程组&#xff08;process groups&#xff09;使用的系统资源&#xff08;如 CPU、内存、磁盘 I/O、网络等&#xff09;。它通过将进程分组并对这些组进行资源分配和…

小迪Web自用笔记30

Node.js原生态的js运行在前端。Node.js&#xff1a;他与原生态JS最大的不同&#xff0c;就是前端只能看到输出的代码&#xff0c;而看不到jS文件req接收&#xff0c;res回显dirname获取绝对路径提交表单 &#xff1a;“Post路由” 到底是什么。这是一个非常核心的Web开发概念。…

并发编程的守护者:信号量与日志策略模式解析

一、信号量 关于信号量的介绍在深入Linux内核&#xff1a;IPC资源管理揭秘 这篇文章当中已经做了初步的介绍了&#xff0c;相信大家对于信号量已经有了初步的认知了。 今天&#xff0c;我们就来探讨如何实现信号量。 1. 信号量的接口 //初始化信号量 //成功了&#xff0c;返…

conda 创建环境嵌套报错

使用conda create --prefix /path可以成功创建&#xff0c;有可能时默认路径冲突导致的 conda config --show 发现&#xff1a; envs_dirs: /root/autodl-tmp/miniconda3/envs/envs_test/path/root/autodl-tmp/miniconda3/envs/root/.conda/envs 未显式指定环境路径&#xf…

低代码核心原理总结

Web 低代码平台核心原理深度解析 1. 架构总览 Web低代码平台的核心架构包含四个关键层次&#xff1a; class LowCodePlatform {constructor() {this.visualEditor new VisualEditor(); // 可视化编辑器this.metaDataEngine new MetaDataEngine(); // 元数据引擎this.code…

操作系统研发工作心得体会 - 于复杂性中构建秩序

在操作系统&#xff08;OS&#xff09;研发这片要求极致严谨与创新的工程深海中航行数载&#xff0c;我的角色从一个纯粹的技术专家&#xff0c;逐渐演变为一个需要兼顾技术深度、系统广度与团队效能的复合型角色。这段旅程&#xff0c;让我深刻体会到&#xff0c;构建一个成功…

Excel 表格 - Excel 减少干扰、专注于内容的查看方式

Excel 减少干扰、专注于内容的查看方式 1、隐藏元素 点击 【视图】 -> 取消勾选 【网格线】 -> 取消勾选 【编辑栏】 -> 取消勾选 【标题】2、全屏显示 点击 【功能区显示选项】&#xff08;工具栏右下角小箭头&#xff09; -> 点击 【全屏模式】

C# Web API 前端传入参数时间为Utc

Web API 前端传入参数时间为Utc&#xff08;时间相差8个小时&#xff09;1.在Program.csbuilder.Services.AddControllers().AddJsonOptions(options > {// 序列化时将时间转换为本地时间&#xff08;北京时间&#xff09;options.JsonSerializerOptions.Converters.Add(new…

AI Agent开发入门:Semantic Kernel构建智能邮件助手

点击 “AladdinEdu&#xff0c;同学们用得起的【H卡】算力平台”&#xff0c;H卡级别算力&#xff0c;80G大显存&#xff0c;按量计费&#xff0c;灵活弹性&#xff0c;顶级配置&#xff0c;学生更享专属优惠。 引言&#xff1a;AI Agent——下一代人机交互范式 在人工智能技术…

WebAssembly:开启高性能 Web 应用的新篇章

在互联网技术飞速发展的浪潮中&#xff0c;Web应用的性能一直是一个重要的优化目标。传统的JavaScript虽然灵活便捷&#xff0c;但在处理CPU密集型任务时&#xff0c;其性能瓶颈日益凸显&#xff0c;限制了Web应用在游戏、音视频编辑、科学计算、图像处理等高性能领域的深入发展…

001-003 产品经理-ML应用构建-ML应用范围

001-003 产品经理-ML应用构建-ML应用范围 时间&#xff1a;2025年09月08日14:48:01 备注&#xff1a;笔记回顾和复习&#xff0c;仅用于分享而非商用&#xff0c;引用内容若侵权请联系并删除。 文章目录001-003 产品经理-ML应用构建-ML应用范围导引 学习法则1 内容索引 产品经…

软件测试错题笔记

1.capitalize()表示将字符串第一个字符转换为大写 2.pop()方法&#xff1a;指定一个键&#xff08;key&#xff09;作为参数来删除并返回对应的值&#xff0c;不传入任何参数报错。 3.测试方法&#xff1a;黑盒测试&#xff08;等价类划分法、边界值分析、因果图分析&#xf…

【一文分享】安全数据交换系统是什么?哪款产品性价比高?

随着数据价值的提升&#xff0c;其流动过程中的安全风险也与日俱增。内部核心数据泄露、外部攻击、不合规传输导致的合规风险……这些问题如同悬在企业头上的“达摩克利斯之剑”。正是在这样的背景下&#xff0c;安全数据交换系统 应运而生&#xff0c;成为了保障数据安全流动的…

postgresql9.2.4 离线安装

1、创建用户[rootvkeep ~]# groupadd postgres [rootvkeep ~]# useradd -g postgres postgres -m -s /bin/bash [rootvkeep ~]# echo "Database123" | passwd --stdin postgres2、安装依赖包[rootvkeep ~]# yum install gcc gcc-c zlib-devel readline readline-deve…

【C++设计模式】第三篇:观察者模式(别名:发布-订阅模式、模型-视图模式、源-监听器模式)

C设计模式系列文章目录 【C设计模式】第一篇 C单例模式–懒汉与饿汉以及线程安全 【C设计模式】第二篇&#xff1a;策略模式&#xff08;Strategy&#xff09;–从基本介绍&#xff0c;内部原理、应用场景、使用方法&#xff0c;常见问题和解决方案进行深度解析 【C设计模式】…

运作管理学习笔记5-生产和服务设施的选址

运作管理-北京交通大学5.1.设施选址概述 设施选址是一个战略性的决策&#xff0c;做这个决策的时候会投入比较多的资源&#xff0c;而且未来去改变选址的成本和代价也比较大。 5.1.1.设施选址的重要性 设施选址影响企业经营情况 设施选址对设施布局以及投产后的生产经营费用、产…

JUnit 详解

一、JUnit 简介&#xff1a;什么是 JUnit&#xff1f;为什么要用它&#xff1f;1.1 核心定义JUnit 是一个开源的、基于 Java 语言的单元测试框架&#xff0c;最初由 Erich Gamma (GoF 设计模式作者之一) 和 Kent Beck (极限编程创始人) 在 1997 年共同开发。作为 xUnit 测试框架…

数据结构造神计划第三天---数据类型

&#x1f525;个人主页&#xff1a;寻星探路 &#x1f3ac;作者简介&#xff1a;Java研发方向学习者 &#x1f4d6;个人专栏&#xff1a;《从青铜到王者&#xff0c;就差这讲数据结构&#xff01;&#xff01;&#xff01;》、 《JAVA&#xff08;SE&#xff09;----如此简单&a…

AI API Tester体验:API测试工具如何高效生成接口测试用例、覆盖异常场景?

前阵子帮后端测试支付接口时&#xff0c;我算是彻底明白 “API 测试能磨掉半条命”—— 明明接口文档里写了十几种参数组合&#xff0c;手动写测试用例时要么漏了 “签名过期” 的场景&#xff0c;要么忘了校验 “金额超过限额” 的返回值&#xff0c;测到半夜还被开发吐槽 “你…

音频驱动数字人人脸模型

1.LatentSync: Taming Audio-Conditioned Latent Diffusion Models for Lip Sync with SyncNet Supervision 字节 2024 文章地址&#xff1a;https://arxiv.org/pdf/2412.09262 代码地址&#xff1a;https://github.com/bytedance/LatentSync 训练推理都有 2.wan2.2-s2v …