批改状态:合格
老师批语:
<?phpnamespace app\api\controller;use think\facade\Db;use think\facade\Request;class Api{// Access to XMLHttpRequest at 'http://www.tp.com/index.php/api/Api/index'// from origin 'http://localhost:8080' has been blocked by CORS policy: No// 'Access-Control-Allow-Origin' header is present on the requested resource.// 错误信息:是因为前后端分离导致的。前后端 前端和后端的域名不是一个。不是一个,就会出现这种错误。// 跨域名访问的安全错误提示public function __construct(){// 使用php的header函数,设置为*,全部能访问header("Access-Control-Allow-Origin:*");}public function index(){// 如何写一个 前端数据接口呢?app、小程序、vue// 接口:让2个以上的项目进行数据联通,数据交互// 多个语言 必须有统一的格式, 最后返回值,必须多种语言都能使用// 接口的统一数据格式是 json// php有json的函数// json_encode 把php的数据加密成json格式// json_decode 把json格式转为 php数据格式// $arr = [// "ouyangke" => "欧阳克",// "miejue" => "灭绝师太",// "php" => [// "ouyangke",// "miejue"// ],// "tianpeng" => "朱天蓬"// ];// json格式,是文本,我们就可以echo// {"ouyangke":"\u6b27\u9633\u514b","miejue":"\u706d\u7edd\u5e08\u592a","tianpeng":"\u6731\u5929\u84ec"}// echo json_encode($arr);// 1、接口 必须用json返回数据// 2、用数组 转为json数据$ad = Db::table('oyk_adver')->where('status',1)->order('sort DESC')->select()->toArray();$lists = Db::table('oyk_shop_lists')->where('status',1)->order('add_time DESC')->limit(6)->select()->toArray();// & 取之前的地址foreach($lists as &$v){$img = explode(';',$v['img']);$v['img_s'] = $img[0];}// 3、接口只能一次性返回数据,不能多次// echo json_encode($ad);// echo json_encode($lists);$arr = ['ad' => $ad,'lists' => $lists];echo json_encode($arr);}public function goods_index(){//1.第一种:父子层级获取数据 (更快更好)// echo '第一种方法开始时间:' . time() . '<br />';$cat = Db::table('oyk_shop_cat')->where('status',1)->order('pid,sort DESC')->select()->toArray();// print_r($cat);$tmp =[];foreach($cat as $v){// pid == 0 表示是一级菜单if($v['pid'] == 0){//把一级的id,作为下标$tmp[$v['cid']] = $v;}else {//把多个二级放入一级菜单下面$tmp[$v['pid']]['son'][] = $v;}}// print_r($tmp);// echo json_encode($tmp);$arr = ['code'=>0,'msg'=>'成功',// 'data'=>$tmp,// 第二种显示方式'data'=>array_merge($tmp),];echo json_encode($arr);//把二级菜单放到一级菜单下面// foreach($cat as $v){// if($v['pid'] != 0){// //把一个二级放入一级菜单下面// // $tmp[$v['pid']]['son'] = $v;// //把多个二级放入一级菜单下面// $tmp[$v['pid']]['son'][] = $v;// }// }// print_r($tmp);// echo '第一种方法结束时间:' . time() . '<br />';// 2.第二种方法// echo '第二种方法开始时间:' . time() . '<br />';// $cat = Db::table('oyk_shop_cat')->where('status',1)->where('pid',0)->select()->toArray();// // print_r($cat);// foreach($cat as &$v){// $v['son'] = Db::table('oyk_shop_cat')->where('status',1)->where('pid',$v['cid'])->select()->toArray();// }// print_r($cat);// echo '第二种方法结束时间:' . time() . '<br />';}// 列表页public function goods_lists(){// $id = input('post.id');$id = input('post.id');if(empty($id)){echo json_encode(['code' => 1,'msg' => '未找到列表',]);exit;}$page = input('post.p',1);$count = Db::table('oyk_shop_lists')->where('status',1)->where('cid',$id)->count();// print_r((int)($count/5)+1);// ceil 向上取整// print_r(ceil($count/5));$lists = Db::table('oyk_shop_lists')->where('status',1)->page(1,5)->where('cid',$id)->select()->toArray();// 图集处理获取第一张foreach($lists as &$v){$img = explode(';',$v['img']);$v['img_s'] = $img[0];}$arr = ['code' => 0,'msg' =>'成功','data' => ['lists' => $lists,'num' => ceil($count/5),],];echo json_encode($arr);}//详情页public function goods_details(){$id = input('post.id');if(empty($id)){echo json_encode(['code' =>1,'msg' =>'未找到商品',]);exit;}$find = Db::table('oyk_shop_lists')->where('id',$id)->find();// print_r($find);if(!empty($find)){$find['img_s'] = explode(';',$find['img']);$find['info_s'] = explode(';',$find['info']);}echo json_encode(['code' => 0,'msg' => '成功','data' => $find,]);}}
import { request } from "./request.js";export function Index() {return request({method: "POST",url: "Api/index",});}export function GoodsIndex() {return request({method: "POST",url: "Api/goods_index",});}export function GoodsLists(data = {}) {return request({method: "POST",url: "Api/goods_lists",// 通过data 向Api接口传值data,});}export function GoodsDetails(data = {}) {return request({method: "POST",url: "Api/goods_details",// 通过data 向Api接口传值data,});}
<template><div class="fui-fullHigh-group"><div class="fui-fullHigh-item menu"><divclass="nav":class="on == index ? 'on' : ''"@click="edit_cat(index)"v-for="(item, index, key) in cat":key="key">{{ item.name }}</div></div><div class="fui-fullHigh-item container"><!-- 第一种遍历方式 :两次循环<divclass="fui-icon-group"v-for="(item, index, key) in cat":key="key"><div v-if="on == index"><router-link to="/goods_lists" v-for="(items, indexs, keys) in item.son" :key="keys"><div class="fui-icon-col"><div class="icon"><img class="img" :src="items.pic" /></div><div class="text">{{ items.name }}</div></div></router-link></div></div> --><!-- 第二种遍历方式 --><div class="fui-icon-group"><router-link:to="'/goods_lists?id=' + items.cid"v-for="(items, indexs, keys) in cat_son":key="keys"><div class="fui-icon-col"><div class="icon"><img class="img" :src="items.pic" /></div><div class="text">{{ items.name }}</div></div></router-link></div></div></div></template><script>import { reactive, toRefs } from "vue";import { GoodsIndex } from "../../network/index.js";export default {setup() {const data = reactive({// on: 1,// 第二种方式on: 0,cat: [],cat_son: [],});//切换左侧一级分类const edit_cat = (e) => {data.on = e;console.log(e);data.cat_son = data.cat[e].son;};// 获取接口数据GoodsIndex().then((e) => {console.log(e);if (e.code != 0) {}data.cat = e.data;// 第二种方式console.log(e.data[0]);data.cat_son = e.data[0].son;});return {title: "分类",...toRefs(data),edit_cat,};},};</script><style scoped>.fui-fullHigh-group {position: absolute;top: 0;bottom: 0;width: 100%;display: flex;}/* 左侧 */.fui-fullHigh-item {height: inherit;width: 100%;background: #fff;overflow-y: auto;}.fui-fullHigh-item.menu {width: 5.25rem;background: #f8f8f8;}.fui-fullHigh-item.menu .nav {font-size: 28rpx;text-align: center;color: #000;padding: 0.2rem 0;height: 2.5rem;text-overflow: ellipsis;white-space: nowrap;overflow: hidden;position: relative;display: flex;justify-content: center;align-items: Center;}.fui-fullHigh-item.menu .on {background: #fff;position: relative;color: #ff5555;}/* 右侧 */.fui-fullHigh-item.container {position: relative;padding: 0.8rem;flex: 1;}.fui-icon-group {position: relative;overflow: hidden;background: #fff;display: flex;flex-wrap: wrap;}.fui-icon-group .fui-icon-col {height: auto;position: relative;padding: 0.5rem 0;text-align: center;transition: background-color 300ms;-webkit-transition: background-color 300ms;float: left;border: none !important;}.fui-icon-group .fui-icon-col {float: left;margin-right: 17px;padding-top: 10px;}.fui-icon-group .fui-icon-col .icon {height: 115px;width: 100%;margin: auto;text-align: center;line-height: 2.2rem;}.icon {font-family: "icon" !important;font-size: 16px;font-style: normal;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;}.img {width: 115px;height: 100%;}.fui-icon-group .fui-icon-col .text {font-size: 24px;text-align: center;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;padding: 0.2rem;color: #000;}.fui-icon-group .fui-icon-col .text {font-size: 0.55rem;line-height: 1.05rem;padding-top: 0.5rem;}</style>
<template><Header :title="title"></Header><div style="background: #f3f3f3"><!-- 商品列表 --><div class="fui-content"><div class="fui-content-inner"><div class="fui-goods-group block"><!-- 单个商品 --><divclass="fui-goods-item"@click="go_url(item.id)"v-for="(item, index, key) in lists":key="key"><img class="image" :src="item.img_s" /><div class="detail"><div class="name">{{ item.title }}</div><divstyle="line-height: 0.7rem;height: 0.7rem;color: #b2b2b2;font-size: 0.6rem;margin-top: 0.2rem;text-decoration: line-through;"></div><div class="price"><span class="text">¥{{ item.price }}</span><span class="buy">销量:{{ item.num }}</span></div></div></div><!-- 单个商品 --></div></div><button v-if="is_b" class="ant-btn ant-btn-primary" style="width: 100%" @click="xiala()">加载更多</button></div></div></template><script>import Header from "../../components/Header.vue";import { reactive, toRefs } from "vue";import { useRoute, useRouter } from "vue-router";import { GoodsLists } from "../../network/index.js";export default {components: {Header,},setup() {const route = useRoute();const router = useRouter();const go_url = (id) => {router.push("/goods_details?id=" + id);};// 获取数据// console.log(route.query.id);const data = reactive({lists: [],page: 1,num: 1,is_b: true,});GoodsLists({ id: route.query.id, p: data.page }).then((e) => {// console.log(e);data.lists = e.data.lists;data.num = e.data.num;// 取掉加载更多if (data.page >= data.num) {data.is_b = false;}});// 加载更多const xiala = () => {data.page = data.page + 1;if (data.page <= data.num) {GoodsLists({ id: route.query.id }).then((e) => {// console.log(e);// data.lists = e.data;//合并显示页data.lists = data.lists.concat(e.data.lists);// 取掉加载更多if (data.page >= data.num) {data.is_b = false;}});}};return {go_url,title: "列表",...toRefs(data),xiala,};},};</script><style scoped>/* 顶部筛选 */.sort {position: relative;width: 100%;padding: 0.4rem 0;background: #fff;-webkit-box-align: center;border-bottom: 1px solid #e7e7e7;}.sort .item {position: relative;width: 1%;display: table-cell;text-align: center;font-size: 0.7rem;border-left: 1px solid #e7e7e7;color: #666;}.sort .item:first-child {border: 0;}.on .text {color: #fd5454;}/* 商品 */.fui-content {position: absolute;right: 0;left: 0;overflow: auto;-webkit-overflow-scrolling: touch;}.fui-content-inner {box-sizing: border-box;border-top: 1px solid transparent;margin-top: -1px;}.fui-goods-group {height: auto;overflow: hidden;background: #f9f9f9;}.fui-goods-group.block {padding: 0.2rem;}/* 单个商品 */.fui-goods-group .fui-goods-item {width: 50%;float: left;border-bottom: 0;background: none;padding: 0.25rem;display: block;}.fui-goods-item {position: relative;height: auto;padding: 0.8rem;border-bottom: 1px solid #e7e7e7;background: #fff;overflow: hidden;display: flex;}.image {width: 100%;overflow: hidden;margin: 0;background-position: center;background-repeat: no-repeat;background-size: cover;position: relative;float: none;}/* 商品名 */.detail {-webkit-box-flex: 1;-webkit-flex: 1;-ms-flex: 1;flex: 1;background: #fff;padding-left: 0.5rem;padding: 0.5rem;}.name {height: 1.7rem;overflow: hidden;text-overflow: ellipsis;display: -webkit-box;-webkit-line-clamp: 2;-webkit-box-orient: vertical;font-size: 0.65rem;line-height: 0.9rem;margin-top: 0;color: #262626;}.price {position: relative;display: flex;align-items: center;font-size: 0.7rem;margin-top: 0;}.price .text {flex: 1;color: #ff5555;font-size: 0.8rem;}.buy {text-align: center;color: #666;font-size: 0.6rem;}.ant-btn {line-height: 1.5715;position: relative;display: inline-block;font-weight: 400;white-space: nowrap;text-align: center;background-image: none;border: 1px solid transparent;box-shadow: 0 2px 0 rgb(0 0 0 / 2%);cursor: pointer;transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);-webkit-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;touch-action: manipulation;height: 32px;padding: 4px 15px;font-size: 14px;border-radius: 2px;color: rgba(0, 0, 0, 0.85);background: #fff;border-color: #d9d9d9;}.ant-btn-primary {color: #fff;background: #1890ff;border-color: #1890ff;text-shadow: 0 -1px 0 rgb(0 0 0 / 12%);box-shadow: 0 2px 0 rgb(0 0 0 / 5%);}</style>
<template><Header :title="title" :is_img="1"></Header><div class="rele-wrap"><div class="has-bottom"><swiper:modules="modules":loop="true":pagination="swiper_options.pagination":autoplay="swiper_options.autoplay"class="swiper"><swiper-slide v-for="(item, index, key) in shop.img_s" :key="key"><img :src="item" alt="" class="active" /></swiper-slide></swiper><div class="idle-panel"><div class="p1">{{ shop.title }}</div><div class="p2"><text class="span">{{ shop.price }}元</text></div></div><div class="sale-panel"><div class="tit">商品详情</div><div class="all open"><img :src="item" v-for="(item, index, key) in shop.info_s" :key="key" /></div></div></div><div class="fui-navbar bottom-buttons"><button class="btn btn_left">加入购物车</button><button class="btn btn_right" @click="go_url()">立即购买</button></div></div></template><script>import { reactive, toRefs } from "vue";import { useRoute, useRouter } from "vue-router";import Header from "../../components/Header.vue";import { GoodsDetails } from "../../network/index.js";import SwiperCore, { Pagination, Autoplay } from "swiper";import { Swiper, SwiperSlide } from "swiper/vue/swiper-vue.js";import "swiper/swiper.min.css";import "swiper/modules/pagination/pagination.min.css";SwiperCore.use([Autoplay, Pagination]);export default {components: {Swiper,SwiperSlide,Header,},setup() {const swiper_options = new reactive({pagination: {clickable: true,},autoplay: {disableOnInteraction: false, // 鼠标滑动后继续自动播放delay: 2000, //2秒切换一次pauseOnMouseEnter: true,},speed: 500, //切换过渡速度});//获取数据const route = useRoute();const router = useRouter();const go_url = () => {router.push("/cart_index");};const data = reactive({shop: [],});GoodsDetails({ id: route.query.id }).then((e) => {// console.log(e);data.shop = e.data;});return {swiper_options,go_url,title: "详情",...toRefs(data),};},};</script><style scoped>.swiper {margin: 0 0.1rem;}.swiper .swiper-wrapper {/* 图片容器必须要有高度,否则下面图片不能正常显示 */height: 1.5rem;border-radius: 0.1rem;}.swiper .swiper-wrapper img {height: 100%;width: 100%;border-radius: 0.1rem;}.swiper {--swiper-pagination-color: #fff;--swiper-navigation-color: black;}.rele-wrap {background: #f5f5f5;}.has-bottom {padding-bottom: 55px !important;}.banner {position: relative;background: #fff;overflow: hidden;margin: 0;visibility: visible;height: 315px;}.banner .swipe-wrap {overflow: hidden;position: relative;}.vi_img {float: left;width: 100%;height: 100%;position: relative;}.idle-panel {padding: 1px 12px 12px 12px;background: #fff;padding-left: 12px;margin-top: 0;}.p1 {font-weight: normal;line-height: 22px;padding-bottom: 0;color: #222;padding: 15px 10px 8px 0;font-size: 100%;position: relative;}.p2 {height: 20px;padding-top: 2px;padding-right: 10px;color: #222;}.p2 .span {font-size: 16px;line-height: 20px;color: #ff3600;float: right;}.sale-panel {margin-top: 10px;background: #fff;padding: 1px 12px 12px 12px;}.tit {letter-spacing: 1px;color: #666;height: 14px;line-height: 14px;font-size: 14px;padding-left: 12px;position: relative;margin: 15px 0 0;}.tit::after {position: absolute;content: "";width: 2px;height: 100%;background: #56b244;left: 5px;top: 0;}.open {height: auto;text-overflow: inherit;-webkit-line-clamp: 100000;display: -webkit-box;-webkit-box-orient: vertical;overflow: hidden;line-height: 22px;margin-top: 13px;font-size: 14px;color: #333;position: relative;}.open img {width: 100%;}/* 底部按钮 */.fui-navbar {position: fixed;width: 100%;bottom: 0;z-index: 2;}.btn {border: none;font-size: 0.7rem;color: #fff;border-radius: 0;width: 50%;height: 49px;}.btn_left {background: #fe9402;float: left;}.btn_right {float: right;background: #fd5555;}</style>
<?php// 全局中间件定义文件return [// 全局请求缓存// \think\middleware\CheckRequestCache::class,// 多语言加载// \think\middleware\LoadLangPack::class,// Session初始化// \think\middleware\SessionInit::class//允许跨域传值\think\middleware\AllowCrossDomain::class,];
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号