Compare commits

...

41 Commits

Author SHA1 Message Date
彭桃
524e2dbfe0 后台 2023-04-11 17:59:02 +08:00
彭桃
9565792609 后台 2023-04-10 17:38:49 +08:00
彭桃
45e9f2810d 后台 2023-04-08 17:47:15 +08:00
彭桃
c0ff1742fd 提现 2023-04-07 17:39:42 +08:00
mkm
d5405d65ee 修复权限错误 2023-04-07 16:54:33 +08:00
mkm
1fcf92094d 修复 首页查询错误 2023-04-07 16:37:53 +08:00
彭桃
1a18ed0a83 3 2023-04-04 14:13:12 +08:00
彭桃
b0f54fe29c 3 2023-04-04 14:11:41 +08:00
彭桃
9b04d020ef 1 2023-04-04 14:07:41 +08:00
彭桃
a05c48b7e1 2 2023-04-04 14:02:53 +08:00
彭桃
f32a0c5d06 1 2023-04-04 13:46:35 +08:00
彭桃
109bf3a6a7 1 2023-04-04 10:28:17 +08:00
彭桃
4148793380 后台修改 2023-04-03 17:00:32 +08:00
彭桃
73d1cbfe44 2 2023-04-03 16:02:18 +08:00
彭桃
1e841dfcff 11 2023-03-30 11:17:24 +08:00
彭桃
ad42e3f1c5 11 2023-03-30 10:27:06 +08:00
彭桃
47812418b8 接口修改2 2023-03-29 16:14:06 +08:00
彭桃
ebcfa79114 接口修改 2023-03-29 16:11:14 +08:00
彭桃
843dcfd2f1 1 2023-03-29 15:50:36 +08:00
彭桃
70108bfe30 1 2023-03-29 14:18:36 +08:00
彭桃
b5a3a6666f 新种植分类等接口 2023-03-28 17:55:50 +08:00
彭桃
8df482d949 商品编辑 2023-03-27 17:51:10 +08:00
彭桃
7ddd6ec107 1 2023-03-27 14:41:19 +08:00
彭桃
8ba171039f 1 2023-03-27 14:38:02 +08:00
彭桃
cb373a99e5 商品添加 2023-03-27 09:22:57 +08:00
1937dbde5c 商品添加提及 2023-03-24 14:33:36 +08:00
彭桃
2edc939178 1 2023-03-24 10:21:46 +08:00
彭桃
11ab30cf2c 1 2023-03-24 09:52:44 +08:00
彭桃
fa8b6729d1 1 2023-03-24 09:47:00 +08:00
彭桃
ec620b8736 1 2023-03-23 13:48:47 +08:00
彭桃
649140cad5 供应链B到B商品 2023-03-22 16:51:51 +08:00
monanxiao
9f09cba053 Merge branch 'master' of git.excellentkk.cn:mkm/nk-lihaink-cn 2023-03-22 16:06:51 +08:00
monanxiao
c238c0f50c 更新统计视图 2023-03-22 16:06:49 +08:00
mkm
f6a7078a2d 修复land_area 错误 breed_area 错误 2023-03-22 14:00:56 +08:00
mkm
5870683c22 修复land_area 错误 breed_area 错误 2023-03-22 13:51:45 +08:00
mkm
b4d2add477 修复user_id错误 2023-03-22 13:48:14 +08:00
mkm
f0b1e3435d 修复idcard错误 2023-03-22 13:42:01 +08:00
monanxiao
7d229466e3 完善后台诉求列表 2023-03-22 13:36:50 +08:00
monanxiao
dd8d756149 修复后台村民互动展示、审核等业务逻辑 2023-03-22 13:36:50 +08:00
monanxiao
22a9379d54 合并代码 2023-03-22 13:36:50 +08:00
mkm
3a97605c1c 修复错误 2023-03-22 13:35:24 +08:00
656 changed files with 78526 additions and 660 deletions

View File

@ -18,9 +18,36 @@ use think\exception\ValidateException;
use think\facade\Cache;
use think\facade\Db;
use think\facade\Session;
use app\admin\model\InformationUserMsg;
use app\admin\model\InformationUserAddress;
use app\admin\model\ShopUser;
use app\admin\model\SupplyBrokerage as SupplyBrokerageModel;
use app\admin\model\StoreOrder;
use app\admin\model\StoreCategory as StoreCategoryModel;
use app\common\controller\FormatList;
use app\common\model\merchant\user\UserMerchant;
class Api extends BaseController
{
protected $category;
public function __construct(StoreCategoryModel $category)
{
$this->category = $category;
}
/**
* 平台商品分类
*
*/
public function getAllList()
{
$where['mer_id'] = 0;
$where['is_show'] = 0;
$data = $this->category->getStoreCategoryList(0,1);
$list = FormatList::FormatCategory($data,'store_category_id', 'pid', 'cate_name','child', 'id', 'title');
return to_assign(0, '', $list);
}
//上传文件
public function upload()
{
@ -136,6 +163,122 @@ class Api extends BaseController
return to_assign(1, '上传失败,请重试');
}
}
//上传文件
public function upload2()
{
$param = get_params();
//var_dump($param);exit;
$sourse = 'file';
if(isset($param['sourse'])){
$sourse = $param['sourse'];
}
if($sourse == 'file' || $sourse == 'tinymce'){
if(request()->file('file')){
$file = request()->file('file');
}
else{
return to_assign(1, '没有选择上传文件');
}
}
else{
if (request()->file('editormd-image-file')) {
$file = request()->file('editormd-image-file');
} else {
return to_assign(1, '没有选择上传文件');
}
}
// 获取上传文件的hash散列值
$sha1 = $file->hash('sha1');
$md5 = $file->hash('md5');
$rule = [
'image' => 'jpg,png,jpeg,gif',
'doc' => 'doc,docx,ppt,pptx,xls,xlsx,pdf',
'file' => 'zip,gz,7z,rar,tar',
'video' => 'mpg,mp4,mpeg,avi,wmv,mov,flv,m4v',
];
$fileExt = $rule['image'] . ',' . $rule['doc'] . ',' . $rule['file'] . ',' . $rule['video'];
//1M=1024*1024=1048576字节
$fileSize = 100 * 1024 * 1024;
if (isset($param['type']) && $param['type']) {
$fileExt = $rule[$param['type']];
}
if (isset($param['size']) && $param['size']) {
$fileSize = $param['size'];
}
$validate = \think\facade\Validate::rule([
'image' => 'require|fileSize:' . $fileSize . '|fileExt:' . $fileExt,
]);
$file_check['image'] = $file;
if (!$validate->check($file_check)) {
return to_assign(1, $validate->getError());
}
// 日期前綴
$dataPath = date('Ym');
$use = 'thumb';
$accessKeyId = "LTAI5t7mhH3ij2cNWs1zhPmv"; ;
$accessKeySecret = "gqo2wMpvi8h5bDBmCpMje6BaiXvcPu";
$endpoint = "oss-cn-chengdu.aliyuncs.com";
try {
$ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);
} catch (OssException $e) {
return to_assign(1, $e->getMessage());
}
$bucket = "lihai001";
$object = 'storage/'.$dataPath.'/'.$md5.'.jpg';
// $filename = \think\facade\Filesystem::disk('public')->putFile($dataPath, $file, function () use ($md5) {
// return $md5;
// });
try {
$filename=$ossClient->uploadFile($bucket, $object,$file);
} catch (OssException $e) {
return to_assign(1, $e->getMessage());
}
if ($filename) {
//写入到附件表
$data = [];
$path = get_config('filesystem.disks.public.url');
$data['filepath'] = $filename['info']['url'];
$data['name'] = $file->getOriginalName();
$data['mimetype'] = $file->getOriginalMime();
$data['fileext'] = $file->extension();
$data['filesize'] = $file->getSize();
$data['filename'] = $object;
$data['sha1'] = $sha1;
$data['md5'] = $md5;
$data['module'] = \think\facade\App::initialize()->http->getName();
$data['action'] = app('request')->action();
$data['uploadip'] = app('request')->ip();
$data['create_time'] = time();
$data['user_id'] = get_login_admin('id') ? get_login_admin('id') : 0;
if ($data['module'] = 'admin') {
//通过后台上传的文件直接审核通过
$data['status'] = 1;
$data['admin_id'] = $data['user_id'];
$data['audit_time'] = time();
}
$data['use'] = request()->has('use') ? request()->param('use') : $use; //附件用处
$res['id'] = Db::name('file')->insertGetId($data);
$res['url'] = $data['filepath'];
$res['name'] = $data['name'];
$res['filename'] = $data['filename'];
add_log('upload', $data['user_id'], $data);
if($sourse == 'editormd'){
//editormd编辑器上传返回
return json(['success'=>1,'message'=>'上传成功','url'=>$data['filepath']]);
}
else if($sourse == 'tinymce'){
//tinymce编辑器上传返回
return json(['success'=>1,'message'=>'上传成功','location'=>$data['filepath']]);
}
else{
//普通上传返回
return to_assign(200, '上传成功', $res);
}
} else {
return to_assign(1, '上传失败,请重试');
}
}
//获取权限树所需的节点列表
public function get_rule()
@ -515,10 +658,37 @@ class Api extends BaseController
*/
public function main()
{
$res = Cache::store('file')->remember(self::class . '@main', function () {
$today = $this->mainGroup('today');
$yesterday = $this->mainGroup('yesterday');
$lastWeek = $this->mainGroup(date('Y-m-d', strtotime('- 7day')));
// 获取当前登录账号
$adminUserInfo = get_login_admin();
$mmm = [];
//权限组信息
if ($adminUserInfo['group_access'] != 1) {
$find = InformationUserAddress::where('admin_id', $adminUserInfo['id'])->find();
if ($find) {
if ($find['auth_range'] == 1) {
$mmm['area_id'] = $find['area_id'];
$mmm['street_id'] = $find['street_id'];
$mmm['village_id'] = $find['village_id'];
} elseif ($find['auth_range'] == 2) {
$mmm['area_id'] = $find['area_id'];
$mmm['street_id'] = $find['street_id'];
}elseif ($find['auth_range'] == 5) {
$mmm['area_id'] = $find['area_id'];
$mmm['street_id'] = $find['street_id'];
$mmm['village_id'] = $find['village_id'];
$mmm['brigade_id'] = $find['brigade_id'];
}
}
}
$res = Cache::store('file')->remember(self::class . '@main', function () use ($mmm){
$today = $this->mainGroup('today' , $mmm);
$yesterday = $this->mainGroup('yesterday', $mmm);
$lastWeek = $this->mainGroup(date('Y-m-d', strtotime('- 7day')), $mmm);
$lastWeekRate = [];
foreach ($lastWeek as $k => $item) {
@ -561,28 +731,66 @@ class Api extends BaseController
* @author xaboy
* @day 2020/6/25
*/
protected function mainGroup($date,$merId=null)
protected function mainGroup($date, $mmm)
{
// 获取当前地域成员
$userList = InformationUserMsg::where($mmm)
->with(['user'])
->select();
$payPrice = getModelTime(Db::connect('shop')->table('eb_store_order')->where('paid', 1)->when($merId, function ($query, $merId) {
$query->where('mer_id', $merId);
}), $date, 'pay_time')->sum('pay_price');
// 地域成员ID
$arrUid = [];
$arrPhone = [];
foreach ($userList as $v) {
// 如果存在服务小组的话,则取出
if($v['user']['fa_supply_team_id'])
{
$arrUid[] = $v['user']['uid'];
$arrPhone[] = $v['user']['phone'];
}
}
$merId = null;
$payPrice = getModelTime(StoreOrder::whereIn('uid', $arrUid)
->where('paid', 1), $date, 'create_time')
->sum('pay_price');
// $list = SupplyBrokerageModel::whereIn('user_id', $arrUid)
// ->with(['user', 'merchant', 'supplyChain', 'level'])
// ->page($params['page'])
// ->limit($params['limit'])
// ->select();
$payUser = getModelTime(Db::connect('shop')->table('eb_store_order')->where('paid', 1)->when($merId, function ($query, $merId) {
$query->where('mer_id', $merId);
}), $date, 'pay_time')->group('uid')->count();
// $payPrice = getModelTime(Db::connect('shop')->table('eb_store_order')->where('paid', 1)->when($merId, function ($query, $merId) {
// $query->where('mer_id', $merId);
// }), $date, 'pay_time')->sum('pay_price');
$userNum = (float)Db::connect('shop')->table('eb_user')->when($date, function ($query, $date) {
$payUser = getModelTime(StoreOrder::whereIn('uid', $arrUid)->where('paid', 1), $date, 'pay_time')->group('uid')->count();
$userNum = (float)ShopUser::whereIn('uid', $arrUid)->when($date, function ($query, $date) {
getModelTime($query, $date, 'create_time');
})->count();
$storeNum = (float)Db::connect('shop')->table('eb_merchant')->where('is_del', 0)->when($date, function ($query, $date) {
getModelTime($query, $date);
})->count();
$visitUserNum = (float)Db::connect('shop')->table('eb_user_visit')->alias('A')->join('eb_store_product B', 'A.type_id = B.product_id')->when($date, function ($query, $date) {
getModelTime($query, $date, 'A.create_time');
})->when($merId, function ($query, $merId) {
$query->where('B.mer_id', $merId);
})->where('A.type', 'product')->group('uid')->count();
// 可能存在问题,待更新
$storeNum = (float)Db::connect('shop')
->table('eb_merchant')
->where('is_del', 0)
->whereIn('mer_phone', $arrPhone)
->when($date, function ($query, $date) {
getModelTime($query, $date);
})->count();
$visitUserNum = (float)Db::connect('shop')
->table('eb_user_visit')
->alias('A')
->whereIn('A.uid', $arrUid)
->join('eb_store_product B', 'A.type_id = B.product_id')
->when($date, function ($query, $date) {
getModelTime($query, $date, 'A.create_time');
})->when($merId, function ($query, $merId) {
$query->where('B.mer_id', $merId);
})->where('A.type', 'product')->group('uid')->count();
$visitNum = (float)Db::connect('shop')->table('eb_user_visit')->when($date, function ($query, $date) {
getModelTime($query, $date, 'create_time');
@ -833,10 +1041,59 @@ class Api extends BaseController
*/
public function product()
{
// 获取当前登录账号
$adminUserInfo = get_login_admin();
$mmm = [];
//权限组信息
if ($adminUserInfo['group_access'] != 1) {
$find = InformationUserAddress::where('admin_id', $adminUserInfo['id'])->find();
if ($find) {
if ($find['auth_range'] == 1) {
$mmm['area_id'] = $find['area_id'];
$mmm['street_id'] = $find['street_id'];
$mmm['village_id'] = $find['village_id'];
} elseif ($find['auth_range'] == 2) {
$mmm['area_id'] = $find['area_id'];
$mmm['street_id'] = $find['street_id'];
}elseif ($find['auth_range'] == 5) {
$mmm['area_id'] = $find['area_id'];
$mmm['street_id'] = $find['street_id'];
$mmm['village_id'] = $find['village_id'];
$mmm['brigade_id'] = $find['brigade_id'];
}
}
}
// 获取当前地域成员
$userList = InformationUserMsg::where($mmm)
->with(['user'])
->select();
// 地域成员ID
$arrUid = [];
$arrPhone = [];
foreach ($userList as $v) {
// 如果存在服务小组的话,则取出
if($v['user']['fa_supply_team_id'])
{
$arrUid[] = $v['user']['uid'];
$arrPhone[] = $v['user']['phone'];
}
}
$date = get_params('date') ?? 'today';
$merId = get_params('mer_id') ??'';
$res = Cache::store('file')->remember(self::class . '@product' . $merId . $date, function () use ($merId, $date) {
return Db::connect('shop')->table('eb_store_order_product')->alias('A')->Join('eb_store_order B', 'A.order_id = B.order_id')
$www2[] = ['A.uid','in', $arrUid];
$res = Cache::store('file')->remember(self::class . '@product' . $merId . $date, function () use ($merId, $date, $arrUid,$www2) {
return Db::connect('shop')->table('eb_store_order_product')
->alias('A')
->where($www2)
->Join('eb_store_order B', 'A.order_id = B.order_id')
->field(Db::raw('sum(A.product_num) as total,A.product_id,cart_info'))
->withAttr('cart_info', function ($val) {
return json_decode($val, true);
@ -851,7 +1108,8 @@ class Api extends BaseController
getModelTime($query, $date, 'B.pay_time');
})->when($merId, function ($query, $merId) {
$query->where('B.mer_id', $merId);
})->where('B.paid', 1)->group('A.product_id')->limit(10)->order('total DESC')->select();
})->where('B.paid', '1')->group('A.product_id')->limit(10)->order('total DESC')->select();
}, 2000 + random_int(600, 1200));
$result = ['data' => $res];
return table_assign(0, '', $result);
@ -860,11 +1118,60 @@ class Api extends BaseController
//商品访客排行
public function productVisit()
{
// 获取当前登录账号
$adminUserInfo = get_login_admin();
$mmm = [];
//权限组信息
if ($adminUserInfo['group_access'] != 1) {
$find = InformationUserAddress::where('admin_id', $adminUserInfo['id'])->find();
if ($find) {
if ($find['auth_range'] == 1) {
$mmm['area_id'] = $find['area_id'];
$mmm['street_id'] = $find['street_id'];
$mmm['village_id'] = $find['village_id'];
} elseif ($find['auth_range'] == 2) {
$mmm['area_id'] = $find['area_id'];
$mmm['street_id'] = $find['street_id'];
}elseif ($find['auth_range'] == 5) {
$mmm['area_id'] = $find['area_id'];
$mmm['street_id'] = $find['street_id'];
$mmm['village_id'] = $find['village_id'];
$mmm['brigade_id'] = $find['brigade_id'];
}
}
}
// 获取当前地域成员
$userList = InformationUserMsg::where($mmm)
->with(['user'])
->select();
// 地域成员ID
$arrUid = [];
$arrPhone = [];
foreach ($userList as $v) {
// 如果存在服务小组的话,则取出
if($v['user']['fa_supply_team_id'])
{
$arrUid[] = $v['user']['uid'];
$arrPhone[] = $v['user']['phone'];
}
}
$date = get_params('date') ?? 'today';
$merId = get_params('mer_id') ??'';
$res = Cache::store('file')->remember(self::class . '@productVisit' . $merId . $date, function () use ($merId, $date) {
return Db::connect('shop')->table('eb_user_visit')->alias('A')->join('eb_store_product B', 'A.type_id = B.product_id')
$res = Cache::store('file')->remember(self::class . '@productVisit' . $merId . $date, function () use ($merId, $date, $arrUid) {
return Db::connect('shop')
->table('eb_user_visit')
->alias('A')
->whereIn('A.uid', $arrUid)
->join('eb_store_product B', 'A.type_id = B.product_id')
->join('eb_merchant C', 'C.mer_id = B.mer_id')
->field(Db::raw('count(A.type_id) as total,B.image,B.store_name'))
->when($date, function ($query, $date) {
@ -884,118 +1191,107 @@ class Api extends BaseController
*/
public function productCart()
{
// 获取当前登录账号
$adminUserInfo = get_login_admin();
$mmm = [];
//权限组信息
if ($adminUserInfo['group_access'] != 1) {
$find = InformationUserAddress::where('admin_id', $adminUserInfo['id'])->find();
if ($find) {
if ($find['auth_range'] == 1) {
$mmm['area_id'] = $find['area_id'];
$mmm['street_id'] = $find['street_id'];
$mmm['village_id'] = $find['village_id'];
} elseif ($find['auth_range'] == 2) {
$mmm['area_id'] = $find['area_id'];
$mmm['street_id'] = $find['street_id'];
}elseif ($find['auth_range'] == 5) {
$mmm['area_id'] = $find['area_id'];
$mmm['street_id'] = $find['street_id'];
$mmm['village_id'] = $find['village_id'];
$mmm['brigade_id'] = $find['brigade_id'];
}
}
}
// 获取当前地域成员
$userList = InformationUserMsg::where($mmm)
->with(['user'])
->select();
// 地域成员ID
$arrMerId = [];
$mer_id = '';
foreach ($userList as $v) {
// 如果存在服务小组的话,则取出
if($v['user']['fa_supply_team_id'])
{
$mer_id = (float)Db::connect('shop')
->table('eb_merchant')
->where('is_del', 0)
->where('mer_phone', $v['user']['phone'])
->value('mer_id');
if($mer_id)
{
$arrMerId[] = $mer_id;
}
}
}
$date = get_params('date') ?? 'today';
$merId = get_params('mer_id') ??'';
$res = Cache::store('file')->remember(self::class . '@productCart' . $merId . $date, function () use ($merId, $date) {
return Db::connect('shop')->table('eb_store_product')->alias('A')->Join('eb_store_cart B', 'A.product_id = B.product_id')
->field(Db::raw('sum(B.cart_num) as total,A.product_id,A.store_name,A.image'))
->when($date, function ($query, $date) {
getModelTime($query, $date, 'B.create_time');
})->when($merId, function ($query, $merId) {
$query->where('A.mer_id', $merId);
})->where('B.product_type', 0)->where('B.is_pay', 0)->where('B.is_del', 0)
->where('B.is_new', 0)->where('B.is_fail', 0)->group('A.product_id')->limit(10)->order('total DESC')->select();
$res = Cache::store('file')->remember(self::class . '@productCart' . $merId . $date, function () use ($merId, $date, $arrMerId) {
return Db::connect('shop')
->table('eb_store_product')
->alias('A')
->whereIn('A.mer_id', $arrMerId)
->Join('eb_store_cart B', 'A.product_id = B.product_id')
->field(Db::raw('sum(B.cart_num) as total,A.product_id,A.store_name,A.image'))
->when($date, function ($query, $date) {
getModelTime($query, $date, 'B.create_time');
})->when($merId, function ($query, $merId) {
$query->where('A.mer_id', $merId);
})->where('B.product_type', 0)->where('B.is_pay', 0)->where('B.is_del', 0)
->where('B.is_new', 0)->where('B.is_fail', 0)->group('A.product_id')->limit(10)->order('total DESC')->select();
}, 2000 + random_int(600, 1200));
$result = ['data' => $res];
return table_assign(0, '', $result);
}
// 接收微信支付状态的通知
public function notify()
{
$app = $this->payment();
// 用 easywechat 封装的方法接收微信的信息, 根据 $message 的内容进行处理, 之后要告知微信服务器处理好了, 否则微信会一直请求这个 url, 发送信息
$response = $app->handlePaidNotify(function($message, $fail){
// 首先查看 order 表, 如果 order 表有记录, 表示已经支付过了
$order = Order::where('order_sn', $message['out_trade_no'])->first();
if ($order) {
return true; // 如果已经生成订单, 表示已经处理完了, 告诉微信不用再通知了
public function changestatus(){
$data = get_params();
if($data){
$where['product_id'] = $data['product_id'];
$d['is_show'] = $data['is_show'];
$res = Db::connect('shop')->table('eb_store_product')->where($where)->update($d);
if($res){
return to_assign(200, '操作成功');
}else{
return to_assign(0, '操作失败');
}
}
return to_assign(0, '操作失败');
}
// 查看支付日志
$payLog = PayLog::where('out_trade_no', $message['out_trade_no'])->first();
if (!$payLog || $payLog->paid_at) { // 如果订单不存在 或者 订单已经支付过了
return true; // 告诉微信,我已经处理完了,订单没找到,别再通知我了
}
// return_code 表示通信状态,不代表支付状态
if ($message['return_code'] === 'SUCCESS') {
// 用户是否支付成功
if ($message['result_code'] === 'SUCCESS') {
// 更新支付时间为当前时间
$payLog->paid_at = now();
$post_id = $payLog->post_id;
// 联表查询 post 的相关信息
$post_title = $payLog->post->title;
$post_price = $payLog->post->price;
$post_original_price = $payLog->post->original_price;
$post_cover = $payLog->post->post_cover;
$post_description = $payLog->post->description;
$user_id = $payLog->post->user_id;
// 创建订单记录
Order::create([
'order_sn' => $message['out_trade_no'],
'total_fee' => $message['total_fee'],
'pay_log_id' => $payLog->id,
'status' => 1,
'user_id' => $user_id,
'paid_at' => $payLog->paid_at,
'post_id' => $post_id,
'post_title' => $post_title,
'post_price' => $post_price,
'post_original_price' => $post_original_price,
'post_cover' => $post_cover,
'post_description' => $post_description,
]);
// 更新 PayLog, 这里的字段都是根据微信支付结果通知的字段设置的(https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_7&index=8)
PayLog::where('out_trade_no', $message['out_trade_no'])->update([
'appid' => $message['appid'],
'bank_type' => $message['bank_type'],
'total_fee' => $message['total_fee'],
'trade_type' => $message['trade_type'],
'is_subscribe' => $message['is_subscribe'],
'mch_id' => $message['mch_id'],
'nonce_str' => $message['nonce_str'],
'openid' => $message['openid'],
'sign' => $message['sign'],
'cash_fee' => $message['cash_fee'],
'fee_type' => $message['fee_type'],
'transaction_id' => $message['transaction_id'],
'time_end' => $payLog->paid_at,
'result_code' => $message['result_code'],
'return_code' => $message['return_code'],
]);
}
} else {
// 如果支付失败, 也更新 PayLog, 跟上面一样, 就是多了 error 信息
PayLog::where('out_trade_no', $message['out_trade_no'])->update([
'appid' => $message['appid'],
'bank_type' => $message['bank_type'],
'total_fee' => $message['total_fee'],
'trade_type' => $message['trade_type'],
'is_subscribe' => $message['is_subscribe'],
'mch_id' => $message['mch_id'],
'nonce_str' => $message['nonce_str'],
'openid' => $message['openid'],
'sign' => $message['sign'],
'cash_fee' => $message['cash_fee'],
'fee_type' => $message['fee_type'],
'transaction_id' => $message['transaction_id'],
'time_end' => $payLog->paid_at,
'result_code' => $message['result_code'],
'return_code' => $message['return_code'],
'err_code' => $message['err_code'],
'err_code_des' => $message['err_code_des'],
]);
return $fail('通信失败,请稍后再通知我');
}
return true; // 返回处理完成
});
// 这里是必须这样返回的, 会发送给微信服务器处理结果
return $response;
public function category_arr($id=0){
$where[]=['is_show','=',1];
$where[]=['mer_id','=',0];
if($id!=0){
$where[1]=['mer_id','=',$id];
}
$list=Db::connect('shop')->table('eb_store_category')->where($where)
->field('store_category_id id,pid,cate_name name')->select();
$category_arr=create_tree_list(0,$list,0);
return to_assign(0,'操作成功', $category_arr);
}
}

View File

@ -90,7 +90,7 @@ class Index extends BaseController
View::assign('month_order',$Month_order);
return View('main2');
}
$where=[];
// 如果登录ID不是超管的话
if ($this->adminInfo['id'] != 1){
@ -111,10 +111,7 @@ class Index extends BaseController
}
}
}else{
$where=[];
}
// 获取**数量
$num = InformationUserMsg::where($where)->count();

File diff suppressed because it is too large Load Diff

View File

@ -71,7 +71,7 @@ class Article extends BaseController
->page($params['page'])
->limit($params['limit'])
->order('id desc')
->field('id,title,user_id,county,township,village,image,view_time')
->field('id,title,user_id,content,county,township,village,image,view_time')
->select();
$result = ['total' => $total, 'data' => $list];

View File

@ -29,6 +29,8 @@ class Community extends BaseController
'/admin/nk.community/del',
'/admin/nk.community/read',
];
// 获取用户信息
$this->users = Db::table('fa_szxc_information_usermsg')->where('status',1)->field('user_id,name')->select();
}
/**
* 数据列表
@ -59,6 +61,7 @@ class Community extends BaseController
$total = Db::connect('shop')->name('community_address')
->where($where)
->count();
if ($total!=0){
$list = Db::connect('shop')->name('community_address')
->where($where)
@ -69,7 +72,7 @@ class Community extends BaseController
foreach ($list as $k=>$v){
$arr[]=$v['community_id'];
}
$list2=Db::connect('shop')->name('community')->where('community_id','in',$arr)->select();
$list2=Db::connect('shop')->name('community')->where('community_id','in',$arr)->order('community_id desc')->select();
}else{
$list2=[];
}
@ -83,6 +86,47 @@ class Community extends BaseController
}
public function edit(){
$param = get_params();
if (request()->isAjax()) {
$is_show = $param['status'] == 1 ? 1 : 0;
$data = [
'refusal' => $param['refusal'],
'status' => $param['status'],
'is_show' => $is_show,
];
$res = Db::connect('shop')->name('community')
->where('community_id', $param['id'])
->strict(false)
->update($data);
if ($res){
return to_assign(0, '操作成功');
}else{
return to_assign(1, '操作失败,原因:'.$res);
}
}else{
$id = isset($param['id']) ? $param['id'] : 0;
$detail = Db::connect('shop')->name('community')->where('community_id',$id)->find();
View::assign('editor', get_system_config('other','editor'));
if (!empty($detail)) {
View::assign('detail', $detail);
View::assign('users', $this->users);
return view();
}
else{
throw new \think\exception\HttpException(404, '找不到页面');
}
}
}
/**
* 查看信息
*/

View File

@ -34,11 +34,66 @@ class Feedback extends BaseController
public function index()
{
if (request()->isAjax()) {
$params= get_params();
$params['category_id']=$this->category_id;
(new Article())->index($params);
$params = get_params();
$where[]= ['status','=',1];
if (isset($params['keywords']) && !empty($params['keywords'])){
$where[]=['title','like','%'.$params['keywords'].'%'];
}
if($this->adminInfo['position_id'] != 1){ //不是超级管理员
$www['admin_id'] = $this->adminInfo['id'];
$user_address = Db::table('fa_szxc_information_useraddress')->where($www)->find();
if ($user_address) {
if ($user_address['auth_range'] == 1) {
$where[]= ['county','=',$user_address['area_id']];
$where[] =['township','=', $user_address['street_id']];
$where[] =['village','=', $user_address['village_id']];
} elseif ($user_address['auth_range'] == 2) {
$where[]= ['county','=',$user_address['area_id']];
$where[] =['township','=', $user_address['street_id']];
}
}
}
$category_id =$params['category_id'];
if($category_id){
$map[] = ['category_id','in',$category_id];
}else{
$map = [];
}
$total = Db::table('fa_article')
->where($where)
->where($map)
->count();
$list = Db::table('fa_article')
->withAttr('nickname',function ($value,$data){
return Db::table('fa_szxc_information_usermsg')->where('user_id',$data['user_id'])->value('name');
})
->withAttr('area',function ($value,$data){
return Db::table('fa_geo_area')->where('area_code',$data['county'])->value('area_name');
})
->withAttr('street',function ($value,$data){
return Db::table('fa_geo_street')->where('street_code',$data['township'])->value('street_name');
})
->withAttr('village',function ($value,$data){
return Db::table('fa_geo_village')->where('village_id',$data['village'])->value('village_name');
})
->where($where)
->where($map)
->page($params['page'])
->limit($params['limit'])
->order('id desc')
->field('id,title,user_id,content,is_solve,county,township,village,image,view_time')
->select();
$result = ['total' => $total, 'data' => $list];
return table_assign(0, '', $result);
}
return view('nk/article/index',['url'=>$this->url]);
View::assign('url', $this->url);
return view();
}
/**
* 添加
@ -76,12 +131,30 @@ class Feedback extends BaseController
*/
public function read()
{
$params = get_params();
(new Article())->read($params);
$param= get_params();
$id = isset($param['id']) ? $param['id'] : 0;
return view('nk/article/read',['url'=>$this->url]);
$detail = Db::table('fa_article')->where('id',$id)->find();
if ($detail) {
$detail['comment'] = Db::table('fa_article_comment')
->where('vote_id',$id)
->withAttr('user_info',function ($value,$data){
return Db::table('fa_szxc_information_usermsg')->where('user_id', $data['user_id'])->value('name');
})
->select();
View::assign('detail', $detail);
View::assign('admin_id', $this->adminInfo['id']);
return view();
}else{
throw new \think\exception\HttpException(404, '找不到页面');
}
}
/**
* 修改
*/

View File

@ -62,7 +62,6 @@ class Spread extends BaseController
}
}
if ($post) {
if (isset($post['area_id']) && !empty($post['area_id'])) {
$mmm['area_id'] = $post['area_id'];

View File

@ -81,6 +81,7 @@ class Street extends BaseController
$params['address']='泸州市'.$area_code.$street_code;
$params['createtime']=time();
$params['people_num']=0;
$res=Db::table('fa_szxc_village')->strict(false)->field(true)->insertGetId($params);
if ($res){
return to_assign(0,'操作成功',['aid'=>$res]);

View File

@ -110,13 +110,13 @@ class Village extends BaseController
$village_id=Db::table('fa_geo_village')->where('village_id',$params['village_id'])->value('village_name');
$params['address']='泸州市'.$area_code.$street_code.$village_id;
$params['createtime']=time();
$params['people_num']=0;
$res=Db::table('fa_szxc_village')->strict(false)->field(true)->insertGetId($params);
if ($res){
return to_assign(0,'操作成功',['aid'=>$res]);
}
return to_assign(1, '操作失败,原因:'.$res);
}
if($this->adminInfo['position_id'] != 1){ //不是超级管理员
$www['admin_id'] = $this->adminInfo['id'];
$user_address = Db::table('fa_szxc_information_useraddress')->where($www)->find();

File diff suppressed because it is too large Load Diff

View File

@ -65,8 +65,6 @@ class Auth
*/
protected function checkAuth($controller, $pathInfo, $action, $uid)
{
return true;
//Cache::delete('RulesSrc' . $uid);
if (!Cache::get('RulesSrc' . $uid) || !Cache::get('RulesSrc0')) {
//用户所在权限组及所拥有的权限
// 执行查询

View File

@ -28,10 +28,9 @@
<script type="text/html" id="barDemo">
<div class="layui-btn-group">
{if {:session('gougu_admin')['group_access']==1}
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="read">查看</a>
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
{/if}
<a class="layui-btn layui-btn-normal layui-btn-xs {{# if(d.status != '待审核'){ }}{{# } else { }}layui-hide{{# } }}" lay-event="read">查看</a>
<a class="layui-btn layui-btn-xs {{# if(d.status == '待审核'){ }}{{# } else { }}layui-hide{{# } }}" lay-event="edit">审核</a>
</div>

View File

@ -0,0 +1,90 @@
{extend name="common/base"/}
{block name="style"}
<style type="text/css">
.editormd-code-toolbar select {
display: inline-block
}
.editormd li {
list-style: inherit;
}
.layui-td-gray{
width: 110px;
}
</style>
{/block}
<!-- 主体 -->
{block name="body"}
<form class="layui-form p-4">
<h3 class="pb-3">编辑</h3>
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray">话题标题<font>*</font></td>
<td colspan="6">
<textarea class="layui-textarea" name="title" disabled>{$detail.title}</textarea>
</td>
</tr>
<tr>
<td class="layui-td-gray">话题内容<font>*</font></td>
<td colspan="6">
<textarea class="layui-textarea" name="content" disabled>{$detail.content}</textarea>
</td>
</tr>
<tr>
<td class="layui-td-gray">状态<font>*</font></td>
<td colspan="6">
<input type="radio" name="status" value="1" title="通过" checked>
<input type="radio" name="status" value="-1" title="不通过" >
</td>
</tr>
<tr>
<td class="layui-td-gray">原因<font>*</font></td>
<td colspan="6">
<textarea class="layui-textarea" name="refusal" placeholder="请输入不通过原因"></textarea>
</td>
</tr>
</table>
<div class="pt-3">
<input type="hidden" name="id" value="{$detail.community_id}"/>
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</form>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
var moduleInit = ['tool', 'tagpicker', 'tinymce'];
function gouguInit() {
var form = layui.form, tool = layui.tool, tagpicker = layui.tagpicker,laydate = layui.laydate;
//监听提交
form.on('submit(webform)', function (data) {
let callback = function (e) {
layer.msg(e.msg);
if (e.code == 0) {
tool.sideClose(1000);
}
}
tool.post("/admin/nk.community/edit", data.field, callback);
return false;
});
//日期选择
laydate.render({
elem: '#formDate',
max: 7,
showBottom: false
});
}
</script>
{/block}
<!-- /脚本 -->

View File

@ -21,12 +21,21 @@
<script type="text/html" id="toolbarDemo">
<div class="layui-btn-container">
<span class="layui-btn layui-btn-sm" lay-event="add" data-title="添加内容">+ 添加内容</span>
<!-- <span class="layui-btn layui-btn-sm" lay-event="add" data-title="添加内容">+ 添加内容</span> -->
</div>
</script>
<script type="text/html" id="barDemo">
<div class="layui-btn-group"><a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="read">查看</a><a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a></div>
<div class="layui-btn-group">
<a class="layui-btn layui-btn-normal layui-btn-xs {{# if(d.status != 0){ }}{{# } else { }}layui-hide{{# } }}" lay-event="read">查看</a>
<a class="layui-btn layui-btn-xs {{# if(d.status == 0){ }}{{# } else { }}layui-hide{{# } }}" lay-event="edit">审核</a>
{if {:session('gougu_admin')['group_access']==1}
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
{/if}
</div>
</script>
{/block}
@ -56,6 +65,44 @@
},{
field: 'title',
title: '标题',
},{
field: 'content',
title: '内容',
},{
field: 'status',
title: '状态',
templet: function (d)
{
switch (d.status) {
case 0:
return '待审核';
break;
case 1:
return '审核通过';
break;
case -1:
return '不通过,原因:' + d.refusal;
break;
}
}
},{
field: 'is_show',
title: '显示状态',
templet: function (d)
{
switch (d.is_show) {
case 0:
return '不显示';
break;
case 1:
return '显示';
break;
}
}
},{
fixed: 'right',
field: 'right',

View File

@ -0,0 +1,221 @@
{extend name="common/base"/}
{block name="style"}
<style type="text/css">
.editormd-code-toolbar select {display: inline-block}
.editormd li {list-style: inherit;}
</style>
{/block}
<!-- 主体 -->
{block name="body"}
<form class="layui-form p-4">
<h3 class="pb-3">新建文章</h3>
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray">文章标题<font>*</font></td>
<td colspan="7"><input type="text" name="title" lay-verify="required" lay-reqText="请输入文章标题"
autocomplete="off" placeholder="请输入文章标题" class="layui-input"></td>
</tr>
{notempty name="is_vote"}
<tr>
<td class="layui-td-gray">结束时间<font>*</font></td>
<td colspan="7"> <input type="text" placeholder="yyyy-MM-dd" autocomplete="off" class="layui-input" id="test1" name="end_time">
<input type="hidden" name="is_vote" value="1">
</td>
</tr>
{/notempty}
<tr>
<td class="layui-td-gray" style="vertical-align:top;">文章摘要</td>
<td colspan="3">
<textarea name="describe" placeholder="请输入摘要不能超过200个字" class="layui-textarea"></textarea>
</td>
<td class="layui-td-gray" style="vertical-align:top;">缩略图</td>
<td>
<div class="layui-upload">
<button type="button" class="layui-btn layui-btn-sm" id="upload_btn_thumb">上传缩略图(尺寸:640x360)</button>
<div class="layui-upload-list" id="upload_box_thumb" style="width: 120px; height:66px; overflow: hidden;">
<img src="" onerror="javascript:this.src='{__GOUGU__}/gougu/images/nonepic600x360.jpg';this.onerror=null;" width="100" style="max-width: 100%; height:66px;"/>
<input type="hidden" name="image" value="">
</div>
</div>
</td>
</tr>
{if {:session('gougu_admin')['group_access']==1}
<tr>
<td class="layui-td-gray" style="vertical-align:top;">区县</td>
<td colspan="3">
<div class="layui-col-md6">
<div >
<select name="county" lay-filter="area_id" >
{volist name='street' id='vo'}
<option value="{$vo.code}" >{$vo.name}</option>
{/volist}
</select>
</div>
</div>
</td>
</tr>
<tr>
<td class="layui-td-gray" style="vertical-align:top;">街道/镇</td>
<td colspan="3">
<div class="layui-col-md6">
<div >
<div id="demo1" ></div>
</div>
</div>
</td>
</tr>
<tr>
<td class="layui-td-gray" style="vertical-align:top;">村/社区</td>
<td colspan="3">
<div class="layui-col-md6">
<div >
<div id="demo2" ></div>
</div>
</div>
</td>
</tr>
<tr>
<td class="layui-td-gray">用户<font>*</font></td>
<td colspan="3">
<div class="layui-col-md6">
<select name="user_id" lay-verify="required" lay-search="">
<option value="" >请选择</option>
{volist name='users' id='vo'}
<option value="{$vo.user_id}" >{$vo.name}</option>
{/volist}
</select>
</div>
</td>
</tr>
{/if}
<tr>
<td colspan="6" class="layui-td-gray" style="text-align:left">文章内容</td>
</tr>
<tr>
<td colspan="6">
<textarea class="layui-textarea" id="container_content"></textarea>
</td>
</tr>
</table>
<div class="pt-3">
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</form>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script src="/static/assets/js/xm-select.js"></script>
<script>
const editorType = '{$editor}';
var moduleInit = ['tool', 'tagpicker', 'tinymce'];
var group_access = "{:session('gougu_admin')['group_access']}"
function gouguInit() {
var form =layui.form, tool = layui.tool,tagspicker = layui.tagpicker,laydate=layui.laydate;
laydate.render({
elem: '#test1' //指定元素
});
//上传缩略图
var upload_thumb = layui.upload.render({
elem: '#upload_btn_thumb',
url: '/admin/api/upload',
done: function (res) {
//如果上传失败
if (res.code == 1) {
return layer.msg('上传失败');
}
//上传成功
$('#upload_box_thumb input').attr('value', res.data.filepath);
$('#upload_box_thumb img').attr('src', res.data.filepath);
}
});
street();
village();
form.on('select(area_id)', function (data) {
street(data.value)
});
function street (id) {
var demo1 = xmSelect.render({
name: 'township',
el: '#demo1',
initValue: [],
prop: {
name: 'name',
value: 'code',
},
data: [],
radio: true,
disabled: group_access == 2 ||group_access == 4? true : false,
on: function (data) {
var arr = data.arr;
if(arr.length > 0){
village(arr[0]['code']);
}else{
village();
}
},
})
$.get('/api/geo/street?pcode=' + id, function (result) {
demo1.update({
data: result.data
})
});
}
function village (id) {
var demo2 = xmSelect.render({
name: 'village',
el: '#demo2',
initValue: [],
prop: {
name: 'name',
value: 'id',
},
data: [],
radio: true,
disabled: group_access == 2 ? true : false,
})
$.get('/api/geo/village?pcode=' + id, function (result) {
demo2.update({
data: result.data
})
});
}
var editor = layui.tinymce;
var edit = editor.render({
selector: "#container_content",
height: 500
});
//监听提交
form.on('submit(webform)', function (data) {
data.field.content = tinyMCE.editors['container_content'].getContent();
if (data.field.content == '') {
layer.msg('请先完善文章内容');
return false;
}
let callback = function (e) {
layer.msg(e.msg);
if (e.code == 0) {
tool.tabRefresh(71);
tool.sideClose(1000);
}
}
tool.post('{$url[1]}', data.field, callback);
return false;
});
}
</script>
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,240 @@
{extend name="common/base"/}
{block name="style"}
<style type="text/css">
.editormd-code-toolbar select {
display: inline-block
}
.editormd li {
list-style: inherit;
}
</style>
{/block}
<!-- 主体 -->
{block name="body"}
<form class="layui-form p-4">
<h3 class="pb-3">编辑文章表</h3>
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray">文章标题<font>*</font></td>
<td colspan="7"><input type="text" name="title" lay-verify="required" lay-reqText="请输入文章标题"
autocomplete="off" placeholder="请输入文章标题" class="layui-input"
value="{$detail.title}"></td>
</tr>
{notempty name="is_vote"}
<tr>
<td class="layui-td-gray">结束时间<font>*</font></td>
<td colspan="7"> <input type="text" placeholder="yyyy-MM-dd" autocomplete="off" class="layui-input" id="test1" name="end_time">
<input type="hidden" name="is_vote" value="1">
</td>
</tr>
{/notempty}
<tr>
<td class="layui-td-gray" style="vertical-align:top;">摘要</td>
<td colspan="3">
<textarea name="describe" placeholder="请输入摘要不能超过200个字"
class="layui-textarea">{$detail.describe}</textarea>
</td>
<td class="layui-td-gray" style="vertical-align:top;">缩略图</td>
<td>
<div class="layui-upload">
<button type="button" class="layui-btn layui-btn-sm" id="upload_btn_thumb">
上传缩略图(尺寸:640x360)
</button>
<div class="layui-upload-list" id="upload_box_thumb"
style="width: 120px; height:66px; overflow: hidden;">
<img src="{$detail.image}"
onerror="javascript:this.src='{__GOUGU__}/gougu/images/nonepic600x360.jpg';this.onerror=null;"
style="max-width: 100%; height:66px;"/>
<input type="hidden" name="image" value="{$detail.image}">
</div>
</div>
</td>
</tr>
{if {:session('gougu_admin')['group_access']==1}
<tr>
<td class="layui-td-gray" style="vertical-align:top;">区县</td>
<td colspan="3">
<div class="layui-col-md6">
<div >
<select name="county" lay-filter="area_id">
{volist name='street' id='vo'}
<option value="{$vo.code}" {if $detail.county==$vo.code} selected {/if}>{$vo.name}</option>
{/volist}
</select>
</div>
</div>
</td>
</tr>
<tr>
<td class="layui-td-gray" style="vertical-align:top;">街道/镇</td>
<td colspan="3">
<div class="layui-col-md6">
<div >
<div id="demo1" ></div>
</div>
</div>
</td>
</tr>
<tr>
<td class="layui-td-gray" style="vertical-align:top;">村/社区</td>
<td colspan="3">
<div class="layui-col-md6">
<div >
<div id="demo2" ></div>
</div>
</div>
</td>
</tr>
<tr>
<td class="layui-td-gray">用户<font>*</font></td>
<td colspan="3">
<div class="layui-col-md6">
<select name="user_id" lay-verify="required" lay-search="">
<option value="" >请选择</option>
{volist name='users' id='vo'}
<option value="{$vo.user_id}" {if $detail.user_id==$vo.user_id} selected {/if}>{$vo.name}</option>
{/volist}
</select>
</div>
</td>
</tr>
{/if}
<tr>
<td colspan="6" class="layui-td-gray" style="text-align:left">文章内容</td>
</tr>
<tr>
<td colspan="6">
<textarea placeholder="请输入内容" class="layui-textarea"
id="container_content">{$detail.content}</textarea>
</td>
</tr>
</table>
<div class="pt-3">
<input type="hidden" name="id" value="{$detail.id}"/>
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</form>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script src="/static/assets/js/xm-select.js"></script>
<script>
const editorType = '{$editor}';
var moduleInit;
if (editorType == 1) {
moduleInit = ['tool', 'tagpicker', 'tinymce'];
} else {
moduleInit = ['tool', 'tagpicker', 'editormd'];
}
var group_access = "{:session('gougu_admin')['group_access']}";
var area_id = "{$detail.county}";
var street_id = "{$detail.township}";
function gouguInit() {
var form =layui.form, tool = layui.tool,tagspicker = layui.tagpicker,laydate=layui.laydate;
laydate.render({
elem: '#test1' //指定元素
});
//上传缩略图
var upload_thumb = layui.upload.render({
elem: '#upload_btn_thumb',
url: '/admin/api/upload',
done: function (res) {
//如果上传失败
if (res.code == 1) {
layer.msg('上传失败');
return false;
}
//上传成功
$('#upload_box_thumb input').attr('value', res.data.filepath);
$('#upload_box_thumb img').attr('src', res.data.filepath);
}
});
if (area_id != 0) {
street(area_id)
}
if (street_id != 0) {
village(street_id)
}
form.on('select(area_id)', function (data) {
street(data.value)
});
function street (id) {
var demo1 = xmSelect.render({
name: 'township',
el: '#demo1',
initValue: ["{$detail.township}"],
prop: {
name: 'name',
value: 'code',
},
data: [],
radio: true,
disabled: group_access == 2 ||group_access == 4? true : false,
on: function (data) {
var arr = data.arr;
if(arr.length > 0){
village(arr[0]['code']);
}else{
village();
}
},
})
$.get('/api/geo/street?pcode=' + id, function (result) {
demo1.update({
data: result.data
})
});
}
function village (id) {
var demo2 = xmSelect.render({
name: 'village',
el: '#demo2',
initValue: ["{$detail.village}"],
prop: {
name: 'name',
value: 'id',
},
data: [],
radio: true,
disabled: group_access == 2 ? true : false,
})
$.get('/api/geo/village?pcode=' + id, function (result) {
demo2.update({
data: result.data
})
});
}
var editor = layui.tinymce;
var edit = editor.render({
selector: "#container_content",
height: 500
});
//监听提交
form.on('submit(webform)', function (data) {
data.field.content = tinyMCE.editors['container_content'].getContent();
if (data.field.content == '') {
layer.msg('请先完善文章内容');
return false;
}
let callback = function (e) {
layer.msg(e.msg);
if (e.code == 0) {
tool.sideClose(1000);
}
}
tool.post("{$url[2]}", data.field, callback);
return false;
});
}
</script>
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,178 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<div class="p-3">
<form class="layui-form gg-form-bar border-t border-x">
<div class="layui-input-inline" style="width:300px;">
<input type="text" name="keywords" placeholder="请输入标题" class="layui-input" autocomplete="off" />
</div>
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="searchform">提交搜索</button>
</form>
<table class="layui-hide" id="article" lay-filter="article"></table>
</div>
<script type="text/html" id="status">
<i class="layui-icon {{# if(d.status == 1){ }}layui-icon-ok{{# } else { }}layui-icon-close{{# } }}"></i>
</script>
<script type="text/html" id="is_home">
<i class="layui-icon {{# if(d.is_home == 1){ }}layui-icon-ok{{# } else { }}layui-icon-close{{# } }}"></i>
</script>
<script type="text/html" id="toolbarDemo">
<div class="layui-btn-container">
<!-- <span class="layui-btn layui-btn-sm" lay-event="add" data-title="添加内容">+ 添加内容</span> -->
</div>
</script>
<script type="text/html" id="barDemo">
<div class="layui-btn-group">
<a class="layui-btn layui-btn-normal layui-btn-xs {{# if(d.is_solve == 0){ }}{{# } else { }}layui-hide{{# } }}" lay-event="read">回复</a>
<a class="layui-btn layui-btn-green layui-btn-xs {{# if(d.is_solve != 0){ }}{{# } else { }}layui-hide{{# } }}" lay-event="read">查看</a>
<!-- <a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a> -->
{if {:session('gougu_admin')['group_access']==1}
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
{/if}
</div>
</script>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
const moduleInit = ['tool'];
function gouguInit() {
var table = layui.table,tool = layui.tool, form = layui.form;
layui.pageTable = table.render({
elem: '#article',
title: '文章表列表',
toolbar: '#toolbarDemo',
url: '{$url[0]}',
page: true,
limit: 20,
cols: [
[
{
fixed: 'left',
field: 'id',
title: '编号',
align: 'center',
width:120,
},{
field: 'area',
title: '区县',
align: 'center',
width:120,
},{
field: 'street',
title: '乡镇',
align: 'center',
width:120,
},{
field: 'village',
title: '街道/村',
align: 'center',
width:120,
},{
field: 'is_solve',
title: '状态',
align: 'center',
width:120,
templet: function (d)
{
switch (d.is_solve) {
case 0:
return '待回复';
break;
case 1:
return '已回复';
break;
}
return ;
}
},{
field: 'title',
title: '文章标题',
},{
field: 'content',
title: '诉求内容',
templet: function (d)
{
return d.content;
}
},{
field: 'nickname',
title: '用户',
align: 'center',
},{
field: 'view_time',
title: '发布时间',
align: 'center',
},{
fixed: 'right',
field: 'right',
title: '操作',
toolbar: '#barDemo',
align: 'center'
}
]
]
});
//监听表头工具栏事件
table.on('toolbar(article)', function(obj){
if (obj.event === 'add') {
tool.side('{$url[1]}');
return false;
}
});
//监听表格行工具事件
table.on('tool(article)', function(obj) {
var data = obj.data;
if (obj.event === 'read') {
tool.side('{$url[4]}?id='+obj.data.id);
}
else if (obj.event === 'edit') {
tool.side('{$url[2]}?id='+obj.data.id);
}
else if (obj.event === 'del') {
layer.confirm('确定要删除该记录吗?', {
icon: 3,
title: '提示'
}, function(index) {
let callback = function (e) {
layer.msg(e.msg);
if (e.code == 0) {
obj.del();
}
}
tool.delete('{$url[3]}', { id: data.id }, callback);
layer.close(index);
});
}
return false;
});
//监听搜索提交
form.on('submit(searchform)', function(data) {
layui.pageTable.reload({
where: {
keywords: data.field.keywords,
cate_id: data.field.cate_id
},
page: {
curr: 1
}
});
return false;
});
}
</script>
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,87 @@
{extend name="common/base"/}
{block name="style"}
<style>
.content-article img{max-width:88%!important; height:auto!important; margin:6px 0!important; border-radius:4px;}
</style>
{/block}
<!-- 主体 -->
{block name="body"}
<div class="layui-form p-4">
<h3 class="pb-3">诉求详情</h3>
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray">诉求</td>
<td colspan="3">{$detail.title}</td>
</tr>
<tr>
<td class="layui-td-gray">创建时间</td>
<td>{$detail.view_time}</td>
</tr>
<tr>
<td class="layui-td-gray">诉求内容</td>
<td colspan="5" class="content-article">
{$detail.content|raw}
</td>
</tr>
{if in_array($detail.category_id,[149,157,158,148,147,165]) }
<tr >
<td class="layui-td-gray">回复内容:</td>
<td colspan="6">
{volist name="$detail.comment" id="vo"}
{$vo.user_info}的回复:{$vo.content}<br>
{/volist}
</td>
</tr>
{/if}
{if $detail.is_solve == 0}
{if in_array($detail.category_id,[149,157,158,148,147,165]) }
<tr >
<td class="layui-td-gray">回复:</td>
<td colspan="6">
<textarea class="layui-textarea" name="reply" ></textarea>
</td>
</tr>
{/if}
</table>
{if in_array($detail.category_id,[149,157,158,148,147,165]) }
<div class="pt-3">
<input type="hidden" name="id" value="{$detail.id}"/>
<input type="hidden" name="admin_id" value="{$admin_id}"/>
<input type="hidden" name="content" value="{$detail.content}"/>
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即回复</button>
</div>
{/if}
{/if}
</div>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
var moduleInit = ['tool', 'tagpicker', 'tinymce'];
function gouguInit() {
var form = layui.form, tool = layui.tool, tagpicker = layui.tagpicker,laydate = layui.laydate;
//监听提交
form.on('submit(webform)', function (data) {
let callback = function (e) {
layer.msg(e.msg);
if (e.code == 0) {
tool.sideClose(1000);
}
}
tool.post("/admin/api/reply", data.field, callback);
return false;
});
}
</script>
{/block}
<!-- /脚本 -->

View File

@ -22,11 +22,7 @@
</tr>
<tr>
<td class="layui-td-gray">人数<font>*</font></td>
<td colspan="3">
<input type="text" name="people_num" lay-verify="required" lay-reqText="请输入人数"
autocomplete="off" placeholder="请输入人数" class="layui-input"></td>
<td class="layui-td-gray">标签(多选)<font>*</font></td>
<td class="layui-td-gray">标签</td>
<td>
<input type="checkbox" name="is_hot" title="热门">
<input type="checkbox" name="is_tourism" title="文旅">

View File

@ -22,11 +22,7 @@
</tr>
<tr>
<td class="layui-td-gray">人数<font>*</font></td>
<td colspan="3">
<input type="text" name="people_num" lay-verify="required" lay-reqText="请输入人数"
autocomplete="off" placeholder="请输入人数" class="layui-input" value="{$detail.people_num}"></td>
<td class="layui-td-gray">标签(多选)<font>*</font></td>
<td class="layui-td-gray">标签</td>
<td>
<input type="checkbox" name="is_hot" title="热门" {if $detail.is_hot==1} checked {/if}>
<input type="checkbox" name="is_tourism" title="文旅" {if $detail.is_tourism==1} checked {/if}>

View File

@ -19,8 +19,8 @@
<td colspan="3">{$detail.people_num}</td>
<td class="layui-td-gray">标签(多选)<font>*</font></td>
<td>
<input type="checkbox" name="is_hot" title="热门" {if $detail.is_hot==1} checked {/if}>
<input type="checkbox" name="is_tourism" title="文旅" {if $detail.is_tourism==1} checked {/if>
<input type="checkbox" name="is_hot" title="热门" {if $detail.is_hot==1} checked {/if} >
<input type="checkbox" name="is_tourism" title="文旅" {if $detail.is_tourism==1} checked {/if}>
</td>
</tr>
<tr>

View File

@ -22,11 +22,7 @@
</tr>
<tr>
<td class="layui-td-gray">人数<font>*</font></td>
<td colspan="3">
<input type="text" name="people_num" lay-verify="required" lay-reqText="请输入人数"
autocomplete="off" placeholder="请输入人数" class="layui-input"></td>
<td class="layui-td-gray">标签(多选)<font>*</font></td>
<td class="layui-td-gray">标签(多选)</td>
<td>
<input type="checkbox" name="is_hot" title="热门">
<input type="checkbox" name="is_tourism" title="文旅">
@ -114,8 +110,8 @@
const editorType = '{$editor}';
var moduleInit = ['tool', 'tagpicker', 'tinymce'];
var group_access = "{:session('gougu_admin')['group_access']}"
var area_id = "{$detail.area_id}"
var street_id = "{$detail.street_id}"
var area_id = "{$detail.area_id|default=0}"
var street_id = "{$detail.street_id|default=0}"
var admin_id = "{$admin_id}"
function gouguInit() {
var form = layui.form, tool = layui.tool, tagspicker = layui.tagpicker;
@ -148,7 +144,7 @@
var demo1 = xmSelect.render({
name: 'street_id',
el: '#demo1',
initValue: group_access == 2 ||group_access == 4? ["{$detail.street_id}"] : [],
initValue: group_access == 2 ||group_access == 4? ["{$detail.street_id|default=0}"] : [],
prop: {
name: 'name',
value: 'code',

View File

@ -22,10 +22,6 @@
</tr>
<tr>
<td class="layui-td-gray">人数<font>*</font></td>
<td colspan="3">
<input type="text" name="people_num" lay-verify="required" lay-reqText="请输入人数"
autocomplete="off" placeholder="请输入人数" class="layui-input" value="{$detail.people_num}"></td>
<td class="layui-td-gray">标签(多选)<font>*</font></td>
<td>
<input type="checkbox" name="is_hot" title="热门" {if $detail.is_hot==1} checked {/if}>

View File

@ -20,7 +20,7 @@
<td class="layui-td-gray">标签(多选)<font>*</font></td>
<td>
<input type="checkbox" name="is_hot" title="热门" {if $detail.is_hot==1} checked {/if}>
<input type="checkbox" name="is_tourism" title="文旅" {if $detail.is_tourism==1} checked {/if>
<input type="checkbox" name="is_tourism" title="文旅" {if $detail.is_tourism==1} checked {/if}>
</td>
</tr>
<tr>

View File

@ -0,0 +1,471 @@
{extend name="common/base"/}
{block name="style"}
<style type="text/css">
.editormd-code-toolbar select {
display: inline-block
}
.editormd li {
list-style: inherit;
}
</style>
{/block}
<!-- 主体 -->
{block name="body"}
<form class="layui-form p-4">
<h3 class="pb-3">添加</h3>
<div class="layui-tab layui-tab-brief">
<ul class="layui-tab-title">
<li class="layui-this">商品信息</li>
<li>规格设置</li>
<li>商品详情</li>
<li>营销设置</li>
<li>其他设置</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray">商品名称<font>*</font>
</td>
<td colspan="7"><input type="text" name="store_name" lay-verify="required" lay-reqText="请输入商品名称"
autocomplete="off" placeholder="请输入商品名称" class="layui-input"></td>
</tr>
<tr>
<td class="layui-td-gray">平台商品分类<font>*</font>
</td>
<td>
<div id="cate_id"></div>
</td>
<td class="layui-td-gray">品牌选择<font>*</font>
</td>
<td colspan="6">
<select name="brand_id" lay-verify="required" lay-search="">
<option value="">请选择</option>
{volist name='store_brand' id='vo'}
<option value="{$vo.brand_id}">{$vo.brand_name}</option>
{/volist}
</select>
</td>
</tr>
<tr>
<td class="layui-td-gray">商户分类<font>*</font>
</td>
<td colspan="3">
<div id="mer_cate_id"></div>
</td>
</tr>
<tr>
<td class="layui-td-gray" style="vertical-align:top;">商品封面图</td>
<td colspan="12">
<div class="layui-upload">
<button type="button" class="layui-btn layui-btn-sm" id="upload_btn_thumb">
上传缩略图(尺寸:750x750)
</button>
<div class="layui-upload-list" id="upload_box_thumb" style=" overflow: hidden;">
<img src=""
onerror="javascript:this.src='{__GOUGU__}/gougu/images/nonepic600x360.jpg';this.onerror=null;"
width="100" style="max-width: 100%; height:66px;" />
<input type="hidden" name="image" value="">
</div>
</div>
</td>
</tr>
<tr>
<td class="layui-td-gray" style="vertical-align:top;">商品轮播图</td>
<td colspan="12">
<div class="layui-upload">
<button type="button" class="layui-btn layui-btn-sm" id="upload_btn_thumb2">
上传商品轮播图
</button>
<div class="layui-upload-list" id="upload_box_thumb2" style="overflow: hidden;">
<input type="hidden" name="slider_image" value="">
</div>
</div>
</td>
</tr>
<!-- <tr>
<td class="layui-td-gray">主图视频:<font>*</font>
</td>
<td colspan="7">video_link</td>
</tr> -->
<tr>
<td class="layui-td-gray">单位<font>*</font>
</td>
<td colspan="7"><input type="text" name="unit_name" lay-verify="required" lay-reqText="请输入单位"
autocomplete="off" placeholder="请输入单位" class="layui-input"></td>
</tr>
<tr>
<td class="layui-td-gray">商品关键字<font>*</font>
</td>
<td colspan="7"><input type="text" name="keyword" lay-verify="required" lay-reqText="请输入商品关键字"
autocomplete="off" placeholder="请输入商品关键字" class="layui-input"></td>
</tr>
<tr>
<td class="layui-td-gray" style="text-align:left">商品简介</td>
<td colspan="6">
<textarea class="layui-textarea" name="store_info"></textarea>
</td>
</tr>
<!-- <tr>
<td class="layui-td-gray">优惠券:<font>*</font>
</td>
<td colspan="7">couponData</td>
</tr> -->
</table>
</div>
<div class="layui-tab-item">
<table class="layui-table layui-table-form">
<!-- <tr>
<td class="layui-td-gray" style="background-color: #fff;width: 92px;">佣金设置</td>
<td colspan="6">
<input type="radio" name="status" value="1" title="单独设置">
<input type="radio" name="status" value="0" title="默认设置" checked>
</td>
</tr> -->
<!-- <tr>
<td class="layui-td-gray" style="text-align:left">付费会员价设置</td>
<td colspan="6">
</td>
</tr> -->
<tr>
<td colspan="6">
<!-- 规格类型 -->
<div id="fairy-is-attribute"></div>
<!--商品规格表-->
<div id="fairy-spec-table"></div>
<div id="fairy-sku-table"></div>
</td>
</tr>
</table>
</div>
<div class="layui-tab-item">
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray" style="text-align:left">商品详情</td>
<td colspan="6">
<textarea class="layui-textarea" id="container_content"></textarea>
</td>
</tr>
</table>
</div>
<div class="layui-tab-item">
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray" style="text-align:left">商品推荐</td>
<td colspan="6">
<input type="checkbox" name="is_good" title="店铺推荐" value="1">
</td>
</tr>
</table>
</div>
<div class="layui-tab-item">
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray" style="text-align:left">送货方式</td>
<td colspan="6">
<input type="checkbox" name="delivery_way[]" title="到店自提" value="1">
<input type="checkbox" name="delivery_way[]" title="快递配送" value="2">
</td>
<td class="layui-td-gray" style="text-align:left">是否包邮</td>
<td colspan="6">
<input type="radio" name="delivery_free" value="1" title="是"checked>
<input type="radio" name="delivery_free" value="0" title="否" >
</td>
</tr>
<!-- <tr>
<td class="layui-td-gray" style="text-align:left">运费模板</td>
<td colspan="6">
</td>
</tr> -->
<tr>
<td class="layui-td-gray" style="text-align:left">最少购买件数</td>
<td colspan="6">
<input type="text" name="once_min_count" lay-verify="required" lay-reqText="默认为0则不限制购买件数"
autocomplete="off" placeholder="默认为0则不限制购买件数" class="layui-input" value="0">
</td>
<td class="layui-td-gray" style="text-align:left">排序</td>
<td colspan="6">
<input type="text" name="sort" lay-verify="required" lay-reqText="默认为0则不限制购买件数"
autocomplete="off" placeholder="默认为0则不限制购买件数" class="layui-input" value="0">
</td>
</tr>
<!-- <tr>
<td class="layui-td-gray" style="text-align:left">限购类型</td>
<td colspan="6">
<input type="radio" name="pay_limit" value="0" title="不限购"checked>
<input type="radio" name="pay_limit" value="1" title="单次限购" >
<input type="radio" name="pay_limit" value="2" title="长期限购" >
</td>
</tr> -->
<!-- <tr>
<td class="layui-td-gray" style="text-align:left">平台保障服务</td>
<td colspan="6">
</td>
</tr>
<tr>
<td class="layui-td-gray" style="text-align:left">商品参数</td>
<td colspan="6">
</td>
</tr> -->
</table>
</div>
</div>
</div>
<div class="pt-3">
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</form>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script src="/static/assets/js/xm-select.js"></script>
<script>
var moduleInit = ['tool', 'tagpicker', 'tinymce','skuTable'];
var group_access = "{:session('gougu_admin')['group_access']}"
var multiple_images = [];
//单击图片删除图片 【注册全局函数】
function delMultipleImgs (this_img) {
//获取下标
var subscript = $("#upload_box_thumb2 img").index(this_img);
//删除图片
this_img.remove();
//删除数组
multiple_images.splice(subscript, 1);
//重新排序
multiple_images.sort();
$('#upload_box_thumb2 input').attr('value', multiple_images);
//返回
return;
}
function gouguInit () {
var form = layui.form, tool = layui.tool, tagspicker = layui.tagpicker, element = layui.element,skuTable = layui.skuTable,server=layui.server,laySku=layui.laySku,$ = layui.$;;
function demo1 (id) {
var demo1 = xmSelect.render({
name: 'street_id',
el: '#demo1',
initValue: [street_id],
prop: {
name: 'name',
value: 'code',
},
data: [],
radio: true,
disabled: group_access == 2 || group_access == 4 ? true : false,
on: function (data) {
var arr = data.arr;
village(arr[0]['code'])
},
})
$.get('/api/geo/street?pcode=' + id, function (result) {
demo1.update({
data: result.data
})
});
}
function demo_cate_id () {
var demo_cate = xmSelect.render({
name: 'cate_id',
el: '#cate_id',
autoRow: true,
radio: true,
cascader: {
show: true,
indent: 200,
},
prop: {
name: 'name',
value: 'id',
},
data: [],
})
$.get('/admin/product.product/category_arr', function (result) {
demo_cate.update({
data: result.data
})
});
}
demo_cate_id()
function demo_mer_cate_id () {
var demo_cate = xmSelect.render({
name: 'mer_cate_id',
el: '#mer_cate_id',
autoRow: true,
cascader: {
show: true,
indent: 200,
},
prop: {
name: 'name',
value: 'id',
},
data: [],
radio: true,
})
$.get('/admin/product.product/category_arr?id=4', function (result) {
demo_cate.update({
data: result.data
})
});
}
demo_mer_cate_id();
var obj = skuTable.render({
//规格类型 0统一规格 1多规格
isAttributeValue: 0,
//规格类型容器id
isAttributeElemId: 'fairy-is-attribute',
//规格表容器id
specTableElemId: 'fairy-spec-table',
//sku表容器id
skuTableElemId: 'fairy-sku-table',
//规格拖拽排序
sortable: true,
//sku表相同属性值是否合并行
rowspan: false,
//请求成功返回状态码值
requestSuccessCode: 200,
//上传接口地址
//接口要求返回格式为 {"code": 200, "data": {"url": "xxx"}, "msg": ""}
uploadUrl: '/admin/api/upload2',
//统一规格配置项
singleSkuTableConfig: {
thead: [
{title: '销售价(元)', icon: 'layui-icon-cols'},
{title: '市场价(元)', icon: 'layui-icon-cols'},
{title: '成本价(元)', icon: 'layui-icon-cols'},
{title: '库存', icon: 'layui-icon-cols'},
{title: '商品编号', icon: 'layui-icon-cols'},
{title: '重量', icon: 'layui-icon-cols'},
{title: '体积', icon: 'layui-icon-cols'},
// {title: '状态', icon: ''},extension_one extension_two svip_price
],
tbody: [
{type: 'input', field: 'price', value: '', verify: 'required|number', reqtext: '销售价不能为空'},
{type: 'input', field: 'ot_price', value: '0', verify: 'required|number', reqtext: '市场价不能为空'},
{type: 'input', field: 'cost', value: '0', verify: 'required|number', reqtext: '成本价不能为空'},
{type: 'input', field: 'stock', value: '0', verify: 'required|number', reqtext: '库存不能为空'},
{type: 'input', field: 'bar_code', value: '', },
{type: 'input', field: 'weight', value: '0', verify: 'required|number', reqtext: '重量不能为空'},
{type: 'input', field: 'volume', value: '0', verify: 'required|number', reqtext: '体积不能为空'},
// {type: 'select', field: 'status', option: [{key: '启用', value: '1'}, {key: '禁用', value: '0'}], verify: 'required', reqtext: '状态不能为空'},
]
},
//多规格配置项
multipleSkuTableConfig: {
thead: [
{title: '图片', icon: ''},
{title: '销售价(元)', icon: 'layui-icon-cols'},
{title: '市场价(元)', icon: 'layui-icon-cols'},
{title: '成本价(元)', icon: 'layui-icon-cols'},
{title: '库存', icon: 'layui-icon-cols'},
{title: '商品编号', icon: 'layui-icon-cols'},
{title: '重量', icon: 'layui-icon-cols'},
{title: '体积', icon: 'layui-icon-cols'},
],
tbody: [
{type: 'image', field: 'image', value: '', verify: '', reqtext: ''},
{type: 'input', field: 'price', value: '', verify: 'required|number', reqtext: '销售价不能为空'},
{type: 'input', field: 'ot_price', value: '0', verify: 'required|number', reqtext: '市场价不能为空'},
{type: 'input', field: 'cost', value: '0', verify: 'required|number', reqtext: '成本价不能为空'},
{type: 'input', field: 'stock', value: '0', verify: 'required|number', reqtext: '库存不能为空'},
{type: 'input', field: 'bar_code', value: '', },
{type: 'input', field: 'weight', value: '0', verify: 'required|number', reqtext: '重量不能为空'},
{type: 'input', field: 'volume', value: '0', verify: 'required|number', reqtext: '体积不能为空'},
]
},
//商品id 配合specDataUrl和skuDataUrl使用
productId: '',
//规格数据, 一般从后台获取
specData: [],
});
//上传缩略图
var upload_thumb = layui.upload.render({
elem: '#upload_btn_thumb',
url: '/admin/api/upload',
done: function (res) {
//如果上传失败
if (res.code == 1) {
return layer.msg('上传失败');
}
//上传成功
$('#upload_box_thumb input').attr('value', res.data.filepath);
$('#upload_box_thumb img').attr('src', res.data.filepath);
}
});
//上传商品轮播图
var upload_thumb = layui.upload.render({
elem: '#upload_btn_thumb2',
url: '/admin/api/upload',
multiple: true,
before: function (obj) {
//预读本地文件示例不支持ie8
obj.preview(function (index, file, result) {
$('#upload_box_thumb2').append(`
<img src="${result}"
onerror="javascript:this.src='{__GOUGU__}/gougu/images/nonepic600x360.jpg';this.onerror=null;"
width="100" style="max-width: 100%; height:66px;" alt="${file.name}" onclick="delMultipleImgs(this)" title="点击删除"/>
`)
});
},
done: function (res) {
//如果上传失败
if (res.code == 1) {
return layer.msg('上传失败');
}
//上传成功
//追加图片成功追加文件名至图片容器
multiple_images.push(res.data.filepath);
$('#upload_box_thumb2 input').attr('value', multiple_images);
// $('#upload_box_thumb2 img').attr('src', res.data.filepath);
}
});
var editor = layui.tinymce;
var edit = editor.render({
selector: "#container_content",
height: 500
});
//监听提交
form.on('submit(webform)', function (data) {
data.field.content = tinyMCE.editors['container_content'].getContent();
if (data.field.content == '') {
layer.msg('请先完善商品详情');
return false;
}
let callback = function (e) {
layer.msg(e.msg);
if (e.code == 0) {
tool.tabRefresh(71);
tool.sideClose(1000);
}
}
tool.post('/admin/product.product/add', data.field, callback);
return false;
});
}
</script>
{/block}
<!-- /脚本 -->

View File

@ -8,79 +8,231 @@
.editormd li {
list-style: inherit;
}
.layui-td-gray{
width: 110px;
}
.addrhelper-ok-btn{
display: none;
}
</style>
{/block}
<!-- 主体 -->
{block name="body"}
<form class="layui-form p-4">
<input type="hidden" name="id" value="{$detail.store_category_id}">
<h3 class="pb-3">编辑</h3>
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray">选择商户</td>
<td colspan="4">
<div class="layui-col-md4">
<select lay-filter="merchant" lay-search>
<option value="" >上级分类</option>
{volist name='merchant' id='vo'}
<option id="merchant{$vo.mer_id}" value="{$vo.mer_id}" >{$vo.real_name}</option>
{/volist}
</select>
</div>
</td>
</tr>
<tr>
<td>
<div class="layui-col-md4" id="address"></div>
</td>
</tr>
<tr>
<td colspan="4">
<div class="layui-col-md4">
<label class="layui-form-label">分类名称<font>*</font></label>
<div class="layui-input-block">
<input type="text" name="title" required lay-verify="required" value="{$detail.cate_name}" placeholder="请输入团队名称" autocomplete="off" class="layui-input">
</div>
</div>
</td>
<td>
<div class="layui-upload">
<button type="button" class="layui-btn layui-btn-sm" id="upload_btn_thumb">上传分类图片(尺寸:110x110)</button>
<div class="layui-upload-list" id="upload_box_thumb" style="width: 120px; height:66px; overflow: hidden;">
<img src="{$detail.pic}" onerror="javascript:this.src='{__GOUGU__}/gougu/images/nonepic600x360.jpg';this.onerror=null;" width="100" style="max-width: 100%; height:66px;"/>
<input type="hidden" name="avatar" value="">
</div>
</div>
</td>
</tr>
<div class="layui-tab layui-tab-brief">
<tr>
<td colspan="4">
<div class="layui-form-item">
<label class="layui-form-label">是否显示</label>
<div class="layui-input-block">
<input type="checkbox" name="is_show" lay-skin="switch" {$detail.is_show?'checked':''}>
</div>
</div>
</td>
<td colspan="4">
<div class="layui-col-md4">
<label class="layui-form-label">排序<font>*</font></label>
<div class="layui-input-block">
<input type="text" name="sort" required lay-verify="required" value="{$detail.sort}" autocomplete="off" class="layui-input">
</div>
</div>
</td>
</tr>
<ul class="layui-tab-title">
<li class="layui-this">商品信息</li>
<li>规格设置</li>
<li>商品详情</li>
<li>营销设置</li>
<li>其他设置</li>
</ul>
</table>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray">商品名称<font>*</font>
</td>
<td colspan="7"><input type="text" name="store_name" lay-verify="required" lay-reqText="请输入商品名称"
autocomplete="off" placeholder="请输入商品名称" class="layui-input" value="{$product.store_name}"></td>
</tr>
<tr>
<td class="layui-td-gray">平台商品分类<font>*</font>
</td>
<td>
<div id="cate_id"></div>
</td>
<td class="layui-td-gray">品牌选择<font>*</font>
</td>
<td colspan="6">
<select name="brand_id" lay-verify="required" lay-search="">
<option value="">请选择</option>
{volist name='store_brand' id='vo'}
<option value="{$vo.brand_id}" {if $product.brand_id==$vo.brand_id} selected {/if}>{$vo.brand_name}</option>
{/volist}
</select>
</td>
</tr>
<tr>
<td class="layui-td-gray">商户分类<font>*</font>
</td>
<td colspan="3">
<div id="mer_cate_id"></div>
</td>
</tr>
<tr>
<td class="layui-td-gray" style="vertical-align:top;">商品封面图</td>
<td colspan="12">
<div class="layui-upload">
<button type="button" class="layui-btn layui-btn-sm" id="upload_btn_thumb">
上传缩略图(尺寸:750x750)
</button>
<div class="layui-upload-list" id="upload_box_thumb" style=" overflow: hidden;">
<img src="{$product.image}"
onerror="javascript:this.src='{__GOUGU__}/gougu/images/nonepic600x360.jpg';this.onerror=null;"
width="100" style="max-width: 100%; height:66px;" />
<input type="hidden" name="image" value="{$product.image}">
</div>
</div>
</td>
</tr>
<tr>
<td class="layui-td-gray" style="vertical-align:top;">商品轮播图</td>
<td colspan="12">
<div class="layui-upload">
<button type="button" class="layui-btn layui-btn-sm" id="upload_btn_thumb2">
上传商品轮播图
</button>
<div class="layui-upload-list" id="upload_box_thumb2" style="overflow: hidden;">
{volist name='$product.slider_image_arr' id='vo'}
{if $vo}
<img src="{$vo}"
onerror="javascript:this.src='{__GOUGU__}/gougu/images/nonepic600x360.jpg';this.onerror=null;"
width="100" style="max-width: 100%; height:66px;" onclick="delMultipleImgs(this)"/>
{/if}
{/volist}
<input type="hidden" name="slider_image" value="{$product.slider_image}">
</div>
</div>
</td>
</tr>
<!-- <tr>
<td class="layui-td-gray">主图视频:<font>*</font>
</td>
<td colspan="7">video_link</td>
</tr> -->
<tr>
<td class="layui-td-gray">单位<font>*</font>
</td>
<td colspan="7"><input type="text" name="unit_name" lay-verify="required" lay-reqText="请输入单位"
autocomplete="off" placeholder="请输入单位" class="layui-input" value="{$product.unit_name}"></td>
</tr>
<tr>
<td class="layui-td-gray">商品关键字<font>*</font>
</td>
<td colspan="7"><input type="text" name="keyword" lay-verify="required" lay-reqText="请输入商品关键字"
autocomplete="off" placeholder="请输入商品关键字" class="layui-input" value="{$product.keyword}"></td>
</tr>
<tr>
<td class="layui-td-gray" style="text-align:left">商品简介</td>
<td colspan="6">
<textarea class="layui-textarea" name="store_info">{$product.store_info}</textarea>
</td>
</tr>
<!-- <tr>
<td class="layui-td-gray">优惠券:<font>*</font>
</td>
<td colspan="7">couponData</td>
</tr> -->
</table>
</div>
<div class="layui-tab-item">
<table class="layui-table layui-table-form">
<!-- <tr>
<td class="layui-td-gray" style="background-color: #fff;width: 92px;">佣金设置</td>
<td colspan="6">
<input type="radio" name="status" value="1" title="单独设置">
<input type="radio" name="status" value="0" title="默认设置" checked>
</td>
</tr> -->
<!-- <tr>
<td class="layui-td-gray" style="text-align:left">付费会员价设置</td>
<td colspan="6">
</td>
</tr> -->
<tr>
<td colspan="6">
<!-- 规格类型 -->
<div id="fairy-is-attribute"></div>
<!--商品规格表-->
<div id="fairy-spec-table"></div>
<div id="fairy-sku-table"></div>
</td>
</tr>
</table>
</div>
<div class="layui-tab-item">
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray" style="text-align:left">商品详情</td>
<td colspan="6">
<textarea class="layui-textarea" id="container_content">{$product.content}</textarea>
</td>
</tr>
</table>
</div>
<div class="layui-tab-item">
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray" style="text-align:left">商品推荐</td>
<td colspan="6">
<input type="checkbox" name="is_good" title="店铺推荐" value="1" {if $product.is_good == 1} checked {/if}>
</td>
</tr>
</table>
</div>
<div class="layui-tab-item">
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray" style="text-align:left">送货方式</td>
<td colspan="6">
<input type="checkbox" name="delivery_way[]" title="到店自提" value="1" {if $product.delivery_way1 == 1} checked {/if}>
<input type="checkbox" name="delivery_way[]" title="快递配送" value="2" {if $product.delivery_way2 == 1} checked {/if}>
</td>
<td class="layui-td-gray" style="text-align:left">是否包邮</td>
<td colspan="6">
<input type="radio" name="delivery_free" value="1" title="是" {if $product.delivery_free == 1} checked {/if}>
<input type="radio" name="delivery_free" value="0" title="否" {if $product.delivery_free == 0} checked {/if}>
</td>
</tr>
<!-- <tr>
<td class="layui-td-gray" style="text-align:left">运费模板</td>
<td colspan="6">
</td>
</tr> -->
<tr>
<td class="layui-td-gray" style="text-align:left">最少购买件数</td>
<td colspan="6">
<input type="text" name="once_min_count" lay-verify="required" lay-reqText="默认为0则不限制购买件数"
autocomplete="off" placeholder="默认为0则不限制购买件数" class="layui-input" value="{$product.once_min_count}">
</td>
<td class="layui-td-gray" style="text-align:left">排序</td>
<td colspan="6">
<input type="text" name="sort" lay-verify="required" lay-reqText="默认为0则不限制购买件数"
autocomplete="off" placeholder="默认为0则不限制购买件数" class="layui-input" value="{$product.sort}">
</td>
</tr>
<!-- <tr>
<td class="layui-td-gray" style="text-align:left">限购类型</td>
<td colspan="6">
<input type="radio" name="pay_limit" value="0" title="不限购"checked>
<input type="radio" name="pay_limit" value="1" title="单次限购" >
<input type="radio" name="pay_limit" value="2" title="长期限购" >
</td>
</tr> -->
<!-- <tr>
<td class="layui-td-gray" style="text-align:left">平台保障服务</td>
<td colspan="6">
</td>
</tr>
<tr>
<td class="layui-td-gray" style="text-align:left">商品参数</td>
<td colspan="6">
</td>
</tr> -->
</table>
</div>
</div>
</div>
<div class="pt-3">
<input type="hidden" name="id" value="{$product.product_id}"/>
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
@ -90,99 +242,259 @@
<!-- 脚本 -->
{block name="script"}
<script src="/static/assets/js/jquery.min.js"></script>
<script src="/static/assets/js/addrHelper.js"></script>
<script src="/static/assets/js/xm-select.js"></script>
<script>
var moduleInit = ['tool','tinymce'];
function gouguInit() {
var form = layui.form, tool = layui.tool;
// 下拉选中事件
form.on('select(merchant)', function(data){
if(data.value == null || data.value == '')
{
return false;
}
const title = $('#merchant' + data.value).text();
const html = `<input type="checkbox" id="mer_id` + data.value + `" name="mer_id[]" title="` + title + `" value="` + data.value + `" checked/>`
+ `<div id="mer_id_style` + data.value + `" class="layui-unselect layui-form-checkbox layui-form-checked" onclick="merchantxz(` + data.value + `)"><span>` + title + `</span><i class="layui-icon layui-icon-ok"></i></div>`;
$('#merchantList').append(html);
$("#merchant"+ data.value).remove();
$(".layui-this").remove();
});
form.on('select(merchantAddress)', function (data) {
street(data.value);
});
//监听提交
form.on('submit(webform)', function (data) {
let callback = function (e) {
console.log(e);
layer.msg(e.msg);
if (e.code == 0) {
tool.tabRefresh(71);
tool.sideClose(1000);
}
}
tool.post('{$url[2]}', data.field, callback);
return false;
});
// 删除选中商户
function merchantxz(env)
{
if($('#mer_id'+env).attr("checked") == 'checked')
{
$('#mer_id'+env).removeAttr('checked');
$('#mer_id_style'+env).removeClass('layui-form-checked');
}else{
$('#mer_id'+env).attr('checked', 'checked');
$('#mer_id_style'+env).addClass('layui-form-checked');
}
var moduleInit = ['tool', 'tagpicker', 'tinymce','skuTable'];
var group_access = "{:session('gougu_admin')['group_access']}"
var multiple_images = [];
var cate_id = "{$product['cate_id']}";
var mer_cate_id = "{$product['mer_cate_id']}";
var is_attribute = "{$product['spec_type']}";
var product_attr = "{$product['attr']}";
var product_attr_value = "{$product['attrValue']}".replace(/&quot;/g,"\"");
var product_id = "{$product['product_id']}";
//单击图片删除图片 【注册全局函数】
function delMultipleImgs (this_img) {
//获取下标
var subscript = $("#upload_box_thumb2 img").index(this_img);
//删除图片
this_img.remove();
//删除数组
multiple_images.splice(subscript, 1);
//重新排序
multiple_images.sort();
$('#upload_box_thumb2 input').attr('value', multiple_images);
//返回
return;
}
var group_access = "{:session('gougu_admin')['group_access']}";
street("{$detail.store_category_id}");
function street (id) {
if(id == null || id == '')
{
return false;
function gouguInit () {
var form = layui.form, tool = layui.tool, tagspicker = layui.tagpicker, element = layui.element,skuTable = layui.skuTable;
if(product_attr){
product_attr = "{$product['attr']}".replace(/&quot;/g,"\"");
}
var demo1 = xmSelect.render({
name: 'pid',
el: '#demo1',
prop: {
name: 'name',
value: 'id',
},
data: [],
radio: true,
initValue: ['{$detail.pid}'],
disabled: group_access == 2 || group_access==4 ? true : false
});
$.get('/api/geo/street?pcode=' + id, function (result) {
demo1.update({
data: result.data
function demo1 (id) {
var demo1 = xmSelect.render({
name: 'street_id',
el: '#demo1',
initValue: [street_id],
prop: {
name: 'name',
value: 'code',
},
data: [],
radio: true,
disabled: group_access == 2 || group_access == 4 ? true : false,
on: function (data) {
var arr = data.arr;
village(arr[0]['code'])
},
})
$.get('/api/geo/street?pcode=' + id, function (result) {
demo1.update({
data: result.data
})
});
}
function demo_cate_id () {
var demo_cate = xmSelect.render({
name: 'cate_id',
el: '#cate_id',
initValue: [cate_id],
autoRow: true,
cascader: {
show: true,
indent: 200,
},
prop: {
name: 'name',
value: 'id',
},
data: [],
radio: true,
})
$.get('/admin/product.product/category_arr', function (result) {
demo_cate.update({
data: result.data
})
});
}
demo_cate_id()
function demo_mer_cate_id () {
var demo_cate = xmSelect.render({
name: 'mer_cate_id',
el: '#mer_cate_id',
autoRow: true,
initValue: [mer_cate_id],
cascader: {
show: true,
indent: 200,
},
prop: {
name: 'name',
value: 'id',
},
data: [],
radio: true,
})
$.get('/admin/product.product/category_arr?id=4', function (result) {
demo_cate.update({
data: result.data
})
});
}
demo_mer_cate_id()
product_attr = JSON.parse(product_attr);
product_attr_value = JSON.parse(product_attr_value);
// console.log(product_attr_value);
var obj = skuTable.render({
//规格类型 0统一规格 1多规格
isAttributeValue: is_attribute,
//规格类型容器id
isAttributeElemId: 'fairy-is-attribute',
//规格表容器id
specTableElemId: 'fairy-spec-table',
//sku表容器id
skuTableElemId: 'fairy-sku-table',
//规格拖拽排序
sortable: true,
//sku表相同属性值是否合并行
rowspan: false,
//请求成功返回状态码值
requestSuccessCode: 200,
//上传接口地址
//接口要求返回格式为 {"code": 200, "data": {"url": "xxx"}, "msg": ""}
uploadUrl: '/admin/api/upload',
//统一规格配置项
singleSkuTableConfig: {
thead: [
{title: '销售价(元)', icon: 'layui-icon-cols'},
{title: '市场价(元)', icon: 'layui-icon-cols'},
{title: '成本价(元)', icon: 'layui-icon-cols'},
{title: '库存', icon: 'layui-icon-cols'},
{title: '商品编号', icon: 'layui-icon-cols'},
{title: '重量', icon: 'layui-icon-cols'},
{title: '体积', icon: 'layui-icon-cols'},
// {title: '状态', icon: ''},extension_one extension_two svip_price
],
tbody: [
{type: 'input', field: 'price', value: '', verify: 'required|number', reqtext: '销售价不能为空'},
{type: 'input', field: 'ot_price', value: '0', verify: 'required|number', reqtext: '市场价不能为空'},
{type: 'input', field: 'cost', value: '0', verify: 'required|number', reqtext: '成本价不能为空'},
{type: 'input', field: 'stock', value: '0', verify: 'required|number', reqtext: '库存不能为空'},
{type: 'input', field: 'bar_code', value: '', },
{type: 'input', field: 'weight', value: '0', verify: 'required|number', reqtext: '重量不能为空'},
{type: 'input', field: 'volume', value: '0', verify: 'required|number', reqtext: '体积不能为空'},
// {type: 'select', field: 'status', option: [{key: '启用', value: '1'}, {key: '禁用', value: '0'}], verify: 'required', reqtext: '状态不能为空'},
]
},
//多规格配置项
multipleSkuTableConfig: {
thead: [
{title: '图片', icon: ''},
{title: '销售价(元)', icon: 'layui-icon-cols'},
{title: '市场价(元)', icon: 'layui-icon-cols'},
{title: '成本价(元)', icon: 'layui-icon-cols'},
{title: '库存', icon: 'layui-icon-cols'},
{title: '商品编号', icon: 'layui-icon-cols'},
{title: '重量', icon: 'layui-icon-cols'},
{title: '体积', icon: 'layui-icon-cols'},
],
tbody: [
{type: 'image', field: 'image', value: '', verify: '', reqtext: ''},
{type: 'input', field: 'price', value: '', verify: 'required|number', reqtext: '销售价不能为空'},
{type: 'input', field: 'ot_price', value: '0', verify: 'required|number', reqtext: '市场价不能为空'},
{type: 'input', field: 'cost', value: '0', verify: 'required|number', reqtext: '成本价不能为空'},
{type: 'input', field: 'stock', value: '0', verify: 'required|number', reqtext: '库存不能为空'},
{type: 'input', field: 'bar_code', value: '', },
{type: 'input', field: 'weight', value: '0', verify: 'required|number', reqtext: '重量不能为空'},
{type: 'input', field: 'volume', value: '0', verify: 'required|number', reqtext: '体积不能为空'},
]
},
//商品id 配合specDataUrl和skuDataUrl使用
productId: product_id,
//规格数据, 一般从后台获取
specData: product_attr,
specDataUrl :"",
skuDataUrl :"",
skuData: product_attr_value,
});
//上传缩略图
var upload_thumb = layui.upload.render({
elem: '#upload_btn_thumb',
url: '/admin/api/upload',
done: function (res) {
//如果上传失败
if (res.code == 1) {
return layer.msg('上传失败');
}
//上传成功
$('#upload_box_thumb input').attr('value', res.data.filepath);
$('#upload_box_thumb img').attr('src', res.data.filepath);
}
});
//上传商品轮播图
var upload_thumb = layui.upload.render({
elem: '#upload_btn_thumb2',
url: '/admin/api/upload',
multiple: true,
before: function (obj) {
//预读本地文件示例不支持ie8
obj.preview(function (index, file, result) {
$('#upload_box_thumb2').append(`
<img src="${result}"
onerror="javascript:this.src='{__GOUGU__}/gougu/images/nonepic600x360.jpg';this.onerror=null;"
width="100" style="max-width: 100%; height:66px;" alt="${file.name}" onclick="delMultipleImgs(this)" title="点击删除"/>
`)
});
},
done: function (res) {
//如果上传失败
if (res.code == 1) {
return layer.msg('上传失败');
}
//上传成功
//追加图片成功追加文件名至图片容器
multiple_images.push(res.data.filepath);
$('#upload_box_thumb2 input').attr('value', multiple_images);
// $('#upload_box_thumb2 img').attr('src', res.data.filepath);
}
});
var editor = layui.tinymce;
var edit = editor.render({
selector: "#container_content",
height: 500
});
//监听提交
form.on('submit(webform)', function (data) {
//获取规格数据
var state = Object.keys(data.field).some(function (item, index, array) {
return item.startsWith('skus');
});
data.field.attrValue = state;
data.field.content = tinyMCE.editors['container_content'].getContent();
if (data.field.content == '') {
layer.msg('请先完善商品详情');
return false;
}
// if(data.field.is_attribute == 1){
// data.field.attrValue = '';
// }
let callback = function (e) {
layer.msg(e.msg);
if (e.code == 0) {
tool.tabRefresh(71);
tool.sideClose(1000);
}
}
tool.post('/admin/product.product/edit', data.field, callback);
return false;
});
}
}
</script>
{/block}
<!-- /脚本 -->

View File

@ -38,7 +38,7 @@
<div class="layui-form">
<form id="filterform" class="layui-form gg-form-bar border-t border-x" >
<input id="protype" type="hidden" name="type" value="">
<input id="protype" type="hidden" name="type" value="1">
<div class="layui-form-item">
<div class="layui-input-inline">
@ -161,6 +161,11 @@
</script>
<script type="text/html" id="thumb">
</script>
<script type="text/html" id="toolbarDemo">
<div class="layui-btn-container">
<span class="layui-btn layui-btn-sm" lay-event="add" data-title="添加商品">+ 添加商品</span>
</div>
</script>
<!-- <script type="text/html" id="toolbarDemo">
<div class="layui-btn-container">
@ -257,6 +262,22 @@
align: 'center',
width:150,
},{
field: 'is_show',
title: '商品状态',
align: 'center',
width:150,
escape:true,
templet: function (d)
{
if (d.is_show == 1) {
return '<input type="checkbox" checked="checked" name="is_show" lay-filter="switchTest" lay-skin="switch" lay-text="上架|未上架" value="1" userId=' + d.product_id + '>'
} else if (d.is_show == 0) {
return '<input type="checkbox" name="is_show" lay-filter="switchTest" lay-skin="switch" lay-text="上架|未上架" value="0" userId=' + d.product_id + '>'
}
// var html = d.is_show ? '上架显示' : '平台关闭';
// return html;
},
},{
field: 'is_good',
title: '推荐级别',
align: 'center',
@ -276,16 +297,6 @@
var html = d.is_used ? '显示' : '隐藏';
return html;
},
},{
field: 'is_show',
title: '商品状态',
align: 'center',
width:150,
templet: function (d)
{
var html = d.is_show ? '上架显示' : '平台关闭';
return html;
},
},{
field: 'keyword',
title: '标签',
@ -315,10 +326,10 @@
table.on('tool(article)', function(obj) {
var data = obj.data;
if (obj.event === 'read') {
tool.side('{$url[2]}?id='+obj.data.reply_id);
tool.side('{$url[4]}?id='+obj.data.product_id);
}
else if (obj.event === 'edit') {
tool.side('{$url[2]}?id='+obj.data.reply_id);
tool.side('{$url[2]}?id='+obj.data.product_id);
}
else if (obj.event === 'del') {
layer.confirm('确定要删除该记录吗?', {
@ -331,7 +342,7 @@
obj.del();
}
}
tool.delete('{$url[3]}', { id: data.reply_id }, callback);
tool.delete('{$url[3]}', { id: data.product_id }, callback);
layer.close(index);
});
}
@ -350,7 +361,7 @@
var $ = layui.$, active = {
reload: function(){
let dataRload = getformdata();;
let dataRload = getformdata();
//执行重载
table.reload('article', {
page: {
@ -427,7 +438,33 @@
active[type] ? active[type].call(this, othis) : '';
});
});
//监听指定开关
form.on('switch(switchTest)', function (data) { //根据lay-filter进行监听
console.log(this.checked ? "1" : "0");
var is_show = this.checked ? "1" : "0"; //锁定状态赋值为1未锁定赋值为2根据数据库中的值
console.log(data.elem.attributes['userId'].nodeValue); //获取修改数据的参数条件
$.ajax({
url: '/admin/api/changestatus',
type: 'post',
data: {
'product_id': data.elem.attributes['userId'].nodeValue,
'is_show': is_show
},
success: function (res) {
if(res.code==200){
layer.msg('操作成功');
}else{
layer.msg('操作失败');
}
setTimeout(function () {
location.reload();
}, 1000);
},
dataType: 'json'
});
form.render();
});
});
// 获取表单所有参数

View File

@ -0,0 +1,500 @@
{extend name="common/base"/}
{block name="style"}
<style type="text/css">
.editormd-code-toolbar select {
display: inline-block
}
.editormd li {
list-style: inherit;
}
</style>
{/block}
<!-- 主体 -->
{block name="body"}
<form class="layui-form p-4">
<h3 class="pb-3">查看</h3>
<div class="layui-tab layui-tab-brief">
<ul class="layui-tab-title">
<li class="layui-this">商品信息</li>
<li>规格设置</li>
<li>商品详情</li>
<li>营销设置</li>
<li>其他设置</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray">商品名称<font>*</font>
</td>
<td colspan="7"><input type="text" name="store_name" lay-verify="required" lay-reqText="请输入商品名称"
autocomplete="off" placeholder="请输入商品名称" class="layui-input" value="{$product.store_name}"></td>
</tr>
<tr>
<td class="layui-td-gray">平台商品分类<font>*</font>
</td>
<td>
<div id="cate_id"></div>
</td>
<td class="layui-td-gray">品牌选择<font>*</font>
</td>
<td colspan="6">
<select name="brand_id" lay-verify="required" lay-search="">
<option value="">请选择</option>
{volist name='store_brand' id='vo'}
<option value="{$vo.brand_id}" {if $product.brand_id==$vo.brand_id} selected {/if}>{$vo.brand_name}</option>
{/volist}
</select>
</td>
</tr>
<tr>
<td class="layui-td-gray">商户分类<font>*</font>
</td>
<td colspan="3">
<div id="mer_cate_id"></div>
</td>
</tr>
<tr>
<td class="layui-td-gray" style="vertical-align:top;">商品封面图</td>
<td colspan="12">
<div class="layui-upload">
<button type="button" class="layui-btn layui-btn-sm" id="upload_btn_thumb">
上传缩略图(尺寸:750x750)
</button>
<div class="layui-upload-list" id="upload_box_thumb" style=" overflow: hidden;">
<img src="{$product.image}"
onerror="javascript:this.src='{__GOUGU__}/gougu/images/nonepic600x360.jpg';this.onerror=null;"
width="100" style="max-width: 100%; height:66px;" />
<input type="hidden" name="image" value="{$product.image}">
</div>
</div>
</td>
</tr>
<tr>
<td class="layui-td-gray" style="vertical-align:top;">商品轮播图</td>
<td colspan="12">
<div class="layui-upload">
<button type="button" class="layui-btn layui-btn-sm" id="upload_btn_thumb2">
上传商品轮播图
</button>
<div class="layui-upload-list" id="upload_box_thumb2" style="overflow: hidden;">
{volist name='$product.slider_image_arr' id='vo'}
{if $vo}
<img src="{$vo}"
onerror="javascript:this.src='{__GOUGU__}/gougu/images/nonepic600x360.jpg';this.onerror=null;"
width="100" style="max-width: 100%; height:66px;" onclick="delMultipleImgs(this)"/>
{/if}
{/volist}
<input type="hidden" name="slider_image" value="{$product.slider_image}">
</div>
</div>
</td>
</tr>
<!-- <tr>
<td class="layui-td-gray">主图视频:<font>*</font>
</td>
<td colspan="7">video_link</td>
</tr> -->
<tr>
<td class="layui-td-gray">单位<font>*</font>
</td>
<td colspan="7"><input type="text" name="unit_name" lay-verify="required" lay-reqText="请输入单位"
autocomplete="off" placeholder="请输入单位" class="layui-input" value="{$product.unit_name}"></td>
</tr>
<tr>
<td class="layui-td-gray">商品关键字<font>*</font>
</td>
<td colspan="7"><input type="text" name="keyword" lay-verify="required" lay-reqText="请输入商品关键字"
autocomplete="off" placeholder="请输入商品关键字" class="layui-input" value="{$product.keyword}"></td>
</tr>
<tr>
<td class="layui-td-gray" style="text-align:left">商品简介</td>
<td colspan="6">
<textarea class="layui-textarea" name="store_info">{$product.store_info}</textarea>
</td>
</tr>
<!-- <tr>
<td class="layui-td-gray">优惠券:<font>*</font>
</td>
<td colspan="7">couponData</td>
</tr> -->
</table>
</div>
<div class="layui-tab-item">
<table class="layui-table layui-table-form">
<!-- <tr>
<td class="layui-td-gray" style="background-color: #fff;width: 92px;">佣金设置</td>
<td colspan="6">
<input type="radio" name="status" value="1" title="单独设置">
<input type="radio" name="status" value="0" title="默认设置" checked>
</td>
</tr> -->
<!-- <tr>
<td class="layui-td-gray" style="text-align:left">付费会员价设置</td>
<td colspan="6">
</td>
</tr> -->
<tr>
<td colspan="6">
<!-- 规格类型 -->
<div id="fairy-is-attribute"></div>
<!--商品规格表-->
<div id="fairy-spec-table"></div>
<div id="fairy-sku-table"></div>
</td>
</tr>
</table>
</div>
<div class="layui-tab-item">
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray" style="text-align:left">商品详情</td>
<td colspan="6">
<textarea class="layui-textarea" id="container_content">{$product.content}</textarea>
</td>
</tr>
</table>
</div>
<div class="layui-tab-item">
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray" style="text-align:left">商品推荐</td>
<td colspan="6">
<input type="checkbox" name="is_good" title="店铺推荐" value="1" {if $product.is_good == 1} checked {/if}>
</td>
</tr>
</table>
</div>
<div class="layui-tab-item">
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray" style="text-align:left">送货方式</td>
<td colspan="6">
<input type="checkbox" name="delivery_way[]" title="到店自提" value="1" {if $product.delivery_way1 == 1} checked {/if}>
<input type="checkbox" name="delivery_way[]" title="快递配送" value="2" {if $product.delivery_way2 == 1} checked {/if}>
</td>
<td class="layui-td-gray" style="text-align:left">是否包邮</td>
<td colspan="6">
<input type="radio" name="delivery_free" value="1" title="是" {if $product.delivery_free == 1} checked {/if}>
<input type="radio" name="delivery_free" value="0" title="否" {if $product.delivery_free == 0} checked {/if}>
</td>
</tr>
<!-- <tr>
<td class="layui-td-gray" style="text-align:left">运费模板</td>
<td colspan="6">
</td>
</tr> -->
<tr>
<td class="layui-td-gray" style="text-align:left">最少购买件数</td>
<td colspan="6">
<input type="text" name="once_min_count" lay-verify="required" lay-reqText="默认为0则不限制购买件数"
autocomplete="off" placeholder="默认为0则不限制购买件数" class="layui-input" value="{$product.once_min_count}">
</td>
<td class="layui-td-gray" style="text-align:left">排序</td>
<td colspan="6">
<input type="text" name="sort" lay-verify="required" lay-reqText="默认为0则不限制购买件数"
autocomplete="off" placeholder="默认为0则不限制购买件数" class="layui-input" value="{$product.sort}">
</td>
</tr>
<!-- <tr>
<td class="layui-td-gray" style="text-align:left">限购类型</td>
<td colspan="6">
<input type="radio" name="pay_limit" value="0" title="不限购"checked>
<input type="radio" name="pay_limit" value="1" title="单次限购" >
<input type="radio" name="pay_limit" value="2" title="长期限购" >
</td>
</tr> -->
<!-- <tr>
<td class="layui-td-gray" style="text-align:left">平台保障服务</td>
<td colspan="6">
</td>
</tr>
<tr>
<td class="layui-td-gray" style="text-align:left">商品参数</td>
<td colspan="6">
</td>
</tr> -->
</table>
</div>
</div>
</div>
<!-- <div class="pt-3">-->
<!-- <input type="hidden" name="id" value="{$product.product_id}"/>-->
<!-- <button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>-->
<!-- <button type="reset" class="layui-btn layui-btn-primary">重置</button>-->
<!-- </div>-->
</form>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script src="/static/assets/js/xm-select.js"></script>
<script>
var moduleInit = ['tool', 'tagpicker', 'tinymce','skuTable'];
var group_access = "{:session('gougu_admin')['group_access']}"
var multiple_images = [];
var cate_id = "{$product['cate_id']}";
var mer_cate_id = "{$product['mer_cate_id']}";
var is_attribute = "{$product['spec_type']}";
var product_attr = "{$product['attr']}";
var product_attr_value = "{$product['attrValue']}".replace(/&quot;/g,"\"");
var product_id = "{$product['product_id']}";
//单击图片删除图片 【注册全局函数】
function delMultipleImgs (this_img) {
//获取下标
var subscript = $("#upload_box_thumb2 img").index(this_img);
//删除图片
this_img.remove();
//删除数组
multiple_images.splice(subscript, 1);
//重新排序
multiple_images.sort();
$('#upload_box_thumb2 input').attr('value', multiple_images);
//返回
return;
}
function gouguInit () {
var form = layui.form, tool = layui.tool, tagspicker = layui.tagpicker, element = layui.element,skuTable = layui.skuTable;
if(product_attr){
product_attr = "{$product['attr']}".replace(/&quot;/g,"\"");
}
function demo1 (id) {
var demo1 = xmSelect.render({
name: 'street_id',
el: '#demo1',
initValue: [street_id],
prop: {
name: 'name',
value: 'code',
},
data: [],
radio: true,
disabled: group_access == 2 || group_access == 4 ? true : false,
on: function (data) {
var arr = data.arr;
village(arr[0]['code'])
},
})
$.get('/api/geo/street?pcode=' + id, function (result) {
demo1.update({
data: result.data
})
});
}
function demo_cate_id () {
var demo_cate = xmSelect.render({
name: 'cate_id',
el: '#cate_id',
initValue: [cate_id],
autoRow: true,
cascader: {
show: true,
indent: 200,
},
prop: {
name: 'name',
value: 'id',
},
data: [],
radio: true,
})
$.get('/admin/product.product/category_arr', function (result) {
demo_cate.update({
data: result.data
})
});
}
demo_cate_id()
function demo_mer_cate_id () {
var demo_cate = xmSelect.render({
name: 'mer_cate_id',
el: '#mer_cate_id',
autoRow: true,
initValue: [mer_cate_id],
cascader: {
show: true,
indent: 200,
},
prop: {
name: 'name',
value: 'id',
},
data: [],
radio: true,
})
$.get('/admin/product.product/category_arr?id=4', function (result) {
demo_cate.update({
data: result.data
})
});
}
demo_mer_cate_id()
product_attr = JSON.parse(product_attr);
product_attr_value = JSON.parse(product_attr_value);
// console.log(product_attr_value);
var obj = skuTable.render({
//规格类型 0统一规格 1多规格
isAttributeValue: is_attribute,
//规格类型容器id
isAttributeElemId: 'fairy-is-attribute',
//规格表容器id
specTableElemId: 'fairy-spec-table',
//sku表容器id
skuTableElemId: 'fairy-sku-table',
//规格拖拽排序
sortable: true,
//sku表相同属性值是否合并行
rowspan: false,
//请求成功返回状态码值
requestSuccessCode: 200,
//上传接口地址
//接口要求返回格式为 {"code": 200, "data": {"url": "xxx"}, "msg": ""}
uploadUrl: '/admin/api/upload',
//统一规格配置项
singleSkuTableConfig: {
thead: [
{title: '销售价(元)', icon: 'layui-icon-cols'},
{title: '市场价(元)', icon: 'layui-icon-cols'},
{title: '成本价(元)', icon: 'layui-icon-cols'},
{title: '库存', icon: 'layui-icon-cols'},
{title: '商品编号', icon: 'layui-icon-cols'},
{title: '重量', icon: 'layui-icon-cols'},
{title: '体积', icon: 'layui-icon-cols'},
// {title: '状态', icon: ''},extension_one extension_two svip_price
],
tbody: [
{type: 'input', field: 'price', value: '', verify: 'required|number', reqtext: '销售价不能为空'},
{type: 'input', field: 'ot_price', value: '0', verify: 'required|number', reqtext: '市场价不能为空'},
{type: 'input', field: 'cost', value: '0', verify: 'required|number', reqtext: '成本价不能为空'},
{type: 'input', field: 'stock', value: '0', verify: 'required|number', reqtext: '库存不能为空'},
{type: 'input', field: 'bar_code', value: '', },
{type: 'input', field: 'weight', value: '0', verify: 'required|number', reqtext: '重量不能为空'},
{type: 'input', field: 'volume', value: '0', verify: 'required|number', reqtext: '体积不能为空'},
// {type: 'select', field: 'status', option: [{key: '启用', value: '1'}, {key: '禁用', value: '0'}], verify: 'required', reqtext: '状态不能为空'},
]
},
//多规格配置项
multipleSkuTableConfig: {
thead: [
{title: '图片', icon: ''},
{title: '销售价(元)', icon: 'layui-icon-cols'},
{title: '市场价(元)', icon: 'layui-icon-cols'},
{title: '成本价(元)', icon: 'layui-icon-cols'},
{title: '库存', icon: 'layui-icon-cols'},
{title: '商品编号', icon: 'layui-icon-cols'},
{title: '重量', icon: 'layui-icon-cols'},
{title: '体积', icon: 'layui-icon-cols'},
],
tbody: [
{type: 'image', field: 'image', value: '', verify: '', reqtext: ''},
{type: 'input', field: 'price', value: '', verify: 'required|number', reqtext: '销售价不能为空'},
{type: 'input', field: 'ot_price', value: '0', verify: 'required|number', reqtext: '市场价不能为空'},
{type: 'input', field: 'cost', value: '0', verify: 'required|number', reqtext: '成本价不能为空'},
{type: 'input', field: 'stock', value: '0', verify: 'required|number', reqtext: '库存不能为空'},
{type: 'input', field: 'bar_code', value: '', },
{type: 'input', field: 'weight', value: '0', verify: 'required|number', reqtext: '重量不能为空'},
{type: 'input', field: 'volume', value: '0', verify: 'required|number', reqtext: '体积不能为空'},
]
},
//商品id 配合specDataUrl和skuDataUrl使用
productId: product_id,
//规格数据, 一般从后台获取
specData: product_attr,
specDataUrl :"",
skuDataUrl :"",
skuData: product_attr_value,
});
//上传缩略图
var upload_thumb = layui.upload.render({
elem: '#upload_btn_thumb',
url: '/admin/api/upload',
done: function (res) {
//如果上传失败
if (res.code == 1) {
return layer.msg('上传失败');
}
//上传成功
$('#upload_box_thumb input').attr('value', res.data.filepath);
$('#upload_box_thumb img').attr('src', res.data.filepath);
}
});
//上传商品轮播图
var upload_thumb = layui.upload.render({
elem: '#upload_btn_thumb2',
url: '/admin/api/upload',
multiple: true,
before: function (obj) {
//预读本地文件示例不支持ie8
obj.preview(function (index, file, result) {
$('#upload_box_thumb2').append(`
<img src="${result}"
onerror="javascript:this.src='{__GOUGU__}/gougu/images/nonepic600x360.jpg';this.onerror=null;"
width="100" style="max-width: 100%; height:66px;" alt="${file.name}" onclick="delMultipleImgs(this)" title="点击删除"/>
`)
});
},
done: function (res) {
//如果上传失败
if (res.code == 1) {
return layer.msg('上传失败');
}
//上传成功
//追加图片成功追加文件名至图片容器
multiple_images.push(res.data.filepath);
$('#upload_box_thumb2 input').attr('value', multiple_images);
// $('#upload_box_thumb2 img').attr('src', res.data.filepath);
}
});
var editor = layui.tinymce;
var edit = editor.render({
selector: "#container_content",
height: 500
});
//监听提交
form.on('submit(webform)', function (data) {
//获取规格数据
var state = Object.keys(data.field).some(function (item, index, array) {
return item.startsWith('skus');
});
data.field.attrValue = state;
data.field.content = tinyMCE.editors['container_content'].getContent();
if (data.field.content == '') {
layer.msg('请先完善商品详情');
return false;
}
// if(data.field.is_attribute == 1){
// data.field.attrValue = '';
// }
let callback = function (e) {
layer.msg(e.msg);
if (e.code == 0) {
tool.tabRefresh(71);
tool.sideClose(1000);
}
}
tool.post('/admin/product.product/edit', data.field, callback);
return false;
});
}
</script>
{/block}
<!-- /脚本 -->

View File

@ -34,34 +34,57 @@
<!-- </div>-->
<!-- </td>-->
<!-- </tr>-->
<tr>
<td class="layui-td-gray">平台商品分类<font>*</font></td>
<td colspan="3">
<div class="layui-col-md6">
<select name="cate_id" lay-verify="required" lay-search="">
<option value="" >请选择</option>
{volist name=':set_recursion(get_store_category())' id='vo'}
<option value="{$vo.id}" >{$vo.title}</option>
{/volist}
</select>
</div>
</td>
</tr>
<!-- <tr>-->
<!-- <td class="layui-td-gray">平台商品分类<font>*</font></td>-->
<!-- <td colspan="3">-->
<!-- <div class="layui-col-md6">-->
<!-- <select name="cate_id" lay-verify="required" lay-search="">-->
<!-- <option value="" >请选择</option>-->
<!-- {volist name=':set_recursion(get_store_category())' id='vo'}-->
<!-- <option value="{$vo.id}" >{$vo.title}</option>-->
<!-- {/volist}-->
<!-- </select>-->
<!-- </div>-->
<!-- </td>-->
<!-- </tr>-->
<!-- <tr>-->
<!-- <td class="layui-td-gray">品牌选择<font>*</font></td>-->
<!-- <td colspan="3">-->
<!-- <div class="layui-col-md6">-->
<!-- <select name="brand_id" lay-verify="required" lay-search="">-->
<!-- <option value="" >请选择</option>-->
<!-- {volist name='store_brand' id='vo'}-->
<!-- <option value="{$vo.brand_id}" >{$vo.brand_name}</option>-->
<!-- {/volist}-->
<!-- </select>-->
<!-- </div>-->
<!-- </td>-->
<!-- </tr>-->
<tr>
<td class="layui-td-gray">品牌选择<font>*</font></td>
<td colspan="3">
<div class="layui-col-md6">
<select name="brand_id" lay-verify="required" lay-search="">
<option value="" >请选择</option>
{volist name='store_brand' id='vo'}
<option value="{$vo.brand_id}" >{$vo.brand_name}</option>
{/volist}
</select>
</div>
<td class="layui-td-gray">平台商品分类<font>*</font>
</td>
<td>
<div id="cate_id"></div>
</td>
<!-- <td class="layui-td-gray">品牌选择<font>*</font>-->
<!-- </td>-->
<!-- <td colspan="6">-->
<!-- <select name="brand_id" lay-verify="required" lay-search="">-->
<!-- <option value="">请选择</option>-->
<!-- {volist name='store_brand' id='vo'}-->
<!-- <option value="{$vo.brand_id}">{$vo.brand_name}</option>-->
<!-- {/volist}-->
<!-- </select>-->
<!-- </td>-->
</tr>
<!-- <tr>-->
<!-- <td class="layui-td-gray">商户分类<font>*</font>-->
<!-- </td>-->
<!-- <td colspan="3">-->
<!-- <div id="mer_cate_id"></div>-->
<!-- </td>-->
<!-- </tr>-->
<tr>
<td class="layui-td-gray" style="vertical-align:top;">商品封面图</td>
@ -96,7 +119,11 @@
</div>
</td>
</tr>
<tr>
<td class="layui-td-gray">商品编码<font>*</font></td>
<td colspan="7"><input type="text" name="bar_code" lay-verify="required" lay-reqText="请输入商品编码"
autocomplete="off" placeholder="请输入商品编码" class="layui-input"></td>
</tr>
<tr>
<td class="layui-td-gray">单位<font>*</font></td>
<td colspan="7"><input type="text" name="unit_name" lay-verify="required" lay-reqText="请输入单位"
@ -220,6 +247,53 @@
}
});
function demo_cate_id () {
var demo_cate = xmSelect.render({
name: 'cate_id',
el: '#cate_id',
autoRow: true,
radio: true,
cascader: {
show: true,
indent: 200,
},
prop: {
name: 'name',
value: 'id',
},
data: [],
})
$.get('/admin/api/category_arr', function (result) {
demo_cate.update({
data: result.data
})
});
}
demo_cate_id()
function demo_mer_cate_id () {
var demo_cate = xmSelect.render({
name: 'mer_cate_id',
el: '#mer_cate_id',
autoRow: true,
cascader: {
show: true,
indent: 200,
},
prop: {
name: 'name',
value: 'id',
},
data: [],
radio: true,
})
$.get('/admin/api/category_arr?id=4', function (result) {
demo_cate.update({
data: result.data
})
});
}
demo_mer_cate_id();
var editor = layui.tinymce;
var edit = editor.render({
selector: "#container_content",
@ -232,6 +306,17 @@
layer.msg('请先完善商品详情');
return false;
}
if (data.field.cate_id == '') {
layer.msg('请先选择平台分类');
return false;
}
// if (data.field.mer_cate_id == '') {
// layer.msg('请先选择商户分类');
// return false;
// }
let callback = function (e) {
layer.msg(e.msg);
if (e.code == 0) {

View File

@ -0,0 +1,466 @@
{extend name="common/base"/}
{block name="style"}
<style type="text/css">
.editormd-code-toolbar select {
display: inline-block
}
.editormd li {
list-style: inherit;
}
</style>
{/block}
<!-- 主体 -->
{block name="body"}
<form class="layui-form p-4">
<div class="layui-tab layui-tab-brief">
<ul class="layui-tab-title">
<li class="layui-this">商品信息</li>
<li>规格设置</li>
<li>商品详情</li>
<li>营销设置</li>
<li>其他设置</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray">商品名称<font>*</font>
</td>
<td colspan="7"><input type="text" name="store_name" lay-verify="required" lay-reqText="请输入商品名称"
autocomplete="off" placeholder="请输入商品名称" class="layui-input"></td>
</tr>
<tr>
<td class="layui-td-gray">平台商品分类<font>*</font>
</td>
<td>
<div id="cate_id"></div>
</td>
<td class="layui-td-gray">品牌选择<font>*</font>
</td>
<td colspan="6">
<select name="brand_id" lay-verify="required" lay-search="">
<option value="">请选择</option>
{volist name='store_brand' id='vo'}
<option value="{$vo.brand_id}">{$vo.brand_name}</option>
{/volist}
</select>
</td>
</tr>
<tr>
<td class="layui-td-gray">商户分类<font>*</font>
</td>
<td colspan="3">
<div id="mer_cate_id"></div>
</td>
</tr>
<tr>
<td class="layui-td-gray" style="vertical-align:top;">商品封面图</td>
<td colspan="12">
<div class="layui-upload">
<button type="button" class="layui-btn layui-btn-sm" id="upload_btn_thumb">
上传缩略图(尺寸:750x750)
</button>
<div class="layui-upload-list" id="upload_box_thumb" style=" overflow: hidden;">
<img src=""
onerror="javascript:this.src='{__GOUGU__}/gougu/images/nonepic600x360.jpg';this.onerror=null;"
width="100" style="max-width: 100%; height:66px;" />
<input type="hidden" name="image" value="">
</div>
</div>
</td>
</tr>
<tr>
<td class="layui-td-gray" style="vertical-align:top;">商品轮播图</td>
<td colspan="12">
<div class="layui-upload">
<button type="button" class="layui-btn layui-btn-sm" id="upload_btn_thumb2">
上传商品轮播图
</button>
<div class="layui-upload-list" id="upload_box_thumb2" style="overflow: hidden;">
<input type="hidden" name="slider_image" value="">
</div>
</div>
</td>
</tr>
<!-- <tr>
<td class="layui-td-gray">主图视频:<font>*</font>
</td>
<td colspan="7">video_link</td>
</tr> -->
<tr>
<td class="layui-td-gray">单位<font>*</font>
</td>
<td colspan="7"><input type="text" name="unit_name" lay-verify="required" lay-reqText="请输入单位"
autocomplete="off" placeholder="请输入单位" class="layui-input"></td>
</tr>
<tr>
<td class="layui-td-gray">商品关键字<font>*</font>
</td>
<td colspan="7"><input type="text" name="keyword" lay-verify="required" lay-reqText="请输入商品关键字"
autocomplete="off" placeholder="请输入商品关键字" class="layui-input"></td>
</tr>
<tr>
<td class="layui-td-gray" style="text-align:left">商品简介</td>
<td colspan="6">
<textarea class="layui-textarea" name="store_info"></textarea>
</td>
</tr>
<!-- <tr>
<td class="layui-td-gray">优惠券:<font>*</font>
</td>
<td colspan="7">couponData</td>
</tr> -->
</table>
</div>
<div class="layui-tab-item">
<table class="layui-table layui-table-form">
<!-- <tr>
<td class="layui-td-gray" style="background-color: #fff;width: 92px;">佣金设置</td>
<td colspan="6">
<input type="radio" name="status" value="1" title="单独设置">
<input type="radio" name="status" value="0" title="默认设置" checked>
</td>
</tr> -->
<!-- <tr>
<td class="layui-td-gray" style="text-align:left">付费会员价设置</td>
<td colspan="6">
</td>
</tr> -->
<tr>
<td colspan="6">
<!-- 规格类型 -->
<div id="fairy-is-attribute"></div>
<!--商品规格表-->
<div id="fairy-spec-table"></div>
<div id="fairy-sku-table"></div>
</td>
</tr>
</table>
</div>
<div class="layui-tab-item">
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray" style="text-align:left">商品详情</td>
<td colspan="6">
<textarea class="layui-textarea" id="container_content"></textarea>
</td>
</tr>
</table>
</div>
<div class="layui-tab-item">
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray" style="text-align:left">商品推荐</td>
<td colspan="6">
<input type="checkbox" name="is_good" title="店铺推荐">
</td>
</tr>
</table>
</div>
<div class="layui-tab-item">
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray" style="text-align:left">送货方式</td>
<td colspan="6">
<input type="checkbox" name="ziti" title="到店自提">
<input type="checkbox" name="kuaidi" title="快递配送">
</td>
<td class="layui-td-gray" style="text-align:left">是否包邮</td>
<td colspan="6">
<input type="radio" name="delivery_free" value="1" title="是"checked>
<input type="radio" name="delivery_free" value="0" title="否" >
</td>
</tr>
<!-- <tr>
<td class="layui-td-gray" style="text-align:left">运费模板</td>
<td colspan="6">
</td>
</tr> -->
<tr>
<td class="layui-td-gray" style="text-align:left">最少购买件数</td>
<td colspan="6">
<input type="text" name="once_min_count" lay-verify="required" lay-reqText="默认为0则不限制购买件数"
autocomplete="off" placeholder="默认为0则不限制购买件数" class="layui-input" value="0">
</td>
<td class="layui-td-gray" style="text-align:left">排序</td>
<td colspan="6">
<input type="text" name="sort" lay-verify="required" lay-reqText="默认为0则不限制购买件数"
autocomplete="off" placeholder="默认为0则不限制购买件数" class="layui-input" value="0">
</td>
</tr>
<!-- <tr>
<td class="layui-td-gray" style="text-align:left">限购类型</td>
<td colspan="6">
<input type="radio" name="pay_limit" value="0" title="不限购"checked>
<input type="radio" name="pay_limit" value="1" title="单次限购" >
<input type="radio" name="pay_limit" value="2" title="长期限购" >
</td>
</tr> -->
<!-- <tr>
<td class="layui-td-gray" style="text-align:left">平台保障服务</td>
<td colspan="6">
</td>
</tr>
<tr>
<td class="layui-td-gray" style="text-align:left">商品参数</td>
<td colspan="6">
</td>
</tr> -->
</table>
</div>
</div>
</div>
<div class="pt-3">
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</form>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script src="/static/assets/js/xm-select.js"></script>
<script>
var moduleInit = ['tool', 'tagpicker', 'tinymce','skuTable'];
var group_access = "{:session('gougu_admin')['group_access']}"
var multiple_images = [];
//单击图片删除图片 【注册全局函数】
function delMultipleImgs (this_img) {
//获取下标
var subscript = $("#upload_box_thumb2 img").index(this_img);
//删除图片
this_img.remove();
//删除数组
multiple_images.splice(subscript, 1);
//重新排序
multiple_images.sort();
$('#upload_box_thumb2 input').attr('value', multiple_images);
//返回
return;
}
function gouguInit () {
var form = layui.form, tool = layui.tool, tagspicker = layui.tagpicker, element = layui.element,skuTable = layui.skuTable;
function demo1 (id) {
var demo1 = xmSelect.render({
name: 'street_id',
el: '#demo1',
initValue: [street_id],
prop: {
name: 'name',
value: 'code',
},
data: [],
radio: true,
disabled: group_access == 2 || group_access == 4 ? true : false,
on: function (data) {
var arr = data.arr;
village(arr[0]['code'])
},
})
$.get('/api/geo/street?pcode=' + id, function (result) {
demo1.update({
data: result.data
})
});
}
function demo_cate_id () {
var demo_cate = xmSelect.render({
name: 'cate_id',
el: '#cate_id',
autoRow: true,
cascader: {
show: true,
indent: 200,
},
prop: {
name: 'name',
value: 'id',
},
data: [],
radio: true,
})
$.get('/admin/api/category_arr', function (result) {
demo_cate.update({
data: result.data
})
});
}
demo_cate_id()
function demo_mer_cate_id () {
var demo_cate = xmSelect.render({
name: 'mer_cate_id',
el: '#mer_cate_id',
autoRow: true,
cascader: {
show: true,
indent: 200,
},
prop: {
name: 'name',
value: 'id',
},
data: [],
radio: true,
})
$.get('/admin/api/category_arr?id=4', function (result) {
demo_cate.update({
data: result.data
})
});
}
demo_mer_cate_id()
var obj = skuTable.render({
//规格类型 0统一规格 1多规格
isAttributeValue: 0,
//规格类型容器id
isAttributeElemId: 'fairy-is-attribute',
//规格表容器id
specTableElemId: 'fairy-spec-table',
//sku表容器id
skuTableElemId: 'fairy-sku-table',
//规格拖拽排序
sortable: true,
//sku表相同属性值是否合并行
rowspan: true,
//请求成功返回状态码值
requestSuccessCode: 200,
//上传接口地址
//接口要求返回格式为 {"code": 200, "data": {"url": "xxx"}, "msg": ""}
uploadUrl: './json/upload.json',
//统一规格配置项
singleSkuTableConfig: {
thead: [
{title: '销售价(元)', icon: 'layui-icon-cols'},
{title: '市场价(元)', icon: 'layui-icon-cols'},
{title: '成本价(元)', icon: 'layui-icon-cols'},
{title: '库存', icon: 'layui-icon-cols'},
{title: '商品编号', icon: 'layui-icon-cols'},
{title: '重量', icon: 'layui-icon-cols'},
{title: '体积', icon: 'layui-icon-cols'},
// {title: '状态', icon: ''},extension_one extension_two svip_price
],
tbody: [
{type: 'input', field: 'price', value: '', verify: 'required|number', reqtext: '销售价不能为空'},
{type: 'input', field: 'market_price', value: '0', verify: 'required|number', reqtext: '市场价不能为空'},
{type: 'input', field: 'cost_price', value: '0', verify: 'required|number', reqtext: '成本价不能为空'},
{type: 'input', field: 'stock', value: '0', verify: 'required|number', reqtext: '库存不能为空'},
{type: 'input', field: 'bar_code', value: '', },
{type: 'input', field: 'weight', value: '0', verify: 'required|number', reqtext: '重量不能为空'},
{type: 'input', field: 'volume', value: '0', verify: 'required|number', reqtext: '体积不能为空'},
// {type: 'select', field: 'status', option: [{key: '启用', value: '1'}, {key: '禁用', value: '0'}], verify: 'required', reqtext: '状态不能为空'},
]
},
//多规格配置项
multipleSkuTableConfig: {
thead: [
{title: '图片', icon: ''},
{title: '销售价(元)', icon: 'layui-icon-cols'},
{title: '市场价(元)', icon: 'layui-icon-cols'},
{title: '成本价(元)', icon: 'layui-icon-cols'},
{title: '库存', icon: 'layui-icon-cols'},
{title: '商品编号', icon: 'layui-icon-cols'},
{title: '重量', icon: 'layui-icon-cols'},
{title: '体积', icon: 'layui-icon-cols'},
],
tbody: [
{type: 'image', field: 'image', value: '', verify: '', reqtext: ''},
{type: 'input', field: 'price', value: '', verify: 'required|number', reqtext: '销售价不能为空'},
{type: 'input', field: 'market_price', value: '0', verify: 'required|number', reqtext: '市场价不能为空'},
{type: 'input', field: 'cost_price', value: '0', verify: 'required|number', reqtext: '成本价不能为空'},
{type: 'input', field: 'stock', value: '0', verify: 'required|number', reqtext: '库存不能为空'},
{type: 'input', field: 'bar_code', value: '', },
{type: 'input', field: 'weight', value: '0', verify: 'required|number', reqtext: '重量不能为空'},
{type: 'input', field: 'volume', value: '0', verify: 'required|number', reqtext: '体积不能为空'},
]
},
//商品id 配合specDataUrl和skuDataUrl使用
productId: '',
//规格数据, 一般从后台获取
specData: [],
});
//上传缩略图
var upload_thumb = layui.upload.render({
elem: '#upload_btn_thumb',
url: '/admin/api/upload',
done: function (res) {
//如果上传失败
if (res.code == 1) {
return layer.msg('上传失败');
}
//上传成功
$('#upload_box_thumb input').attr('value', res.data.filepath);
$('#upload_box_thumb img').attr('src', res.data.filepath);
}
});
//上传商品轮播图
var upload_thumb = layui.upload.render({
elem: '#upload_btn_thumb2',
url: '/admin/api/upload',
multiple: true,
before: function (obj) {
//预读本地文件示例不支持ie8
obj.preview(function (index, file, result) {
$('#upload_box_thumb2').append(`
<img src="${result}"
onerror="javascript:this.src='{__GOUGU__}/gougu/images/nonepic600x360.jpg';this.onerror=null;"
width="100" style="max-width: 100%; height:66px;" alt="${file.name}" onclick="delMultipleImgs(this)" title="点击删除"/>
`)
});
},
done: function (res) {
//如果上传失败
if (res.code == 1) {
return layer.msg('上传失败');
}
//上传成功
//追加图片成功追加文件名至图片容器
multiple_images.push(res.data.filepath);
$('#upload_box_thumb2 input').attr('value', multiple_images);
// $('#upload_box_thumb2 img').attr('src', res.data.filepath);
}
});
var editor = layui.tinymce;
var edit = editor.render({
selector: "#container_content",
height: 500
});
//监听提交
form.on('submit(webform)', function (data) {
data.field.content = tinyMCE.editors['container_content'].getContent();
if (data.field.content == '') {
layer.msg('请先完善商品详情');
return false;
}
let callback = function (e) {
layer.msg(e.msg);
if (e.code == 0) {
tool.tabRefresh(71);
tool.sideClose(1000);
}
}
tool.post('/admin/store_product/add', data.field, callback);
return false;
});
}
</script>
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,397 @@
{extend name="common/base"/}
{block name="style"}
<link rel="stylesheet" href="/static/assets/libs/layui/css/layui.css" />
<style type="text/css">
.editormd-code-toolbar select {
display: inline-block
}
.editormd li {
list-style: inherit;
}
</style>
{/block}
<!-- 主体 -->
{block name="body"}
<form class="layui-form p-4">
<div class="layui-card">
<table class="layui-table layui-table-form">
<div class="layui-card-header"><h3>商品名称</h3></div>
<div class="layui-card-body layui-row layui-col-space12">
<div class="layui-col-md12">
<input type="text" name="store_name" lay-verify="required" lay-reqText="请输入商品名称"
autocomplete="off" placeholder="请输入商品名称" class="layui-input" value="{$detail.store_name}" readonly style="background-color:#f7f7f7">
</div>
</div>
<div class="layui-card-header"><h3>商品封面图</h3></div>
<div class="layui-card-body layui-row layui-col-space12">
<div class="layui-col-md12">
<div class="layui-upload">
<!-- <button type="button" class="layui-btn layui-btn-sm" id="upload_btn_thumb">-->
<!-- 上传缩略图(尺寸:428x270)-->
<!-- </button>-->
<div class="layui-upload-list" id="upload_box_thumb"
style="overflow: hidden;">
<img src="{$detail.image}"
onerror="javascript:this.src='{__GOUGU__}/gougu/images/nonepic600x360.jpg';this.onerror=null;"
width="100" style="max-width: 100%; height:66px;"/>
<input type="hidden" name="image" value="{$detail.image}">
</div>
</div>
</div>
</div>
<div class="layui-card-header"><h3>购买数量</h3></div>
<div class="layui-card-body layui-row layui-col-space12">
<div class="layui-col-md12">
<input type="text" name="number" lay-verify="required|integer" lay-reqText="请输入购买数量"
autocomplete="off" placeholder="请输入购买数量" class="layui-input" value="" id="sorts">
</div>
</div>
<!-- <tr>-->
<!-- <td class="layui-td-gray">商品名称</td>-->
<!-- <td colspan="7"><input type="text" name="store_name" lay-verify="required" lay-reqText="请输入商品名称"-->
<!-- autocomplete="off" placeholder="请输入商品名称" class="layui-input" value="{$detail.store_name}" readonly></td>-->
<!-- </tr>-->
<!-- <tr>-->
<!-- <td class="layui-td-gray" style="vertical-align:top;">商品封面图</td>-->
<!-- <td>-->
<!-- <div class="layui-upload">-->
<!-- &lt;!&ndash; <button type="button" class="layui-btn layui-btn-sm" id="upload_btn_thumb">&ndash;&gt;-->
<!-- &lt;!&ndash; 上传缩略图(尺寸:428x270)&ndash;&gt;-->
<!-- &lt;!&ndash; </button>&ndash;&gt;-->
<!-- <div class="layui-upload-list" id="upload_box_thumb"-->
<!-- style="overflow: hidden;">-->
<!-- <img src="{$detail.image}"-->
<!-- onerror="javascript:this.src='{__GOUGU__}/gougu/images/nonepic600x360.jpg';this.onerror=null;"-->
<!-- width="100" style="max-width: 100%; height:66px;"/>-->
<!-- <input type="hidden" name="image" value="{$detail.image}">-->
<!-- </div>-->
<!-- </div>-->
<!-- </td>-->
<!-- </tr>-->
<!-- <tr>-->
<!-- <td class="layui-td-gray">购买数量<font>*</font></td>-->
<!-- <td colspan="7"><input type="text" name="number" lay-verify="required|integer" lay-reqText="请输入购买数量"-->
<!-- autocomplete="off" placeholder="请输入购买数量" class="layui-input" value=""></td>-->
<!-- </tr>-->
</table>
<div class="pt-3" style="right: 0;position: absolute;padding-right: 30px;z-index: 999">
<input type="hidden" name="product_id" value="{$detail.product_id}"/>
<button type="reset" class="layui-btn layui-btn-primary preservation" >重置</button>
<button class="layui-btn layui-btn-normal preservation" lay-submit="" lay-filter="webform" >立即提交</button>
</div>
<div class="layui-card-header" style="margin-top:25px;"></div>
<div class="layui-card-body layui-row layui-col-space12 " style="margin-top:10px;">
<div class="layui-col-md12">
<img id="codes" src="" alt="" style="width: 200px;margin:0 auto;position: relative;
left: 39%;">
</div>
<div id="wenzi" style="width: 200px;margin:0 auto;color: #05c2fb;font-size: 20px;"></div>
</div>
</div>
</form>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script src="/static/assets/js/xm-select.js"></script>
<script src="/static/assets/libs/layui/layui.js"></script>
<script>
var moduleInit = ['tool', 'tagpicker', 'tinymce'];
var group_access = "{:session('gougu_admin')['group_access']}";
var multiple_images = "{$detail['slider_image']}".split(',');
//单击图片删除图片 【注册全局函数】
function delMultipleImgs(this_img){
//获取下标
var subscript=$("#upload_box_thumb2 img").index(this_img);
//删除图片
this_img.remove();
//删除数组
multiple_images.splice(subscript, 1);
//重新排序
multiple_images.sort();
$('#upload_box_thumb2 input').attr('value', multiple_images);
//返回
return ;
}
function gouguInit() {
layui.config({
base: "/static/assets/libs/layui_exts/",
})
.extend({
numberInput: "numberInput/js/index",
});
layui.use(["numberInput", "layer"], function () {
var numberInput = layui.numberInput;
var layer = layui.layer;
numberInput.render("#sorts", {
// 2.0.3.20220623 新增,默认 input
handleEvent: "blur",
// 最小值
min: 1,
// 最大值
max: 10000,
// 步数
step: 1,
// 所有的事件都需要写到 event 下面
// event: {
// beforeCreated() {
// console.log("生命周期: beforeCreated", "插件开始工作啦!");
// },
// created($tree) {
// console.log("生命周期: created", "插件已经创建好DOM了! 但是还没塞到页面上, 可以理解成现在是虚拟的DOM", $tree);
// },
// mounted($tree) {
// console.log("生命周期: mounted", "创建的DOM已经替换掉原始的DOM了, 撸起袖子就是干", $tree);
// },
// change(event, $input, value, $tree) {
// console.log("事件: change", "数据改变", {
// event,
// $input,
// value,
// $tree,
// });
// },
// input(event, $input, value, $tree) {
// console.log("事件: input", "数据输入", {
// event,
// $input,
// value,
// $tree,
// });
// },
// blur(event, $input, value, $tree) {
// console.log("事件: blur", "失去焦点", {
// event,
// $input,
// value,
// $tree,
// });
// },
// toMin(event, $subtract, value, $tree) {
// console.log("事件: toMin", "到达最小值", {
// event,
// $subtract,
// value,
// $tree,
// });
// },
// toMax(event, $add, value, $tree) {
// console.log("事件: toMax", "到达最大值", {
// event,
// $add,
// value,
// $tree,
// });
// },
// focus(event, $input, value, $tree) {
// console.log("事件: focus", "获得焦点", {
// event,
// $input,
// value,
// $tree,
// });
// },
// select(event, $input, value, $tree) {
// console.log("事件: select", "当全选的时候", {
// event,
// $input,
// value,
// $tree,
// });
// },
// keypress(event, $input, value, $tree) {
// console.log("事件: keypress", "当按下某个键的时候", {
// event,
// $input,
// value,
// $tree,
// });
// },
// mousewheel(event, $input, value, $tree) {
// console.log("事件: mousewheel", "当鼠标滚轮滚动的时候", {
// event,
// $input,
// value,
// $tree,
// });
// },
// },
});
});
var form = layui.form, tool = layui.tool, tagpicker = layui.tagpicker,numberInput =layui.numberInput;
form.verify({
integer: [
/^[1-9]\d*$/
, '只能输入正整数'
]
});
//上传缩略图
var upload_thumb = layui.upload.render({
elem: '#upload_btn_thumb',
url: '/admin/api/upload',
done: function (res) {
//如果上传失败
if (res.code == 1) {
layer.msg('上传失败');
return false;
}
//上传成功
$('#upload_box_thumb input').attr('value', res.data.filepath);
$('#upload_box_thumb img').attr('src', res.data.filepath);
}
});
//上传商品轮播图
var upload_thumb = layui.upload.render({
elem: '#upload_btn_thumb2',
url: '/admin/api/upload',
multiple: true,
before: function(obj){
//预读本地文件示例不支持ie8
obj.preview(function(index, file, result){
$('#upload_box_thumb2').append(`
<img src="${result}"
onerror="javascript:this.src='{__GOUGU__}/gougu/images/nonepic600x360.jpg';this.onerror=null;"
width="100" style="max-width: 100%; height:66px;" alt="${file.name}" onclick="delMultipleImgs(this)" title="点击删除"/>
`)
});
},
done: function (res) {
//如果上传失败
if (res.code == 1) {
return layer.msg('上传失败');
}
//上传成功
//追加图片成功追加文件名至图片容器
multiple_images.push(res.data.filepath);
$('#upload_box_thumb2 input').attr('value', multiple_images);
// $('#upload_box_thumb2 img').attr('src', res.data.filepath);
}
});
var editor = layui.tinymce;
var edit = editor.render({
selector: "#container_content",
height: 500
});
//监听提交
form.on('submit(webform)', function (data) {
if (data.field.number == '0') {
layer.msg('请先选择购买数量');
return false;
}
// 单击之后提交按钮不可选,防止重复提交
var DISABLED = 'layui-btn-disabled';
// 增加样式
$('.preservation').addClass(DISABLED);
// 增加属性
$('.preservation').attr('disabled', 'disabled');
let callback = function (e) {
if (e.code == 200) {
// 成功的时候
/** 把生成的二维码放到页面上 */
var url = e.data.html;
/** 弹出二维码 **/
// layer.open({
// //type:1 表示页面层
// type: 1,
// title: '扫码支付',
// //是否点击遮罩关闭
// shadeClose: false,
// //样式类名,可以自定义弹窗样式
// skin:'demo_share',
// // 去掉关闭按钮
// closeBtn :'',
// //弹层外区域
// shade: 0.3,
// maxmin: false, //开启最大化最小化按钮
// //宽高
// area: ['200px','220px'],
// //内容
// content: "<img src='"+url+"' alt='' style='margin-left: 20px;'>",
// });
$('#codes').attr('src',url);
$('#wenzi').html('请扫描上面二维码付款');
/** 设置定时器, 即一弹出二维码就开始不断请求查看支付状态, 直到收到支付成功的返回, 再终止定时器 **/
var timer = setInterval(function () {
/** 在这里请求微信支付状态的接口 **/
//ajax。必填参数'options':请求参数,对象,'callback':成功回调函数
let options = {
url: '/admin/store_product/paid',
type: 'get',
data: {
out_trade_no: e.data.order_sn,
}
};
let callback = function(res) {
if (res.code == 200) {
// layer.open({
// type: 1,
// title: '付款成功提示',
// shadeClose: true,
// shade: false,
// maxmin: false, //开启最大化最小化按钮
// area: ['1000px', '200px'],
// content: '<div style="width: 300px;margin:0 auto;font-size: 16px;margin-top:50px;">付款成功,请前往购买列表查看</div>'
// });
// parent.layer.closeAll();//关闭弹出层
layer.msg('支付成功',{time:2000,icon:6});
/** 如果支付成功, 就取消定时器, 并重新加载页面 */
window.clearInterval(timer);
// 关闭所有层
setTimeout(function () {
parent.layer.closeAll();
}, 2000);
// tool.sideClose(2000);
}
}
tool.ajax(options, callback);
}, 3000);
}else{
layer.msg(e.msg,{icon:5});
// 失败的时候
// 单击之后提交按钮不可选,防止重复提交
var DISABLED = 'layui-btn-disabled';
$('.preservation').removeClass(DISABLED);
$('.preservation').removeAttr('disabled');
}
}
tool.post("/admin/store_product/place_order", data.field, callback);
return false;
});
}
</script>
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,446 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<style>
.layui-input-inline{
width:35% !important;
}
.layui-input-inline .layui-form-item{
display:flex;
}
.layui-input-inline .layui-form-item .layui-form-label{
width:30%;
}
.layui-input-block{
margin-left:unset !important;
width:75%;
}
#seleform{
border-color: #eee;
background-color: #fff;
color:#a39f9f;
width:100%;
}
</style>
<div class="p-3">
<form id="filterform" class="layui-form gg-form-bar border-t border-x">
<div class="layui-form-item">
<div class="layui-input-inline">
<div class="layui-form-item">
<label class="layui-form-label">商品分类</label>
<div class="layui-input-block">
<input id="store_cate" type="hidden" readonly="readonly" name="store_cate">
<button id="seleform" lay-filter="seleform" class="layui-btn">请选择</button>
<div id="removeselect"><i class="bi-x-lg" style="position: absolute;right:2px;top:10px;z-index: 9;cursor:pointer;"></i></div>
</div>
</div>
</div>
</div>
<div class="layui-input-inline" style="width:300px;">
<input type="text" name="keywords" placeholder="请输入关键字" class="layui-input" autocomplete="off" />
</div>
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="searchform">提交搜索</button>
</form>
<table class="layui-hide" id="store_product" lay-filter="store_product"></table>
</div>
<script type="text/html" id="toolbarDemo">
<div class="layui-btn-container">
<span class="layui-btn layui-btn-sm preservation" lay-event="paycar" data-title="支付">支付</span>
<span class="layui-btn layui-btn-sm preservations" lay-event="saveorder" data-title="保存">保存</span>
</div>
</script>
<script type="text/html" id="barDemo">
<div class="layui-btn-group"><a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a></div>
</script>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
const moduleInit = ['tool'];
function gouguInit() {
var table = layui.table,tool = layui.tool, form = layui.form;
layui.pageTable = table.render({
elem: '#store_product',
title: '列表',
toolbar: '#toolbarDemo',
url: '/admin/store_product/carlist',
page: true,
limit: 20,
cellMinWidth: 300,
cols: [
[
{type:'checkbox', fixed: 'left'},
{
field: 'cart_id',
title: '编号',
align: 'center',
width: 80
},{
field: 'nickname',
title: '用户',
align: 'center',
width: 200,
},{
field: 'cart_num',
title: '商品数量',
align: 'center',
width: 100
},{
field: 'product',
title: '商品简介',
align: 'center',
width: 300,
templet: function (d) {
var html = '<div><img src="'+d.image+'" style="width:30px; height:30px;"> '+d.store_name+'</div>';
return html;
}
}, {
fixed: 'right',
field: 'right',
title: '操作',
toolbar: '#barDemo',
width: 136,
align: 'center'
}
]
],
id: 'testReload' ,
});
//监听表头工具栏事件
table.on('toolbar(store_product)', function(obj){
if (obj.event === 'paycar') {
//获取选中数据
var checkStatus = table.checkStatus('testReload')
,data = checkStatus.data;
var newJson = []
$.each(data, function (index, item) {
newJson.push(item.cart_id);
})
newJson.join(",");
if (newJson.length == 0){
layer.msg("请选择需要操作数据");
}else {
// 单击之后提交按钮不可选,防止重复提交
var DISABLED = 'layui-btn-disabled';
// 增加样式
$('.preservation').addClass(DISABLED);
// 增加属性
$('.preservation').attr('lay-event', 'paycar_disabled');
$.ajax({
url : "/admin/store_product/paycar?cart_id="+newJson, //请求的url地址
dataType : "json", //返回格式为json
async : true,//请求是否异步默认为异步这也是ajax重要特性
type : "POST", //请求方式
success : function(data) {
var url = data.data.html;
/** 弹出二维码 **/
layer.open({
//type:1 表示页面层
type: 1,
title: '扫码支付',
//是否点击遮罩关闭
shadeClose: false,
//样式类名,可以自定义弹窗样式
//弹层外区域
shade: 0.3,
maxmin: false, //开启最大化最小化按钮
//宽高
area: ['1000px','800px'],
//内容
content: "<div>"+data.data.data.html+"</div> 扫码支付:<img src='"+url+"' alt='' style='margin-left: 40px;'>",
});
/** 设置定时器, 即一弹出二维码就开始不断请求查看支付状态, 直到收到支付成功的返回, 再终止定时器 **/
var timer = setInterval(function () {
/** 在这里请求微信支付状态的接口 **/
//ajax。必填参数'options':请求参数,对象,'callback':成功回调函数
let options = {
url: '/admin/store_product/paid',
type: 'get',
data: {
out_trade_no: data.data.order_sn,
}
};
let callback = function(res) {
if (res.code == 200) {
layer.msg('支付成功',{time:2000,icon:6});
/** 如果支付成功, 就取消定时器, 并重新加载页面 */
window.clearInterval(timer);
// 关闭所有层
setTimeout(function () {
layer.closeAll();
}, 2000);
// tool.sideClose(2000);
}
}
tool.ajax(options, callback);
}, 3000);
// 恢复按钮
var DISABLED = 'layui-btn-disabled';
$('.preservation').removeClass(DISABLED);
$('.preservation').removeAttr('disabled');
$('.preservation').attr('lay-event', 'paycar');
},
complete : function() {
//请求完成的处理
},
error : function() {
// 恢复按钮
var DISABLED = 'layui-btn-disabled';
$('.preservation').removeClass(DISABLED);
$('.preservation').removeAttr('disabled');
$('.preservation').attr('lay-event', 'paycar');
//请求出错处理
layer.alert("系统异常");
}
});
}
}
else if (obj.event === 'saveorder') {
//获取选中数据
var checkStatus = table.checkStatus('testReload')
,data = checkStatus.data;
var newJson = []
$.each(data, function (index, item) {
newJson.push(item.cart_id);
})
newJson.join(",");
if (newJson.length == 0){
layer.msg("请选择需要操作数据")
}else {
// 单击之后提交按钮不可选,防止重复提交
var DISABLED = 'layui-btn-disabled';
// 增加样式
$('.preservations').addClass(DISABLED);
// 增加属性
$('.preservations').attr('lay-event', 'saveorder_disabled');
$.ajax({
url : "/admin/store_product/savecar?cart_id="+newJson, //请求的url地址
dataType : "json", //返回格式为json
async : true,//请求是否异步默认为异步这也是ajax重要特性
type : "POST", //请求方式
success : function(res) {
if (res.code == 200) {
layer.msg('保存成功',{time:2000,icon:6});
// 关闭所有层
setTimeout(function () {
layer.closeAll();
}, 2000);
// tool.sideClose(2000);
location.reload();
}
},
complete : function() {
//请求完成的处理
},
error : function() {
// 恢复按钮
var DISABLED = 'layui-btn-disabled';
$('.preservations').removeClass(DISABLED);
$('.preservations').removeAttr('disabled');
$('.preservation').attr('lay-event', 'saveorder');
//请求出错处理
layer.alert("系统异常");
}
});
}
}
});
// 表格点击行自动选中 ==========================================================================
$(document).on("click",".layui-table-body table.layui-table tbody tr", function (e) {
var index = $(this).attr('data-index');
var tableBox = $(this).parents('.layui-table-box');
//存在固定列
if (tableBox.find(".layui-table-fixed.layui-table-fixed-l").length > 0) {
tableDiv = tableBox.find(".layui-table-fixed.layui-table-fixed-l");
} else {
tableDiv = tableBox.find(".layui-table-body.layui-table-main");
}
var checkCell = tableDiv.find("tr[data-index=" + index + "]").find("td div.laytable-cell-checkbox div.layui-form-checkbox I");
if (checkCell.length > 0) {
checkCell.click();
}
});
// 表格点击行出发复选框后,阻止向上冒泡===============================================================
$(document).on("click", "td div.laytable-cell-checkbox div.layui-form-checkbox", function (e) {
e.stopPropagation();
});
//监听表格行工具事件
table.on('tool(store_product)', function(obj) {
var data = obj.data;
if (obj.event === 'read') {
tool.side('/admin/store_product/buy?cart_id='+obj.data.cart_id);
}
else if (obj.event === 'edit') {
tool.side('/admin/store_product/edit?cart_id='+obj.data.cart_id);
}
else if (obj.event === 'del') {
layer.confirm('确定要删除该记录吗?', {
icon: 3,
title: '提示'
}, function(index) {
let callback = function (e) {
layer.msg(e.msg);
if (e.code == 200) {
obj.del();
}
}
tool.delete("/admin/store_product/delcar", { cart_id: data.cart_id }, callback);
layer.close(index);
});
}
return false;
});
// 商户商品分类搜索
layui.use(['rate','dropdown', 'util', 'layer', 'table'], function(){
var dropdown = layui.dropdown
,util = layui.util
,layer = layui.layer
,rate = layui.rate
// ,table = layui.table
,$ = layui.jquery;
var $ = layui.$, active = {
reload: function(){
let dataRload = getformdata();
//执行重载
table.reload('store_product', {
page: {
curr: 1 //重新从第 1 页开始
}
,where: {
...dataRload
}
});
},
};
//商户商品分类菜单
$.ajax({
url: '/admin/api/getAllList',
method: "get",
data: {},
success: function(res) {
if (res.code!==0)return ;
//高级演示 - 各种组合
dropdown.render({
elem: '#seleform'
,isAllowSpread: false //禁止菜单组展开收缩
,style: 'width: 200px' //定义宽度,默认自适应
,id: 'test777' //定义唯一索引
,title: 'title1'
,data: res.data
,click: function(item){
$('#seleform').text(item.title);
$('#seleform').css({color:'rgba(0,0,0,.85)'});
$('#store_cate').val(item.id);
active['reload'] ? active['reload'].call(this) : '';
}
});
},
fail:function(){}
});
//基础效果
rate.render({
elem: '#is_good'
})
//监听搜索提交
form.on('submit(searchform)', function(data) {
layui.pageTable.reload({
where: {
...data.field
},
page: {
curr: 1
}
});
return false;
});
//监听select提交
form.on('select(seleform)', function(data) {
active['reload'] ? active['reload'].call(this) : '';
return false;
});
//监听removeselect点击
$('#removeselect').on('click', function(){
$('#seleform').text('请选择');
$('#seleform').css({color:'#a39f9f'});
$('#store_cate').val('');
active['reload'] ? active['reload'].call(this) : '';
return false;
});
// tab 状态列表切换
$('.site-demo-active').on('click', function(){
var othis = $(this), type = othis.data('type');
$('#protype').val(this.getAttribute('type'));
active[type] ? active[type].call(this, othis) : '';
});
});
// //监听搜索提交
// form.on('submit(searchform)', function(data) {
// layui.pageTable.reload({
// where: {
// keywords: data.field.keywords
// },
// page: {
// curr: 1
// }
// });
// return false;
// });
// 获取表单所有参数
function getformdata() {
var form = $('#filterform').serializeArray();
var data = new Array();
for(let i=0;i<form.length; i++){
data[form[i].name] = form[i].value;
}
return data;
}
}
</script>
{/block}
<!-- /脚本 -->

View File

@ -1,9 +1,45 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<style>
.layui-input-inline{
width:35% !important;
}
.layui-input-inline .layui-form-item{
display:flex;
}
.layui-input-inline .layui-form-item .layui-form-label{
width:30%;
}
.layui-input-block{
margin-left:unset !important;
width:75%;
}
#seleform{
border-color: #eee;
background-color: #fff;
color:#a39f9f;
width:100%;
}
</style>
<div class="p-3">
<form class="layui-form gg-form-bar border-t border-x">
<form id="filterform" class="layui-form gg-form-bar border-t border-x">
<div class="layui-form-item">
<div class="layui-input-inline">
<div class="layui-form-item">
<label class="layui-form-label">商品分类</label>
<div class="layui-input-block">
<input id="store_cate" type="hidden" readonly="readonly" name="store_cate">
<button id="seleform" lay-filter="seleform" class="layui-btn">请选择</button>
<div id="removeselect"><i class="bi-x-lg" style="position: absolute;right:2px;top:10px;z-index: 9;cursor:pointer;"></i></div>
</div>
</div>
</div>
</div>
<div class="layui-input-inline" style="width:300px;">
<input type="text" name="keywords" placeholder="请输入关键字" class="layui-input" autocomplete="off" />
</div>
@ -15,6 +51,7 @@
<script type="text/html" id="toolbarDemo">
<div class="layui-btn-container">
<span class="layui-btn layui-btn-sm" lay-event="add" data-title="添加商品">+ 添加商品</span>
<!-- <span class="layui-btn layui-btn-sm" lay-event="adds" data-title="添加商品">+ 添加商品2</span>-->
</div>
</script>
@ -46,6 +83,11 @@
title: '编号',
align: 'center',
width: 80
},{
field: 'shangjia',
title: '商家',
align: 'center',
width: 100
},{
field: 'image',
title: '商品图片',
@ -63,13 +105,18 @@
align: 'center',
width: 100
},{
field: 'keyword',
title: '关键字',
field: 'stock',
title: '总库存',
align: 'center',
width: 100
},{
field: 'brand_id',
title: '品牌 id',
field: 'bar_code',
title: '产品条码',
align: 'center',
width: 100
},{
field: 'keyword',
title: '关键字',
align: 'center',
width: 100
},{
@ -102,11 +149,6 @@
title: '原价',
align: 'center',
width: 100
},{
field: 'stock',
title: '总库存',
align: 'center',
width: 100
}, {
fixed: 'right',
field: 'right',
@ -125,8 +167,110 @@
tool.side("/admin/store_product/add");
return false;
}
if (obj.event === 'adds') {
tool.side("/admin/store_product/adds");
return false;
}
});
// 商户商品分类搜索
layui.use(['rate','dropdown', 'util', 'layer', 'table'], function(){
var dropdown = layui.dropdown
,util = layui.util
,layer = layui.layer
,rate = layui.rate
// ,table = layui.table
,$ = layui.jquery;
var $ = layui.$, active = {
reload: function(){
let dataRload = getformdata();
//执行重载
table.reload('store_product', {
page: {
curr: 1 //重新从第 1 页开始
}
,where: {
...dataRload
}
});
},
};
//商户商品分类菜单
$.ajax({
url: '/admin/api/getAllList',
method: "get",
data: {},
success: function(res) {
if (res.code!==0)return ;
//高级演示 - 各种组合
dropdown.render({
elem: '#seleform'
,isAllowSpread: false //禁止菜单组展开收缩
,style: 'width: 200px' //定义宽度,默认自适应
,id: 'test777' //定义唯一索引
,title: 'title1'
,data: res.data
,click: function(item){
$('#seleform').text(item.title);
$('#seleform').css({color:'rgba(0,0,0,.85)'});
$('#store_cate').val(item.id);
active['reload'] ? active['reload'].call(this) : '';
}
});
},
fail:function(){}
});
//基础效果
rate.render({
elem: '#is_good'
})
//监听搜索提交
form.on('submit(searchform)', function(data) {
layui.pageTable.reload({
where: {
...data.field
},
page: {
curr: 1
}
});
return false;
});
//监听select提交
form.on('select(seleform)', function(data) {
active['reload'] ? active['reload'].call(this) : '';
return false;
});
//监听removeselect点击
$('#removeselect').on('click', function(){
$('#seleform').text('请选择');
$('#seleform').css({color:'#a39f9f'});
$('#store_cate').val('');
active['reload'] ? active['reload'].call(this) : '';
return false;
});
// tab 状态列表切换
$('.site-demo-active').on('click', function(){
var othis = $(this), type = othis.data('type');
$('#protype').val(this.getAttribute('type'));
active[type] ? active[type].call(this, othis) : '';
});
});
//监听表格行工具事件
table.on('tool(store_product)', function(obj) {
var data = obj.data;
@ -166,6 +310,19 @@
});
return false;
});
// 获取表单所有参数
function getformdata() {
var form = $('#filterform').serializeArray();
var data = new Array();
for(let i=0;i<form.length; i++){
data[form[i].name] = form[i].value;
}
return data;
}
}
</script>
{/block}

View File

@ -13,7 +13,7 @@
<!-- 主体 -->
{block name="body"}
<form class="layui-form p-4">
<h3 class="pb-3">编辑文章表</h3>
<h3 class="pb-3">编辑</h3>
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray">商品名称<font>*</font></td>
@ -33,34 +33,58 @@
<!-- </div>-->
<!-- </td>-->
<!-- </tr>-->
<tr>
<td class="layui-td-gray">平台商品分类<font>*</font></td>
<td colspan="3">
<div class="layui-col-md6">
<select name="cate_id" lay-verify="required" lay-search="">
<option value="" >请选择</option>
{volist name=':set_recursion(get_store_category())' id='vo'}
<option value="{$vo.id}" {if $detail.cate_id==$vo.id} selected {/if}>{$vo.title}</option>
{/volist}
</select>
</div>
</td>
</tr>
<!-- <tr>-->
<!-- <td class="layui-td-gray">平台商品分类<font>*</font></td>-->
<!-- <td colspan="3">-->
<!-- <div class="layui-col-md6">-->
<!-- <select name="cate_id" lay-verify="required" lay-search="">-->
<!-- <option value="" >请选择</option>-->
<!-- {volist name=':set_recursion(get_store_category())' id='vo'}-->
<!-- <option value="{$vo.id}" {if $detail.cate_id==$vo.id} selected {/if}>{$vo.title}</option>-->
<!-- {/volist}-->
<!-- </select>-->
<!-- </div>-->
<!-- </td>-->
<!-- </tr>-->
<!-- <tr>-->
<!-- <td class="layui-td-gray">品牌选择<font>*</font></td>-->
<!-- <td colspan="3">-->
<!-- <div class="layui-col-md6">-->
<!-- <select name="brand_id" lay-verify="required" lay-search="">-->
<!-- <option value="" >请选择</option>-->
<!-- {volist name='store_brand' id='vo'}-->
<!-- <option value="{$vo.brand_id}" {if $detail.brand_id==$vo.brand_id} selected {/if}>{$vo.brand_name}</option>-->
<!-- {/volist}-->
<!-- </select>-->
<!-- </div>-->
<!-- </td>-->
<!-- </tr>-->
<tr>
<td class="layui-td-gray">品牌选择<font>*</font></td>
<td colspan="3">
<div class="layui-col-md6">
<select name="brand_id" lay-verify="required" lay-search="">
<option value="" >请选择</option>
{volist name='store_brand' id='vo'}
<option value="{$vo.brand_id}" {if $detail.brand_id==$vo.brand_id} selected {/if}>{$vo.brand_name}</option>
{/volist}
</select>
</div>
<td class="layui-td-gray">平台商品分类<font>*</font>
</td>
<td>
<div id="cate_id"></div>
</td>
<!-- <td class="layui-td-gray">品牌选择<font>*</font>-->
<!-- </td>-->
<!-- <td colspan="6">-->
<!-- <select name="brand_id" lay-verify="required" lay-search="">-->
<!-- <option value="">请选择</option>-->
<!-- {volist name='store_brand' id='vo'}-->
<!-- <option value="{$vo.brand_id}" {if $detail.brand_id==$vo.brand_id} selected {/if}>{$vo.brand_name}</option>-->
<!-- {/volist}-->
<!-- </select>-->
<!-- </td>-->
</tr>
<!-- <tr>-->
<!-- <td class="layui-td-gray">商户分类<font>*</font>-->
<!-- </td>-->
<!-- <td colspan="3">-->
<!-- <div id="mer_cate_id"></div>-->
<!-- </td>-->
<!-- </tr>-->
<tr>
<td class="layui-td-gray" style="vertical-align:top;">商品封面图</td>
@ -102,6 +126,12 @@
</td>
</tr>
<tr>
<td class="layui-td-gray">商品编码<font>*</font></td>
<td colspan="7"><input type="text" name="bar_code" lay-verify="required" lay-reqText="请输入商品编码"
autocomplete="off" placeholder="请输入商品编码" class="layui-input" value="{$detail.bar_code}"></td>
</tr>
<tr>
<td class="layui-td-gray">单位<font>*</font></td>
<td colspan="7"><input type="text" name="unit_name" lay-verify="required" lay-reqText="请输入单位"
@ -165,6 +195,8 @@
var moduleInit = ['tool', 'tagpicker', 'tinymce'];
var group_access = "{:session('gougu_admin')['group_access']}";
var multiple_images = "{$detail['slider_image']}".split(',');
var cate_id = "{$detail['cate_id']}";
var mer_cate_id = "{$detail['mer_cate_id']}";
//单击图片删除图片 【注册全局函数】
function delMultipleImgs(this_img){
//获取下标
@ -224,6 +256,56 @@
}
});
function demo_cate_id () {
var demo_cate = xmSelect.render({
name: 'cate_id',
el: '#cate_id',
initValue: [cate_id],
autoRow: true,
cascader: {
show: true,
indent: 200,
},
prop: {
name: 'name',
value: 'id',
},
data: [],
radio: true,
})
$.get('/admin/api/category_arr', function (result) {
demo_cate.update({
data: result.data
})
});
}
demo_cate_id()
function demo_mer_cate_id () {
var demo_cate = xmSelect.render({
name: 'mer_cate_id',
el: '#mer_cate_id',
autoRow: true,
initValue: [mer_cate_id],
cascader: {
show: true,
indent: 200,
},
prop: {
name: 'name',
value: 'id',
},
data: [],
radio: true,
})
$.get('/admin/api/category_arr?id=4', function (result) {
demo_cate.update({
data: result.data
})
});
}
demo_mer_cate_id()
var editor = layui.tinymce;
var edit = editor.render({
selector: "#container_content",
@ -236,6 +318,17 @@
layer.msg('请先完善商品详情');
return false;
}
if (data.field.cate_id == '') {
layer.msg('请先选择平台分类');
return false;
}
if (data.field.mer_cate_id == '') {
layer.msg('请先选择商户分类');
return false;
}
let callback = function (e) {
layer.msg(e.msg);
if (e.code == 0) {

View File

@ -0,0 +1,377 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<style>
.layui-input-inline{
width:35% !important;
}
.layui-input-inline .layui-form-item{
display:flex;
}
.layui-input-inline .layui-form-item .layui-form-label{
width:30%;
}
.layui-input-block{
margin-left:unset !important;
width:75%;
}
#seleform{
border-color: #eee;
background-color: #fff;
color:#a39f9f;
width:100%;
}
</style>
<div class="p-3">
<form id="filterform" class="layui-form gg-form-bar border-t border-x">
<div class="layui-form-item">
<div class="layui-input-inline">
<div class="layui-form-item">
<label class="layui-form-label">商品分类</label>
<div class="layui-input-block">
<input id="store_cate" type="hidden" readonly="readonly" name="store_cate">
<button id="seleform" lay-filter="seleform" class="layui-btn">请选择</button>
<div id="removeselect"><i class="bi-x-lg" style="position: absolute;right:2px;top:10px;z-index: 9;cursor:pointer;"></i></div>
</div>
</div>
</div>
</div>
<div class="layui-input-inline" style="width:300px;">
<input type="text" name="keywords" placeholder="请输入关键字" class="layui-input" autocomplete="off" />
</div>
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="searchform">提交搜索</button>
</form>
<table class="layui-hide" id="store_product" lay-filter="store_product"></table>
</div>
<script type="text/html" id="barDemo">
<div class="layui-btn-group"><a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="read">采购</a><a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="joincar">加入购物车</a></div>
</script>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
const moduleInit = ['tool'];
function gouguInit() {
var table = layui.table,tool = layui.tool, form = layui.form;
layui.pageTable = table.render({
elem: '#store_product',
title: '商品表列表',
toolbar: '#toolbarDemo',
url: '/admin/store_product/index',
page: true,
limit: 20,
cellMinWidth: 300,
cols: [
[
{
fixed: 'left',
field: 'product_id',
title: '编号',
align: 'center',
width: 80
},{
field: 'shangjia',
title: '商家',
align: 'center',
width: 100
},{
field: 'image',
title: '商品图片',
align: 'center',
width: 100,
templet: '<div><img src="{{ d.image }}" style="width:30px; height:30px;"></div>',
},{
field: 'store_name',
title: '商品名称',
align: 'center',
width: 100
},{
field: 'store_info',
title: '商品简介',
align: 'center',
width: 100
},{
field: 'stock',
title: '总库存',
align: 'center',
width: 100
},{
field: 'keyword',
title: '关键字',
align: 'center',
width: 100
},{
field: 'brand_id',
title: '品牌 id',
align: 'center',
width: 100
},{
field: 'cate_id',
title: '分类',
align: 'center',
width: 100
},{
field: 'unit_name',
title: '单位名',
align: 'center',
width: 100
},{
field: 'sales',
title: '销量',
align: 'center',
width: 100
},{
field: 'price',
title: '最低价格',
align: 'center',
width: 100
},{
field: 'cost',
title: '成本价',
align: 'center',
width: 100
},{
field: 'ot_price',
title: '原价',
align: 'center',
width: 100
}, {
fixed: 'right',
field: 'right',
title: '操作',
toolbar: '#barDemo',
width: 136,
align: 'center'
}
]
]
});
//监听表头工具栏事件
table.on('toolbar(store_product)', function(obj){
if (obj.event === 'add') {
tool.side("/admin/store_product/add");
return false;
}
});
//监听表格行工具事件
table.on('tool(store_product)', function(obj) {
var data = obj.data;
if (obj.event === 'read') {
// tool.side('/admin/store_product/buy?product_id='+obj.data.product_id);
var index = layer.open({
type: 2,
title: '购买商品',
shadeClose: true,
shade: false,
maxmin: false, //开启最大化最小化按钮
area: ['1000px', '800px'],
content: '/admin/store_product/buy?product_id='+obj.data.product_id
});
}
else if (obj.event === 'edit') {
tool.side('/admin/store_product/edit?product_id='+obj.data.product_id);
}
else if (obj.event === 'joincar') {
layer.open({
type: 1,
area: ["400px", "200px"],
title: "加入购物车",
content: "<input type=\"text\" name=\"number\" lay-verify=\"required|number\" placeholder=\"输入加入购物车数量\" lay-reqtext=\"请输入数字\" autocomplete=\"off\" class=\"layui-input\" id='carnum' min='1 '>",
btn: ['确定', '关闭'],
yes: function (index, layero) {
//ajax。必填参数'options':请求参数,对象,'callback':成功回调函数
// 单击之后提交按钮不可选,防止重复提交
var DISABLED = 'layui-btn-disabled';
// 增加样式
$('.layui-layer-btn0').addClass(DISABLED);
// 增加属性
$('.layui-layer-btn0').attr('disabled', 'disabled');
let options = {
url: '/admin/store_product/joincar',
type: 'get',
data: {
product_id: obj.data.product_id,
cart_num:$('#carnum').val(),
is_new:1,
}
};
let callback = function(res) {
if (res.code == 200) {
layer.msg('加入成功',{time:2000,icon:6});
// 关闭所有层
setTimeout(function () {
layer.closeAll();
}, 2000);
}else{
layer.msg(res.msg,{time:2000,icon:2});
$('.layui-layer-btn0').removeClass(DISABLED);
$('.layui-layer-btn0').removeAttr('disabled');
}
}
tool.ajax(options, callback);
},
cancel: function (layer_window) {
// 关闭弹出框页面
layer.close(layer_window);
}
});
}
else if (obj.event === 'del') {
layer.confirm('确定要删除该记录吗?', {
icon: 3,
title: '提示'
}, function(index) {
let callback = function (e) {
layer.msg(e.msg);
if (e.code == 0) {
obj.del();
}
}
tool.delete("/admin/store_product/del", { product_id: data.product_id }, callback);
layer.close(index);
});
}
return false;
});
// 商户商品分类搜索
layui.use(['rate','dropdown', 'util', 'layer', 'table'], function(){
var dropdown = layui.dropdown
,util = layui.util
,layer = layui.layer
,rate = layui.rate
// ,table = layui.table
,$ = layui.jquery;
var $ = layui.$, active = {
reload: function(){
let dataRload = getformdata();
//执行重载
table.reload('store_product', {
page: {
curr: 1 //重新从第 1 页开始
}
,where: {
...dataRload
}
});
},
};
//商户商品分类菜单
$.ajax({
url: '/admin/api/getAllList',
method: "get",
data: {},
success: function(res) {
if (res.code!==0)return ;
//高级演示 - 各种组合
dropdown.render({
elem: '#seleform'
,isAllowSpread: false //禁止菜单组展开收缩
,style: 'width: 200px' //定义宽度,默认自适应
,id: 'test777' //定义唯一索引
,title: 'title1'
,data: res.data
,click: function(item){
$('#seleform').text(item.title);
$('#seleform').css({color:'rgba(0,0,0,.85)'});
$('#store_cate').val(item.id);
active['reload'] ? active['reload'].call(this) : '';
}
});
},
fail:function(){}
});
//基础效果
rate.render({
elem: '#is_good'
})
//监听搜索提交
form.on('submit(searchform)', function(data) {
layui.pageTable.reload({
where: {
...data.field
},
page: {
curr: 1
}
});
return false;
});
//监听select提交
form.on('select(seleform)', function(data) {
active['reload'] ? active['reload'].call(this) : '';
return false;
});
//监听removeselect点击
$('#removeselect').on('click', function(){
$('#seleform').text('请选择');
$('#seleform').css({color:'#a39f9f'});
$('#store_cate').val('');
active['reload'] ? active['reload'].call(this) : '';
return false;
});
// tab 状态列表切换
$('.site-demo-active').on('click', function(){
var othis = $(this), type = othis.data('type');
$('#protype').val(this.getAttribute('type'));
active[type] ? active[type].call(this, othis) : '';
});
});
// //监听搜索提交
// form.on('submit(searchform)', function(data) {
// layui.pageTable.reload({
// where: {
// keywords: data.field.keywords
// },
// page: {
// curr: 1
// }
// });
// return false;
// });
// 获取表单所有参数
function getformdata() {
var form = $('#filterform').serializeArray();
var data = new Array();
for(let i=0;i<form.length; i++){
data[form[i].name] = form[i].value;
}
return data;
}
}
</script>
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,238 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<style>
.layui-input-inline{
width:35% !important;
}
.layui-input-inline .layui-form-item{
display:flex;
}
.layui-input-inline .layui-form-item .layui-form-label{
width:30%;
}
.layui-input-block{
margin-left:unset !important;
width:75%;
}
#seleform{
border-color: #eee;
background-color: #fff;
color:#a39f9f;
width:100%;
}
</style>
<div class="p-3">
<form id="filterform" class="layui-form gg-form-bar border-t border-x">
<div class="layui-input-inline" style="width:300px;">
<input type="text" name="keywords" placeholder="请输入订单号" class="layui-input" autocomplete="off" />
</div>
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="searchform">提交搜索</button>
</form>
<table class="layui-hide" id="store_product" lay-filter="store_product"></table>
</div>
<script type="text/html" id="barDemo">
<div class="layui-btn-group"></div>
</script>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
const moduleInit = ['tool'];
function gouguInit() {
var table = layui.table,tool = layui.tool, form = layui.form;
layui.pageTable = table.render({
elem: '#store_product',
title: '商品表列表',
toolbar: '#toolbarDemo',
url: '/admin/store_product/log',
page: true,
limit: 20,
cellMinWidth: 300,
cols: [
[
{
fixed: 'left',
field: 'id',
title: '编号',
align: 'center',
width: 80
},{
field: 'order_sn',
title: '订单号',
align: 'center',
width: 180
},{
field: 'paid_at',
title: '交易时间',
align: 'center',
width: 150,
},{
field: 'name',
title: '对方信息',
align: 'center',
width: 150
},{
field: 'type',
title: '交易类型',
align: 'center',
width: 100
},{
field: 'total_fee',
title: '收支金额(元)',
align: 'center',
width: 150
}, {
fixed: 'right',
field: 'right',
title: '操作',
toolbar: '#barDemo',
width: 136,
align: 'center'
}
]
]
});
//监听表头工具栏事件
table.on('toolbar(store_product)', function(obj){
if (obj.event === 'add') {
tool.side("/admin/store_product/add");
return false;
}
if (obj.event === 'adds') {
tool.side("/admin/store_product/adds");
return false;
}
});
// 商户商品分类搜索
layui.use(['rate','dropdown', 'util', 'layer', 'table'], function(){
var dropdown = layui.dropdown
,util = layui.util
,layer = layui.layer
,rate = layui.rate
// ,table = layui.table
,$ = layui.jquery;
var $ = layui.$, active = {
reload: function(){
let dataRload = getformdata();
//执行重载
table.reload('store_product', {
page: {
curr: 1 //重新从第 1 页开始
}
,where: {
...dataRload
}
});
},
};
//基础效果
rate.render({
elem: '#is_good'
})
//监听搜索提交
form.on('submit(searchform)', function(data) {
layui.pageTable.reload({
where: {
...data.field
},
page: {
curr: 1
}
});
return false;
});
//监听select提交
form.on('select(seleform)', function(data) {
active['reload'] ? active['reload'].call(this) : '';
return false;
});
//监听removeselect点击
$('#removeselect').on('click', function(){
$('#seleform').text('请选择');
$('#seleform').css({color:'#a39f9f'});
$('#store_cate').val('');
active['reload'] ? active['reload'].call(this) : '';
return false;
});
// tab 状态列表切换
$('.site-demo-active').on('click', function(){
var othis = $(this), type = othis.data('type');
$('#protype').val(this.getAttribute('type'));
active[type] ? active[type].call(this, othis) : '';
});
});
//监听表格行工具事件
table.on('tool(store_product)', function(obj) {
var data = obj.data;
if (obj.event === 'read') {
tool.side('/admin/store_product/read?product_id='+obj.data.product_id);
}
else if (obj.event === 'edit') {
tool.side('/admin/store_product/edit?product_id='+obj.data.product_id);
}
else if (obj.event === 'del') {
layer.confirm('确定要删除该记录吗?', {
icon: 3,
title: '提示'
}, function(index) {
let callback = function (e) {
layer.msg(e.msg);
if (e.code == 0) {
obj.del();
}
}
tool.delete("/admin/store_product/del", { product_id: data.product_id }, callback);
layer.close(index);
});
}
return false;
});
//监听搜索提交
form.on('submit(searchform)', function(data) {
layui.pageTable.reload({
where: {
keywords: data.field.keywords
},
page: {
curr: 1
}
});
return false;
});
// 获取表单所有参数
function getformdata() {
var form = $('#filterform').serializeArray();
var data = new Array();
for(let i=0;i<form.length; i++){
data[form[i].name] = form[i].value;
}
return data;
}
}
</script>
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,392 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<style>
.layui-input-inline{
width:35% !important;
}
.layui-input-inline .layui-form-item{
display:flex;
}
.layui-input-inline .layui-form-item .layui-form-label{
width:30%;
}
.layui-input-block{
margin-left:unset !important;
width:75%;
}
#seleform{
border-color: #eee;
background-color: #fff;
color:#a39f9f;
width:100%;
}
</style>
<div class="p-3">
<div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief">
<ul class="layui-tab-title">
<li class="layui-this site-demo-active" type="1" data-type="reload">预订单</li>
<li class="site-demo-active" type="2" data-type="reload">已支付订单</li>
</ul>
</div>
<form id="filterform" class="layui-form gg-form-bar border-t border-x">
<input id="protype" type="hidden" name="type" value="1">
<div class="layui-form-item">
<!-- <div class="layui-input-inline">-->
<!-- <div class="layui-form-item">-->
<!-- <label class="layui-form-label">商品分类</label>-->
<!-- <div class="layui-input-block">-->
<!-- <input id="store_cate" type="hidden" readonly="readonly" name="store_cate">-->
<!-- <button id="seleform" lay-filter="seleform" class="layui-btn">请选择</button>-->
<!-- <div id="removeselect"><i class="bi-x-lg" style="position: absolute;right:2px;top:10px;z-index: 9;cursor:pointer;"></i></div>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
</div>
<div class="layui-input-inline" style="width:300px;">
<input type="text" name="keywords" placeholder="请输入订单号" class="layui-input" autocomplete="off" />
</div>
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="searchform">提交搜索</button>
</form>
<table class="layui-hide" id="store_product" lay-filter="store_product"></table>
</div>
<script type="text/html" id="barDemo">
<div class="layui-btn-group">
<a class="layui-btn layui-btn-normal layui-btn-xs preservation {{# if(d.status != 0){ }}layui-hide{{# } }}" lay-event="topay">去支付</a>
</div>
</script>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
const moduleInit = ['tool'];
function gouguInit() {
var table = layui.table,tool = layui.tool, form = layui.form;
layui.pageTable = table.render({
elem: '#store_product',
title: '列表',
toolbar: '#toolbarDemo',
url: '/admin/store_product/order',
page: true,
limit: 20,
cellMinWidth: 300,
cols: [
[
{
fixed: 'left',
field: 'id',
title: '编号',
align: 'center',
width: 80
},{
field: 'order_sn',
title: '订单号',
align: 'center',
width: 200,
},{
field: 'number',
title: '购买数量',
align: 'center',
width: 100
},{
field: 'total_fee',
title: '订单金额',
align: 'center',
width: 100
},{
field: 'name',
title: '商户',
align: 'center',
width: 200,
},{
field: 'product',
title: '商品简介',
align: 'center',
width: 300,
templet: function (d) {
var html = '<div>';
var img = '';
var prod = d.product;
for (i = 0; i < prod.length; i++) {
img = '<img src="'+prod[i].image+'" style="width:30px; height:30px;"> '+prod[i].store_name + '&nbsp;' +img;
}
var html2 = '</div>';
// var html = '<div><img src="'+d[k].image+'" style="width:30px; height:30px;"> '+d[k].store_name+'</div>';
var ret = html + img + html2;
return ret;
}
},{
field: 'paid_at',
title: '支付完成时间',
align: 'center',
width: 150,
},{
field: 'status',
title: '状态',
align: 'center',
width: 100,
templet: function (d) {
var html = '<span style="color:#fbbc05">未支付</span>';
if (d.status == '1') {
html = '<span style="color:#12bb37">已支付</span>';
}
return html;
}
}, {
fixed: 'right',
field: 'right',
title: '操作',
toolbar: '#barDemo',
width: 136,
align: 'center'
}
]
]
});
//监听表头工具栏事件
table.on('toolbar(store_product)', function(obj){
if (obj.event === 'add') {
tool.side("/admin/store_product/add");
return false;
}
});
//监听表格行工具事件
table.on('tool(store_product)', function(obj) {
var data = obj.data;
if (obj.event === 'topay') {
// 单击之后提交按钮不可选,防止重复提交
var DISABLED = 'layui-btn-disabled';
// 增加样式
$('.preservation').addClass(DISABLED);
// 增加属性
$('.preservation').attr('disabled', 'disabled');
$.ajax({
url : "/admin/store_product/payorder?id="+data.id, //请求的url地址
dataType : "json", //返回格式为json
async : true,//请求是否异步默认为异步这也是ajax重要特性
type : "POST", //请求方式
success : function(data) {
var url = data.data.html;
/** 弹出二维码 **/
layer.open({
//type:1 表示页面层
type: 1,
title: '扫码支付',
//是否点击遮罩关闭
shadeClose: false,
//样式类名,可以自定义弹窗样式
//弹层外区域
shade: 0.3,
maxmin: false, //开启最大化最小化按钮
//宽高
area: ['250px','250px'],
//内容
content: "<img src='"+url+"' alt='' style='margin-left: 40px;'>",
});
/** 设置定时器, 即一弹出二维码就开始不断请求查看支付状态, 直到收到支付成功的返回, 再终止定时器 **/
var timer = setInterval(function () {
/** 在这里请求微信支付状态的接口 **/
//ajax。必填参数'options':请求参数,对象,'callback':成功回调函数
let options = {
url: '/admin/store_product/paid',
type: 'get',
data: {
out_trade_no: data.data.order_sn,
}
};
let callback = function(res) {
if (res.code == 200) {
layer.msg('支付成功',{time:2000,icon:6});
/** 如果支付成功, 就取消定时器, 并重新加载页面 */
window.clearInterval(timer);
// 关闭所有层
setTimeout(function () {
layer.closeAll();
}, 2000);
// tool.sideClose(2000);
}
}
tool.ajax(options, callback);
}, 3000);
},
complete : function() {
//请求完成的处理
},
error : function() {
//请求出错处理
layer.alert("系统异常");
}
});
// 恢复按钮
var DISABLED = 'layui-btn-disabled';
$('.preservation').removeClass(DISABLED);
$('.preservation').removeAttr('disabled');
}
else if (obj.event === 'edit') {
tool.side('/admin/store_product/edit?product_id='+obj.data.product_id);
}
else if (obj.event === 'del') {
layer.confirm('确定要删除该记录吗?', {
icon: 3,
title: '提示'
}, function(index) {
let callback = function (e) {
layer.msg(e.msg);
if (e.code == 0) {
obj.del();
}
}
tool.delete("/admin/store_product/del", { product_id: data.product_id }, callback);
layer.close(index);
});
}
return false;
});
// 商户商品分类搜索
layui.use(['rate','dropdown', 'util', 'layer', 'table'], function(){
var dropdown = layui.dropdown
,util = layui.util
,layer = layui.layer
,rate = layui.rate
// ,table = layui.table
,$ = layui.jquery;
var $ = layui.$, active = {
reload: function(){
let dataRload = getformdata();
//执行重载
table.reload('store_product', {
page: {
curr: 1 //重新从第 1 页开始
}
,where: {
...dataRload
}
});
},
};
//商户商品分类菜单
$.ajax({
url: '/admin/api/getAllList',
method: "get",
data: {},
success: function(res) {
if (res.code!==0)return ;
//高级演示 - 各种组合
dropdown.render({
elem: '#seleform'
,isAllowSpread: false //禁止菜单组展开收缩
,style: 'width: 200px' //定义宽度,默认自适应
,id: 'test777' //定义唯一索引
,title: 'title1'
,data: res.data
,click: function(item){
$('#seleform').text(item.title);
$('#seleform').css({color:'rgba(0,0,0,.85)'});
$('#store_cate').val(item.id);
active['reload'] ? active['reload'].call(this) : '';
}
});
},
fail:function(){}
});
//基础效果
rate.render({
elem: '#is_good'
})
//监听搜索提交
form.on('submit(searchform)', function(data) {
layui.pageTable.reload({
where: {
...data.field
},
page: {
curr: 1
}
});
return false;
});
//监听select提交
form.on('select(seleform)', function(data) {
active['reload'] ? active['reload'].call(this) : '';
return false;
});
//监听removeselect点击
$('#removeselect').on('click', function(){
$('#seleform').text('请选择');
$('#seleform').css({color:'#a39f9f'});
$('#store_cate').val('');
active['reload'] ? active['reload'].call(this) : '';
return false;
});
// tab 状态列表切换
$('.site-demo-active').on('click', function(){
var othis = $(this), type = othis.data('type');
$('#protype').val(this.getAttribute('type'));
active[type] ? active[type].call(this, othis) : '';
});
});
// //监听搜索提交
// form.on('submit(searchform)', function(data) {
// layui.pageTable.reload({
// where: {
// keywords: data.field.keywords
// },
// page: {
// curr: 1
// }
// });
// return false;
// });
// 获取表单所有参数
function getformdata() {
var form = $('#filterform').serializeArray();
var data = new Array();
for(let i=0;i<form.length; i++){
data[form[i].name] = form[i].value;
}
return data;
}
}
</script>
{/block}
<!-- /脚本 -->

View File

@ -7,7 +7,7 @@
<!-- 主体 -->
{block name="body"}
<div class="layui-form p-4">
<h3 class="pb-3">文章详情</h3>
<h3 class="pb-3">详情</h3>
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray">商品名称<font>*</font></td>
@ -27,34 +27,58 @@
<!-- </div>-->
<!-- </td>-->
<!-- </tr>-->
<tr>
<td class="layui-td-gray">商户商品分类<font>*</font></td>
<td colspan="3">
<div class="layui-col-md6">
<select name="cate_id" lay-verify="required" lay-search="">
<option value="" >请选择</option>
{volist name=':set_recursion(get_store_category())' id='vo'}
<option value="{$vo.id}" {if $detail.cate_id==$vo.id} selected {/if}>{$vo.title}</option>
{/volist}
</select>
</div>
</td>
</tr>
<!-- <tr>-->
<!-- <td class="layui-td-gray">商户商品分类<font>*</font></td>-->
<!-- <td colspan="3">-->
<!-- <div class="layui-col-md6">-->
<!-- <select name="cate_id" lay-verify="required" lay-search="">-->
<!-- <option value="" >请选择</option>-->
<!-- {volist name=':set_recursion(get_store_category())' id='vo'}-->
<!-- <option value="{$vo.id}" {if $detail.cate_id==$vo.id} selected {/if}>{$vo.title}</option>-->
<!-- {/volist}-->
<!-- </select>-->
<!-- </div>-->
<!-- </td>-->
<!-- </tr>-->
<!-- <tr>-->
<!-- <td class="layui-td-gray">品牌选择<font>*</font></td>-->
<!-- <td colspan="3">-->
<!-- <div class="layui-col-md6">-->
<!-- <select name="brand_id" lay-verify="required" lay-search="">-->
<!-- <option value="" >请选择</option>-->
<!-- {volist name='store_brand' id='vo'}-->
<!-- <option value="{$vo.brand_id}" {if $detail.brand_id==$vo.brand_id} selected {/if}>{$vo.brand_name}</option>-->
<!-- {/volist}-->
<!-- </select>-->
<!-- </div>-->
<!-- </td>-->
<!-- </tr>-->
<tr>
<td class="layui-td-gray">品牌选择<font>*</font></td>
<td colspan="3">
<div class="layui-col-md6">
<select name="brand_id" lay-verify="required" lay-search="">
<option value="" >请选择</option>
{volist name='store_brand' id='vo'}
<option value="{$vo.brand_id}" {if $detail.brand_id==$vo.brand_id} selected {/if}>{$vo.brand_name}</option>
{/volist}
</select>
</div>
<td class="layui-td-gray">平台商品分类<font>*</font>
</td>
<td>
<div id="cate_id"></div>
</td>
<!-- <td class="layui-td-gray">品牌选择<font>*</font>-->
<!-- </td>-->
<!-- <td colspan="6">-->
<!-- <select name="brand_id" lay-verify="required" lay-search="" disabled>-->
<!-- <option value="">请选择</option>-->
<!-- {volist name='store_brand' id='vo'}-->
<!-- <option value="{$vo.brand_id}" {if $detail.brand_id==$vo.brand_id} selected {/if}>{$vo.brand_name}</option>-->
<!-- {/volist}-->
<!-- </select>-->
<!-- </td>-->
</tr>
<!-- <tr>-->
<!-- <td class="layui-td-gray">商户分类<font>*</font>-->
<!-- </td>-->
<!-- <td colspan="3">-->
<!-- <div id="mer_cate_id"></div>-->
<!-- </td>-->
<!-- </tr>-->
<tr>
<td class="layui-td-gray" style="vertical-align:top;">商品封面图</td>
@ -96,6 +120,12 @@
</td>
</tr>
<tr>
<td class="layui-td-gray">商品编码<font>*</font></td>
<td colspan="7"><input type="text" name="bar_code" lay-verify="required" lay-reqText="请输入商品编码"
autocomplete="off" placeholder="请输入商品编码" class="layui-input" value="{$detail.bar_code}"></td>
</tr>
<tr>
<td class="layui-td-gray">单位<font>*</font></td>
<td colspan="7"><input type="text" name="unit_name" lay-verify="required" lay-reqText="请输入单位"
@ -145,4 +175,160 @@
</table>
</div>
{/block}
<!-- /主体 -->
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script src="/static/assets/js/xm-select.js"></script>
<script>
var moduleInit = ['tool', 'tagpicker', 'tinymce'];
var group_access = "{:session('gougu_admin')['group_access']}";
var multiple_images = "{$detail['slider_image']}".split(',');
var cate_id = "{$detail['cate_id']}";
var mer_cate_id = "{$detail['mer_cate_id']}";
//单击图片删除图片 【注册全局函数】
function delMultipleImgs(this_img){
//获取下标
var subscript=$("#upload_box_thumb2 img").index(this_img);
//删除图片
this_img.remove();
//删除数组
multiple_images.splice(subscript, 1);
//重新排序
multiple_images.sort();
$('#upload_box_thumb2 input').attr('value', multiple_images);
//返回
return ;
}
function gouguInit() {
var form = layui.form, tool = layui.tool, tagpicker = layui.tagpicker;
//上传缩略图
var upload_thumb = layui.upload.render({
elem: '#upload_btn_thumb',
url: '/admin/api/upload',
done: function (res) {
//如果上传失败
if (res.code == 1) {
layer.msg('上传失败');
return false;
}
//上传成功
$('#upload_box_thumb input').attr('value', res.data.filepath);
$('#upload_box_thumb img').attr('src', res.data.filepath);
}
});
//上传商品轮播图
var upload_thumb = layui.upload.render({
elem: '#upload_btn_thumb2',
url: '/admin/api/upload',
multiple: true,
before: function(obj){
//预读本地文件示例不支持ie8
obj.preview(function(index, file, result){
$('#upload_box_thumb2').append(`
<img src="${result}"
onerror="javascript:this.src='{__GOUGU__}/gougu/images/nonepic600x360.jpg';this.onerror=null;"
width="100" style="max-width: 100%; height:66px;" alt="${file.name}" onclick="delMultipleImgs(this)" title="点击删除"/>
`)
});
},
done: function (res) {
//如果上传失败
if (res.code == 1) {
return layer.msg('上传失败');
}
//上传成功
//追加图片成功追加文件名至图片容器
multiple_images.push(res.data.filepath);
$('#upload_box_thumb2 input').attr('value', multiple_images);
// $('#upload_box_thumb2 img').attr('src', res.data.filepath);
}
});
function demo_cate_id () {
var demo_cate = xmSelect.render({
name: 'cate_id',
el: '#cate_id',
initValue: [cate_id],
autoRow: true,
cascader: {
show: true,
indent: 200,
},
prop: {
name: 'name',
value: 'id',
},
data: [],
radio: true,
disabled:true,
})
$.get('/admin/api/category_arr', function (result) {
demo_cate.update({
data: result.data
})
});
}
demo_cate_id()
function demo_mer_cate_id () {
var demo_cate = xmSelect.render({
name: 'mer_cate_id',
el: '#mer_cate_id',
autoRow: true,
initValue: [mer_cate_id],
cascader: {
show: true,
indent: 200,
},
prop: {
name: 'name',
value: 'id',
},
data: [],
radio: true,
disabled:true,
})
$.get('/admin/api/category_arr?id=4', function (result) {
demo_cate.update({
data: result.data
})
});
}
demo_mer_cate_id()
var editor = layui.tinymce;
var edit = editor.render({
selector: "#container_content",
height: 500
});
//监听提交
form.on('submit(webform)', function (data) {
data.field.content = tinyMCE.editors['container_content'].getContent();
if (data.field.content == '') {
layer.msg('请先完善商品详情');
return false;
}
if (data.field.cate_id == '') {
layer.msg('请先选择平台分类');
return false;
}
if (data.field.mer_cate_id == '') {
layer.msg('请先选择商户分类');
return false;
}
let callback = function (e) {
layer.msg(e.msg);
if (e.code == 0) {
tool.sideClose(1000);
}
}
tool.post("/admin/store_product/edit", data.field, callback);
return false;
});
}
</script>
{/block}

View File

@ -0,0 +1,209 @@
{extend name="common/base"/}
{block name="style"}
<style type="text/css">
.editormd-code-toolbar select {
display: inline-block
}
.editormd li {
list-style: inherit;
}
</style>
{/block}
<!-- 主体 -->
{block name="body"}
<div class="layui-form p-4">
<h3 class="pb-3">收款方式</h3>
<div class="layui-tab layui-tab-card">
<ul class="layui-tab-title">
<li class="layui-this">银行卡</li>
<li>微信</li>
<li>支付宝</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<form class="layui-form p-4">
<div class="layui-form-item">
<label class="layui-form-label">姓名</label>
<div class="layui-input-block">
<input type="text" value="{$arr.card_name}" autocomplete="off" class="layui-input" name="card_name">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">开户银行</label>
<div class="layui-input-block">
<input type="text" name="bank" value="{$arr.bank}" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">银行卡号</label>
<div class="layui-input-block">
<input type="text" name="card_code" value="{$arr.card_code}" autocomplete="off" class="layui-input">
</div>
</div>
<div class="pt-3">
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform1">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</form>
</div>
<div class="layui-tab-item">
<form class="layui-form p-4">
<div class="layui-form-item">
<label class="layui-form-label">姓名</label>
<div class="layui-input-block">
<input type="text" name="wechat_name" value="{$arr['wechat_name']}" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">微信号</label>
<div class="layui-input-block">
<input type="text" name="wechat_code" value="{$arr['wechat_code']}" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-upload layui-input-block">
<button type="button" class="layui-btn layui-btn-sm" id="upload_btn_thumb">
微信收款二维码
</button>
<div class="layui-upload-list" id="upload_box_thumb"
style=" overflow: hidden;">
<img src="{$arr.wechat_img}"
onerror="javascript:this.src='{__GOUGU__}/gougu/images/nonepic600x360.jpg';this.onerror=null;"
width="100" style="max-width: 100%; height:66px;"/>
<input type="hidden" name="wechat_img" value="">
</div>
</div>
</div>
<div class="pt-3">
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform2">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</form>
</div>
<div class="layui-tab-item">
<form class="layui-form p-4">
<div class="layui-form-item">
<label class="layui-form-label">姓名</label>
<div class="layui-input-block">
<input type="text" name="alipay_name" value="{$arr['alipay_name']}" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">支付宝账号</label>
<div class="layui-input-block">
<input type="text" name="alipay_code" value="{$arr['alipay_code']}" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-upload layui-input-block">
<button type="button" class="layui-btn layui-btn-sm" id="upload_btn_thumb2">
支付宝收款二维码
</button>
<div class="layui-upload-list" id="upload_box_thumb2"
style=" overflow: hidden;">
<img src="{$arr.alipay_img}"
onerror="javascript:this.src='{__GOUGU__}/gougu/images/nonepic600x360.jpg';this.onerror=null;"
width="100" style="max-width: 100%; height:66px;"/>
<input type="hidden" name="alipay_img" value="">
</div>
</div>
</div>
<div class="pt-3">
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform3">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</form>
</div>
</div>
</div>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
var moduleInit = ['tool'];
function ceshi(e){
$(e).parent().remove();
}
function gouguInit () {
var form = layui.form, tool = layui.tool;
//上传缩略图
var upload_thumb = layui.upload.render({
elem: '#upload_btn_thumb',
url: '/admin/api/upload',
done: function (res) {
//如果上传失败
if (res.code == 1) {
return layer.msg('上传失败');
}
//上传成功
$('#upload_box_thumb input').attr('value', res.data.filepath);
$('#upload_box_thumb img').attr('src', res.data.filepath);
}
});
//上传缩略图
var upload_thumb2 = layui.upload.render({
elem: '#upload_btn_thumb2',
url: '/admin/api/upload',
done: function (res) {
//如果上传失败
if (res.code == 1) {
return layer.msg('上传失败');
}
//上传成功
$('#upload_box_thumb2 input').attr('value', res.data.filepath);
$('#upload_box_thumb2 img').attr('src', res.data.filepath);
}
});
//监听提交
form.on('submit(webform1)', function (data) {
let callback = function (e) {
layer.msg(e.msg);
if (e.code == 200) {
tool.sideClose(1000);
}
}
tool.post("/admin/store_product/sktype", data.field, callback);
return false;
});
form.on('submit(webform2)', function (data) {
let callback = function (e) {
layer.msg(e.msg);
if (e.code == 200) {
tool.sideClose(1000);
}
}
tool.post("/admin/store_product/sktype", data.field, callback);
return false;
});
form.on('submit(webform3)', function (data) {
let callback = function (e) {
layer.msg(e.msg);
if (e.code == 200) {
tool.sideClose(1000);
}
}
tool.post("/admin/store_product/sktype", data.field, callback);
return false;
});
}
</script>
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,297 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<style>
.layui-input-inline{
width:35% !important;
}
.layui-input-inline .layui-form-item{
display:flex;
}
.layui-input-inline .layui-form-item .layui-form-label{
width:30%;
}
.layui-input-block{
margin-left:unset !important;
width:75%;
}
#seleform{
border-color: #eee;
background-color: #fff;
color:#a39f9f;
width:100%;
}
</style>
<div class="p-3">
<form id="filterform" class="layui-form gg-form-bar border-t border-x">
<div class="layui-form-item">
<div class="layui-input-inline">
<div class="layui-form-item">
<label class="layui-form-label">商品分类</label>
<div class="layui-input-block">
<input id="store_cate" type="hidden" readonly="readonly" name="store_cate">
<button id="seleform" lay-filter="seleform" class="layui-btn">请选择</button>
<div id="removeselect"><i class="bi-x-lg" style="position: absolute;right:2px;top:10px;z-index: 9;cursor:pointer;"></i></div>
</div>
</div>
</div>
</div>
<div class="layui-input-inline" style="width:300px;">
<input type="text" name="keywords" placeholder="请输入关键字" class="layui-input" autocomplete="off" />
</div>
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="searchform">提交搜索</button>
</form>
<table class="layui-hide" id="store_product" lay-filter="store_product"></table>
</div>
<script type="text/html" id="barDemo">
<div class="layui-btn-group"></div>
</script>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
const moduleInit = ['tool'];
function gouguInit() {
var table = layui.table,tool = layui.tool, form = layui.form;
layui.pageTable = table.render({
elem: '#store_product',
title: '商品表列表',
toolbar: '#toolbarDemo',
url: '/admin/store_product/stock',
page: true,
limit: 20,
cellMinWidth: 300,
cols: [
[
{
fixed: 'left',
field: 'product_id',
title: '编号',
align: 'center',
width: 80
},{
field: 'shangjia',
title: '商家',
align: 'center',
width: 100
},{
field: 'image',
title: '商品图片',
align: 'center',
width: 120,
templet: '<div><img src="{{ d.image }}" style="width:30px; height:30px;"></div>',
},{
field: 'store_name',
title: '商品名称',
align: 'center',
width: 200
},{
field: 'stock',
title: '总库存',
align: 'center',
width: 100
},{
field: 'bar_code',
title: '产品条码',
align: 'center',
width: 150
},{
field: 'cate_id',
title: '分类',
align: 'center',
width: 100
},{
field: 'price',
title: '最低价格',
align: 'center',
width: 100
},{
field: 'cost',
title: '成本价',
align: 'center',
width: 100
},{
field: 'ot_price',
title: '原价',
align: 'center',
width: 100
}
]
]
});
//监听表头工具栏事件
table.on('toolbar(store_product)', function(obj){
if (obj.event === 'add') {
tool.side("/admin/store_product/add");
return false;
}
if (obj.event === 'adds') {
tool.side("/admin/store_product/adds");
return false;
}
});
// 商户商品分类搜索
layui.use(['rate','dropdown', 'util', 'layer', 'table'], function(){
var dropdown = layui.dropdown
,util = layui.util
,layer = layui.layer
,rate = layui.rate
// ,table = layui.table
,$ = layui.jquery;
var $ = layui.$, active = {
reload: function(){
let dataRload = getformdata();
//执行重载
table.reload('store_product', {
page: {
curr: 1 //重新从第 1 页开始
}
,where: {
...dataRload
}
});
},
};
//商户商品分类菜单
$.ajax({
url: '/admin/api/getAllList',
method: "get",
data: {},
success: function(res) {
if (res.code!==0)return ;
//高级演示 - 各种组合
dropdown.render({
elem: '#seleform'
,isAllowSpread: false //禁止菜单组展开收缩
,style: 'width: 200px' //定义宽度,默认自适应
,id: 'test777' //定义唯一索引
,title: 'title1'
,data: res.data
,click: function(item){
$('#seleform').text(item.title);
$('#seleform').css({color:'rgba(0,0,0,.85)'});
$('#store_cate').val(item.id);
active['reload'] ? active['reload'].call(this) : '';
}
});
},
fail:function(){}
});
//基础效果
rate.render({
elem: '#is_good'
})
//监听搜索提交
form.on('submit(searchform)', function(data) {
layui.pageTable.reload({
where: {
...data.field
},
page: {
curr: 1
}
});
return false;
});
//监听select提交
form.on('select(seleform)', function(data) {
active['reload'] ? active['reload'].call(this) : '';
return false;
});
//监听removeselect点击
$('#removeselect').on('click', function(){
$('#seleform').text('请选择');
$('#seleform').css({color:'#a39f9f'});
$('#store_cate').val('');
active['reload'] ? active['reload'].call(this) : '';
return false;
});
// tab 状态列表切换
$('.site-demo-active').on('click', function(){
var othis = $(this), type = othis.data('type');
$('#protype').val(this.getAttribute('type'));
active[type] ? active[type].call(this, othis) : '';
});
});
//监听表格行工具事件
table.on('tool(store_product)', function(obj) {
var data = obj.data;
if (obj.event === 'read') {
tool.side('/admin/store_product/read?product_id='+obj.data.product_id);
}
else if (obj.event === 'edit') {
tool.side('/admin/store_product/edit?product_id='+obj.data.product_id);
}
else if (obj.event === 'del') {
layer.confirm('确定要删除该记录吗?', {
icon: 3,
title: '提示'
}, function(index) {
let callback = function (e) {
layer.msg(e.msg);
if (e.code == 0) {
obj.del();
}
}
tool.delete("/admin/store_product/del", { product_id: data.product_id }, callback);
layer.close(index);
});
}
return false;
});
//监听搜索提交
form.on('submit(searchform)', function(data) {
layui.pageTable.reload({
where: {
keywords: data.field.keywords
},
page: {
curr: 1
}
});
return false;
});
// 获取表单所有参数
function getformdata() {
var form = $('#filterform').serializeArray();
var data = new Array();
for(let i=0;i<form.length; i++){
data[form[i].name] = form[i].value;
}
return data;
}
}
</script>
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,414 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<style>
.layui-input-inline{
width:35% !important;
}
.layui-input-inline .layui-form-item{
display:flex;
}
.layui-input-inline .layui-form-item .layui-form-label{
width:30%;
}
.layui-input-block{
margin-left:unset !important;
width:75%;
}
#seleform{
border-color: #eee;
background-color: #fff;
color:#a39f9f;
width:100%;
}
</style>
<div class="p-3">
<form id="filterform" class="layui-form gg-form-bar border-t border-x">
<div class="layui-input-inline" style="width:300px;vertical-align:top;">
<div class="layui-form-item">
<label class="layui-form-label">状态</label>
<div class="layui-input-block">
<select name="status" lay-filter="seleform">
<option value=""></option>
<option value="2">审核中</option>
<option value="3">提现成功</option>
<option value="4">提现拒绝</option>
</select>
</div>
</div>
</div>
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="searchform">提交搜索</button>
</form>
<table class="layui-hide" id="store_product" lay-filter="store_product"></table>
</div>
<script type="text/html" id="toolbarDemo">
<div class="layui-btn-container">
<span class="layui-btn layui-btn-sm" lay-event="add" data-title="申请提现">申请提现</span>
</div>
</script>
<script type="text/html" id="barDemo">
<div class="layui-btn-group">
{if {:session('gougu_admin')['group_access']==1}
<a class="layui-btn layui-btn-normal layui-btn-xs {{# if(d.status != 2){ }}layui-hide{{# } }}" lay-event="pass">已打款</a>
<a class="layui-btn layui-btn-danger layui-btn-xs {{# if(d.status != 2){ }}layui-hide{{# } }}" lay-event="afuse">拒绝提现</a>
{/if}
</div>
</script>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
const moduleInit = ['tool'];
function gouguInit() {
var table = layui.table,tool = layui.tool, form = layui.form;
layui.pageTable = table.render({
elem: '#store_product',
title: '列表',
toolbar: '#toolbarDemo',
url: '/admin/store_product/tixian',
page: true,
limit: 20,
cellMinWidth: 300,
cols: [
[
{
field: 'id',
title: '编号',
align: 'center',
width: 80
},{
field: 'nickname',
title: '用户',
align: 'center',
width: 120,
},{
field: 'num',
title: '提现金额',
align: 'center',
width: 100
},{
field: 'skfs',
title: '收款方式',
align: 'center',
width:300,
templet: function (d)
{
if(d.skfs == 1)
{
return '银行卡姓名:'+d.find.card_name+', '+'开户银行:'+d.find.bank+', '+'银行卡号:'+d.find.card_code;
}
if(d.skfs == 2)
{
return '微信姓名:'+d.find.wechat_name+', '+'微信号:'+d.find.wechat_code+', '+'微信收款二维码:'+'<img src="'+d.find.wechat_img+'" style="width:40px; height:40px;">';
}
if(d.skfs == 3)
{
return '支付宝姓名:'+d.find.alipay_name+', '+'支付宝账号:'+d.find.alipay_code+', '+'支付宝收款二维码:'+'<img src="'+d.find.alipay_img+'" style="width:40px; height:40px;">';
}
return '无';
}
},{
field: 'create_time',
title: '提现时间',
align: 'center',
width: 150
},{
field: 'status',
title: '状态',
align: 'center',
width: 100,
templet: function (d)
{
switch (d.status) {
case 2:
return '审核中';
break;
case 4:
return '未通过';
break;
case 3:
return '提现完成';
break;
}
}
},{
field: 'admin_user',
title: '审核用户',
align: 'center',
width:120,
templet: function (d)
{
if(d.admin_user)
{
return d.admin_user;
}
if(d.status == 2)
{
return '等待审核';
}
return '无';
}
},{
field: 'fail_msg',
title: '拒绝原因',
align: 'center',
width:150,
},{
fixed: 'right',
field: 'right',
title: '操作',
toolbar: '#barDemo',
width: 136,
align: 'center'
}
]
],
id: 'testReload' ,
});
//监听表头工具栏事件
table.on('toolbar(store_product)', function(obj){
if (obj.event === 'add') {
tool.side('/admin/store_product/withdrawal');
return false;
}
});
// 表格点击行自动选中 ==========================================================================
$(document).on("click",".layui-table-body table.layui-table tbody tr", function (e) {
var index = $(this).attr('data-index');
var tableBox = $(this).parents('.layui-table-box');
//存在固定列
if (tableBox.find(".layui-table-fixed.layui-table-fixed-l").length > 0) {
tableDiv = tableBox.find(".layui-table-fixed.layui-table-fixed-l");
} else {
tableDiv = tableBox.find(".layui-table-body.layui-table-main");
}
var checkCell = tableDiv.find("tr[data-index=" + index + "]").find("td div.laytable-cell-checkbox div.layui-form-checkbox I");
if (checkCell.length > 0) {
checkCell.click();
}
});
// 表格点击行出发复选框后,阻止向上冒泡===============================================================
$(document).on("click", "td div.laytable-cell-checkbox div.layui-form-checkbox", function (e) {
e.stopPropagation();
});
//监听表格行工具事件
table.on('tool(store_product)', function(obj) {
var data = obj.data;
if (obj.event === 'afuse') {
layer.open({
type: 1,
area: ["400px", "200px"],
title: "拒绝提现",
content: "<input type=\"text\" name=\"fail_msg\" lay-verify=\"required\" placeholder=\"输入拒绝原因\" autocomplete=\"off\" class=\"layui-input\" id='fail_msg' min='1 '>",
btn: ['确定', '关闭'],
yes: function (index, layero) {
//ajax。必填参数'options':请求参数,对象,'callback':成功回调函数
// 单击之后提交按钮不可选,防止重复提交
var DISABLED = 'layui-btn-disabled';
// 增加样式
$('.layui-layer-btn0').addClass(DISABLED);
// 增加属性
$('.layui-layer-btn0').attr('disabled', 'disabled');
let options = {
url: '/admin/store_product/afuse',
type: 'get',
data: {
id: obj.data.id,
fail_msg:$('#fail_msg').val(),
}
};
let callback = function(res) {
if (res.code == 200) {
layer.msg('操作成功',{time:2000,icon:6});
// 关闭所有层
setTimeout(function () {
layer.closeAll();
}, 2000);
location.reload();
}else{
layer.msg(res.msg,{time:2000,icon:2});
$('.layui-layer-btn0').removeClass(DISABLED);
$('.layui-layer-btn0').removeAttr('disabled');
}
}
tool.ajax(options, callback);
},
cancel: function (layer_window) {
// 关闭弹出框页面
layer.close(layer_window);
}
});
}
else if (obj.event === 'edit') {
tool.side('/admin/store_product/edit?id='+obj.data.id);
}
else if (obj.event === 'pass') {
layer.confirm('确定要已打款吗?', {
icon: 3,
title: '提示'
}, function(index) {
let callback = function (e) {
layer.msg(e.msg,{time:2000,icon:6});
if(e.code == 200){
location.reload();
}
}
tool.delete("/admin/store_product/pass", { id: data.id }, callback);
layer.close(index);
});
}
return false;
});
// 商户商品分类搜索
layui.use(['rate','dropdown', 'util', 'layer', 'table'], function(){
var dropdown = layui.dropdown
,util = layui.util
,layer = layui.layer
,rate = layui.rate
// ,table = layui.table
,$ = layui.jquery;
var $ = layui.$, active = {
reload: function(){
let dataRload = getformdata();
//执行重载
table.reload('store_product', {
page: {
curr: 1 //重新从第 1 页开始
}
,where: {
...dataRload
}
});
},
};
//商户商品分类菜单
$.ajax({
url: '/admin/api/getAllList',
method: "get",
data: {},
success: function(res) {
if (res.code!==0)return ;
//高级演示 - 各种组合
dropdown.render({
elem: '#seleform'
,isAllowSpread: false //禁止菜单组展开收缩
,style: 'width: 200px' //定义宽度,默认自适应
,id: 'test777' //定义唯一索引
,title: 'title1'
,data: res.data
,click: function(item){
$('#seleform').text(item.title);
$('#seleform').css({color:'rgba(0,0,0,.85)'});
$('#store_cate').val(item.id);
active['reload'] ? active['reload'].call(this) : '';
}
});
},
fail:function(){}
});
//基础效果
rate.render({
elem: '#is_good'
})
//监听搜索提交
form.on('submit(searchform)', function(data) {
layui.pageTable.reload({
where: {
...data.field
},
page: {
curr: 1
}
});
return false;
});
//监听select提交
form.on('select(seleform)', function(data) {
active['reload'] ? active['reload'].call(this) : '';
return false;
});
//监听removeselect点击
$('#removeselect').on('click', function(){
$('#seleform').text('请选择');
$('#seleform').css({color:'#a39f9f'});
$('#store_cate').val('');
active['reload'] ? active['reload'].call(this) : '';
return false;
});
// tab 状态列表切换
$('.site-demo-active').on('click', function(){
var othis = $(this), type = othis.data('type');
$('#protype').val(this.getAttribute('type'));
active[type] ? active[type].call(this, othis) : '';
});
});
// //监听搜索提交
// form.on('submit(searchform)', function(data) {
// layui.pageTable.reload({
// where: {
// keywords: data.field.keywords
// },
// page: {
// curr: 1
// }
// });
// return false;
// });
// 获取表单所有参数
function getformdata() {
var form = $('#filterform').serializeArray();
var data = new Array();
for(let i=0;i<form.length; i++){
data[form[i].name] = form[i].value;
}
return data;
}
}
</script>
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,134 @@
{extend name="common/base"/}
{block name="style"}
<style type="text/css">
.editormd-code-toolbar select {
display: inline-block
}
.editormd li {
list-style: inherit;
}
</style>
{/block}
<!-- 主体 -->
{block name="body"}
<form class="layui-form p-4">
<h3 class="pb-3">申请提现</h3>
<table class="layui-table layui-table-form">
<tr>
<td class="layui-td-gray">提现金额<font>*</font></td>
<td colspan="7"><input type="text" name="num" lay-verify="required|number" lay-reqText="请输入提现金额"
autocomplete="off" placeholder="请输入提现金额" class="layui-input"></td>
</tr>
<tr>
<td class="layui-td-gray">银行卡号<font>*</font></td>
<td colspan="7">
<select name="skfs" lay-verify="required" lay-search="">
<option value="">请选择收款方式</option>
<option value="1">银行卡</option>
<option value="2">微信</option>
<option value="3">支出宝</option>
</select>
</td>
</tr>
</table>
<div class="pt-3">
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</form>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script src="/static/assets/js/xm-select.js"></script>
<script>
var moduleInit = ['tool', 'tagpicker', 'tinymce'];
var group_access = "{:session('gougu_admin')['group_access']}"
var multiple_images = [];
//单击图片删除图片 【注册全局函数】
function delMultipleImgs(this_img){
//获取下标
var subscript=$("#upload_box_thumb2 img").index(this_img);
//删除图片
this_img.remove();
//删除数组
multiple_images.splice(subscript, 1);
//重新排序
multiple_images.sort();
$('#upload_box_thumb2 input').attr('value', multiple_images);
//返回
return ;
}
function gouguInit() {
var form = layui.form, tool = layui.tool, tagspicker = layui.tagpicker;
//上传缩略图
var upload_thumb = layui.upload.render({
elem: '#upload_btn_thumb',
url: '/admin/api/upload',
done: function (res) {
//如果上传失败
if (res.code == 1) {
return layer.msg('上传失败');
}
//上传成功
$('#upload_box_thumb input').attr('value', res.data.filepath);
$('#upload_box_thumb img').attr('src', res.data.filepath);
}
});
//上传商品轮播图
var upload_thumb = layui.upload.render({
elem: '#upload_btn_thumb2',
url: '/admin/api/upload',
multiple: true,
before: function(obj){
//预读本地文件示例不支持ie8
obj.preview(function(index, file, result){
$('#upload_box_thumb2').append(`
<img src="${result}"
onerror="javascript:this.src='{__GOUGU__}/gougu/images/nonepic600x360.jpg';this.onerror=null;"
width="100" style="max-width: 100%; height:66px;" alt="${file.name}" onclick="delMultipleImgs(this)" title="点击删除"/>
`)
});
},
done: function (res) {
//如果上传失败
if (res.code == 1) {
return layer.msg('上传失败');
}
//上传成功
//追加图片成功追加文件名至图片容器
multiple_images.push(res.data.filepath);
$('#upload_box_thumb2 input').attr('value', multiple_images);
// $('#upload_box_thumb2 img').attr('src', res.data.filepath);
}
});
//监听提交
form.on('submit(webform)', function (data) {
let callback = function (e) {
layer.msg(e.msg);
if (e.code == 200) {
tool.tabRefresh(71);
tool.sideClose(1000);
}
}
tool.post('/admin/store_product/withdrawal', data.field, callback);
return false;
});
}
</script>
{/block}
<!-- /脚本 -->

View File

@ -0,0 +1,250 @@
{extend name="common/base"/}
<!-- 主体 -->
{block name="body"}
<style>
.layui-input-inline{
width:35% !important;
}
.layui-input-inline .layui-form-item{
display:flex;
}
.layui-input-inline .layui-form-item .layui-form-label{
width:30%;
}
.layui-input-block{
margin-left:unset !important;
width:75%;
}
#seleform{
border-color: #eee;
background-color: #fff;
color:#a39f9f;
width:100%;
}
</style>
<div class="p-3">
<div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief">
<ul class="layui-tab-title">
<li class="layui-this site-demo-active" type="1" data-type="reload">日账单</li>
<li class="site-demo-active" type="2" data-type="reload">月账单</li>
</ul>
</div>
<form id="filterform" class="layui-form gg-form-bar border-t border-x">
<input id="protype" type="hidden" name="type" value="1">
<div class="layui-form-item">
<!-- <div class="layui-input-inline">-->
<!-- <div class="layui-form-item">-->
<!-- <label class="layui-form-label">商品分类</label>-->
<!-- <div class="layui-input-block">-->
<!-- <input id="store_cate" type="hidden" readonly="readonly" name="store_cate">-->
<!-- <button id="seleform" lay-filter="seleform" class="layui-btn">请选择</button>-->
<!-- <div id="removeselect"><i class="bi-x-lg" style="position: absolute;right:2px;top:10px;z-index: 9;cursor:pointer;"></i></div>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
</div>
<!-- <div class="layui-input-inline" style="width:300px;">-->
<!-- <input type="text" name="keywords" placeholder="请输入订单号" class="layui-input" autocomplete="off" />-->
<!-- </div>-->
<!-- <button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="searchform">提交搜索</button>-->
</form>
<table class="layui-hide" id="store_product" lay-filter="store_product"></table>
</div>
<script type="text/html" id="barDemo">
<div class="layui-btn-group">
<a class="layui-btn layui-btn-normal layui-btn-xs preservation {{# if(d.status != 0){ }}layui-hide{{# } }}" lay-event="topay">去支付</a>
</div>
</script>
{/block}
<!-- /主体 -->
<!-- 脚本 -->
{block name="script"}
<script>
const moduleInit = ['tool'];
function gouguInit() {
var table = layui.table,tool = layui.tool, form = layui.form;
layui.pageTable = table.render({
elem: '#store_product',
title: '列表',
toolbar: '#toolbarDemo',
url: '/admin/store_product/zdlist',
page: false,
limit: 20,
cellMinWidth: 300,
cols: [
[
{
fixed: 'left',
field: 'id',
title: '编号',
align: 'center',
width: 80
},{
field: 'time',
title: '日期',
align: 'center',
width: 200,
},{
field: 'shouru',
title: '账期内收入',
align: 'center',
width: 100
},{
field: 'zhichu',
title: '账期内支出',
align: 'center',
width: 100
},{
field: 'money',
title: '商户应入账金额',
align: 'center',
width: 200,
},
]
]
});
//监听表头工具栏事件
table.on('toolbar(store_product)', function(obj){
if (obj.event === 'add') {
tool.side("/admin/store_product/add");
return false;
}
});
//监听表格行工具事件
table.on('tool(store_product)', function(obj) {
var data = obj.data;
if (obj.event === 'topay') {
}
else if (obj.event === 'edit') {
tool.side('/admin/store_product/edit?product_id='+obj.data.product_id);
}
else if (obj.event === 'del') {
layer.confirm('确定要删除该记录吗?', {
icon: 3,
title: '提示'
}, function(index) {
let callback = function (e) {
layer.msg(e.msg);
if (e.code == 0) {
obj.del();
}
}
tool.delete("/admin/store_product/del", { product_id: data.product_id }, callback);
layer.close(index);
});
}
return false;
});
// 商户商品分类搜索
layui.use(['rate','dropdown', 'util', 'layer', 'table'], function(){
var dropdown = layui.dropdown
,util = layui.util
,layer = layui.layer
,rate = layui.rate
// ,table = layui.table
,$ = layui.jquery;
var $ = layui.$, active = {
reload: function(){
let dataRload = getformdata();
//执行重载
table.reload('store_product', {
page: {
curr: 1 //重新从第 1 页开始
}
,where: {
...dataRload
}
});
},
};
//基础效果
rate.render({
elem: '#is_good'
})
//监听搜索提交
form.on('submit(searchform)', function(data) {
layui.pageTable.reload({
where: {
...data.field
},
page: {
curr: 1
}
});
return false;
});
//监听select提交
form.on('select(seleform)', function(data) {
active['reload'] ? active['reload'].call(this) : '';
return false;
});
//监听removeselect点击
$('#removeselect').on('click', function(){
$('#seleform').text('请选择');
$('#seleform').css({color:'#a39f9f'});
$('#store_cate').val('');
active['reload'] ? active['reload'].call(this) : '';
return false;
});
// tab 状态列表切换
$('.site-demo-active').on('click', function(){
var othis = $(this), type = othis.data('type');
$('#protype').val(this.getAttribute('type'));
active[type] ? active[type].call(this, othis) : '';
});
});
// //监听搜索提交
// form.on('submit(searchform)', function(data) {
// layui.pageTable.reload({
// where: {
// keywords: data.field.keywords
// },
// page: {
// curr: 1
// }
// });
// return false;
// });
// 获取表单所有参数
function getformdata() {
var form = $('#filterform').serializeArray();
var data = new Array();
for(let i=0;i<form.length; i++){
data[form[i].name] = form[i].value;
}
return data;
}
}
</script>
{/block}
<!-- /脚本 -->

View File

@ -404,9 +404,8 @@ class Article extends BaseController
}
$find['nickname'] = Db::table('fa_szxc_information_usermsg')->where('user_id', $value['user_id'])->value('name');
}
$config_find = Db::table('fa_config')->where('id', 20)->find();
//是否查询提案数
if (in_array($value['category_id'], explode(',', $config_find['value']))) {
//是否查询提案数 分类id
if (in_array($value['category_id'],[152,147,165,164,163,162,161,160,148,149,150])) {
//提案总数
$where = [
['category_id', '=', $value['category_id']],

View File

@ -438,9 +438,8 @@ class Cultural extends BaseController
}
$find['nickname'] = Db::table('fa_szxc_information_usermsg')->where('user_id', $value['user_id'])->value('name');
}
$config_find = Db::table('fa_config')->where('id', 20)->find();
//是否查询提案数
if (in_array($value['category_id'], explode(',', $config_find['value']))) {
//是否查询提案数 分类id
if (in_array($value['category_id'],[152,147,165,164,163,162,161,160,148,149,150])) {
//提案总数
$where = [
['category_id', '=', $value['category_id']],

View File

@ -647,9 +647,27 @@ class Maintainentry extends BaseController
$find=Db::table('fa_category')->where('id',$res['nature_of_land'])->find();
$res['nature_of_land_id']=$res['nature_of_land'];
$res['nature_of_land']=$find['name'];
$res['tools_msg'] = $res['tools_msg'] ? json_decode($res['tools_msg'], 1):[];
$res['crops_msg'] = $res['crops_msg'] ? json_decode($res['crops_msg'], 1):[];
$res['breed_msg'] = $res['breed_msg'] ? json_decode($res['breed_msg'], 1):[];
$ids1 = Db::table('cms_planting_type')->where('pid',1)->column('id') ??[];
$result1 = Db::table('cms_planting_information')->where($where)->whereIn('type_id',$ids1)->limit(3)->order('id desc')->field('id,type_id')
->withAttr('name', function ($val,$data) {
return Db::table('cms_planting_type')->where('id',$data['type_id'])->value('name');
})
->select()->toArray();
$ids2 = Db::table('cms_planting_type')->where('pid',2)->column('id') ??[];
$result2 = Db::table('cms_planting_information')->where($where)->whereIn('type_id',$ids2)->limit(3)->order('id desc')->field('id,type_id')
->withAttr('name', function ($val,$data) {
return Db::table('cms_planting_type')->where('id',$data['type_id'])->value('name');
})
->select()->toArray();
$ids3 = Db::table('cms_planting_type')->where('pid',3)->column('id') ??[];
$result3 = Db::table('cms_planting_information')->where($where)->whereIn('type_id',$ids3)->limit(3)->order('id desc')->field('id,type_id')
->withAttr('name', function ($val,$data) {
return Db::table('cms_planting_type')->where('id',$data['type_id'])->value('name');
})
->select()->toArray();
$res['tools_msg'] = $result1;
$res['crops_msg'] = $result2;
$res['breed_msg'] = $result3;
$this->apiSuccess('获取成功', $res, 1);
} else {
$this->apiError('暂无数据');
@ -696,84 +714,82 @@ class Maintainentry extends BaseController
$map[] = ['user_id','=',$user_id];
$find=Db::table('fa_szxc_information_planting')->where($map)->find();
// 新增写入种植表
Db::table('fa_szxc_planting')->where('user_id',$user_id)->delete();
$mianji = 0;
if($post['crops_msg']){
$crops_msg_arr = json_decode($post['crops_msg'],1);
foreach ($crops_msg_arr as $k=>$v){
// 根据名字查询分类
if($v['name']){
$type = Db::table('fa_szxc_planting_type')->where('name',$v['name'])->find();
if($type){
$planting_data['type_id'] = $type['id'];
}else{
$type_data['name'] = $v['name'];
$type_data['createtime'] = $time;
$type_id = Db::table('fa_szxc_planting_type')->strict(false)->insertGetId($type_data);
$planting_data['type_id'] = $type_id;
}
$planting_data['user_id'] = $user_id;
$planting_data['num'] = $v['num']??0;
$planting_data['measure'] = $v['mianji']??0;
$planting_data['createtime'] = $time;
Db::table('fa_szxc_planting')->strict(false)->insertGetId($planting_data);
}
// 计算面积
if($v['mianji']){
$mianji += $v['mianji'];
}
}
}
// Db::table('fa_szxc_planting')->where('user_id',$user_id)->delete();
// $mianji = 0;
// if($post['crops_msg']){
// $crops_msg_arr = json_decode($post['crops_msg'],1);
// foreach ($crops_msg_arr as $k=>$v){
// // 根据名字查询分类
// if($v['name']){
// $type = Db::table('fa_szxc_planting_type')->where('name',$v['name'])->find();
// if($type){
// $planting_data['type_id'] = $type['id'];
// }else{
// $type_data['name'] = $v['name'];
// $type_data['createtime'] = $time;
// $type_id = Db::table('fa_szxc_planting_type')->strict(false)->insertGetId($type_data);
// $planting_data['type_id'] = $type_id;
// }
// $planting_data['user_id'] = $user_id;
// $planting_data['num'] = $v['num']??0;
// $planting_data['measure'] = $v['mianji']??0;
// $planting_data['createtime'] = $time;
// Db::table('fa_szxc_planting')->strict(false)->insertGetId($planting_data);
// }
// // 计算面积
// if($v['mianji']){
// $mianji += $v['mianji'];
// }
// }
// }
// 新增写入养殖表
Db::table('fa_szxc_breed')->where('user_id',$user_id)->delete();
// $mianji = 0;
if(isset($post['breed_msg']) && !empty($post['breed_msg'])){
$breed_msg_arr = json_decode($post['breed_msg'],1);
foreach ($breed_msg_arr as $k=>$v){
// 根据名字查询分类
if($v['name']){
$type = Db::table('fa_szxc_breed_type')->where('name',$v['name'])->find();
if($type){
$breed_data['type_id'] = $type['id'];
}else{
$type_data['name'] = $v['name'];
$type_data['createtime'] = $time;
$type_id = Db::table('fa_szxc_breed_type')->strict(false)->insertGetId($type_data);
$breed_data['type_id'] = $type_id;
}
$breed_data['user_id'] = $user_id;
$breed_data['num'] = $v['num']??0;
$breed_data['measure'] = $v['mianji']??0;
$breed_data['createtime'] = $time;
Db::table('fa_szxc_breed')->strict(false)->insertGetId($breed_data);
}
//// 计算面积
// if($v['mianji']){
// $mianji += $v['mianji'];
// }
}
}
// Db::table('fa_szxc_breed')->where('user_id',$user_id)->delete();
//// $mianji = 0;
// if(isset($post['breed_msg']) && !empty($post['breed_msg'])){
// $breed_msg_arr = json_decode($post['breed_msg'],1);
// foreach ($breed_msg_arr as $k=>$v){
//// 根据名字查询分类
// if($v['name']){
// $type = Db::table('fa_szxc_breed_type')->where('name',$v['name'])->find();
// if($type){
// $breed_data['type_id'] = $type['id'];
// }else{
// $type_data['name'] = $v['name'];
// $type_data['createtime'] = $time;
// $type_id = Db::table('fa_szxc_breed_type')->strict(false)->insertGetId($type_data);
// $breed_data['type_id'] = $type_id;
// }
// $breed_data['user_id'] = $user_id;
// $breed_data['num'] = $v['num']??0;
// $breed_data['measure'] = $v['mianji']??0;
// $breed_data['createtime'] = $time;
// Db::table('fa_szxc_breed')->strict(false)->insertGetId($breed_data);
// }
// }
// }
$waste_land_area = 0;
$www5['user_id'] = $user_id;
$www5['type_id'] = 1;
$mianji = Db::table('cms_planting_information')->where($www5)->sum('measure');
$waste_land_area = $post['land_area'] - $mianji - $post['breed_area'];
if($waste_land_area < 0){
$waste_land_area = 0;
if (!empty($post['land_area']) && !empty($post['breed_area']))
{
$waste_land_area = $post['land_area'] - $mianji - $post['breed_area'];
if($waste_land_area < 0){
$waste_land_area = 0;
}
}
if ($find) {
// 修改人员信息
$data['tools_msg'] = $post['tools_msg'];
$data['breed_msg'] = $post['breed_msg']??'';
// $data['tools_msg'] = $post['tools_msg'];
// $data['breed_msg'] = $post['breed_msg']??'';
$data['breed_area'] = $post['breed_area']??'';
$data['crops_msg'] = $post['crops_msg'];
// $data['crops_msg'] = $post['crops_msg'];
$data['land_area'] = $post['land_area'];
$data['nature_of_land'] = $post['nature_of_land_id'];
$data['is_wz'] = $post['is_wz'];
// $data['work_name'] = $post['work_name'];
// $data['work_gender'] = $post['work_gender'];
// $data['work_phone'] = $post['work_phone'] ?? '';
// $data['work_relation'] = $post['work_relation'];
// $data['work_id'] = $post['work_id'];
$data['waste_land_area'] = $waste_land_area;
$data['user_id'] = $user_id;
$data['updatetime'] = time();
@ -785,18 +801,13 @@ class Maintainentry extends BaseController
}
}else{
// 修改人员信息
$data['tools_msg'] = $post['tools_msg'];
$data['breed_msg'] = $post['breed_msg']??'';
// $data['tools_msg'] = $post['tools_msg'];
// $data['breed_msg'] = $post['breed_msg']??'';
$data['breed_area'] = $post['breed_area']??'';
$data['crops_msg'] = $post['crops_msg'];
// $data['crops_msg'] = $post['crops_msg'];
$data['land_area'] = $post['land_area'];
$data['nature_of_land'] = $post['nature_of_land_id'];
$data['is_wz'] = $post['is_wz'];
// $data['work_name'] = $post['work_name'];
// $data['work_gender'] = $post['work_gender'];
// $data['work_phone'] = $post['work_phone'] ?? '';
// $data['work_relation'] = $post['work_relation'];
// $data['work_id'] = $post['work_id'];
$data['waste_land_area'] = $waste_land_area;
$data['user_id'] = $user_id;
@ -1274,7 +1285,7 @@ class Maintainentry extends BaseController
$userid = Db::connect('shop')->table('eb_user')->strict(false)->insertGetId($params);
//写入用户信息表
$post['user_id'] = 0;
$post['user_id'] = $userid;
$post['createtime'] = $time;
$post['enter_id'] = $this->request->uid;
$post['gender']= $post['gender_id'];
@ -1382,19 +1393,16 @@ class Maintainentry extends BaseController
$breed_data['createtime'] = $time;
Db::table('fa_szxc_breed')->strict(false)->insertGetId($breed_data);
}
//// 计算面积
// if($v['mianji']){
// $mianji += $v['mianji'];
// }
}
}
$waste_land_area = 0;
if(!isset($post['breed_area'])){
$post['breed_area'] = 0;
}
$waste_land_area = $post['land_area'] - $mianji - $post['breed_area'];
if($waste_land_area < 0){
$waste_land_area = 0;
if (!empty($post['land_area']) && !empty($post['breed_area']))
{
$waste_land_area = $post['land_area'] - $mianji - $post['breed_area'];
if($waste_land_area < 0){
$waste_land_area = 0;
}
}
// 写入种植信息表
$cropsarr['user_id'] = $userid; //用户id
@ -1402,10 +1410,6 @@ class Maintainentry extends BaseController
$cropsarr['crops_msg'] = $post['crops_msg'];//农作物信息
$cropsarr['land_area'] = $post['land_area'];//土地面积
$cropsarr['nature_of_land'] = $post['nature_of_land'];//土地性质
// $cropsarr['work_name'] = $post['work_name'];//劳动人姓名
// $cropsarr['work_gender'] = $post['work_gender'];//劳动人口性别
// $cropsarr['work_relation'] = $post['work_relation'];//劳动人与户主关系
// $cropsarr['work_id'] = $post['work_id'];//劳动人id
$cropsarr['waste_land_area'] = $waste_land_area;//荒地面积
$cropsarr['breed_msg'] = $post['breed_msg']??'';//养殖详情信息
$cropsarr['breed_area'] = $post['breed_area']??'';//养殖面积
@ -1490,11 +1494,6 @@ class Maintainentry extends BaseController
// }
if ($post) {
//// 验证验证码
// if (! Sms::check($post['phone'], $post['captcha'], 'mobilelogin')) {
// $this->apiError(__('Captcha is incorrect'));
// }
Db::startTrans();
// 获取录入人地址
$add = Db::table('fa_szxc_information_useraddress')->where('user_id',$this->request->uid)->find();
@ -1926,5 +1925,204 @@ class Maintainentry extends BaseController
}
}
/**
* 获取分类(农作物、农机农具、养殖)
*
*/
public function get_category()
{
// 分类标识
$type = get_params('type_id');
if (empty($type)) {
$this->apiError('缺少参数');
} else {
$where[] = ['pid','<>',0];
$where[] = ['pid','=',$type];
$where[] = ['status','=','1'];
$result = Db::table('cms_planting_type')->where($where)->field('id,name')->order('id desc')->select()->toArray();
if ($result) {
$this->apiSuccess('获取成功', $result);
} else {
$this->apiError('暂无数据');
}
}
}
/**
* 新增分类(农作物、农机农具、养殖)
*
*/
public function add_category()
{
// 分类标识
$type = get_params('type_id');
$name = get_params('name');
if (empty($type) || empty($name)) {
$this->apiError('缺少参数');
} else {
// 判断是否存在
$where['name'] = $name;
$where['pid'] = $type;
$is_have = Db::table('cms_planting_type')->where($where)->find();
if($is_have){
$this->apiError('该分类已存在');
}
$data['name'] = $name;
$data['pid'] = $type;
$data['createtime'] = time();
$result = Db::table('cms_planting_type')->strict(false)->insert($data);
if ($result) {
$this->apiSuccess('添加成功', $result);
} else {
$this->apiError('添加失败');
}
}
}
/**
* 添加(农作物、农机农具、养殖)
*
*/
public function add_information()
{
// 分类标识
$type = get_params('type_id');
$user_id = get_params('user_id');
if (empty($type) || empty($user_id)) {
$this->apiError('缺少参数');
} else {
$data = get_params();
// 判断是否存在
$where['type_id'] = $type;
$where['user_id'] = $user_id;
$is_have = Db::table('cms_planting_information')->where($where)->find();
if($is_have){
$this->apiError('请勿重复录入');
}
$data['user_id'] = $user_id;
$data['createtime'] = time();
$result = Db::table('cms_planting_information')->strict(false)->insert($data);
if ($result) {
$this->apiSuccess('添加成功', $result);
} else {
$this->apiError('添加失败');
}
}
}
/**
* 获取详情(农作物、农机农具、养殖)
*
*/
public function get_by_id()
{
$id = get_params('id');
if (empty($id)) {
$this->apiError('缺少参数');
} else {
$data = get_params();
// 判断是否存在
$where['id'] = $id;
$result = Db::table('cms_planting_information')->where($where)
->withAttr('createtime', function ($val,$data) {
return date('Y-m-d',$data['createtime']);
})
->find();
if ($result) {
$this->apiSuccess('获取成功', $result);
} else {
$this->apiError('暂无数据');
}
}
}
/**
* 编辑(农作物、农机农具、养殖)
*
*/
public function edit_information()
{
$id = get_params('id');
if (empty($id)) {
$this->apiError('缺少参数');
} else {
$data = get_params();
// 判断是否存在
$where['id'] = $id;
$is_have = Db::table('cms_planting_information')->where($where)->find();
if(!$is_have){
$this->apiError('未找到该数据');
}
$result = Db::table('cms_planting_information')->where($where)->update($data);
if ($result) {
$this->apiSuccess('编辑成功', $result);
} else {
$this->apiError('编辑失败');
}
}
}
/**
* 获取列表(农作物、农机农具、养殖)
*
*/
public function get_information()
{
// 分类标识
$type = get_params('type_id'); //1农作物2农机农具3养殖物
$user_id = get_params('user_id');
if (empty($type) || empty($user_id)) {
$this->apiError('缺少参数');
} else {
$ids = Db::table('cms_planting_type')->where('pid',$type)->column('id') ??[];
$where['user_id'] = $user_id;
$page = get_params('page')??1;
$limit = get_params('limit')??10;
$order = get_params('order')??'id';
$result = Db::table('cms_planting_information')->where($where)->whereIn('type_id',$ids)->page($page,$limit)->order($order. ' desc')
->withAttr('createtime', function ($val,$data) {
return date('Y-m-d',$data['createtime']);
})
->withAttr('name', function ($val,$data) {
return Db::table('cms_planting_type')->where('id',$data['type_id'])->value('name');
})
->withAttr('image', function ($val,$data) {
return Db::table('cms_planting_type')->where('id',$data['type_id'])->value('image');
})
->select()->toArray();
if ($result) {
$this->apiSuccess('获取成功', $result);
} else {
$this->apiError('获取失败');
}
}
}
/**
* 删除(农作物、农机农具、养殖)
*
*/
public function del_information()
{
// 分类标识
$id = get_params('id');
if (empty($id)) {
$this->apiError('缺少参数');
} else {
$where['id'] = $id;
$result = Db::table('cms_planting_information')->where($where)->delete();
if ($result) {
$this->apiSuccess('删除成功', $result);
} else {
$this->apiError('删除失败');
}
}
}
}

View File

@ -116,9 +116,8 @@ class MyArticle extends BaseController
$find = $user;
}
}
$config_find = Db::table('fa_config')->where('id', 20)->find();
//是否查询提案数
if (in_array($value['category_id'], explode(',', $config_find['value']))) {
//是否查询提案数 //分类id
if (in_array($value['category_id'], [152,147,165,164,163,162,161,160,148,149,150])) {
//提案总数
$where = [
['category_id', '=', $value['category_id']],

View File

@ -1,12 +1,16 @@
<?php
namespace app\api\controller;
use app\common\controller\Api;
use app\api\BaseController;
use EasyWeChat\Factory;
use EasyWeChat\Pay\Application;
use EasyWeChat\Pay\Message;
use think\facade\Db;
use think\facade\Log;
use think\facade\Request;
class PayNotify extends Api{
class PayNotify extends BaseController
{
public function index(){
$config = [
'mch_id' => 1635725673,
@ -55,4 +59,215 @@ class PayNotify extends Api{
}
// 接收微信支付状态的通知 商城后台采购商品回调
public function notify()
{
// 配置信息
$config = [
'app_id' => 'wx0b3defb62f0f910b',//注意这个APPID只能是公众号的id没有的话要去申请并且在微信支付平台里绑定
'mch_id' => '1635725673',//商户号
'key' => '95d195Dcf6ec66156dfeeb4E7435faef',//支付秘钥
'secret' => 'c02aa7ad9e4a5c423862e068b6cb4ad4',
'notify_url' => Request::instance()->domain().'/api/PayNotify/notify',//异步回调通知地址
];
// 这个就是 easywechat 封装的了, 一行代码搞定, 照着写就行了
$app = Factory::payment($config);
// 用 easywechat 封装的方法接收微信的信息, 根据 $message 的内容进行处理, 之后要告知微信服务器处理好了, 否则微信会一直请求这个 url, 发送信息
$response = $app->handlePaidNotify(function($message, $fail){
// 首先查看 order 表, 如果 order 表有记录, 表示已经支付过了
$order = Db::table('cms_store_product_order')->where('order_sn', $message['out_trade_no'])->find();
if ($order) {
return true; // 如果已经生成订单, 表示已经处理完了, 告诉微信不用再通知了
}
// 查看支付日志
$payLog = Db::table('cms_store_product_paylog')->where('out_trade_no', $message['out_trade_no'])->find();
if (!$payLog || $payLog['time_end']) { // 如果订单不存在 或者 订单已经支付过了
return true; // 告诉微信,我已经处理完了,订单没找到,别再通知我了
}
// 更新支付时间为当前时间
$paid_at = time();
// return_code 表示通信状态,不代表支付状态
if ($message['return_code'] === 'SUCCESS') {
// 用户是否支付成功
if ($message['result_code'] === 'SUCCESS') {
$post_id = $payLog['product_id'];
// 创建订单记录
$order_arr = [
'order_sn' => $message['out_trade_no'],
'total_fee' => bcdiv($message['total_fee'],'100',2),
'pay_log_id' => $payLog['id'],
'status' => 1,
'admin_id' => $payLog['admin_id'],
'paid_at' => $paid_at,
'product_id' => $post_id,
'number' => $payLog['number'],
'cart_id' => $payLog['cart_id'],
];
$order_id = Db::table('cms_store_product_order')->strict(false)->field(true)->insertGetId($order_arr);
// 更新 PayLog, 这里的字段都是根据微信支付结果通知的字段设置的(https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_7&index=8)
$pay_log = [
'appid' => $message['appid'],
'bank_type' => $message['bank_type'],
'total_fee' => $message['total_fee'],
'trade_type' => $message['trade_type'],
'is_subscribe' => $message['is_subscribe'],
'mch_id' => $message['mch_id'],
'nonce_str' => $message['nonce_str'],
'openid' => $message['openid'],
'sign' => $message['sign'],
'cash_fee' => $message['cash_fee'],
'fee_type' => $message['fee_type'],
'transaction_id' => $message['transaction_id'],
'time_end' => $paid_at,
'result_code' => $message['result_code'],
'return_code' => $message['return_code'],
];
Db::table('cms_store_product_paylog')->where('out_trade_no', $message['out_trade_no'])->update($pay_log);
// 写入商户余额表
if($payLog['cart_id']){ //购物车
$time = time();
if(strpos($payLog['cart_id'],',')){
$cart_ids = explode(',',$payLog['cart_id']);
foreach ($cart_ids as $k=>$v){
// 根据 id 查出价格
$where['cart_id'] = $v;
$cart = Db::table('cms_store_cart')->where($where)->lock(true)->find();
if (empty($cart)) {
continue;
}
// 根据商品id获取商户admin_id
$wwww['product_id'] = $cart['product_id'];
$store_product = Db::table('cms_store_product')->where($wwww)->lock(true)->find();
if (empty($store_product)) {
continue;
}
// 更新购物车
$c_data['is_pay'] = 1;
Db::table('cms_store_cart')->where($where)->update($c_data);
// 减库存
Db::table('cms_store_product')->where('product_id', $cart['product_id'])->dec('stock',$cart['cart_num'])->update();
// 写入后台余额表
$is_money = Db::table('cms_admin_money')->where('admin_id',$store_product['admin_id'])->lock(true)->find();
if($is_money){
$total_fee = bcmul((string)$store_product['price'],(string)$cart['cart_num']);
Db::table('cms_admin_money')->where('admin_id',$store_product['admin_id'])->inc('money',$total_fee)->update();
}else{
$total_fee = bcmul((string)$store_product['price'],(string)$cart['cart_num']);
$m_data['admin_id'] = $store_product['admin_id'];
$m_data['money'] = $total_fee;
Db::table('cms_admin_money')->insert($m_data);
}
//写入后台余额记录表
$log_arr['type'] = 0;
$log_arr['admin_id'] = $store_product['admin_id'];
$log_arr['num'] = $total_fee;
$log_arr['create_time'] = $time;
$log_arr['status'] = 1;
$log_arr['order_id'] = $order_id;
Db::table('cms_admin_money_log')->where('admin_id',$store_product['admin_id'])->strict(false)->field(true)->insert($log_arr);
}
}else{
$where['cart_id'] = $payLog['cart_id'];
$cart = Db::table('cms_store_cart')->where($where)->lock(true)->find();
if ($cart) {
// 根据商品id获取商户admin_id
$wwww['product_id'] = $cart['product_id'];
$store_product = Db::table('cms_store_product')->where($wwww)->lock(true)->find();
if ($store_product) {
// 更新购物车
$c_data['is_pay'] = 1;
Db::table('cms_store_cart')->where($where)->update($c_data);
// 减库存
Db::table('cms_store_product')->where('product_id', $cart['product_id'])->dec('stock',$cart['cart_num'])->update();
//写入后台余额表
$is_money = Db::table('cms_admin_money')->where('admin_id',$store_product['admin_id'])->lock(true)->find();
if($is_money){
$total_fee = bcmul((string)$store_product['price'],(string)$cart['cart_num']);
Db::table('cms_admin_money')->where('admin_id',$store_product['admin_id'])->inc('money',$total_fee)->update();
}else{
$total_fee = bcmul((string)$store_product['price'],(string)$cart['cart_num']);
$m_data['admin_id'] = $store_product['admin_id'];
$m_data['money'] = $total_fee;
Db::table('cms_admin_money')->insert($m_data);
}
//写入后台余额记录表
$log_arr['type'] = 0;
$log_arr['admin_id'] = $store_product['admin_id'];
$log_arr['num'] = $total_fee;
$log_arr['create_time'] = $time;
$log_arr['status'] = 1;
$log_arr['order_id'] = $order_id;
Db::table('cms_admin_money_log')->where('admin_id',$store_product['admin_id'])->strict(false)->field(true)->insert($log_arr);
}
}
}
}else{
// 根据商品id获取商户admin_id
$www['product_id'] = $post_id;
$store_product = Db::table('cms_store_product')->where($www)->find();
if (!empty($store_product)) {
// 减库存
Db::table('cms_store_product')->where('product_id', $post_id)->dec('stock',$payLog['number'])->update();
//写入后台余额表
$is_money = Db::table('cms_admin_money')->where('admin_id',$store_product['admin_id'])->lock(true)->find();
if($is_money){
$total_fee = bcdiv($message['total_fee'],'100',2);
Db::table('cms_admin_money')->where('admin_id',$store_product['admin_id'])->inc('money',$total_fee)->update();
}else{
$total_fee = bcdiv($message['total_fee'],'100',2);
$m_data['admin_id'] = $store_product['admin_id'];
$m_data['money'] = $total_fee;
Db::table('cms_admin_money')->insert($m_data);
}
//写入后台余额记录表
$log_arr['type'] = 0;
$log_arr['admin_id'] = $store_product['admin_id'];
$log_arr['num'] = $total_fee;
$log_arr['create_time'] = time();
$log_arr['status'] = 1;
$log_arr['order_id'] = $order_id;
Db::table('cms_admin_money_log')->where('admin_id',$store_product['admin_id'])->strict(false)->field(true)->insert($log_arr);
}
}
}
} else {
// 如果支付失败, 也更新 PayLog, 跟上面一样, 就是多了 error 信息
$pay_log = [
'appid' => $message['appid'],
'bank_type' => $message['bank_type'],
'total_fee' => $message['total_fee'],
'trade_type' => $message['trade_type'],
'is_subscribe' => $message['is_subscribe'],
'mch_id' => $message['mch_id'],
'nonce_str' => $message['nonce_str'],
'openid' => $message['openid'],
'sign' => $message['sign'],
'cash_fee' => $message['cash_fee'],
'fee_type' => $message['fee_type'],
'transaction_id' => $message['transaction_id'],
'time_end' => $paid_at,
'result_code' => $message['result_code'],
'return_code' => $message['return_code'],
'err_code' => $message['err_code'],
'err_code_des' => $message['err_code_des'],
];
Db::table('cms_store_product_paylog')->where('out_trade_no', $message['out_trade_no'])->update($pay_log);
return $fail('通信失败,请稍后再通知我');
}
return true; // 返回处理完成
});
// 这里是必须这样返回的, 会发送给微信服务器处理结果
return $response;
}
}

View File

@ -318,6 +318,10 @@ class Village extends BaseController
$www['village_id'] = $address['village_id'];
$news = Db::table('fa_szxc_village')->where($www)->field('id,title,address,people_num,images,views,likes,createtime,introduce,info,area_id,street_id,village_id')->find();
if ($news) {
$news['area_name'] = $area_name;
$news['street_name'] = $street_name;
$news['village'] = $village;
$news['brigade_name'] = $brigade_name;
// 判断redis
$user_id = $this->request->uid;
if($user_id){
@ -391,6 +395,10 @@ class Village extends BaseController
}
$this->apiSuccess('获取成功', $news);
} else {
$news['area_name'] = $area_name;
$news['street_name'] = $street_name;
$news['village'] = $village;
$news['brigade_name'] = $brigade_name;
// 判断redis
if($this->request->uid){
$name = $this->request->uid . $address['village_id'];

View File

@ -69,10 +69,6 @@ Route::group('/',function () {
* 获取 民族等
*/
Route::get('Maintainentry/getcategory', 'Maintainentry/getcategory');
/**
* 身份证查询
*/
Route::get('idcard', 'idcard');
/**
* 获取验证码
*/

View File

@ -1,7 +0,0 @@
<IfModule mod_rewrite.c>
Options +FollowSymlinks -Multiviews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?/$1 [QSA,PT,L]
</IfModule>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,396 @@
var options = [
{
value: 'zhinan',
label: '指南',
children: [{
value: 'shejiyuanze',
label: '设计原则',
disabled: true,
children: [{
disabled: true,
value: 'yizhi',
label: '一致'
}, {
value: 'fankui',
label: '反馈'
}, {
value: 'xiaolv',
label: '效率'
}, {
value: 'kekong',
label: '可控'
}]
}, {
value: 'daohang',
label: '导航',
children: [{
disabled: true,
value: 'cexiangdaohang',
label: '侧向导航'
}, {
value: 'dingbudaohang',
label: '顶部导航'
}]
}]
},
{
value: 'zujian',
label: '组件',
children: [{
value: 'basic',
label: 'Basic',
children: [{
value: 'layout',
label: 'Layout 布局'
}, {
value: 'color',
label: 'Color 色彩'
}, {
value: 'typography',
label: 'Typography 字体'
}, {
value: 'icon',
label: 'Icon 图标'
}, {
value: 'button',
label: 'Button 按钮'
}]
}, {
value: 'form',
label: 'Form',
children: [{
value: 'radio',
label: 'Radio 单选框'
}, {
value: 'checkbox',
label: 'Checkbox 多选框'
}, {
value: 'input',
label: 'Input 输入框'
}, {
value: 'input-number',
label: 'InputNumber 计数器'
}, {
value: 'select',
label: 'Select 选择器'
}, {
value: 'cascader',
label: 'Cascader 级联选择器'
}, {
value: 'switch',
label: 'Switch 开关'
}, {
value: 'slider',
label: 'Slider 滑块'
}, {
value: 'time-picker',
label: 'TimePicker 时间选择器'
}, {
value: 'date-picker',
label: 'DatePicker 日期选择器'
}, {
value: 'datetime-picker',
label: 'DateTimePicker 日期时间选择器'
}, {
value: 'upload',
label: 'Upload 上传'
}, {
value: 'rate',
label: 'Rate 评分'
}, {
value: 'form',
label: 'Form 表单'
}]
}, {
value: 'data',
label: 'Data',
children: [{
value: 'table',
label: 'Table 表格'
}, {
value: 'tag',
label: 'Tag 标签'
}, {
value: 'progress',
label: 'Progress 进度条'
}, {
value: 'tree',
label: 'Tree 树形控件'
}, {
value: 'pagination',
label: 'Pagination 分页'
}, {
value: 'badge',
label: 'Badge 标记'
}]
}, {
value: 'notice',
label: 'Notice',
children: [{
value: 'alert',
label: 'Alert 警告'
}, {
value: 'loading',
label: 'Loading 加载'
}, {
value: 'message',
label: 'Message 消息提示'
}, {
value: 'message-box',
label: 'MessageBox 弹框'
}, {
value: 'notification',
label: 'Notification 通知'
}]
}, {
value: 'navigation',
label: 'Navigation',
children: [{
value: 'menu',
label: 'NavMenu 导航菜单'
}, {
value: 'tabs',
label: 'Tabs 标签页'
}, {
value: 'breadcrumb',
label: 'Breadcrumb 面包屑'
}, {
value: 'dropdown',
label: 'Dropdown 下拉菜单'
}, {
value: 'steps',
label: 'Steps 步骤条'
}]
}, {
value: 'others',
label: 'Others',
children: [{
value: 'dialog',
label: 'Dialog 对话框'
}, {
value: 'tooltip',
label: 'Tooltip 文字提示'
}, {
value: 'popover',
label: 'Popover 弹出框'
}, {
value: 'card',
label: 'Card 卡片'
}, {
value: 'carousel',
label: 'Carousel 走马灯'
}, {
value: 'collapse',
label: 'Collapse 折叠面板'
}]
}]
}, {
value: 'ziyuan',
label: '资源',
children: [{
value: 'axure',
label: 'Axure Components'
}, {
value: 'sketch',
label: 'Sketch Templates'
}, {
value: 'jiaohu',
label: '组件交互文档'
}]
}];
var options2 = [{
value: 'zhinan',
label: '指南',
disabled: true,
children: [{
value: 'shejiyuanze',
label: '设计原则',
children: [{
value: 'yizhi',
label: '一致'
}, {
value: 'fankui',
label: '反馈'
}, {
value: 'xiaolv',
label: '效率'
}, {
value: 'kekong',
label: '可控'
}]
}, {
value: 'daohang',
label: '导航',
children: [{
value: 'cexiangdaohang',
label: '侧向导航'
}, {
value: 'dingbudaohang',
label: '顶部导航'
}]
}]
}, {
value: 'zujian',
label: '组件',
children: [{
value: 'basic',
label: 'Basic',
children: [{
value: 'layout',
label: 'Layout 布局'
}, {
value: 'color',
label: 'Color 色彩'
}, {
value: 'typography',
label: 'Typography 字体'
}, {
value: 'icon',
label: 'Icon 图标'
}, {
value: 'button',
label: 'Button 按钮'
}]
}, {
value: 'form',
label: 'Form',
children: [{
value: 'radio',
label: 'Radio 单选框'
}, {
value: 'checkbox',
label: 'Checkbox 多选框'
}, {
value: 'input',
label: 'Input 输入框'
}, {
value: 'input-number',
label: 'InputNumber 计数器'
}, {
value: 'select',
label: 'Select 选择器'
}, {
value: 'cascader',
label: 'Cascader 级联选择器'
}, {
value: 'switch',
label: 'Switch 开关'
}, {
value: 'slider',
label: 'Slider 滑块'
}, {
value: 'time-picker',
label: 'TimePicker 时间选择器'
}, {
value: 'date-picker',
label: 'DatePicker 日期选择器'
}, {
value: 'datetime-picker',
label: 'DateTimePicker 日期时间选择器'
}, {
value: 'upload',
label: 'Upload 上传'
}, {
value: 'rate',
label: 'Rate 评分'
}, {
value: 'form',
label: 'Form 表单'
}]
}, {
value: 'data',
label: 'Data',
children: [{
value: 'table',
label: 'Table 表格'
}, {
value: 'tag',
label: 'Tag 标签'
}, {
value: 'progress',
label: 'Progress 进度条'
}, {
value: 'tree',
label: 'Tree 树形控件'
}, {
value: 'pagination',
label: 'Pagination 分页'
}, {
value: 'badge',
label: 'Badge 标记'
}]
}, {
value: 'notice',
label: 'Notice',
children: [{
value: 'alert',
label: 'Alert 警告'
}, {
value: 'loading',
label: 'Loading 加载'
}, {
value: 'message',
label: 'Message 消息提示'
}, {
value: 'message-box',
label: 'MessageBox 弹框'
}, {
value: 'notification',
label: 'Notification 通知'
}]
}, {
value: 'navigation',
label: 'Navigation',
children: [{
value: 'menu',
label: 'NavMenu 导航菜单'
}, {
value: 'tabs',
label: 'Tabs 标签页'
}, {
value: 'breadcrumb',
label: 'Breadcrumb 面包屑'
}, {
value: 'dropdown',
label: 'Dropdown 下拉菜单'
}, {
value: 'steps',
label: 'Steps 步骤条'
}]
}, {
value: 'others',
label: 'Others',
children: [{
value: 'dialog',
label: 'Dialog 对话框'
}, {
value: 'tooltip',
label: 'Tooltip 文字提示'
}, {
value: 'popover',
label: 'Popover 弹出框'
}, {
value: 'card',
label: 'Card 卡片'
}, {
value: 'carousel',
label: 'Carousel 走马灯'
}, {
value: 'collapse',
label: 'Collapse 折叠面板'
}]
}]
}, {
value: 'ziyuan',
label: '资源',
children: [{
value: 'axure',
label: 'Axure Components'
}, {
value: 'sketch',
label: 'Sketch Templates'
}, {
value: 'jiaohu',
label: '组件交互文档'
}]
}];

View File

@ -0,0 +1,190 @@
.layui-rc-cascader {
position: relative;
font-size: 14px;
line-height: 40px;
}
.cascader-input {
cursor: pointer;
position: relative;
width: 100%;
}
.cascader-input > input {
cursor: pointer;
user-select:none;
}
.cascader-input__inner {
text-overflow: ellipsis;
}
.cascader-input--suffix > .cascader-input__inner {
padding-right: 32px;
}
.cascader-input.focus .cascader-input__inner {
border-color: #5FB878 !important;
}
.cascader-input__suffix {
display: flex;
position: absolute;
width: 36px;
height: 100%;
right: 0;
top: 0;
align-items: center;
justify-content: center;
color: #c0c4cc;
transition: all .3s;
pointer-events: none;
cursor: pointer;
}
.cascader-input.focus .cascader-input__suffix {
transform: rotate(180deg);
}
.cascader-dropdown {
display: none;
position: absolute;
left: 0;
top: auto;
padding: 5px 0;
z-index: 899;
}
.layui-selectup .cascader-dropdown {
top: auto;
bottom: 42px;
}
.cascader-input.focus + .cascader-dropdown {
display: block;
}
.cascader-dropdown > .cascader-dropdown-panel {
display: flex;
flex-flow: row;
border: 1px solid #d2d2d2;
background-color: #fff;
border-radius: 2px;
box-shadow: 0 2px 4px rgba(0,0,0,.12);
box-sizing: border-box;
}
.cascader-dropdown-panel > .cascader-dropdown-dl {
min-width: 180px;
min-height: 180px;
max-height: 300px;
overflow-y: auto;
box-sizing: border-box;
color: #606266;
border-right: 1px solid #d2d2d2;
}
.cascader-dropdown-dl {
-ms-overflow-style: none;
overflow-x: hidden;
overflow-y: auto;
}
.cascader-dropdown-dl::-webkit-scrollbar {
display: none;
}
.cascader-dropdown-dl:last-child {
border-right: none;
}
.cascader-dropdown-dd {
cursor: pointer;
position: relative;
display: flex;
align-items: center;
padding: 0 16px;
height: 40px;
line-height: 40px;
outline: none;
color: #606266;
user-select: none;
}
.cascader-dropdown-dd:hover {
transition: .5s all;
background-color: #f2f2f2;
}
.cascader-dropdown-dd.active, .cascader-dropdown-dd.in-active{
background-color: #5FB878;
color: #fff;
}
.cascader-dropdown-dd > span {
flex: 1;
padding-right: 16px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.cascader-dropdown-dd.selected {
color: #5FB878;
font-weight: 600;
}
.cascader-dropdown-dd .layui-icon-ok {
display: none;
}
.cascader-dropdown-dd.selected .layui-icon-ok {
display: inline-block;
}
.cascader-tags {
display: none;
position: absolute;
top: 0;
left: 0;
right: 36px;
cursor: pointer;
margin: 2px 0 0 2px;
background-color: #fff;
}
.cascader-tags-body {
display: flex;
flex-wrap: wrap;
}
.cascader-tags > .cascaer-tags-list {
display: flex;
flex-wrap: wrap;
}
.cascader-tags-item {
white-space: nowrap;
display: inline-flex;
align-items: center;
max-width: 100%;
margin: 4px 0 4px 6px !important;
text-overflow: ellipsis;
background-color: #f0f2f5;
height: 30px;
padding: 0 8px;
line-height: 22px;
box-sizing: border-box;
font-size: 12px;
color: #909399;
user-select: none;
}
.cascader-tags-item > i {
margin-left: 4px;
color: #c0c4cc;
}
.cascader-tags-item > i:hover {
color: #909399;
}

View File

@ -0,0 +1,317 @@
"use strict";
layui.define(['jquery', 'laytpl'], function (e) {
var mod = 'cascader';
var $ = layui.$, tpl = layui.laytpl;
var sys = {
class: {
container: 'layui-rc-cascader',
inputBox: 'cascader-input',
input: 'cascader-input__inner',
inputSuffix: 'cascader-input__suffix',
tags: 'cascader-tags',
tagBody: 'cascader-tags-body',
tagItem: 'cascader-tags-item',
tagNum: 'cascader-tags-num',
dropdown: 'cascader-dropdown',
dropdownPanel: 'cascader-dropdown-panel',
dropdownDl: 'cascader-dropdown-dl',
dropdownDd: 'cascader-dropdown-dd',
selectup: 'layui-selectup'
},
template: {
main: '<div class="{{d.cls.container}}"><div class="{{d.cls.inputBox}} cascader-input--suffix"><input type="text" readonly placeholder="{{d.opts.placeholder}}" class="{{d.cls.input}} layui-input" /><span class="{{d.cls.inputSuffix}}"><i class="layui-icon layui-icon-triangle-d"></i></span></div><div class="{{d.cls.dropdown}} layui-anim layui-anim-upbit"><div class="{{d.cls.dropdownPanel}}"></div></div>{{# if (d.opts.multiple) { }}<div class="{{d.cls.tags}}"><div class="{{d.cls.tagBody}}"></div></div>{{# } }}</div>',
dropdownDl: '<div class="{{d.cls.dropdownDl}}">{{# layui.each(d.list, function(i, e){ }}<div class="{{d.cls.dropdownDd}}" data-v="{{e.value}}"><span>{{e.label}}</span>{{# if (e.hasChildren) { }}<i class="layui-icon layui-icon-right"></i>{{# } }}<i class="layui-icon layui-icon-ok"></i></div>{{# }); }}</div>',
tags: '{{# layui.each(d.list, function (i, e) { }}<div class="{{d.cls.tagItem}}" data-v="{{e.value}}"><span>{{ e.label }}</span><i class="layui-icon layui-icon-close-fill"></i></div>{{# }); }}',
tagsCollapse: '<div class="{{d.cls.tagItem}}" data-v="{{d.list[0].value}}"><span>{{d.list[0].label}}</span><i class="layui-icon layui-icon-close-fill"></i></div><div class="{{d.cls.tagItem}} {{d.cls.tagNum}}">+{{d.list.length}}</div>'
}
};
var selected = []
var Cascader = function (opts) {
var _s = this;
_s.config = $.extend({}, _s.config, opts);
_s.render();
}
Cascader.prototype.config = {
elem: '',
options: [],
multiple: false,
clearable: false,
collapseTags: true,
filterable: false,
showAllLevels: true,
placeholder: '请选择',
separator: '/',
valueSeparator: ',',
groupSeparator: '|',
props: {
label: 'label',
value: 'value',
children: 'children'
},
debounce: 300,
onChange: function () {}
};
Cascader.prototype.render = function () {
var _s = this, _e = this.config.elem;
$(_e).parent().find(`.${sys.class.container}`).remove(), selected = [], $(_e).hide().after(tpl(sys.template.main).render({ cls: sys.class, opts: _s.config }));
if (typeof _s.config.onChange !== 'function') {
_s.config.onChange = function () {}
}
_s.renderData([]), _s.eventRegister(), _s.showLabel();
}
Cascader.prototype.eventRegister = function () {
var _s = this, _e = _s.config.elem, _cls = sys.class, $c = $(_e).next();
$c.find(`.${_cls.inputBox}`).on('click', _s.onShow.bind(_s));
$c.find(`.${_cls.tags}`).on('click', _s.onShow.bind(_s));
$c.find(`.${_cls.tags}`).on('click', `.${_cls.tagItem} > i`, function (e) { e.stopPropagation(); _s.onSelect.bind(_s)($(this).closest(`.${_cls.tagItem}`).data('v')); });
$c.on('click', `.${_cls.dropdownDd}`, function (e) { e.stopPropagation(); _s.onSelect.bind(_s)($(this).data('v'))});
$(document).off('click', _s.maskTap.bind(_s)), $(document).on('click', _s.maskTap.bind(_s));
}
Cascader.prototype.maskTap = function (e) {
var _s = this, _e = _s.config.elem, $c = $(_e).next(), _target = e.target, _item = $c.find(_target);
if (_item.length === 0) {
_s.onClose.bind(_s)(e);
}
}
Cascader.prototype.renderData = function (treePath) {
var _s = this, _e = this.config.elem, _cls = sys.class, $c = $(_e).next(), $dp = $c.find(`.${_cls.dropdownPanel}`), _options = _s.config.options;
if (treePath.length > 0) {
_options = _s.getChildren(treePath);
}
$dp.find(`.${_cls.dropdownDl}`).each(function (i, e) {
if (i >= treePath.length) {
$(e).remove();
}
});
if (_options.length === 0) {
return;
}
var _$ddList = $(tpl(sys.template.dropdownDl).render({ list: _options.map(function (e, i) {
return {
label: e[_s.config.props.label],
value: treePath.concat([e[_s.config.props.value]]).join(_s.config.valueSeparator),
hasChildren: e[_s.config.props.children] === undefined ? false : e[_s.config.props.children].length > 0
}
}), cls: sys.class }));
_$ddList.appendTo($dp);
_s.highlight();
}
Cascader.prototype.onSelect = function (v) {
var _s = this, _e = _s.config.elem, _cls = sys.class, $c = $(_e).next(), $dp = $c.find(`.${_cls.dropdownPanel}`);
var _v = _s.getSelectedValue(), _treePath = (`${v}`.split(_s.config.valueSeparator));
if (_s.getChildren(_treePath).length > 0) {
selected = _treePath;
_s.renderData(_treePath);
_s.highlight();
return;
}
if (_s.config.multiple) {
var _item = _s.getItemByPath(_treePath), _value = _s.convertValue(_item)
var _i = _v.indexOf(_value);
if (_i >= 0) {
_v.splice(_i, 1)
} else {
_v = _v.concat(_value);
}
var _elementValue = _v.join(_s.config.groupSeparator);
$(_e).val(_elementValue), _s.showLabel(), _s.config.onChange(_value, _elementValue);
} else {
var _value = _s.convertValue(_s.getItemByPath(_treePath));
$(_e).val(_value), _s.showLabel(), _s.onClose(), _s.config.onChange(_value);
}
_s.highlight();
}
Cascader.prototype.showLabel = function () {
var _s = this, _e = this.config.elem, _cls = sys.class, $c = $(_e).next(), $tags = $c.find(`.${_cls.tags}`);
var _selectedOptions = _s.getSelectOptions();
if (_s.config.multiple) {
var $input = $c.find(`.${_cls.input}`), $tagBody = $tags.find(`.${_cls.tagBody}`), _labels = _selectedOptions.map(function (e) { return { label: _s.convertInputText(e), value: _s.convertValue(e) }; });
if (_labels.length === 0) {
$input.attr('placeholder', _s.config.placeholder), $input.height('')
$tags.hide();
return;
}
tpl(_s.config.collapseTags ? sys.template.tagsCollapse : sys.template.tags).render({ cls: sys.class, list: _labels }, function (html) {
$tagBody.html(html);
setTimeout(function () {
$input.attr('placeholder', ''), $input.height($tags.height() + 2), $tags.show();
}, 300);
});
} else {
$c.find(`.${_cls.input}`).val(_s.convertInputText(_selectedOptions ? _selectedOptions[0] : null));
}
}
Cascader.prototype.getChildren = function (path) {
var _s = this;
if (!Array.isArray(path)) {
path = path.split(_s.config.valueSeparator);
}
return path.reduce(function (res, e) {
var _selected = res.filter(function (_e, _i) {
return _e[_s.config.props.value].toString() === e.toString();
});
_selected = _selected.length > 0 ? _selected[0] : {};
return _selected.hasOwnProperty(_s.config.props.children) ? _selected[_s.config.props.children] : [];
}, _s.config.options)
}
Cascader.prototype.getItemByPath = function (path) {
var _s = this, _options = _s.config.options;
if (!Array.isArray(path)) {
path = path.split(_s.config.valueSeparator);
}
return path.reduce(function (res, e) {
var restruct = _options.filter(function (_e) {
return _e[_s.config.props.value].toString() === e.toString()
})
if (restruct.length > 0) {
res.push(restruct[0]);
_options = restruct[0][_s.config.props.children] !== undefined ? restruct[0][_s.config.props.children] : [];
}
return res
}, [])
}
Cascader.prototype.getSelectOptions = function () {
var _s = this, _v = _s.getSelectedValue();
return _v.map(function (el) {
var _options = _s.config.options;
return el.split(_s.config.valueSeparator).reduce(function (res, e) {
var restruct = _options.filter(function (_e) {
return _e[_s.config.props.value].toString() === e.toString();
});
if (restruct.length > 0) {
res.push(restruct[0]);
_options = restruct[0][_s.config.props.children] !== undefined ? restruct[0][_s.config.props.children] : [];
}
return res
}, [])
});
}
Cascader.prototype.highlight = function (callback) {
var _s = this, _e = this.config.elem, _cls = sys.class, $c = $(_e).next(), $dp = $c.find(`.${_cls.dropdownPanel}`);
var _v = _s.getSelectedValue();
var _marginObject = function (arr, obj) {
var e = arr.shift();
if (!obj.hasOwnProperty(e)) {
obj[e] = {}
}
if (arr.length > 0) {
obj[e] = _marginObject(arr, obj[e])
}
return obj;
}
_v = _v.concat(selected.join(_s.config.valueSeparator)).reduce(function (res, e) {
return _marginObject(e.split(_s.config.valueSeparator), res);
}, {});
$dp.find(`.${_cls.dropdownDd}`).removeClass('selected in-active');
$dp.find(`.${_cls.dropdownDl}`).each(function (i, e) {
if (_v === undefined) { return; }
var _keys = Object.keys(_v);
if (_keys.length > 0) {
_keys.forEach(function (_e) {
var _key = selected.slice(0, i).concat(_e).join(_s.config.valueSeparator);
$(e).find(`.${_cls.dropdownDd}[data-v="${_key}"]`).addClass(_s.getChildren(_key).length > 0 ? (_s.config.multiple ? 'in-active' : '') : 'selected')
});
_v = _v[selected[i]]
}
})
if (callback !== undefined) {
callback.call(this);
}
}
Cascader.prototype.getSelectedValue = function () {
var _s = this, _e = this.config.elem;
var value = $(_e).val() === ""
? []
: $(_e).val().split(_s.config.groupSeparator)
return Array.isArray(value) ? value : [value];
}
Cascader.prototype.convertInputText = function (v) {
if (!v) {
return '';
}
var _s = this, _e = this.config.elem, _cls = sys.class, $c = $(_e).next(), $input = $c.find(`.${_cls.input}`);
return _s.config.showAllLevels
? v.map(function (e) { return e[_s.config.props.label]; }).join(` ${_s.config.separator} `)
: v[v.length - 1][_s.config.props.label];
}
Cascader.prototype.convertValue = function (v) {
var _s = this;
if (!Array.isArray(v)) {
v = [v];
}
return v.map(function (e) { return e[_s.config.props.value]; }).join(_s.config.valueSeparator)
}
Cascader.prototype.onShow = function (e) {
var _s = this, _e = this.config.elem, _cls = sys.class, $c = $(_e).next(), $input = $c.find(`.${_cls.input}`);
if ($c.find(`.${_cls.inputBox}`).hasClass('focus')) {
return _s.onClose.bind(_s)(e);
}
if (document.body.offsetHeight - ($input.offset().top + $input.height()) < 300 && $input.offset().top > 300) {
$c.addClass(_cls.selectup);
}
$c.find(`.${_cls.inputBox}`).addClass('focus');
}
Cascader.prototype.onClose = function (e) {
var _e = this.config.elem, $c = $(_e).next(), _cls = sys.class;
$c.removeClass(_cls.selectup);
$c.find(`.${_cls.inputBox}`).removeClass('focus');
}
e(mod, {
render (opts) {
if (opts.elem === undefined) {
return console.error(mod, 'elem is undefined');
} else if (typeof opts.elem !== 'object' || !(opts.elem instanceof HTMLElement)) {
return console.error(mod, 'elem is not HTMLElement');
}
return new Cascader(opts);
}
});
layui.link(layui.cache.base + 'cascader/cascader.css')
});

View File

@ -0,0 +1,745 @@
/*
* Name: skuTable
* Author: cshaptx4869
* Project: https://github.com/cshaptx4869/skuTable
*/
layui.define(['jquery', 'form', 'upload', 'layer', 'sortable'], function (exports) {
"use strict";
var $ = layui.jquery,
form = layui.form,
upload = layui.upload,
layer = layui.layer,
sortable = layui.sortable,
MOD_NAME = 'skuTable';
//工具类
class Util {
static config = {
shade: [0.02, '#000'],
time: 2000
};
static msg = {
// 成功消息
success: function (msg, callback = null) {
return layer.msg(msg, {
icon: 1,
shade: Util.config.shade,
scrollbar: false,
time: Util.config.time,
shadeClose: true
}, callback);
},
// 失败消息
error: function (msg, callback = null) {
return layer.msg(msg, {
icon: 2,
shade: Util.config.shade,
scrollbar: false,
time: Util.config.time,
shadeClose: true
}, callback);
},
// 警告消息框
alert: function (msg, callback = null) {
return layer.alert(msg, {end: callback, scrollbar: false});
},
// 对话框
confirm: function (msg, ok, no) {
var index = layer.confirm(msg, {title: '操作确认', btn: ['确认', '取消']}, function () {
typeof ok === 'function' && ok.call(this);
}, function () {
typeof no === 'function' && no.call(this);
Util.msg.close(index);
});
return index;
},
// 消息提示
tips: function (msg, callback = null) {
return layer.msg(msg, {
time: Util.config.time,
shade: Util.config.shade,
end: callback,
shadeClose: true
});
},
// 加载中提示
loading: function (msg, callback = null) {
return msg ? layer.msg(msg, {
icon: 16,
scrollbar: false,
shade: Util.config.shade,
time: 0,
end: callback
}) : layer.load(2, {time: 0, scrollbar: false, shade: Util.config.shade, end: callback});
},
// 输入框
prompt: function (option, callback = null) {
return layer.prompt(option, callback);
},
// 关闭消息框
close: function (index) {
return layer.close(index);
}
};
static request = {
post: function (option, ok, no, ex) {
return Util.request.ajax('post', option, ok, no, ex);
},
get: function (option, ok, no, ex) {
return Util.request.ajax('get', option, ok, no, ex);
},
ajax: function (type, option, ok, no, ex) {
type = type || 'get';
option.url = option.url || '';
option.data = option.data || {};
option.statusName = option.statusName || 'code';
option.statusCode = option.statusCode || 200;
ok = ok || function (res) {
};
no = no || function (res) {
var msg = res.msg == undefined ? '返回数据格式有误' : res.msg;
Util.msg.error(msg);
return false;
};
ex = ex || function (res) {
};
if (option.url == '') {
Util.msg.error('请求地址不能为空');
return false;
}
var index = Util.msg.loading('加载中');
$.ajax({
url: option.url,
type: type,
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
dataType: "json",
data: option.data,
timeout: 60000,
success: function (res) {
Util.msg.close(index);
if (res[option.statusName] == option.statusCode) {
return ok(res);
} else {
return no(res);
}
},
error: function (xhr, textstatus, thrown) {
Util.msg.error('Status:' + xhr.status + '' + xhr.statusText + ',请稍后再试!', function () {
ex(xhr);
});
return false;
}
});
}
};
static tool = {
uuid: function uuid(randomLength = 8) {
return Number(Math.random().toString().substr(2, randomLength) + Date.now()).toString(36)
}
}
}
class SkuTable {
options = {
isAttributeValue: 0, //规格类型 0统一规格 1多规格
isAttributeElemId: 'fairy-is-attribute', //规格类型容器id
specTableElemId: 'fairy-spec-table', //规格表容器id
skuTableElemId: 'fairy-sku-table', //SKU表容器id
rowspan: false, //是否开启SKU行合并,
sortable: false, //规格拖拽排序
skuIcon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDY3IDc5LjE1Nzc0NywgMjAxNS8wMy8zMC0yMzo0MDo0MiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjczN0RFNzU1MTk1RTExRTlBMEQ5OEEwMEM5NDNFOEE4IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjczN0RFNzU2MTk1RTExRTlBMEQ5OEEwMEM5NDNFOEE4Ij4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NzM3REU3NTMxOTVFMTFFOUEwRDk4QTAwQzk0M0U4QTgiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NzM3REU3NTQxOTVFMTFFOUEwRDk4QTAwQzk0M0U4QTgiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz5NHmJUAAAA+0lEQVR42pySPwsBYRzH7zk3KIP34CVIKSOrELLJdpuymyzew90kIwMZvACDsCldWZTFn5WQpPN5rlPXlXJ39en7/J57fn+fR9i2rYT5NNM0B2gC3n/6qHBQDMOwZNYg4LOQ3vcQld40/w6lC13Xbd/eHElC3G1JqL4DFWSNprz7BMpAFJ6YkW+jThaosuxAD/rY6R9lCmeq8IAmtKBA1A1OW9YjtIS9QvPYRZkcXo43EzqjF/mDQ5an7ALShTFk4eQOsgFTWeoNKl4nt68J0oYc1LHLbmtDp1IyLgPe4QCuMkIsyAWSuYbs5HD29DML8OTkHR9F2Ef+EWAAdwmkvBAtw94AAAAASUVORK5CYII=',
uploadUrl: '',
requestSuccessCode: 1, //请求成功返回状态码值
specDataDelete: false, //开启规格删除
productId: '', //商品id 配合specDataUrl和skuDataUrl使用
specData: [], //规格数据
specDataUrl: '', //优先级大于specData
skuData: {}, //SKU数据
skuDataUrl: '', //优先级大于skuDataUrl
skuNameType: 0,
skuNameDelimiter: '-',
//统一规格配置项
singleSkuTableConfig: {
thead: [
{title: '销售价(元)', icon: 'layui-icon-cols'},
{title: '市场价(元)', icon: 'layui-icon-cols'},
{title: '成本价(元)', icon: 'layui-icon-cols'},
{title: '库存', icon: 'layui-icon-cols'},
{title: '状态', icon: ''},
],
tbody: [
{type: 'input', field: 'price', value: '', verify: 'required|number', reqtext: '销售价不能为空'},
{type: 'input', field: 'market_price', value: '0', verify: 'required|number', reqtext: '市场价不能为空'},
{type: 'input', field: 'cost_price', value: '0', verify: 'required|number', reqtext: '成本价不能为空'},
{type: 'input', field: 'stock', value: '0', verify: 'required|number', reqtext: '库存不能为空'},
{type: 'select', field: 'status', option: [{key: '启用', value: '1'}, {key: '禁用', value: '0'}], verify: 'required', reqtext: '状态不能为空'},
]
},
//多规格配置项
multipleSkuTableConfig: {
thead: [
{title: '图片', icon: ''},
{title: '销售价(元)', icon: 'layui-icon-cols'},
{title: '市场价(元)', icon: 'layui-icon-cols'},
{title: '成本价(元)', icon: 'layui-icon-cols'},
{title: '库存', icon: 'layui-icon-cols'},
{title: '状态', icon: ''},
],
tbody: [
{type: 'image', field: 'picture', value: '', verify: '', reqtext: ''},
{type: 'input', field: 'price', value: '', verify: 'required|number', reqtext: '销售价不能为空'},
{type: 'input', field: 'market_price', value: '0', verify: 'required|number', reqtext: '市场价不能为空'},
{type: 'input', field: 'cost_price', value: '0', verify: 'required|number', reqtext: '成本价不能为空'},
{type: 'input', field: 'stock', value: '0', verify: 'required|number', reqtext: '库存不能为空'},
{
type: 'select',
field: 'status',
option: [{key: '启用', value: '1'}, {key: '禁用', value: '0'}],
verify: '',
reqtext: ''
},
]
}
};
constructor(options) {
this.options = $.extend(this.options, options);
if (this.options.skuDataUrl && this.options.productId) {
Util.request.get({
url: this.options.skuDataUrl,
data: {
product_id: this.options.productId
},
statusCode: this.options.requestSuccessCode
}, (res) => {
this.options.skuData = res.data;
this.css();
this.render();
this.listen();
});
} else {
this.css();
this.render();
this.listen();
}
}
css() {
$('head').append(`<style>
${this.options.sortable ? `#${this.options.specTableElemId} tbody tr {cursor: move;transition:unset;-webkit-transition:unset;}` : ''}
#${this.options.specTableElemId} tbody tr td:first-child > i.layui-icon-delete {
margin-left:3px;
}
#${this.options.specTableElemId} tbody tr td:last-child > i.layui-icon-delete {
margin-right:15px;
margin-left:-7px;
vertical-align: top;
}
#${this.options.specTableElemId} tbody tr td div.fairy-spec-value-create,
#${this.options.specTableElemId} tfoot tr td div.fairy-spec-create {
display: inline-block;
color: #1E9FFF;
vertical-align: middle;
padding: 4px 6px;
}
#${this.options.specTableElemId} tfoot tr td div.layui-form-checkbox {
margin-top: 0;
}
#${this.options.specTableElemId} tfoot tr td div.layui-form-checkbox > span{
color: #1E9FFF;
}
#${this.options.skuTableElemId} tbody tr td > img.fairy-sku-img{
width: 16px;
height: 16px;
padding: 6px;
border: 1px solid #eceef1;
vertical-align: middle;
}
#${this.options.specTableElemId} tbody tr td > i.layui-icon-delete,
#${this.options.specTableElemId} tbody tr td div.fairy-spec-value-create,
#${this.options.specTableElemId} tfoot tr td div.fairy-spec-create,
#${this.options.skuTableElemId} thead tr th > i.layui-icon,
#${this.options.skuTableElemId} tbody tr td > img.fairy-sku-img {
cursor: pointer;
}
</style>`
);
}
listen() {
var that = this;
/**
* 监听规格类型选择
*/
form.on('radio(fairy-is-attribute)', function (data) {
that.options.isAttributeValue = data.value;
that.render();
});
/**
* 监听所选规格值的变化
*/
form.on('checkbox(fairy-spec-filter)', function (data) {
var specData = [];
$.each($(`#${that.options.specTableElemId} tbody tr`), function () {
var child = [];
$.each($(this).find('input[type=checkbox]'), function () {
child.push({id: $(this).val(), title: $(this).attr('title'), checked: $(this).is(':checked')});
});
var specItem = {
id: $(this).find('td').eq(0).data('spec-id'),
title: $(this).find('td').eq(0).text(),
child: child
};
specData.push(specItem);
});
that.options.specData = specData;
that.options.skuData = $.extend(that.options.skuData, that.getFormSkuData());
that.resetRender(that.options.skuTableElemId);
that.renderMultipleSkuTable();
});
/**
* 监听批量赋值
*/
$(document).on('click', `#${this.options.skuTableElemId} thead tr th i`, function () {
var thisI = this;
Util.msg.prompt({title: $(thisI).parent().text().trim() + '批量赋值'}, function (value, index, elem) {
$.each($(`#${that.options.skuTableElemId} tbody tr`), function () {
var index = that.options.rowspan ?
$(thisI).parent().index() - ($(`#${that.options.skuTableElemId} thead th.fairy-spec-name`).length - $(this).children('td.fairy-spec-value').length) :
$(thisI).parent().index();
$(this).find('td').eq(index).children('input').val(value);
});
Util.msg.close(index);
});
});
/**
* 监听添加规格
*/
$(document).on('click', `#${this.options.specTableElemId} .fairy-spec-create`, function () {
layer.prompt({title: '规格'}, function (value, index, elem) {
var specTitleArr = [];
$.each(that.options.specData, function (k, v) {
specTitleArr.push(v.title)
})
if (specTitleArr.includes(value)) {
Util.msg.error('规格名已存在');
} else {
that.options.specData.push({id: Util.tool.uuid(), title: value, child: []});
that.resetRender(that.options.specTableElemId);
that.renderSpecTable();
}
Util.msg.close(index);
});
});
/**
* 监听添加规格值
*/
$(document).on('click', `#${this.options.specTableElemId} .fairy-spec-value-create`, function () {
var specId = $(this).parent('td').prev().data('spec-id');
layer.prompt({title: '规格值'}, function (value, index, elem) {
that.options.specData.forEach(function (v, i) {
if (v.id == specId) {
v.child.push({id: Util.tool.uuid(), title: value, checked: false});
}
});
that.resetRender(that.options.specTableElemId);
that.renderSpecTable();
Util.msg.close(index);
});
});
/**
* 监听删除规格/规格值
*/
$(document).on('click', `#${this.options.specTableElemId} i.layui-icon-delete`, function () {
if (typeof $(this).attr('data-spec-index') !== "undefined") {
that.options.specData.splice($(this).data('spec-index'), 1);
that.resetRender([that.options.specTableElemId, that.options.skuTableElemId]);
that.renderSpecTable();
that.renderMultipleSkuTable();
} else if (typeof $(this).attr('data-spec-value-index') !== "undefined") {
var [i, ii] = $(this).data('spec-value-index').split('-');
that.options.specData[i].child.splice(ii, 1);
that.resetRender([that.options.specTableElemId, that.options.skuTableElemId]);
that.renderSpecTable();
that.renderMultipleSkuTable();
}
});
/**
* 监听规格表是否开启删除
*/
form.on('checkbox(fairy-spec-delete-filter)', function (data) {
that.options.specDataDelete = data.elem.checked;
if (data.elem.checked) {
$(`#${that.options.specTableElemId} tbody tr i.layui-icon-delete`).removeClass('layui-hide');
} else {
$(`#${that.options.specTableElemId} tbody tr i.layui-icon-delete`).addClass('layui-hide')
}
});
/**
* 图片移入放大/移出恢复
*/
var imgLayerIndex = null;
$(document).on('mouseenter', '.fairy-sku-img', function () {
imgLayerIndex = layer.tips('<img src="' + $(this).attr('src') + '" style="max-width:200px;" alt=""/>', this, {
tips: [2, 'rgba(41,41,41,.5)'],
time: 0
});
}).on('mouseleave', '.fairy-sku-img', function () {
layer.close(imgLayerIndex);
})
}
/**
* 渲染
*/
render() {
this.resetRender();
this.renderIsAttribute(this.options.isAttributeValue);
if (this.options.isAttributeValue == '1') {
if (this.options.specDataUrl && this.options.productId) {
Util.request.get({
url: this.options.specDataUrl,
productId: this.options.productId,
statusCode: this.options.requestSuccessCode
}, (res) => {
this.options.specData = res.data;
this.renderSpecTable();
this.renderMultipleSkuTable();
});
} else {
this.renderSpecTable();
this.renderMultipleSkuTable();
}
} else {
this.renderSingleSkuTable();
}
}
/**
* 重新渲染
* @param targets
*/
resetRender(targets) {
if (typeof targets === 'string') {
$(`#${targets}`).parents('.layui-form-item').replaceWith(`<div id="${targets}"></div>`);
} else if ($.isArray(targets) && targets.length) {
targets.forEach((item) => {
$(`#${item}`).parents('.layui-form-item').replaceWith(`<div id="${item}"></div>`);
})
} else {
$(`#${this.options.isAttributeElemId}`).parents('.layui-form-item').replaceWith(`<div id="${this.options.isAttributeElemId}"></div>`);
$(`#${this.options.specTableElemId}`).parents('.layui-form-item').replaceWith(`<div id="${this.options.specTableElemId}"></div>`);
$(`#${this.options.skuTableElemId}`).parents('.layui-form-item').replaceWith(`<div id="${this.options.skuTableElemId}"></div>`);
}
}
/**
* 渲染规格类型
* @param checkedValue
*/
renderIsAttribute(checkedValue) {
var html = '';
html += `<input type="radio" name="is_attribute" title="统一规格" value="0" lay-filter="fairy-is-attribute" ${checkedValue == '0' ? 'checked' : ''}>`;
html += `<input type="radio" name="is_attribute" title="多规格" value="1" lay-filter="fairy-is-attribute" ${checkedValue == '1' ? 'checked' : ''}>`;
this.renderFormItem('规格类型', html, this.options.isAttributeElemId);
}
renderSingleSkuTable() {
var that = this,
table = `<table class="layui-table" id="${this.options.skuTableElemId}">`;
table += '<thead>';
table += '<tr>';
this.options.singleSkuTableConfig.thead.forEach((item) => {
table += `<th>${item.title}</th>`;
});
table += '</tr>';
table += '</thead>';
table += '<tbody>';
table += '<tr>';
that.options.singleSkuTableConfig.tbody.forEach(function (item) {
switch (item.type) {
case "select":
table += '<td>';
table += `<select name="${item.field}" lay-verify="${item.verify}" lay-reqtext="${item.reqtext}">`;
item.option.forEach(function (o) {
table += `<option value="${o.value}" ${that.options.skuData[item.field] == o.value ? 'selected' : ''}>${o.key}</option>`;
});
table += '</select>';
table += '</td>';
break;
case "input":
default:
table += '<td>';
table += `<input type="text" name="${item.field}" value="${that.options.skuData[item.field] ? that.options.skuData[item.field] : item.value}" class="layui-input" lay-verify="${item.verify}" lay-reqtext="${item.reqtext}">`;
table += '</td>';
break;
}
});
table += '</tr>';
table += '<tbody>';
table += '</table>';
this.renderFormItem('SKU', table, this.options.skuTableElemId);
}
/**
* 渲染规格表
*/
renderSpecTable() {
var that = this,
table = `<table class="layui-table" id="${this.options.specTableElemId}"><thead><tr><th>规格名</th><th>规格值</th></tr></thead><colgroup><col width="140"></colgroup><tbody>`;
$.each(this.options.specData, function (index, item) {
table += that.options.sortable ? `<tr data-id="${item.id}">` : '<tr>';
table += `<td data-spec-id="${item.id}">${item.title}<i class="layui-icon layui-icon-delete layui-anim layui-anim-scale ${that.options.specDataDelete ? '' : 'layui-hide'}" data-spec-index="${index}"></i></td>`;
table += '<td>';
$.each(item.child, function (key, value) {
table += `<input type="checkbox" title="${value.title}" lay-filter="fairy-spec-filter" value="${value.id}" ${value.checked ? 'checked' : ''} /><i class="layui-icon layui-icon-delete layui-anim layui-anim-scale ${that.options.specDataDelete ? '' : 'layui-hide'}" data-spec-value-index="${index}-${key}"></i> `;
});
table += '<div class="fairy-spec-value-create"><i class="layui-icon layui-icon-addition"></i>规格值</div>'
table += '</td>';
table += '</tr>';
});
table += '</tbody>';
table += '<tfoot><tr><td colspan="2">';
table += `<textarea name="attr" style="display:none">${JSON.stringify(this.options.specData)}</textarea><input type="checkbox" title="开启删除" lay-skin="primary" lay-filter="fairy-spec-delete-filter" ${that.options.specDataDelete ? 'checked' : ''}/>`;
table += `<div class="fairy-spec-create"><i class="layui-icon layui-icon-addition"></i>规格</div>`;
table += '</td></tr></tfoot>';
table += '</table>';
this.renderFormItem('商品规格', table, this.options.specTableElemId);
if (this.options.sortable) {
/**
* 拖拽
*/
var sortableObj = sortable.create($(`#${this.options.specTableElemId} tbody`)[0], {
animation: 1000,
onEnd: (evt) => {
//获取拖动后的排序
var sortArr = sortableObj.toArray(),
sortSpecData = [];
this.options.specData.forEach((item) => {
sortSpecData[sortArr.indexOf(String(item.id))] = item;
});
this.options.specData = sortSpecData;
this.resetRender(that.options.skuTableElemId);
this.renderMultipleSkuTable();
},
});
}
}
/**
* 渲染sku表
*/
renderMultipleSkuTable() {
var that = this, table = `<table class="layui-table" id="${this.options.skuTableElemId}">`;
if ($(`#${this.options.specTableElemId} tbody input[type=checkbox]:checked`).length) {
var prependThead = [], prependTbody = [];
$.each(this.options.specData, function (index, item) {
var isShow = item.child.some(function (value, index, array) {
return value.checked;
});
if (isShow) {
prependThead.push(item.title);
var prependTbodyItem = [];
$.each(item.child, function (key, value) {
if (value.checked) {
prependTbodyItem.push({id: value.id, title: value.title});
}
});
prependTbody.push(prependTbodyItem);
}
});
table += '<colgroup>' + '<col width="70">'.repeat(prependThead.length + 1) + '</colgroup>';
table += '<thead>';
if (prependThead.length > 0) {
var theadTr = '<tr>';
theadTr += prependThead.map(function (t, i, a) {
return '<th class="fairy-spec-name"><input type="hidden" name="kk['+i+']" value="' + t + '"/>' + t + '</th>';
}).join('');
this.options.multipleSkuTableConfig.thead.forEach(function (item) {
theadTr += '<th>' + item.title + (item.icon ? ' <i class="layui-icon ' + item.icon + '"></i>' : '') + '</th>';
});
theadTr += '</tr>';
table += theadTr;
}
table += '</thead>';
if (this.options.rowspan) {
var skuRowspanArr = [];
prependTbody.forEach(function (v, i, a) {
var num = 1, index = i;
while (index < a.length - 1) {
num *= a[index + 1].length;
index++;
}
skuRowspanArr.push(num);
});
}
var prependTbodyTrs = [];
prependTbody.reduce(function (prev, cur, index, array) {
var tmp = [];
prev.forEach(function (a) {
cur.forEach(function (b) {
tmp.push({id: a.id + that.options.skuNameDelimiter + b.id, title: a.title + that.options.skuNameDelimiter + b.title});
})
});
return tmp;
}).forEach(function (item, index, array) {
var tr = '<tr>';
tr += item.title.split(that.options.skuNameDelimiter).map(function (t, i, a) {
if (that.options.rowspan) {
if (index % skuRowspanArr[i] === 0 && skuRowspanArr[i] > 1) {
return '<td class="fairy-spec-value" rowspan="' + skuRowspanArr[i] + '"><input type="hidden" name="' + that.makeSkuName2(item, 'value'+i) + '" value="' + t + '"/>' + t + '</td>';
} else if (skuRowspanArr[i] === 1) {
return '<td class="fairy-spec-value"><input type="hidden" name="' + that.makeSkuName2(item, 'value'+i) + '" value="' + t + '"/>' + t + '</td>';
} else {
return '';
}
} else {
return '<td><input type="hidden" name="' + that.makeSkuName2(item, 'value'+i) + '" value="' + t + '"/>' + t + '</td>';
}
}).join('');
that.options.multipleSkuTableConfig.tbody.forEach(function (c) {
switch (c.type) {
case "image":
tr += '<td><input type="hidden" name="' + that.makeSkuName(item, c) + '" value="' + (that.options.skuData[that.makeSkuName(item, c)] ? that.options.skuData[that.makeSkuName(item, c)] : c.value) + '" lay-verify="' + c.verify + '" lay-reqtext="' + c.reqtext + '"><img class="fairy-sku-img" src="' + (that.options.skuData[that.makeSkuName(item, c)] ? that.options.skuData[that.makeSkuName(item, c)] : that.options.skuIcon) + '" alt="' + c.field + '图片"></td>';
break;
case "select":
tr += '<td><select name="' + that.makeSkuName(item, c) + '" lay-verify="' + c.verify + '" lay-reqtext="' + c.reqtext + '">';
c.option.forEach(function (o) {
tr += '<option value="' + o.value + '" ' + (that.options.skuData[that.makeSkuName(item, c)] == o.value ? 'selected' : '') + '>' + o.key + '</option>';
});
tr += '</select></td>';
break;
case "input":
default:
tr += '<td><input type="text" name="' + that.makeSkuName(item, c) + '" value="' + (that.options.skuData[that.makeSkuName(item, c)] ? that.options.skuData[that.makeSkuName(item, c)] : c.value) + '" class="layui-input" lay-verify="' + c.verify + '" lay-reqtext="' + c.reqtext + '"></td>';
break;
}
});
tr += '</tr>';
tr && prependTbodyTrs.push(tr);
});
table += '<tbody>';
if (prependTbodyTrs.length > 0) {
table += prependTbodyTrs.join('');
}
table += '</tbody>';
} else {
table += '<thead></thead><tbody></tbody><tfoot><tr><td>请先选择规格值</td></tr></tfoot>';
}
table += '</table>';
this.renderFormItem('SKU', table, this.options.skuTableElemId);
//上传
if (this.options.uploadUrl) {
upload.render({
elem: '.fairy-sku-img',
url: this.options.uploadUrl,
exts: 'png|jpg|ico|jpeg|gif',
accept: 'images',
acceptMime: 'image/*',
multiple: false,
done: function (res) {
if (res.code === that.options.requestSuccessCode) {
var url = res.data.url;
$(this.item).attr('src', url).prev().val(url);
Util.msg.success(res.msg);
} else {
var msg = res.msg == undefined ? '返回数据格式有误' : res.msg;
Util.msg.error(msg);
}
return false;
}
});
}
}
/**
* 渲染表单项
* @param label 标题
* @param content 内容
* @param target id
* @param isRequired
*/
renderFormItem(label, content, target, isRequired = true) {
var html = '';
html += '<div class="layui-form-item">';
html += `<label class="layui-form-label ${isRequired ? 'required' : ''}">${label.length ? label : ''}</label>`;
html += '<div class="layui-input-block">';
html += content;
html += '</div>';
html += '</div>';
$(`#${target}`).replaceWith(html);
form.render();
}
makeSkuName(sku, conf) {
return 'skus[' + (this.options.skuNameType === 0 ? sku.id : sku.title) + '][' + conf.field + ']';
}
makeSkuName2(sku, conf) {
return 'skus[' + (this.options.skuNameType === 0 ? sku.id : sku.title) + '][' + conf + ']';
}
getSpecData() {
return this.options.specData;
}
getFormFilter() {
var fariyForm = $('form.fairy-form');
if (!fariyForm.attr('lay-filter')) {
fariyForm.attr('lay-filter', 'fairy-form-filter');
}
return fariyForm.attr('lay-filter');
}
getFormSkuData() {
var skuData = {};
$.each(form.val(this.getFormFilter()), function (key, value) {
if (key.startsWith('skus')) {
skuData[key] = value;
}
});
return skuData;
}
}
exports(MOD_NAME, {
render: function (options) {
return new SkuTable(options);
}
})
});

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
html #layuicss-skincodecss{display:none;position:absolute;width:1989px}.layui-code-h3,.layui-code-view{position:relative;font-size:12px}.layui-code-view{display:block;margin:10px 0;padding:0;border:1px solid #eee;border-left-width:6px;background-color:#FAFAFA;color:#333;font-family:Courier New}.layui-code-h3{padding:0 10px;height:40px;line-height:40px;border-bottom:1px solid #eee}.layui-code-h3 a{position:absolute;right:10px;top:0;color:#999}.layui-code-view .layui-code-ol{position:relative;overflow:auto}.layui-code-view .layui-code-ol li{position:relative;margin-left:45px;line-height:20px;padding:0 10px;border-left:1px solid #e2e2e2;list-style-type:decimal-leading-zero;*list-style-type:decimal;background-color:#fff}.layui-code-view .layui-code-ol li:first-child{padding-top:10px}.layui-code-view .layui-code-ol li:last-child{padding-bottom:10px}.layui-code-view pre{margin:0}.layui-code-notepad{border:1px solid #0C0C0C;border-left-color:#3F3F3F;background-color:#0C0C0C;color:#C2BE9E}.layui-code-notepad .layui-code-h3{border-bottom:none}.layui-code-notepad .layui-code-ol li{background-color:#3F3F3F;border-left:none}.layui-code-demo .layui-code{visibility:visible!important;margin:-15px;border-top:none;border-right:none;border-bottom:none}.layui-code-demo .layui-tab-content{padding:15px;border-top:none}

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 701 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 299 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,66 @@
.number-input-container {
overflow: hidden;
display: inline-block;
}
.number-input-container .number-input-subtract,
.number-input-container .number-input-add,
.number-input-container .layui-input {
position: relative;
z-index: 0;
float: left;
user-select: none;
-ms-user-select: none;
-moz-user-select: none;
-webkit-user-select: none;
background-color: #ffffff;
}
.number-input-container .number-input-subtract,
.number-input-container .number-input-add {
cursor: pointer;
height: 36px;
line-height: 38px;
width: 38px;
border-radius: 2px;
text-align: center;
border: 1px solid #eee;
transition: 0.2s;
background-color: #f6f6f6;
}
.number-input-container .number-input-subtract:hover,
.number-input-container .number-input-add:hover {
background-color: #f2f2f2;
}
.number-input-container .number-input-subtract {
border-top-right-radius: 0px;
border-bottom-right-radius: 0px;
}
.number-input-container .number-input-add {
border-top-left-radius: 0px;
border-bottom-left-radius: 0px;
margin-left: -1px;
}
.number-input-container .layui-input {
z-index: 1;
float: left;
border-radius: 0px;
padding-left: 0;
text-align: center;
margin-left: -1px;
}
.number-input-container .layui-input::-webkit-inner-spin-button,
.number-input-container .layui-input::-webkit-outer-spin-button {
-webkit-appearance: none;
}
@media screen and (max-width: 678px) {
.media-screen-container .media-screen-subtract,
.media-screen-container .media-screen-add {
height: 30px;
line-height: 30px;
}
.media-screen-container .media-screen-input {
height: 32px;
line-height: 32px;
width: 60px !important;
}
}
/*# sourceMappingURL=theme.css.map */

View File

@ -0,0 +1 @@
{"version":3,"sources":["theme.less"],"names":[],"mappings":"AAAA;EACE,gBAAA;EACA,qBAAA;;AAFF,uBAIE;AAJF,uBAI0B;AAJ1B,uBAI6C;EACzC,kBAAA;EACA,UAAA;EACA,WAAA;EACA,iBAAA;EACA,qBAAA;EACA,sBAAA;EACA,yBAAA;EACA,yBAAA;;AAZJ,uBAeE;AAfF,uBAe0B;EACtB,eAAA;EACA,YAAA;EACA,iBAAA;EACA,WAAA;EACA,kBAAA;EACA,kBAAA;EACA,sBAAA;EACA,gBAAA;EACA,yBAAA;;AAxBJ,uBA2BE,uBAAsB;AA3BxB,uBA2BgC,kBAAiB;EAC7C,yBAAA;;AA5BJ,uBA+BE;EACE,4BAAA;EACA,+BAAA;;AAjCJ,uBAoCE;EACE,2BAAA;EACA,8BAAA;EACA,iBAAA;;AAvCJ,uBA0CE;EACE,UAAA;EACA,WAAA;EACA,kBAAA;EACA,eAAA;EACA,kBAAA;EACA,iBAAA;;AAhDJ,uBAmDE,aAAY;AAnDd,uBAoDE,aAAY;EACV,wBAAA;;AAIJ,mBAAqC;EACnC,uBACE;EADF,uBAC0B;IACtB,YAAA;IACA,iBAAA;;EAHJ,uBAME;IACE,YAAA;IACA,iBAAA;IACA,sBAAA","file":"theme.css"}

View File

@ -0,0 +1,71 @@
.number-input-container {
overflow: hidden;
display: inline-block;
.number-input-subtract, .number-input-add, .layui-input {
position: relative;
z-index: 0;
float: left;
user-select: none;
-ms-user-select: none;
-moz-user-select: none;
-webkit-user-select: none;
background-color: #ffffff;
}
.number-input-subtract, .number-input-add {
cursor: pointer;
height: 36px;
line-height: 38px;
width: 38px;
border-radius: 2px;
text-align: center;
border: 1px solid #eee;
transition: .2s;
background-color: #f6f6f6;
}
.number-input-subtract:hover, .number-input-add:hover {
background-color: #f2f2f2;
}
.number-input-subtract {
border-top-right-radius: 0px;
border-bottom-right-radius: 0px;
}
.number-input-add {
border-top-left-radius: 0px;
border-bottom-left-radius: 0px;
margin-left: -1px;
}
.layui-input {
z-index: 1;
float: left;
border-radius: 0px;
padding-left: 0;
text-align: center;
margin-left: -1px;
}
.layui-input::-webkit-inner-spin-button,
.layui-input::-webkit-outer-spin-button {
-webkit-appearance: none;
}
}
@media screen and (max-width: 678px) {
.media-screen-container {
.media-screen-subtract, .media-screen-add {
height: 30px;
line-height: 30px;
}
.media-screen-input {
height: 30px + 2px;
line-height: 30px + 2px;
width: 60px !important;
}
}
}

View File

@ -0,0 +1,293 @@
/**
* @name numberInput
* @author HuangJunjie
* @description layui 数值输入框扩展
* @version 2.0.3.20220623
*/
layui.define(["jquery"], function (exports) {
var $ = layui.jquery;
var prefix = "number-input";
/**
* 链接外部样式文件
* 码云 @hulangfy 同学建议
*/
layui.link(layui.cache.base + 'numberInput/css/theme.css');
/**
* 创建样式列表
* @param names
* @returns {string}
*/
function createClassList(flag, names) {
if (typeof names == "string") names = [names];
var classList = [];
names.forEach(function (name) {
classList.push([prefix, flag].join("-"));
classList.push([name, flag].join("-"));
});
return classList.join(" ");
}
/**
* 精度数字
* @param value
* @param precision
*/
function ratioNumber(value, precision) {
if (precision === undefined) precision = 0;
var floatVal = parseFloat(value) || 0;
var ratio = Math.pow(10, precision);
return ((floatVal * ratio) / ratio).toFixed(precision);
}
/**
* 检查是否包含特定属性
* @param {*} $el
* @param {*} attr
* @returns
*/
function hasAttr($el, attr) {
var attrs = $el[0].attributes;
for (var i = 0; i < attrs.length; i++) {
if (attrs[i].name === attr) {
return attrs[i].value !== "false";
}
}
return false;
}
/**
* 初始化操作
* @param id
* @param opts
*/
function render(id, opts) {
if (!opts) opts = {};
// 绑定Dom
$(id).each(function () {
(function ($input) {
var $target = $input.parent();
// 取出配置
var max = parseFloat(opts.max || $input.data("max")) || 999999999;
var min = parseFloat(opts.min || $input.data("min")) || 0;
var precision = parseInt(opts.precision || $input.data("precision")) || 0;
var ratio = Math.pow(10, precision);
var step = opts.step ? parseFloat(opts.step || $input.date("step")) : ((parseFloat(opts.step) || 1) / ratio);
var skin = opts.skin || "auto";
var iconAdd = opts.iconAdd || $input.data("icon-add") || "layui-icon layui-icon-addition";
var iconSubtract = opts.iconSubtract || $input.data("icon-subtract") || "layui-icon layui-icon-subtraction";
var width = opts.width || $input.data("width") || 100;
var allowEmpty = opts.allowEmpty || hasAttr($input, "data-allow-empty") || false;
var autoSelect = opts.autoSelect || hasAttr($input, "data-auto-select") || false;
var setDefaultValue = opts.defaultValue || $input.val() || (hasAttr($input, "data-default-value") ? $input.attr("data-default-value") : "");
var defaultEmptyValue = opts.defaultEmptyValue || false;
var defaultValue = ratioNumber(parseFloat(setDefaultValue) || 0, precision);
if (defaultEmptyValue && setDefaultValue.length === 0) defaultValue = "";
var readonly = opts.readonly || $input.attr("readonly") || false;
var disabled = opts.disabled || $input.attr("disabled") || false;
var handleEvent = opts.handleEvent || "input";
// 激活指定事件
function activeEvent(name, event, dom, value, tree) {
if (opts.event && typeof opts.event[name] == "function") {
return opts.event[name](event, dom, value, tree);
} else {
return false;
}
}
// 开始组装DOM
activeEvent("beforeCreated");
// 绑定元素
var $container = $('<div class="' + createClassList("container", skin) + '"></div>');
var $subtract = $('<div class="' + createClassList("subtract", skin) + '"></div>').append($('<i class="' + iconSubtract + '"></i>'));
var $add = $('<div class="' + createClassList("add", skin) + '"></div>').append($('<i class="' + iconAdd + '"></i>'));
$input.addClass(createClassList("input", skin));
// DOM集合
var $dom = {
input: $input,
subtract: $subtract,
add: $add,
container: $container,
};
// 自动全选
$input.on("focus", function (event) {
activeEvent("focus", event, $input, $input.val(), $dom);
if (autoSelect) $input.select()
});
$input.on("select", function (event) {
activeEvent("select", event, $input, $input.val(), $dom);
});
// 处理逻辑
$input
.val(defaultValue)
.css({
width: width,
})
.attr({
readonly: readonly,
disabled: disabled
})
.on(handleEvent, function (event) {
var val = $(this).val();
var newVal = val;
// 如果精度大于0
if (precision > 0) {
newVal = val.replace(/[^\d\-\.]/g, "");
newVal = newVal.replace(/^\./, "");
newVal = newVal.replace(/\.{2,}$/g, ".");
newVal = newVal.replace(/\-\./, "-");
newVal = newVal.replace(new RegExp("\\.(\\d{" + precision + "})\\d+", "g"), ".$1");
} else {
newVal = newVal.replace(/[^\d\-]/g, "");
if (min >= 0) {
newVal = newVal.replace(/^0([0-9])/, "$1");
} else {
newVal = newVal.replace(/\-0{2}/, "-0");
newVal = newVal.replace(/\-0([0-9])/, "-$1");
}
}
// 不允许输入以0开头的整数
newVal = newVal.replace(/^0+/g, "0");
$(this).val(newVal);
// 如果最小值小于零则不允许输入负数
if (min >= 0) {
newVal = newVal.replace(/\-/g, "");
}
// 只允许头部出现负号
var values = newVal.split("");
values.forEach(function (val, i) {
if (val === "-" && i !== 0) {
values.splice(i, 1);
}
});
newVal = values.join("");
if (newVal) {
var floatVal = parseFloat(newVal);
if (floatVal > max) {
var maxVal = ratioNumber(max, precision);
$(this).val(maxVal);
activeEvent("change", event, $input, maxVal, $dom);
activeEvent("input", event, $input, maxVal, $dom);
return;
}
if (floatVal < min) {
var minVal = ratioNumber(min, precision);
$(this).val(minVal);
activeEvent("change", event, $input, minVal, $dom);
activeEvent("input", event, $input, minVal, $dom);
return;
}
}
$(this).val(newVal);
activeEvent("change", event, $input, val, $dom);
activeEvent("input", event, $input, val, $dom);
})
.on("blur", function (event) {
var val = $(this).val();
var newVal = 0;
if (val.length === 0) {
if (allowEmpty) {
activeEvent("change", event, $input, val, $dom);
activeEvent("blur", event, $input, val, $dom);
} else {
newVal = ratioNumber(defaultValue, precision);
$(this).val(newVal);
activeEvent("change", event, $input, newVal, $dom);
activeEvent("blur", event, $input, newVal, $dom);
}
} else {
newVal = ratioNumber(val, precision);
$(this).val(newVal);
activeEvent("change", event, $input, newVal, $dom);
activeEvent("blur", event, $input, newVal, $dom);
}
})
.on("keypress", function (event) {
activeEvent("keypress", event, $input, $input.val(), $dom);
}).on("mousewheel", function (event) {
activeEvent("mousewheel", event, $input, $input.val(), $dom);
});
$subtract.on("click", function (event) {
if (readonly || disabled) return;
var val = $input.val();
var floatVal = parseFloat(val);
var newVal = 0;
if (floatVal - step >= min) {
newVal = ratioNumber(floatVal - step, precision);
$input.val(newVal);
if (floatVal !== min) {
activeEvent("change", event, $subtract, newVal, $dom);
} else {
activeEvent("toMin", event, $subtract, newVal, $dom);
}
} else {
newVal = ratioNumber(min, precision);
$input.val(newVal);
if (floatVal === min) {
activeEvent("toMin", event, $subtract, newVal, $dom);
} else {
activeEvent("change", event, $subtract, newVal, $dom);
}
}
});
$add.on("click", function (event) {
if (readonly || disabled) return;
var val = $input.val();
var floatVal = parseFloat(val);
var newVal = 0;
if (floatVal + step <= max) {
newVal = ratioNumber(floatVal + step, precision);
$input.val(newVal);
activeEvent("change", event, $add, newVal, $dom);
} else {
newVal = ratioNumber(max, precision);
$input.val(newVal);
if (floatVal === max) {
activeEvent("toMax", event, $add, newVal, $dom);
} else {
activeEvent("change", event, $add, newVal, $dom);
}
}
});
$container.append($subtract).append($input).append($add);
activeEvent("created", $dom);
$target.empty().append($container);
activeEvent("mounted", $dom);
})($(this))
})
}
exports("numberInput", {
render: render
});
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 444 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 451 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 443 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 447 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 447 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 443 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 455 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 447 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 456 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 453 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 447 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 460 B

581
vendor/composer/ClassLoader.php vendored Normal file
View File

@ -0,0 +1,581 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Autoload;
/**
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
*
* $loader = new \Composer\Autoload\ClassLoader();
*
* // register classes with namespaces
* $loader->add('Symfony\Component', __DIR__.'/component');
* $loader->add('Symfony', __DIR__.'/framework');
*
* // activate the autoloader
* $loader->register();
*
* // to enable searching the include path (eg. for PEAR packages)
* $loader->setUseIncludePath(true);
*
* In this example, if you try to use a class in the Symfony\Component
* namespace or one of its children (Symfony\Component\Console for instance),
* the autoloader will first look for the class under the component/
* directory, and it will then fallback to the framework/ directory if not
* found before giving up.
*
* This class is loosely based on the Symfony UniversalClassLoader.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jordi Boggiano <j.boggiano@seld.be>
* @see https://www.php-fig.org/psr/psr-0/
* @see https://www.php-fig.org/psr/psr-4/
*/
class ClassLoader
{
/** @var \Closure(string):void */
private static $includeFile;
/** @var ?string */
private $vendorDir;
// PSR-4
/**
* @var array[]
* @psalm-var array<string, array<string, int>>
*/
private $prefixLengthsPsr4 = array();
/**
* @var array[]
* @psalm-var array<string, array<int, string>>
*/
private $prefixDirsPsr4 = array();
/**
* @var array[]
* @psalm-var array<string, string>
*/
private $fallbackDirsPsr4 = array();
// PSR-0
/**
* @var array[]
* @psalm-var array<string, array<string, string[]>>
*/
private $prefixesPsr0 = array();
/**
* @var array[]
* @psalm-var array<string, string>
*/
private $fallbackDirsPsr0 = array();
/** @var bool */
private $useIncludePath = false;
/**
* @var string[]
* @psalm-var array<string, string>
*/
private $classMap = array();
/** @var bool */
private $classMapAuthoritative = false;
/**
* @var bool[]
* @psalm-var array<string, bool>
*/
private $missingClasses = array();
/** @var ?string */
private $apcuPrefix;
/**
* @var self[]
*/
private static $registeredLoaders = array();
/**
* @param ?string $vendorDir
*/
public function __construct($vendorDir = null)
{
$this->vendorDir = $vendorDir;
self::initializeIncludeClosure();
}
/**
* @return string[]
*/
public function getPrefixes()
{
if (!empty($this->prefixesPsr0)) {
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
}
return array();
}
/**
* @return array[]
* @psalm-return array<string, array<int, string>>
*/
public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}
/**
* @return array[]
* @psalm-return array<string, string>
*/
public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}
/**
* @return array[]
* @psalm-return array<string, string>
*/
public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}
/**
* @return string[] Array of classname => path
* @psalm-return array<string, string>
*/
public function getClassMap()
{
return $this->classMap;
}
/**
* @param string[] $classMap Class to filename map
* @psalm-param array<string, string> $classMap
*
* @return void
*/
public function addClassMap(array $classMap)
{
if ($this->classMap) {
$this->classMap = array_merge($this->classMap, $classMap);
} else {
$this->classMap = $classMap;
}
}
/**
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param string[]|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*
* @return void
*/
public function add($prefix, $paths, $prepend = false)
{
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
(array) $paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
(array) $paths
);
}
return;
}
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
(array) $paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param string[]|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
(array) $paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
(array) $paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
// Register directories for a new namespace.
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
(array) $paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param string[]|string $paths The PSR-0 base directories
*
* @return void
*/
public function set($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr0 = (array) $paths;
} else {
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
}
}
/**
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param string[]|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function setPsr4($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr4 = (array) $paths;
} else {
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
}
}
/**
* Turns on searching the include path for class files.
*
* @param bool $useIncludePath
*
* @return void
*/
public function setUseIncludePath($useIncludePath)
{
$this->useIncludePath = $useIncludePath;
}
/**
* Can be used to check if the autoloader uses the include path to check
* for classes.
*
* @return bool
*/
public function getUseIncludePath()
{
return $this->useIncludePath;
}
/**
* Turns off searching the prefix and fallback directories for classes
* that have not been registered with the class map.
*
* @param bool $classMapAuthoritative
*
* @return void
*/
public function setClassMapAuthoritative($classMapAuthoritative)
{
$this->classMapAuthoritative = $classMapAuthoritative;
}
/**
* Should class lookup fail if not found in the current class map?
*
* @return bool
*/
public function isClassMapAuthoritative()
{
return $this->classMapAuthoritative;
}
/**
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
*
* @param string|null $apcuPrefix
*
* @return void
*/
public function setApcuPrefix($apcuPrefix)
{
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
}
/**
* The APCu prefix in use, or null if APCu caching is not enabled.
*
* @return string|null
*/
public function getApcuPrefix()
{
return $this->apcuPrefix;
}
/**
* Registers this instance as an autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not
*
* @return void
*/
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
if (null === $this->vendorDir) {
return;
}
if ($prepend) {
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
} else {
unset(self::$registeredLoaders[$this->vendorDir]);
self::$registeredLoaders[$this->vendorDir] = $this;
}
}
/**
* Unregisters this instance as an autoloader.
*
* @return void
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
if (null !== $this->vendorDir) {
unset(self::$registeredLoaders[$this->vendorDir]);
}
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
* @return true|null True if loaded, null otherwise
*/
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
(self::$includeFile)($file);
return true;
}
return null;
}
/**
* Finds the path to the file where the class is defined.
*
* @param string $class The name of the class
*
* @return string|false The path if found, false otherwise
*/
public function findFile($class)
{
// class map lookup
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
return false;
}
if (null !== $this->apcuPrefix) {
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
if ($hit) {
return $file;
}
}
$file = $this->findFileWithExtension($class, '.php');
// Search for Hack files if we are running on HHVM
if (false === $file && defined('HHVM_VERSION')) {
$file = $this->findFileWithExtension($class, '.hh');
}
if (null !== $this->apcuPrefix) {
apcu_add($this->apcuPrefix.$class, $file);
}
if (false === $file) {
// Remember that this class does not exist.
$this->missingClasses[$class] = true;
}
return $file;
}
/**
* Returns the currently registered loaders indexed by their corresponding vendor directories.
*
* @return self[]
*/
public static function getRegisteredLoaders()
{
return self::$registeredLoaders;
}
/**
* @param string $class
* @param string $ext
* @return string|false
*/
private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
$first = $class[0];
if (isset($this->prefixLengthsPsr4[$first])) {
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\\')) {
$subPath = substr($subPath, 0, $lastPos);
$search = $subPath . '\\';
if (isset($this->prefixDirsPsr4[$search])) {
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
foreach ($this->prefixDirsPsr4[$search] as $dir) {
if (file_exists($file = $dir . $pathEnd)) {
return $file;
}
}
}
}
}
// PSR-4 fallback dirs
foreach ($this->fallbackDirsPsr4 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
return $file;
}
}
// PSR-0 lookup
if (false !== $pos = strrpos($class, '\\')) {
// namespaced class name
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
} else {
// PEAR-like class name
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
}
if (isset($this->prefixesPsr0[$first])) {
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
if (0 === strpos($class, $prefix)) {
foreach ($dirs as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
}
}
}
// PSR-0 fallback dirs
foreach ($this->fallbackDirsPsr0 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
// PSR-0 include paths.
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
return $file;
}
return false;
}
private static function initializeIncludeClosure(): void
{
if (self::$includeFile !== null) {
return;
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*
* @param string $file
* @return void
*/
self::$includeFile = static function($file) {
include $file;
};
}
}

352
vendor/composer/InstalledVersions.php vendored Normal file
View File

@ -0,0 +1,352 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer;
use Composer\Autoload\ClassLoader;
use Composer\Semver\VersionParser;
/**
* This class is copied in every Composer installed project and available to all
*
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
*
* To require its presence, you can require `composer-runtime-api ^2.0`
*
* @final
*/
class InstalledVersions
{
/**
* @var mixed[]|null
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
*/
private static $installed;
/**
* @var bool|null
*/
private static $canGetVendors;
/**
* @var array[]
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static $installedByVendor = array();
/**
* Returns a list of all package names which are present, either by being installed, replaced or provided
*
* @return string[]
* @psalm-return list<string>
*/
public static function getInstalledPackages()
{
$packages = array();
foreach (self::getInstalled() as $installed) {
$packages[] = array_keys($installed['versions']);
}
if (1 === \count($packages)) {
return $packages[0];
}
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
}
/**
* Returns a list of all package names with a specific type e.g. 'library'
*
* @param string $type
* @return string[]
* @psalm-return list<string>
*/
public static function getInstalledPackagesByType($type)
{
$packagesByType = array();
foreach (self::getInstalled() as $installed) {
foreach ($installed['versions'] as $name => $package) {
if (isset($package['type']) && $package['type'] === $type) {
$packagesByType[] = $name;
}
}
}
return $packagesByType;
}
/**
* Checks whether the given package is installed
*
* This also returns true if the package name is provided or replaced by another package
*
* @param string $packageName
* @param bool $includeDevRequirements
* @return bool
*/
public static function isInstalled($packageName, $includeDevRequirements = true)
{
foreach (self::getInstalled() as $installed) {
if (isset($installed['versions'][$packageName])) {
return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
}
}
return false;
}
/**
* Checks whether the given package satisfies a version constraint
*
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
*
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
*
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
* @param string $packageName
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
* @return bool
*/
public static function satisfies(VersionParser $parser, $packageName, $constraint)
{
$constraint = $parser->parseConstraints($constraint);
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
return $provided->matches($constraint);
}
/**
* Returns a version constraint representing all the range(s) which are installed for a given package
*
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
* whether a given version of a package is installed, and not just whether it exists
*
* @param string $packageName
* @return string Version constraint usable with composer/semver
*/
public static function getVersionRanges($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
$ranges = array();
if (isset($installed['versions'][$packageName]['pretty_version'])) {
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
}
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
}
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
}
if (array_key_exists('provided', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
}
return implode(' || ', $ranges);
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
*/
public static function getVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['version'])) {
return null;
}
return $installed['versions'][$packageName]['version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
*/
public static function getPrettyVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
return null;
}
return $installed['versions'][$packageName]['pretty_version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
*/
public static function getReference($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['reference'])) {
return null;
}
return $installed['versions'][$packageName]['reference'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
*/
public static function getInstallPath($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @return array
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
*/
public static function getRootPackage()
{
$installed = self::getInstalled();
return $installed[0]['root'];
}
/**
* Returns the raw installed.php data for custom implementations
*
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
* @return array[]
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
*/
public static function getRawData()
{
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
if (null === self::$installed) {
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
self::$installed = include __DIR__ . '/installed.php';
} else {
self::$installed = array();
}
}
return self::$installed;
}
/**
* Returns the raw data of all installed.php which are currently loaded for custom implementations
*
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
public static function getAllRawData()
{
return self::getInstalled();
}
/**
* Lets you reload the static array from another file
*
* This is only useful for complex integrations in which a project needs to use
* this class but then also needs to execute another project's autoloader in process,
* and wants to ensure both projects have access to their version of installed.php.
*
* A typical case would be PHPUnit, where it would need to make sure it reads all
* the data it needs from this class, then call reload() with
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
* the project in which it runs can then also use this class safely, without
* interference between PHPUnit's dependencies and the project's dependencies.
*
* @param array[] $data A vendor/composer/installed.php data set
* @return void
*
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
*/
public static function reload($data)
{
self::$installed = $data;
self::$installedByVendor = array();
}
/**
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static function getInstalled()
{
if (null === self::$canGetVendors) {
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
}
$installed = array();
if (self::$canGetVendors) {
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
if (isset(self::$installedByVendor[$vendorDir])) {
$installed[] = self::$installedByVendor[$vendorDir];
} elseif (is_file($vendorDir.'/composer/installed.php')) {
$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
self::$installed = $installed[count($installed) - 1];
}
}
}
}
if (null === self::$installed) {
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
self::$installed = require __DIR__ . '/installed.php';
} else {
self::$installed = array();
}
}
$installed[] = self::$installed;
return $installed;
}
}

21
vendor/composer/LICENSE vendored Normal file
View File

@ -0,0 +1,21 @@
Copyright (c) Nils Adermann, Jordi Boggiano
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

Some files were not shown because too many files have changed in this diff Show More