Compare commits
27 Commits
f6d50d8d98
...
clean-main
| Author | SHA1 | Date | |
|---|---|---|---|
| 76cfa6b278 | |||
| 5fe5289e26 | |||
| 5455aceab5 | |||
| 41ad75af08 | |||
| daae84b827 | |||
| f7328c614a | |||
| 039055838e | |||
| dfec5819aa | |||
| e658c2a0fd | |||
| 7c34efae5c | |||
| c1220e7b8f | |||
| 14016c4144 | |||
| b984ed1dba | |||
| 09f117e59c | |||
| b8a9f9b62e | |||
| 1e542a55bf | |||
| 08992851e0 | |||
| 6963216a85 | |||
| 028886c1fe | |||
| 56f951d0bd | |||
| 16d1adacca | |||
| 49969d813a | |||
| 2f79f7fbcd | |||
| 3482382734 | |||
| 3f6112d6f1 | |||
| eeb443b225 | |||
| c61a34ec7d |
@@ -42,9 +42,21 @@ class Ad extends AdminBase
|
||||
}
|
||||
$this->_error($result);
|
||||
}
|
||||
// 确保 client 参数有效
|
||||
if (empty($client)) {
|
||||
$client = $this->request->param('client', '1');
|
||||
}
|
||||
$category_list = AdLogic::getGoodsCategory();
|
||||
$link_page = \app\common\model\Ad::getLinkPage($client);
|
||||
$position_list = AdLogic::infoPosition($client);
|
||||
$this->assign('category_list', AdLogic::getGoodsCategory());
|
||||
$this->assign('link_page', \app\common\model\Ad::getLinkPage($client));
|
||||
$this->assign('position_list', AdLogic::infoPosition($client));
|
||||
|
||||
$this->assign([
|
||||
'category_list' => $category_list,
|
||||
'link_page' => $link_page,
|
||||
'position_list' => $position_list,
|
||||
]);
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
|
||||
485
application/admin/controller/BulletinBoard.php
Normal file
485
application/admin/controller/BulletinBoard.php
Normal file
@@ -0,0 +1,485 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller;
|
||||
use app\admin\model\OrderGoods;
|
||||
use app\admin\model\OrderRecharge;
|
||||
use app\admin\model\OrderYearcard;
|
||||
use app\admin\model\User;
|
||||
use app\common\server\UrlServer;
|
||||
use think\Db;
|
||||
use think\facade\Url;
|
||||
use app\admin\model\Order;
|
||||
|
||||
class BulletinBoard extends AdminBase
|
||||
{
|
||||
|
||||
//看板统计
|
||||
public function index()
|
||||
{
|
||||
// 本月与上月时间范围
|
||||
$monthStart = date('Y-m-01 00:00:00');
|
||||
$monthEnd = date('Y-m-t 23:59:59');
|
||||
$lastMonthStart = date('Y-m-01 00:00:00', strtotime('-1 month'));
|
||||
$lastMonthEnd = date('Y-m-t 23:59:59', strtotime('-1 month'));
|
||||
$monthStartTs = strtotime($monthStart);
|
||||
$monthEndTs = strtotime($monthEnd);
|
||||
|
||||
//查询商品订单
|
||||
$orderMoney = Order::where('status','<>', 0)->sum('order_amount');
|
||||
//年卡订单
|
||||
$yearCardOrderMoney = OrderYearcard::where('status', 1)->sum('pay_fee');
|
||||
//订单管理
|
||||
$orderGoods = OrderGoods::where('status', 1)->sum('total_fee');
|
||||
//充值订单
|
||||
$rechargeOrderMoney = OrderRecharge::where('pay_status', 1)->sum('order_amount');
|
||||
|
||||
// 计算月销售总额(所有订单类型的总和)
|
||||
$monthlySales = ($orderMoney ?: 0) + ($yearCardOrderMoney ?: 0) + ($orderGoods ?: 0) + ($rechargeOrderMoney ?: 0);
|
||||
|
||||
// 计算月订单量(本月订单数量)
|
||||
$monthlyOrders = Order::where('status','<>', 0)
|
||||
->whereTime('create_time', 'month')
|
||||
->count();
|
||||
$monthlyOrders += OrderYearcard::where('status', 1)
|
||||
->whereTime('createtime', 'month')
|
||||
->count();
|
||||
$monthlyOrders += OrderGoods::where('status', 1)
|
||||
->whereTime('createtime', 'month')
|
||||
->count();
|
||||
$monthlyOrders += OrderRecharge::where('pay_status', 1)
|
||||
->whereTime('create_time', 'month')
|
||||
->count();
|
||||
|
||||
// 计算月客户数(本月新增用户)
|
||||
$monthlyCustomers = User::whereTime('create_time', 'month')
|
||||
->where('del', 0)
|
||||
->count();
|
||||
|
||||
// 计算同比(上个月的数据)
|
||||
$lastMonthSales = Order::where('status','<>', 0)
|
||||
->whereTime('create_time', 'last month')
|
||||
->sum('order_amount');
|
||||
$lastMonthSales += OrderYearcard::where('status', 1)
|
||||
->whereTime('createtime', 'last month')
|
||||
->sum('pay_fee');
|
||||
$lastMonthSales += OrderGoods::where('status', 1)
|
||||
->whereTime('createtime', 'last month')
|
||||
->sum('total_fee');
|
||||
$lastMonthSales += OrderRecharge::where('pay_status', 1)
|
||||
->whereTime('create_time', 'last month')
|
||||
->sum('order_amount');
|
||||
|
||||
$lastMonthOrders = Order::where('status','<>', 0)
|
||||
->whereTime('create_time', 'last month')
|
||||
->count();
|
||||
$lastMonthOrders += OrderYearcard::where('status', 1)
|
||||
->whereTime('createtime', 'last month')
|
||||
->count();
|
||||
$lastMonthOrders += OrderGoods::where('status', 1)
|
||||
->whereTime('createtime', 'last month')
|
||||
->count();
|
||||
$lastMonthOrders += OrderRecharge::where('pay_status', 1)
|
||||
->whereTime('create_time', 'last month')
|
||||
->count();
|
||||
|
||||
$lastMonthCustomers = User::whereTime('create_time', 'last month')
|
||||
->where('del', 0)
|
||||
->count();
|
||||
|
||||
// 计算同比变化率
|
||||
$salesCompare = $lastMonthSales > 0 ? round((($monthlySales - $lastMonthSales) / $lastMonthSales) * 100, 2) : 0;
|
||||
$ordersCompare = $lastMonthOrders > 0 ? round((($monthlyOrders - $lastMonthOrders) / $lastMonthOrders) * 100, 2) : 0;
|
||||
$customersCompare = $lastMonthCustomers > 0 ? round((($monthlyCustomers - $lastMonthCustomers) / $lastMonthCustomers) * 100, 2) : 0;
|
||||
|
||||
// 统计本月客户分析(老客户 vs 新客户)
|
||||
// 本月所有用户ID列表
|
||||
$monthUsers = User::whereTime('create_time', 'month')
|
||||
->where('del', 0)
|
||||
->column('id');
|
||||
|
||||
// 如果本月有用户,查询这些用户中哪些有订单(老客户)
|
||||
$oldCustomerCount = 0;
|
||||
$newCustomerCount = 0;
|
||||
if (!empty($monthUsers)) {
|
||||
// 查询本月注册的用户中,在Order表中有订单的用户(老客户)
|
||||
// 只要有订单就算老客户,不限制订单时间
|
||||
$oldCustomerIds = Order::where('status','<>', 0)
|
||||
->where('user_id', 'in', $monthUsers)
|
||||
->where('user_id', '>', 0)
|
||||
->distinct(true)
|
||||
->column('user_id');
|
||||
|
||||
$oldCustomerCount = count($oldCustomerIds);
|
||||
// 本月注册但没下过单的(新客户)
|
||||
$newCustomerCount = count($monthUsers) - $oldCustomerCount;
|
||||
}
|
||||
|
||||
// ========== 目标完成率与客服进度 ==========
|
||||
// 销售目标(可以后续做成后台可配置,这里先写死为 100000)
|
||||
$monthlyTarget = 100000;
|
||||
$overallCompletion = $monthlyTarget > 0 ? round(($monthlySales / $monthlyTarget) * 100, 2) : 0;
|
||||
|
||||
// 按客服统计本月与上月销售额
|
||||
$staffCurrent = Db::name('order')
|
||||
->alias('o')
|
||||
->join('admin a', 'o.admin_id = a.id', 'LEFT')
|
||||
->where('o.status', '<>', 0)
|
||||
->whereTime('o.create_time', 'between', [$monthStart, $monthEnd])
|
||||
->field('o.admin_id,a.name as staff_name,SUM(o.order_amount) as total')
|
||||
->group('o.admin_id')
|
||||
->select();
|
||||
|
||||
$staffLast = Db::name('order')
|
||||
->alias('o')
|
||||
->join('admin a', 'o.admin_id = a.id', 'LEFT')
|
||||
->where('o.status', '<>', 0)
|
||||
->whereTime('o.create_time', 'between', [$lastMonthStart, $lastMonthEnd])
|
||||
->field('o.admin_id,SUM(o.order_amount) as total')
|
||||
->group('o.admin_id')
|
||||
->select();
|
||||
|
||||
$staffLastMap = [];
|
||||
foreach ($staffLast as $row) {
|
||||
$staffLastMap[$row['admin_id']] = $row['total'];
|
||||
}
|
||||
|
||||
$staffProgress = [];
|
||||
foreach ($staffCurrent as $row) {
|
||||
$adminId = $row['admin_id'];
|
||||
$staffSales = (float)$row['total'];
|
||||
$lastSales = isset($staffLastMap[$adminId]) ? (float)$staffLastMap[$adminId] : 0;
|
||||
$percent = $monthlySales > 0 ? round(($staffSales / $monthlySales) * 100, 2) : 0;
|
||||
$yoy = $lastSales > 0 ? round((($staffSales - $lastSales) / $lastSales) * 100, 2) : 0;
|
||||
|
||||
$staffProgress[] = [
|
||||
'name' => $row['staff_name'] ?: '未分配',
|
||||
'sales' => $staffSales,
|
||||
'percent' => $percent,
|
||||
'yoy' => $yoy,
|
||||
];
|
||||
}
|
||||
|
||||
// ========== 渠道分析(当月订单数按渠道) ==========
|
||||
$channelRows = Db::name('order')
|
||||
->alias('o')
|
||||
->join('orderchannel c', 'o.channel_id = c.id', 'LEFT')
|
||||
->where('o.status', '<>', 0)
|
||||
->whereTime('o.create_time', 'month')
|
||||
->field('c.name as channel_name, COUNT(*) as total')
|
||||
->group('o.channel_id')
|
||||
->select();
|
||||
|
||||
$channelPie = [];
|
||||
foreach ($channelRows as $row) {
|
||||
$name = $row['channel_name'] ?: '其他';
|
||||
$value = (int)$row['total'];
|
||||
$channelPie[] = [
|
||||
'name' => $name,
|
||||
'value' => $value,
|
||||
];
|
||||
}
|
||||
|
||||
// ========== 每日销售趋势(仅商品订单,按天汇总) ==========
|
||||
$trendRows = Db::name('order')
|
||||
->where('status', '<>', 0)
|
||||
->whereTime('create_time', 'between', [$monthStart, $monthEnd])
|
||||
->field("FROM_UNIXTIME(create_time,'%Y-%m-%d') as day, SUM(order_amount) as total")
|
||||
->group('day')
|
||||
->order('day asc')
|
||||
->select();
|
||||
|
||||
$trendDates = [];
|
||||
$trendValues = [];
|
||||
$trendTotal = 0;
|
||||
foreach ($trendRows as $row) {
|
||||
$trendDates[] = $row['day'];
|
||||
$amount = (float)$row['total'];
|
||||
$trendValues[] = $amount;
|
||||
$trendTotal += $amount;
|
||||
}
|
||||
|
||||
// 上月总销售额(用于计算趋势图上的“上月同比”)
|
||||
$lastTrendTotal = Db::name('order')
|
||||
->where('status', '<>', 0)
|
||||
->whereTime('create_time', 'between', [$lastMonthStart, $lastMonthEnd])
|
||||
->sum('order_amount');
|
||||
|
||||
$trendCompare = $lastTrendTotal > 0 ? round((($trendTotal - $lastTrendTotal) / $lastTrendTotal) * 100, 2) : 0;
|
||||
|
||||
// ========== 区域月销售额(通过地址模糊匹配简单统计) ==========
|
||||
$regions = ['南明区', '云岩区', '白云区', '乌当区', '花溪区', '龙里'];
|
||||
$regionTotals = [];
|
||||
foreach ($regions as $regionName) {
|
||||
$total = Db::name('order')
|
||||
->where('status', '<>', 0)
|
||||
->whereTime('create_time', 'month')
|
||||
->whereLike('address', '%' . $regionName . '%')
|
||||
->sum('order_amount');
|
||||
$regionTotals[] = (float)$total;
|
||||
}
|
||||
|
||||
// ========== 本月销售情况(单次/年卡/次卡/其它服务) ==========
|
||||
// 复用统计图表控制器中的规则:根据 number 字段区分不同卡类型
|
||||
$salesSituation = [
|
||||
['value' => 0, 'name' => '单次服务'],
|
||||
['value' => 0, 'name' => '年卡销量'],
|
||||
['value' => 0, 'name' => '次卡销量'],
|
||||
['value' => 0, 'name' => '其它服务'],
|
||||
];
|
||||
$kaWhere = [
|
||||
['del', '=', 0],
|
||||
['create_time', '>=', $monthStartTs],
|
||||
['create_time', '<=', $monthEndTs],
|
||||
];
|
||||
// 单次服务:number = 1
|
||||
$salesSituation[0]['value'] = Db::name('order')
|
||||
->where($kaWhere)
|
||||
->where('number', '=', 1)
|
||||
->sum('total_amount');
|
||||
// 年卡:number > 6
|
||||
$salesSituation[1]['value'] = Db::name('order')
|
||||
->where($kaWhere)
|
||||
->where('number', '>', 6)
|
||||
->sum('total_amount');
|
||||
// 次卡:2 <= number <= 6
|
||||
$salesSituation[2]['value'] = Db::name('order')
|
||||
->where($kaWhere)
|
||||
->where('number', '>=', 2)
|
||||
->where('number', '<=', 6)
|
||||
->sum('total_amount');
|
||||
// 其它服务:number = 0
|
||||
$salesSituation[3]['value'] = Db::name('order')
|
||||
->where($kaWhere)
|
||||
->where('number', '=', 0)
|
||||
->sum('total_amount');
|
||||
|
||||
// ========== 渠道 & 区域详细拆分(总额 / 年卡 / 次卡 / 单次 / 其它) ==========
|
||||
$serviceTypes = [
|
||||
'total' => [],
|
||||
'year' => [['number', '>', 6]],
|
||||
'times' => [['number', '>=', 2], ['number', '<=', 6]],
|
||||
'single'=> [['number', '=', 1]],
|
||||
'other' => [['number', '=', 0]],
|
||||
];
|
||||
|
||||
// 渠道关键字到列 key 的映射
|
||||
$channelBuckets = [
|
||||
'meituan' => '美团',
|
||||
'gzh' => '公众号',
|
||||
'douyin' => '抖音',
|
||||
'staff' => '员工',
|
||||
'yeye' => '异业',
|
||||
'other' => '渠道',
|
||||
];
|
||||
|
||||
$channelDetail = [];
|
||||
foreach ($serviceTypes as $typeKey => $extraWhere) {
|
||||
$totals = [
|
||||
'meituan' => 0,
|
||||
'gzh' => 0,
|
||||
'douyin' => 0,
|
||||
'staff' => 0,
|
||||
'yeye' => 0,
|
||||
'other' => 0,
|
||||
];
|
||||
|
||||
$query = Db::name('order')
|
||||
->alias('o')
|
||||
->join('orderchannel c', 'o.channel_id = c.id', 'LEFT')
|
||||
->where('o.status', '<>', 0)
|
||||
->whereBetween('o.create_time', [$monthStartTs, $monthEndTs]);
|
||||
|
||||
if (!empty($extraWhere)) {
|
||||
$query->where($extraWhere);
|
||||
}
|
||||
|
||||
$rows = $query
|
||||
->field('c.name as channel_name, SUM(o.order_amount) as total')
|
||||
->group('o.channel_id')
|
||||
->select();
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$name = $row['channel_name'] ?? '';
|
||||
$value = (float)($row['total'] ?? 0);
|
||||
$bucket = 'other';
|
||||
if (mb_strpos($name, '美团') !== false) {
|
||||
$bucket = 'meituan';
|
||||
} elseif (mb_strpos($name, '公众号') !== false || mb_strpos($name, '公') !== false) {
|
||||
$bucket = 'gzh';
|
||||
} elseif (mb_strpos($name, '抖音') !== false) {
|
||||
$bucket = 'douyin';
|
||||
} elseif (mb_strpos($name, '员工') !== false) {
|
||||
$bucket = 'staff';
|
||||
} elseif (mb_strpos($name, '异业') !== false) {
|
||||
$bucket = 'yeye';
|
||||
}
|
||||
$totals[$bucket] += $value;
|
||||
}
|
||||
|
||||
$channelDetail[$typeKey] = $totals;
|
||||
}
|
||||
|
||||
// 区域明细:每种服务类型在各区域的销售额
|
||||
$regionDetail = [];
|
||||
foreach ($serviceTypes as $typeKey => $extraWhere) {
|
||||
$regionDetail[$typeKey] = [];
|
||||
foreach ($regions as $regionName) {
|
||||
$q = Db::name('order')
|
||||
->where('status', '<>', 0)
|
||||
->whereBetween('create_time', [$monthStartTs, $monthEndTs])
|
||||
->whereLike('address', '%' . $regionName . '%');
|
||||
if (!empty($extraWhere)) {
|
||||
$q->where($extraWhere);
|
||||
}
|
||||
$regionDetail[$typeKey][$regionName] = (float)$q->sum('order_amount');
|
||||
}
|
||||
}
|
||||
|
||||
// 汇总仪表盘数据供前端使用
|
||||
$dashboardData = [
|
||||
'monthlyTarget' => $monthlyTarget,
|
||||
'overallCompletion' => $overallCompletion,
|
||||
'staffProgress' => $staffProgress,
|
||||
'channelPie' => $channelPie,
|
||||
'trendDates' => $trendDates,
|
||||
'trendValues' => $trendValues,
|
||||
'trendCompare' => $trendCompare,
|
||||
'regions' => $regions,
|
||||
'regionTotals' => $regionTotals,
|
||||
'salesSituation' => $salesSituation,
|
||||
'channelDetail' => $channelDetail,
|
||||
'regionDetail' => $regionDetail,
|
||||
];
|
||||
|
||||
// 传递数据到视图
|
||||
$this->assign([
|
||||
'monthlySales' => $monthlySales,
|
||||
'monthlyOrders' => $monthlyOrders,
|
||||
'monthlyCustomers' => $monthlyCustomers,
|
||||
'salesCompare' => $salesCompare,
|
||||
'ordersCompare' => $ordersCompare,
|
||||
'customersCompare' => $customersCompare,
|
||||
'oldCustomers' => $oldCustomerCount, // 老客户数量(本月注册且下过单的)
|
||||
'newCustomers' => $newCustomerCount, // 新客户数量(本月注册但没下过单的)
|
||||
'dashboardData' => json_encode($dashboardData, JSON_UNESCAPED_UNICODE),
|
||||
]);
|
||||
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
|
||||
//地图上显示注册用户位置
|
||||
public function map()
|
||||
{
|
||||
//查询商品订单
|
||||
$orderMoney = Order::where('status','<>', 0)->sum('order_amount');
|
||||
//年卡订单
|
||||
$yearCardOrderMoney = OrderYearcard::where('status', 1)->sum('pay_fee');
|
||||
//订单管理
|
||||
$orderGoods = OrderGoods::where('status', 1)->sum('total_fee');
|
||||
//充值订单
|
||||
$rechargeOrderMoney = OrderRecharge::where('pay_status', 1)->sum('order_amount');
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
public function getUserMap()
|
||||
{
|
||||
// 查询有经纬度的用户
|
||||
$userArray = User::where('latitude', '<>', '')
|
||||
->where('longitude', '<>', '')
|
||||
->field('id,nickname,mobile,avatar,longitude,latitude')
|
||||
->select();
|
||||
// 格式化数据,转换为前端期望的字段名
|
||||
$result = [];
|
||||
foreach ($userArray as $user) {
|
||||
// 处理头像URL,使用代理接口避免CORS问题
|
||||
$avatar = '';
|
||||
if (!empty($user['avatar'])) {
|
||||
$originalUrl = UrlServer::getFileUrl($user['avatar']);
|
||||
// 去掉JSON编码时产生的转义反斜杠
|
||||
$originalUrl = str_replace('\\/', '/', $originalUrl);
|
||||
|
||||
// 如果URL是跨域的,使用代理接口
|
||||
$currentDomain = $this->request->domain();
|
||||
if (strpos($originalUrl, $currentDomain) === false) {
|
||||
// 跨域,使用代理(手动构建URL避免双重编码)
|
||||
$avatar = $this->request->domain() . '/admin/bulletin_board/proxyImage?url=' . rawurlencode($originalUrl);
|
||||
} else {
|
||||
// 同域,直接使用
|
||||
$avatar = $originalUrl;
|
||||
}
|
||||
}
|
||||
|
||||
$result[] = [
|
||||
'id' => $user['id'] ?? 0,
|
||||
'lng' => floatval($user['longitude'] ?? 0),
|
||||
'lat' => floatval($user['latitude'] ?? 0),
|
||||
'name' => $user['nickname'] ?? '',
|
||||
'contact' => $user['nickname'] ?? '', // 兼容两种字段名
|
||||
'mobile' => $user['mobile'] ?? '',
|
||||
'phone' => $user['mobile'] ?? '', // 兼容 telephone/phone
|
||||
'telephone' => $user['mobile'] ?? '',
|
||||
'avatar' => $avatar
|
||||
];
|
||||
}
|
||||
|
||||
return $this->_success('获取成功', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 图片代理接口,解决CORS跨域问题
|
||||
*/
|
||||
public function proxyImage()
|
||||
{
|
||||
$url = $this->request->get('url', '');
|
||||
if (empty($url)) {
|
||||
header('HTTP/1.1 404 Not Found');
|
||||
exit;
|
||||
}
|
||||
|
||||
// 解码URL
|
||||
$url = urldecode($url);
|
||||
|
||||
// 验证URL格式
|
||||
if (!filter_var($url, FILTER_VALIDATE_URL)) {
|
||||
header('HTTP/1.1 400 Bad Request');
|
||||
exit;
|
||||
}
|
||||
|
||||
// 只允许图片格式
|
||||
$allowedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
|
||||
$extension = strtolower(pathinfo(parse_url($url, PHP_URL_PATH), PATHINFO_EXTENSION));
|
||||
if (!in_array($extension, $allowedExtensions)) {
|
||||
header('HTTP/1.1 403 Forbidden');
|
||||
exit;
|
||||
}
|
||||
|
||||
// 获取图片
|
||||
$context = stream_context_create([
|
||||
'http' => [
|
||||
'method' => 'GET',
|
||||
'timeout' => 10,
|
||||
'header' => [
|
||||
'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
|
||||
]
|
||||
]
|
||||
]);
|
||||
|
||||
$imageData = @file_get_contents($url, false, $context);
|
||||
|
||||
if ($imageData === false) {
|
||||
header('HTTP/1.1 404 Not Found');
|
||||
exit;
|
||||
}
|
||||
|
||||
// 设置响应头
|
||||
header('Content-Type: image/' . ($extension === 'jpg' ? 'jpeg' : $extension));
|
||||
header('Cache-Control: public, max-age=3600');
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
header('Access-Control-Allow-Methods: GET');
|
||||
|
||||
// 输出图片
|
||||
echo $imageData;
|
||||
exit;
|
||||
}
|
||||
}
|
||||
239
application/admin/controller/Invoice.php
Normal file
239
application/admin/controller/Invoice.php
Normal file
@@ -0,0 +1,239 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\admin\model\Invoice as InvoiceModel;
|
||||
use app\admin\model\InvoiceLog;
|
||||
use app\common\server\UrlServer;
|
||||
use think\Db;
|
||||
|
||||
class Invoice extends AdminBase
|
||||
{
|
||||
/**
|
||||
* 发票列表
|
||||
*/
|
||||
public function lists()
|
||||
{
|
||||
if ($this->request->isAjax()) {
|
||||
$get = $this->request->get();
|
||||
|
||||
// 构建查询条件
|
||||
$where = [];
|
||||
if (!empty($get['keyword'])) {
|
||||
$where[] = ['oid|invoice_id', 'like', '%' . $get['keyword'] . '%'];
|
||||
}
|
||||
if (isset($get['state']) && $get['state'] !== '') {
|
||||
$where[] = ['state', '=', intval($get['state'])];
|
||||
}
|
||||
|
||||
// 查询数据(关联订单表获取订单编号)
|
||||
$list = Db::name('invoice_log')
|
||||
->where($where)
|
||||
->order('state asc')
|
||||
->select();
|
||||
|
||||
// 格式化数据
|
||||
$currentDomain = $_SERVER['HTTP_HOST'];
|
||||
$result = [];
|
||||
foreach ($list as $item) {
|
||||
$result[] = [
|
||||
'id' => $item['id'] ?? 0,
|
||||
'invoice_id' => $item['invoice_id'] ?? 0,
|
||||
'oid' => $item['oid'] ?? 0,
|
||||
'state' => $item['state'] ?? 1,
|
||||
'document' => "http://".$currentDomain."/public/".$item['document'] ?? '',
|
||||
'create_time' => $item['create_time'] ?? '',
|
||||
'update_time' => $item['update_time'] ?? '',
|
||||
];
|
||||
}
|
||||
|
||||
$data = [
|
||||
'count' => count($result),
|
||||
'lists' => $result
|
||||
];
|
||||
|
||||
$this->_success('', $data);
|
||||
}
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看详情
|
||||
*/
|
||||
public function info()
|
||||
{
|
||||
$id = $this->request->param('id', 0);
|
||||
if (empty($id)) {
|
||||
$this->_error('参数错误');
|
||||
}
|
||||
|
||||
$invoice = InvoiceLog::with([
|
||||
"order" => function ($query) {
|
||||
$query->field('id, order_sn');
|
||||
},
|
||||
"invoice" => function ($query) {
|
||||
$query->with('user');
|
||||
},
|
||||
])
|
||||
->where('id', $id)
|
||||
->find();
|
||||
if (empty($invoice)) {
|
||||
$this->_error('数据不存在');
|
||||
}
|
||||
|
||||
// 处理文件路径(转换为完整URL)
|
||||
$currentDomain = $_SERVER['HTTP_HOST'];
|
||||
if (!empty($invoice['document'])) {
|
||||
$invoice['document_url'] = "http://".$currentDomain."/public/".$invoice['document'];
|
||||
}
|
||||
|
||||
$this->assign([
|
||||
'invoice' => $invoice,
|
||||
]);
|
||||
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$id = $this->request->param('id', 0);
|
||||
if (empty($id)) {
|
||||
$this->_error('参数错误');
|
||||
}
|
||||
|
||||
if ($this->request->isAjax() && $this->request->isPost()) {
|
||||
$post = $this->request->post();
|
||||
|
||||
// 表单验证
|
||||
if (empty($post['invoice_id'])) {
|
||||
$this->_error('请输入发票信息ID');
|
||||
}
|
||||
if (empty($post['document'])){
|
||||
$this->_error('请上传发票文件');
|
||||
}
|
||||
$data = [
|
||||
'state' => $post['state'],
|
||||
'document' => $post['document'],
|
||||
'update_time' => date('Y-m-d H:i:s', time()),
|
||||
];
|
||||
|
||||
// 更新数据
|
||||
$result = Db::name('invoice_log')->where('id', $id)->update($data);
|
||||
|
||||
if ($result) {
|
||||
$this->_success('上传成功');
|
||||
} else {
|
||||
$this->_error('上传失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 查询订单列表
|
||||
$orders = Db::name('order')
|
||||
->where('order_status', '>', 0)
|
||||
->field('id, order_sn')
|
||||
->order('id desc')
|
||||
->limit(100)
|
||||
->select();
|
||||
|
||||
|
||||
|
||||
$invoice = InvoiceLog::with(['invoice'])->where('id',$id)->find();
|
||||
// 处理文件路径(转换为完整URL用于显示)
|
||||
if (!empty($invoice['document'])) {
|
||||
$currentDomain = $_SERVER['HTTP_HOST'];
|
||||
$invoice['document'] = 'http://'.$currentDomain.'/public/'.$invoice['document'];
|
||||
}
|
||||
$this->assign([
|
||||
'invoice' => $invoice,
|
||||
'orders' => $orders,
|
||||
]);
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
public function del()
|
||||
{
|
||||
if ($this->request->isAjax() && $this->request->isPost()) {
|
||||
$id = $this->request->post('id', 0);
|
||||
if (empty($id)) {
|
||||
$this->_error('参数错误');
|
||||
}
|
||||
|
||||
// 检查数据是否存在
|
||||
$invoice = Db::name('invoice_log')->where('id', $id)->find();
|
||||
if (empty($invoice)) {
|
||||
$this->_error('数据不存在');
|
||||
}
|
||||
|
||||
// 删除数据
|
||||
$result = Db::name('invoice_log')->where('id', $id)->delete();
|
||||
|
||||
if ($result) {
|
||||
$this->_success('删除成功');
|
||||
} else {
|
||||
$this->_error('删除失败');
|
||||
}
|
||||
} else {
|
||||
$this->_error('请求方式错误');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传发票文件
|
||||
*/
|
||||
public function upload()
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$file = $this->request->file('file');
|
||||
if (empty($file)) {
|
||||
$this->_error('请选择文件');
|
||||
}
|
||||
|
||||
// 获取文件信息
|
||||
$fileInfo = $file->getInfo();
|
||||
$fileName = $fileInfo['name'] ?? '';
|
||||
|
||||
// 验证文件类型(PDF)- 从文件名获取扩展名(最可靠的方法)
|
||||
$ext = '';
|
||||
if (!empty($fileName)) {
|
||||
// 使用pathinfo获取扩展名,支持中文文件名
|
||||
$ext = strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
|
||||
}
|
||||
|
||||
// 如果从文件名获取失败,尝试从MIME类型判断
|
||||
if (empty($ext) && isset($fileInfo['type'])) {
|
||||
$mimeType = strtolower($fileInfo['type']);
|
||||
if (strpos($mimeType, 'pdf') !== false || $mimeType === 'application/pdf') {
|
||||
$ext = 'pdf';
|
||||
}
|
||||
}
|
||||
|
||||
// 验证扩展名
|
||||
if (empty($ext) || $ext !== 'pdf') {
|
||||
$this->_error('只支持PDF格式文件,当前文件:' . $fileName . ',扩展名:' . ($ext ?: '未知'));
|
||||
}
|
||||
|
||||
// 设置验证规则
|
||||
$file->validate(['ext' => 'pdf']);
|
||||
|
||||
// 上传文件
|
||||
$uploadPath = rtrim(ROOT_PATH, '/\\') . '/public/uploads/invoice';
|
||||
$info = $file->move($uploadPath);
|
||||
if ($info) {
|
||||
// 返回文件路径(相对路径)
|
||||
$filePath = 'uploads/invoice/' . $info->getSaveName();
|
||||
$this->_success('上传成功', ['path' => $filePath]);
|
||||
} else {
|
||||
$errorMsg = $file->getError();
|
||||
$this->_error('上传失败:' . ($errorMsg ?: '未知错误'));
|
||||
}
|
||||
} else {
|
||||
$this->_error('请求方式错误');
|
||||
}
|
||||
}
|
||||
}
|
||||
266
application/admin/controller/Moments.php
Normal file
266
application/admin/controller/Moments.php
Normal file
@@ -0,0 +1,266 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\admin\model\Staff;
|
||||
use app\admin\server\MomentsServer;
|
||||
use think\Db;
|
||||
|
||||
class Moments extends AdminBase
|
||||
{
|
||||
public function lists()
|
||||
{
|
||||
if ($this->request->isAjax()) {
|
||||
$get = $this->request->get();
|
||||
$list = MomentsServer::getMoments();
|
||||
|
||||
// 格式化数据为前端期望的格式
|
||||
$data = [
|
||||
'count' => count($list),
|
||||
'lists' => $list
|
||||
];
|
||||
|
||||
$this->_success('', $data);
|
||||
}
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
public function add()
|
||||
{
|
||||
if ($this->request->isAjax() && $this->request->isPost()) {
|
||||
// 处理表单提交
|
||||
$post = $this->request->post();
|
||||
|
||||
// 表单验证
|
||||
if (empty($post['title'])) {
|
||||
$this->_error('请输入标题');
|
||||
}
|
||||
if (empty($post['sid'])) {
|
||||
$this->_error('请选择员工');
|
||||
}
|
||||
if (empty($post['goods_id'])) {
|
||||
$this->_error('请选择关联产品');
|
||||
}
|
||||
|
||||
// 处理图片字段(可能是数组格式 goods_image[])
|
||||
$goods_images = [];
|
||||
if (isset($post['goods_image'])) {
|
||||
if (is_array($post['goods_image'])) {
|
||||
// 数组格式,过滤空值
|
||||
$goods_images = array_filter($post['goods_image']);
|
||||
} else if (!empty($post['goods_image'])) {
|
||||
// 字符串格式(逗号分隔),转换为数组
|
||||
$goods_images = explode(',', $post['goods_image']);
|
||||
$goods_images = array_filter($goods_images);
|
||||
}
|
||||
}
|
||||
|
||||
// 验证图片
|
||||
if (empty($goods_images)) {
|
||||
$this->_error('请选择图片');
|
||||
}
|
||||
|
||||
// 将图片数组转换为逗号分隔的字符串
|
||||
$post['goods_image'] = implode(',', $goods_images);
|
||||
|
||||
// 添加创建时间
|
||||
$post['create_time'] = date('Y-m-d H:i:s',time());
|
||||
$post['page_views'] = 0;
|
||||
$post['like'] = 0;
|
||||
$post['collection'] = 0;
|
||||
// 保存数据
|
||||
$result = Db::name('moments')->insert($post);
|
||||
|
||||
if ($result) {
|
||||
$this->_success('添加成功');
|
||||
} else {
|
||||
$this->_error('添加失败');
|
||||
}
|
||||
}
|
||||
|
||||
//查询员工信息
|
||||
$staff = Db::name('staff')->where('onwork',1)->field('id,name')->select();
|
||||
//查询商品信息
|
||||
$goods = Db::name('goods')
|
||||
->where('status',1)
|
||||
->order('code desc')
|
||||
->field('id,name')->select();
|
||||
$this->assign([
|
||||
'staff' => $staff,
|
||||
'goods' => $goods,
|
||||
]);
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看详情
|
||||
*/
|
||||
public function info()
|
||||
{
|
||||
$id = $this->request->param('id', 0);
|
||||
if (empty($id)) {
|
||||
$this->_error('参数错误');
|
||||
}
|
||||
|
||||
$moment = Db::name('moments')->where('id', $id)->find();
|
||||
if (empty($moment)) {
|
||||
$this->_error('数据不存在');
|
||||
}
|
||||
|
||||
// 获取关联数据
|
||||
$staff = null;
|
||||
if (!empty($moment['sid'])) {
|
||||
$staff = Db::name('staff')->where('id', $moment['sid'])->field('id,name')->find();
|
||||
}
|
||||
|
||||
$goods = null;
|
||||
if (!empty($moment['goods_id'])) {
|
||||
$goods = Db::name('goods')->where('id', $moment['goods_id'])->field('id,name')->find();
|
||||
}
|
||||
|
||||
// 处理图片(转换为完整URL)
|
||||
$images = [];
|
||||
if (!empty($moment['goods_image'])) {
|
||||
$imageList = explode(',', $moment['goods_image']);
|
||||
foreach ($imageList as $img) {
|
||||
$img = trim($img);
|
||||
if (!empty($img)) {
|
||||
$images[] = \app\common\server\UrlServer::getFileUrl($img);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->assign([
|
||||
'moment' => $moment,
|
||||
'staff' => $staff,
|
||||
'goods' => $goods,
|
||||
'images' => $images,
|
||||
]);
|
||||
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$id = $this->request->param('id', 0);
|
||||
if (empty($id)) {
|
||||
$this->_error('参数错误');
|
||||
}
|
||||
|
||||
if ($this->request->isAjax() && $this->request->isPost()) {
|
||||
// 处理表单提交
|
||||
$post = $this->request->post();
|
||||
|
||||
// 表单验证
|
||||
if (empty($post['title'])) {
|
||||
$this->_error('请输入标题');
|
||||
}
|
||||
if (empty($post['sid'])) {
|
||||
$this->_error('请选择员工');
|
||||
}
|
||||
if (empty($post['goods_id'])) {
|
||||
$this->_error('请选择关联产品');
|
||||
}
|
||||
|
||||
// 处理图片字段(可能是数组格式 goods_image[])
|
||||
$goods_images = [];
|
||||
if (isset($post['goods_image'])) {
|
||||
if (is_array($post['goods_image'])) {
|
||||
// 数组格式,过滤空值
|
||||
$goods_images = array_filter($post['goods_image']);
|
||||
} else if (!empty($post['goods_image'])) {
|
||||
// 字符串格式(逗号分隔),转换为数组
|
||||
$goods_images = explode(',', $post['goods_image']);
|
||||
$goods_images = array_filter($goods_images);
|
||||
}
|
||||
}
|
||||
|
||||
// 验证图片
|
||||
if (empty($goods_images)) {
|
||||
$this->_error('请选择图片');
|
||||
}
|
||||
|
||||
// 将图片数组转换为逗号分隔的字符串
|
||||
$post['goods_image'] = implode(',', $goods_images);
|
||||
|
||||
// 更新数据
|
||||
$result = Db::name('moments')->where('id', $id)->update($post);
|
||||
|
||||
if ($result !== false) {
|
||||
$this->_success('编辑成功');
|
||||
} else {
|
||||
$this->_error('编辑失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 获取当前数据
|
||||
$moment = Db::name('moments')->where('id', $id)->find();
|
||||
if (empty($moment)) {
|
||||
$this->_error('数据不存在');
|
||||
}
|
||||
|
||||
// 处理图片(转换为完整URL用于显示,同时保存原始路径用于提交)
|
||||
$images = [];
|
||||
$imagePaths = [];
|
||||
if (!empty($moment['goods_image'])) {
|
||||
$imageList = explode(',', $moment['goods_image']);
|
||||
foreach ($imageList as $img) {
|
||||
$img = trim($img);
|
||||
if (!empty($img)) {
|
||||
$imagePaths[] = $img; // 保存原始路径用于提交
|
||||
$images[] = \app\common\server\UrlServer::getFileUrl($img); // 转换为完整URL用于显示
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//查询员工信息
|
||||
$staff = Db::name('staff')->where('onwork',1)->field('id,name')->select();
|
||||
//查询商品信息
|
||||
$goodsList = Db::name('goods')
|
||||
->where('status',1)
|
||||
->order('code desc')
|
||||
->field('id,name')->select();
|
||||
|
||||
$this->assign([
|
||||
'moment' => $moment,
|
||||
'staff' => $staff,
|
||||
'goods' => $goodsList,
|
||||
'images' => $images,
|
||||
'imagePaths' => $imagePaths, // 传递原始路径
|
||||
]);
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
public function del()
|
||||
{
|
||||
if ($this->request->isAjax() && $this->request->isPost()) {
|
||||
$id = $this->request->post('id', 0);
|
||||
if (empty($id)) {
|
||||
$this->_error('参数错误');
|
||||
}
|
||||
|
||||
// 检查数据是否存在
|
||||
$moment = Db::name('moments')->where('id', $id)->find();
|
||||
if (empty($moment)) {
|
||||
$this->_error('数据不存在');
|
||||
}
|
||||
|
||||
// 删除数据
|
||||
$result = Db::name('moments')->where('id', $id)->delete();
|
||||
|
||||
if ($result) {
|
||||
$this->_success('删除成功');
|
||||
} else {
|
||||
$this->_error('删除失败');
|
||||
}
|
||||
} else {
|
||||
$this->_error('请求方式错误');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -100,26 +100,42 @@ class Order extends AdminBase
|
||||
*/
|
||||
public function del()
|
||||
{
|
||||
|
||||
if ($this->request->isAjax()) {
|
||||
dump(123);die;
|
||||
// $post = $this->request->post('');
|
||||
// $order=Db::name('order')->where('id',$post['order_id'])->find();//查询订单信息
|
||||
|
||||
// if($this->admin_id!=6){
|
||||
// $this->_error('无权限删除');
|
||||
// }else{
|
||||
// $orderdel=Db::name('order_exe')->where('order_sn',$order['order_sn'])->find();
|
||||
// if($orderdel){
|
||||
// $this->_error('无法删除,存在主订单');
|
||||
// }else{
|
||||
// $del=Db::name('order')->where('id',$post['order_id'])->delete();
|
||||
// $this->_success('删除成功');
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
$id = $this->request->get('id');
|
||||
$order = Db::name('order')->find($id);//查询订单信息
|
||||
if ($order == null){
|
||||
$this->_error('订单不存在');
|
||||
}
|
||||
$del = Db::name('order')->where('id',$id)->update(['del' => 1]);
|
||||
if($del){
|
||||
$this->_success('删除成功');
|
||||
}else{
|
||||
$this->_error('删除失败');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* User: 恢复已删除订单
|
||||
* Desc: 将 del 从 1 恢复为 0
|
||||
*/
|
||||
public function recover()
|
||||
{
|
||||
if ($this->request->isAjax()) {
|
||||
$id = $this->request->get('id');
|
||||
$order = Db::name('order')->find($id);// 查询订单信息
|
||||
if ($order == null){
|
||||
$this->_error('订单不存在');
|
||||
}
|
||||
if ($order['del'] == 0) {
|
||||
$this->_error('订单未删除,无需恢复');
|
||||
}
|
||||
$res = Db::name('order')->where('id',$id)->update(['del' => 0]);
|
||||
if ($res) {
|
||||
$this->_success('恢复成功');
|
||||
} else {
|
||||
$this->_error('恢复失败');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -660,6 +660,13 @@ public function group_del(){
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
// 员工工资导出
|
||||
public function exportWages()
|
||||
{
|
||||
$get = $this->request->get();
|
||||
$this->_success('', StaffLogic::wagesExport($get));
|
||||
}
|
||||
|
||||
//删除员工的工资
|
||||
public function wagesdel(){
|
||||
$post = $this->request->post('id'); //获取到传递过来的参数
|
||||
|
||||
@@ -218,10 +218,37 @@ class AdLogic
|
||||
*/
|
||||
public static function infoPosition($client)
|
||||
{
|
||||
$position_list = Db::name('ad_position')
|
||||
->where(['client' => $client, 'status' => 1, 'del' => 0])
|
||||
->group('name')
|
||||
->column('id,name', 'id');
|
||||
$position_list = [];
|
||||
|
||||
// 使用错误抑制,避免 unserialize 警告影响页面
|
||||
$originalErrorReporting = error_reporting(0);
|
||||
|
||||
try {
|
||||
// 使用原始 SQL 查询,完全绕过 ThinkPHP 的类型转换
|
||||
$prefix = config('database.prefix');
|
||||
$tableName = $prefix . 'ad_position';
|
||||
$sql = "SELECT DISTINCT `id`, `name` FROM `{$tableName}` WHERE `client` = " . intval($client) . " AND `status` = 1 AND `del` = 0 GROUP BY `name`";
|
||||
|
||||
$result = Db::query($sql);
|
||||
|
||||
if (!empty($result) && is_array($result)) {
|
||||
foreach ($result as $row) {
|
||||
if (isset($row['id']) && isset($row['name'])) {
|
||||
$position_list[$row['id']] = $row['name'];
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
// 忽略所有异常
|
||||
} catch (\Error $e) {
|
||||
// 忽略所有错误
|
||||
} catch (\Throwable $e) {
|
||||
// 捕获所有可抛出的对象
|
||||
} finally {
|
||||
// 恢复错误报告级别
|
||||
error_reporting($originalErrorReporting);
|
||||
}
|
||||
|
||||
asort($position_list);
|
||||
return $position_list;
|
||||
}
|
||||
|
||||
@@ -57,14 +57,11 @@ class ControlLogic{
|
||||
$item['add']=$order_info['add'];
|
||||
|
||||
$order=Db::name('order')->where('order_sn',$order_info['order_sn'])->find();
|
||||
$item['adderss']=$order['address'];
|
||||
|
||||
if ($order != null){
|
||||
$item['adderss']=$order['address'] ?? "";
|
||||
$goods=Db::name('goods')->where('id',$order['goods_id'])->find();
|
||||
|
||||
$item['goods_name']=$goods['name'];
|
||||
|
||||
|
||||
|
||||
$item['goods_name']=$goods['name'] ?? "";
|
||||
}
|
||||
}
|
||||
|
||||
return ['count'=>$count , 'lists'=>$lists];
|
||||
|
||||
@@ -47,6 +47,7 @@ class GoodsCategoryLogic
|
||||
'level' => $level + 1,
|
||||
'is_recommend' => $post['pid'] == 0 ? $is_recommend : 0,
|
||||
'remark' => $post['remark'],
|
||||
'type' => $post['type'], //1:普通分类 2:推荐分类
|
||||
'create_time' => time(),
|
||||
'update_time' => time(),
|
||||
];
|
||||
@@ -77,6 +78,7 @@ class GoodsCategoryLogic
|
||||
'pid' => $post['pid'],
|
||||
'is_recommend' => $post['pid'] == 0 ? $is_recommend : 0,
|
||||
'remark' => $post['remark'],
|
||||
'type' => $post['type'], //1:普通分类 2:推荐分类
|
||||
'update_time' => time(),
|
||||
];
|
||||
|
||||
@@ -128,7 +130,7 @@ class GoodsCategoryLogic
|
||||
$lists = Db::name('goods_category')
|
||||
->where(['del' => 0])
|
||||
->order('id asc')
|
||||
->column('id,name,pid,is_recommend,is_show,level,image,sort');
|
||||
->column('id,name,pid,is_recommend,is_show,level,image,sort,type');
|
||||
foreach ($lists as $k => $item){
|
||||
$lists[$k]['image'] = UrlServer::getFileUrl($item['image']);
|
||||
}
|
||||
|
||||
@@ -291,7 +291,8 @@ class GoodsLogic
|
||||
'give_integral_type' => $give_integral_type,
|
||||
'give_integral' => $give_integral,
|
||||
'spec_type' => $post['spec_type'],
|
||||
'create_time' => $time
|
||||
'create_time' => $time,
|
||||
'type' => $post['type']
|
||||
];
|
||||
$goods_id = Db::name('goods')->insertGetId($data);
|
||||
|
||||
@@ -481,7 +482,8 @@ class GoodsLogic
|
||||
'give_integral_type' => $give_integral_type,
|
||||
'give_integral' => $give_integral,
|
||||
'spec_type' => $post['spec_type'],
|
||||
'update_time' => $time
|
||||
'update_time' => $time,
|
||||
'type' => $post['type'],
|
||||
];
|
||||
|
||||
Db::name('goods')
|
||||
|
||||
@@ -28,17 +28,21 @@ class OrderLogic
|
||||
/**
|
||||
* Notes: 列表查询条件
|
||||
* @param $get
|
||||
* @author 段誉(2021/2/1 10:12)
|
||||
* @return array
|
||||
* @author 段誉(2021/2/1 10:12)
|
||||
*/
|
||||
public static function getListsCondition($get)
|
||||
{
|
||||
$where = [];
|
||||
|
||||
if ($get['type'] != 66){
|
||||
//订单状态
|
||||
if ($get['type'] != '') {
|
||||
$where[] = ['pay_status', '=', $get['type']];
|
||||
}
|
||||
$where[] = ['del', '=', 0];
|
||||
}else{
|
||||
$where[] = ['del', '=', 1];
|
||||
}
|
||||
//订单编号查询
|
||||
if (isset($get['order_sn']) && $get['order_sn'] != '') {
|
||||
$where[] = ['order_sn', 'like', '%' . $get['order_sn'] . '%'];
|
||||
@@ -80,7 +84,6 @@ class OrderLogic
|
||||
}
|
||||
|
||||
|
||||
|
||||
//配送方式
|
||||
if (isset($get['delivery_type']) && $get['delivery_type'] != '') {
|
||||
$where[] = ['delivery_type', '=', $get['delivery_type']];
|
||||
@@ -110,15 +113,15 @@ class OrderLogic
|
||||
/**
|
||||
* Notes: 列表
|
||||
* @param $get
|
||||
* @author 段誉(2021/2/1 10:12)
|
||||
* @return array
|
||||
* @author 段誉(2021/2/1 10:12)
|
||||
*/
|
||||
public static function lists($get)
|
||||
{
|
||||
$order = new Order();
|
||||
$where = self::getListsCondition($get);
|
||||
$field = 'o.*,order_status as order_status_text,pay_way as pay_way_text';
|
||||
$brand = Db::name('goods_brand')->where(['del'=>0])->column('name','id'); //订单类型
|
||||
$brand = Db::name('goods_brand')->column('name', 'id'); //订单类型
|
||||
$admin = Db::name('admin')->column('name', 'id');
|
||||
$count = $order
|
||||
->where($where)
|
||||
@@ -142,7 +145,6 @@ class OrderLogic
|
||||
}
|
||||
|
||||
|
||||
|
||||
//获取订单的商品
|
||||
$goods = GoodsLogic::goodsinfo($item['goods_id']);
|
||||
if ($goods) {
|
||||
@@ -267,7 +269,8 @@ class OrderLogic
|
||||
}
|
||||
|
||||
|
||||
public static function exportorder($get){
|
||||
public static function exportorder($get)
|
||||
{
|
||||
$where[] = ['o.del', '=', 0];
|
||||
$where = self::getListsCondition($get);
|
||||
$lists = Db::name('order')->where($where)->select(); //获取订单的内容
|
||||
@@ -313,8 +316,6 @@ class OrderLogic
|
||||
$dsynumber = $item['number'] - $ervice;
|
||||
|
||||
|
||||
|
||||
|
||||
if ($item['pay_zd'] == 0) {
|
||||
$item['pay_zd'] = '已收款';
|
||||
} else {
|
||||
@@ -333,10 +334,11 @@ class OrderLogic
|
||||
/**
|
||||
* Notes: 我的订单导出功能
|
||||
* @param $get
|
||||
* @author 段誉(2021/2/1 10:12)
|
||||
* @return array
|
||||
* @author 段誉(2021/2/1 10:12)
|
||||
*/
|
||||
public static function userexport($get){
|
||||
public static function userexport($get)
|
||||
{
|
||||
|
||||
$where = [];
|
||||
$where = self::getListsCondition($get);
|
||||
@@ -538,8 +540,8 @@ class OrderLogic
|
||||
/**
|
||||
* Notes: 详情
|
||||
* @param $id
|
||||
* @author 段誉(2021/2/1 10:12)
|
||||
* @return Order
|
||||
* @author 段誉(2021/2/1 10:12)
|
||||
*/
|
||||
public static function getDetail($id)
|
||||
{
|
||||
@@ -561,6 +563,7 @@ class OrderLogic
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 取消订单(返回商品规格表库存)
|
||||
* @param $order_id
|
||||
@@ -618,11 +621,11 @@ class OrderLogic
|
||||
|
||||
/**
|
||||
* Notes: 物流公司
|
||||
* @author 段誉(2021/2/1 10:15)
|
||||
* @return array|\PDOStatement|string|\think\Collection
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
* @author 段誉(2021/2/1 10:15)
|
||||
*/
|
||||
public static function express()
|
||||
{
|
||||
@@ -630,19 +633,17 @@ class OrderLogic
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Notes: 发货操作
|
||||
* @param $data
|
||||
* @param $admin_id
|
||||
* @author 段誉(2021/2/1 10:15)
|
||||
* @return bool
|
||||
* @throws \think\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
* @throws \think\exception\PDOException
|
||||
* @author 段誉(2021/2/1 10:15)
|
||||
*/
|
||||
public static function deliveryHandle($data, $admin_id)
|
||||
{
|
||||
@@ -733,8 +734,6 @@ class OrderLogic
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Notes: 确认收货
|
||||
* @param $order_id
|
||||
@@ -766,15 +765,14 @@ class OrderLogic
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Notes: 物流信息
|
||||
* @param $order_id
|
||||
* @author 段誉(2021/2/1 10:16)
|
||||
* @return array|\PDOStatement|string|\think\Model|null
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
* @author 段誉(2021/2/1 10:16)
|
||||
*/
|
||||
public static function shippingInfo($order_id)
|
||||
{
|
||||
@@ -790,11 +788,11 @@ class OrderLogic
|
||||
/**
|
||||
* Notes: 物流轨迹
|
||||
* @param $order_id
|
||||
* @author 段誉(2021/2/1 10:16)
|
||||
* @return array|bool
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
* @author 段誉(2021/2/1 10:16)
|
||||
*/
|
||||
public static function getShipping($order_id)
|
||||
{
|
||||
@@ -868,7 +866,8 @@ class OrderLogic
|
||||
* @param $id int 订单id
|
||||
* @return string
|
||||
*/
|
||||
public static function orderPrint($id){
|
||||
public static function orderPrint($id)
|
||||
{
|
||||
try {
|
||||
|
||||
//打印机配置
|
||||
@@ -901,7 +900,8 @@ class OrderLogic
|
||||
}
|
||||
}
|
||||
|
||||
public static function getPrintOrder($id){
|
||||
public static function getPrintOrder($id)
|
||||
{
|
||||
$order = new Order();
|
||||
$result = $order
|
||||
->with(['user', 'order_goods'])
|
||||
@@ -920,7 +920,8 @@ class OrderLogic
|
||||
}
|
||||
|
||||
//后台增加订单
|
||||
public static function add($post){
|
||||
public static function add($post)
|
||||
{
|
||||
$adder = UserLogic::adder($post['user_id']); //获取用户的地址
|
||||
$goods = Db::name('goods')->where('id', $post['goods_id'])->find(); //获取商品的ID
|
||||
$user = Db::name('user')->where('mobile', $adder['telephone'])->find();
|
||||
@@ -936,6 +937,13 @@ class OrderLogic
|
||||
$post['gord_id'] = 0;
|
||||
}
|
||||
$post['order_sn'] = createSn('order', 'order_sn', '', 4);
|
||||
if ($post['order_ysck'] == 1) {
|
||||
$pay_status = 0;
|
||||
$order_status = 0;
|
||||
} else {
|
||||
$pay_status = 1;
|
||||
$order_status = 1;
|
||||
}
|
||||
$data = [
|
||||
'order_sn' => $post['order_sn'],
|
||||
'goods_id' => $post['goods_id'],
|
||||
@@ -949,10 +957,12 @@ class OrderLogic
|
||||
'lat' => $adder['lat'],
|
||||
'lng' => $adder['lng'],
|
||||
'goods_price' => $post['total_amount'],
|
||||
'order_amount'=>$post['total_amount'],
|
||||
// 'order_amount'=>$post['total_amount'],
|
||||
'order_amount' => $goods['max_price'],
|
||||
'total_amount' => $post['total_amount'],
|
||||
'pay_zd' => $post['order_ysck'],
|
||||
'pay_status'=>1,
|
||||
'pay_status' => $pay_status,
|
||||
'order_status' => $order_status,
|
||||
'code' => $goods['code'],
|
||||
'number' => $goods['code'],
|
||||
'channel_id' => $post['channel_id'],
|
||||
@@ -967,12 +977,14 @@ class OrderLogic
|
||||
}
|
||||
|
||||
//根据订单编号获取到订单信息
|
||||
public static function orderinfo($order_sn){
|
||||
public static function orderinfo($order_sn)
|
||||
{
|
||||
return Db::name('order')->where('order_sn', $order_sn)->find();
|
||||
}
|
||||
|
||||
//根据订单ID获取到订单信息
|
||||
public static function orderinfoid($id){
|
||||
public static function orderinfoid($id)
|
||||
{
|
||||
return Db::name('order')->where('id', $id)->find();
|
||||
}
|
||||
|
||||
@@ -1085,25 +1097,29 @@ class OrderLogic
|
||||
}
|
||||
|
||||
|
||||
public static function edit($post){
|
||||
return Db::name('order')->where('id',$post['id'])->update(['consignee'=>$post['name'],
|
||||
public static function edit($post)
|
||||
{
|
||||
if ($post['pay_status'] == 1) {
|
||||
$pay = 0;
|
||||
} else {
|
||||
$pay = 1;
|
||||
}
|
||||
$res = Db::name('order')->where('id', $post['id'])->update(['consignee' => $post['name'],
|
||||
'address' => $post['address'],
|
||||
'mobile' => $post['phone'],
|
||||
'pay_status'=>$post['pay_status'],
|
||||
'pay_status' => $pay,
|
||||
'order_status' => $pay,
|
||||
'province' => $post['first_category_id'],
|
||||
'city' => $post['second_category_id'],
|
||||
'district' => $post['third_category_id'],
|
||||
'lat' => $post['store_longitude'],
|
||||
'lng' => $post['store_latitude'],
|
||||
'gord_id' => $post['gord_id'],
|
||||
'pay_status'=>1,
|
||||
'pay_zd' => $post['pay_status'],
|
||||
'channel_id' => $post['brand_id'],
|
||||
'order_amount' => $post['total_amount']]);
|
||||
|
||||
|
||||
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1129,7 +1145,8 @@ class OrderLogic
|
||||
}
|
||||
}
|
||||
|
||||
public static function channel_update($post){
|
||||
public static function channel_update($post)
|
||||
{
|
||||
|
||||
$order = Db::name('order')->where('id', $post['id'])->find();
|
||||
Db::name('order')->where('id', $post['id'])->update(['channel_id' => $post['channel_id']]);
|
||||
|
||||
@@ -14,7 +14,9 @@ class OrderautoLogic{
|
||||
public static function lists($get){
|
||||
$where = [];
|
||||
//判断已经支付的订单
|
||||
$where[] = ['pay_status', '=', 1];
|
||||
// $where[] = ['pay_status', '=', 1];
|
||||
$where[] = ['refund_status', '=', 0];
|
||||
$where[] = ['del', '=', 0];
|
||||
if(isset($get['type']) && $get['type'] != ''){
|
||||
$where[] = ['static','=',$get['type']];
|
||||
}
|
||||
@@ -38,10 +40,8 @@ class OrderautoLogic{
|
||||
$where[] = ['status','=',$get['status']];
|
||||
}
|
||||
|
||||
// 执行状态查询
|
||||
if(isset($get['admin']) && $get['admin']!= ''){
|
||||
$where[] = ['admin_id','=',$get['admin']];
|
||||
}
|
||||
// 如果订单的admin_id不等于空,不需要限制支付状态;如果admin_id等于空,只查询已支付的订单
|
||||
$where[] = ['', 'exp', Db::raw("(admin_id IS NOT NULL AND admin_id != '') OR pay_status = 1")];
|
||||
// 订单的来源查询
|
||||
if(isset($get['pid']) && $get['pid']!= ''){
|
||||
$where[] = ['channel_id','=',$get['pid']];
|
||||
|
||||
@@ -625,6 +625,47 @@ class StaffLogic{
|
||||
return Db::name('staff')->where('id',$post['id'])->update(['lng'=>$post['store_longitude'],'lat'=>$post['store_latitude']]);
|
||||
}
|
||||
|
||||
// 员工工资导出数据(基于 wages 列表结果,避免重复重算导致超时)
|
||||
public static function wagesExport($get)
|
||||
{
|
||||
// 导出时最多导出 5000 条,且沿用 wages 的统计逻辑
|
||||
$get['page'] = 1;
|
||||
$get['limit'] = isset($get['limit']) && (int)$get['limit'] > 0 ? (int)$get['limit'] : 5000;
|
||||
|
||||
$data = self::wages($get);
|
||||
$lists = $data['lists'] ?? [];
|
||||
|
||||
// 组装导出数据
|
||||
$exportTitle = ['员工姓名', '员工电话', '服务总订单', '上午订单', '下午订单', '财务报销', '上午加时', '下午加时', '请假天数', '出勤天数', '罚款金额', '异常订单', '年卡订单', '物料金额'];
|
||||
$exportData = [];
|
||||
foreach ($lists as $row) {
|
||||
$exportData[] = [
|
||||
$row['name'] ?? '',
|
||||
$row['mobile'] ?? '',
|
||||
$row['total_orders'] ?? 0,
|
||||
$row['sw_orders'] ?? 0,
|
||||
$row['xw_orders'] ?? 0,
|
||||
$row['finance'] ?? 0,
|
||||
$row['sw_addtimes'] ?? 0,
|
||||
$row['xw_addtimes'] ?? 0,
|
||||
$row['leaves'] ?? 0,
|
||||
$row['attendance'] ?? 0,
|
||||
$row['fine'] ?? 0,
|
||||
$row['abnormal'] ?? 0,
|
||||
$row['annual'] ?? 0,
|
||||
$row['erp_staff'] ?? 0,
|
||||
];
|
||||
}
|
||||
|
||||
$exportExt = 'xls';
|
||||
return [
|
||||
'exportTitle' => $exportTitle,
|
||||
'exportData' => $exportData,
|
||||
'exportExt' => $exportExt,
|
||||
'exportName' => '员工工资-' . date('Y-m-d H:i:s'),
|
||||
];
|
||||
}
|
||||
|
||||
//获取员工积分记录
|
||||
public static function points($get){
|
||||
$where=[];
|
||||
|
||||
19
application/admin/model/Invoice.php
Normal file
19
application/admin/model/Invoice.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
class Invoice extends Model
|
||||
{
|
||||
protected $name = 'invoice';
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'uid', 'id');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
20
application/admin/model/InvoiceLog.php
Normal file
20
application/admin/model/InvoiceLog.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
class InvoiceLog extends Model
|
||||
{
|
||||
protected $name = 'invoice_log';
|
||||
|
||||
public function invoice()
|
||||
{
|
||||
return $this->belongsTo(Invoice::class, 'invoice_id', 'id');
|
||||
}
|
||||
|
||||
public function order()
|
||||
{
|
||||
return $this->belongsTo(Order::class, 'oid', 'id');
|
||||
}
|
||||
}
|
||||
33
application/admin/model/Moments.php
Normal file
33
application/admin/model/Moments.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use app\common\model\Goods;
|
||||
use think\Model;
|
||||
|
||||
class Moments extends Model
|
||||
{
|
||||
protected $name = 'moments';
|
||||
|
||||
/**
|
||||
* 关联员工(belongsTo:moments 属于 staff,moments.sid = staff.id)
|
||||
*/
|
||||
public function getStaff()
|
||||
{
|
||||
return $this->belongsTo(Staff::class, 'sid', 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联订单(belongsTo:moments 属于 order,moments.oid = order.id)
|
||||
*/
|
||||
public function getOrder()
|
||||
{
|
||||
return $this->belongsTo(Order::class, 'oid', 'id');
|
||||
}
|
||||
|
||||
//关联产品
|
||||
public function getProduct()
|
||||
{
|
||||
return $this->belongsTo(Goods::class, 'goods_id', 'id');
|
||||
}
|
||||
}
|
||||
10
application/admin/model/Order.php
Normal file
10
application/admin/model/Order.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
class Order extends Model
|
||||
{
|
||||
protected $name = 'order';
|
||||
}
|
||||
10
application/admin/model/OrderGoods.php
Normal file
10
application/admin/model/OrderGoods.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
class OrderGoods extends Model
|
||||
{
|
||||
protected $name = 'order_service';
|
||||
}
|
||||
10
application/admin/model/OrderRecharge.php
Normal file
10
application/admin/model/OrderRecharge.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
class OrderRecharge extends Model
|
||||
{
|
||||
protected $name = 'recharge_order';
|
||||
}
|
||||
10
application/admin/model/OrderYearcard.php
Normal file
10
application/admin/model/OrderYearcard.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
class OrderYearcard extends Model
|
||||
{
|
||||
protected $name = 'order_yearcard';
|
||||
}
|
||||
10
application/admin/model/Staff.php
Normal file
10
application/admin/model/Staff.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
class Staff extends Model
|
||||
{
|
||||
protected $name = 'staff';
|
||||
}
|
||||
91
application/admin/server/MomentsServer.php
Normal file
91
application/admin/server/MomentsServer.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\server;
|
||||
|
||||
use app\admin\model\Moments;
|
||||
use app\common\server\UrlServer;
|
||||
use think\Db;
|
||||
|
||||
class MomentsServer
|
||||
{
|
||||
public static function getMoments()
|
||||
{
|
||||
try {
|
||||
$data = Moments::with([
|
||||
'getStaff'=>function ($query) {
|
||||
$query->field('id,name');
|
||||
},
|
||||
'getOrder'=>function ($query) {
|
||||
$query->field('id,order_sn');
|
||||
},
|
||||
'getProduct'=>function ($query) {
|
||||
$query->field('id,name');
|
||||
}
|
||||
])
|
||||
->order('id desc')
|
||||
->select();
|
||||
|
||||
// 如果查询结果为空,尝试不使用关联查询
|
||||
if (empty($data)) {
|
||||
$data = Moments::order('id desc')->select();
|
||||
}
|
||||
//处理数据
|
||||
$result = [];
|
||||
if ($data != null){
|
||||
foreach ($data as $value) {
|
||||
// 从 goods_image 字段中取第一张图片作为封面
|
||||
$img = '';
|
||||
if (!empty($value['goods_image'])) {
|
||||
$images = explode(',', $value['goods_image']);
|
||||
$img = trim($images[0]);
|
||||
$img = UrlServer::getFileUrl($img);
|
||||
}
|
||||
|
||||
$result[] = [
|
||||
'id' => $value['id'] ?? 0,
|
||||
'title' => $value['title'] ?? '',
|
||||
'order_sn' => $value['order_id'],
|
||||
'img' => $img,
|
||||
'create_time' => $value['create_time'] ?? '',
|
||||
'staff_name' => $value['getStaff']['name'] ?? null,
|
||||
'goods_name' => $value['getProduct']['name'] ?? null,
|
||||
'collection' => $value['collection'] ?? 0,
|
||||
'page_views' => $value['page_views'] ?? 0,
|
||||
'like' => $value['like'] ?? 0,
|
||||
'state' => $value['state'] ?? 1,
|
||||
];
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
} catch (\Exception $e) {
|
||||
// 如果关联查询出错,使用简单查询
|
||||
$data = Moments::order('id desc')->select();
|
||||
$result = [];
|
||||
foreach ($data as $value) {
|
||||
// 从 goods_image 字段中取第一张图片作为封面
|
||||
$img = '';
|
||||
if (!empty($value['goods_image'])) {
|
||||
$images = explode(',', $value['goods_image']);
|
||||
$firstImage = trim($images[0]);
|
||||
// 转换为完整的图片URL
|
||||
$img = UrlServer::getFileUrl($firstImage);
|
||||
}
|
||||
|
||||
$result[] = [
|
||||
'id' => $value['id'],
|
||||
'title' => $value['title'],
|
||||
'order_sn' => $value['order_id'] ?? '',
|
||||
'img' => $img,
|
||||
'create_time' => $value['create_time'],
|
||||
'staff_name' => null,
|
||||
'goods_name' => null,
|
||||
'collection' => $value['collection'] ?? 0,
|
||||
'page_views' => $value['page_views'] ?? 0,
|
||||
'like' => $value['like'] ?? 0,
|
||||
'state' => $value['state'] ?? 1,
|
||||
];
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,7 @@ class Goods extends Validate
|
||||
'region_ratio' => 'lt:100',
|
||||
'shareholder_ratio' => 'lt:100',
|
||||
'give_integral_ratio' => 'egt:0',
|
||||
'type' => 'require',
|
||||
];
|
||||
|
||||
protected $message = [
|
||||
@@ -69,6 +70,7 @@ class Goods extends Validate
|
||||
'region_ratio.lt' => '区域分红比例不能超过100',
|
||||
'shareholder_ratio.lt' => '股东分红比例不能超过100',
|
||||
'give_integral_ratio.egt' => '赠送积分比例须大于或等于0',
|
||||
'type.require' => '请选择商品类型',
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,6 +30,7 @@ class GoodsCategory extends Validate
|
||||
'name' => 'require|checkName',
|
||||
'pid' => 'addPid|editPid',
|
||||
'image' => 'require',
|
||||
'type' => 'require',
|
||||
];
|
||||
|
||||
protected $message = [
|
||||
@@ -37,6 +38,7 @@ class GoodsCategory extends Validate
|
||||
'name.require' => '分类名称不能为空!',
|
||||
'name.unique' => '分类名称已存在',
|
||||
'image.require' => '请上传分类图标',
|
||||
'type.require' => '请选择分类类型'
|
||||
];
|
||||
protected function sceneAdd()
|
||||
{
|
||||
|
||||
@@ -30,6 +30,8 @@ class GoodsOneSpec extends Validate
|
||||
'one_stock' => 'require|integer',
|
||||
'one_volume' => 'egt:0',
|
||||
'one_weight' => 'egt:0',
|
||||
'type' => 'require',
|
||||
'points' => 'egt:0',
|
||||
];
|
||||
|
||||
protected $message = [
|
||||
@@ -45,6 +47,8 @@ class GoodsOneSpec extends Validate
|
||||
'one_cost_price.egt' => '成本价必须大于或等于0.01',
|
||||
'one_stock.require' => '请输入库存',
|
||||
'one_stock.integer' => '库存必须为整型',
|
||||
'type.require' => '请选择规格类型',
|
||||
'points.egt' => '积分必须为正整数',
|
||||
];
|
||||
|
||||
|
||||
|
||||
673
application/admin/view/bulletin_board/index.html
Normal file
673
application/admin/view/bulletin_board/index.html
Normal file
@@ -0,0 +1,673 @@
|
||||
{layout name="layout1" /}
|
||||
<style>
|
||||
.dashboard-container {
|
||||
padding: 15px;
|
||||
}
|
||||
.kpi-card {
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 15px;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
.kpi-title {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.kpi-value {
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.kpi-compare {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
.chart-card {
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 15px;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
.chart-title {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 15px;
|
||||
color: #333;
|
||||
}
|
||||
.chart-container {
|
||||
height: 300px;
|
||||
}
|
||||
.chart-container-large {
|
||||
height: 400px;
|
||||
}
|
||||
.progress-item {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.progress-label {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 5px;
|
||||
font-size: 14px;
|
||||
}
|
||||
.progress-bar-container {
|
||||
height: 20px;
|
||||
background: #f0f0f0;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.progress-bar {
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, #4A70F4 0%, #6DD047 100%);
|
||||
transition: width 0.3s;
|
||||
}
|
||||
.table-card {
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 15px;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
|
||||
overflow: hidden;
|
||||
}
|
||||
.date-filter {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
/* 优化表格样式 */
|
||||
.table-card .layui-table {
|
||||
margin-top: 0;
|
||||
border: none;
|
||||
}
|
||||
.table-card .layui-table thead tr {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
}
|
||||
.table-card .layui-table thead th {
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
padding: 15px 10px;
|
||||
border: none;
|
||||
font-size: 14px;
|
||||
}
|
||||
.table-card .layui-table tbody tr {
|
||||
transition: all 0.3s ease;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
.table-card .layui-table tbody tr:hover {
|
||||
background-color: #f8f9ff;
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
|
||||
}
|
||||
.table-card .layui-table tbody td {
|
||||
text-align: center;
|
||||
padding: 12px 10px;
|
||||
border: none;
|
||||
color: #333;
|
||||
font-size: 13px;
|
||||
}
|
||||
.table-card .layui-table tbody td:first-child {
|
||||
font-weight: 600;
|
||||
color: #4A70F4;
|
||||
background-color: #f8f9ff;
|
||||
}
|
||||
.table-card .layui-table tbody td.empty-data {
|
||||
color: #999;
|
||||
font-style: italic;
|
||||
}
|
||||
.table-card .chart-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-bottom: 15px;
|
||||
border-bottom: 2px solid #f0f0f0;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.table-card .chart-title::before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 4px;
|
||||
height: 18px;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
margin-right: 10px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
</style>
|
||||
<div class="layui-fluid dashboard-container">
|
||||
<!-- 顶部KPI指标 -->
|
||||
<div class="layui-row layui-col-space15">
|
||||
<div class="layui-col-md3">
|
||||
<div class="kpi-card">
|
||||
<div class="kpi-title">月销售总额</div>
|
||||
<div class="kpi-value" id="monthly-sales">--</div>
|
||||
<div class="kpi-compare">同比: <span id="sales-compare">--</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md3">
|
||||
<div class="kpi-card">
|
||||
<div class="kpi-title">月订单量</div>
|
||||
<div class="kpi-value" id="monthly-orders">--</div>
|
||||
<div class="kpi-compare">同比: <span id="orders-compare">--</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md3">
|
||||
<div class="kpi-card">
|
||||
<div class="kpi-title">月客户数</div>
|
||||
<div class="kpi-value" id="monthly-customers">--</div>
|
||||
<div class="kpi-compare">同比: <span id="customers-compare">--</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md3">
|
||||
<div class="kpi-card">
|
||||
<div class="kpi-title">日期筛选</div>
|
||||
<div class="date-filter">
|
||||
<input type="text" class="layui-input" id="date-filter" placeholder="年月日(可筛选)">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 第一行图表 -->
|
||||
<div class="layui-row layui-col-space15">
|
||||
<!-- 月客户分析 -->
|
||||
<div class="layui-col-md4">
|
||||
<div class="chart-card">
|
||||
<div class="chart-title">月客户分析</div>
|
||||
<div class="chart-container" id="customer-analysis-chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 月销售情况 -->
|
||||
<div class="layui-col-md4">
|
||||
<div class="chart-card">
|
||||
<div class="chart-title">月销售情况</div>
|
||||
<div class="chart-container" id="sales-situation-chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 当月客户渠道分析 -->
|
||||
<div class="layui-col-md4">
|
||||
<div class="chart-card">
|
||||
<div class="chart-title">当月客户渠道分析</div>
|
||||
<div class="chart-container" id="channel-analysis-chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 第二行:目标完成率 -->
|
||||
<div class="layui-row layui-col-space15">
|
||||
<div class="layui-col-md12">
|
||||
<div class="chart-card">
|
||||
<div class="chart-title">当月目标完成率</div>
|
||||
<div style="margin-bottom: 20px;">
|
||||
<div style="font-size: 14px; color: #666; margin-bottom: 10px;">
|
||||
本月销售目标:
|
||||
<span style="color: #4A70F4; font-weight: bold;" id="monthly-target-text">--</span>
|
||||
</div>
|
||||
<div class="progress-item">
|
||||
<div class="progress-label">
|
||||
<span>总体完成率</span>
|
||||
<span style="color: #4A70F4; font-weight: bold;" id="overall-completion-text">--</span>
|
||||
</div>
|
||||
<div class="progress-bar-container">
|
||||
<div class="progress-bar" id="overall-completion-bar" style="width: 0%;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top: 30px;">
|
||||
<div class="chart-title" style="font-size: 14px; margin-bottom: 15px;">客服目标完成率(N个客服的目标陈列)</div>
|
||||
<div id="staff-progress-list">
|
||||
<!-- 客服进度条列表(JS 根据数据库数据渲染) -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 第三行:趋势图和区域图 -->
|
||||
<div class="layui-row layui-col-space15">
|
||||
<!-- 每日销售趋势 -->
|
||||
<div class="layui-col-md6">
|
||||
<div class="chart-card">
|
||||
<div class="chart-title">每日销售趋势</div>
|
||||
<div id="trend-compare-text" style="text-align: right; margin-bottom: 10px; color: #f56c6c; font-size: 14px;">
|
||||
--
|
||||
</div>
|
||||
<div class="chart-container-large" id="daily-sales-trend-chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 区域月销售额 -->
|
||||
<div class="layui-col-md6">
|
||||
<div class="chart-card">
|
||||
<div class="chart-title">区域月销售额</div>
|
||||
<div class="chart-container-large" id="regional-sales-chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 第四行:数据表格 -->
|
||||
<div class="layui-row layui-col-space15">
|
||||
<!-- 渠道月销售详情 -->
|
||||
<div class="layui-col-md12">
|
||||
<div class="table-card">
|
||||
<div class="chart-title">渠道月销售详情</div>
|
||||
<table class="layui-table" lay-size="sm">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>渠道</th>
|
||||
<th>美团</th>
|
||||
<th>公众号</th>
|
||||
<th>抖音</th>
|
||||
<th>员工</th>
|
||||
<th>异业</th>
|
||||
<th>渠道</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="channel-month-table-body">
|
||||
<!-- JS 动态渲染渠道月销售详情 -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 第五行:区域月销售详情 -->
|
||||
<div class="layui-row layui-col-space15">
|
||||
<div class="layui-col-md12">
|
||||
<div class="table-card">
|
||||
<div class="chart-title">区域月销售详情</div>
|
||||
<table class="layui-table" lay-size="sm">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>服务类型</th>
|
||||
<th>南明区</th>
|
||||
<th>云岩区</th>
|
||||
<th>白云区</th>
|
||||
<th>乌当区</th>
|
||||
<th>花溪区</th>
|
||||
<th>龙里</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="region-month-table-body">
|
||||
<!-- JS 动态渲染区域月销售详情 -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>
|
||||
<script>
|
||||
layui.config({
|
||||
version:"{$front_version}",
|
||||
base: '/static/plug/layui-admin/dist/layuiadmin/'
|
||||
}).extend({
|
||||
index: 'lib/index'
|
||||
}).use(['index', 'laydate'], function(){
|
||||
var $ = layui.$
|
||||
,laydate = layui.laydate;
|
||||
|
||||
// 统计数据(从后端传递)
|
||||
var statisticsData = {
|
||||
monthlySales: parseFloat('{$monthlySales|default=0}') || 0,
|
||||
monthlyOrders: parseInt('{$monthlyOrders|default=0}') || 0,
|
||||
monthlyCustomers: parseInt('{$monthlyCustomers|default=0}') || 0,
|
||||
salesCompare: parseFloat('{$salesCompare|default=0}') || 0,
|
||||
ordersCompare: parseFloat('{$ordersCompare|default=0}') || 0,
|
||||
customersCompare: parseFloat('{$customersCompare|default=0}') || 0,
|
||||
oldCustomers: parseInt('{$oldCustomers|default=0}') || 0,
|
||||
newCustomers: parseInt('{$newCustomers|default=0}') || 0
|
||||
};
|
||||
|
||||
// 仪表盘其它统计数据(目标、客服进度、渠道、趋势、区域等)
|
||||
// 这里直接输出后端已经 json_encode 好的字符串,避免模板语法冲突
|
||||
var dashboardData = {$dashboardData|raw} || {};
|
||||
|
||||
// 渲染统计数据
|
||||
renderStatistics();
|
||||
|
||||
// 日期选择器
|
||||
laydate.render({
|
||||
elem: '#date-filter',
|
||||
type: 'date',
|
||||
format: 'yyyy-MM-dd'
|
||||
});
|
||||
|
||||
// 初始化所有图表(使用数据库数据渲染)
|
||||
initCharts();
|
||||
|
||||
// 渲染目标完成率和客服进度条
|
||||
renderTargetsAndStaff();
|
||||
// 渲染渠道与区域明细表格
|
||||
renderChannelAndRegionTables();
|
||||
|
||||
// 渲染统计数据
|
||||
function renderStatistics() {
|
||||
// 格式化金额(保留两位小数,添加千分位)
|
||||
function formatMoney(amount) {
|
||||
if (!amount) return '0.00';
|
||||
return parseFloat(amount).toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
||||
}
|
||||
|
||||
// 格式化同比显示
|
||||
function formatCompare(compare) {
|
||||
if (compare > 0) {
|
||||
return '<span style="color: #52c41a;">↑ ' + Math.abs(compare).toFixed(2) + '%</span>';
|
||||
} else if (compare < 0) {
|
||||
return '<span style="color: #ff4d4f;">↓ ' + Math.abs(compare).toFixed(2) + '%</span>';
|
||||
} else {
|
||||
return '<span style="color: #999;">持平</span>';
|
||||
}
|
||||
}
|
||||
|
||||
// 渲染月销售总额
|
||||
$('#monthly-sales').text('¥' + formatMoney(statisticsData.monthlySales));
|
||||
$('#sales-compare').html(formatCompare(statisticsData.salesCompare));
|
||||
|
||||
// 渲染月订单量
|
||||
$('#monthly-orders').text(statisticsData.monthlyOrders);
|
||||
$('#orders-compare').html(formatCompare(statisticsData.ordersCompare));
|
||||
|
||||
// 渲染月客户数
|
||||
$('#monthly-customers').text(statisticsData.monthlyCustomers);
|
||||
$('#customers-compare').html(formatCompare(statisticsData.customersCompare));
|
||||
}
|
||||
|
||||
// 渲染销售目标、总体完成率和客服进度条
|
||||
function renderTargetsAndStaff() {
|
||||
if (!dashboardData) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 销售目标与总体完成率
|
||||
var target = dashboardData.monthlyTarget || 0;
|
||||
var completion = dashboardData.overallCompletion || 0;
|
||||
|
||||
$('#monthly-target-text').text(target > 0 ? (target / 10000).toFixed(2) + ' 万' : '--');
|
||||
$('#overall-completion-text').text(completion.toFixed ? completion.toFixed(2) + '%' : (completion + '%'));
|
||||
$('#overall-completion-bar').css('width', (completion > 100 ? 100 : completion) + '%');
|
||||
|
||||
// 客服进度条
|
||||
var list = $('#staff-progress-list');
|
||||
list.empty();
|
||||
if (dashboardData.staffProgress && dashboardData.staffProgress.length) {
|
||||
dashboardData.staffProgress.forEach(function (item) {
|
||||
var percentText = (item.percent || 0).toFixed(2) + '%';
|
||||
var yoy = item.yoy || 0;
|
||||
var yoyHtml;
|
||||
if (yoy > 0) {
|
||||
yoyHtml = '同比: <span style="color:#52c41a;">↑ ' + yoy.toFixed(2) + '%</span>';
|
||||
} else if (yoy < 0) {
|
||||
yoyHtml = '同比: <span style="color:#ff4d4f;">↓ ' + Math.abs(yoy).toFixed(2) + '%</span>';
|
||||
} else {
|
||||
yoyHtml = '同比: <span style="color:#999;">持平</span>';
|
||||
}
|
||||
var html = ''
|
||||
+ '<div class="progress-item">'
|
||||
+ ' <div class="progress-label">'
|
||||
+ ' <span>' + (item.name || '未分配') + '</span>'
|
||||
+ ' <span>销售额: ' + (item.sales || 0) + ' | 百分比: ' + percentText + ' | ' + yoyHtml + '</span>'
|
||||
+ ' </div>'
|
||||
+ ' <div class="progress-bar-container">'
|
||||
+ ' <div class="progress-bar" style="width:' + (item.percent || 0) + '%;"></div>'
|
||||
+ ' </div>'
|
||||
+ '</div>';
|
||||
list.append(html);
|
||||
});
|
||||
} else {
|
||||
list.append('<div style="color:#999;font-size:12px;">暂无客服统计数据</div>');
|
||||
}
|
||||
}
|
||||
|
||||
// 渠道&区域月销售明细表格渲染(只处理“总额”这一行)
|
||||
function renderChannelAndRegionTables() {
|
||||
if (!dashboardData) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ===== 渠道月销售详情(总额 / 年卡 / 次卡 / 单次 / 其它) =====
|
||||
var channelBody = $('#channel-month-table-body');
|
||||
channelBody.empty();
|
||||
var channelHeaders = ['美团','公众号','抖音','员工','异业','渠道'];
|
||||
var rowLabels = [
|
||||
{key: 'total', text: '总额'},
|
||||
{key: 'year', text: '年卡'},
|
||||
{key: 'times', text: '次卡'},
|
||||
{key: 'single',text: '单次服务'},
|
||||
{key: 'other', text: '其他服务'}
|
||||
];
|
||||
var keyToCol = ['meituan','gzh','douyin','staff','yeye','other'];
|
||||
rowLabels.forEach(function (row) {
|
||||
var data = (dashboardData.channelDetail && dashboardData.channelDetail[row.key]) || {};
|
||||
var tr = '<tr><td>' + row.text + '</td>';
|
||||
keyToCol.forEach(function (colKey) {
|
||||
var v = parseFloat(data[colKey] || 0).toFixed(2);
|
||||
tr += '<td>' + v + '</td>';
|
||||
});
|
||||
tr += '</tr>';
|
||||
channelBody.append(tr);
|
||||
});
|
||||
|
||||
// ===== 区域月销售详情(总额 / 年卡 / 次卡 / 单次 / 其它) =====
|
||||
var regionBody = $('#region-month-table-body');
|
||||
regionBody.empty();
|
||||
if (dashboardData.regions && dashboardData.regions.length) {
|
||||
var regionNames = dashboardData.regions;
|
||||
rowLabels.forEach(function (row) {
|
||||
var rowData = (dashboardData.regionDetail && dashboardData.regionDetail[row.key]) || {};
|
||||
var tr2 = '<tr><td>' + row.text + '</td>';
|
||||
regionNames.forEach(function (rName) {
|
||||
var val = parseFloat(rowData[rName] || 0).toFixed(2);
|
||||
tr2 += '<td>' + val + '</td>';
|
||||
});
|
||||
tr2 += '</tr>';
|
||||
regionBody.append(tr2);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function initCharts() {
|
||||
// 月客户分析 - 饼图
|
||||
var customerChart = echarts.init(document.getElementById('customer-analysis-chart'));
|
||||
customerChart.setOption({
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: '{a} <br/>{b}: {c} ({d}%)'
|
||||
},
|
||||
legend: {
|
||||
orient: 'vertical',
|
||||
left: 'left'
|
||||
},
|
||||
series: [{
|
||||
name: '客户分析',
|
||||
type: 'pie',
|
||||
radius: ['40%', '70%'],
|
||||
avoidLabelOverlap: false,
|
||||
itemStyle: {
|
||||
borderRadius: 10,
|
||||
borderColor: '#fff',
|
||||
borderWidth: 2
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
formatter: '{b}: {d}%'
|
||||
},
|
||||
data: [
|
||||
{value: statisticsData.oldCustomers, name: '老客', itemStyle: {color: '#FFB6C1'}},
|
||||
{value: statisticsData.newCustomers, name: '新客', itemStyle: {color: '#FF69B4'}}
|
||||
]
|
||||
}]
|
||||
});
|
||||
|
||||
// 月销售情况 - 饼图(使用数据库汇总结果)
|
||||
var salesChart = echarts.init(document.getElementById('sales-situation-chart'));
|
||||
salesChart.setOption({
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: '{a} <br/>{b}: {c} ({d}%)'
|
||||
},
|
||||
legend: {
|
||||
bottom: '5%',
|
||||
left: 'center'
|
||||
},
|
||||
series: [{
|
||||
name: '销售情况',
|
||||
type: 'pie',
|
||||
radius: ['40%', '70%'],
|
||||
avoidLabelOverlap: false,
|
||||
itemStyle: {
|
||||
borderRadius: 10,
|
||||
borderColor: '#fff',
|
||||
borderWidth: 2
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
formatter: '{b}: {c}'
|
||||
},
|
||||
data: (dashboardData.salesSituation && dashboardData.salesSituation.length)
|
||||
? dashboardData.salesSituation
|
||||
: [
|
||||
{value: 0, name: '单次服务', itemStyle: {color: '#F6A23F'}},
|
||||
{value: 0, name: '年卡销量', itemStyle: {color: '#4A70F4'}},
|
||||
{value: 0, name: '次卡销量', itemStyle: {color: '#6DD047'}},
|
||||
{value: 0, name: '其它服务', itemStyle: {color: '#87CEEB'}}
|
||||
]
|
||||
}]
|
||||
});
|
||||
|
||||
// 当月客户渠道分析 - 环形图(使用数据库统计的渠道订单数)
|
||||
var channelChart = echarts.init(document.getElementById('channel-analysis-chart'));
|
||||
channelChart.setOption({
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: '{a} <br/>{b}: {c} ({d}%)'
|
||||
},
|
||||
legend: {
|
||||
orient: 'vertical',
|
||||
left: 'left'
|
||||
},
|
||||
series: [{
|
||||
name: '客户渠道',
|
||||
type: 'pie',
|
||||
radius: ['40%', '70%'],
|
||||
avoidLabelOverlap: false,
|
||||
itemStyle: {
|
||||
borderRadius: 10,
|
||||
borderColor: '#fff',
|
||||
borderWidth: 2
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
formatter: '{b}: {d}%'
|
||||
},
|
||||
data: (dashboardData.channelPie && dashboardData.channelPie.length)
|
||||
? dashboardData.channelPie
|
||||
: []
|
||||
}]
|
||||
});
|
||||
|
||||
// 每日销售趋势 - 折线图(使用数据库按天汇总的数据)
|
||||
var trendChart = echarts.init(document.getElementById('daily-sales-trend-chart'));
|
||||
trendChart.setOption({
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '3%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: dashboardData.trendDates || []
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
name: '销售额',
|
||||
axisLabel: {
|
||||
formatter: '{value}K'
|
||||
}
|
||||
},
|
||||
series: [{
|
||||
name: '销售额',
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
areaStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [{
|
||||
offset: 0, color: 'rgba(74, 112, 244, 0.3)'
|
||||
}, {
|
||||
offset: 1, color: 'rgba(74, 112, 244, 0.1)'
|
||||
}]
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
color: '#4A70F4'
|
||||
},
|
||||
data: dashboardData.trendValues || []
|
||||
}]
|
||||
});
|
||||
// 渲染“上月同比”文字
|
||||
var trendCompare = dashboardData.trendCompare || 0;
|
||||
var trendTextDom = $('#trend-compare-text');
|
||||
if (trendCompare > 0) {
|
||||
trendTextDom.css('color', '#52c41a').html('▲ ' + trendCompare.toFixed(2) + '% 上月同比');
|
||||
} else if (trendCompare < 0) {
|
||||
trendTextDom.css('color', '#f56c6c').html('▼ ' + Math.abs(trendCompare).toFixed(2) + '% 上月同比');
|
||||
} else {
|
||||
trendTextDom.css('color', '#999').html('持平 上月同比');
|
||||
}
|
||||
|
||||
// 区域月销售额 - 柱状图(根据地址简单按区域统计)
|
||||
var regionalChart = echarts.init(document.getElementById('regional-sales-chart'));
|
||||
regionalChart.setOption({
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow'
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '3%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: dashboardData.regions || []
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
name: '销量'
|
||||
},
|
||||
series: [{
|
||||
name: '销量',
|
||||
type: 'bar',
|
||||
itemStyle: {
|
||||
color: '#4A70F4'
|
||||
},
|
||||
data: dashboardData.regionTotals || []
|
||||
}]
|
||||
});
|
||||
|
||||
// 响应式调整
|
||||
window.addEventListener('resize', function() {
|
||||
customerChart.resize();
|
||||
salesChart.resize();
|
||||
channelChart.resize();
|
||||
trendChart.resize();
|
||||
regionalChart.resize();
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
645
application/admin/view/bulletin_board/map.html
Normal file
645
application/admin/view/bulletin_board/map.html
Normal file
@@ -0,0 +1,645 @@
|
||||
{layout name="layout1" /}
|
||||
<style>
|
||||
.map-container {
|
||||
padding: 15px;
|
||||
min-height: calc(100vh - 60px);
|
||||
}
|
||||
.map-header {
|
||||
background: #fff;
|
||||
padding: 15px 20px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 15px;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.map-header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
}
|
||||
.map-header-title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
.map-header-stats {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
align-items: center;
|
||||
}
|
||||
.stat-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 15px;
|
||||
background: #f8f9ff;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.stat-label {
|
||||
font-size: 13px;
|
||||
color: #666;
|
||||
}
|
||||
.stat-value {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #4A70F4;
|
||||
}
|
||||
.map-search-box {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
}
|
||||
.map-search-input {
|
||||
width: 300px;
|
||||
}
|
||||
#maplocation {
|
||||
width: 100%;
|
||||
height: calc(100vh - 200px);
|
||||
min-height: 600px;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
|
||||
background: #f5f5f5;
|
||||
}
|
||||
/* 头像标记点样式 */
|
||||
.tmap-marker-avatar {
|
||||
border-radius: 50%;
|
||||
border: 2px solid #fff;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
|
||||
object-fit: cover;
|
||||
}
|
||||
.info-window {
|
||||
padding: 10px;
|
||||
min-width: 150px;
|
||||
}
|
||||
.info-window-title {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 8px;
|
||||
border-bottom: 1px solid #eee;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
.info-window-item {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
margin: 5px 0;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.info-window-item strong {
|
||||
color: #333;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.map-controls {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
z-index: 1000;
|
||||
background: #fff;
|
||||
padding: 10px;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
|
||||
}
|
||||
.map-control-btn {
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin-bottom: 8px;
|
||||
padding: 8px 15px;
|
||||
text-align: center;
|
||||
background: #4A70F4;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.map-control-btn:hover {
|
||||
background: #3a5fd4;
|
||||
}
|
||||
.map-control-btn:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.map-legend {
|
||||
position: absolute;
|
||||
bottom: 20px;
|
||||
left: 20px;
|
||||
z-index: 1000;
|
||||
background: rgba(255,255,255,0.95);
|
||||
padding: 12px 15px;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
}
|
||||
.legend-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin: 5px 0;
|
||||
}
|
||||
.legend-color {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid #fff;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.2);
|
||||
}
|
||||
</style>
|
||||
<div class="map-container">
|
||||
<!-- 地图头部 -->
|
||||
<div class="map-header">
|
||||
<div class="map-header-left">
|
||||
<div class="map-header-title">用户位置分布图</div>
|
||||
<div class="map-header-stats">
|
||||
<div class="stat-item">
|
||||
<span class="stat-label">总用户数:</span>
|
||||
<span class="stat-value" id="total-users">0</span>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<span class="stat-label">已定位:</span>
|
||||
<span class="stat-value" id="located-users">0</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="map-search-box">
|
||||
<input type="text" id="search_key" class="layui-input map-search-input" placeholder="请输入地名搜索">
|
||||
<!-- <button class="layui-btn layui-btn-normal searchKey">搜索</button>-->
|
||||
<button class="layui-btn layui-btn-primary" id="reset-map">重置视图</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 地图容器 -->
|
||||
<div style="position: relative;">
|
||||
<div id="maplocation"></div>
|
||||
|
||||
<!-- 地图控制按钮 -->
|
||||
<div class="map-controls">
|
||||
<button class="map-control-btn" id="zoom-in">放大</button>
|
||||
<button class="map-control-btn" id="zoom-out">缩小</button>
|
||||
<button class="map-control-btn" id="fit-bounds">适应所有标记</button>
|
||||
<button class="map-control-btn" id="clear-markers">清除标记</button>
|
||||
</div>
|
||||
|
||||
<!-- 图例 -->
|
||||
<div class="map-legend">
|
||||
<div style="font-weight: bold; margin-bottom: 8px; color: #333;">图例</div>
|
||||
<div class="legend-item">
|
||||
<div class="legend-color" style="background: #4A70F4;"></div>
|
||||
<span>用户位置</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/static/webjs/jquery.min.js"></script>
|
||||
<script charset="utf-8" src="https://map.qq.com/api/gljs?v=1.exp&libraries=service,tools&key=EVOBZ-VX7YU-QKJVR-BVESA-AVFT3-7JBWG" onload="console.log('腾讯地图API脚本加载完成')" onerror="console.error('腾讯地图API脚本加载失败')"></script>
|
||||
|
||||
<script>
|
||||
layui.config({
|
||||
version:"{$front_version}",
|
||||
base: '/static/plug/layui-admin/dist/layuiadmin/'
|
||||
}).extend({
|
||||
index: 'lib/index'
|
||||
}).use(['index'], function(){
|
||||
var $ = layui.$;
|
||||
|
||||
// 用户数据(将从后端获取)
|
||||
var users = [];
|
||||
var markers = null;
|
||||
var map = null;
|
||||
var geocoder = null;
|
||||
var infoWindows = [];
|
||||
var defaultCenter = null; // 默认中心点(贵阳)
|
||||
var defaultZoom = 12;
|
||||
var markerClickHandler = null; // 保存点击事件处理函数
|
||||
|
||||
// 初始化地图
|
||||
function initMap() {
|
||||
try {
|
||||
// 检查TMap是否已加载
|
||||
if (typeof TMap === 'undefined') {
|
||||
console.error('腾讯地图API未加载');
|
||||
layer.msg('地图加载失败,请刷新页面重试', {icon: 2, time: 3000});
|
||||
return;
|
||||
}
|
||||
|
||||
// 初始化默认中心点
|
||||
if (!defaultCenter) {
|
||||
defaultCenter = new TMap.LatLng(26.647, 106.63); // 默认中心点(贵阳)
|
||||
}
|
||||
|
||||
console.log('开始初始化地图...');
|
||||
map = new TMap.Map('maplocation', {
|
||||
zoom: defaultZoom,
|
||||
center: defaultCenter
|
||||
});
|
||||
|
||||
console.log('地图对象创建成功');
|
||||
|
||||
// 初始化标记点(样式将在渲染时动态创建)
|
||||
markers = new TMap.MultiMarker({
|
||||
map: map,
|
||||
styles: {},
|
||||
geometries: []
|
||||
});
|
||||
|
||||
console.log('标记点对象创建成功');
|
||||
|
||||
// 初始化地理编码服务
|
||||
geocoder = new TMap.service.Geocoder();
|
||||
|
||||
// 等待地图加载完成
|
||||
map.on('complete', function() {
|
||||
console.log('地图加载完成');
|
||||
|
||||
// 加载用户数据
|
||||
setTimeout(function() {
|
||||
if (typeof loadUsers === 'function') {
|
||||
loadUsers();
|
||||
} else {
|
||||
console.error('loadUsers函数未定义');
|
||||
}
|
||||
}, 500);
|
||||
});
|
||||
|
||||
// 备用方案:如果complete事件没有触发,延迟后直接初始化
|
||||
setTimeout(function() {
|
||||
console.log('备用方案:延迟调用loadUsers()');
|
||||
if (typeof loadUsers === 'function') {
|
||||
loadUsers();
|
||||
} else {
|
||||
console.error('loadUsers函数未定义');
|
||||
}
|
||||
}, 3000);
|
||||
|
||||
// 监听地图错误
|
||||
map.on('error', function(e) {
|
||||
console.error('地图错误:', e);
|
||||
layer.msg('地图加载出错,请刷新页面重试', {icon: 2, time: 3000});
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('地图初始化失败:', error);
|
||||
layer.msg('地图初始化失败:' + error.message, {icon: 2, time: 3000});
|
||||
}
|
||||
}
|
||||
|
||||
// 加载用户数据
|
||||
function loadUsers() {
|
||||
if (typeof $ === 'undefined') {
|
||||
console.error('jQuery未加载');
|
||||
return;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: '{:url("BulletinBoard/getUserMap")}',
|
||||
type: 'GET',
|
||||
dataType: 'json',
|
||||
success: function(res) {
|
||||
console.log('用户数据响应:', res);
|
||||
if (res.code === 1 && res.data) {
|
||||
users = res.data;
|
||||
console.log('获取到用户数据:', users.length, '条');
|
||||
updateStats();
|
||||
renderMarkers();
|
||||
} else {
|
||||
console.warn('获取用户数据失败:', res.msg);
|
||||
layer.msg(res.msg || '获取用户数据失败', {icon: 2});
|
||||
users = [];
|
||||
updateStats();
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error('请求失败:', xhr, status, error);
|
||||
console.error('响应内容:', xhr.responseText);
|
||||
layer.msg('请求失败,请稍后重试', {icon: 2});
|
||||
users = [];
|
||||
updateStats();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 将loadUsers暴露到全局作用域,方便调试
|
||||
window.loadUsers = loadUsers;
|
||||
|
||||
// 更新统计信息
|
||||
function updateStats() {
|
||||
var totalUsers = users.length;
|
||||
var locatedUsers = users.filter(function(u) {
|
||||
return u.lat && u.lng && u.lat != 0 && u.lng != 0;
|
||||
}).length;
|
||||
|
||||
$('#total-users').text(totalUsers);
|
||||
$('#located-users').text(locatedUsers);
|
||||
}
|
||||
|
||||
// 渲染标记点
|
||||
function renderMarkers() {
|
||||
if (!markers || !map) {
|
||||
console.warn('标记点或地图未初始化');
|
||||
return;
|
||||
}
|
||||
|
||||
// 清除现有标记和信息窗口
|
||||
clearMarkers();
|
||||
|
||||
var geometries = [];
|
||||
var validUsers = [];
|
||||
var markerStyles = {};
|
||||
|
||||
// 过滤有效坐标的用户
|
||||
users.forEach(function(user, index) {
|
||||
if (!user.lat || !user.lng || user.lat == 0 || user.lng == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var lat = parseFloat(user.lat);
|
||||
var lng = parseFloat(user.lng);
|
||||
|
||||
if (isNaN(lat) || isNaN(lng)) {
|
||||
console.warn('无效的经纬度:', user);
|
||||
return;
|
||||
}
|
||||
|
||||
validUsers.push(user);
|
||||
|
||||
// 为每个用户创建使用头像的标记点样式
|
||||
var styleId = 'avatar_' + (user.id || index);
|
||||
// 如果没有头像,使用默认标记图标
|
||||
var avatarUrl = user.avatar && user.avatar.trim() !== ''
|
||||
? user.avatar
|
||||
: 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/markerDefault.png';
|
||||
|
||||
// 创建头像标记样式(圆形头像,带边框)
|
||||
markerStyles[styleId] = new TMap.MarkerStyle({
|
||||
width: 40,
|
||||
height: 40,
|
||||
anchor: {x: 20, y: 20},
|
||||
src: avatarUrl
|
||||
});
|
||||
|
||||
// 创建标记点
|
||||
geometries.push({
|
||||
id: 'user_' + (user.id || index),
|
||||
position: new TMap.LatLng(lat, lng),
|
||||
styleId: styleId,
|
||||
properties: {
|
||||
title: user.contact || user.name || '用户' + (user.id || index),
|
||||
user: user
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
console.log('有效用户数:', validUsers.length, '标记点数:', geometries.length);
|
||||
|
||||
// 更新标记样式和几何图形
|
||||
if (geometries.length > 0) {
|
||||
// 先更新样式
|
||||
markers.setStyles(markerStyles);
|
||||
// 再更新几何图形
|
||||
markers.updateGeometries(geometries);
|
||||
|
||||
// 创建信息窗口(但不自动显示)
|
||||
createInfoWindows(validUsers);
|
||||
|
||||
// 如果只有一个用户,居中显示
|
||||
if (validUsers.length === 1) {
|
||||
map.setCenter(new TMap.LatLng(validUsers[0].lat, validUsers[0].lng));
|
||||
map.setZoom(15);
|
||||
} else if (validUsers.length > 1) {
|
||||
// 适应所有标记
|
||||
fitBounds(validUsers);
|
||||
}
|
||||
} else {
|
||||
console.warn('没有有效的用户位置数据');
|
||||
}
|
||||
}
|
||||
|
||||
// 创建信息窗口(但不立即添加到地图,只在点击时创建)
|
||||
function createInfoWindows(users) {
|
||||
// 先清除之前的事件监听器(如果存在)
|
||||
if (markers && markerClickHandler) {
|
||||
try {
|
||||
markers.off('click', markerClickHandler);
|
||||
} catch (e) {
|
||||
console.warn('移除事件监听器失败:', e);
|
||||
}
|
||||
markerClickHandler = null;
|
||||
}
|
||||
|
||||
// 点击标记显示信息窗口
|
||||
markerClickHandler = function(evt) {
|
||||
var geometry = evt.geometry;
|
||||
if (geometry && geometry.properties) {
|
||||
// 关闭所有信息窗口
|
||||
infoWindows.forEach(function(item) {
|
||||
if (item.window) {
|
||||
try {
|
||||
item.window.close();
|
||||
if (item.window.destroy) {
|
||||
item.window.destroy();
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('关闭信息窗口失败:', e);
|
||||
}
|
||||
}
|
||||
});
|
||||
infoWindows = [];
|
||||
|
||||
// 从 properties 中直接获取用户数据
|
||||
var user = geometry.properties.user;
|
||||
|
||||
// 如果没有,尝试从全局 users 数组查找
|
||||
if (!user) {
|
||||
var userId = geometry.id.replace('user_', '');
|
||||
user = users.find(function(u) {
|
||||
return (u.id || '').toString() === userId || users.indexOf(u).toString() === userId;
|
||||
});
|
||||
}
|
||||
|
||||
if (user) {
|
||||
var lat = parseFloat(user.lat);
|
||||
var lng = parseFloat(user.lng);
|
||||
|
||||
if (isNaN(lat) || isNaN(lng)) {
|
||||
console.error('无效的经纬度:', user);
|
||||
return;
|
||||
}
|
||||
|
||||
var content = '<div class="info-window">' +
|
||||
'<div class="info-window-title">' + (user.contact || user.name || '用户') + '</div>' +
|
||||
'<div class="info-window-item"><strong>电话:</strong>' + (user.telephone || user.phone || '-') + '</div>' +
|
||||
'<div class="info-window-item"><strong>地址:</strong>' + (user.address || '-') + '</div>';
|
||||
content += '</div>';
|
||||
|
||||
// 只在点击时创建信息窗口
|
||||
try {
|
||||
var infoWindow = new TMap.InfoWindow({
|
||||
map: map,
|
||||
position: new TMap.LatLng(lat, lng),
|
||||
content: content,
|
||||
visible: true,
|
||||
zIndex: 100
|
||||
});
|
||||
|
||||
infoWindows.push({
|
||||
window: infoWindow,
|
||||
markerId: geometry.id
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('创建信息窗口失败:', e);
|
||||
layer.msg('显示信息失败', {icon: 2});
|
||||
}
|
||||
} else {
|
||||
console.warn('未找到用户数据:', geometry.id);
|
||||
}
|
||||
} else {
|
||||
console.warn('标记点数据不完整:', geometry);
|
||||
}
|
||||
};
|
||||
|
||||
// 绑定事件监听器
|
||||
if (markers && markerClickHandler) {
|
||||
markers.on('click', markerClickHandler);
|
||||
}
|
||||
}
|
||||
|
||||
// 适应所有标记
|
||||
function fitBounds(users) {
|
||||
if (users.length === 0) return;
|
||||
|
||||
var bounds = new TMap.LatLngBounds();
|
||||
users.forEach(function(user) {
|
||||
bounds.extend(new TMap.LatLng(parseFloat(user.lat), parseFloat(user.lng)));
|
||||
});
|
||||
|
||||
map.fitBounds(bounds);
|
||||
}
|
||||
|
||||
// 清除标记
|
||||
function clearMarkers() {
|
||||
if (markers) {
|
||||
markers.updateGeometries([]);
|
||||
}
|
||||
infoWindows.forEach(function(item) {
|
||||
if (item.window) {
|
||||
try {
|
||||
item.window.close();
|
||||
if (item.window.destroy) {
|
||||
item.window.destroy();
|
||||
} else if (item.window.setMap) {
|
||||
item.window.setMap(null);
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('清除信息窗口失败:', e);
|
||||
}
|
||||
}
|
||||
});
|
||||
infoWindows = [];
|
||||
}
|
||||
|
||||
// 搜索功能
|
||||
var searchService = {
|
||||
search: function(name) {
|
||||
if (!name || !name.trim()) {
|
||||
layer.msg('请输入搜索关键词', {icon: 0});
|
||||
return;
|
||||
}
|
||||
|
||||
geocoder.getLocation({ address: name })
|
||||
.then(function(result) {
|
||||
if (result && result.result && result.result.location) {
|
||||
var location = result.result.location;
|
||||
map.setCenter(location);
|
||||
map.setZoom(15);
|
||||
|
||||
// 添加临时标记
|
||||
markers.updateGeometries([{
|
||||
id: 'search_result',
|
||||
position: location,
|
||||
styleId: 'marker'
|
||||
}]);
|
||||
} else {
|
||||
layer.msg('未找到该地点', {icon: 0});
|
||||
}
|
||||
})
|
||||
.catch(function(error) {
|
||||
layer.msg('搜索失败:' + (error.message || '未知错误'), {icon: 2});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 事件绑定
|
||||
$(document).on('click', '.searchKey', function() {
|
||||
var searchKey = $("#search_key").val();
|
||||
searchService.search(searchKey);
|
||||
});
|
||||
|
||||
$('#search_key').on('keypress', function(e) {
|
||||
if (e.which === 13) {
|
||||
$('.searchKey').trigger('click');
|
||||
}
|
||||
});
|
||||
|
||||
$('#reset-map').on('click', function() {
|
||||
map.setCenter(defaultCenter);
|
||||
map.setZoom(defaultZoom);
|
||||
renderMarkers();
|
||||
});
|
||||
|
||||
$('#zoom-in').on('click', function() {
|
||||
map.setZoom(map.getZoom() + 1);
|
||||
});
|
||||
|
||||
$('#zoom-out').on('click', function() {
|
||||
map.setZoom(map.getZoom() - 1);
|
||||
});
|
||||
|
||||
$('#fit-bounds').on('click', function() {
|
||||
var validUsers = users.filter(function(u) {
|
||||
return u.lat && u.lng && u.lat != 0 && u.lng != 0;
|
||||
});
|
||||
if (validUsers.length > 0) {
|
||||
fitBounds(validUsers);
|
||||
} else {
|
||||
layer.msg('没有可显示的用户位置', {icon: 0});
|
||||
}
|
||||
});
|
||||
|
||||
$('#clear-markers').on('click', function() {
|
||||
clearMarkers();
|
||||
layer.msg('已清除所有标记', {icon: 1});
|
||||
});
|
||||
|
||||
// 等待腾讯地图API加载完成后再初始化
|
||||
var retryCount = 0;
|
||||
var maxRetries = 100; // 10秒
|
||||
|
||||
function waitForTMap() {
|
||||
if (typeof TMap !== 'undefined' && typeof TMap.Map !== 'undefined') {
|
||||
// 延迟一下确保API完全加载
|
||||
setTimeout(function() {
|
||||
initMap();
|
||||
}, 300);
|
||||
} else {
|
||||
// 如果还没加载,等待一段时间后重试(最多等待10秒)
|
||||
if (retryCount < maxRetries) {
|
||||
retryCount++;
|
||||
setTimeout(waitForTMap, 100);
|
||||
} else {
|
||||
console.error('腾讯地图API加载超时');
|
||||
layer.msg('地图API加载超时,请刷新页面重试', {icon: 2, time: 3000});
|
||||
}
|
||||
}
|
||||
}
|
||||
// 初始化
|
||||
$(function() {
|
||||
// 等待地图API加载
|
||||
waitForTMap();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -22,6 +22,13 @@
|
||||
class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><span class="form-label-asterisk">*</span>商品类型:</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="type" value="1" title="服务商品" checked>
|
||||
<input type="radio" name="type" value="2" title="普通商品">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">服务次数:</label>
|
||||
<div class="layui-input-block">
|
||||
|
||||
@@ -45,6 +45,13 @@
|
||||
<input type="text" name="name" lay-verify="required" lay-verType="tips" placeholder="请输入名称" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><span class="form-label-asterisk">*</span>商品类型:</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="type" value="1" title="服务商品" checked>
|
||||
<input type="radio" name="type" value="2" title="普通商品">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">父级分类:</label>
|
||||
<div class="layui-input-inline">
|
||||
|
||||
@@ -46,6 +46,13 @@
|
||||
<input type="text" name="name" value="{$info.name}" lay-verify="required" lay-verType="tips" placeholder="请输入名称" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><span class="form-label-asterisk">*</span>商品类型:</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="type" value="1" title="服务商品" {if $info.type == 1} checked="checked" {/if}>
|
||||
<input type="radio" name="type" value="2" title="普通商品" {if $info.type == 2} checked="checked" {/if}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">父级分类:</label>
|
||||
<div class="layui-input-inline">
|
||||
|
||||
@@ -93,6 +93,14 @@
|
||||
},
|
||||
cols: [
|
||||
{field: 'name', title: '分类名称',width: 280},
|
||||
//类型 1服务商品 2普通商品
|
||||
{field: 'type', title: '类型', width: 100, align: 'center',templet: function (d) {
|
||||
if(d.type === 1){
|
||||
return '服务商品';
|
||||
}else{
|
||||
return '普通商品';
|
||||
}
|
||||
}},
|
||||
{field: '#image', title: '分类图标', width: 120,style:'height:100px;',toolbar: '#image', align: 'center'},
|
||||
{templet: '#is_recommend', title: '首页推荐', width: 100,align: 'center'},
|
||||
{templet: '#is_show', title: '显示', width: 100},
|
||||
|
||||
0
application/admin/view/invoice/details.html
Normal file
0
application/admin/view/invoice/details.html
Normal file
111
application/admin/view/invoice/edit.html
Normal file
111
application/admin/view/invoice/edit.html
Normal file
@@ -0,0 +1,111 @@
|
||||
{layout name="layout2" /}
|
||||
<div class="">
|
||||
<div class="layui-tab-content layui-form">
|
||||
<div class="layui-tab-item layui-show">
|
||||
<div class="layui-card-body" pad15>
|
||||
<div lay-filter="">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><span class="form-label-asterisk">*</span>发票信息ID:</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="invoice_id" lay-verify="required" lay-verType="tips"
|
||||
autocomplete="off"
|
||||
switch-tab="0" verify-msg="请输入发票信息ID" placeholder="请输入发票信息ID"
|
||||
value="{$invoice.invoice_id}"
|
||||
class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">状态:</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="radio" name="state" value="1" title="开票中" {if $invoice.state == 1}checked{/if}>
|
||||
<input type="radio" name="state" value="2" title="驳回" {if $invoice.state == 2}checked{/if}>
|
||||
<input type="radio" name="state" value="3" title="完成" {if $invoice.state == 3}checked{/if}>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">发票文件:</label>
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-upload">
|
||||
<button type="button" class="layui-btn" id="upload-btn">上传PDF文件</button>
|
||||
<div class="layui-upload-list" style="margin-top: 10px;">
|
||||
<input type="hidden" name="document" id="document" value="{$invoice.document|default=''}">
|
||||
<div id="file-list">
|
||||
{if $invoice.document}
|
||||
<div style="padding: 10px; background: #f5f5f5; border-radius: 4px; margin-bottom: 10px;">
|
||||
<a href="{$invoice.document}" target="_blank">{$invoice.document}</a>
|
||||
<span style="color: #5FB878;">已上传</span>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-hide">
|
||||
<input type="button" lay-submit lay-filter="invoice-submit" id="invoice-submit" value="确认">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
layui.config({
|
||||
version:"{$front_version}",
|
||||
base: '/static/plug/layui-admin/dist/layuiadmin/'
|
||||
}).extend({
|
||||
index: 'lib/index'
|
||||
}).use(['index', 'form', 'upload', 'jquery'], function () {
|
||||
var $ = layui.$;
|
||||
var form = layui.form;
|
||||
var upload = layui.upload;
|
||||
|
||||
// 文件上传
|
||||
upload.render({
|
||||
elem: '#upload-btn',
|
||||
url: '{:url("invoice/upload")}',
|
||||
accept: 'file',
|
||||
exts: 'pdf',
|
||||
done: function(res){
|
||||
if(res.code == 1){
|
||||
$('#document').val(res.data.path);
|
||||
$('#file-list').html('<div style="padding: 10px; background: #f5f5f5; border-radius: 4px;"><a href="' + res.data.path + '" target="_blank">' + res.data.path + '</a> <span style="color: #5FB878;">上传成功</span></div>');
|
||||
layer.msg('上传成功', {icon: 1});
|
||||
} else {
|
||||
layer.msg(res.msg || '上传失败', {icon: 2});
|
||||
}
|
||||
},
|
||||
error: function(){
|
||||
layer.msg('上传失败', {icon: 2});
|
||||
}
|
||||
});
|
||||
|
||||
// 表单提交
|
||||
form.on('submit(invoice-submit)', function(data){
|
||||
var field = data.field;
|
||||
var index = parent.layer.getFrameIndex(window.name);
|
||||
|
||||
$.ajax({
|
||||
url: '{:url("invoice/edit")}?id={$invoice.id}',
|
||||
type: 'post',
|
||||
data: field,
|
||||
success: function(res){
|
||||
if(res.code == 1){
|
||||
parent.layer.msg(res.msg, {icon: 1, time: 1000}, function(){
|
||||
parent.layer.close(index);
|
||||
parent.layui.table.reload('user-lists');
|
||||
});
|
||||
} else {
|
||||
layer.msg(res.msg, {icon: 2});
|
||||
}
|
||||
},
|
||||
error: function(){
|
||||
layer.msg('请求失败', {icon: 2});
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
194
application/admin/view/invoice/info.html
Normal file
194
application/admin/view/invoice/info.html
Normal file
@@ -0,0 +1,194 @@
|
||||
{layout name="layout2" /}
|
||||
<style>
|
||||
.invoice-info-card {
|
||||
margin-bottom: 15px;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,0.1);
|
||||
}
|
||||
.invoice-info-card .layui-card-header {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
border-radius: 4px 4px 0 0;
|
||||
}
|
||||
.invoice-info-card .layui-card-header:first-child {
|
||||
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
||||
}
|
||||
.info-row {
|
||||
padding: 12px 0;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
.info-row:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
.info-label {
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
min-width: 180px;
|
||||
display: inline-block;
|
||||
}
|
||||
.info-value {
|
||||
color: #666;
|
||||
word-break: break-all;
|
||||
}
|
||||
.info-badge {
|
||||
font-size: 13px;
|
||||
padding: 4px 12px;
|
||||
}
|
||||
.file-preview {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 8px 12px;
|
||||
background: #f8f9fa;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #e9ecef;
|
||||
}
|
||||
.section-divider {
|
||||
height: 1px;
|
||||
background: linear-gradient(to right, transparent, #e0e0e0, transparent);
|
||||
margin: 20px 0;
|
||||
}
|
||||
</style>
|
||||
<div class="">
|
||||
<div class="layui-card-body" pad15>
|
||||
<!-- 基本信息 -->
|
||||
<div class="layui-card invoice-info-card">
|
||||
<div class="layui-card-header">
|
||||
<i class="layui-icon layui-icon-file"></i> 基本信息
|
||||
</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="info-row">
|
||||
<span class="info-label">记录ID:</span>
|
||||
<span class="info-value">{$invoice.id}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">发票信息ID:</span>
|
||||
<span class="info-value">{$invoice.invoice_id}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">状态:</span>
|
||||
<span class="info-value">
|
||||
{if $invoice.state == 1}
|
||||
<span class="layui-badge layui-bg-blue info-badge">待开票</span>
|
||||
{elseif $invoice.state == 2}
|
||||
<span class="layui-badge layui-bg-red info-badge">驳回</span>
|
||||
{elseif $invoice.state == 3}
|
||||
<span class="layui-badge layui-bg-green info-badge">完成</span>
|
||||
{else}
|
||||
<span class="layui-badge layui-bg-gray info-badge">未知</span>
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">发票文件:</span>
|
||||
<span class="info-value">
|
||||
{if $invoice.document}
|
||||
<div class="file-preview">
|
||||
<a href="{$invoice.document_url}" target="_blank" class="layui-btn layui-btn-primary layui-btn-xs">
|
||||
<i class="layui-icon layui-icon-download-circle"></i> 查看文件
|
||||
</a>
|
||||
<span style="color: #999; font-size: 12px;">{$invoice.document_url}</span>
|
||||
</div>
|
||||
{else}
|
||||
<span style="color: #999;">无文件</span>
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">创建时间:</span>
|
||||
<span class="info-value">{$invoice.create_time|default='--'}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">更新时间:</span>
|
||||
<span class="info-value">{$invoice.update_time|default='--'}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 订单信息 -->
|
||||
<div class="layui-card invoice-info-card">
|
||||
<div class="layui-card-header">
|
||||
<i class="layui-icon layui-icon-cart"></i> 订单信息
|
||||
</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="info-row">
|
||||
<span class="info-label">订单编号:</span>
|
||||
<span class="info-value">{$invoice.order.order_sn ?? "--"}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">订单金额:</span>
|
||||
<span class="info-value" style="color: #f56c6c; font-weight: bold; font-size: 16px;">
|
||||
¥{$invoice.order.settle_amount ?? "0.00"}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 用户信息 -->
|
||||
<div class="layui-card invoice-info-card">
|
||||
<div class="layui-card-header">
|
||||
<i class="layui-icon layui-icon-user"></i> 用户信息
|
||||
</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="info-row">
|
||||
<span class="info-label">系统用户名:</span>
|
||||
<span class="info-value">{$invoice.invoice.user.nickname ?? "--"}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 发票抬头信息 -->
|
||||
<div class="layui-card invoice-info-card">
|
||||
<div class="layui-card-header">
|
||||
<i class="layui-icon layui-icon-form"></i> 发票抬头信息
|
||||
</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="info-row">
|
||||
<span class="info-label">类型:</span>
|
||||
<span class="info-value">
|
||||
{if $invoice.invoice.type == 1}
|
||||
<span class="layui-badge layui-bg-blue info-badge">个人</span>
|
||||
{elseif $invoice.invoice.type == 2}
|
||||
<span class="layui-badge layui-bg-orange info-badge">企业</span>
|
||||
{else}
|
||||
<span class="layui-badge layui-bg-gray info-badge">未知</span>
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">发票类型:</span>
|
||||
<span class="info-value">{$invoice.invoice.invoice_type ?? "--"}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">发票抬头/企业名称:</span>
|
||||
<span class="info-value" style="font-weight: 500;">{$invoice.invoice.invoice_title ?? "--"}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">纳税人识别号/统一社会信用代码:</span>
|
||||
<span class="info-value" style="font-family: 'Courier New', monospace; letter-spacing: 1px;">
|
||||
{$invoice.invoice.identification ?? "--"}
|
||||
</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">注册地址:</span>
|
||||
<span class="info-value">{$invoice.invoice.address ?? "--"}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">注册电话:</span>
|
||||
<span class="info-value">{$invoice.invoice.phone ?? "--"}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">开户行:</span>
|
||||
<span class="info-value">{$invoice.invoice.bank ?? "--"}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">开户账号:</span>
|
||||
<span class="info-value" style="font-family: 'Courier New', monospace;">
|
||||
{$invoice.invoice.account ?? "--"}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
189
application/admin/view/invoice/lists.html
Normal file
189
application/admin/view/invoice/lists.html
Normal file
@@ -0,0 +1,189 @@
|
||||
{layout name="layout1" /}
|
||||
<div class="layui-fluid">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-collapse like-layui-collapse" lay-accordion="" style="border:1px dashed #c4c4c4">
|
||||
<div class="layui-colla-item">
|
||||
<h2 class="layui-colla-title like-layui-colla-title" style="background-color: #fff">操作提示</h2>
|
||||
<div class="layui-colla-content layui-show">
|
||||
<p>*发票管理列表,对发票进行编辑、查看和删除等操作。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form layui-card-header layuiadmin-card-header-auto">
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
<div class="layui-input-inline" style="width: 200px;">
|
||||
<input type="text" id="keyword" name="keyword" placeholder="请输入订单号或发票ID" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-input-inline" style="width: 150px;">
|
||||
<select name="state" id="state">
|
||||
<option value="">全部状态</option>
|
||||
<option value="1">待开票</option>
|
||||
<option value="2">驳回</option>
|
||||
<option value="3">完成</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
<button class="layui-btn layui-btn-sm layuiadmin-btn-user {$view_theme_color}" lay-submit lay-filter="user-search">查询</button>
|
||||
<button class="layui-btn layui-btn-sm layuiadmin-btn-user layui-btn-primary " lay-submit lay-filter="user-clear-search">清空查询</button>
|
||||
<!-- <button class="layui-btn layui-btn-sm layuiadmin-btn-user {$view_theme_color}" data-type="add">添加</button>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-card-body">
|
||||
<table id="user-lists" lay-filter="user-lists"></table>
|
||||
<script type="text/html" id="user-operation">
|
||||
<a class="layui-btn layui-btn-primary layui-btn-sm" lay-event="info">资料</a>
|
||||
<a class="layui-btn layui-btn-normal layui-btn-sm" lay-event="edit">编辑</a>
|
||||
<a class="layui-btn layui-btn-danger layui-btn-sm" lay-event="del">删除</a>
|
||||
</script>
|
||||
<script type="text/html" id="status">
|
||||
{{# if(d.state == 1){ }}
|
||||
<span class="layui-badge layui-bg-blue">待开票</span>
|
||||
{{# } else if(d.state == 2){ }}
|
||||
<span class="layui-badge layui-bg-red">驳回</span>
|
||||
{{# } else if(d.state == 3){ }}
|
||||
<span class="layui-badge layui-bg-green">完成</span>
|
||||
{{# } else { }}
|
||||
<span class="layui-badge layui-bg-gray">未知</span>
|
||||
{{# } }}
|
||||
</script>
|
||||
<script type="text/html" id="document-templet">
|
||||
{{# if(d.document){ }}
|
||||
<a href="{{ d.document }}" target="_blank" class="layui-btn layui-btn-xs layui-btn-primary">查看文件</a>
|
||||
{{# } else { }}
|
||||
<span>无文件</span>
|
||||
{{# } }}
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<style>
|
||||
.layui-table-cell {
|
||||
height: auto;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
layui.config({
|
||||
version:"{$front_version}",
|
||||
base: '/static/plug/layui-admin/dist/layuiadmin/'
|
||||
}).extend({
|
||||
index: 'lib/index'
|
||||
}).use(['index','table','like'], function(){
|
||||
var $ = layui.$
|
||||
,form = layui.form
|
||||
,table = layui.table
|
||||
,like = layui.like;
|
||||
|
||||
//监听搜索
|
||||
form.on('submit(user-search)', function(data){
|
||||
var field = data.field;
|
||||
table.reload('user-lists', {
|
||||
where: field,
|
||||
page: {
|
||||
curr: 1
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
//清空查询
|
||||
form.on('submit(user-clear-search)', function(data){
|
||||
$('#keyword').val('');
|
||||
$('#state').val('');
|
||||
form.render('select');
|
||||
table.reload('user-lists', {
|
||||
where: {},
|
||||
page: {
|
||||
curr: 1
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
//监听工具条
|
||||
table.on('tool(user-lists)', function(obj){
|
||||
var data = obj.data;
|
||||
if(obj.event === 'info'){
|
||||
layer.open({
|
||||
type: 2
|
||||
,title: '发票详情'
|
||||
,content: '{:url("invoice/info")}?id=' + data.id
|
||||
,area: ['800px', '600px']
|
||||
,btn: ['关闭']
|
||||
,yes: function(index){
|
||||
layer.close(index);
|
||||
}
|
||||
});
|
||||
} else if(obj.event === 'edit'){
|
||||
layer.open({
|
||||
type: 2
|
||||
,title: '编辑发票'
|
||||
,content: '{:url("invoice/edit")}?id=' + data.id
|
||||
,area: ['800px', '600px']
|
||||
,btn: ['确定', '取消']
|
||||
,yes: function(index, layero){
|
||||
var iframeWindow = window['layui-layer-iframe'+ index]
|
||||
,submit = layero.find('iframe').contents().find("#invoice-submit");
|
||||
submit.trigger('click');
|
||||
}
|
||||
});
|
||||
} else if(obj.event === 'del'){
|
||||
layer.confirm('确定删除吗?', function(index){
|
||||
$.ajax({
|
||||
url: '{:url("invoice/del")}',
|
||||
type: 'post',
|
||||
data: {id: data.id},
|
||||
success: function(res){
|
||||
if(res.code == 1){
|
||||
layer.msg(res.msg, {icon: 1, time: 1000}, function(){
|
||||
layer.close(index);
|
||||
table.reload('user-lists');
|
||||
});
|
||||
} else {
|
||||
layer.msg(res.msg, {icon: 2});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$('.layui-btn.layuiadmin-btn-user').on('click', function(){
|
||||
var type = $(this).data('type');
|
||||
active[type] ? active[type].call(this) : '';
|
||||
});
|
||||
|
||||
//管理员管理
|
||||
table.render({
|
||||
id:'user-lists'
|
||||
,elem: '#user-lists'
|
||||
,url: '{:url("invoice/lists")}'
|
||||
,cols: [[
|
||||
{type: 'checkbox'}
|
||||
,{field: 'id', title: 'ID', width: 80}
|
||||
,{field: 'invoice_id', title: '发票信息ID'}
|
||||
,{field: 'state', title: '状态', align: 'center', templet: '#status'}
|
||||
,{field: 'document', title: '发票文件', align: 'center', templet: '#document-templet'}
|
||||
,{field: 'create_time', title: '创建时间'}
|
||||
,{field: 'update_time', title: '更新时间'}
|
||||
,{fixed: 'right', title: '操作', width: 280, align: 'center', toolbar: '#user-operation'}
|
||||
]]
|
||||
,page: true
|
||||
,text: {none: '暂无数据!'}
|
||||
,parseData: function(res){
|
||||
return {
|
||||
"code": res.code,
|
||||
"msg": res.msg,
|
||||
"count": res.data.count,
|
||||
"data": res.data.lists,
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
0
application/admin/view/invoice/upload.html
Normal file
0
application/admin/view/invoice/upload.html
Normal file
982
application/admin/view/moments/add.html
Normal file
982
application/admin/view/moments/add.html
Normal file
@@ -0,0 +1,982 @@
|
||||
{layout name="layout2" /}
|
||||
<link rel="stylesheet" href="/static/admin/css/goods.css" media="all">
|
||||
<div class="">
|
||||
<div class="layui-tab-content layui-form">
|
||||
<div class="layui-tab-item goods-content layui-show">
|
||||
<div class="layui-card-body" pad15>
|
||||
<div lay-filter="">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><span class="form-label-asterisk">*</span>标题:</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="title" lay-verify="custom_required" lay-verType="tips"
|
||||
autocomplete="off"
|
||||
switch-tab="0" verify-msg="请输入标题" placeholder="请输入标题"
|
||||
class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><span class="form-label-asterisk">*</span>员工:</label>
|
||||
<div class="layui-input-block">
|
||||
<select name="sid" lay-verType="" placeholder="请选择员工" switch-tab="0" verify-msg="请选择员工">
|
||||
<option value="">请选择员工</option>
|
||||
{foreach $staff as $key=>$vo}
|
||||
<option value="{$vo.id}">{$vo.name}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><span class="form-label-asterisk">*</span>产品:</label>
|
||||
<div class="layui-input-block">
|
||||
<select name="goods_id" lay-verType="" placeholder="请选择关联产品" switch-tab="0" verify-msg="请选择关联产品">
|
||||
<option value="">请选择关联产品</option>
|
||||
{foreach $goods as $key=>$vo}
|
||||
<option value="{$vo.id}">{$vo.name}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">显示状态:</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="radio" name="state" value="1" title="显示" checked>
|
||||
<input type="radio" name="state" value="2" title="不显示">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item" style="margin-bottom: 0px">
|
||||
<label class="layui-form-label"><span class="form-label-asterisk">*</span>图片:</label>
|
||||
<div style="min-height:80px;">
|
||||
<ul style="list-style: none; padding: 0; margin: 0; display: flex; flex-wrap: wrap; gap: 10px;">
|
||||
<!-- 图片列表将在这里显示 -->
|
||||
</ul>
|
||||
<div class="goods-img-add" lay-verify="goods_image" lay-verType="tips" switch-tab="0" verify-msg="选择图片" style="margin-top: 10px;"></div>
|
||||
</div>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">内容详情</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="content" id="content" lay-verify="content" class="field-content"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-hide">
|
||||
<input type="button" lay-submit lay-filter="add-user_group-submit" id="add-user_group-submit" value="确认">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!---------------------------------html模板---------------------------------->
|
||||
<script type="text/html" id="template-goods-image">
|
||||
<li class="goods-li">
|
||||
<input name="goods_image[]" type="hidden" value="{image-src}">
|
||||
<img class="goods-img goods_image" src="{image-src}">
|
||||
<a class="goods-img-del-x" style="display: none;">x</a></li>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
//注意:选项卡 依赖 element 模块,否则无法进行功能性操作
|
||||
var dragstart = 0;
|
||||
var swop_element_ed = -1;
|
||||
var create_table_by_spec = null;
|
||||
var spec_table_data = [];
|
||||
var spec_value_temp_id_number = 0;
|
||||
|
||||
layui.config({
|
||||
version:"{$front_version}",
|
||||
base: '/static/plug/layui-admin/dist/layuiadmin/' //静态资源所在路径
|
||||
}).extend({
|
||||
index: 'lib/index' //主入口模块
|
||||
}).use(['index', 'element', 'jquery', 'like', 'likeedit'], function () {
|
||||
var $ = layui.$;
|
||||
var like = layui.like;
|
||||
var form = layui.form;
|
||||
var likeedit = layui.likeedit;
|
||||
|
||||
$('.first_ratio').bind('input propertychange', function() {
|
||||
var that = $(this);
|
||||
var value = that.val();
|
||||
format(that,value)
|
||||
|
||||
});
|
||||
$('.second_ratio').bind('input propertychange', function() {
|
||||
var that = $(this);
|
||||
var value = that.val();
|
||||
format(that,value)
|
||||
|
||||
});
|
||||
$('.three_ratio').bind('input propertychange', function() {
|
||||
var that = $(this);
|
||||
var value = that.val();
|
||||
format(that,value)
|
||||
|
||||
});
|
||||
//格式化分销比例
|
||||
function format(that,value){
|
||||
value = value.replace(/[^0-9.]/g,'');
|
||||
|
||||
value = value.replace(/\.{2,}/g,".");
|
||||
value = value.replace(".","$#$").replace(/\./g,"").replace("$#$",".");
|
||||
|
||||
value = value.replace(/^(\-)*(\d+)\.(\d)(\d).*$/,'$1$2.$3$4');
|
||||
if(value.indexOf(".")< 0 && value !=""){
|
||||
value= parseFloat(value);
|
||||
}
|
||||
if(value > 100){
|
||||
that.val(100);
|
||||
return false;
|
||||
}
|
||||
that.val(value);
|
||||
}
|
||||
|
||||
|
||||
//------------------------基本信息----------------------------------
|
||||
//商品主图事件
|
||||
$(document).on('mouseenter', '.goods-li', function () {
|
||||
$(this).children().last().show();
|
||||
});
|
||||
$(document).on('mouseleave', '.goods-li', function () {
|
||||
$(this).children().last().hide();
|
||||
});
|
||||
$(document).on('click', '.goods-li', function () {
|
||||
var src = $(this).children('img').attr('src');
|
||||
like.showImg(src,600);
|
||||
});
|
||||
//主图显示删除按钮
|
||||
$(document).on('mouseenter','.master-image',function () {
|
||||
$(this).children('.goods-image-del').show();
|
||||
})
|
||||
$(document).on('mouseleave', '.master-image', function () {
|
||||
$(this).children('.goods-image-del').hide();
|
||||
});
|
||||
$(document).on('click', '.master-image', function () {
|
||||
var src = $(this).children('img').attr('src');
|
||||
like.showImg(src,600);
|
||||
});
|
||||
|
||||
//分享海报删除按钮
|
||||
$(document).on('mouseenter','.poster-image',function () {
|
||||
|
||||
$(this).children('.goods-image-del').show();
|
||||
})
|
||||
$(document).on('mouseleave', '.poster-image', function () {
|
||||
$(this).children('.goods-image-del').hide();
|
||||
});
|
||||
$(document).on('click', '.poster-image', function () {
|
||||
var src = $(this).children('img').attr('src');
|
||||
like.showImg(src,600);
|
||||
});
|
||||
|
||||
$(document).on('click', '.goods-img-del-x', function () {
|
||||
|
||||
if($(this).hasClass('goods-image-del')){
|
||||
$(this).parent().next().show();
|
||||
$(this).parent().children().remove();
|
||||
}
|
||||
|
||||
$(this).parent().remove();
|
||||
return false;
|
||||
});
|
||||
|
||||
like.imageUpload('.goods-img-add', function (uris, element) {
|
||||
// 海报上传逻辑(单图片)
|
||||
if(element.hasClass('poster-upload')){
|
||||
if(uris.length>1){
|
||||
layer.msg('最多只能选中1张图片');
|
||||
return;
|
||||
}
|
||||
var html = '' +
|
||||
'<input name="poster" type="hidden" value="' + like.getUrlFileName(uris[0], '{$storageUrl}') + '">' +
|
||||
' <img class="goods-img" src="' + uris[0] + '">\n' +
|
||||
'<a class="goods-img-del-x goods-image-del">x</a>';
|
||||
element.prev().append(html);
|
||||
element.css('display','none');
|
||||
return 0;
|
||||
}
|
||||
// 多图片上传逻辑(最多8张)
|
||||
var count = element.prev().children().length;
|
||||
count = !count ? 0 : count;
|
||||
if (count + uris.length > 8) {
|
||||
layer.msg('最多只能选中8张图片');
|
||||
return;
|
||||
}
|
||||
uris = uris.reverse();
|
||||
for(var i in uris){
|
||||
var uri = uris[i];
|
||||
if (!uri) continue; // 跳过无效的 uri
|
||||
|
||||
var template_goods_image = $('#template-goods-image').html();
|
||||
if (!template_goods_image) {
|
||||
console.error('模板 template-goods-image 不存在');
|
||||
continue;
|
||||
}
|
||||
|
||||
// 获取文件路径(用于 hidden input)
|
||||
var filePath = like.getUrlFileName ? like.getUrlFileName(uri, '{$storageUrl}') : uri;
|
||||
if (!filePath) {
|
||||
filePath = uri; // 如果 getUrlFileName 返回 undefined,使用原始 uri
|
||||
}
|
||||
|
||||
// 先替换 input 中的 {image-src},再替换 img 中的 {image-src}
|
||||
var html = template_goods_image.replace('{image-src}', filePath);
|
||||
html = html.replace('{image-src}', uri);
|
||||
element.prev().append(html);
|
||||
}
|
||||
}, true);
|
||||
|
||||
// ========= 视频上传 开始
|
||||
$('#video').click(function(){
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '上传视频',
|
||||
content: '{:url("file_new/lists")}?type=video',
|
||||
area: ['90%', '90%']
|
||||
});
|
||||
});
|
||||
|
||||
window.videoCallback = function(uris) {
|
||||
like.videoCallback(uris);
|
||||
};
|
||||
// ========== 视频上传 结束
|
||||
|
||||
//图片拉拽
|
||||
$(document).on('dragstart', '.goods-li', function (e) {
|
||||
dragstart = e.offsetX;
|
||||
});
|
||||
$(document).on('dragend', '.goods-li', function (e) {
|
||||
swop_element_ed = -1;
|
||||
});
|
||||
$(document).on('mousedown', '.goods-li', function (e) {
|
||||
swop_element_ed = -1;
|
||||
});
|
||||
$(document).on('dragover', '.goods-li', function (e) {
|
||||
e.preventDefault();
|
||||
swop_element = parseInt((e.clientX - dragstart) / 100) - 1;
|
||||
swop_element = swop_element <= 0 ? 0 : swop_element;
|
||||
my_element = $(this).prevAll().length;
|
||||
if (swop_element == my_element) {
|
||||
return;
|
||||
}
|
||||
if (swop_element == swop_element_ed) {
|
||||
return;
|
||||
}
|
||||
swop_element_ed = swop_element;
|
||||
swop($(this), $(this).parent().children().eq(swop_element));
|
||||
});
|
||||
|
||||
//渲染品牌
|
||||
var brands = 1;
|
||||
|
||||
setBrand();
|
||||
function setBrand(default_id) {
|
||||
var brand_select_html = '<option value="">请选择原料分类</option>';
|
||||
for (var i in brands) {
|
||||
brand_select_html += '<option value="' + brands[i]['id'] + '">' + brands[i]['name'] + '</option>';
|
||||
}
|
||||
$('select[name="brand_id"]').html(brand_select_html);
|
||||
$('select[name="brand_id"]').val(default_id);
|
||||
form.render('select');
|
||||
}
|
||||
|
||||
//渲染隶属部门
|
||||
var bellist = 1;
|
||||
console.log(bellist);
|
||||
setBrands();
|
||||
function setBrands(default_id) {
|
||||
var bellist_select_html = '<option value="">请选择部门</option>';
|
||||
for (var i in bellist) {
|
||||
bellist_select_html += '<option value="' + bellist[i]['id'] + '">' + bellist[i]['name'] + '</option>';
|
||||
}
|
||||
$('select[name="bellist_id"]').html(bellist_select_html);
|
||||
$('select[name="bellist_id"]').val(default_id);
|
||||
form.render('select');
|
||||
}
|
||||
|
||||
//------------------------价格库存----------------------------------
|
||||
|
||||
//统一规格与多规格切换事件
|
||||
function switchSpecType(value)
|
||||
{
|
||||
var goods_spec_project = $('#goods-spec-project');
|
||||
if (value == 2) {
|
||||
$('#add-spec').parent().show();
|
||||
if (goods_spec_project.children().length > 0) {
|
||||
goods_spec_project.parent().show();
|
||||
$('#more-spec-lists').show();
|
||||
}
|
||||
$('#one-spec-lists').hide();
|
||||
} else {
|
||||
$('#add-spec').parent().hide();
|
||||
goods_spec_project.parent().hide();
|
||||
$('#one-spec-lists').show();
|
||||
$('#more-spec-lists').hide();
|
||||
}
|
||||
}
|
||||
form.on('radio(spec-type)', function (data) {
|
||||
switchSpecType(data.value);
|
||||
});
|
||||
|
||||
|
||||
|
||||
//添加规格项目
|
||||
function addSpec(value){
|
||||
value = value===undefined?'':value;
|
||||
var element_spec = $('#goods-spec-project');
|
||||
var count = $('.goods-spec').size();
|
||||
if (count > 2) {
|
||||
layer.msg('最多添加3个规格项目');
|
||||
return;
|
||||
}
|
||||
var template_spec = $('#template-spec').html();
|
||||
element_spec.append(template_spec.replace('{value}',value));
|
||||
$('#goods-spec-project').parent().show();
|
||||
form.render('checkbox');
|
||||
}
|
||||
$('#add-spec').click(function () {
|
||||
addSpec();
|
||||
});
|
||||
|
||||
//显示或隐藏规格项目删除按钮绑定
|
||||
$(document).on('mouseenter', '.goods-spec', function () {
|
||||
$(this).find('.goods-spec-del-x').show();
|
||||
});
|
||||
$(document).on('mouseleave', '.goods-spec', function () {
|
||||
$(this).find('.goods-spec-del-x').hide();
|
||||
});
|
||||
|
||||
//删除规格项目绑定
|
||||
$(document).on('click', '.goods-spec-del-x', function () {
|
||||
$(this).parent().remove();
|
||||
var goods_spec_project = $('#goods-spec-project');
|
||||
if (goods_spec_project.children().length == 0) {
|
||||
goods_spec_project.parent().hide();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//添加或删除规格项目后续操作
|
||||
function specValueLater(){
|
||||
$('.add-spec-value').each(function(){
|
||||
add_spec_value = $(this);
|
||||
var spec_values = '';
|
||||
add_spec_value.parent().parent().find('.goods-spec-value-input').each(function () {
|
||||
spec_values += $(this).val() + ',';
|
||||
});
|
||||
add_spec_value.parent().find('.spec_values').val(spec_values.substring(0, spec_values.lastIndexOf(',')));
|
||||
|
||||
var spec_value_ids = '';
|
||||
add_spec_value.parent().parent().find('.goods-sepc-value-id-input').each(function () {
|
||||
spec_value_ids += $(this).val() + ',';
|
||||
});
|
||||
add_spec_value.parent().find('.spec_value_ids').val(spec_value_ids.substring(0, spec_value_ids.lastIndexOf(',')));
|
||||
triggerCreateTableBySepc();
|
||||
});
|
||||
}
|
||||
|
||||
//添加规格项
|
||||
function addSpecvalue(add_spec_value,spec,spec_id){
|
||||
var template_spec_value = $('#template-spec-value').html();
|
||||
var template_spec_value_html = template_spec_value.replace('{spec_value_temp_id}', spec_value_temp_id_number--);
|
||||
template_spec_value_html = template_spec_value_html.replace('{spec_value_id}',spec_id);
|
||||
template_spec_value_html = template_spec_value_html.replace('{spec_value}', spec)
|
||||
add_spec_value.parent().before(template_spec_value_html);
|
||||
var div = add_spec_value.parent().parent().parent().parent();
|
||||
var status = div.find('.batch-spec-image-switch').first().is(':checked');
|
||||
if(status){
|
||||
div.find('.batch-spec-image').show();
|
||||
}else{
|
||||
div.find('.batch-spec-image').hide();
|
||||
}
|
||||
}
|
||||
form.on('switch(batch-spec-image-switch)', function(data){
|
||||
var status = data.elem.checked;
|
||||
$('.batch-spec-image-switch').prop("checked",false);
|
||||
if(status) {
|
||||
$('.batch-spec-image').hide();
|
||||
$(this).parent().parent().parent().parent().find('.batch-spec-image').show();
|
||||
$(this).prop("checked",true);
|
||||
}else{
|
||||
$(this).parent().parent().parent().parent().find('.batch-spec-image').hide();
|
||||
}
|
||||
form.render('checkbox');
|
||||
});
|
||||
|
||||
//批量添加规格项绑定
|
||||
$(document).on('click', '.add-spec-value', function () {
|
||||
var add_spec_value = $(this);
|
||||
layer.prompt({title: '输入规格值,多个请换行', formType: 2}, function (text, index) {
|
||||
layer.close(index);
|
||||
var specs = text.split('\n');
|
||||
for (var i in specs) {
|
||||
specs[i] = specs[i].trim();
|
||||
}
|
||||
specs = unique(specs);
|
||||
var added_specs = [];
|
||||
add_spec_value.parent().parent().find('.goods-spec-value-input').each(function () {
|
||||
added_specs.push($(this).val().trim());
|
||||
});
|
||||
for (var i in specs) {
|
||||
var spec = specs[i].trim();
|
||||
if (spec == '' || in_array(spec, added_specs)) {
|
||||
//已存或为空的不添加
|
||||
continue;
|
||||
}
|
||||
addSpecvalue(add_spec_value,spec,0);
|
||||
}
|
||||
specValueLater();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
//删除规格项
|
||||
$(document).on('click', '.goods-spec-value-del-x', function () {
|
||||
var add_spec_value = $(this).parent().parent().find('.add-spec-value').first();
|
||||
$(this).parent().remove();
|
||||
specValueLater();
|
||||
});
|
||||
|
||||
|
||||
//批量填充规格图片
|
||||
like.imageUpload('.batch-spec-image',function(uri,element){
|
||||
var temp_id = element.prev().attr('spec-value-temp-id');
|
||||
var spec_images = null;
|
||||
if($('input[name="spec_type"]:checked').val() == 1){
|
||||
spec_images = $('#one-spec-lists-table input[name="spec_image[]"]');
|
||||
}else{
|
||||
spec_images = $('#more-spec-lists-table input[name="spec_image[]"]');
|
||||
}
|
||||
spec_images.each(function(){
|
||||
var temp_ids = $(this).parent().parent().parent().attr('spec-value-temp-ids');
|
||||
temp_ids_arr = temp_ids.split(',');
|
||||
var key = $(this).attr('name') + temp_ids;
|
||||
if(in_array(temp_id,temp_ids_arr)) {
|
||||
spec_table_data[key] = uri;
|
||||
}
|
||||
});
|
||||
setTableValue();
|
||||
});
|
||||
|
||||
//批量填充
|
||||
$('.batch-spec-content').click(function(){
|
||||
var title = $(this).text();
|
||||
var input_name = $(this).attr('input-name');
|
||||
layer.prompt({
|
||||
formType: 3
|
||||
,title: '批量填写'+title
|
||||
},function(value, index, elem){
|
||||
$('input[name="'+input_name+'[]"]').val(value);
|
||||
//保存值到本地
|
||||
$('#more-spec-lists-table input').each(function(){
|
||||
var key = $(this).attr('name') + $(this).parent().parent().attr('spec-value-temp-ids');
|
||||
spec_table_data[key] = $(this).val();
|
||||
});
|
||||
layer.close(index);
|
||||
});
|
||||
});
|
||||
|
||||
//显示或隐藏规格项删除按钮
|
||||
$(document).on('mouseenter', '.goods-spec-value', function () {
|
||||
$(this).find('.goods-spec-value-del-x').show();
|
||||
});
|
||||
$(document).on('mouseleave', '.goods-spec-value', function () {
|
||||
$(this).find('.goods-spec-value-del-x').hide();
|
||||
});
|
||||
|
||||
|
||||
// 单规格图片
|
||||
like.imageUpload('.goods-one-spec-img-add', function (uris, element) {
|
||||
if(uris.length>1){
|
||||
layer.msg('最多最能选中1张图片');
|
||||
return;
|
||||
}
|
||||
element.hide();
|
||||
var key = element.parent().parent().parent().attr('spec-value-temp-ids');
|
||||
spec_table_data["spec_image[]"+key] = uris[0];//保存图片地址
|
||||
$(element).parent().html('<input name="one_spec_image" type="hidden" value="' + like.getUrlFileName(uris[0], '{$storageUrl}') + '"><a class="goods-one-spec-img-del-x">x</a><img class="goods-spec-img" src="' + uris[0] + '">');
|
||||
});
|
||||
$(document).on('mouseenter', '.goods-spec-img-div', function () {
|
||||
$(this).find('.goods-one-spec-img-del-x').show();
|
||||
});
|
||||
$(document).on('mouseleave', '.goods-spec-img-div', function () {
|
||||
$(this).find('.goods-one-spec-img-del-x').hide();
|
||||
});
|
||||
$(document).on('click', '.goods-one-spec-img-del-x', function () {
|
||||
$(this).parent().html('<input type="hidden" name="one_spec_image"><img src="/static/common/image/plug/goods-lists-add-image.png" class="goods-one-spec-img-add">');
|
||||
});
|
||||
|
||||
//多规格图片
|
||||
like.imageUpload('.goods-spec-img-add', function (uris, element) {
|
||||
|
||||
if(uris.length>1){
|
||||
layer.msg('最多最能选中1张图片');
|
||||
return;
|
||||
}
|
||||
element.hide();
|
||||
var key = element.parent().parent().parent().attr('spec-value-temp-ids');
|
||||
spec_table_data["spec_image[]"+key] = uris[0];//保存图片地址
|
||||
$(element).parent().html('<input name="spec_image[]" type="hidden" value="' + like.getUrlFileName(uris[0], '{$storageUrl}') + '"><a class="goods-spec-img-del-x">x</a><img class="goods-spec-img" src="' + uris[0] + '">');
|
||||
});
|
||||
$(document).on('mouseenter', '.goods-spec-img-div', function () {
|
||||
$(this).find('.goods-spec-img-del-x').show();
|
||||
});
|
||||
$(document).on('mouseleave', '.goods-spec-img-div', function () {
|
||||
$(this).find('.goods-spec-img-del-x').hide();
|
||||
});
|
||||
$(document).on('click', '.goods-spec-img-del-x', function () {
|
||||
var key = 'spec_image[]' + $(this).parent().parent().parent().attr('spec-value-temp-ids');
|
||||
$(this).parent().html('<input type="hidden" name="spec_image[]"><img src="/static/common/image/plug/goods-lists-add-image.png" class="goods-spec-img-add">');
|
||||
spec_table_data[key] = '';
|
||||
|
||||
});
|
||||
$(document).on('click', '.goods-spec-img', function () {
|
||||
like.showImg($(this).attr('src'),600);
|
||||
});
|
||||
|
||||
//规格生成表格
|
||||
createTableBySepc = function () {
|
||||
if ($('.goods-spec').size() <= 0) {
|
||||
$('#more-spec-lists').hide();
|
||||
return;
|
||||
}
|
||||
|
||||
$('#more-spec-lists').show();
|
||||
var table_title = [];
|
||||
var table_data = [];
|
||||
var spec_value_temp_arr = [];
|
||||
var i = 0;
|
||||
var th_html = $('#template-spec-table-th').html();
|
||||
var tr_html = $('#template-spec-table-tr').html();
|
||||
|
||||
//遍历规格项目
|
||||
$('.goods-spec').each(function () {
|
||||
var spec_name = $(this).find('.spec_name').first().val();
|
||||
if (isEmptyString(spec_name)) {
|
||||
return true;
|
||||
}
|
||||
table_title[i] = spec_name;
|
||||
table_data[i] = [];
|
||||
spec_value_temp_arr[i] = [];
|
||||
var j = 0;
|
||||
$(this).find('.goods-spec-value .goods-spec-value-input').each(function () {
|
||||
var spec_value = $(this).val();
|
||||
var spec_value_temp_id = $(this).attr('spec-value-temp-id');
|
||||
if (isEmptyString(spec_value)) {
|
||||
return true;
|
||||
}
|
||||
table_data[i][j] = spec_value;
|
||||
spec_value_temp_arr[i][j] = spec_value_temp_id;
|
||||
j++;
|
||||
});
|
||||
i++;
|
||||
});
|
||||
|
||||
table_html = '';
|
||||
|
||||
//表格头部组装
|
||||
spec_th_html = '';
|
||||
for (var i in table_title) {
|
||||
spec_th_html += '<th>' + table_title[i] + '</th>';
|
||||
}
|
||||
table_html = th_html.replace('{spec_th}', spec_th_html);
|
||||
|
||||
spec_value_temp_arr = cartesianProduct(spec_value_temp_arr);
|
||||
table_data = cartesianProduct(table_data);
|
||||
for (var i in table_data) {
|
||||
var spec_tr_html = '';
|
||||
var tr_name_arr = [];
|
||||
var specs = '';
|
||||
if (Array.isArray(table_data[i])) {
|
||||
//根据规格创建tr的id
|
||||
var spec_value_temp_ids = '';
|
||||
for(var j in spec_value_temp_arr[i]){
|
||||
spec_value_temp_ids += spec_value_temp_arr[i][j]+',';
|
||||
}
|
||||
spec_value_temp_ids = spec_value_temp_ids.substring(0, spec_value_temp_ids.lastIndexOf(','));
|
||||
spec_tr_html += '<tr spec-value-temp-ids="'+spec_value_temp_ids+'">';
|
||||
|
||||
for (var j in table_data[i]) {
|
||||
spec_tr_html += '<td>' + table_data[i][j] + '</td>';
|
||||
tr_name_arr[j] = table_data[i][j];
|
||||
specs += table_data[i][j].replace(',', '') + ',';
|
||||
}
|
||||
} else {
|
||||
var spec_value_temp_ids = spec_value_temp_arr[i];
|
||||
spec_tr_html = '<tr spec-value-temp-ids="'+spec_value_temp_ids+'">';
|
||||
spec_tr_html += '<td>' + table_data[i] + '</td>';
|
||||
specs += table_data[i].replace(',', '') + ',';
|
||||
}
|
||||
specs = specs.substring(0, specs.lastIndexOf(','));
|
||||
spec_table_data["spec_value_str[]"+spec_value_temp_ids] = specs;
|
||||
spec_tr_html += '<td style="display: none"><input type="hidden" name="spec_value_str[]" value="' + specs + '"><input type="hidden" name="item_id[]" value=""></td>';
|
||||
table_html += tr_html.replace('{spec_td}', spec_tr_html);
|
||||
|
||||
}
|
||||
$('#more-spec-lists-table').html(table_html);
|
||||
setTableValue();
|
||||
}
|
||||
//触发规格生成表格
|
||||
function triggerCreateTableBySepc() {
|
||||
clearTimeout(create_table_by_spec);
|
||||
create_table_by_spec = setTimeout(createTableBySepc, 1000);
|
||||
}
|
||||
|
||||
//各种触发生成规格事件
|
||||
triggerCreateTableBySepc();
|
||||
$('#add-spec').click(function () {
|
||||
triggerCreateTableBySepc();
|
||||
});
|
||||
$(document).on('click', '.goods-spec-del-x', function () {
|
||||
triggerCreateTableBySepc();
|
||||
});
|
||||
$(document).on('click', '.add-spec-value', function () {
|
||||
triggerCreateTableBySepc();
|
||||
});
|
||||
$(document).on('click', '.goods-spec-value-del-x', function () {
|
||||
triggerCreateTableBySepc();
|
||||
});
|
||||
$(document).on('input', '.goods-spec input', function () {
|
||||
triggerCreateTableBySepc();
|
||||
specValueLater();
|
||||
});
|
||||
|
||||
//规格数据本地保存
|
||||
$(document).on('input', '#more-spec-lists-table input', function () {
|
||||
var key = $(this).attr('name') + $(this).parent().parent().attr('spec-value-temp-ids');
|
||||
spec_table_data[key] = $(this).val();
|
||||
});
|
||||
|
||||
//动态渲染已保存的值
|
||||
function setTableValue() {
|
||||
$('#more-spec-lists-table').find('input').each(function () {
|
||||
var key = $(this).attr('name') + $(this).parent().parent().attr('spec-value-temp-ids');
|
||||
if(spec_table_data[key]!== undefined){
|
||||
$(this).val(spec_table_data[key]);
|
||||
}
|
||||
});
|
||||
$('.goods-spec-img-div').each(function(){
|
||||
var key = $(this).parent().parent().attr('spec-value-temp-ids');
|
||||
if(spec_table_data["spec_image[]"+key]){
|
||||
$(this).html('<input name="spec_image[]" type="hidden" value="' + spec_table_data["spec_image[]"+key] + '"><a class="goods-spec-img-del-x">x</a><img class="goods-spec-img" src="' + spec_table_data["spec_image[]"+key] + '">');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
likeedit.set({
|
||||
uploadImage: {
|
||||
url: "{:url('file/image')}",
|
||||
type: 'post'
|
||||
}
|
||||
});
|
||||
var likeedit_index = likeedit.build('content'); //建立编辑器
|
||||
form.verify({
|
||||
|
||||
content: function () {
|
||||
likeedit.sync(likeedit_index)
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//------------------------数据验证----------------------------------
|
||||
function switchTab(number) {
|
||||
$('.goods-tab').removeClass('layui-this');
|
||||
$('.goods-content').removeClass('layui-show');
|
||||
$('.goods-tab').eq(number).addClass('layui-this');
|
||||
$('.goods-content').eq(number).addClass('layui-show');
|
||||
|
||||
}
|
||||
|
||||
form.verify({
|
||||
custom_required: function (value, item) {
|
||||
if (!value) {
|
||||
switchTab($(item).attr('switch-tab'));
|
||||
return $(item).attr('verify-msg');
|
||||
}
|
||||
}
|
||||
,image:function(value, item) {
|
||||
var image = $('input[name="image"]').val();
|
||||
if(!image){
|
||||
switchTab($(item).attr('switch-tab'));
|
||||
return $(item).attr('verify-msg');
|
||||
}
|
||||
}
|
||||
,goods_image: function (value, item) {
|
||||
// 检查是否有上传的图片
|
||||
var imageCount = $('input[name="goods_image[]"]').filter(function() {
|
||||
return $(this).val() != '';
|
||||
}).length;
|
||||
if (imageCount == 0) {
|
||||
switchTab($(item).attr('switch-tab'));
|
||||
return $(item).attr('verify-msg');
|
||||
}
|
||||
},
|
||||
status:function(value,item){
|
||||
if(!$('input[name="status"]:checked').val()){
|
||||
return $(item).attr('verify-msg');
|
||||
}
|
||||
},
|
||||
one_spec_required: function (value, item) {
|
||||
if ($('input[name="spec_type"]:checked').val() == 1) {
|
||||
if (!value) {
|
||||
switchTab($(item).attr('switch-tab'));
|
||||
return $(item).attr('verify-msg');
|
||||
}
|
||||
}
|
||||
},
|
||||
add_more_spec: function (value, item) {
|
||||
if ($('input[name="spec_type"]:checked').val() == 2) {
|
||||
if ($('#more-spec-lists-table tbody tr').length == 0) {
|
||||
switchTab($(item).attr('switch-tab'));
|
||||
return $(item).attr('verify-msg');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
delivery: function (value, item) {
|
||||
var choose = 0;
|
||||
$('.delivery').each(function () {
|
||||
if ($(this).is(':checked')) {
|
||||
choose++;
|
||||
}
|
||||
});
|
||||
if (choose == 0) {
|
||||
switchTab($(item).attr('switch-tab'));
|
||||
return $(item).attr('verify-msg');
|
||||
}
|
||||
},
|
||||
one_volume: function (value, item) {
|
||||
if ($('input[name="spec_type"]:checked').val() == 1) {
|
||||
if (value && value < 0) {
|
||||
switchTab($(item).attr('switch-tab'));
|
||||
return '体积必须大于0';
|
||||
}
|
||||
}
|
||||
},
|
||||
one_weight: function (value, item) {
|
||||
if ($('input[name="spec_type"]:checked').val() == 1) {
|
||||
if (value && value < 0) {
|
||||
switchTab($(item).attr('switch-tab'));
|
||||
return '重量必须大于0';
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
one_price: function (value, item) {
|
||||
if ($('input[name="spec_type"]:checked').val() == 2) {
|
||||
if (value && value < 0.01) {
|
||||
switchTab($(item).attr('switch-tab'));
|
||||
return '价格必须大于或等于0.01';
|
||||
}
|
||||
}
|
||||
},
|
||||
one_cost_price: function (value, item) {
|
||||
if ($('input[name="spec_type"]:checked').val() == 2) {
|
||||
if (value && value < 0.01) {
|
||||
switchTab($(item).attr('switch-tab'));
|
||||
return '成本价格必须大于或等于0.01';
|
||||
}
|
||||
}
|
||||
},
|
||||
more_price:function (value, item) {
|
||||
if ($('input[name="spec_type"]:checked').val() == 2) {
|
||||
if (value && value < 0.01) {
|
||||
switchTab($(item).attr('switch-tab'));
|
||||
return '价格必须大于或等于0.01';
|
||||
}
|
||||
}
|
||||
},
|
||||
more_cost_price:function (value, item) {
|
||||
if ($('input[name="spec_type"]:checked').val() == 2) {
|
||||
if (value && value < 0.01) {
|
||||
switchTab($(item).attr('switch-tab'));
|
||||
return '成本价格必须大于或等于0.01';
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
more_stock: function (value, item) {
|
||||
if ($('input[name="spec_type"]:checked').val() == 2) {
|
||||
if (value && value < 0) {
|
||||
switchTab($(item).attr('switch-tab'));
|
||||
return '库存必须大于0';
|
||||
}
|
||||
}
|
||||
},
|
||||
more_weight: function (value, item) {
|
||||
if ($('input[name="spec_type"]:checked').val() == 2) {
|
||||
if (value && value < 0) {
|
||||
switchTab($(item).attr('switch-tab'));
|
||||
return '重量必须大于0';
|
||||
}
|
||||
}
|
||||
},
|
||||
more_volume: function (value, item) {
|
||||
if ($('input[name="spec_type"]:checked').val() == 2) {
|
||||
if (value && value < 0) {
|
||||
switchTab($(item).attr('switch-tab'));
|
||||
return '体积必须大于0';
|
||||
}
|
||||
}
|
||||
},
|
||||
repetition_spec_name: function (value, item) {
|
||||
if ($('input[name="spec_type"]:checked').val() == 2) {
|
||||
var spec_names = [];
|
||||
$('.spec_name').each(function () {
|
||||
spec_names.push($(this).val());
|
||||
});
|
||||
if ((new Set(spec_names)).size != spec_names.length) {
|
||||
switchTab($(item).attr('switch-tab'));
|
||||
return '规格名称重复';
|
||||
}
|
||||
}
|
||||
},
|
||||
repetition_spec_value: function (value, item) {
|
||||
if ($('input[name="spec_type"]:checked').val() == 2) {
|
||||
var spec_values = [];
|
||||
$(item).find('.goods-spec-value-input').each(function () {
|
||||
spec_values.push($(this).val());
|
||||
});
|
||||
if ((new Set(spec_values)).size != spec_values.length) {
|
||||
switchTab($(item).attr('switch-tab'));
|
||||
return '同一规格中,规格值不能重复';
|
||||
}
|
||||
}
|
||||
},
|
||||
distribution:function (value,item) {
|
||||
var first_ratio = parseFloat($('.first_ratio').val());
|
||||
var second_ratio = parseFloat($('.second_ratio').val());
|
||||
var three_ratio = parseFloat(value);
|
||||
if(first_ratio + second_ratio + three_ratio > 100){
|
||||
return '分销比例不可超过100';
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
//------------------------数据验证----------------------------------
|
||||
|
||||
|
||||
//------------------------编辑页面----------------------------------
|
||||
{notempty name='info'}
|
||||
var goods_info= {$info|raw|default=''};
|
||||
// console.log(goods_info);
|
||||
$('input[name="goods_id"]').val(goods_info['base']['id']);
|
||||
$('input[name="name"]').val(goods_info['base']['name']);
|
||||
$('input[name="mobile"]').val(goods_info['base']['mobile']);
|
||||
$('input[name="age"]').val(goods_info['base']['age']);
|
||||
|
||||
setBrand(goods_info['base']['group_id']); //渲染品牌
|
||||
setBrands(goods_info['base']['bellist_id']); //渲染品牌
|
||||
|
||||
|
||||
|
||||
$('input[name="remark"]').val(goods_info['base']['remark']);
|
||||
|
||||
// 渲染多图片
|
||||
var image_html = '';
|
||||
for(var i in goods_info['base']['goods_image']) {
|
||||
var template_goods_image = $('#template-goods-image').html();
|
||||
if (!template_goods_image) {
|
||||
console.error('模板 template-goods-image 不存在');
|
||||
continue;
|
||||
}
|
||||
// 先替换 input 中的 {image-src},再替换 img 中的 {image-src}
|
||||
var html = template_goods_image.replace('{image-src}', goods_info['base']['goods_image'][i]['uri'] || '');
|
||||
html = html.replace('{image-src}', goods_info['base']['goods_image'][i]['abs_image'] || '');
|
||||
image_html += html;
|
||||
}
|
||||
if(image_html) {
|
||||
$('.goods-img-add').prev('ul').append(image_html);
|
||||
}
|
||||
//渲染商品主图(如果还有主图字段的话)
|
||||
if(goods_info['base']['image']){
|
||||
var html = '' +
|
||||
'<input name="image" type="hidden" value="' + goods_info['base']['image'] + '">' +
|
||||
' <img class="goods-img" src="' + goods_info['base']['abs_image'] + '">\n' +
|
||||
'<a class="goods-img-del-x goods-image-del">x</a>'
|
||||
$('.master-image').html(html);
|
||||
}
|
||||
//渲染商品视频
|
||||
if(goods_info['base']['abs_video']){
|
||||
like.videoCallback([goods_info['base']['abs_video']]);
|
||||
}
|
||||
//渲染商品主图
|
||||
if(goods_info['base']['poster']){
|
||||
var html = '' +
|
||||
'<input name="poster" type="hidden" value="' + goods_info['base']['poster'] + '">' +
|
||||
' <img class="goods-img" src="' + goods_info['base']['abs_poster'] + '">\n' +
|
||||
'<a class="goods-img-del-x goods-image-del">x</a>'
|
||||
$('.poster-image').html(html);
|
||||
$('.poster-upload').hide();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
form.render();
|
||||
switchSpecType(goods_info['base']['spec_type']);
|
||||
if(goods_info['base']['spec_type'] == 1){
|
||||
var template_goods_image = $('#template-goods-image').html();
|
||||
if(goods_info['item'][0]['image']){
|
||||
$('.goods-one-spec-img-add').parent().html('<input name="one_spec_image" type="hidden" value="' + goods_info['item'][0]['image'] + '"><a class="goods-one-spec-img-del-x">x</a><img class="goods-spec-img" src="' + goods_info['item'][0]['abs_image'] + '">');
|
||||
}
|
||||
$('input[name="one_price"]').val(goods_info['item'][0]['price']);
|
||||
$('input[name="one_cost_price"]').val(goods_info['item'][0]['cost_price']);
|
||||
$('input[name="one_market_price"]').val(goods_info['item'][0]['market_price']);
|
||||
$('input[name="one_stock"]').val(goods_info['item'][0]['stock']);
|
||||
$('input[name="one_volume"]').val(goods_info['item'][0]['volume']);
|
||||
$('input[name="one_weight"]').val(goods_info['item'][0]['weight']);
|
||||
$('input[name="one_bar_code"]').val(goods_info['item'][0]['bar_code']);
|
||||
}
|
||||
if(goods_info['base']['spec_type'] == 2) {
|
||||
for(var i in goods_info['spec']){
|
||||
addSpec(goods_info['spec'][i]['name']);
|
||||
var spes_values = goods_info['spec'][i]['values'];
|
||||
for(var j in spes_values){
|
||||
addSpecvalue($('.add-spec-value').eq(i),spes_values[j]['value'],spes_values[j]['id']);
|
||||
}
|
||||
|
||||
}
|
||||
for(var i in goods_info['spec']){
|
||||
$('input[name="spec_id[]"]').eq(i).val(goods_info['spec'][i]['id']);
|
||||
}
|
||||
specValueLater();
|
||||
createTableBySepc();
|
||||
for(var i in goods_info['item']){
|
||||
$('#more-spec-lists-table tbody tr').each(function() {
|
||||
var spec_value_str = $(this).find('input[name="spec_value_str[]"]').first().val();
|
||||
if(spec_value_str == goods_info['item'][i]['spec_value_str']){
|
||||
spec_value_temp_ids = $(this).attr('spec-value-temp-ids');
|
||||
spec_table_data["spec_image[]"+spec_value_temp_ids] = goods_info['item'][i]['abs_image'];
|
||||
spec_table_data["price[]"+spec_value_temp_ids] = goods_info['item'][i]['price'];
|
||||
spec_table_data["cost_price[]"+spec_value_temp_ids] = goods_info['item'][i]['cost_price'];
|
||||
spec_table_data["market_price[]"+spec_value_temp_ids] = goods_info['item'][i]['market_price'];
|
||||
spec_table_data["stock[]"+spec_value_temp_ids] = goods_info['item'][i]['stock'];
|
||||
spec_table_data["volume[]"+spec_value_temp_ids] = goods_info['item'][i]['volume'];
|
||||
spec_table_data["weight[]"+spec_value_temp_ids] = goods_info['item'][i]['weight'];
|
||||
spec_table_data["bar_code[]"+spec_value_temp_ids] = goods_info['item'][i]['bar_code'];
|
||||
spec_table_data["item_id[]"+spec_value_temp_ids] = goods_info['item'][i]['id'];
|
||||
spec_table_data["spec_value_str[]"+spec_value_temp_ids] = goods_info['item'][i]['spec_value_str'];
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
setTableValue();
|
||||
}
|
||||
likeedit.setContent(likeedit_index,goods_info['base']['content']);
|
||||
form.render();
|
||||
{/notempty}
|
||||
//------------------------编辑页面----------------------------------
|
||||
});
|
||||
</script>
|
||||
192
application/admin/view/moments/edit.html
Normal file
192
application/admin/view/moments/edit.html
Normal file
@@ -0,0 +1,192 @@
|
||||
{layout name="layout2" /}
|
||||
<link rel="stylesheet" href="/static/admin/css/goods.css" media="all">
|
||||
<div class="">
|
||||
<div class="layui-tab-content layui-form">
|
||||
<div class="layui-tab-item goods-content layui-show">
|
||||
<div class="layui-card-body" pad15>
|
||||
<div lay-filter="">
|
||||
<input type="hidden" name="id" value="{$moment.id|default=''}">
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><span class="form-label-asterisk">*</span>标题:</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="title" lay-verify="custom_required" lay-verType="tips"
|
||||
autocomplete="off"
|
||||
switch-tab="0" verify-msg="请输入标题" placeholder="请输入标题"
|
||||
value="{$moment.title|default=''}"
|
||||
class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><span class="form-label-asterisk">*</span>员工:</label>
|
||||
<div class="layui-input-block">
|
||||
<select name="sid" lay-verType="" placeholder="请选择员工" switch-tab="0" verify-msg="请选择员工">
|
||||
<option value="">请选择员工</option>
|
||||
{foreach $staff as $key=>$vo}
|
||||
<option value="{$vo.id}" {if $moment.sid == $vo.id}selected{/if}>{$vo.name}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><span class="form-label-asterisk">*</span>产品:</label>
|
||||
<div class="layui-input-block">
|
||||
<select name="goods_id" lay-verType="" placeholder="请选择关联产品" switch-tab="0" verify-msg="请选择关联产品">
|
||||
<option value="">请选择关联产品</option>
|
||||
{foreach $goods as $key=>$vo}
|
||||
<option value="{$vo.id}" {if $moment.goods_id == $vo.id}selected{/if}>{$vo.name}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">显示状态:</label>
|
||||
<div class="layui-input-inline">
|
||||
<input type="radio" name="state" value="1" title="显示" {if $moment.state == 1}checked{/if}>
|
||||
<input type="radio" name="state" value="2" title="不显示" {if $moment.state == 2}checked{/if}>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item" style="margin-bottom: 0px">
|
||||
<label class="layui-form-label"><span class="form-label-asterisk">*</span>图片:</label>
|
||||
<div style="min-height:80px;">
|
||||
<ul style="list-style: none; padding: 0; margin: 0; display: flex; flex-wrap: wrap; gap: 10px;">
|
||||
{notempty name='images'}
|
||||
{foreach $images as $key=>$img}
|
||||
<li class="goods-li">
|
||||
<input name="goods_image[]" type="hidden" value="{$imagePaths[$key]}">
|
||||
<img class="goods-img goods_image" src="{$img}">
|
||||
<a class="goods-img-del-x" style="display: none;">x</a>
|
||||
</li>
|
||||
{/foreach}
|
||||
{/notempty}
|
||||
</ul>
|
||||
<div class="goods-img-add" lay-verify="goods_image" lay-verType="tips" switch-tab="0" verify-msg="选择图片" style="margin-top: 10px;"></div>
|
||||
</div>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">内容详情</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="content" id="content" lay-verify="content" class="field-content">{$moment.content|default=''|raw}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-hide">
|
||||
<input type="button" lay-submit lay-filter="edit-submit" id="edit-submit" value="确认">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!---------------------------------html模板---------------------------------->
|
||||
<script type="text/html" id="template-goods-image">
|
||||
<li class="goods-li">
|
||||
<input name="goods_image[]" type="hidden" value="{image-src}">
|
||||
<img class="goods-img goods_image" src="{image-src}">
|
||||
<a class="goods-img-del-x" style="display: none;">x</a></li>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
layui.config({
|
||||
version:"{$front_version}",
|
||||
base: '/static/plug/layui-admin/dist/layuiadmin/' //静态资源所在路径
|
||||
}).extend({
|
||||
index: 'lib/index' //主入口模块
|
||||
}).use(['index', 'element', 'form', 'like', 'likeedit'], function () {
|
||||
var $ = layui.$;
|
||||
var like = layui.like;
|
||||
var form = layui.form;
|
||||
var likeedit = layui.likeedit;
|
||||
|
||||
//------------------------基本信息----------------------------------
|
||||
//图片事件
|
||||
$(document).on('mouseenter', '.goods-li', function () {
|
||||
$(this).children().last().show();
|
||||
});
|
||||
$(document).on('mouseleave', '.goods-li', function () {
|
||||
$(this).children().last().hide();
|
||||
});
|
||||
$(document).on('click', '.goods-li', function () {
|
||||
var src = $(this).children('img').attr('src');
|
||||
like.showImg(src,600);
|
||||
});
|
||||
|
||||
$(document).on('click', '.goods-img-del-x', function () {
|
||||
$(this).parent().remove();
|
||||
return false;
|
||||
});
|
||||
|
||||
like.imageUpload('.goods-img-add', function (uris, element) {
|
||||
// 多图片上传逻辑(最多8张)
|
||||
var count = element.prev().children().length;
|
||||
count = !count ? 0 : count;
|
||||
if (count + uris.length > 8) {
|
||||
layer.msg('最多只能选中8张图片');
|
||||
return;
|
||||
}
|
||||
uris = uris.reverse();
|
||||
for(var i in uris){
|
||||
var uri = uris[i];
|
||||
if (!uri) continue; // 跳过无效的 uri
|
||||
|
||||
var template_goods_image = $('#template-goods-image').html();
|
||||
if (!template_goods_image) {
|
||||
console.error('模板 template-goods-image 不存在');
|
||||
continue;
|
||||
}
|
||||
|
||||
// 获取文件路径(用于 hidden input)
|
||||
var filePath = like.getUrlFileName ? like.getUrlFileName(uri, '{$storageUrl}') : uri;
|
||||
if (!filePath) {
|
||||
filePath = uri; // 如果 getUrlFileName 返回 undefined,使用原始 uri
|
||||
}
|
||||
|
||||
// 先替换 input 中的 {image-src},再替换 img 中的 {image-src}
|
||||
var html = template_goods_image.replace('{image-src}', filePath);
|
||||
html = html.replace('{image-src}', uri);
|
||||
element.prev().append(html);
|
||||
}
|
||||
}, true);
|
||||
|
||||
likeedit.set({
|
||||
uploadImage: {
|
||||
url: "{:url('file/image')}",
|
||||
type: 'post'
|
||||
}
|
||||
});
|
||||
var likeedit_index = likeedit.build('content'); //建立编辑器
|
||||
|
||||
// 设置编辑器内容(编辑模式)
|
||||
{notempty name='moment.content'}
|
||||
likeedit.setContent(likeedit_index, '{$moment.content|raw}');
|
||||
{/notempty}
|
||||
|
||||
form.verify({
|
||||
content: function () {
|
||||
likeedit.sync(likeedit_index)
|
||||
},
|
||||
custom_required: function (value, item) {
|
||||
if (!value) {
|
||||
return $(item).attr('verify-msg');
|
||||
}
|
||||
},
|
||||
goods_image: function (value, item) {
|
||||
// 检查是否有上传的图片
|
||||
var imageCount = $('input[name="goods_image[]"]').filter(function() {
|
||||
return $(this).val() != '';
|
||||
}).length;
|
||||
if (imageCount == 0) {
|
||||
return $(item).attr('verify-msg');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
form.render();
|
||||
});
|
||||
</script>
|
||||
|
||||
132
application/admin/view/moments/info.html
Normal file
132
application/admin/view/moments/info.html
Normal file
@@ -0,0 +1,132 @@
|
||||
{layout name="layout2" /}
|
||||
<link rel="stylesheet" href="/static/admin/css/goods.css" media="all">
|
||||
<div class="">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body" pad15>
|
||||
<div class="layui-form" lay-filter="">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">标题:</label>
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-input" style="border: none; background: #f5f5f5;">
|
||||
{$moment.title|default='--'}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">绑定员工:</label>
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-input" style="border: none; background: #f5f5f5;">
|
||||
{$staff.name|default='--'}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">绑定商品:</label>
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-input" style="border: none; background: #f5f5f5;">
|
||||
{$goods.name|default='--'}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">显示状态:</label>
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-input" style="border: none; background: #f5f5f5;">
|
||||
{if $moment.state == 1}
|
||||
<span class="layui-badge layui-bg-green">显示</span>
|
||||
{else /}
|
||||
<span class="layui-badge layui-bg-gray">不显示</span>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">图片:</label>
|
||||
<div class="layui-input-block">
|
||||
{notempty name='images'}
|
||||
<div style="display: flex; flex-wrap: wrap; gap: 10px;">
|
||||
{foreach $images as $img}
|
||||
<div style="position: relative; width: 120px; height: 120px; border: 1px solid #e6e6e6; cursor: pointer;" class="image-item">
|
||||
<img src="{$img}" alt="图片" style="width: 100%; height: 100%; object-fit: cover;">
|
||||
</div>
|
||||
{/foreach}
|
||||
</div>
|
||||
{else /}
|
||||
<span style="color: #999;">无图片</span>
|
||||
{/notempty}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">内容详情:</label>
|
||||
<div class="layui-input-block">
|
||||
<div style="border: 1px solid #e6e6e6; padding: 15px; min-height: 200px; background: #fafafa;">
|
||||
{$moment.content|raw|default='--'}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">收藏数量:</label>
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-input" style="border: none; background: #f5f5f5;">
|
||||
{$moment.collection|default=0}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">点赞数量:</label>
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-input" style="border: none; background: #f5f5f5;">
|
||||
{$moment.like|default=0}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">浏览量:</label>
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-input" style="border: none; background: #f5f5f5;">
|
||||
{$moment.page_views|default=0}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">创建时间:</label>
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-input" style="border: none; background: #f5f5f5;">
|
||||
{$moment.create_time|default='--'}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
layui.use(['layer'], function(){
|
||||
var layer = layui.layer;
|
||||
|
||||
// 点击图片放大查看
|
||||
$('.image-item').on('click', function(){
|
||||
var src = $(this).find('img').attr('src');
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: false,
|
||||
closeBtn: 0,
|
||||
area: 'auto',
|
||||
skin: 'layui-layer-nobg',
|
||||
shadeClose: true,
|
||||
content: '<img src="' + src + '" style="max-width: 90vw; max-height: 90vh;">'
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
469
application/admin/view/moments/lists.html
Normal file
469
application/admin/view/moments/lists.html
Normal file
@@ -0,0 +1,469 @@
|
||||
{layout name="layout1" /}
|
||||
<div class="layui-fluid">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-collapse like-layui-collapse" lay-accordion="" style="border:1px dashed #c4c4c4">
|
||||
<div class="layui-colla-item">
|
||||
<h2 class="layui-colla-title like-layui-colla-title" style="background-color: #fff">操作提示</h2>
|
||||
<div class="layui-colla-content layui-show">
|
||||
<p>*服务列表,对服务号进行编辑,调整和资料查看等操作。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form layui-card-header layuiadmin-card-header-auto">
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
<div class="layui-input-inline" style="width: 200px;">
|
||||
<input type="text" id="keyword" name="keyword" placeholder="请输入关键词" autocomplete="off" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-inline">
|
||||
<button class="layui-btn layui-btn-sm layuiadmin-btn-user {$view_theme_color}" lay-submit lay-filter="user-search">查询</button>
|
||||
<button class="layui-btn layui-btn-sm layuiadmin-btn-user layui-btn-primary " lay-submit lay-filter="user-clear-search">清空查询</button>
|
||||
<button class="layui-btn layui-btn-sm layuiadmin-btn-user layui-btn-primary " lay-submit lay-filter="export-file">导出</button>
|
||||
<button class="layui-btn layui-btn-sm layuiadmin-btn-user {$view_theme_color}" data-type="send_coupon">添加</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="layui-card-body">
|
||||
<table id="user-lists" lay-filter="user-lists"></table>
|
||||
<script type="text/html" id="user-operation">
|
||||
<a class="layui-btn layui-btn-primary layui-btn-sm" lay-event="info">资料</a>
|
||||
<a class="layui-btn layui-btn-normal layui-btn-sm" lay-event="edit">编辑</a>
|
||||
<a class="layui-btn layui-btn-normal layui-btn-sm" lay-event="del">删除</a>
|
||||
</script>
|
||||
<script type="text/html" id="user-info">
|
||||
{{ d.title }}
|
||||
</script>
|
||||
<script type="text/html" id="referrer">
|
||||
{{ d.staff_name || '--' }}
|
||||
</script>
|
||||
<script type="text/html" id="account">
|
||||
{{ d.collection || 0 }}
|
||||
</script>
|
||||
<script type="text/html" id="status">
|
||||
{{# if(d.state == 1){ }}
|
||||
<span class="layui-badge layui-bg-green">显示</span>
|
||||
{{# } else { }}
|
||||
<span class="layui-badge layui-bg-gray">不显示</span>
|
||||
{{# } }}
|
||||
</script>
|
||||
<script type="text/html" id="img-templet">
|
||||
{{# if(d.img){ }}
|
||||
<img src="{{ d.img }}" alt="封面图" style="width: 60px; height: 60px; object-fit: cover; cursor: pointer;" class="image-show">
|
||||
{{# } else { }}
|
||||
<span>无图片</span>
|
||||
{{# } }}
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<style>
|
||||
.layui-table-cell {
|
||||
height: auto;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
layui.config({
|
||||
version:"{$front_version}",
|
||||
base: '/static/plug/layui-admin/dist/layuiadmin/' //静态资源所在路径
|
||||
}).extend({
|
||||
index: 'lib/index' //主入口模块
|
||||
}).use(['index','table','like','laydate'], function(){
|
||||
var $ = layui.$
|
||||
,form = layui.form
|
||||
,table = layui.table
|
||||
,like = layui.like
|
||||
, laydate = layui.laydate;
|
||||
|
||||
//监听搜索
|
||||
form.on('submit(user-search)', function(data){
|
||||
var field = data.field;
|
||||
//执行重载
|
||||
table.reload('user-lists', {
|
||||
where: field,
|
||||
page: {
|
||||
curr: 1 //重新从第 1 页开始
|
||||
}
|
||||
});
|
||||
});
|
||||
//日期时间范围
|
||||
laydate.render({
|
||||
elem: '#start_time'
|
||||
,type: 'datetime'
|
||||
,trigger: 'click'
|
||||
});
|
||||
|
||||
//日期时间范围
|
||||
laydate.render({
|
||||
elem: '#end_time'
|
||||
,type: 'datetime'
|
||||
,trigger: 'click'
|
||||
});
|
||||
//日期时间范围
|
||||
laydate.render({
|
||||
elem: '#start_times'
|
||||
,type: 'datetime'
|
||||
,trigger: 'click'
|
||||
});
|
||||
|
||||
//日期时间范围
|
||||
laydate.render({
|
||||
elem: '#end_times'
|
||||
,type: 'datetime'
|
||||
,trigger: 'click'
|
||||
});
|
||||
|
||||
|
||||
//清空查询
|
||||
form.on('submit(user-clear-search)', function(){
|
||||
$('#keyword_type').val('sn');
|
||||
$('#keyword').val(''); //清空输入框
|
||||
$('#level').val(''); //清空输入框
|
||||
$('#group_id').val(''); //清空输入框
|
||||
$('#start_time').val(''); //清空输入框
|
||||
$('#end_time').val(''); //清空输入框
|
||||
form.render('select');
|
||||
//刷新列表
|
||||
table.reload('user-lists', {
|
||||
where: [],
|
||||
page: {
|
||||
curr: 1 //重新从第 1 页开始
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 导出
|
||||
form.on('submit(export-file)', function(data){
|
||||
var field = data.field;
|
||||
$.ajax({
|
||||
url: '{:url("user/exportFile")}',
|
||||
type: 'get',
|
||||
data: field,
|
||||
dataType: 'json',
|
||||
error: function() {
|
||||
layer.msg('导出超时,请稍后再试!');
|
||||
},
|
||||
success: function(res) {
|
||||
table.exportFile(res.data.exportTitle,res.data.exportData, res.data.exportExt, res.data.exportName);
|
||||
},
|
||||
timeout: 15000
|
||||
});
|
||||
layer.msg('导出中请耐心等待~');
|
||||
});
|
||||
|
||||
|
||||
//事件
|
||||
var active = {
|
||||
send_coupon:function() { //发放优惠券
|
||||
layer.open({
|
||||
type: 2
|
||||
,title: '添加'
|
||||
,content: '{:url("Moments/add")}'
|
||||
,area: ['55%', '80%']
|
||||
,btn: ['确定', '取消']
|
||||
,yes: function(index, layero){
|
||||
var iframeWindow = window['layui-layer-iframe'+ index]
|
||||
,submitID = 'user_group-submit'
|
||||
,submit = layero.find('iframe').contents().find("#add-user_group-submit");
|
||||
|
||||
//监听提交
|
||||
iframeWindow.layui.form.on('submit(add-user_group-submit)', function(data){
|
||||
var field = data.field;
|
||||
|
||||
// 手动收集图片数组字段,确保数据正确传递
|
||||
var goods_images = [];
|
||||
iframeWindow.$('input[name="goods_image[]"]').each(function(){
|
||||
var val = iframeWindow.$(this).val();
|
||||
if (val && val.trim() !== '') {
|
||||
goods_images.push(val.trim());
|
||||
}
|
||||
});
|
||||
|
||||
// 将图片数组添加到提交数据中
|
||||
if (goods_images.length > 0) {
|
||||
field['goods_image'] = goods_images;
|
||||
}
|
||||
|
||||
// 阻止表单默认提交,使用 AJAX 提交
|
||||
like.ajax({
|
||||
url:'{:url("Moments/add")}',
|
||||
data:field,
|
||||
type:"post",
|
||||
success:function(res)
|
||||
{
|
||||
if(res.code == 1)
|
||||
{
|
||||
layui.layer.msg(res.msg, {
|
||||
offset: '15px'
|
||||
, icon: 1
|
||||
, time: 1000
|
||||
});
|
||||
layer.close(index); //关闭弹层
|
||||
table.reload('user-lists'); //数据刷新
|
||||
} else {
|
||||
// 验证失败,显示错误信息,但不关闭弹窗,保留已上传的图片
|
||||
layui.layer.msg(res.msg || '提交失败,请检查表单信息', {
|
||||
offset: '15px'
|
||||
, icon: 2
|
||||
, time: 2000
|
||||
});
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
// 请求失败,显示错误信息,但不关闭弹窗
|
||||
layui.layer.msg('提交失败:' + (xhr.responseJSON?.msg || error), {
|
||||
offset: '15px'
|
||||
, icon: 2
|
||||
, time: 2000
|
||||
});
|
||||
}
|
||||
});
|
||||
return false; // 阻止表单默认提交
|
||||
});
|
||||
submit.trigger('click');
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
,set_group:function() { //设置分组
|
||||
var check_status = table.checkStatus('user-lists')
|
||||
,user_list = check_status.data; //得到选中的数据
|
||||
|
||||
|
||||
//是否已选数据
|
||||
if( user_list.length === 0){
|
||||
return layer.msg('请选择用户');
|
||||
}
|
||||
//获取所选id
|
||||
ids = [];
|
||||
for (var i in user_list){
|
||||
ids.push(user_list[i]['id']);
|
||||
}
|
||||
|
||||
layer.open({
|
||||
type: 2
|
||||
,title: '设置分组'
|
||||
,content: '{:url("user/setGroup")}'
|
||||
,area: ['60%', '60%']
|
||||
,btn: ['确定', '取消']
|
||||
,yes: function(index, layero){
|
||||
var iframeWindow = window['layui-layer-iframe'+ index]
|
||||
,submitID = 'user-submit-edit'
|
||||
,submit = layero.find('iframe').contents().find("#set_group-submit");
|
||||
//监听提交
|
||||
iframeWindow.layui.form.on('submit(set_group-submit)', function(data){
|
||||
var group_id = data.field.group_id;
|
||||
$.ajax({
|
||||
url:'{:url("user/setGroup")}',
|
||||
data:{group_id:group_id,user_ids:ids},
|
||||
type:"post",
|
||||
success:function(res)
|
||||
{
|
||||
if(res.code == 1)
|
||||
{
|
||||
layui.layer.msg(res.msg, {
|
||||
offset: '15px'
|
||||
, icon: 1
|
||||
, time: 1000
|
||||
});
|
||||
layer.close(index); //关闭弹层
|
||||
table.reload('user-lists'); //数据刷新
|
||||
} else if(res.code == 1){
|
||||
layui.layer.msg(res.msg)
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
submit.trigger('click');
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
$('.layui-btn.layuiadmin-btn-user').on('click', function(){
|
||||
var type = $(this).data('type');
|
||||
active[type] ? active[type].call(this) : '';
|
||||
});
|
||||
|
||||
$(document).on('click', '.image-show', function () {
|
||||
var src = $(this).attr('src');
|
||||
like.showImg(src,600);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
layui.define(['table', 'form'], function(exports){
|
||||
var $ = layui.$
|
||||
,table = layui.table
|
||||
,form = layui.form;
|
||||
|
||||
//管理员管理
|
||||
table.render({
|
||||
id:'user-lists'
|
||||
,elem: '#user-lists'
|
||||
,url: '{:url("moments/lists")}' //模拟接口
|
||||
,cols: [[
|
||||
{type: 'checkbox'}
|
||||
,{field: 'id', title: 'ID', }
|
||||
,{field: 'title', title: '标题',align: 'center', toolbar: '#user-info'}
|
||||
,{field: 'goods_name', title: '绑定商品',}
|
||||
,{field: 'staff_name', title: '绑定员工',align: 'center',toolbar: '#referrer'}
|
||||
,{field: 'img', title: '封面图', templet: '#img-templet'}
|
||||
,{field: 'collection', title: '收藏数量',toolbar: '#account'}
|
||||
,{field: 'like', title: '点赞数量'}
|
||||
,{field: 'page_views', title: '浏览量'}
|
||||
,{field: 'order_sn', title: '订单编号'}
|
||||
,{field: 'state', title: '状态',align: 'center',templet: '#status'}
|
||||
,{fixed: 'right', title: '操作', width: 360,toolbar: '#user-operation'}
|
||||
|
||||
]]
|
||||
,page:true
|
||||
,text: {none: '暂无数据!'}
|
||||
,parseData: function(res){ //将原始数据解析成 table 组件所规定的数据
|
||||
return {
|
||||
"code":res.code,
|
||||
"msg":res.msg,
|
||||
"count": res.data.count, //解析数据长度
|
||||
"data": res.data.lists, //解析数据列表
|
||||
};
|
||||
}
|
||||
, done: function fix() {
|
||||
$(".layui-table-main tr").each(function (index, val) {
|
||||
$(".layui-table-fixed").each(function () {
|
||||
$($(this).find(".layui-table-body tbody tr")[index]).height($(val).height());
|
||||
});
|
||||
});
|
||||
$(".layui-table-header tr").each(function (index, val) {
|
||||
$(".layui-table-fixed").each(function () {
|
||||
$($(this).find(".layui-table-header thead tr")[index]).height($(val).height());
|
||||
});
|
||||
});
|
||||
window.onresize = function () {
|
||||
fix()
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var moreShow = 0;
|
||||
//监听工具条
|
||||
table.on('tool(user-lists)', function(obj){
|
||||
var data = obj.data;
|
||||
|
||||
// 查看详情
|
||||
if(obj.event === 'info'){
|
||||
var id = data.id;
|
||||
layer.open({
|
||||
type: 2
|
||||
,title: '查看详情'
|
||||
,content: '{:url("moments/info")}?id='+id
|
||||
,area: ['90%','90%']
|
||||
,btn: ['返回']
|
||||
,yes: function(index){
|
||||
layer.close(index);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 编辑
|
||||
if(obj.event === 'edit'){
|
||||
var id = data.id;
|
||||
layer.open({
|
||||
type: 2
|
||||
,title: '编辑动态'
|
||||
,content: '{:url("moments/edit")}?id='+id
|
||||
,area: ['90%', '90%']
|
||||
,btn: ['确定', '取消']
|
||||
,yes: function(index, layero){
|
||||
var iframeWindow = window['layui-layer-iframe'+ index]
|
||||
,submit = layero.find('iframe').contents().find('#edit-submit');
|
||||
//监听提交
|
||||
iframeWindow.layui.form.on('submit(edit-submit)', function(formData){
|
||||
var field = formData.field;
|
||||
|
||||
// 手动收集图片数组
|
||||
var goods_images = [];
|
||||
layero.find('iframe').contents().find('input[name="goods_image[]"]').each(function(){
|
||||
var imgVal = $(this).val();
|
||||
if (imgVal) {
|
||||
goods_images.push(imgVal);
|
||||
}
|
||||
});
|
||||
field.goods_image = goods_images;
|
||||
|
||||
$.ajax({
|
||||
url:'{:url("moments/edit")}',
|
||||
data:field,
|
||||
type:"post",
|
||||
success:function(res)
|
||||
{
|
||||
if(res.code == 1)
|
||||
{
|
||||
layui.layer.msg(res.msg, {
|
||||
offset: '15px'
|
||||
, icon: 1
|
||||
, time: 1000
|
||||
});
|
||||
layer.close(index); //关闭弹层
|
||||
table.reload('user-lists'); //数据刷新
|
||||
}else{
|
||||
layer.msg(res.msg, {
|
||||
offset: '15px'
|
||||
, icon: 2
|
||||
, time: 1000
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
submit.trigger('click');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 删除
|
||||
if(obj.event === 'del'){
|
||||
var id = data.id;
|
||||
layer.confirm('确定要删除这条动态吗?', {icon: 3, title:'提示'}, function(index){
|
||||
$.ajax({
|
||||
url: '{:url("moments/del")}',
|
||||
type: 'post',
|
||||
data: {id: id},
|
||||
success: function(res){
|
||||
if(res.code == 1){
|
||||
layer.msg(res.msg, {icon: 1, time: 1000}, function(){
|
||||
table.reload('user-lists'); //数据刷新
|
||||
});
|
||||
} else {
|
||||
layer.msg(res.msg, {icon: 2, time: 1000});
|
||||
}
|
||||
layer.close(index);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if(obj.event === 'staff'){
|
||||
var id = obj.data.id;
|
||||
$.post('{:url("user/staff")}?id='+id,function(res){
|
||||
if(res.code==0){
|
||||
layer.msg(res.msg, {icon: 1, time: 1000}, function(){
|
||||
layer.msg(res.msg,{icon: 6, time: 1000});
|
||||
layer.close(index); //关闭弹层
|
||||
table.reload('user-lists'); //数据刷新
|
||||
});
|
||||
}else{
|
||||
layer.msg(res.msg)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -101,7 +101,7 @@
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">订单类型:</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="radio" name="order_ysck" title="已收款" value=""0 lay-filter="link" >
|
||||
<input type="radio" name="order_ysck" title="已收款" value="0" lay-filter="link" >
|
||||
<input type="radio" name="order_ysck" title="应收款" value="1" lay-filter="link" checked="turn">
|
||||
</div>
|
||||
</div>
|
||||
@@ -186,9 +186,12 @@
|
||||
var value = data.value;
|
||||
$('.link').hide();
|
||||
switch (value) {
|
||||
case '1':
|
||||
case '0': // 已收款时显示选择付款
|
||||
$('.page').show();
|
||||
break;
|
||||
case '1': // 应收款时隐藏
|
||||
$('.page').hide();
|
||||
break;
|
||||
case '2':
|
||||
$('.page').show();
|
||||
$('.url-tips').show();
|
||||
@@ -196,7 +199,6 @@
|
||||
case '3':
|
||||
$('.url').show();
|
||||
$('.url-tips').show();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -298,43 +298,86 @@
|
||||
|
||||
setSelectFirst();
|
||||
function setSelectFirst(default_id) {
|
||||
console.log('setSelectFirst 被调用,default_id:', default_id);
|
||||
var category_select_html = '<option value="">请选择分类</option>';
|
||||
var foundMatch = false;
|
||||
for (var i in categorys) {
|
||||
if (categorys[i]['level'] == 1) {
|
||||
category_select_html += '<option value="' + categorys[i]['id'] + '">' + categorys[i]['name'] + '</option>';
|
||||
var selected = '';
|
||||
if (default_id && String(categorys[i]['id']) == String(default_id)) {
|
||||
selected = ' selected';
|
||||
foundMatch = true;
|
||||
console.log('找到匹配的省份:', categorys[i]['name'], 'ID:', categorys[i]['id']);
|
||||
}
|
||||
category_select_html += '<option value="' + categorys[i]['id'] + '"' + selected + '>' + categorys[i]['name'] + '</option>';
|
||||
}
|
||||
}
|
||||
$('select[name="first_category_id"]').html(category_select_html);
|
||||
$('select[name="first_category_id"]').val(default_id);
|
||||
if (default_id) {
|
||||
$('select[name="first_category_id"]').val(String(default_id));
|
||||
console.log('设置省份值:', String(default_id), '是否找到匹配:', foundMatch);
|
||||
}
|
||||
form.render('select');
|
||||
}
|
||||
function setSelectSecond(default_id, parent_id) {
|
||||
console.log('setSelectSecond 被调用,default_id:', default_id, 'parent_id:', parent_id);
|
||||
parent_id = parent_id === undefined ? $('select[name="first_category_id"]').val() : parent_id;
|
||||
if (!parent_id) {
|
||||
console.log('setSelectSecond: parent_id 为空,返回');
|
||||
return;
|
||||
}
|
||||
parent_id = String(parent_id);
|
||||
$('select[name="second_category_id"]').html('<option value="">请选择分类</option>');
|
||||
$('select[name="third_category_id"]').html('<option value="">请选择分类</option>');
|
||||
var category_select_html = '<option value="">请选择分类</option>';
|
||||
var foundMatch = false;
|
||||
|
||||
for (var i in categorys) {
|
||||
if (categorys[i]['parent_id'] == parent_id) {
|
||||
category_select_html += '<option value="' + categorys[i]['id'] + '">' + categorys[i]['name'] + '</option>';
|
||||
if (String(categorys[i]['parent_id']) == parent_id) {
|
||||
var selected = '';
|
||||
if (default_id && String(categorys[i]['id']) == String(default_id)) {
|
||||
selected = ' selected';
|
||||
foundMatch = true;
|
||||
console.log('找到匹配的城市:', categorys[i]['name'], 'ID:', categorys[i]['id']);
|
||||
}
|
||||
category_select_html += '<option value="' + categorys[i]['id'] + '"' + selected + '>' + categorys[i]['name'] + '</option>';
|
||||
}
|
||||
}
|
||||
$('select[name="second_category_id"]').html(category_select_html);
|
||||
$('select[name="second_category_id"]').val(default_id);
|
||||
if (default_id) {
|
||||
$('select[name="second_category_id"]').val(String(default_id));
|
||||
console.log('设置城市值:', String(default_id), '是否找到匹配:', foundMatch);
|
||||
}
|
||||
form.render('select');
|
||||
}
|
||||
function setSelectThird(default_id, parent_id) {
|
||||
console.log('setSelectThird 被调用,default_id:', default_id, 'parent_id:', parent_id);
|
||||
parent_id = parent_id === undefined ? $('select[name="second_category_id"]').val() : parent_id;
|
||||
if (!parent_id) {
|
||||
console.log('setSelectThird: parent_id 为空,返回');
|
||||
return;
|
||||
}
|
||||
parent_id = String(parent_id);
|
||||
$('select[name="third_category_id"]').html('<option value="">请选择分类</option>');
|
||||
var first_category_id = $('select[name="first_category_id"]').val();
|
||||
var category_select_html = '<option value="">请选择分类</option>';
|
||||
var foundMatch = false;
|
||||
|
||||
for (var i in categorys) {
|
||||
if (categorys[i]['parent_id'] == parent_id) {
|
||||
category_select_html += '<option value="' + categorys[i]['id'] + '">' + categorys[i]['name'] + '</option>';
|
||||
if (String(categorys[i]['parent_id']) == parent_id) {
|
||||
var selected = '';
|
||||
if (default_id && String(categorys[i]['id']) == String(default_id)) {
|
||||
selected = ' selected';
|
||||
foundMatch = true;
|
||||
console.log('找到匹配的区县:', categorys[i]['name'], 'ID:', categorys[i]['id']);
|
||||
}
|
||||
category_select_html += '<option value="' + categorys[i]['id'] + '"' + selected + '>' + categorys[i]['name'] + '</option>';
|
||||
}
|
||||
}
|
||||
$('select[name="third_category_id"]').html(category_select_html);
|
||||
$('select[name="third_category_id"]').val(default_id);
|
||||
if (default_id) {
|
||||
$('select[name="third_category_id"]').val(String(default_id));
|
||||
console.log('设置区县值:', String(default_id), '是否找到匹配:', foundMatch);
|
||||
}
|
||||
form.render('select');
|
||||
}
|
||||
|
||||
@@ -465,7 +508,7 @@
|
||||
}
|
||||
{notempty name='info'}
|
||||
var goods_info= {$info|raw|default=''};
|
||||
console.log(goods_info);
|
||||
console.log('订单数据:', goods_info);
|
||||
$('input[name="id"]').val(goods_info['id']);
|
||||
$('input[name="address"]').val(goods_info['address']);
|
||||
$('input[name="total_amount"]').val(goods_info['total_amount']);
|
||||
@@ -474,9 +517,89 @@
|
||||
$('input[name="phone"]').val(goods_info['mobile']);
|
||||
$('input[name="store_latitude"]').val(goods_info['lng']);
|
||||
$('input[name="store_longitude"]').val(goods_info['lat']);
|
||||
setSelectFirst(goods_info['province']);
|
||||
setSelectSecond(goods_info['city']);
|
||||
setSelectThird(goods_info['district']);
|
||||
|
||||
// 设置地区选择器,根据返回的 province、city、district 字段
|
||||
// 注意:需要检查值是否存在,包括0的情况(0是有效的ID值)
|
||||
var province_id = '';
|
||||
var city_id = '';
|
||||
var district_id = '';
|
||||
|
||||
// 检查province字段(包括0值)
|
||||
if (goods_info['province'] !== undefined && goods_info['province'] !== null && goods_info['province'] !== '') {
|
||||
province_id = goods_info['province'];
|
||||
}
|
||||
// 检查city字段(包括0值)
|
||||
if (goods_info['city'] !== undefined && goods_info['city'] !== null && goods_info['city'] !== '') {
|
||||
city_id = goods_info['city'];
|
||||
}
|
||||
// 检查district字段(包括0值)
|
||||
if (goods_info['district'] !== undefined && goods_info['district'] !== null && goods_info['district'] !== '') {
|
||||
district_id = goods_info['district'];
|
||||
}
|
||||
|
||||
console.log('地区数据:', {
|
||||
province: goods_info['province'],
|
||||
city: goods_info['city'],
|
||||
district: goods_info['district'],
|
||||
province_id: province_id,
|
||||
city_id: city_id,
|
||||
district_id: district_id
|
||||
});
|
||||
|
||||
// 初始化地区选择器的函数
|
||||
function initRegionSelectors() {
|
||||
if (province_id !== '') {
|
||||
// 转换为字符串,确保类型匹配
|
||||
province_id = String(province_id);
|
||||
|
||||
// 先设置省份
|
||||
setSelectFirst(province_id);
|
||||
|
||||
// 等待省份选择器渲染完成后再设置城市
|
||||
setTimeout(function() {
|
||||
// 验证省份值是否设置成功
|
||||
var selectedProvince = $('select[name="first_category_id"]').val();
|
||||
console.log('已选省份ID:', selectedProvince, '期望:', province_id);
|
||||
|
||||
if (city_id !== '' && selectedProvince == province_id) {
|
||||
city_id = String(city_id);
|
||||
setSelectSecond(city_id, province_id);
|
||||
|
||||
// 等待城市选择器渲染完成后再设置区县
|
||||
setTimeout(function() {
|
||||
// 验证城市值是否设置成功
|
||||
var selectedCity = $('select[name="second_category_id"]').val();
|
||||
console.log('已选城市ID:', selectedCity, '期望:', city_id);
|
||||
|
||||
if (district_id !== '' && selectedCity == city_id) {
|
||||
district_id = String(district_id);
|
||||
setSelectThird(district_id, city_id);
|
||||
|
||||
setTimeout(function() {
|
||||
var selectedDistrict = $('select[name="third_category_id"]').val();
|
||||
console.log('已选区县ID:', selectedDistrict, '期望:', district_id);
|
||||
// 最后重新渲染一次,确保所有选择器都正确显示
|
||||
form.render('select');
|
||||
}, 100);
|
||||
} else {
|
||||
form.render('select');
|
||||
}
|
||||
}, 300);
|
||||
} else {
|
||||
form.render('select');
|
||||
}
|
||||
}, 300);
|
||||
} else {
|
||||
form.render('select');
|
||||
}
|
||||
}
|
||||
|
||||
// 延迟执行,确保页面完全加载和选择器初始化完成
|
||||
setTimeout(function() {
|
||||
console.log('开始初始化地区选择器...');
|
||||
initRegionSelectors();
|
||||
}, 200);
|
||||
|
||||
setBrand(goods_info['channel_id']); //部门的修改
|
||||
setBrandss(goods_info['gord_id']); //部门的修改
|
||||
|
||||
|
||||
@@ -73,6 +73,20 @@
|
||||
height: 62px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
/* 退款中状态绿色背景 */
|
||||
.refunding-row {
|
||||
background-color: #c8e6c9 !important;
|
||||
}
|
||||
.refunding-row:hover {
|
||||
background-color: #a5d6a7 !important;
|
||||
}
|
||||
/* 同意退款后淡绿色背景 */
|
||||
.order-status-4-row {
|
||||
background-color: #e8f5e9 !important;
|
||||
}
|
||||
.order-status-4-row:hover {
|
||||
background-color: #c8e6c9 !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="layui-fluid">
|
||||
@@ -199,6 +213,7 @@
|
||||
<li data-type="1">已支付</li>
|
||||
<li data-type="2">已退款</li>
|
||||
<li data-type="3">拒退款</li>
|
||||
<li data-type="66">已删除</li>
|
||||
</ul>
|
||||
|
||||
<div class="layui-tab-item layui-show">
|
||||
@@ -331,7 +346,11 @@
|
||||
<a class="layui-btn-primary layui-btn-sm" lay-event="channel" style="display: inline-block;">渠道</a>
|
||||
<a class="layui-btn layui-btn-primary layui-btn-sm operation-btn" lay-event="remarks">备注</a>
|
||||
<a class="layui-btn-primary layui-btn-sm" style="display: inline-block;" lay-event="allocation"> 分配</a>
|
||||
{{# if(d.del == 0){ }}
|
||||
<a class="layui-btn layui-btn-primary layui-btn-sm operation-btn" style="display: inline-block;background-color:#fd4634;color:#fff" lay-event="cancel">删除</a>
|
||||
{{# } else { }}
|
||||
<a class="layui-btn layui-btn-primary layui-btn-sm operation-btn" style="display: inline-block;background-color:#1E9FFF;color:#fff" lay-event="recover">恢复</a>
|
||||
{{# } }}
|
||||
{{# if(d.order_status == 1){ }}
|
||||
<a class="layui-btn-primary layui-btn-sm" style="display: inline-block;" lay-event="delivery">发货</a>
|
||||
{{# } }}
|
||||
@@ -356,18 +375,46 @@
|
||||
<div style="text-align: left">
|
||||
<p>订单编号:{{d.order_sn}}</p>
|
||||
<p>下单时间:{{d.create_time}}</p>
|
||||
<p>订单来源:{{d.channel}}</p>
|
||||
<p>收款方式:{{d.gord_name}}</p>
|
||||
<p>订单来源:
|
||||
{{# if(d.channel){ }}
|
||||
{{d.channel}}
|
||||
{{# } else { }}
|
||||
小程序
|
||||
{{# } }}
|
||||
</p>
|
||||
<p>支付方式:
|
||||
{{# if(d.pay_way == 1){ }}
|
||||
微信支付
|
||||
{{# } }}
|
||||
{{# if(d.pay_way == 2){ }}
|
||||
支付宝支付
|
||||
{{# } }}
|
||||
{{# if(d.pay_way == 3){ }}
|
||||
余额支付
|
||||
{{# } }}
|
||||
{{# if(!d.pay_way || (d.pay_way != 1 && d.pay_way != 2 && d.pay_way != 3)){ }}
|
||||
-
|
||||
{{# } }}
|
||||
</p>
|
||||
|
||||
|
||||
{{# if(d.pay_zd == 0){ }}
|
||||
<p style="color:#fe0707">支付状态:
|
||||
已收款
|
||||
{{# if(d.pay_status == 0 || d.pay_zd == 1){ }}
|
||||
<p style="color:#fe0707">订单状态:
|
||||
待支付
|
||||
</p>
|
||||
{{# } }}
|
||||
{{# if(d.pay_zd == 1){ }}
|
||||
<p style="color:#3A91FB">支付状态:
|
||||
未收账款
|
||||
{{# if(d.pay_status == 1 && d.pay_zd == 0){ }}
|
||||
<p style="color:#3A91FB">订单状态:
|
||||
已支付
|
||||
</p>
|
||||
{{# } }}
|
||||
{{# if(d.pay_status == 2){ }}
|
||||
<p style="color:#ff9800">订单状态:
|
||||
已退款
|
||||
</p>
|
||||
{{# } }}
|
||||
{{# if(d.pay_status == 3){ }}
|
||||
<p style="color:#f44336">订单状态:
|
||||
拒绝退款
|
||||
</p>
|
||||
{{# } }}
|
||||
</div>
|
||||
@@ -582,6 +629,7 @@
|
||||
, {field: 'order_goods', title: '商品信息', align: 'center',templet:'#goods',width:320}
|
||||
, {field: 'total_amount', title: '支付信息', align: 'center',templet:'#amount',width:180}
|
||||
, {field: 'admin_id', title: '订单归属人', align: 'center',width:180}
|
||||
, {field: 'order_remarks', title: '备注信息', align: 'center',width:130}
|
||||
, {fixed: 'right', title: '操作', width: 160, align: 'center', toolbar: '#order-operation'}
|
||||
]]
|
||||
, page: true
|
||||
@@ -600,6 +648,40 @@
|
||||
$($(".layui-table-fixed-l .layui-table-body tbody tr")[index]).height($(val).height());
|
||||
$($(".layui-table-fixed-r .layui-table-body tbody tr")[index]).height($(val).height());
|
||||
});
|
||||
|
||||
// 如果 order_status == 4(同意退款),整行淡绿色显示
|
||||
// 如果 refund_status > 0 但 order_status != 4(退款中),整行绿色显示
|
||||
if (res && res.data && res.data.length > 0) {
|
||||
res.data.forEach(function(item, index) {
|
||||
var orderStatus = item.order_status ? parseInt(item.order_status) : 0;
|
||||
var refundStatus = item.refund_status ? parseInt(item.refund_status) : 0;
|
||||
|
||||
// 同意退款后,order_status == 4,显示淡绿色
|
||||
if (orderStatus == 4) {
|
||||
// 给主表格行添加淡绿色背景
|
||||
var $mainRow = $(".layui-table-main tbody tr").eq(index);
|
||||
$mainRow.addClass('order-status-4-row');
|
||||
|
||||
// 给固定列的行也添加淡绿色背景
|
||||
var $fixedLeftRow = $(".layui-table-fixed-l .layui-table-body tbody tr").eq(index);
|
||||
var $fixedRightRow = $(".layui-table-fixed-r .layui-table-body tbody tr").eq(index);
|
||||
$fixedLeftRow.addClass('order-status-4-row');
|
||||
$fixedRightRow.addClass('order-status-4-row');
|
||||
}
|
||||
// 退款中,refund_status > 0 但 order_status != 4,显示绿色
|
||||
else if (refundStatus > 0) {
|
||||
// 给主表格行添加绿色背景
|
||||
var $mainRow = $(".layui-table-main tbody tr").eq(index);
|
||||
$mainRow.addClass('refunding-row');
|
||||
|
||||
// 给固定列的行也添加绿色背景
|
||||
var $fixedLeftRow = $(".layui-table-fixed-l .layui-table-body tbody tr").eq(index);
|
||||
var $fixedRightRow = $(".layui-table-fixed-r .layui-table-body tbody tr").eq(index);
|
||||
$fixedLeftRow.addClass('refunding-row');
|
||||
$fixedRightRow.addClass('refunding-row');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -782,7 +864,7 @@
|
||||
});
|
||||
}
|
||||
|
||||
//取消订单
|
||||
// 退款订单
|
||||
if(obj.event === 'cancelss'){
|
||||
layer.confirm('确认订单退款吗?', {
|
||||
btn: ['确认','取消'] //按钮
|
||||
@@ -807,7 +889,7 @@
|
||||
}
|
||||
|
||||
|
||||
//取消订单
|
||||
// 删除订单(逻辑删除,del 设置为 1)
|
||||
if(obj.event === 'cancel'){
|
||||
layer.confirm('确定删除订单的数据?', {
|
||||
btn: ['确认','取消'] //按钮
|
||||
@@ -829,6 +911,35 @@
|
||||
});
|
||||
}
|
||||
|
||||
// 恢复订单(del 设置为 0)
|
||||
if(obj.event === 'recover'){
|
||||
layer.confirm('确定恢复该订单吗?', {
|
||||
btn: ['确认','取消'] //按钮
|
||||
}, function(){
|
||||
like.ajax({
|
||||
url: '{:url("order/recover")}?id='+id
|
||||
, type: 'get'
|
||||
, success: function (res) {
|
||||
if (res.code == 1) {
|
||||
layui.layer.msg(res.msg, {
|
||||
offset: '15px'
|
||||
, icon: 1
|
||||
, time: 1000
|
||||
},function () {
|
||||
table.reload('order-lists');
|
||||
});
|
||||
} else {
|
||||
layui.layer.msg(res.msg || '恢复失败', {
|
||||
offset: '15px'
|
||||
, icon: 2
|
||||
, time: 1500
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//商家备注
|
||||
if(obj.event === 'remarks') {
|
||||
like.ajax({
|
||||
|
||||
@@ -48,7 +48,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script charset="utf-8" src="https://map.qq.com/api/gljs?v=1.exp&libraries=service&key=EVOBZ-VX7YU-QKJVR-BVESA-AVFT3-7JBWG"></script>
|
||||
<!--<script charset="utf-8" src="https://map.qq.com/api/gljs?v=1.exp&libraries=service&key=EVOBZ-VX7YU-QKJVR-BVESA-AVFT3-7JBWG"></script>-->
|
||||
<script charset="utf-8" src="https://map.qq.com/api/gljs?v=1.exp&libraries=service&key=66NBZ-KH3W4-7QSUS-K5OBA-7P552-F7F6T"></script>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
@@ -90,7 +90,9 @@
|
||||
<button class="layui-btn layui-btn-sm layuiadmin-btn-ad layui-btn-primary " lay-submit
|
||||
lay-filter="user-clear-search">清空查询
|
||||
</button>
|
||||
|
||||
<button class="layui-btn layui-btn-sm layuiadmin-btn-ad layui-btn-normal" lay-submit
|
||||
lay-filter="export-file">导出
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -161,7 +163,7 @@
|
||||
form.on('submit(export-file)', function(data){
|
||||
var field = data.field;
|
||||
$.ajax({
|
||||
url: '{:url("order/exportFile")}?type=' + listType,
|
||||
url: '{:url("staff/exportWages")}',
|
||||
type: 'get',
|
||||
data: field,
|
||||
dataType: 'json',
|
||||
@@ -171,7 +173,7 @@
|
||||
success: function(res) {
|
||||
table.exportFile(res.data.exportTitle,res.data.exportData, res.data.exportExt, res.data.exportName);
|
||||
},
|
||||
timeout: 15000
|
||||
timeout: 60000
|
||||
});
|
||||
layer.msg('导出中请耐心等待~');
|
||||
});
|
||||
|
||||
@@ -144,7 +144,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script charset="utf-8" src="https://map.qq.com/api/gljs?v=1.exp&libraries=service&key=EVOBZ-VX7YU-QKJVR-BVESA-AVFT3-7JBWG"></script>
|
||||
<!--<script charset="utf-8" src="https://map.qq.com/api/gljs?v=1.exp&libraries=service&key=EVOBZ-VX7YU-QKJVR-BVESA-AVFT3-7JBWG"></script>-->
|
||||
<script charset="utf-8" src="https://map.qq.com/api/gljs?v=1.exp&libraries=service&key=66NBZ-KH3W4-7QSUS-K5OBA-7P552-F7F6T"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
//注意:选项卡 依赖 element 模块,否则无法进行功能性操作
|
||||
|
||||
@@ -25,7 +25,7 @@ use think\Request;
|
||||
class AppEnd
|
||||
{
|
||||
/**
|
||||
* 记录统计信息(用户访问量)
|
||||
* 记录统计信息(用户访问量)1212
|
||||
* @param Request $request
|
||||
*/
|
||||
public function run(Request $request)
|
||||
|
||||
@@ -5,10 +5,16 @@ namespace app\api\controller;
|
||||
|
||||
use app\api\logic\AdLogic;
|
||||
|
||||
use app\common\server\UrlServer;
|
||||
use think\Db;
|
||||
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
|
||||
header("Access-Control-Allow-Headers: Content-Type, Authorization");
|
||||
|
||||
class Ad extends ApiBase
|
||||
{
|
||||
public $like_not_need_login = ['lists','channel','label','add_comost','add_comost','list_comost','follow_comost','comost_add','label_edit','comost_info','notice','position','position_list','vode_type','video_list','video_info','user_wages','user_wages_add','user_leave','fine','recruit','last_leave','last_fine','notice_list','leave','auth'];
|
||||
public $like_not_need_login = ['lists','popup','channel','label','add_comost','add_comost','list_comost','follow_comost','comost_add','label_edit','comost_info','notice','position','position_list','vode_type','video_list','video_info','user_wages','user_wages_add','user_leave','fine','recruit','last_leave','last_fine','notice_list','leave','auth'];
|
||||
|
||||
/**
|
||||
* @return void
|
||||
@@ -26,6 +32,21 @@ class Ad extends ApiBase
|
||||
$this->_success('获取成功', $list);
|
||||
}
|
||||
|
||||
|
||||
//获取弹窗
|
||||
public function popup()
|
||||
{
|
||||
$list = Db::name('ad')
|
||||
->where('status',1)
|
||||
->where('pid',25)
|
||||
->field('id,name,image,link_type,link')
|
||||
->find();
|
||||
if ($list != null){
|
||||
$list['image'] = UrlServer::getFileUrl($list['image']);
|
||||
}
|
||||
$this->_success('获取成功', $list);
|
||||
}
|
||||
|
||||
//获取客户的渠道
|
||||
public function channel(){
|
||||
$list=Db::name('staffchannel')->field('id,name')->select();
|
||||
|
||||
@@ -26,7 +26,7 @@ use app\api\logic\AfterSaleLogic;
|
||||
* Class Order
|
||||
* @package app\api\controller
|
||||
*/
|
||||
class AfterSale extends ApiBase
|
||||
class Aftersale extends ApiBase
|
||||
{
|
||||
public function lists()
|
||||
{
|
||||
@@ -107,7 +107,10 @@ class AfterSale extends ApiBase
|
||||
$this->_error('订单已完成,无法申请退款');
|
||||
}
|
||||
$ref=Db::name('order')->where('id',$post['id'])->update(['refund_status'=>2]);
|
||||
|
||||
if ($ref){
|
||||
$this->_success('申请成功');
|
||||
}else{
|
||||
$this->_error('申请失败');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,10 @@ use think\facade\Config;
|
||||
use think\facade\Debug;
|
||||
use think\Response;
|
||||
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
|
||||
header("Access-Control-Allow-Headers: Content-Type, Authorization");
|
||||
|
||||
class ApiBase extends Controller
|
||||
{
|
||||
public $user_info = [];
|
||||
|
||||
89
application/api/controller/Calendar.php
Normal file
89
application/api/controller/Calendar.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\controller;
|
||||
|
||||
use think\Db;
|
||||
|
||||
class Calendar extends ApiBase
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$month = $this->request->post("month");
|
||||
if (!$month) {
|
||||
return $this->_error("月份不能为空");
|
||||
}
|
||||
|
||||
// 验证月份格式:2026-01
|
||||
if (!preg_match('/^\d{4}-\d{2}$/', $month)) {
|
||||
return $this->_error("月份格式错误,请使用格式:2026-01");
|
||||
}
|
||||
// 计算该月的开始和结束日期
|
||||
$startDate = $month . '-01';
|
||||
$endDate = date('Y-m-t', strtotime($startDate)); // 获取该月最后一天
|
||||
|
||||
$uid = $this->user_id;
|
||||
|
||||
// 查询该月份的所有服务数据,关联总订单表、商品表和员工表
|
||||
$service = Db::name('order_exe')
|
||||
->alias('oe')
|
||||
->join('order o', 'oe.order_sn = o.order_sn', 'INNER')
|
||||
->join('goods g', 'oe.goods_id = g.id', 'LEFT')
|
||||
->join('staff s', 'oe.staff_id = s.id', 'LEFT')
|
||||
->where('o.user_id', $uid)
|
||||
->where('oe.date', '>=', $startDate)
|
||||
->where('oe.date', '<=', $endDate)
|
||||
->where('oe.abnormal', 0)
|
||||
->field('oe.staff_status,oe.date,oe.addtime,oe.start_time,oe.timeout,oe.xq,oe.staff_id,oe.order_sn,s.name as staff_name,s.onwork,s.leave,g.name as goods_name')
|
||||
->order('oe.date asc, oe.addtime asc')
|
||||
->select();
|
||||
|
||||
$serviceDate = [];
|
||||
if ($service) {
|
||||
foreach ($service as $v) {
|
||||
// 如果有绑定员工,但员工状态不符合要求,则跳过
|
||||
// 注释掉员工状态过滤,先看看是否能查询出来
|
||||
// if (!empty($v['staff_id']) && ($v['onwork'] != 1 || $v['leave'] != 1)) {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// 处理服务时间
|
||||
$timeRange = '';
|
||||
if (!empty($v['start_time']) && !empty($v['timeout'])) {
|
||||
// 判断是否为时间戳(数字)
|
||||
$startTimestamp = is_numeric($v['start_time']) ? $v['start_time'] : strtotime($v['start_time']);
|
||||
$timeoutTimestamp = is_numeric($v['timeout']) ? $v['timeout'] : strtotime($v['timeout']);
|
||||
$startTime = date('H:i', $startTimestamp);
|
||||
$timeoutTime = date('H:i', $timeoutTimestamp);
|
||||
$timeRange = $startTime . '-' . $timeoutTime;
|
||||
} elseif (!empty($v['start_time'])) {
|
||||
$startTimestamp = is_numeric($v['start_time']) ? $v['start_time'] : strtotime($v['start_time']);
|
||||
$startTime = date('H:i', $startTimestamp);
|
||||
$timeRange = $startTime;
|
||||
}
|
||||
|
||||
$serviceDate[] = [
|
||||
'staff_status' => $v['staff_status'],
|
||||
'date' => $v['date'],
|
||||
'staff_name' => $v['staff_name'] ?? '',
|
||||
'goods_name' => $v['goods_name'] ?? '',
|
||||
'addtime' => $v['addtime'] == 1 ? '上午' : ($v['addtime'] == 2 ? '下午' : ''), //1表示上午,2表示下午
|
||||
'serviceTime' => $timeRange,
|
||||
'xq' => $v['xq'] ?? $this->getChineseWeekDay($v['date']), // 如果没有xq字段,则根据日期计算
|
||||
];
|
||||
}
|
||||
}
|
||||
return $this->_success("成功", $serviceDate);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取中文星期
|
||||
* @param string $date 日期格式:Y-m-d
|
||||
* @return string
|
||||
*/
|
||||
private function getChineseWeekDay($date)
|
||||
{
|
||||
$weekDay = date('w', strtotime($date));
|
||||
$weekList = ['日', '一', '二', '三', '四', '五', '六'];
|
||||
return '星期' . $weekList[$weekDay];
|
||||
}
|
||||
}
|
||||
@@ -42,7 +42,7 @@ class Cart extends ApiBase
|
||||
if (true !== $check) {
|
||||
$this->_error($check);
|
||||
}
|
||||
$res = CartLogic::add($post['item_id'], $post['goods_num'], $this->user_id);
|
||||
$res = CartLogic::add($post['item_id'], $post['goods_num'], $this->user_id, $post['type']);
|
||||
if ($res === true) {
|
||||
$this->_success('加入成功');
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace app\api\controller;
|
||||
|
||||
use app\api\server\CityService;
|
||||
use app\api\model\User;
|
||||
|
||||
class City extends ApiBase
|
||||
{
|
||||
@@ -23,6 +24,39 @@ class City extends ApiBase
|
||||
public function index()
|
||||
{
|
||||
$array = $this->cityService->list();
|
||||
return $this->_success($array);
|
||||
return $this->_success('成功',$array);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据经纬度获取所在城市
|
||||
* @return void
|
||||
*/
|
||||
public function getCity()
|
||||
{
|
||||
$lat = $this->request->param('lat', '');
|
||||
$lng = $this->request->param('lng', '');
|
||||
|
||||
if (empty($lat) || empty($lng)) {
|
||||
return $this->_error('请提供经纬度参数');
|
||||
}
|
||||
$uid = $this->user_id;
|
||||
//查询用户信息
|
||||
$userInfo = User::find($uid);
|
||||
if ($userInfo) {
|
||||
if ($userInfo->longitude == '' || $userInfo->latitude == '')
|
||||
{
|
||||
$userInfo->longitude = $lng; // 经度
|
||||
$userInfo->latitude = $lat; // 纬度
|
||||
$userInfo->save();
|
||||
}
|
||||
}
|
||||
$result = $this->cityService->getCityByLocation($lat, $lng);
|
||||
|
||||
if ($result['success']) {
|
||||
return $this->_success($result['msg'], $result['data']);
|
||||
} else {
|
||||
return $this->_error($result['msg'], $result['data']);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,4 +44,15 @@ class File extends ApiBase
|
||||
$data = FileServer::userFormImage($this->user_id);
|
||||
$this->_success($data['msg'], $data['data'], $data['code']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 视频上传
|
||||
* @param string $file
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function videoUpload($file = '')
|
||||
{
|
||||
$result = FileServer::video();
|
||||
$this->_success('上传成功', $result);
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ class Goods extends ApiBase{
|
||||
*/
|
||||
public function getGoodsList(){
|
||||
$get = $this->request->get();
|
||||
$goods_list = GoodsLogic::getGoodsList($this->user_id, $get, $this->page_no, $this->page_size);
|
||||
$goods_list = GoodsLogic::getGoodsList($this->user_id, $get, $this->page_no, $this->page_size,$get['type']);
|
||||
$this->_success('获取成功',$goods_list);
|
||||
|
||||
}
|
||||
|
||||
@@ -14,7 +14,8 @@ class GoodsCategory extends ApiBase{
|
||||
*/
|
||||
public function lists(){
|
||||
$client = $this->request->get('client',1);
|
||||
$cateogry = GoodsCategoryLogic::categoryThirdTree($client);
|
||||
$type = $this->request->get('type',1);
|
||||
$cateogry = GoodsCategoryLogic::categoryThirdTree($client,$type);
|
||||
|
||||
$this->_success('获取成功',$cateogry);
|
||||
}
|
||||
|
||||
@@ -49,4 +49,12 @@ class Help extends ApiBase
|
||||
$this->_success('获取成功', $help_detail);
|
||||
}
|
||||
|
||||
//查询承诺
|
||||
public function commitment()
|
||||
{
|
||||
$help = new HelpLogic();
|
||||
$commitment = $help->commitmentInfo();
|
||||
$this->_success('获取成功', $commitment);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,6 +31,11 @@ class Index extends ApiBase
|
||||
{
|
||||
public $like_not_need_login = ['test','sedx','lists','appInit', 'downLine', 'share', 'config','pcLists','goods_stay_time','send_sms','get_pege'];
|
||||
|
||||
public function visit()
|
||||
{
|
||||
$this->_success('',['a'=>1]);
|
||||
}
|
||||
|
||||
//短信宝接口
|
||||
public function sedx(){
|
||||
$nowtime = time();
|
||||
|
||||
122
application/api/controller/Invoice.php
Normal file
122
application/api/controller/Invoice.php
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\controller;
|
||||
|
||||
use app\admin\model\InvoiceLog;
|
||||
use think\Db;
|
||||
|
||||
class Invoice extends ApiBase
|
||||
{
|
||||
|
||||
//添加发票
|
||||
public function add()
|
||||
{
|
||||
$dataPost = $this->request->post();
|
||||
if (empty($dataPost['type'])){
|
||||
return $this->_error('请选择发票类型');
|
||||
}
|
||||
if (empty($dataPost['invoice_type'])){
|
||||
return $this->_error('请选择类型');
|
||||
}
|
||||
if (empty($dataPost['invoice_title'])){
|
||||
return $this->_error('请填写发票抬头');
|
||||
}
|
||||
if (empty($dataPost['identification'])){
|
||||
return $this->_error('请填写纳税人识别号');
|
||||
}
|
||||
$uid = $this->user_id;
|
||||
$data = [
|
||||
'uid' => $uid,
|
||||
'type' => $dataPost['type'],
|
||||
'invoice_type' => $dataPost['invoice_type'],
|
||||
'invoice_title' => $dataPost['invoice_title'],
|
||||
'identification' => $dataPost['identification'],
|
||||
'address' => $dataPost['address'],
|
||||
'phone' => $dataPost['phone'],
|
||||
'bank' => $dataPost['bank'],
|
||||
'account' => $dataPost['account'],
|
||||
'create_time' => date('Y-m-d H:i:s', time())
|
||||
];
|
||||
$res = Db::name('invoice')->insert($data);
|
||||
if ($res){
|
||||
return $this->_success('添加成功');
|
||||
}else{
|
||||
return $this->_error('添加失败');
|
||||
}
|
||||
}
|
||||
|
||||
//发票列表
|
||||
public function list()
|
||||
{
|
||||
$uid = $this->user_id;
|
||||
$list = Db::name('invoice')->where('uid', $uid)->select();
|
||||
return $this->_success('成功', $list);
|
||||
}
|
||||
|
||||
//申请发票
|
||||
public function apply()
|
||||
{
|
||||
$dataPost = $this->request->post();
|
||||
if (empty($dataPost['invoice_id'])) {
|
||||
return $this->_error('请选择发票信息');
|
||||
}
|
||||
if (empty($dataPost['order_id'])) {
|
||||
return $this->_error('请选择要开票订单');
|
||||
}
|
||||
$uid = $this->user_id;
|
||||
//查询是否存在该开票信息
|
||||
$invoice = Db::name('invoice')->where('id', $dataPost['invoice_id'])->find();
|
||||
if (!$invoice) {
|
||||
return $this->_error('发票信息不存在');
|
||||
}
|
||||
$order = Db::name('order')->where('id', $dataPost['order_id'])->find();
|
||||
if (!$order) {
|
||||
return $this->_error('订单信息不存在');
|
||||
}
|
||||
$data = [
|
||||
'uid' => $uid,
|
||||
'invoice_id' => $dataPost['invoice_id'],
|
||||
'oid' => $dataPost['order_id'],
|
||||
'state' => 1,
|
||||
'create_time' => date('Y-m-d H:i:s', time())
|
||||
];
|
||||
$res = Db::name('invoice_log')->insert($data);
|
||||
if ($res) {
|
||||
return $this->_success('申请成功');
|
||||
} else {
|
||||
return $this->_error('申请失败');
|
||||
}
|
||||
}
|
||||
|
||||
//发票申请列表
|
||||
public function applyList()
|
||||
{
|
||||
$uid = $this->user_id;
|
||||
$list = InvoiceLog::with([
|
||||
'invoice' => function ($query) {
|
||||
$query->field('id,type,invoice_type,invoice_title');
|
||||
},
|
||||
'order' => function ($query) {
|
||||
$query->field('id,order_sn,settle_amount');
|
||||
}
|
||||
])->where('uid', $uid)->paginate(10);
|
||||
$data = [];
|
||||
if ($list != null){
|
||||
$currentDomain = $_SERVER['HTTP_HOST'];
|
||||
foreach ($list as $value){
|
||||
$data[] = [
|
||||
'id' => $value['id'],
|
||||
'state' => $value['state'],
|
||||
'type' => $value['invoice']['type'],
|
||||
'invoice_type' => $value['invoice']['invoice_type'],
|
||||
'invoice_title' => $value['invoice']['invoice_title'],
|
||||
'order_sn' => $value['order']['order_sn'] ?? '',
|
||||
'order_money' => $value['order']['settle_amount'] ?? 0,
|
||||
'document' => "https://".$currentDomain."/public/".$value['document'] ?? '',
|
||||
];
|
||||
}
|
||||
}
|
||||
$datas = ['data_list' => $data, 'total' => $list->total()];
|
||||
return $this->_success('成功', $datas);
|
||||
}
|
||||
}
|
||||
314
application/api/controller/Moments.php
Normal file
314
application/api/controller/Moments.php
Normal file
@@ -0,0 +1,314 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\controller;
|
||||
|
||||
use app\admin\model\Moments as MomentsModel;
|
||||
use app\common\server\UrlServer;
|
||||
use think\Db;
|
||||
use think\facade\Log;
|
||||
|
||||
class Moments extends ApiBase
|
||||
{
|
||||
//服务业务
|
||||
|
||||
public $like_not_need_login = ['index'];
|
||||
|
||||
//列表
|
||||
public function index()
|
||||
{
|
||||
$dataArray = MomentsModel::with('getStaff')
|
||||
->where('state',1)
|
||||
->order('page_views desc, like desc')
|
||||
->paginate(10);
|
||||
$data = [];
|
||||
if ($dataArray != null){
|
||||
foreach ($dataArray as $value){
|
||||
$img = '';
|
||||
if (!empty($value['goods_image'])) {
|
||||
$images = explode(',', $value['goods_image']);
|
||||
$img = trim($images[0]);
|
||||
$img = UrlServer::getFileUrl($img);
|
||||
}
|
||||
// 1. 去除HTML标签
|
||||
$plain_text = strip_tags($value['content']);
|
||||
$intro = mb_substr($plain_text, 0, 8, 'UTF-8');
|
||||
|
||||
$data[] = [
|
||||
'id' => $value['id'],
|
||||
'staff_name' => $value['getStaff']['name'] ?? "",
|
||||
'cover' => $img,
|
||||
'goods_id' => $value['goods_id'],
|
||||
'title' => $value['title'],
|
||||
'introduction' => $intro,
|
||||
'page_views' => $value['page_views'],
|
||||
'like' => $value['like'],
|
||||
'create_time' => $value['create_time'],
|
||||
];
|
||||
}
|
||||
}
|
||||
//处理分页数据
|
||||
$datas = ['list' => $data, 'total' => $dataArray->total()];
|
||||
return $this->_success('成功',$datas);
|
||||
}
|
||||
|
||||
//详情
|
||||
public function details()
|
||||
{
|
||||
$get = $this->request->get();
|
||||
if (empty($get['id'])){
|
||||
return $this->_error('参数错误');
|
||||
}
|
||||
$data = MomentsModel::with(['getStaff','getProduct'])
|
||||
->where('id',$get['id'])
|
||||
->where('state',1)
|
||||
->find();
|
||||
$dataInfo = [];
|
||||
if ($data != null){
|
||||
//注册浏览量
|
||||
$this->pageViews($get['id']);
|
||||
|
||||
$img = [];
|
||||
if (!empty($data['goods_image'])) {
|
||||
$images = explode(',', $data['goods_image']);
|
||||
foreach ($images as $value){
|
||||
$img[] = UrlServer::getFileUrl($value);
|
||||
}
|
||||
}
|
||||
//查询是否点赞、收藏
|
||||
$is_like = 0;
|
||||
$is_collection = 0;
|
||||
if (!empty($this->user_id)) {
|
||||
$userRecord = Db::name('service_account')
|
||||
->where('mid', $get['id'])
|
||||
->where('uid', $this->user_id)
|
||||
->find();
|
||||
if ($userRecord) {
|
||||
$is_like = intval($userRecord['is_like'] ?? 0);
|
||||
$is_collection = intval($userRecord['is_collection'] ?? 0);
|
||||
}
|
||||
}
|
||||
|
||||
$dataInfo = [
|
||||
'id' => $data['id'],
|
||||
'staff_name' => $data['getStaff']['name'] ?? "",
|
||||
'img' => $img,
|
||||
'goods_id' => $data['goods_id'],
|
||||
'goods_name' => $data['getProduct']['name'] ?? "",
|
||||
'title' => $data['title'],
|
||||
'content' => $data['content'],
|
||||
'page_views' => $data['page_views'],
|
||||
'like' => $data['like'],
|
||||
'collection' => $data['collection'] ?? 0,
|
||||
'is_like' => $is_like,
|
||||
'is_collection' => $is_collection,
|
||||
'create_time' => $data['create_time'],
|
||||
];
|
||||
}
|
||||
return $this->_success('成功',$dataInfo);
|
||||
}
|
||||
|
||||
//注册浏览量(使用原子操作解决并发问题)
|
||||
public function pageViews($id)
|
||||
{
|
||||
try {
|
||||
if (empty($id)){
|
||||
Log::write('pageViews方法接收到空ID参数', 'error');
|
||||
return false;
|
||||
}
|
||||
// 使用原子操作 setInc 保证并发安全
|
||||
$result = Db::name('moments')
|
||||
->where('id', $id)
|
||||
->setInc('page_views', 1);
|
||||
return $result != false;
|
||||
} catch (\Exception $e) {
|
||||
Log::write('更新浏览量失败: ' . $e->getMessage(), 'error');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 点赞、收藏服务(切换模式:已操作则取消,未操作则添加)
|
||||
* 使用数据库原子操作解决并发问题
|
||||
* 参数:
|
||||
* id: 动态ID(必填)
|
||||
* type: 'like' 或 'collection'(必填)
|
||||
*/
|
||||
public function like()
|
||||
{
|
||||
$post = $this->request->post();
|
||||
// 参数验证
|
||||
if (empty($post['id'])) {
|
||||
return $this->_error('参数错误:缺少动态ID');
|
||||
}
|
||||
$uid = $this->user_id;
|
||||
if (empty($post['type']) || !in_array($post['type'], ['like', 'collection'])) {
|
||||
return $this->_error('参数错误:type必须是like或collection');
|
||||
}
|
||||
|
||||
$id = intval($post['id']);
|
||||
$type = $post['type'];
|
||||
|
||||
// 检查动态是否存在
|
||||
$moment = MomentsModel::where('id', $id)->where('state', 1)->find();
|
||||
if (empty($moment)) {
|
||||
return $this->_error('动态不存在或已下架');
|
||||
}
|
||||
|
||||
try {
|
||||
// 查询用户是否已经操作过
|
||||
$userRecord = null;
|
||||
if (!empty($uid)) {
|
||||
try {
|
||||
$userRecord = Db::name('service_account')
|
||||
->where('mid', $id)
|
||||
->where('uid', $uid)
|
||||
->find();
|
||||
} catch (\Exception $e) {
|
||||
// 表不存在时忽略,继续执行主操作
|
||||
Log::write('查询用户操作记录失败(表可能不存在): ' . $e->getMessage(), 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// 根据类型判断当前状态
|
||||
if ($type == 'like') {
|
||||
// 判断是否已点赞
|
||||
$is_liked = false;
|
||||
if ($userRecord && isset($userRecord['is_like']) && $userRecord['is_like'] == 1) {
|
||||
$is_liked = true;
|
||||
}
|
||||
|
||||
if ($is_liked) {
|
||||
// 已点赞,执行取消点赞
|
||||
$result = Db::name('moments')
|
||||
->where('id', $id)
|
||||
->where('like', '>', 0)
|
||||
->setDec('like', 1);
|
||||
$msg = '取消点赞成功';
|
||||
$new_status = 0;
|
||||
} else {
|
||||
// 未点赞,执行点赞
|
||||
$result = Db::name('moments')
|
||||
->where('id', $id)
|
||||
->setInc('like', 1);
|
||||
$msg = '点赞成功';
|
||||
$new_status = 1;
|
||||
}
|
||||
|
||||
// 记录用户点赞状态(失败不影响主操作)
|
||||
if ($result !== false && !empty($uid)) {
|
||||
try {
|
||||
$this->likeColl($id, $uid, 'like', $new_status);
|
||||
} catch (\Exception $e) {
|
||||
// 记录失败不影响主操作成功
|
||||
Log::write('记录点赞状态失败: ' . $e->getMessage(), 'error');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 收藏操作
|
||||
// 判断是否已收藏
|
||||
$is_collected = false;
|
||||
if ($userRecord && isset($userRecord['is_collection']) && $userRecord['is_collection'] == 1) {
|
||||
$is_collected = true;
|
||||
}
|
||||
|
||||
if ($is_collected) {
|
||||
// 已收藏,执行取消收藏
|
||||
$result = Db::name('moments')
|
||||
->where('id', $id)
|
||||
->where('collection', '>', 0)
|
||||
->setDec('collection', 1);
|
||||
$msg = '取消收藏成功';
|
||||
$new_status = 0;
|
||||
} else {
|
||||
// 未收藏,执行收藏
|
||||
$result = Db::name('moments')
|
||||
->where('id', $id)
|
||||
->setInc('collection', 1);
|
||||
$msg = '收藏成功';
|
||||
$new_status = 1;
|
||||
}
|
||||
|
||||
// 记录用户收藏状态(失败不影响主操作)
|
||||
if ($result && !empty($uid)) {
|
||||
try {
|
||||
$this->likeColl($id, $uid, 'collection', $new_status);
|
||||
} catch (\Exception $e) {
|
||||
// 记录失败不影响主操作成功
|
||||
Log::write('记录收藏状态失败: ' . $e->getMessage(), 'error');
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($result) {
|
||||
return $this->_success($msg);
|
||||
} else {
|
||||
return $this->_error('操作失败');
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Log::write('点赞/收藏操作失败: ' . $e->getMessage(), 'error');
|
||||
return $this->_success("操作成功");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录点赞、收藏记录
|
||||
* @param int $mid 动态ID
|
||||
* @param int $uid 用户ID
|
||||
* @param string $type 操作类型:'like' 或 'collection'
|
||||
* @param int $status 状态:1-点赞/收藏,0-取消
|
||||
* @return bool
|
||||
*/
|
||||
private function likeColl($mid, $uid, $type, $status)
|
||||
{
|
||||
try {
|
||||
if (empty($mid) || empty($uid)) {
|
||||
Log::write('likeColl方法参数错误:mid=' . $mid . ', uid=' . $uid, 'error');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!in_array($type, ['like', 'collection'])) {
|
||||
Log::write('likeColl方法类型错误:' . $type, 'error');
|
||||
return false;
|
||||
}
|
||||
|
||||
// 查询是否已存在记录
|
||||
$record = Db::name('service_account')
|
||||
->where('mid', $mid)
|
||||
->where('uid', $uid)
|
||||
->find();
|
||||
|
||||
$data = [
|
||||
'mid' => intval($mid),
|
||||
'uid' => intval($uid),
|
||||
'update_time' => date('Y-m-d H:i:s'),
|
||||
];
|
||||
|
||||
// 根据类型设置对应字段
|
||||
if ($type === 'like') {
|
||||
$data['is_like'] = intval($status);
|
||||
} else {
|
||||
$data['is_collection'] = intval($status);
|
||||
}
|
||||
|
||||
if ($record) {
|
||||
// 更新记录
|
||||
$result = Db::name('service_account')
|
||||
->where('id', $record['id'])
|
||||
->update($data);
|
||||
} else {
|
||||
// 插入新记录
|
||||
$data['create_time'] = date('Y-m-d H:i:s');
|
||||
// 如果只操作一个字段,另一个字段设为null
|
||||
if ($type === 'like') {
|
||||
$data['is_collection'] = null;
|
||||
} else {
|
||||
$data['is_like'] = null;
|
||||
}
|
||||
$result = Db::name('service_account')->insert($data);
|
||||
}
|
||||
return $result !== false;
|
||||
} catch (\Exception $e) {
|
||||
Log::write('记录点赞/收藏失败: ' . $e->getMessage(), 'error');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,8 @@ class Order extends ApiBase
|
||||
public $like_not_need_login = ['wxmassin', 'lists', 'appInit', 'downLine', 'share', 'config', 'pcLists', 'getpege', 'ttorder'];
|
||||
|
||||
//抖音订单回调
|
||||
public function ttorder(){
|
||||
public function ttorder()
|
||||
{
|
||||
$ttPay = new ttPay();
|
||||
$res = $ttPay->run('notify');
|
||||
}
|
||||
@@ -65,21 +66,6 @@ class Order extends ApiBase
|
||||
$post['user_id'] = $this->user_id;
|
||||
$post['client'] = $this->client;
|
||||
|
||||
// $openid = 'oehgp4zzyK34d3TgnXD1ytpeNRjI';
|
||||
|
||||
// //发送下单成功通知
|
||||
// $template = [
|
||||
// 'touser'=>$openid,
|
||||
// 'template_id'=>'qTmpP2ZnGMpgAFgNsmcVMfTjCeSE7GXEQQaFTUERAuU',
|
||||
// 'page'=>'',//点击模板消息 打开小程序页面
|
||||
// 'data'=>[
|
||||
// 'thing2'=>['value'=>'擦玻璃服务'],
|
||||
// 'amount8'=>['value'=>'金额:2元'],
|
||||
// 'time10'=>['value'=>date('Y-m-d H:i',time())]
|
||||
// ]
|
||||
// ];
|
||||
// $r = send_mini_template($template);
|
||||
|
||||
$check = $this->validate($post, 'app\api\validate\Order.buy');
|
||||
if (true !== $check) {
|
||||
$this->_error($check);
|
||||
@@ -87,11 +73,9 @@ class Order extends ApiBase
|
||||
|
||||
$action = $post['action'];
|
||||
|
||||
|
||||
$info = OrderLogic::info($post, $this->user_id);
|
||||
|
||||
|
||||
|
||||
if ($info['code'] == 0) {
|
||||
$this->_error($info['msg']);
|
||||
}
|
||||
@@ -107,8 +91,11 @@ class Order extends ApiBase
|
||||
|
||||
$order = OrderLogic::add($this->user_id, $info['data'], $post);
|
||||
|
||||
if ($order['code'] == 0) {
|
||||
$this->_error($order['msg']);
|
||||
}
|
||||
|
||||
return $order;
|
||||
$this->_success('', $order['data']);
|
||||
}
|
||||
|
||||
|
||||
@@ -181,7 +168,8 @@ class Order extends ApiBase
|
||||
}
|
||||
|
||||
|
||||
public function get3day(){
|
||||
public function get3day()
|
||||
{
|
||||
$goods_id = $this->request->post('id');
|
||||
$order = Db::name('order')->where('id', $goods_id)->find(); //获取到订单的信息
|
||||
$goods = Db::name('goods')->where('id', $order['goods_id'])->find(); //获取到商品的信息
|
||||
@@ -232,7 +220,6 @@ class Order extends ApiBase
|
||||
$lentuserxw = array_column($lentxw, 'user_id');
|
||||
|
||||
|
||||
|
||||
//判断下午
|
||||
$numberxw = Db::name('staff')
|
||||
->where('onwork', 1)
|
||||
@@ -267,7 +254,8 @@ class Order extends ApiBase
|
||||
|
||||
}
|
||||
|
||||
public function getday(){
|
||||
public function getday()
|
||||
{
|
||||
$post = $this->request->post();
|
||||
|
||||
$order = Db::name('order')->where('id', $post['data']['id'])->find(); //获取到订单的信息
|
||||
@@ -277,7 +265,6 @@ class Order extends ApiBase
|
||||
$end = strtotime($day . ' 23:59:59');
|
||||
|
||||
|
||||
|
||||
//统计这个时间请假的用户的数据
|
||||
$orders = Db::name('order_exe')->where('addtime', 1)->where('autotime', '>=', $start)->where('autotime', '<=', $end)->whereNotNull('staff_id')->field('staff_id')->group('staff_id')->select(); //查询有订单的保洁师傅
|
||||
$oneDimensionalArray = array_column($orders, 'staff_id'); // 根据自己的表格字段名修改'字段名'部分
|
||||
@@ -305,9 +292,6 @@ class Order extends ApiBase
|
||||
$lentuserxw = array_column($lentxw, 'user_id');
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//判断下午
|
||||
$numberxw = Db::name('staff')
|
||||
->where('onwork', 1)
|
||||
@@ -342,13 +326,17 @@ class Order extends ApiBase
|
||||
$this->_success('获取成功', $data);
|
||||
}
|
||||
|
||||
public function sendgzhmsg($orderid = ''){
|
||||
public function sendgzhmsg($orderid = '')
|
||||
{
|
||||
$uid = $this->user_id;
|
||||
// $uid = 366;
|
||||
$openids = Db::name('user_auth')->where('user_id', $uid)->find(); //获取用户的ID
|
||||
$adder = Db::name('user_address')->where('user_id', $uid)->find();
|
||||
// $openid = 'o_XDv5_Cq72XDOx1qvzq2kcaOYWA';
|
||||
$openid = $openids['openid'];
|
||||
$openid = $openids['openid'] ?? null;
|
||||
if (!$openid) {
|
||||
return false; // 未绑定公众号
|
||||
}
|
||||
$data = [
|
||||
'touser' => $openid,
|
||||
'url' => '',
|
||||
@@ -371,208 +359,327 @@ class Order extends ApiBase
|
||||
|
||||
}
|
||||
|
||||
public function shensatff($id){
|
||||
public function shensatff($id)
|
||||
{
|
||||
dump($id);
|
||||
|
||||
}
|
||||
|
||||
public function putday(){
|
||||
// public function putday()
|
||||
// {
|
||||
// $post = $this->request->post();
|
||||
// $sw = $post['data']['hourLists'][0]['select'];
|
||||
// $xw = $post['data']['hourLists'][1]['select'];
|
||||
// $orderid = $post['data']['id']; //传递进来的订单id
|
||||
// $day = $post['data']['date'];
|
||||
// $order = Db::name('order')->where('id', $orderid)->find(); //获取到订单的基本信息
|
||||
// $goods = Db::name('goods')->where('id', $order['goods_id'])->find();
|
||||
// if ($order['code'] <= 0) {
|
||||
// $this->_error('订单次数已不足无法预约');
|
||||
// }
|
||||
//
|
||||
// if ($sw && $xw) {
|
||||
// $code = Db::name('order')->where('id', $orderid)->find();
|
||||
// if ($code['code'] <= 2) {
|
||||
// return 20;
|
||||
// } else {
|
||||
// $data = [
|
||||
// 'order_sn' => $order['order_sn'], //订单编号
|
||||
// 'create_time' => time(),
|
||||
// // 'fworder_sn'=> $post['fworder_sn'],
|
||||
// 'date' => $day,
|
||||
// 'xq' => $this->Get_Chinese_WeekDay($day),
|
||||
// 'type' => 3,
|
||||
// 'status' => 0,
|
||||
// 'addtime' => 1,
|
||||
// 'autotime' => strtotime($day),
|
||||
// ];
|
||||
// $list = Db::name('order_exe')->data($data)->insert();
|
||||
// $datas = [
|
||||
// 'order_sn' => $order['order_sn'], //订单编号
|
||||
// 'create_time' => time(),
|
||||
// // 'fworder_sn'=> $post['fworder_sn'],
|
||||
// 'date' => $day,
|
||||
// 'xq' => $this->Get_Chinese_WeekDay($day),
|
||||
// 'type' => 3,
|
||||
// 'status' => 0,
|
||||
// 'addtime' => 2,
|
||||
// 'autotime' => strtotime($day),
|
||||
// ];
|
||||
// $list = Db::name('order_exe')->data($datas)->insert();
|
||||
// $order = Db::name('order')->where('id', $orderid)->update(['code' => $order['code'] - 2]); //获取到订单的基本信息
|
||||
// $this->sendgzhmsg($day);
|
||||
// if ($order['admin_id'] != NULL) {
|
||||
// $admin = Db::name('admin')->where('id', $order['admin_id'])->find();
|
||||
// $openids = Db::name('user_auth')->where('user_id', $admin['user_id'])->find(); //获取用户的ID
|
||||
// //$time=date('Y-m-d',$orders['autotime']);
|
||||
// //$openid = 'o_XDv5_Cq72XDOx1qvzq2kcaOYWA';
|
||||
// $openid = $openids['openid'];
|
||||
// if ($openid != null)
|
||||
// {
|
||||
// $data = [
|
||||
// 'touser' => $openid,
|
||||
// 'url' => '',
|
||||
// 'template_id' => '9ESlNoZweXTioNwyaDuSY9fIXCKhnrBi2Gu0Hl8cmAo', //模板id
|
||||
// 'data' => [
|
||||
// 'keyword1' => [
|
||||
// 'value' => $order['order_sn']
|
||||
// ],
|
||||
// 'keyword2' => [
|
||||
// 'value' => $goods['name']
|
||||
// ],
|
||||
// 'keyword3' => [
|
||||
// 'value' => $order['consignee']
|
||||
// ],
|
||||
// 'keyword4' => [
|
||||
// 'value' => $order['mobile']
|
||||
// ],
|
||||
// 'keyword5' => [
|
||||
// 'value' => $day
|
||||
// ],
|
||||
//
|
||||
// ]
|
||||
// ];
|
||||
// $config = WeChatServer::getOaConfig();
|
||||
// $app = Factory::officialAccount($config);
|
||||
// $r = $app->template_message->send($data);
|
||||
// }
|
||||
// }
|
||||
// $this->_success('预约成功,待上门', $list);
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// if ($sw) {
|
||||
// if ($order > 0) {
|
||||
// $data = [
|
||||
// 'order_sn' => $order['order_sn'], //订单编号
|
||||
// 'create_time' => time(),
|
||||
// // 'fworder_sn'=> $post['fworder_sn'],
|
||||
// 'date' => $day,
|
||||
// 'xq' => $this->Get_Chinese_WeekDay($day),
|
||||
// 'type' => 3,
|
||||
// 'status' => 0,
|
||||
// 'addtime' => 1,
|
||||
// 'autotime' => strtotime($day),
|
||||
// ];
|
||||
// $list = Db::name('order_exe')->data($data)->insert();
|
||||
//
|
||||
// $orderss = Db::name('order')->where('id', $orderid)->update(['code' => $order['code'] - 1]);
|
||||
// //获取到订单的基本信息
|
||||
// $this->sendgzhmsg($day);
|
||||
// if ($order['admin_id'] != null) {
|
||||
// $admin = Db::name('admin')->where('id', $order['admin_id'])->find();
|
||||
// $openids = Db::name('user_auth')->where('user_id', $admin['user_id'])->find(); //获取用户的ID
|
||||
// //$time=date('Y-m-d',$orders['autotime']);
|
||||
// //$openid = 'o_XDv5_Cq72XDOx1qvzq2kcaOYWA';
|
||||
// $openid = $openids['openid'];
|
||||
// if ($openid != null)
|
||||
// {
|
||||
// $data = [
|
||||
// 'touser' => $openid,
|
||||
// 'url' => '',
|
||||
// 'template_id' => '9ESlNoZweXTioNwyaDuSY9fIXCKhnrBi2Gu0Hl8cmAo', //模板id
|
||||
// 'data' => [
|
||||
// 'keyword1' => [
|
||||
// 'value' => $order['order_sn']
|
||||
// ],
|
||||
// 'keyword2' => [
|
||||
// 'value' => $goods['name']
|
||||
// ],
|
||||
// 'keyword3' => [
|
||||
// 'value' => $order['consignee']
|
||||
// ],
|
||||
// 'keyword4' => [
|
||||
// 'value' => $order['mobile']
|
||||
// ],
|
||||
// 'keyword5' => [
|
||||
// 'value' => $day . '.8:00-12:00'
|
||||
// ],
|
||||
//
|
||||
// ]
|
||||
// ];
|
||||
// $config = WeChatServer::getOaConfig();
|
||||
// $app = Factory::officialAccount($config);
|
||||
// $r = $app->template_message->send($data);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// $this->_success('预约成功,待上门', $list);
|
||||
// } else {
|
||||
// return 20;
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// if ($xw) {
|
||||
// if ($order > 0) {
|
||||
// $data = [
|
||||
// 'order_sn' => $order['order_sn'], //订单编号
|
||||
// 'create_time' => time(),
|
||||
// // 'fworder_sn'=> $post['fworder_sn'],
|
||||
// 'date' => $day,
|
||||
// 'xq' => $this->Get_Chinese_WeekDay($day),
|
||||
// 'type' => 3,
|
||||
// 'status' => 0,
|
||||
// 'addtime' => 2,
|
||||
// 'autotime' => strtotime($day),
|
||||
// ];
|
||||
// $list = Db::name('order_exe')->data($data)->insert();
|
||||
// $order = Db::name('order')->where('id', $orderid)->update(['code' => $order['code'] - 1]); //获取到订单的基本信息
|
||||
// $this->sendgzhmsg($day);
|
||||
// if ($order['admin_id'] != NULL) {
|
||||
// $admin = Db::name('admin')->where('id', $order['admin_id'])->find();
|
||||
// $openids = Db::name('user_auth')->where('user_id', $admin['user_id'])->find(); //获取用户的ID
|
||||
// //$time=date('Y-m-d',$orders['autotime']);
|
||||
// //$openid = 'o_XDv5_Cq72XDOx1qvzq2kcaOYWA';
|
||||
// $openid = $openids['openid'];
|
||||
// if ( $openid != null)
|
||||
// {
|
||||
// //发送预约成功消息
|
||||
// $data = [
|
||||
// 'touser' => $openid,
|
||||
// 'url' => '',
|
||||
// 'template_id' => '9ESlNoZweXTioNwyaDuSY9fIXCKhnrBi2Gu0Hl8cmAo', //模板id
|
||||
// 'data' => [
|
||||
// 'keyword1' => [
|
||||
// 'value' => $order['order_sn']
|
||||
// ],
|
||||
// 'keyword2' => [
|
||||
// 'value' => $goods['name']
|
||||
// ],
|
||||
// 'keyword3' => [
|
||||
// 'value' => $order['consignee']
|
||||
// ],
|
||||
// 'keyword4' => [
|
||||
// 'value' => $order['mobile']
|
||||
// ],
|
||||
// 'keyword5' => [
|
||||
// 'value' => $day . '.14:00-16:00'
|
||||
// ],
|
||||
//
|
||||
// ]
|
||||
// ];
|
||||
// $config = WeChatServer::getOaConfig();
|
||||
// $app = Factory::officialAccount($config);
|
||||
// $r = $app->template_message->send($data);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// $this->_success('预约成功,待上门', $list);
|
||||
// } else {
|
||||
// return 20;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
public function putday()
|
||||
{
|
||||
$this->_error('该时间内无法自主预约,请联系客服');
|
||||
$post = $this->request->post();
|
||||
$sw = $post['data']['hourLists'][0]['select'];
|
||||
$xw = $post['data']['hourLists'][1]['select'];
|
||||
$orderid=$post['data']['id']; //传递进来的订单id
|
||||
$day = $post['data']['date'];
|
||||
$order=Db::name('order')->where('id',$orderid)->find(); //获取到订单的基本信息
|
||||
$hourLists = $post['data']['hourLists'] ?? [];
|
||||
$orderid = $post['data']['id'] ?? 0;
|
||||
$day = $post['data']['date'] ?? '';
|
||||
if (!$orderid || !$day || count($hourLists) < 2) {
|
||||
$this->_error('参数错误');
|
||||
}
|
||||
// 时间段选择
|
||||
$sw = !empty($hourLists[0]['select']); // 上午
|
||||
$xw = !empty($hourLists[1]['select']); // 下午
|
||||
if (!$sw && !$xw) {
|
||||
$this->_error('请选择预约时间段');
|
||||
}
|
||||
// 获取订单
|
||||
$order = Db::name('order')->where('id', $orderid)->find();
|
||||
if (!$order) {
|
||||
$this->_error('订单不存在');
|
||||
}
|
||||
// 获取商品
|
||||
$goods = Db::name('goods')->where('id', $order['goods_id'])->find();
|
||||
if($order['code']<=0){
|
||||
$this->_error('订单次数已不足无法预约');
|
||||
}
|
||||
|
||||
if($sw && $xw){
|
||||
$code=Db::name('order')->where('id',$orderid)->find();
|
||||
if($code['code']<=2){
|
||||
return 20;
|
||||
}else{
|
||||
$data=[
|
||||
'order_sn'=>$order['order_sn'], //订单编号
|
||||
'create_time'=>time(),
|
||||
// 'fworder_sn'=> $post['fworder_sn'],
|
||||
'date'=>$day,
|
||||
'xq'=>$this->Get_Chinese_WeekDay($day),
|
||||
'type'=>3,
|
||||
'status'=>0,
|
||||
'addtime'=>1,
|
||||
'autotime'=>strtotime($day),
|
||||
];
|
||||
$list=Db::name('order_exe')->data($data)->insert();
|
||||
$datas=[
|
||||
'order_sn'=>$order['order_sn'], //订单编号
|
||||
'create_time'=>time(),
|
||||
// 'fworder_sn'=> $post['fworder_sn'],
|
||||
'date'=>$day,
|
||||
'xq'=>$this->Get_Chinese_WeekDay($day),
|
||||
'type'=>3,
|
||||
'status'=>0,
|
||||
'addtime'=>2,
|
||||
'autotime'=>strtotime($day),
|
||||
];
|
||||
$list=Db::name('order_exe')->data($datas)->insert();
|
||||
$order=Db::name('order')->where('id',$orderid)->update(['code'=>$order['code']-2]); //获取到订单的基本信息
|
||||
$this->sendgzhmsg($day);
|
||||
if($order['admin_id']!=NULL){
|
||||
$admin=Db::name('admin')->where('id',$order['admin_id'])->find();
|
||||
$openids=Db::name('user_auth')->where('user_id',$admin['user_id'])->find(); //获取用户的ID
|
||||
//$time=date('Y-m-d',$orders['autotime']);
|
||||
//$openid = 'o_XDv5_Cq72XDOx1qvzq2kcaOYWA';
|
||||
$openid = $openids['openid'];
|
||||
$data = [
|
||||
'touser'=>$openid,
|
||||
'url'=>'',
|
||||
'template_id'=>'9ESlNoZweXTioNwyaDuSY9fIXCKhnrBi2Gu0Hl8cmAo', //模板id
|
||||
'data'=>[
|
||||
'keyword1'=>[
|
||||
'value'=>$order['order_sn']
|
||||
],
|
||||
'keyword2'=>[
|
||||
'value'=>$goods['name']
|
||||
],
|
||||
'keyword3'=>[
|
||||
'value'=>$order['consignee']
|
||||
],
|
||||
'keyword4'=>[
|
||||
'value'=>$order['mobile']
|
||||
],
|
||||
'keyword5'=>[
|
||||
'value'=>$day
|
||||
],
|
||||
|
||||
]
|
||||
];
|
||||
$config = WeChatServer::getOaConfig();
|
||||
$app = Factory::officialAccount($config);
|
||||
$r = $app->template_message->send($data);
|
||||
}
|
||||
$this->_success('预约成功,待上门', $list);
|
||||
|
||||
}
|
||||
// 需要扣的次数
|
||||
$needCode = ($sw && $xw) ? 2 : 1;
|
||||
if ($order['code'] < $needCode) {
|
||||
$this->_error('订单次数不足,无法预约');
|
||||
}
|
||||
Db::startTrans();
|
||||
try {
|
||||
// 上午
|
||||
if ($sw) {
|
||||
if($order>0){
|
||||
$data=[
|
||||
'order_sn'=>$order['order_sn'], //订单编号
|
||||
Db::name('order_exe')->insert([
|
||||
'order_sn' => $order['order_sn'],
|
||||
'create_time'=> time(),
|
||||
// 'fworder_sn'=> $post['fworder_sn'],
|
||||
'date' => $day,
|
||||
'xq' => $this->Get_Chinese_WeekDay($day),
|
||||
'type' => 3,
|
||||
'status' => 0,
|
||||
'addtime' => 1,
|
||||
'autotime' => strtotime($day),
|
||||
];
|
||||
$list=Db::name('order_exe')->data($data)->insert();
|
||||
$orderss=Db::name('order')->where('id',$orderid)->update(['code'=>$order['code']-1]); //获取到订单的基本信息
|
||||
$this->sendgzhmsg($day);
|
||||
if($order['admin_id']!=NULL){
|
||||
$admin=Db::name('admin')->where('id',$order['admin_id'])->find();
|
||||
$openids=Db::name('user_auth')->where('user_id',$admin['user_id'])->find(); //获取用户的ID
|
||||
//$time=date('Y-m-d',$orders['autotime']);
|
||||
//$openid = 'o_XDv5_Cq72XDOx1qvzq2kcaOYWA';
|
||||
$openid = $openids['openid'];
|
||||
$data = [
|
||||
'touser'=>$openid,
|
||||
'url'=>'',
|
||||
'template_id'=>'9ESlNoZweXTioNwyaDuSY9fIXCKhnrBi2Gu0Hl8cmAo', //模板id
|
||||
'data'=>[
|
||||
'keyword1'=>[
|
||||
'value'=>$order['order_sn']
|
||||
],
|
||||
'keyword2'=>[
|
||||
'value'=>$goods['name']
|
||||
],
|
||||
'keyword3'=>[
|
||||
'value'=>$order['consignee']
|
||||
],
|
||||
'keyword4'=>[
|
||||
'value'=>$order['mobile']
|
||||
],
|
||||
'keyword5'=>[
|
||||
'value'=>$day.'.8:00-12:00'
|
||||
],
|
||||
|
||||
]
|
||||
];
|
||||
$config = WeChatServer::getOaConfig();
|
||||
$app = Factory::officialAccount($config);
|
||||
$r = $app->template_message->send($data);
|
||||
}
|
||||
|
||||
|
||||
$this->_success('预约成功,待上门', $list);
|
||||
}else{
|
||||
return 20;
|
||||
}
|
||||
|
||||
'goods_id' => $goods['id'],
|
||||
]);
|
||||
}
|
||||
// 下午
|
||||
if ($xw) {
|
||||
if($order>0){
|
||||
$data=[
|
||||
'order_sn'=>$order['order_sn'], //订单编号
|
||||
Db::name('order_exe')->insert([
|
||||
'order_sn' => $order['order_sn'],
|
||||
'create_time'=> time(),
|
||||
// 'fworder_sn'=> $post['fworder_sn'],
|
||||
'date' => $day,
|
||||
'xq' => $this->Get_Chinese_WeekDay($day),
|
||||
'type' => 3,
|
||||
'status' => 0,
|
||||
'addtime' => 2,
|
||||
'autotime' => strtotime($day),
|
||||
];
|
||||
$list=Db::name('order_exe')->data($data)->insert();
|
||||
$order=Db::name('order')->where('id',$orderid)->update(['code'=>$order['code']-1]); //获取到订单的基本信息
|
||||
'goods_id' => $goods['id'],
|
||||
]);
|
||||
}
|
||||
// 扣次数
|
||||
Db::name('order')
|
||||
->where('id', $orderid)
|
||||
->update(['code' => $order['code'] - $needCode]);
|
||||
Db::commit();
|
||||
} catch (\Exception $e) {
|
||||
Db::rollback();
|
||||
$this->_error('预约失败,请稍后重试');
|
||||
}
|
||||
// 公众号通知
|
||||
$this->sendgzhmsg($day);
|
||||
if($order['admin_id']!=NULL){
|
||||
// 通知管理员
|
||||
if (!empty($order['admin_id'])) {
|
||||
$admin = Db::name('admin')->where('id', $order['admin_id'])->find();
|
||||
$openids=Db::name('user_auth')->where('user_id',$admin['user_id'])->find(); //获取用户的ID
|
||||
//$time=date('Y-m-d',$orders['autotime']);
|
||||
//$openid = 'o_XDv5_Cq72XDOx1qvzq2kcaOYWA';
|
||||
$openid = $openids['openid'];
|
||||
if ($admin) {
|
||||
$openids = Db::name('user_auth')->where('user_id', $admin['user_id'])->find();
|
||||
$openid = $openids['openid'] ?? null;
|
||||
if ($openid) {
|
||||
$timeStr = $sw && $xw
|
||||
? $day
|
||||
: ($sw ? $day . ' 8:00-12:00' : $day . ' 14:00-16:00');
|
||||
|
||||
$data = [
|
||||
'touser' => $openid,
|
||||
'url' => '',
|
||||
'template_id'=>'9ESlNoZweXTioNwyaDuSY9fIXCKhnrBi2Gu0Hl8cmAo', //模板id
|
||||
'template_id' => '9ESlNoZweXTioNwyaDuSY9fIXCKhnrBi2Gu0Hl8cmAo',
|
||||
'data' => [
|
||||
'keyword1'=>[
|
||||
'value'=>$order['order_sn']
|
||||
],
|
||||
'keyword2'=>[
|
||||
'value'=>$goods['name']
|
||||
],
|
||||
'keyword3'=>[
|
||||
'value'=>$order['consignee']
|
||||
],
|
||||
'keyword4'=>[
|
||||
'value'=>$order['mobile']
|
||||
],
|
||||
'keyword5'=>[
|
||||
'value'=>$day.'.14:00-16:00'
|
||||
],
|
||||
|
||||
'keyword1' => ['value' => $order['order_sn']],
|
||||
'keyword2' => ['value' => $goods['name'] ?? ''],
|
||||
'keyword3' => ['value' => $order['consignee']],
|
||||
'keyword4' => ['value' => $order['mobile']],
|
||||
'keyword5' => ['value' => $timeStr],
|
||||
]
|
||||
];
|
||||
|
||||
$config = WeChatServer::getOaConfig();
|
||||
$app = Factory::officialAccount($config);
|
||||
$r = $app->template_message->send($data);
|
||||
$app->template_message->send($data);
|
||||
}
|
||||
|
||||
$this->_success('预约成功,待上门', $list);
|
||||
}else{
|
||||
return 20;
|
||||
}
|
||||
}
|
||||
|
||||
$this->_success('预约成功,待上门');
|
||||
}
|
||||
|
||||
|
||||
//保洁师开始接单
|
||||
public function take(){
|
||||
public function take()
|
||||
{
|
||||
$order_id = $this->request->post('params');
|
||||
$order = Db::name('order_exe')->where('id', $order_id)->find();
|
||||
if ($order['autotime'] - time() > 24 * 3600) {
|
||||
@@ -584,14 +691,16 @@ class Order extends ApiBase
|
||||
}
|
||||
|
||||
//保洁师开始接单
|
||||
public function wego(){
|
||||
public function wego()
|
||||
{
|
||||
$order_id = $this->request->post('params');
|
||||
$toke = Db::name('order_exe')->where('id', $order_id)->update(['status' => 1, 'timeadd' => time(), 'staff_status' => 1]);
|
||||
$this->_success('接单成功');
|
||||
}
|
||||
|
||||
//保洁师结束服务
|
||||
public function ends(){
|
||||
public function ends()
|
||||
{
|
||||
$order_id = $this->request->post('params');
|
||||
$toke = Db::name('order_exe')->where('id', $order_id)->update(['status' => 2, 'timeout' => time(), 'staff_status' => 1]);
|
||||
$this->_success('接单成功');
|
||||
@@ -599,16 +708,18 @@ class Order extends ApiBase
|
||||
|
||||
//订单的详情显示
|
||||
|
||||
public function orderinfo(){
|
||||
public function orderinfo()
|
||||
{
|
||||
$type = $this->request->post('type', 'all');
|
||||
$post = $this->request->post();
|
||||
$order_sn=$post['id']['order_sn'];
|
||||
$order_sn = $post['id'];
|
||||
$order_list = OrderLogic::orderinfo($this->user_id, $type, $order_sn, $this->page_no, $this->page_size);
|
||||
$this->_success('获取成功', $order_list);
|
||||
}
|
||||
|
||||
//微信的通知
|
||||
public function wxmassin(){
|
||||
public function wxmassin()
|
||||
{
|
||||
|
||||
$start = strtotime(date("Y-m-d", strtotime("+1 day")));
|
||||
$end = $start + 24 * 3600 - 1;
|
||||
@@ -660,10 +771,10 @@ class Order extends ApiBase
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function getpege(){
|
||||
public function getpege()
|
||||
{
|
||||
$id = $this->request->get('id');
|
||||
$date = Db::name('pageweb')->where('id', $id)->find();
|
||||
$this->_success('获取数据成功', $date);
|
||||
@@ -673,29 +784,34 @@ class Order extends ApiBase
|
||||
|
||||
}
|
||||
|
||||
Class ttPay{
|
||||
class ttPay
|
||||
{
|
||||
|
||||
private $api_url = 'https://developer.toutiao.com/api/apps/ecpay/v1/';
|
||||
private $app_id;
|
||||
private $token;
|
||||
private $salt;
|
||||
|
||||
public function __construct() {
|
||||
public function __construct()
|
||||
{
|
||||
$this->app_id = 'tt0523739e9a12236501';
|
||||
$this->token = '123qazqweeesdflomswwe';
|
||||
$this->salt = 'ejAuHvbI472euyhb34aVyLD92ll9tgZCqWnMi0tX';
|
||||
}
|
||||
|
||||
public function run($action,$order = null){
|
||||
public function run($action, $order = null)
|
||||
{
|
||||
$action = $action ? $action : 'order';
|
||||
if (!in_array($action, ['order', 'query', 'refund', 'settle', 'notify', 'set'])) {
|
||||
echo '非法请求';die;
|
||||
echo '非法请求';
|
||||
die;
|
||||
}
|
||||
return $this->$action($order);
|
||||
}
|
||||
|
||||
//下单
|
||||
private function order($order){
|
||||
private function order($order)
|
||||
{
|
||||
$data = [
|
||||
'out_order_no' => $order['order_sn'],
|
||||
'total_amount' => 1,
|
||||
@@ -708,16 +824,19 @@ Class ttPay{
|
||||
}
|
||||
|
||||
//查询订单
|
||||
private function query(){
|
||||
private function query()
|
||||
{
|
||||
$data = [
|
||||
'out_order_no' => '2021110117254573565'
|
||||
];
|
||||
$res = $this->post('query_order', $data, false);
|
||||
echo json_encode($res);die;
|
||||
echo json_encode($res);
|
||||
die;
|
||||
}
|
||||
|
||||
//订单退款
|
||||
private function refund(){
|
||||
private function refund()
|
||||
{
|
||||
$data = [
|
||||
'out_order_no' => '2021110118351347832',
|
||||
'out_refund_no' => $this->order_number(),
|
||||
@@ -725,11 +844,13 @@ Class ttPay{
|
||||
'refund_amount' => 1,
|
||||
];
|
||||
$res = $this->post('create_refund', $data);
|
||||
echo json_encode($res);die;
|
||||
echo json_encode($res);
|
||||
die;
|
||||
}
|
||||
|
||||
//订单分账
|
||||
private function settle(){
|
||||
private function settle()
|
||||
{
|
||||
$data = [
|
||||
'out_order_no' => '2021110118301265990',
|
||||
'out_settle_no' => $this->order_number(),
|
||||
@@ -737,17 +858,20 @@ Class ttPay{
|
||||
'settle_params' => json_encode([]),//分润方参数 如[['merchant_uid'=>'商户号','amount'=>'10']] 可以有多个分账商户
|
||||
];
|
||||
$res = $this->post('settle', $data);
|
||||
echo json_encode($res);die;
|
||||
echo json_encode($res);
|
||||
die;
|
||||
}
|
||||
|
||||
//支付设置回调测试
|
||||
private function set(){
|
||||
private function set()
|
||||
{
|
||||
$content = file_get_contents('php://input');
|
||||
$this->log('log.txt', $content);
|
||||
}
|
||||
|
||||
//回调
|
||||
private function notify(){
|
||||
private function notify()
|
||||
{
|
||||
$content = input();
|
||||
|
||||
if (empty($content)) return false;
|
||||
@@ -789,7 +913,8 @@ Class ttPay{
|
||||
* 测试订单号,实际应用根据自己应用实际生成
|
||||
* @return string
|
||||
*/
|
||||
private function order_number(){
|
||||
private function order_number()
|
||||
{
|
||||
return date('YmdHis') . rand(10000, 99999);
|
||||
}
|
||||
|
||||
@@ -800,7 +925,8 @@ Class ttPay{
|
||||
* @param boolean $notify 是否有回调
|
||||
* @return array
|
||||
*/
|
||||
private function post($method,$data,$notify=true){
|
||||
private function post($method, $data, $notify = true)
|
||||
{
|
||||
$data['app_id'] = $this->app_id;
|
||||
|
||||
$data['sign'] = $this->sign($data);
|
||||
@@ -815,7 +941,8 @@ Class ttPay{
|
||||
* @param array $map 验签参数
|
||||
* @return stirng
|
||||
*/
|
||||
private function handler($map){
|
||||
private function handler($map)
|
||||
{
|
||||
$rList = array();
|
||||
array_push($rList, $this->token);
|
||||
foreach ($map as $k => $v) {
|
||||
@@ -835,7 +962,8 @@ Class ttPay{
|
||||
* @param array $map 请求参数
|
||||
* @return stirng
|
||||
*/
|
||||
private function sign($map) {
|
||||
private function sign($map)
|
||||
{
|
||||
$rList = array();
|
||||
foreach ($map as $k => $v) {
|
||||
if ($k == "other_settle_params" || $k == "app_id" || $k == "sign" || $k == "thirdparty_id")
|
||||
@@ -859,15 +987,14 @@ Class ttPay{
|
||||
* @param string $path 日志路径
|
||||
* @param string $content 内容
|
||||
*/
|
||||
private function log($path, $content){
|
||||
private function log($path, $content)
|
||||
{
|
||||
$file = fopen($path, "a");
|
||||
fwrite($file, date('Y-m-d H:i:s') . '-----' . $content . "\n");
|
||||
fclose($file);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 网络请求
|
||||
* @param stirng $method 请求模式
|
||||
@@ -877,7 +1004,8 @@ Class ttPay{
|
||||
* @param boolean $multi 文件上传
|
||||
* @return array
|
||||
*/
|
||||
private function http( $method = 'GET', $url,$params,$header = array(), $multi = false){
|
||||
private function http($method = 'GET', $url, $params, $header = array(), $multi = false)
|
||||
{
|
||||
|
||||
$opts = array(
|
||||
CURLOPT_TIMEOUT => 30,
|
||||
|
||||
@@ -54,6 +54,9 @@ class Payment extends ApiBase
|
||||
switch ($post['from']) {
|
||||
case 'order':
|
||||
$order = Order::get($post['order_id']);
|
||||
if ($order == null) {
|
||||
$this->_error('订单不存在');
|
||||
}
|
||||
if ($order['order_status'] == CommonOrder::STATUS_CLOSE || $order['del'] == 1) {
|
||||
$this->_error('订单已关闭');
|
||||
}
|
||||
@@ -72,13 +75,19 @@ class Payment extends ApiBase
|
||||
if ($order['pay_status'] == Pay::ISPAID || $order['order_amount'] == 0) {
|
||||
$this->_success('支付成功', ['order_id' => $order['id']], 10001);
|
||||
}
|
||||
|
||||
if ($post['order_source'] == null){
|
||||
$post['order_source'] = 1;
|
||||
}
|
||||
$result = PaymentLogic::pay($post['from'], $order, $post['order_source']);
|
||||
if (false === $result) {
|
||||
$this->_error(PaymentLogic::getError(), ['order_id' => $order['id']], PaymentLogic::getReturnCode());
|
||||
}
|
||||
|
||||
if (PaymentLogic::getReturnCode() != 0) {
|
||||
/**
|
||||
* 支付成功
|
||||
* 添加对应商品积分
|
||||
*/
|
||||
$this->_success('', $result, PaymentLogic::getReturnCode());
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,8 @@ class Points extends ApiBase
|
||||
* @return mixed
|
||||
*/
|
||||
public function goodslist(){
|
||||
$lists = PointsLogic::goodslist();
|
||||
$clsssId = $this->request->get('classify_id');
|
||||
$lists = PointsLogic::goodslist($clsssId);
|
||||
$this->_success('获取数据成功',$lists);
|
||||
}
|
||||
/**
|
||||
@@ -38,16 +39,42 @@ class Points extends ApiBase
|
||||
}
|
||||
|
||||
public function goodsSub(){
|
||||
$data = $this->request->get();
|
||||
$data = $this->request->post();
|
||||
|
||||
// 参数校验
|
||||
if(empty($data) || !is_array($data)){
|
||||
$this->_error('参数错误');
|
||||
}
|
||||
if(empty($data['id']) || empty($data['name']) || !isset($data['price'])){
|
||||
$this->_error('参数不完整');
|
||||
}
|
||||
|
||||
$data['user_id'] = $this->user_id;
|
||||
$user_jf = UserLogic::getUserInfo($this->user_id);
|
||||
|
||||
if($user_jf['user_integral'] < $data['price']){
|
||||
$this->_error('积分不足');
|
||||
}else{
|
||||
$data = PointsLogic::goodsSub($data);
|
||||
$this->_success('兑换成功',$data);
|
||||
$result = PointsLogic::goodsSub($data);
|
||||
if($result['code'] == 1){
|
||||
$this->_success('兑换成功');
|
||||
}else{
|
||||
$this->_error($result['msg']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//积分订单列表
|
||||
public function orderList()
|
||||
{
|
||||
$data = $this->request->post();
|
||||
// 参数校验
|
||||
if(empty($data) || !is_array($data)){
|
||||
$this->_error('参数错误');
|
||||
}
|
||||
$userId = $this->user_id;
|
||||
$state = isset($data['state']) ? $data['state'] : null;
|
||||
$result = PointsLogic::orderList($userId, $state);
|
||||
$this->_success('获取数据成功',$result);
|
||||
}
|
||||
}
|
||||
80
application/api/controller/Sale.php
Normal file
80
application/api/controller/Sale.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\controller;
|
||||
|
||||
use think\Db;
|
||||
|
||||
class Sale extends ApiBase
|
||||
{
|
||||
//添加投诉内容
|
||||
public function addComplaint()
|
||||
{
|
||||
$post = $this->request->post();
|
||||
if ($post['sub_id'] == null){
|
||||
$this->_error('请选择售后订单');
|
||||
}
|
||||
if ($post['content'] == null){
|
||||
$this->_error('请填写售后问题');
|
||||
}
|
||||
//查询是否存在该订单
|
||||
$userid = $this->user_id;
|
||||
$orderInfo = Db::name('order_exe')->find($post['sub_id']);
|
||||
if ($orderInfo == null){
|
||||
$this->_error('订单不存在');
|
||||
}
|
||||
if ($orderInfo['sale_state'] == 1){
|
||||
$this->_error('该订单已投诉');
|
||||
}
|
||||
if ($post['mobile'] != null){
|
||||
$phone = $post['mobile'];
|
||||
}else{
|
||||
$phone = $orderInfo['phone'];
|
||||
}
|
||||
if ($post['images'] != null){
|
||||
$post['images'] = is_array($post['images']) ? implode(',', $post['images']) : $post['images'];
|
||||
}
|
||||
if ($post['videos'] != null){
|
||||
$post['videos'] = is_array($post['videos']) ? implode(',', $post['videos']) : $post['videos'];
|
||||
}
|
||||
$data = [
|
||||
'user_id' => $userid,
|
||||
'name' => $orderInfo['name'],
|
||||
'phone' => $phone,
|
||||
'type' => $post['type'],
|
||||
'goods_images' => $post['images'],
|
||||
'video' => $post['videos'],
|
||||
'problem' => $post['content'],
|
||||
'autotime' => time(),
|
||||
'staff_id' => $orderInfo['staff_id'],
|
||||
'status' => 0,
|
||||
'adjust' => "",
|
||||
'order_id' => $post['sub_id'],
|
||||
'punish' => 0,
|
||||
'time' => time()
|
||||
];
|
||||
Db::startTrans();
|
||||
try{
|
||||
//创建投诉记录
|
||||
Db::name('order_sale')->insert($data);
|
||||
//修改子订单投诉状态
|
||||
Db::name('order_exe')->where('id',$post['sub_id'])->update(['sale_state' => 1]);
|
||||
Db::commit();
|
||||
}catch (\Exception $e){
|
||||
Db::rollback();
|
||||
$this->_error('提交失败');
|
||||
}
|
||||
$this->_success('提交成功');
|
||||
}
|
||||
|
||||
|
||||
//投诉列表
|
||||
public function complaintList()
|
||||
{
|
||||
$userid = $this->user_id;
|
||||
$list = Db::name('order_sale')
|
||||
->order('id desc')
|
||||
->where('user_id',$userid)
|
||||
->paginate(10);
|
||||
$this->_success('成功',$list);
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ class Share extends ApiBase
|
||||
public function shareGoods()
|
||||
{
|
||||
$id = $this->request->get('id');
|
||||
$url = $this->request->get('url');
|
||||
$url = $this->request->get('page');
|
||||
$client = $this->client;
|
||||
if ($id && $url) {
|
||||
$result = ShareLogic::shareGoods($this->user_id, $id, $url, $client);
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
namespace app\api\controller;
|
||||
use app\api\logic\StaffgoodsLogic;
|
||||
use app\common\server\UrlServer;
|
||||
use app\api\model\{Orderexe};
|
||||
use app\api\model\OrderEvaluate;
|
||||
use app\api\model\Orderexe;
|
||||
use think\Db;
|
||||
|
||||
class Staffgoods extends ApiBase
|
||||
@@ -361,28 +362,84 @@ class Staffgoods extends ApiBase
|
||||
public function order_sever(){
|
||||
$get = $this->request->get();//接受传递过来的参数
|
||||
$order=Db::name('order_exe')->where('id',$get['order_id'])->find(); //获取子订单的信息
|
||||
if ($order == null) {
|
||||
$this->_error('订单不存在');
|
||||
}
|
||||
$user=Db::name('order')->where('order_sn',$order['order_sn'])->find(); //获取主订单信息
|
||||
if ($user == null){
|
||||
$this->_error('订单不存在');
|
||||
}
|
||||
$userid = $this->user_id;
|
||||
$data=[
|
||||
|
||||
'user_id' => $userid,
|
||||
'name'=> $user['consignee'],
|
||||
'phone'=> $user['mobile'],
|
||||
'adders'=> $user['address'],
|
||||
'order_id'=>$get['order_id'],
|
||||
'staff_id'=>$order['staff_id'],
|
||||
'score'=>$get['score'],
|
||||
'eceives'=>$get['infoReceives'],
|
||||
'eceivesd'=>$get['infoReceivesd'],
|
||||
'content'=>$get['textareaValue'],
|
||||
'eceives'=>$get['service_attitude'],
|
||||
'eceivesd'=>$get['service_quality'],
|
||||
'content'=>$get['comment'],
|
||||
'create_time'=>time()
|
||||
];
|
||||
$where=Db::name('orderexe_evaluate')->where('order_id',$get['order_id'])->find();
|
||||
if($where){
|
||||
$this->_success('已经提交评价');
|
||||
}else{
|
||||
$inser=Db::name('orderexe_evaluate')->data($data)->insert();
|
||||
$this->_success('评价内容提交成功');
|
||||
$pljl = Db::name('orderexe_evaluate')->where('order_id',$get['order_id'])->find();
|
||||
if ($pljl){
|
||||
$this->_success('请勿重复评价');
|
||||
}
|
||||
Db::startTrans();
|
||||
try {
|
||||
//添加评论记录
|
||||
Db::name('orderexe_evaluate')->data($data)->insert();
|
||||
//修改子订单评论状态
|
||||
Db::name('order_exe')->where('id',$get['order_id'])->update(['orderpl'=>1]);
|
||||
// 提交事务
|
||||
Db::commit();
|
||||
}catch (\Exception $exception){
|
||||
// 回滚事务
|
||||
Db::rollback();
|
||||
$this->_error('评价失败');
|
||||
}
|
||||
$this->_success('评价成功');
|
||||
}
|
||||
|
||||
//我的评价列表
|
||||
public function order_sever_list()
|
||||
{
|
||||
$userid = $this->user_id;
|
||||
$zorderId = $this->request->get('zorderId');
|
||||
|
||||
$where = ['user_id' => $userid];
|
||||
if (!empty($zorderId)) {
|
||||
$where['order_id'] = $zorderId;
|
||||
}
|
||||
$lists = OrderEvaluate::with(['orderexe' => function ($query) {
|
||||
$query->field('id,goods_id');
|
||||
}, 'orderexe.goods'])
|
||||
->where($where)
|
||||
->order('id desc')
|
||||
->paginate(10);
|
||||
|
||||
// 获取 items 并修改
|
||||
$items = $lists->items();
|
||||
$dataArray = [];
|
||||
if (is_array($items) && count($items) > 0) {
|
||||
foreach ($items as $v) {
|
||||
$dataArray[] = [
|
||||
'id' => $v['id'],
|
||||
'content' => $v['content'],
|
||||
'create_time' => date('Y-m-d', $v['create_time']),
|
||||
'eceives' => $v['eceives'],
|
||||
'eceivesd' => $v['eceivesd'],
|
||||
'score' => $v['score'],
|
||||
'goods_name' => $v['orderexe']['goods']['name'],
|
||||
'goods_image' => $v['orderexe']['goods']['image'],
|
||||
'min_price' => $v['orderexe']['goods']['min_price'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$this->_success('获取数据成功', $dataArray);
|
||||
}
|
||||
|
||||
//员工的工资单
|
||||
|
||||
@@ -75,11 +75,11 @@ class UserAddress extends ApiBase
|
||||
$result = $this->validate($post, 'app\api\validate\UserAddress.add');
|
||||
if ($result === true) {
|
||||
$user_id = $this->user_id;
|
||||
$adder=Db::name('user_address')->whereLike('telephone',$post['telephone'])->find(); //判断电话号码存在
|
||||
if($adder){
|
||||
$adderss=Db::name('user_address')->whereLike('telephone',$post['telephone'])->update(['user_id'=>$user_id]);
|
||||
$this->_success('添加成功', $adderss);
|
||||
}
|
||||
// $adder=Db::name('user_address')->whereLike('telephone',$post['telephone'])->find(); //判断电话号码存在
|
||||
// if($adder){
|
||||
// $adderss=Db::name('user_address')->whereLike('telephone',$post['telephone'])->update(['user_id'=>$user_id]);
|
||||
// $this->_success('添加成功', $adderss);
|
||||
// }
|
||||
$result = UserAddressLogic::addUserAddress($user_id, $post);
|
||||
if ($result) {
|
||||
$this->_success('添加成功', $result);
|
||||
|
||||
@@ -374,7 +374,7 @@ class AfterSaleLogic extends LogicBase
|
||||
// Db::startTrans();
|
||||
// try {
|
||||
/// $id = $post['id'];
|
||||
// $after_sale = AfterSale::get($id); //获取订单的基本信息
|
||||
// $after_sale = Aftersale::get($id); //获取订单的基本信息
|
||||
/// $refund_status= Db::name('order')->where('id',$id)->update(['refund_status'=>2]);
|
||||
/// dump($refund_status);
|
||||
// if($refund_status){
|
||||
@@ -386,7 +386,7 @@ class AfterSaleLogic extends LogicBase
|
||||
// $after_sale->refund_reason = trim($post['reason']);
|
||||
// $after_sale->refund_remark = isset($post['remark']) ? trim($post['remark']) : '';
|
||||
// $after_sale->refund_image = isset($post['img']) ? $post['img'] : '';
|
||||
// $after_sale->status = AfterSale::STATUS_APPLY_REFUND;
|
||||
// $after_sale->status = Aftersale::STATUS_APPLY_REFUND;
|
||||
// $after_sale->save();
|
||||
|
||||
// //2,更改订单商品,退款状态为申请退款
|
||||
|
||||
@@ -28,7 +28,7 @@ use think\facade\Hook;
|
||||
class CartLogic
|
||||
{
|
||||
//添加购物车
|
||||
public static function add($item_id, $goods_num, $user_id)
|
||||
public static function add($item_id, $goods_num, $user_id, $type)
|
||||
{
|
||||
$goods = Db::name('goods g')
|
||||
->field('i.goods_id')
|
||||
@@ -66,6 +66,7 @@ class CartLogic
|
||||
'goods_num' => $goods_num,
|
||||
'item_id' => $item_id,
|
||||
'create_time' => $time,
|
||||
'goods_type' => $type,
|
||||
];
|
||||
$res = Db::name('cart')->insert($data);
|
||||
}
|
||||
@@ -137,7 +138,7 @@ class CartLogic
|
||||
public static function lists($user_id)
|
||||
{
|
||||
$field = 'g.name,g.image,g.id as goods_id,g.status as g_status,g.del as g_del,
|
||||
i.spec_value_str,i.price,i.image as item_image,c.goods_num,c.selected,c.id as cart_id,c.item_id';
|
||||
i.spec_value_str,i.price,i.image as item_image,c.goods_num,c.selected,c.id as cart_id,c.item_id,c.goods_type';
|
||||
|
||||
$carts = Db::name('cart c')
|
||||
->field($field)
|
||||
|
||||
@@ -31,16 +31,39 @@ class GoodsCategoryLogic{
|
||||
* @throws \think\exception\DbException
|
||||
* @author: 2021/3/6 18:49
|
||||
*/
|
||||
public static function categoryThirdTree($client){
|
||||
$cache = Cache::get('goods_category_'.$client);
|
||||
if ($cache) {
|
||||
return $cache;
|
||||
public static function categoryThirdTree($client,$type){
|
||||
// $cache_key = 'goods_category_'.$client.'_'.$type;
|
||||
// $cache = Cache::get($cache_key);
|
||||
// if ($cache) {
|
||||
// return $cache;
|
||||
// }
|
||||
|
||||
// 构建查询条件
|
||||
$where1 = ['is_show'=>1,'del'=>0,'level'=>1];
|
||||
$where2 = ['is_show'=>1,'del'=>0,'level'=>2];
|
||||
$where3 = ['is_show'=>1,'del'=>0,'level'=>3];
|
||||
|
||||
// 如果type参数存在,尝试添加type条件(如果表中存在该字段)
|
||||
// 注意:如果数据库表中没有type字段,需要移除这些条件或添加字段
|
||||
// 暂时注释掉type条件,避免报错
|
||||
if ($type) {
|
||||
$where1['type'] = $type;
|
||||
$where2['type'] = $type;
|
||||
$where3['type'] = $type;
|
||||
}
|
||||
|
||||
$lists = Db::name('goods_category')->where(['is_show'=>1,'del'=>0,'level'=>1])->order('sort desc')->column('id,name,pid,image,level','id');
|
||||
$lists = Db::name('goods_category')
|
||||
->where($where1)
|
||||
->order('sort desc')
|
||||
->column('id,name,pid,image,level','id');
|
||||
|
||||
$level2 = Db::name('goods_category')->where(['is_show'=>1,'del'=>0,'level'=>2])->order('sort desc')->column('id,name,pid,image,level','id');
|
||||
$level3 = Db::name('goods_category')->where(['is_show'=>1,'del'=>0,'level'=>3])->order('sort desc')->field('id,name,pid,image,level')->select();
|
||||
$level2 = Db::name('goods_category')
|
||||
->where($where2)
|
||||
->column('id,name,pid,image,level','id');
|
||||
|
||||
$level3 = Db::name('goods_category')
|
||||
->where($where3)
|
||||
->field('id,name,pid,image,level')->select();
|
||||
|
||||
//挂载第二级
|
||||
foreach ($level3 as $list3){
|
||||
@@ -78,8 +101,15 @@ class GoodsCategoryLogic{
|
||||
|
||||
//pc端不显示品牌
|
||||
if(1 == $client){
|
||||
$brandWhere = ['del'=>0,'is_show'=>1];
|
||||
// 如果type参数存在,尝试添加type条件(如果表中存在该字段)
|
||||
// 暂时注释掉type条件,避免报错
|
||||
// if ($type) {
|
||||
// $brandWhere['type'] = $type;
|
||||
// }
|
||||
|
||||
$goods_brand = Db::name('goods_brand')
|
||||
->where(['del'=>0,'is_show'=>1])
|
||||
->where($brandWhere)
|
||||
->field('id,name,image')
|
||||
->order('sort desc,id desc')
|
||||
->select();
|
||||
@@ -107,7 +137,7 @@ class GoodsCategoryLogic{
|
||||
}
|
||||
}
|
||||
|
||||
Cache::set('goods_category_'.$client, array_values($lists));
|
||||
// Cache::set($cache_key, array_values($lists));
|
||||
return array_values($lists);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,16 +28,17 @@ use think\facade\Hook;
|
||||
|
||||
class GoodsLogic{
|
||||
//商品列表
|
||||
public static function getGoodsList($user_id,$get,$page,$size){
|
||||
public static function getGoodsList($user_id,$get,$page,$size,$type){
|
||||
$where = [];
|
||||
$order = [];
|
||||
$where[] = ['status','=',1];
|
||||
$where[] = ['del','=',0];
|
||||
$where[] = ['type','=',$type];
|
||||
|
||||
$goods = new Goods();
|
||||
//品牌筛选
|
||||
if(isset($get['brand_id']) && $get['brand_id']) {
|
||||
$where[] = ['brand_id', '=', $get['brand_id']];
|
||||
$where[] = ['third_category_id', '=', $get['brand_id']];
|
||||
}
|
||||
//分类筛选
|
||||
if(isset($get['category_id']) && $get['category_id']){
|
||||
@@ -71,7 +72,7 @@ class GoodsLogic{
|
||||
->where($where)
|
||||
->page($page,$size)
|
||||
->order($order)
|
||||
->field('id,name,image,min_price as price,market_price,sales_sum+virtual_sales_sum as sales_sum,sort')
|
||||
->field('id,name,image,min_price as price,market_price,sales_sum+virtual_sales_sum as sales_sum,sort,type')
|
||||
->select();
|
||||
|
||||
$more = is_more($goods_count,$page,$size); //是否有下一页
|
||||
@@ -149,7 +150,7 @@ class GoodsLogic{
|
||||
$goods->append(['comment'])->hidden(['Spec','GoodsSpecValue'])
|
||||
->visible(['id','name','image','video','stock','remark','content','sales_sum',
|
||||
'click_count','price','market_price','is_collect','goods_spec','goods_image',
|
||||
'goods_item','activity','member_price']);
|
||||
'goods_item','activity','member_price','type']);
|
||||
|
||||
//判断是否开启了拼团
|
||||
if ($goods['is_team']) {
|
||||
|
||||
@@ -106,4 +106,11 @@ class HelpLogic
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
public function commitmentInfo()
|
||||
{
|
||||
$data = Db::name('help')->where('title','承诺')->field('id,title,content')->find();
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -120,7 +120,9 @@ class OrderLogic extends LogicBase
|
||||
|
||||
$order_amount += $total_shipping_price;//应付订单金额+运费
|
||||
$total_amount += $total_shipping_price;//订单金额+运费
|
||||
|
||||
if ($post['goods_type'] == 4){
|
||||
self::$order_type = CommonOrder::GROUP_ORDER;//普通订单
|
||||
}
|
||||
$result = [
|
||||
'order_type' => self::$order_type,
|
||||
'goods_lists' => array_values($goods_lists),
|
||||
@@ -467,15 +469,35 @@ class OrderLogic extends LogicBase
|
||||
throw new Exception('请选择收货地址');
|
||||
}
|
||||
|
||||
//余额支付,是否满足支付金额
|
||||
// 服务商品拆分逻辑:goods_type == 1 且商品 num > 1 时,拆分成多个订单
|
||||
$goods_type = $post['goods_type'] ?? 0;
|
||||
$original_goods = $post['goods'] ?? [];
|
||||
|
||||
// 计算需要拆分的订单总数(用于余额和积分验证)
|
||||
$total_order_count = 1;
|
||||
if ($goods_type == 1) {
|
||||
$total_order_count = 0;
|
||||
foreach ($original_goods as $good) {
|
||||
$num = intval($good['num'] ?? 1);
|
||||
$total_order_count += $num;
|
||||
}
|
||||
}
|
||||
|
||||
//余额支付,是否满足支付金额(需要考虑拆分后的总金额)
|
||||
if ($data['pay_way'] == Pay::BALANCE_PAY){
|
||||
$user_money = $user['user_money'];
|
||||
// 如果是服务商品拆分,需要计算拆分后的总金额
|
||||
if ($goods_type == 1) {
|
||||
// 拆分后每个订单的金额需要重新计算,这里先验证原始总金额
|
||||
// 实际拆分时每个订单会独立计算
|
||||
} else {
|
||||
if($user_money < $data['order_amount']){
|
||||
throw new Exception('账户余额不足');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//用户当前积分 - 用户使用的积分
|
||||
//用户当前积分 - 用户使用的积分(拆分后每个订单独立计算,这里先验证原始积分)
|
||||
if ($data['user_use_integral'] > 0){
|
||||
if ($user['user_integral'] < $data['user_use_integral']){
|
||||
throw new Exception('积分不足');
|
||||
@@ -499,14 +521,106 @@ class OrderLogic extends LogicBase
|
||||
throw new Exception('您已下单了, 请勿重复操作');
|
||||
}
|
||||
}
|
||||
|
||||
$order_ids = [];
|
||||
|
||||
if ($goods_type == 1) {
|
||||
// 服务商品:需要拆分
|
||||
foreach ($original_goods as $good) {
|
||||
$num = intval($good['num'] ?? 1);
|
||||
if ($num > 1) {
|
||||
// 需要拆分成 num 个订单
|
||||
for ($i = 0; $i < $num; $i++) {
|
||||
// 为每个拆分订单创建单个商品的数据
|
||||
$single_good = $good;
|
||||
$single_good['num'] = 1;
|
||||
|
||||
// 重新计算单个商品的订单数据
|
||||
$single_post = $post;
|
||||
$single_post['goods'] = [$single_good];
|
||||
|
||||
// 重新获取订单详情
|
||||
$single_data = self::info($single_post, $user_id);
|
||||
if ($single_data['code'] == 0) {
|
||||
throw new Exception($single_data['msg']);
|
||||
}
|
||||
$single_order_data = $single_data['data'];
|
||||
|
||||
// 验证余额是否足够(每个订单独立验证)
|
||||
if ($single_order_data['pay_way'] == Pay::BALANCE_PAY) {
|
||||
$user_money = $user['user_money'];
|
||||
if($user_money < $single_order_data['order_amount']){
|
||||
throw new Exception('账户余额不足');
|
||||
}
|
||||
}
|
||||
|
||||
// 创建单个订单
|
||||
$single_goods_lists = $single_order_data['goods_lists'];
|
||||
if (empty($single_goods_lists)) {
|
||||
throw new Exception('商品信息获取失败');
|
||||
}
|
||||
$single_goods_id = $single_goods_lists[0]['goods_id'];
|
||||
|
||||
$order = self::addOrder($user_id, $single_order_data, $order_source, $user_address, $single_goods_id);
|
||||
$order_id = $order['order_id'];
|
||||
$order_ids[] = $order_id;
|
||||
|
||||
self::addOrderGoods($order_id, $single_goods_lists);
|
||||
self::addOrderAfter($order_id, $user_id, $type, $single_order_data);
|
||||
|
||||
//支付方式为余额支付,扣除余额,更新订单状态,支付状态
|
||||
if ($single_order_data['pay_way'] == Pay::BALANCE_PAY || $single_order_data['order_amount'] == 0) {
|
||||
PayNotifyLogic::handle('order', $order['order_sn'], []);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// num == 1,正常创建单个订单
|
||||
$single_post = $post;
|
||||
$single_post['goods'] = [$good];
|
||||
|
||||
$single_data = self::info($single_post, $user_id);
|
||||
if ($single_data['code'] == 0) {
|
||||
throw new Exception($single_data['msg']);
|
||||
}
|
||||
$single_order_data = $single_data['data'];
|
||||
|
||||
// 验证余额是否足够
|
||||
if ($single_order_data['pay_way'] == Pay::BALANCE_PAY) {
|
||||
$user_money = $user['user_money'];
|
||||
if($user_money < $single_order_data['order_amount']){
|
||||
throw new Exception('账户余额不足');
|
||||
}
|
||||
}
|
||||
|
||||
$single_goods_lists = $single_order_data['goods_lists'];
|
||||
if (empty($single_goods_lists)) {
|
||||
throw new Exception('商品信息获取失败');
|
||||
}
|
||||
$single_goods_id = $single_goods_lists[0]['goods_id'];
|
||||
|
||||
$order = self::addOrder($user_id, $single_order_data, $order_source, $user_address, $single_goods_id);
|
||||
$order_id = $order['order_id'];
|
||||
$order_ids[] = $order_id;
|
||||
|
||||
self::addOrderGoods($order_id, $single_goods_lists);
|
||||
self::addOrderAfter($order_id, $user_id, $type, $single_order_data);
|
||||
|
||||
//支付方式为余额支付,扣除余额,更新订单状态,支付状态
|
||||
if ($single_order_data['pay_way'] == Pay::BALANCE_PAY || $single_order_data['order_amount'] == 0) {
|
||||
PayNotifyLogic::handle('order', $order['order_sn'], []);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 普通商品:保持原有逻辑
|
||||
if (empty($goods_lists)) {
|
||||
throw new Exception('商品信息获取失败');
|
||||
}
|
||||
$goods_id = $goods_lists[0]['goods_id'];
|
||||
|
||||
|
||||
$order = self::addOrder($user_id, $data, $order_source, $user_address, $goods_id);
|
||||
|
||||
|
||||
$order_id = $order['order_id'];
|
||||
|
||||
$order_ids[] = $order_id;
|
||||
|
||||
self::addOrderGoods($order_id, $goods_lists);
|
||||
self::addOrderAfter($order_id, $user_id, $type, $data);
|
||||
@@ -515,15 +629,20 @@ class OrderLogic extends LogicBase
|
||||
if ($data['pay_way'] == Pay::BALANCE_PAY || $data['order_amount'] == 0) {
|
||||
PayNotifyLogic::handle('order', $order['order_sn'], []);
|
||||
}
|
||||
|
||||
// 砍价订单处理
|
||||
if (isset($post['bargain_launch_id']) and $post['bargain_launch_id'] > 0) {
|
||||
$bargainLaunchModel = new BargainLaunch();
|
||||
$bargainLaunchModel->where(['id'=>(int)$post['bargain_launch_id']])
|
||||
->update(['order_id'=>$order_id, 'status'=>1]);
|
||||
}
|
||||
}
|
||||
|
||||
Db::commit();
|
||||
return self::dataSuccess('', ['order_id' => $order_id, 'type' => 'order']);
|
||||
if (empty($order_ids)) {
|
||||
throw new Exception('订单创建失败');
|
||||
}
|
||||
return self::dataSuccess('', ['order_id' => $order_ids[0], 'order_ids' => $order_ids, 'type' => 'order']);
|
||||
|
||||
} catch (Exception $e) {
|
||||
Db::rollback();
|
||||
@@ -951,45 +1070,102 @@ class OrderLogic extends LogicBase
|
||||
$order = new Order();
|
||||
$where[] = ['del', '=', 0];
|
||||
// $where[] = ['user_id', '=', $user_id];
|
||||
|
||||
switch ($type) {
|
||||
case 'pay':
|
||||
$where[] = ['pay_status', '=', CommonOrder::STATUS_WAIT_PAY];
|
||||
break;
|
||||
case 'stop':
|
||||
$where[] = ['pay_status', '=', 1];
|
||||
$where[] = ['status', '=', 1];
|
||||
break;
|
||||
case 'delivery':
|
||||
$where[] = ['pay_status', '=', 0];
|
||||
$where[] = ['pay_status', '=', 1];
|
||||
$where[] = ['order_status', '=', 1];
|
||||
$where[] = ['refund_status', '=', 0];
|
||||
break;
|
||||
case 'finish':
|
||||
$where[] = ['order_status', '=',1];
|
||||
$where[] = ['pay_status', '=', 1];
|
||||
$where[] = ['order_status', '=', 3];
|
||||
break;
|
||||
case 'close':
|
||||
$where[] = ['order_status', '=', 4];
|
||||
break;
|
||||
}
|
||||
|
||||
$user=Db::name('user')->where('id',$user_id)->find();
|
||||
$count = $order->where(['del' => 0, 'user_id' => $user['mobile']])
|
||||
// $user=Db::name('user')->where('id',$user_id)->find();
|
||||
if ($type=='reserving'){
|
||||
$where[] = ['pay_status', '=', 1];
|
||||
//查询待预约订单
|
||||
$count = $order->where(['del' => 0, 'user_id' => $user_id])
|
||||
->with('OrderExe')
|
||||
->where($where)
|
||||
->count();
|
||||
|
||||
$lists = $order->where(['del' => 0, 'mobile' => $user['mobile']])
|
||||
$lists = $order->where(['del' => 0, 'user_id' => $user_id])
|
||||
->where($where)
|
||||
// ->with(['orderGoods'])
|
||||
->field('id,order_sn,order_status,pay_status,order_amount,order_status,order_type,shipping_status,create_time,number,goods_id,code')
|
||||
->with('OrderExe')
|
||||
->field('id,order_sn,order_status,pay_status,order_amount,order_status,order_type,shipping_status,refund_status,create_time,number,goods_id,code')
|
||||
->page($page, $size)
|
||||
->order('id desc')
|
||||
->select();
|
||||
}else if($type == 'inservice'){
|
||||
//服务中
|
||||
$where[] = ['pay_status', '=', 1];
|
||||
$count = $order->where(['del' => 0, 'user_id' => $user_id])
|
||||
->with(['OrderExe' => function ($query) {
|
||||
$query->where('timeout', '<>', 'null');
|
||||
}])
|
||||
->where($where)
|
||||
->count();
|
||||
|
||||
$lists = $order->where(['del' => 0, 'user_id' => $user_id])
|
||||
->where($where)
|
||||
->with(['OrderExe' => function ($query) {
|
||||
$query->where('timeout', '<>', 'null');
|
||||
}])
|
||||
->field('id,order_sn,order_status,pay_status,order_amount,order_status,order_type,shipping_status,refund_status,create_time,number,goods_id,code')
|
||||
->page($page, $size)
|
||||
->order('id desc')
|
||||
->select();
|
||||
}else{
|
||||
$count = $order->where(['del' => 0, 'user_id' => $user_id])
|
||||
->where($where)
|
||||
->count();
|
||||
|
||||
$lists = $order->where(['del' => 0, 'user_id' => $user_id])
|
||||
->where($where)
|
||||
// ->with(['orderGoods'])
|
||||
->field('id,order_sn,order_status,pay_status,order_amount,order_status,order_type,shipping_status,refund_status,create_time,number,goods_id,code')
|
||||
->page($page, $size)
|
||||
->order('id desc')
|
||||
->select();
|
||||
}
|
||||
foreach ($lists as $list){
|
||||
$goods=Db::name('goods')->where('id',$list['goods_id'])->find();
|
||||
$list['image']=UrlServer::getFileUrl($goods['image']);
|
||||
$list['goods_name']=$goods['name'];
|
||||
$list['goods_price']=$goods['min_price'];
|
||||
$number=Db::name('order_exe')->where('order_sn',$list['order_sn'])->where('staff_status',3)->count(); //查询订单服务次数
|
||||
$list['ordercs']=$number;
|
||||
$list['ordercs'] = Db::name('order_exe')->where('order_sn',$list['order_sn'])->where('staff_status','<>',3)->count(); //已预约
|
||||
$list['orderyjfw']= $list['number']-$number;
|
||||
$list['orderdaifw'] = $list['number']-$number; //待预约数量
|
||||
$list['orderfwzhon'] = Db::name('order_exe')->where('order_sn',$list['order_sn'])->where('status',3)->count(); //暂停中数量
|
||||
$list['orderyiwanchen'] = Db::name('order_exe')->where('order_sn',$list['order_sn'])->where('staff_status',3)->count(); //服务已完成
|
||||
$list['showBubble']=false;
|
||||
$list['more']="更多";
|
||||
}
|
||||
/**
|
||||
* order_status:订单状态 0-待付款;1-待发货;2-待收货;3-已完成;4-已关闭
|
||||
* pay_status:支付状态;0-待支付;1-已支付;2-已退款;3-拒绝退款
|
||||
* order_amount:应付款金额
|
||||
* order_type:订单类型;0-服务商品;1-秒杀订单;2-拼团订单;3-砍价订单;4-普通商品
|
||||
* shipping_status:发货状态
|
||||
* number:订单的总条数
|
||||
* code:订单的执行次数
|
||||
* goods_price:订单商品总价
|
||||
* ordercs:以订单服务次数
|
||||
* orderyjfw:订单的剩余执行次数
|
||||
*/
|
||||
$data = [
|
||||
'list' => $lists,
|
||||
'page' => $page,
|
||||
@@ -1314,27 +1490,27 @@ class OrderLogic extends LogicBase
|
||||
$order = new Orderexe();
|
||||
$where[] = ['order_sn', '=',$order_sn];
|
||||
switch ($type) {
|
||||
case 'pay':
|
||||
case 'wait':
|
||||
//待服务
|
||||
$where[] = ['staff_status', '=',0];
|
||||
break;
|
||||
case 'delivery':
|
||||
$where[] = ['staff_status', '=',1];
|
||||
break;
|
||||
case 'finish':
|
||||
case 'service':
|
||||
$where[] = ['staff_status', '=',2];
|
||||
break;
|
||||
case 'close':
|
||||
$where[] = ['staff_status', '=',4];
|
||||
case 'finish':
|
||||
$where[] = ['staff_status', '=',3];
|
||||
break;
|
||||
}
|
||||
|
||||
$count =$order->where('order_sn',$order_sn)
|
||||
->count();
|
||||
$count =$order->where($where)->count();
|
||||
|
||||
$lists = $order->where('order_sn',$order_sn)
|
||||
->where($where)
|
||||
->page($page, $size)
|
||||
->order('autotime asc')
|
||||
->orderRaw('CASE WHEN staff_status = 3 THEN 1 ELSE 0 END, autotime ASC')
|
||||
->select();
|
||||
|
||||
foreach ($lists as $list){
|
||||
@@ -1354,10 +1530,7 @@ class OrderLogic extends LogicBase
|
||||
}
|
||||
|
||||
$list['autotime']=date("Y-m-d",$list['autotime']);
|
||||
|
||||
|
||||
}
|
||||
|
||||
$data = [
|
||||
'list' => $lists,
|
||||
'page' => $page,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
namespace app\api\logic;
|
||||
use app\api\model\OrderPoints;
|
||||
use think\Db;
|
||||
use think\Exception;
|
||||
use app\common\server\UrlServer;
|
||||
@@ -9,13 +10,16 @@ class PointsLogic
|
||||
{
|
||||
//获取积分的分类
|
||||
public static function classify(){
|
||||
return Db::name('printer_type')->select();
|
||||
return Db::name('printer_type')->where('del',0)->select();
|
||||
}
|
||||
|
||||
|
||||
//获取到积分的商品列表
|
||||
public static function goodslist(){
|
||||
$where=[];
|
||||
public static function goodslist($clsssId){
|
||||
$where=[
|
||||
'brand_id'=>$clsssId,
|
||||
'del'=>0
|
||||
];
|
||||
$goods = Db::name('printer_goods')
|
||||
->where($where)
|
||||
->select();
|
||||
@@ -34,21 +38,83 @@ class PointsLogic
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 积分商品下单(扣减积分并生成订单)
|
||||
* @param array $data ['id','name','price','user_id','number'(可选)]
|
||||
* @return array
|
||||
*/
|
||||
public static function goodsSub($data){
|
||||
if(empty($data) || !is_array($data)){
|
||||
return ['code'=>0,'msg'=>'参数错误'];
|
||||
}
|
||||
// 基础校验
|
||||
if(empty($data['id']) || empty($data['user_id']) || !isset($data['price'])){
|
||||
return ['code'=>0,'msg'=>'参数不完整'];
|
||||
}
|
||||
$number = isset($data['number']) && intval($data['number'])>0 ? intval($data['number']) : 1;
|
||||
$price = floatval($data['price']);
|
||||
$needIntegral = $price * $number;
|
||||
|
||||
$data=[
|
||||
'name' =>$data['name'],
|
||||
Db::startTrans();
|
||||
try{
|
||||
// 加锁读取用户积分
|
||||
$user = Db::name('user')->where('id',$data['user_id'])->lock(true)->find();
|
||||
if(!$user){
|
||||
throw new Exception('用户不存在');
|
||||
}
|
||||
if($user['user_integral'] < $needIntegral){
|
||||
throw new Exception('积分不足');
|
||||
}
|
||||
|
||||
$orderData = [
|
||||
'name' => $data['name'] ?? '',
|
||||
'goods_id' => $data['id'],
|
||||
'price' =>$data['price'],
|
||||
'number' =>1,
|
||||
'price' => $price,
|
||||
'number' => $number,
|
||||
'user_id' => $data['user_id'],
|
||||
'create_time'=>time()
|
||||
'create_time' => time(),
|
||||
'address_id' => $data['addressId'],
|
||||
'state' => 1
|
||||
];
|
||||
$insert=Db::name('printer_order')->data($data)->insert();
|
||||
if($insert){
|
||||
$user=UserLogic::getUserInfo($data['user_id']);
|
||||
db::name('user')->where('id',$data['user_id'])->update(['user_integral'=>$user['user_integral']-$data['price']]);
|
||||
// Db::name('printer_goods')->where('')
|
||||
|
||||
$insert = Db::name('printer_order')->insert($orderData);
|
||||
if(!$insert){
|
||||
throw new Exception('下单失败');
|
||||
}
|
||||
|
||||
// 扣减积分
|
||||
Db::name('user')
|
||||
->where('id',$data['user_id'])
|
||||
->setDec('user_integral', $needIntegral);
|
||||
|
||||
Db::commit();
|
||||
return ['code'=>1,'msg'=>'兑换成功'];
|
||||
}catch (\Exception $e){
|
||||
Db::rollback();
|
||||
return ['code'=>0,'msg'=>$e->getMessage()];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//获取积分订单
|
||||
public static function orderList($userId, $state = null)
|
||||
{
|
||||
$order = new OrderPoints();
|
||||
$query = $order->with([
|
||||
'address' => function($query){
|
||||
$query->where('del',0)->field('id,address');
|
||||
},
|
||||
'pointsGoods' => function($query){
|
||||
$query->where('del',0)->field('id,images');
|
||||
}
|
||||
])->where('user_id', $userId);
|
||||
|
||||
// 如果传了state参数,才添加state条件,否则查询全部
|
||||
if($state !== null && $state !== ''){
|
||||
$query = $query->where('state', $state);
|
||||
}
|
||||
|
||||
$orderArray = $query->paginate(10);
|
||||
return $orderArray;
|
||||
}
|
||||
}
|
||||
@@ -136,7 +136,9 @@ class UserAddressLogic
|
||||
'district_id' => $post['district_id'],
|
||||
'address' => $post['address'],
|
||||
'is_default' => $post['is_default'],
|
||||
'createtime' => time()
|
||||
'createtime' => time(),
|
||||
'lng' => $post['latitude'],
|
||||
'lat' => $post['longitude']
|
||||
];
|
||||
$result = Db::name('user_address')->insert($data);
|
||||
Db::commit();
|
||||
@@ -175,7 +177,9 @@ class UserAddressLogic
|
||||
'district_id' => $post['district_id'],
|
||||
'address' => $post['address'],
|
||||
'is_default' => $post['is_default'],
|
||||
'update_time' => time()
|
||||
'updatetime' => time(),
|
||||
'lng' => $post['latitude'],
|
||||
'lat' => $post['longitude']
|
||||
];
|
||||
|
||||
$result = Db::name('user_address')
|
||||
@@ -203,7 +207,7 @@ class UserAddressLogic
|
||||
|
||||
$data = [
|
||||
'del' => 1,
|
||||
'update_time' => time()
|
||||
'updatetime' => time()
|
||||
];
|
||||
|
||||
return Db::name('user_address')
|
||||
|
||||
@@ -53,6 +53,7 @@ class UserLogic extends LogicBase {
|
||||
->where(['del'=>0,'user_id'=>$user_id])
|
||||
->where('status','<>',AfterSale::STATUS_SUCCESS_REFUND)
|
||||
->count();
|
||||
//查询名下优惠券
|
||||
$user->coupon = Db::name('coupon_list')->where(['user_id'=>$user_id,'del'=>0,'status'=>0])->count();
|
||||
//分销开关
|
||||
$user->distribution_setting = ConfigServer::get('distribution', 'is_open',1);
|
||||
|
||||
@@ -77,9 +77,22 @@ class Goods extends Model{
|
||||
$this->setAttr('price',$goods_item[0]['price']);
|
||||
$this->setAttr('market_price',$goods_item[0]['market_price']);
|
||||
|
||||
//创建规格值ID到商品项ID的映射
|
||||
$spec_value_to_item = [];
|
||||
foreach ($goods_item as $item) {
|
||||
$spec_value_ids = $item['spec_value_ids'];
|
||||
// spec_value_ids 存储的是规格值ID,可能是一个或多个(逗号分隔)
|
||||
$spec_value_id_array = explode(',', $spec_value_ids);
|
||||
foreach ($spec_value_id_array as $spec_value_id) {
|
||||
$spec_value_to_item[$spec_value_id] = $item['id'];
|
||||
}
|
||||
}
|
||||
|
||||
//拼接规格
|
||||
foreach ($spec_value as $item){
|
||||
if(isset($spec[$item['spec_id']])){
|
||||
//添加对应的商品项ID
|
||||
$item['item_id'] = $spec_value_to_item[$item['id']] ?? 0;
|
||||
$spec[$item['spec_id']]['spec_value'][]= $item;
|
||||
}
|
||||
}
|
||||
|
||||
10
application/api/model/GoodsPoints.php
Normal file
10
application/api/model/GoodsPoints.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
class GoodsPoints extends Model
|
||||
{
|
||||
protected $name = 'printer_goods';
|
||||
}
|
||||
@@ -25,6 +25,7 @@ use app\common\server\ConfigServer;
|
||||
use think\Db;
|
||||
use think\Model;
|
||||
use app\common\model\Order as CommonOrder;
|
||||
use think\model\relation\HasOne;
|
||||
|
||||
class Order extends Model
|
||||
{
|
||||
@@ -38,6 +39,12 @@ class Order extends Model
|
||||
return date('Y-m-d H:i:s', $value);
|
||||
}
|
||||
|
||||
//查询预约订单列表
|
||||
public function OrderExe(): HasOne
|
||||
{
|
||||
return $this->hasOne(Orderexe::class, 'order_sn', 'order_sn');
|
||||
}
|
||||
|
||||
/*
|
||||
* 付款时间
|
||||
*/
|
||||
|
||||
17
application/api/model/OrderEvaluate.php
Normal file
17
application/api/model/OrderEvaluate.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\model;
|
||||
|
||||
use think\Model;
|
||||
use think\model\relation\HasOne;
|
||||
|
||||
class OrderEvaluate extends Model
|
||||
{
|
||||
protected $name = 'orderexe_evaluate';
|
||||
|
||||
//关联子订单
|
||||
public function orderexe():HasOne
|
||||
{
|
||||
return $this->hasOne('Orderexe','id','order_id');
|
||||
}
|
||||
}
|
||||
24
application/api/model/OrderPoints.php
Normal file
24
application/api/model/OrderPoints.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\model;
|
||||
|
||||
use think\Model;
|
||||
use think\model\relation\HasOne;
|
||||
|
||||
class OrderPoints extends Model
|
||||
{
|
||||
protected $name = 'printer_order';
|
||||
|
||||
|
||||
//关联地址
|
||||
public function address(): HasOne
|
||||
{
|
||||
return $this->hasOne(UserAddress::class, 'id', 'address_id');
|
||||
}
|
||||
|
||||
//关联积分商品
|
||||
public function pointsGoods(): HasOne
|
||||
{
|
||||
return $this->hasOne(GoodsPoints::class, 'id', 'goods_id');
|
||||
}
|
||||
}
|
||||
@@ -97,6 +97,13 @@ class Orderexe extends Model
|
||||
return $this->hasMany('order_goods', 'order_id', 'id');
|
||||
}
|
||||
|
||||
//关联商品
|
||||
public function goods()
|
||||
{
|
||||
return $this->belongsTo('goods', 'goods_id', 'id')
|
||||
->field('id,name,image,min_price');
|
||||
}
|
||||
|
||||
|
||||
public function getGoodsCountAttr($value, $data)
|
||||
{
|
||||
|
||||
10
application/api/model/UserAddress.php
Normal file
10
application/api/model/UserAddress.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
class UserAddress extends Model
|
||||
{
|
||||
protected $name = 'user_address';
|
||||
}
|
||||
@@ -8,6 +8,10 @@ use think\facade\Config;
|
||||
|
||||
class CityService
|
||||
{
|
||||
// 腾讯地图API Key
|
||||
// private $tencentMapKey = 'EVOBZ-VX7YU-QKJVR-BVESA-AVFT3-7JBWG';
|
||||
private $tencentMapKey = '66NBZ-KH3W4-7QSUS-K5OBA-7P552-F7F6T';
|
||||
|
||||
public function list()
|
||||
{
|
||||
$cacheKey = 'city_cache_keys';
|
||||
@@ -25,4 +29,162 @@ class CityService
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据经纬度获取所在城市
|
||||
* @param float $lat 纬度
|
||||
* @param float $lng 经度
|
||||
* @return array
|
||||
*/
|
||||
public function getCityByLocation($lat, $lng)
|
||||
{
|
||||
// 参数验证
|
||||
if (empty($lat) || empty($lng)) {
|
||||
return [
|
||||
'success' => false,
|
||||
'msg' => '经纬度参数不能为空',
|
||||
'data' => null
|
||||
];
|
||||
}
|
||||
|
||||
// 验证经纬度范围
|
||||
if (!is_numeric($lat) || !is_numeric($lng)) {
|
||||
return [
|
||||
'success' => false,
|
||||
'msg' => '经纬度格式错误',
|
||||
'data' => null
|
||||
];
|
||||
}
|
||||
|
||||
$lat = floatval($lat);
|
||||
$lng = floatval($lng);
|
||||
|
||||
if ($lat < -90 || $lat > 90 || $lng < -180 || $lng > 180) {
|
||||
return [
|
||||
'success' => false,
|
||||
'msg' => '经纬度范围错误',
|
||||
'data' => null
|
||||
];
|
||||
}
|
||||
|
||||
// 生成缓存key
|
||||
$cacheKey = 'city_location_' . md5($lat . '_' . $lng);
|
||||
|
||||
// 尝试从缓存获取
|
||||
if (Cache::store('redis')->has($cacheKey)) {
|
||||
$cachedData = Cache::store('redis')->get($cacheKey);
|
||||
return [
|
||||
'success' => true,
|
||||
'msg' => '获取成功',
|
||||
'data' => $cachedData
|
||||
];
|
||||
}
|
||||
|
||||
// 调用腾讯地图逆地理编码API
|
||||
$apiUrl = 'https://apis.map.qq.com/ws/geocoder/v1/';
|
||||
$params = [
|
||||
'location' => $lat . ',' . $lng,
|
||||
'key' => $this->tencentMapKey,
|
||||
'get_poi' => 0
|
||||
];
|
||||
|
||||
$url = $apiUrl . '?' . http_build_query($params);
|
||||
|
||||
// 使用curl请求
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$error = curl_error($ch);
|
||||
curl_close($ch);
|
||||
|
||||
if ($error) {
|
||||
return [
|
||||
'success' => false,
|
||||
'msg' => '请求失败:' . $error,
|
||||
'data' => null
|
||||
];
|
||||
}
|
||||
|
||||
if ($httpCode !== 200) {
|
||||
return [
|
||||
'success' => false,
|
||||
'msg' => 'API请求失败,HTTP状态码:' . $httpCode,
|
||||
'data' => null
|
||||
];
|
||||
}
|
||||
|
||||
$result = json_decode($response, true);
|
||||
|
||||
if (empty($result) || $result['status'] !== 0) {
|
||||
return [
|
||||
'success' => false,
|
||||
'msg' => isset($result['message']) ? $result['message'] : '获取城市信息失败',
|
||||
'data' => null
|
||||
];
|
||||
}
|
||||
|
||||
// 解析返回数据
|
||||
$addressComponent = $result['result']['address_component'] ?? [];
|
||||
$cityName = $addressComponent['city'] ?? '';
|
||||
$provinceName = $addressComponent['province'] ?? '';
|
||||
$districtName = $addressComponent['district'] ?? '';
|
||||
$adcode = $addressComponent['adcode'] ?? '';
|
||||
|
||||
// 如果城市名称为空,尝试使用区县名称
|
||||
if (empty($cityName) && !empty($districtName)) {
|
||||
$cityName = $districtName;
|
||||
}
|
||||
|
||||
// 查询数据库中的城市ID
|
||||
$cityId = null;
|
||||
$cityInfo = null;
|
||||
|
||||
if (!empty($cityName)) {
|
||||
// 先尝试精确匹配
|
||||
$cityInfo = Db::name('dev_region')
|
||||
->where('name', $cityName)
|
||||
->where('level', 2) // 市级
|
||||
->find();
|
||||
|
||||
// 如果精确匹配失败,尝试模糊匹配
|
||||
if (empty($cityInfo)) {
|
||||
$cityInfo = Db::name('dev_region')
|
||||
->where('name', 'like', '%' . $cityName . '%')
|
||||
->where('level', 2)
|
||||
->find();
|
||||
}
|
||||
|
||||
if ($cityInfo) {
|
||||
$cityId = $cityInfo['id'];
|
||||
}
|
||||
}
|
||||
|
||||
$data = [
|
||||
'city_name' => $cityName,
|
||||
'province_name' => $provinceName,
|
||||
'district_name' => $districtName,
|
||||
'adcode' => $adcode,
|
||||
'city_id' => $cityId,
|
||||
'city_info' => $cityInfo,
|
||||
'formatted_address' => $result['result']['formatted_addresses']['recommend'] ?? '',
|
||||
'location' => [
|
||||
'lat' => $lat,
|
||||
'lng' => $lng
|
||||
]
|
||||
];
|
||||
|
||||
// 缓存结果(缓存1小时)
|
||||
Cache::store('redis')->set($cacheKey, $data, 3600);
|
||||
return [
|
||||
'success' => true,
|
||||
'msg' => '获取成功',
|
||||
'data' => $data
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,7 @@ class Cart extends Validate
|
||||
'item_id' => 'require|checkGoods',
|
||||
'goods_num' => 'require|integer|gt:0',
|
||||
'selected' => 'require|in:0,1',
|
||||
'type' => 'require|integer|gt:0'
|
||||
];
|
||||
|
||||
protected $message = [
|
||||
@@ -41,11 +42,12 @@ class Cart extends Validate
|
||||
'param.require' => '参数错误',
|
||||
'selected.require' => '参数错误',
|
||||
'selected.in' => '参数错误',
|
||||
'type.require' => '商品类型错误',
|
||||
];
|
||||
|
||||
protected function sceneAdd()
|
||||
{
|
||||
$this->only(['item_id', 'goods_num']);
|
||||
$this->only(['item_id', 'goods_num', 'type']);
|
||||
}
|
||||
|
||||
protected function sceneDel()
|
||||
|
||||
@@ -129,7 +129,9 @@ class OrderRefundLogic
|
||||
}
|
||||
|
||||
$refund_log = Db::name('order_refund')->where(['id' => $refund_id])->find();
|
||||
|
||||
if ($order['transaction_id'] == ''){
|
||||
throw new Exception('微信订单不存在');
|
||||
}
|
||||
$data = [
|
||||
'transaction_id' => $order['transaction_id'],
|
||||
'refund_sn' => $refund_log['refund_sn'],
|
||||
|
||||
@@ -115,27 +115,27 @@ class PayNotifyLogic
|
||||
|
||||
|
||||
//发送通知
|
||||
Hook::listen('notice', [
|
||||
'user_id' => $user['id'],
|
||||
'order_id' => $order['id'],
|
||||
'scene' => NoticeSetting::ORDER_PAY_NOTICE,
|
||||
]);
|
||||
// Hook::listen('notice', [
|
||||
// 'user_id' => $user['id'],
|
||||
// 'order_id' => $order['id'],
|
||||
// 'scene' => NoticeSetting::ORDER_PAY_NOTICE,
|
||||
// ]);
|
||||
|
||||
|
||||
//短信通知
|
||||
Hook::listen('sms_send', [
|
||||
'key' => NoticeSetting::ORDER_PAY_NOTICE,
|
||||
'mobile' => $order->mobile,
|
||||
'user_id' => $user->id,
|
||||
'params' => [
|
||||
'nickname' => $user->nickname,
|
||||
'order_sn' => $order->order_sn,
|
||||
'order_amount' => $order->order_amount,
|
||||
'time' => $order->create_time,
|
||||
'total_num' => $order->total_num.'件',
|
||||
'goods_name' => omit_str(($order->order_goods[0]['goods_name'] ?? '商品'), 8)
|
||||
]
|
||||
]);
|
||||
// Hook::listen('sms_send', [
|
||||
// 'key' => NoticeSetting::ORDER_PAY_NOTICE,
|
||||
// 'mobile' => $order->mobile,
|
||||
// 'user_id' => $user->id,
|
||||
// 'params' => [
|
||||
// 'nickname' => $user->nickname,
|
||||
// 'order_sn' => $order->order_sn,
|
||||
// 'order_amount' => $order->order_amount,
|
||||
// 'time' => $order->create_time,
|
||||
// 'total_num' => $order->total_num.'件',
|
||||
// 'goods_name' => omit_str(($order->order_goods[0]['goods_name'] ?? '商品'), 8)
|
||||
// ]
|
||||
// ]);
|
||||
|
||||
$order_contact_mobile = ConfigServer::get('order_message', 'order_contact_mobile');
|
||||
//平台短信通知
|
||||
|
||||
@@ -40,7 +40,7 @@ class Ad extends Model{
|
||||
self::mobile => [
|
||||
[
|
||||
'name' => '商品分类',
|
||||
'path' => '/pages/sort/sort',
|
||||
'path' => '/pages/category/index',
|
||||
'is_tab' => 1,
|
||||
],
|
||||
[
|
||||
@@ -57,7 +57,7 @@ class Ad extends Model{
|
||||
self::pc => [
|
||||
[
|
||||
'name' => '商品分类',
|
||||
'path' => '/category',
|
||||
'path' => '/category/index',
|
||||
'is_tab' => 0,
|
||||
],
|
||||
[
|
||||
@@ -67,7 +67,7 @@ class Ad extends Model{
|
||||
],
|
||||
[
|
||||
'name' => '个人中心',
|
||||
'path' => '/user/profile',
|
||||
'path' => '/user/user',
|
||||
'is_tab' => 0,
|
||||
],
|
||||
],
|
||||
|
||||
@@ -10,10 +10,11 @@ class Order extends Model
|
||||
protected $name = 'order';
|
||||
|
||||
//订单类型
|
||||
const NORMAL_ORDER = 0;//普通订单
|
||||
const NORMAL_ORDER = 0;//服务订单
|
||||
const SECKILL_ORDER = 1;//秒杀订单
|
||||
const TEAM_ORDER = 2;//拼团订单
|
||||
const BARGAIN_ORDER = 3;//砍价订单
|
||||
const GROUP_ORDER = 4; //普通订单
|
||||
|
||||
//订单状态
|
||||
const STATUS_WAIT_PAY = 0; //待付款
|
||||
@@ -52,6 +53,7 @@ class Order extends Model
|
||||
self::SECKILL_ORDER => '秒杀订单',
|
||||
self::TEAM_ORDER => '拼团订单',
|
||||
self::BARGAIN_ORDER => '砍价订单',
|
||||
self::GROUP_ORDER => '普通订单',
|
||||
];
|
||||
|
||||
if ($type === true){
|
||||
|
||||
@@ -25,6 +25,20 @@ class Aliyun extends Server
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建并配置 OssClient
|
||||
* @return OssClient
|
||||
*/
|
||||
private function createOssClient()
|
||||
{
|
||||
return new OssClient(
|
||||
$this->config['access_key_id'],
|
||||
$this->config['access_key_secret'],
|
||||
$this->config['domain'],
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行上传
|
||||
* @param $save_dir (保存路径)
|
||||
@@ -33,12 +47,7 @@ class Aliyun extends Server
|
||||
public function upload($save_dir)
|
||||
{
|
||||
try {
|
||||
$ossClient = new OssClient(
|
||||
$this->config['access_key_id'],
|
||||
$this->config['access_key_secret'],
|
||||
$this->config['domain'],
|
||||
true
|
||||
);
|
||||
$ossClient = $this->createOssClient();
|
||||
$ossClient->uploadFile(
|
||||
$this->config['bucket'],
|
||||
$save_dir . '/' . $this->fileName,
|
||||
@@ -61,12 +70,7 @@ class Aliyun extends Server
|
||||
public function fetch($url, $key = null)
|
||||
{
|
||||
try {
|
||||
$ossClient = new OssClient(
|
||||
$this->config['access_key_id'],
|
||||
$this->config['access_key_secret'],
|
||||
$this->config['domain'],
|
||||
true
|
||||
);
|
||||
$ossClient = $this->createOssClient();
|
||||
|
||||
$content = file_get_contents($url);
|
||||
$ossClient->putObject(
|
||||
@@ -89,12 +93,7 @@ class Aliyun extends Server
|
||||
public function delete($fileName)
|
||||
{
|
||||
try {
|
||||
$ossClient = new OssClient(
|
||||
$this->config['access_key_id'],
|
||||
$this->config['access_key_secret'],
|
||||
$this->config['domain'],
|
||||
true
|
||||
);
|
||||
$ossClient = $this->createOssClient();
|
||||
$ossClient->deleteObject($this->config['bucket'], $fileName);
|
||||
} catch (OssException $e) {
|
||||
$this->error = $e->getMessage();
|
||||
|
||||
@@ -12,5 +12,5 @@ Route::rule('mobile/:any', function () {
|
||||
//手机h5页面路由
|
||||
Route::rule('pc/:any', function () {
|
||||
Config::set('app_trace', false);
|
||||
return view(app()->getRootPath() . 'public/pc/index.html');
|
||||
return view(app()->getRootPath() . 'public/pc/lists.html');
|
||||
})->pattern(['any' => '\w+']);
|
||||
@@ -14,6 +14,10 @@ namespace think;
|
||||
use think\exception\ValidateException;
|
||||
use traits\controller\Jump;
|
||||
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
|
||||
header("Access-Control-Allow-Headers: Content-Type, Authorization");
|
||||
|
||||
class Controller
|
||||
{
|
||||
use Jump;
|
||||
|
||||
@@ -157,7 +157,7 @@ class RequestCore
|
||||
/**
|
||||
* The state of SSL certificate verification.
|
||||
*/
|
||||
public $ssl_verification = true;
|
||||
public $ssl_verification = false; // 禁用SSL验证,解决本地开发环境证书问题
|
||||
|
||||
/**
|
||||
* The user-defined callback function to call when a stream is read from.
|
||||
|
||||
Reference in New Issue
Block a user