初始上传

This commit is contained in:
2026-04-04 17:27:12 +08:00
parent 4d80d28eb4
commit b7e11774ee
11191 changed files with 1588469 additions and 0 deletions

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,110 @@
var form;
layui.use('form',function () {
form = layui.form;
form.render();
//省 - 监听地址操作
form.on('select(province_id)', function (obj) {
getAreaList(obj.value, 2);//重新渲染地址
});
//市 - 监听地址操作
form.on('select(city_id)', function (obj) {
getAreaList(obj.value, 3);//重新渲染地址
});
//区 - 监听地址操作
form.on('select(district_id)', function (obj) {
getAreaList(obj.value, 4);//重新渲染地址
});
//乡镇 - 监听地址操作
form.on('select(community_id)', function (obj) {
getAreaList(obj.value, 5);//重新渲染地址
});
//省 - 监听地址操作
$('body').off("change",'select[name=province_id]').on("change",'select[name=province_id]',function (obj) {
getAreaList(this.value, 2);//重新渲染地址
form.render();
});
//市 - 监听地址操作
$('body').off("change",'select[name=city_id]').on("change",'select[name=city_id]',function (obj) {
getAreaList(this.value, 3);//重新渲染地址
form.render();
});
//区县 - 监听地址操作
$('body').off("change",'select[name=district_id]').on("change",'select[name=district_id]',function (obj) {
getAreaList(this.value, 4);//重新渲染地址
form.render();
});
});
/**
* 获取地区列表
* @param pid
* @param level
*/
function getAreaList(pid, level){
if(level <= 5){
$.ajax({
type : "POST",
dataType: 'JSON',
url : ns.url("shop/address/getAreaList"),
data : {level,pid},
async : false,
success : function(res) {
if(res.code == 0){
if(level == 1){
$("select[name=province_id] option:gt(0)").remove();
$("select[name=city_id] option:gt(0)").remove();
$("select[name=district_id] option:gt(0)").remove();
$.each(res.data, function(name, value) {
$("select[name=province_id]").append("<option value='"+value.id+"'>"+value.name+"</option>");
});
}else if(level == 2){
$("select[name=city_id] option:gt(0)").remove();
$("select[name=district_id] option:gt(0)").remove();
$.each(res.data, function(name, value) {
$("select[name=city_id]").append("<option value='"+value.id+"'>"+value.name+"</option>");
});
}else if(level == 3){
$("select[name=district_id] option:gt(0)").remove();
$.each(res.data, function(name, value) {
$("select[name=district_id]").append("<option value='"+value.id+"'>"+value.name+"</option>");
});
}else if(level == 4){
$("select[name=community_id] option:gt(0)").remove();
$.each(res.data, function(name, value) {
$("select[name=community_id]").append("<option value='"+value.id+"'>"+value.name+"</option>");
});
}
}else{
layer.msg(res.message);
}
form.render();
}
});
}
}
/**
* 初始化地址
* @param obj {"province_id" : '', "city_id" : '', "district_id" : '', "community_id" : ''}
*/
function initAddress(obj, filter){
form.val(filter, {
"province_id": obj.province_id
});
$("select[name=province_id]").change();
form.val(filter, {
"city_id": obj.city_id
});
$("select[name=city_id]").change();
form.val(filter, {
"district_id": obj.district_id
});
$("select[name=district_id]").change();
form.val(filter, {
"community_id": obj.community_id
});
form.render();
}

View File

@@ -0,0 +1,237 @@
(function(){
let boxCount = 0;
let laytpl;
let template = '';
let tree;
function CategorySelect(param = {}){
boxCount ++;
let that = this;
that.elem = param.elem;//绑定显示输入框元素
that.data = param.data || [];//分类数据
that.callback = param.callback || null;//选择完成后回调方法
that.level = param.level || 'end';//等级 any 任意 end 最末级
that.count = boxCount;
that.boxSign = ".category-select-popup[data-count='"+ that.count +"']";
that.showData = [];
that.position = null;
that.isInit = false;
that.bindEvent();
}
CategorySelect.prototype.initShowData = function (){
let that = this;
if(that.isInit) return;
if(that.showData.length === 0){
if(that.data.length > 0){
var currData = tree;
that.data.forEach(function(item, index){
var selected = -1;
currData.forEach(function(ditem, dindex){
if(ditem.category_id == item.category_id){
selected = dindex;
return;
}
})
that.showData.push({
data : JSON.parse(JSON.stringify(currData)),
selected : selected,
})
if(selected != -1){
currData = currData[selected].child_list;
}
})
}else{
that.showData.push({data : tree, selected : -1});
}
}
that.isInit = true;
}
CategorySelect.prototype.getPosition = function (){
let that = this;
let dom = $(that.elem);
if(dom.length <= 0) throw '元素不存在';
that.position = {
left : dom.offset().left,
top : dom.offset().top + dom.height() + 3,
}
}
CategorySelect.prototype.bindEvent = function (){
let that = this;
//点击绑定元素
$('body').off('click', that.elem).on('click', that.elem, function(){
that.initShowData();
that.render();
})
$(document).on('mouseup', function(e){
var targetArea = $(that.boxSign); // 设置目标区域
if(targetArea.length > 0){
if(!targetArea.is(e.target) && targetArea.has(e.target).length === 0){
targetArea.parent().remove();
that.isInit = false;
that.showData = [];
}
}
});
//点击分类
$('body').off('click', that.boxSign + ' .category-select-ul-box ul li').on('click', that.boxSign + ' .category-select-ul-box ul li', function(){
let target = $(this).attr('data-target').split('|');
let level = target[0];
let index = target[1];
//重置数据
let tempShowData = [];
for(let i in that.showData){
if(i <= level){
tempShowData.push(that.showData[i]);
}
}
that.showData = tempShowData;
that.showData[level].selected = index;
//追加新数据
if(that.showData[level]['data'][index].child_num > 0){
that.showData.push({
data : that.showData[level]['data'][index].child_list,
selected : -1,
})
that.render();
}else{
that.selectEnd();
}
})
$('body').off('click', that.boxSign + ' .category-select-btn-box button').on('click', that.boxSign + ' .category-select-btn-box button', function(){
let action = $(this).data('action');
switch (action) {
case 'confirm':
that.selectEnd();
break;
case 'clear':
that.showData = [];
that.selectEnd();
break;
}
that.isInit = false;
})
}
CategorySelect.prototype.render = function (){
let that = this;
//获取原先的滚动高度
let scroll_top_arr = [];
if($(that.boxSign).length > 0){
$(that.boxSign).find('.category-select-ul-box>ul').each(function () {
scroll_top_arr.push($(this).scrollTop());
})
$(that.boxSign).parent().remove();
}
//getPosition();
laytpl(template).render({
count : that.count,
position : that.position,
showData : that.showData,
level : that.level,
}, function(html) {
$(that.elem).after(html);
//调整选择框位置
let popup_dom = $(".category-select-popup[data-count="+that.count+"]").parent();
let popup_offset = popup_dom.offset();
let elem_offset = $(that.elem).offset();
let elem_height = $(that.elem).height();
let left = elem_offset.left - popup_offset.left;
let top = elem_offset.top - popup_offset.top + elem_height + 5;
popup_dom.css({left:left+'px',top:top+'px'});
//重新渲染后恢复滚动高度
$(that.boxSign).find('.category-select-ul-box>ul').each(function (index) {
let scroll_top = scroll_top_arr[index] || 0;
$(this).scrollTop(scroll_top);
})
});
}
CategorySelect.prototype.selectEnd = function (){
let that = this;
that.data = [];
that.showData.forEach(function(item, index){
if(item.selected !== -1){
that.data.push({
category_id : item.data[item.selected].category_id,
category_name : item.data[item.selected].category_name,
level : item.data[item.selected].level,
attr_class_id : item.data[item.selected].attr_class_id,
})
}
})
$(that.boxSign).parent().remove();
if(typeof that.callback == 'function') that.callback(that.data);
}
layui.use(['laytpl','form'], function () {
laytpl = layui.laytpl;
})
template =
`<div class="category-select-popup-position">
<div class="category-select-popup" data-count="{{ d.count }}" style="width: {{ d.showData.length * 140 }}px;">
<div class="category-select-ul-box">
{{# d.showData.forEach(function(data, level){ }}
<ul>
{{# data.data.forEach(function(item, index){ }}
<li data-target="{{ level }}|{{ index }}" class="{{ index == data.selected ? 'selected' : '' }}">
<span title="{{ item.category_name }}">{{ item.category_name }}</span>
{{# if(item.child_num > 0){ }}
<i class="layui-icon-right layui-icon"></i>
{{# } }}
</li>
{{# }) }}
</ul>
{{# }) }}
</div>
<div class="category-select-btn-box">
<button class="layui-btn layui-btn-primary" data-action="clear">清空</button>
{{# if(d.level == 'any'){ }}
<button class="layui-btn ns-bg-color" data-action="confirm">确认</button>
{{# } }}
</div>
</div>
</div>`;
//获取分类数据
function getGoodsCategoryTree() {
return new Promise(function(resolve, reject){
let url = ns.url("shop/goodscategory/getCategoryTree");
if(location.href.indexOf('cardservice://') !== -1){
url = ns.url("cardservice://shop/servicecategory/lists");
}
$.ajax({
url: url,
dataType: 'JSON',
type: 'POST',
data: {
category_id:'category_id',
category_name:'category_name',
children:'child_list',
},
success: function(res) {
resolve(res);
}
})
})
}
getGoodsCategoryTree().then(function(res){
tree = res.data;
})
//向外暴露接口
window.CategorySelect = CategorySelect;
})()

View File

@@ -0,0 +1,137 @@
var layCascader, goodsCategory = [];
layui.use(['layCascader'], function () {
layCascader = layui.layCascader;
$('.goods-category-con-wrap .layui-block').each(function () {
var category_id = $(this).find('.category_id').val();
var _this = this;
fetchCategory({elem: $(this).find('.select-category'), value: category_id ? parseInt(category_id.split(',').splice(-1)) : ''},
function (value, node) {
var categoryId = [];
node.path.forEach(function (item) {
categoryId.push(item.value)
});
$(_this).find('.category_id').val(categoryId.toString())
}
)
})
});
// 刷新商品分类,更新选择商品分类数据
$('body').off('click', '.goods-category-con-wrap .js-refresh-category').on('click', '.goods-category-con-wrap .js-refresh-category', function () {
$.ajax({
url : ns.url("shop/goodscategory/lists"),
dataType: 'JSON',
type: 'POST',
async: false,
success: function(res) {
goodsCategory = res.data;
var str = '<div class="category-list">';
str += '<div class="item">';
str += '<!--后续做搜索-->';
str += '<ul>';
if(goodsCategory.length) {
for (var i=0;i<goodsCategory.length;i++) {
var item = goodsCategory[i];
str += `{{# if(d.category_id_1 == '${item.category_id}' ){ }}`;
str += `<li data-category-id="${item.category_id}" data-commission-rate="${item.commission_rate}" data-level="${item.level}" class="selected">`;
str += '{{# }else{ }}';
str += `<li data-category-id="${item.category_id}" data-commission-rate="${item.commission_rate}" data-level="${item.level}">`;
str += '{{# } }}';
str += `<span class="category-name">${item.category_name}</span>`;
str += '<span class="right-arrow"></span>';
str += '</li>';
}
}
str += '</ul>';
str += '</div>';
str += '<div class="item" data-level="2"><!--后续做搜索--><ul></ul></div>';
str += '<div class="item" data-level="3"><!--后续做搜索--><ul></ul></div>';
str += '</div>';
str += '<div class="selected-category-wrap">';
str += '<label>您当前选择的是:</label>';
str += '<span class="js-selected-category"></span>';
str += '</div>';
$('#selectedCategory').html(str);
// 刷新商品分类下拉框数据
$('.goods-category-con-wrap .layui-block').each(function () {
$(this).find('.el-cascader').remove(); // 清空渲染
var category_id = $(this).find('.category_id').val();
var _this = this;
fetchCategory({elem: $(this).find('.select-category'), value: category_id ? parseInt(category_id.split(',').splice(-1)) : ''},
function (value, node) {
var categoryId = [];
node.path.forEach(function (item) {
categoryId.push(item.value)
});
$(_this).find('.category_id').val(categoryId.toString())
}
)
})
}
});
});
$('body').off('click', '.goods-category-wrap-box .js-add-category').on('click', '.goods-category-wrap-box .js-add-category', function () {
if ($('.goods-category-con-wrap .layui-block').length >= 10) {
layer.msg('最多添加十个分类');
return;
}
var h = `<div class="layui-block">
<div class="layui-input-inline cate-input-default">
<input type="text" readonly lay-verify="required" autocomplete="off" class="layui-input len-mid select-category" />
<input type="hidden" class="category_id" />
</div>
<a href="javascript:;" class="text-color js-delete-category">删除</a>
</div>`;
$('.goods-category-con-wrap').append(h);
fetchCategory({elem: $('.goods-category-con-wrap .layui-block:last-child').find('.select-category')}, function (value, node) {
var categoryId = [];
node.path.forEach(function (item) {
categoryId.push(item.value)
});
$('.goods-category-con-wrap .layui-block:last-child').find('.category_id').val(categoryId.toString());
});
});
$('body').off('click', '.goods-category-con-wrap .js-delete-category').on('click', '.goods-category-con-wrap .js-delete-category', function () {
$(this).parents('.layui-block').remove();
});
/**
* 渲染分类选择
* @param option
* @param callback
*/
function fetchCategory(option, callback){
if (!goodsCategory.length) {
$.ajax({
url : ns.url("shop/goodscategory/lists"),
dataType: 'JSON',
type: 'POST',
async: false,
success: function(res) {
goodsCategory = res.data;
}
})
}
var _option = {
options: goodsCategory,
props: {
value: 'category_id',
label: 'category_name',
children: 'child_list'
}
};
if (option) Object.assign(_option, option);
var _cascader = layCascader(_option);
_cascader.changeEvent(function (value, node) {
typeof callback == 'function' && callback(value, node)
});
}

File diff suppressed because one or more lines are too long

580
app/shop/view/public/js/common.js Executable file
View File

@@ -0,0 +1,580 @@
$(function () {
$('body').on('click', '.icon-box .js-preview', function () {
var h = `<div class="icon-preview">
<div class="icon-preview-block">
` + $(this).parents('.icon-box').html() + `
</div>
</div>`;
$('body').append(h);
$('.icon-preview-block .operation').remove();
$('.icon-preview').click(function () {
$(this).remove();
})
});
tipsShow();
});
/**
* 打开相册
* display_type img-选择图片icon-选择icon
*/
function openAlbum(callback, imgNum = 9999, is_thumb = 0, type = 'img', display_type = "img") {
layui.use(['layer'], function () {
layer.open({
type: 2,
title: '素材管理',
area: ['950px', '610px'],
fixed: false, //不固定
btn: ['保存', '返回'],
content: ns.url("shop/album/album?request_mode=iframe&imgNum=" + imgNum + "&is_thumb=" + is_thumb + '&type=' + type + '&site_id=' + ns_url.siteId + '&app_module=' + ns_url.appModule + '&display_type=' + display_type),
yes: function (index, layero) {
var iframeWin = document.getElementById(layero.find('iframe')[0]['name']).contentWindow;//得到iframe页的窗口对象执行iframe页的方法
iframeWin.selectAlbumListener(function (obj) {
if (typeof callback == "string") {
try {
eval(callback + '(obj)');
layer.close(index);
} catch (e) {
console.error('回调函数' + callback + '未定义');
}
} else if (typeof callback == "function") {
callback(obj);
layer.close(index);
}
});
}
});
});
}
/**
* 商品选择器
* @param callback 回调函数
* @param selectId 已选商品id
* @param params {}
* mode模式spu商品、sku商品多规格项
* max_num最大数量
* min_num最小数量
* is_virtual是否虚拟 0 1
* disabled开启禁用已选 0 1
* promotion营销活动标识pintuan、groupbuy、fenxiao module 表示组件返回id
* is_disabled_goods_class: 1 表示关闭商品类型筛选 0表示开启商品类型筛选
* goods_class: 商品类型1实物商品2虚拟商品3电子卡密商品4服务项目5卡项套餐6称重商品不传查全部
*/
function goodsSelect(callback, selectId, params = {}) {
layui.use(['layer'], function () {
localStorage.removeItem('goods_select_id'); // 删除选中id 本地缓存
if (selectId.length) {
localStorage.setItem('goods_select_id', selectId.toString());
}
params.mode = params.mode ? params.mode : 'spu';
if (params.disabled == undefined || params.disabled == 0) {
params.disabled = 0;
} else {
params.disabled = 1;
}
params.site_id = ns_url.siteId;
params.app_module = ns_url.appModule;
params.is_disabled_goods_class = params.is_disabled_goods_class || 0;
params.goods_class = params.goods_class || "";
params.max_num = params.max_num || 200; // 最多选择数量
params.is_weigh = params.is_weigh || 0; // 是否支持称重
// if(!params.post) params.post = 'shop';
// if (params.post == 'store') params.post += '://store';
var url = ns.url("shop/goods/goodsselect?request_mode=iframe", params);
layer.open({
title: "商品选择",
type: 2,
area: ['1000px', '720px'],
fixed: false, //不固定
btn: ['保存', '清空', '返回'],
content: url,
yes: function (index, layero) {
var iframeWin = document.getElementById(layero.find('iframe')[0]['name']).contentWindow;//得到iframe页的窗口对象执行iframe页的方法
iframeWin.selectGoodsListener(function (obj) {
if (typeof callback == "string") {
try {
eval(callback + '(obj)');
layer.close(index);
} catch (e) {
console.error('回调函数' + callback + '未定义');
}
} else if (typeof callback == "function") {
callback(obj);
layer.close(index);
}
});
},
btn2: function (index, layero) {
// 清空
var iframeWin = document.getElementById(layero.find('iframe')[0]['name']).contentWindow;//得到iframe页的窗口对象执行iframe页的方法
iframeWin.clearGoodsListener(function (obj) {
if (typeof callback == "string") {
try {
eval(callback + '(obj)');
layer.close(index);
} catch (e) {
console.error('回调函数' + callback + '未定义');
}
} else if (typeof callback == "function") {
callback(obj);
layer.close(index);
}
});
}
});
});
}
/**
* 店铺笔记选择器
* @param callback 回调函数
* @param selectId 已选笔记id
* @param params modemin_num 最小数量
*/
function notesSelect(callback, selectId, params) {
layui.use(['layer'], function () {
localStorage.removeItem('note_select_id'); // 删除选中id 本地缓存
if (selectId.length) {
localStorage.setItem('note_select_id', selectId.toString()); // 删除选中id 本地缓存
}
var url = ns.url("notes://shop/notes/notesSelect?request_mode=iframe", params);
layer.open({
title: "店铺笔记选择",
type: 2,
area: ['1000px', '720px'],
fixed: false, //不固定
btn: ['保存', '返回'],
content: url,
yes: function (index, layero) {
var iframeWin = document.getElementById(layero.find('iframe')[0]['name']).contentWindow;//得到iframe页的窗口对象执行iframe页的方法
iframeWin.selectNotesListener(function (obj) {
if (typeof callback == "string") {
try {
eval(callback + '(obj)');
layer.close(index);
} catch (e) {
console.error('回调函数' + callback + '未定义');
}
} else if (typeof callback == "function") {
callback(obj);
layer.close(index);
}
});
}
});
});
}
function tipsShow() {
var prompt_tips_box = 0;
// 处理鼠标划上提示问题
setTimeout(function () {
$('body .js-prompt-top').unbind('mouseover').unbind('mouseout').unbind('mousemove');
$('body .js-prompt-top').mouseover(function () {
var prompt_tips_data;
prompt_tips_data = $(this).data('tips');
if (!prompt_tips_data) {
prompt_tips_data = $('.js-prompt-top-' + $(this).data('tipsbox')).html();
}
prompt_tips_box = layer.tips(prompt_tips_data, $(this), {
tips: [1, '#fff'],//还可配置颜色
time: 0
});
}).mouseleave(function () {
layer.close(prompt_tips_box)
})
}, 1000) //延迟执行为解决某些页面渲染问题
}
/**
* 图标库选择器
* @param callback 回调函数
* @param params icon选中的icon
*/
function iconSelect(callback, params = {}) {
layui.use(['layer'], function () {
layer.open({
title: "图标选择器",
type: 2,
area: ['950px', '550px'],
fixed: false, //不固定
btn: ['保存', '返回'],
content: ns.url("shop/diy/iconfont", {
request_mode: 'iframe',
icon: params.icon,
site_id: ns_url.siteId,
app_module: ns_url.appModule
}),
yes: function (index, layero) {
var iframeWin = document.getElementById(layero.find('iframe')[0]['name']).contentWindow;//得到iframe页的窗口对象执行iframe页的方法
iframeWin.selectIconListener(function (obj) {
if (typeof callback == "string") {
try {
eval(callback + '(obj)');
layer.close(index);
} catch (e) {
console.error('回调函数' + callback + '未定义');
}
} else if (typeof callback == "function") {
callback(obj);
layer.close(index);
}
});
}
});
});
}
/**
* 图标风格设置
* @param params
* @param callback
*/
function iconStyleSet(params, callback) {
if (params.style != undefined) localStorage.setItem('iconStyle', params.style);
layer.open({
title: "图标风格设置",
type: 2,
area: ['1000px', '720px'],
fixed: false, //不固定
btn: ['保存', '取消'],
content: ns.url("shop/diy/iconstyleset?request_mode=iframe", params.query ? params.query : {}),
yes: function (index, layero) {
var iframeWin = document.getElementById(layero.find('iframe')[0]['name']).contentWindow;//得到iframe页的窗口对象执行iframe页的方法
iframeWin.iconStyleListener(function (obj) {
if (typeof callback == "string") {
try {
eval(callback + '(obj)');
layer.close(index);
} catch (e) {
console.error('回调函数' + callback + '未定义');
}
} else if (typeof callback == "function") {
callback(obj);
layer.close(index);
}
});
}
});
}
/**
* 选择图标风格
* @param option
*/
function selectIconStyle(option) {
var _w = option.width ? option.width : 340,
_h = option.height ? option.height : 200,
_x = $(option.elem).offset().left + $(option.elem).width() - _w,
_y = $(option.elem).offset().top + $(option.elem).height();
option.pagex -= _w;
window.onmessage = function (e) {
if (e.data.event && e.data.event == 'selectIconStyle') {
$('.select-icon-style').remove();
typeof option.callback == 'function' && option.callback(e.data.data);
}
};
var h = `
<div class="select-icon-style">
<div class="icon-style-wrap" style="width: ` + _w + `px;height: ` + _h + `px;left:` + _x + `px;top:` + _y + `px">
<iframe src="` + ns.url('shop/diy/selecticonstyle', {request_mode: 'iframe', icon: option.icon}) + `" frameborder="0"></iframe>
</div>
</div>
`;
$('body').append(h);
// 点击任意位置关闭弹窗
$('.select-icon-style').click(function () {
$(this).remove();
})
}
/**
* 商品品牌选择器
* @param callback 回调函数
* @param params select_id 已选商品id
*/
function goodsBrandSelect(callback, params = {}) {
layui.use(['layer'], function () {
localStorage.removeItem('goods_brand_select_id'); // 删除选中id 本地缓存
if (params.select_id) {
localStorage.setItem('goods_brand_select_id', params.select_id);
}
var url = ns.url("shop/goodsbrand/brandselect?request_mode=iframe", params);
layer.open({
title: "商品品牌选择",
type: 2,
area: ['800px', '600px'],
fixed: false, //不固定
btn: ['保存', '返回'],
content: url,
yes: function (index, layero) {
var iframeWin = document.getElementById(layero.find('iframe')[0]['name']).contentWindow;//得到iframe页的窗口对象执行iframe页的方法
iframeWin.selectGoodsBrandListener(function (obj) {
if (typeof callback == "string") {
try {
eval(callback + '(obj)');
layer.close(index);
} catch (e) {
console.error('回调函数' + callback + '未定义');
}
} else if (typeof callback == "function") {
callback(obj);
layer.close(index);
}
});
}
});
});
}
/**
* 文章选择器
* @param callback 回调函数
* @param params select_id 已选商品id
*/
function articleSelect(callback, params = {}) {
layui.use(['layer'], function () {
localStorage.removeItem('article_select_id'); // 删除选中id 本地缓存
if (params.select_id) {
localStorage.setItem('article_select_id', params.select_id);
}
var url = ns.url("shop/article/articleselect?request_mode=iframe", params);
layer.open({
title: "文章选择",
type: 2,
area: ['800px', '600px'],
fixed: false, //不固定
btn: ['保存', '返回'],
content: url,
yes: function (index, layero) {
var iframeWin = document.getElementById(layero.find('iframe')[0]['name']).contentWindow;//得到iframe页的窗口对象执行iframe页的方法
iframeWin.selectArticleListener(function (obj) {
if (typeof callback == "string") {
try {
eval(callback + '(obj)');
layer.close(index);
} catch (e) {
console.error('回调函数' + callback + '未定义');
}
} else if (typeof callback == "function") {
callback(obj);
layer.close(index);
}
});
}
});
});
}
function storeSelect(callback, params = {}) {
layui.use(['layer'], function () {
layer.open({
title: "选择门店",
type: 2,
area: ['950px', '550px'],
fixed: false, //不固定
btn: ['保存', '返回'],
content: ns.url("shop/store/selectstore?request_mode=iframe", params),
yes: function (index, layero) {
var iframeWin = document.getElementById(layero.find('iframe')[0]['name']).contentWindow;//得到iframe页的窗口对象执行iframe页的方法
iframeWin.selectStoreListener(function (obj) {
if (typeof callback == "string") {
try {
eval(callback + '(obj)');
layer.close(index);
} catch (e) {
console.error('回调函数' + callback + '未定义');
}
} else if (typeof callback == "function") {
callback(obj);
layer.close(index);
}
});
}
});
});
}
function showNotify(option) {
var node = {};
if (option.icon && ['success', 'fail', 'info', 'warning'].indexOf(option.icon) != -1) node.icon = '<div class="icon"><i class="' + option.icon + '"></i></div>';
if (option.title) node.title = '<div class="title">' + option.title + '</div>';
if (option.content) node.content = '<div class="content">' + option.content + '</div>';
var h = `<div class="notify-item">
` + (node.icon ? node.icon : '') + `
<span class="iconfont iconclose_light"></span>
<div class="box">
` + (node.title ? node.title : '') + `
` + (node.content ? node.content : '') + `
</div>
</div>`;
if ($('.notify-wrap').length) {
$('.notify-wrap').append(h);
} else {
$('body').append('<div class="notify-wrap">' + h + '</div>');
}
let elem = $('.notify-wrap .notify-item:last-child');
// 手动关闭
elem.find('.iconclose_light').click(function () {
$(this).parents('.notify-item').remove();
})
// 自动关闭
let duration = option.duration != undefined ? option.duration : 4500;
if (duration) {
setTimeout(function () {
elem.remove();
}, duration)
}
}
// 清理缓存
function clearCache() {
$.ajax({
type: 'post',
url: ns.url("shop/Login/clearCache"),
dataType: 'JSON',
success: function (res) {
layer.msg(res.message);
listenerHash(); // 刷新页面
layer.closeAll();
}
})
}
var repeatPwdFlag = false;
// 重置密码
function resetPassword() {
layer.open({
type: 1,
content: $('#reset_pass').html(),
offset: 'auto',
area: ['500px']
});
setTimeout(function () {
$(".reset-pass").removeClass('layui-this');
form.render();
}, 1000);
}
function repass() {
var old_pass = $("#old_pass").val();
var new_pass = $("#new_pass").val();
var repeat_pass = $("#repeat_pass").val();
if (old_pass == '') {
$("#old_pass").focus();
layer.msg("原密码不能为空");
return;
}
if (new_pass == '') {
$("#new_pass").focus();
layer.msg("新密码不能为空");
return;
} else if (new_pass == old_pass) {
$("#new_pass").focus();
layer.msg("新密码不能与原密码一致");
return;
} else if ($("#new_pass").val().length < 6) {
$("#new_pass").focus();
layer.msg("密码不能少于6位数");
return;
}
if (repeat_pass == '') {
$("#repeat_pass").focus();
layer.msg("密码不能为空");
return;
} else if ($("#repeat_pass").val().length < 6) {
$("#repeat_pass").focus();
layer.msg("密码不能少于6位数");
return;
}
if (new_pass != repeat_pass) {
$("#repeat_pass").focus();
layer.msg("两次密码输入不一致,请重新输入");
return;
}
if (repeatPwdFlag) return;
repeatPwdFlag = true;
$.ajax({
type: "POST",
dataType: 'JSON',
url: ns.url("shop/login/modifypassword"),
data: {"old_pass": old_pass, "new_pass": new_pass},
success: function (res) {
layer.msg(res.message);
repeatPwdFlag = false;
if (res.code == 0) {
listenerHash(); // 刷新页面
layer.closeAll();
}
}
});
}
function getShopUrl() {
window.open(ns.url('index/index/h5preview'));
}
function goHelpDocument() {
window.open(ns.url('https://www.kancloud.cn/niucloud/niushop_b2c_v5/3037616'));
}
function patchAlert() {
$.ajax({
type: "POST",
dataType: 'JSON',
url: ns.url("shop/upgrade/patchalertlists"),
data: {},
success: function (res) {
if(res.data.length > 0){
layui.use(['form', 'laytpl'], function (){
laytpl($("#patch_alert").html()).render(res.data, function (html) {
layer.open({
type: 1,
title: "当前有"+res.data.length+"个系统补丁待处理",
content: html,
offset: 'auto',
area: ['50%'],
btn: ['查看补丁'],
yes: function (index, layero) {
layer.close(index);
location.hash = ns.hash('shop/upgrade/patchlists');
},
});
})
})
}
}
});
}
patchAlert();

View File

@@ -0,0 +1,333 @@
/**
* 渲染订单列表
*/
Delivery = function () {
};
/**
* 设置数据集
*/
Delivery.prototype.setData = function (data) {
Delivery.prototype.data = data;
};
/**
* 列名数据
*/
Delivery.prototype.cols = [
{
type: 'checkbox',
fixed: 'left',
width: '2%',
merge: true,
template: function (orderitem, order) {
var json = {}
json.order_id = order.order_id;
json.order_no = order.order_no;
json.full_address = order.full_address;
var h = '<div class="sub-selected-checkbox" data-json='+ JSON.stringify(json) +'>';
h += '<input type="checkbox" lay-skin="primary" lay-filter="subCheckbox" name="">';
h += '</div>';
return h;
}
},
{
title: '<span>商品</span>',
width: "30%",
className: "product-info",
template: function (orderitem, order) {
var h = '<div class="img-block">';
h += '<img layer-src="' + ns.img(orderitem.sku_image,'big') + '" src="' + ns.img(orderitem.sku_image,'small') + '">';
h += '</div>';
h += '<div class="info">';
h += '<a href="' + ns.href("shop/order/detail", {order_id: orderitem.order_id}) + '" target="_blank" title="' + orderitem.sku_name + '" class="multi-line-hiding text-color-sub">' + orderitem.sku_name + '</a>';
if (orderitem.refund_status_name != '') {
h += '<br/><a href="' + ns.href("shop/orderrefund/detail", {order_goods_id: orderitem.order_goods_id}) + '" target="_blank" class="text-color">' + orderitem.refund_status_name + '</a>&nbsp;&nbsp;';
}
return h;
}
},
{
title: "单价(元) / 数量",
width: "10%",
align: "right",
className: "order-price",
template: function (orderitem, order) {
var h = '<div style="padding-right: 15px;">';
h += '<div>';
h += '<span>' + orderitem.price + '</span>';
h += '</div>';
h += '<div>';
h += '<span>' + orderitem.num + '件</span>';
h += '</div>';
h += '</div>';
return h;
}
},
{
title: "实付金额(元)",
width: "10%",
align: "right",
className: "order-money",
merge: true,
template: function (orderitem, order) {
var h = '<div style="padding-right: 15px;">';
h += '<span>' + order.order_money + '</span>';
h += '</div>';
return h;
}
},
{
title: "买家/收货人",
width: "20%",
align: "left",
className: "buyers",
merge: true,
template: function (orderitem, order) {
var h = '';
h += '<p>';
h += '<a class="text-color" target="_blank" href="' + ns.href("shop/member/editmember?member_id=") + order.member_id + '">' + order.nickname + '</a>';
// h += '<span style="margin-left:22px;">' + order.mobile + '</span>';
h += '</p>';
if (order.order_type != 4) {
h += '<p>';
h += '<span>' + order.name + '</span>';
h += '<span style="margin-left:22px;">' + order.mobile + '</span>';
h += '</p>';
h += '<span class="line-hiding address_box" title="' + order.full_address + '">' + order.full_address + " " + order.address + '</span>';
h += '<input type="text" class="address_input" id="'+ order.order_id +'_address" value="'+ order.full_address +'-'+ order.address +'" />'
h += '<a style="vertical-align: top" href="javascript:ns.copy(\''+ order.order_id +'_address\');" class="iconfont iconfuzhi"></a>'
} else {
h += '<p>';
h += '<span>' + order.mobile + '</span>';
h += '</p>';
}
return h;
}
},
{
title: "交易状态",
width: "10%",
align: "center",
className: "transaction-status",
merge: true,
template: function (orderitem, order) {
// console.log("orderitem",order);
// if(order.order_status_name == '待支付'){
//
// }else if(order.order_status_name == '待发货'){
//
// }
var html = '<div>' + order.order_status_name + '</div>';
// html += '<div>' + order.promotion_type_name;
html += order.promotion_status_name != '' ? '(' + order.promotion_status_name + ')' : '';
html += '</div>';
return html;
}
},
// {
// title : "下单时间",
// width : "10%",
// align : "center",
// className : "create-time",
// merge : true,
// template : function(orderitem,order){
// return '<div>' + ns.time_to_date(order.create_time) + '</div>';
// }
// },
// {
// title : "结算状态",
// width : "10%",
// align : "center",
// className : "settlement",
// merge : true,
// template : function(orderitem,order){
// var settlement_name = order.is_settlement == 1 ? "已结算" : "待结算";
// return '<div>'+settlement_name+'</div>';
// }
// },
{
title: "操作",
width: "16%",
align: "right",
className: "operation",
merge: true,
template: function (orderitem, order) {
var url = "shop/order/detail";
var html = '';
var action_json = order.order_status_action;
var action_arr = JSON.parse(action_json);
var action = action_arr.action;
html += '<div class="table-btn">';
for (var k = 0; k < action.length; k++) {
html += '<a class="layui-btn text-color" href="javascript:orderAction(\'' + action[k].action + '\', ' + order.order_id + ')">' + action[k].title + '</a>';
}
html += '</div>';
return html;
}
}
];
/**
* 渲染表头
*/
Delivery.prototype.header = function (hasThead) {
var colgroup = '<colgroup>';
var thead = '';
if (hasThead) thead = '<thead><tr>';
for (var i = 0; i < this.cols.length; i++) {
var align = this.cols[i].align ? "text-align:" + this.cols[i].align : "";
colgroup += '<col width="' + this.cols[i].width + '">';
if (hasThead) {
thead += '<th style="' + align + '" class="' + (this.cols[i].className || "") + '">';
thead += '<div class="layui-table-cell">';
if(this.cols[i].type){
thead += '<div class="all-selected-checkbox">';
thead += '<input type="checkbox" lay-skin="primary" lay-filter="allCheckbox" name="">';
thead += '</div>';
}else{
thead += this.cols[i].title;
}
thead += '</div>';
thead += '</th>';
}
}
colgroup += '</colgroup>';
if (hasThead) thead += '</tr></thead>';
return colgroup + thead;
};
/**
* 渲染内容
*/
Delivery.prototype.tbody = function () {
var tbody = '<tbody>';
for (var i = 0; i < this.data.list.length; i++) {
var order = this.data.list[i];
var orderitemList = order.order_goods;
var pay_type_name = order.pay_type_name != '' ? order.pay_type_name : "";
if (i > 0) {
//分割行
tbody += '<tr class="separation-row">';
tbody += '<td colspan="' + this.cols.length + '"></td>';
tbody += '</tr>';
}
//订单项头部
tbody += '<tr class="header-row">';
tbody += '<td colspan="6">';
tbody += '<span class="order-item-header" style="margin-right:10px;">订单号:' + order.order_no + '</span>';
tbody += '<span class="order-item-header text-color more" style="margin-right:50px;" onclick="showMore(' + order.order_id + ')">更多';
tbody += '<div class="more-operation" data-order-id="' + order.order_id + '">';
tbody += '<span>支付流水号:' + order.out_trade_no + '</span>';
tbody += '</div></span>';
tbody += '<span class="order-item-header" style="margin-right:50px;">下单时间:' + ns.time_to_date(order.create_time) + '</span>';
// tbody += '<span class="order-item-header" style="margin-right:50px;">订单类型:' + order.order_type_name + '</span>';
if (pay_type_name) tbody += '<span class="order-item-header">支付方式:' + pay_type_name + '</span>';
tbody += '</td>';
tbody += '<td>';
tbody += '<div class="table-btn order-list-top-line">';
if (order.order_type == 1) {
tbody += '<a class="layui-btn" href="javascript:printDeliverOrder(' + order.order_id + ');" >打印发货单</a>';
}
if(printer_addon_is_exit == 1 && [1,2,3].indexOf(parseInt(order.order_type)) != -1) {
tbody += '<a class="layui-btn" href="javascript:printTicket(' + order.order_id + ');" >打印小票</a>';
}
if (order.order_status == -1) {
tbody += '<a class="layui-btn" href="javascript:orderDelete(' + order.order_id + ');" >删除</a>';
}
tbody += '<a class="layui-btn" href="' + ns.href("shop/order/detail", {order_id: order.order_id}) + '" target="_blank">详情</a>';
tbody += '<a class="layui-btn" href="javascript:orderRemark(' + order.order_id + ');">备注</a> ';
if (order.order_status == 0) {
tbody += '<a class="layui-btn" href="javascript:offlinePay(' + order.order_id + ');">线下支付</a> ';
}
tbody += '</div>';
tbody += '</td>';
tbody += '</tr>';
// tbody += '<tr class="separation-row"><td colspan="6"><hr /></td></tr>';
var orderitemHtml = '';
loadImgMagnify();
for (var j = 0; j < orderitemList.length; j++) {
var orderitem = orderitemList[j];
orderitemHtml += '<tr class="content-row">';
for (var k = 0; k < this.cols.length; k++) {
if (j == 0 && this.cols[k].merge && this.cols[k].template) {
orderitemHtml += '<td class="' + (this.cols[k].className || "") + '" align="' + (this.cols[k].align || "") + '" style="' + (this.cols[k].style || "") + '" rowspan="' + orderitemList.length + '">';
orderitemHtml += this.cols[k].template(orderitem, order);
orderitemHtml += '</td>';
} else if (this.cols[k].template && !this.cols[k].merge) {
orderitemHtml += '<td class="' + (this.cols[k].className || "") + '" align="' + (this.cols[k].align || "") + '" style="' + (this.cols[k].style || "") + '">';
orderitemHtml += this.cols[k].template(orderitem, order);
orderitemHtml += '</td>';
}
}
orderitemHtml += '</tr>';
}
tbody += orderitemHtml;
if(order.buyer_message != '') {
//订单项底部
tbody += '<tr class="bottom-row">';
tbody += '<td colspan="7">';
tbody += '<span class="order-item-header" style="margin-right:10px;">买家备注:' + order.buyer_message + '</span>';
tbody += '</td>';
tbody += '</tr>';
}
if (order.remark != '') {
tbody += '<tr class="remark-row">';
tbody += '<td colspan="' + this.cols.length + '">卖家备注:' + order.remark + '</td>';
tbody += '</tr>';
}
}
tbody += '</tbody>';
return tbody;
};
/**
* 渲染表格
*/
Delivery.prototype.fetch = function () {
if (this.data.list.length > 0) {
return '<table class="layui-table layui-form">' + this.header(true) + '</table><table class="layui-table order-list-table layui-form">' + this.header(false) + this.tbody() + '</table>';
} else {
return '<table class="layui-table order-list-table layui-form">' + this.header(true) + '</table>' + '<div class="order-no-data-block"><ul><li><i class="layui-icon layui-icon-tabs"></i> </li><li>暂无订单</li></ul></div>';
}
};
function showMore(order_id) {
$(".more-operation[data-order-id]").hide();
$(".more-operation[data-order-id='" + order_id + "']").show();
$("body").bind('click',function (e) {
if (!$(e.target).closest(".order-item-header.more").length) {
$(".more-operation[data-order-id='" + order_id + "']").hide();
$("body").unbind('click');
}
});
}

22
app/shop/view/public/js/echarts.min.js vendored Executable file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,288 @@
Evaluate = function(limit = 0, limits = []) {
var _this = this;
_this.listCount = 0;
_this.page = 1;
_this.limits = limits;
_this.limit = limit == false ? 10 : limit;
};
Evaluate.prototype.getList = function(d) {
var _this = d._this;
var page = _this.page;
var limit = _this.limit;
var search_type = d.search_type;
var search_text = d.search_text == null ? {} : d.search_text;
var explain_type = d.explain_type;
var start_time = d.start_time;
var end_time = d.end_time;
var goods_id = d.goods_id;
var is_audit = d.is_audit;
var _d = d;
$.ajax({
url: ns.url("shop/goods/evaluate"),
data: {
"page": page,
"page_size": limit,
"search_type": search_type,
"search_text": search_text,
"explain_type": explain_type,
"start_time": start_time,
"end_time": end_time,
"goods_id" : goods_id,
"is_audit" : is_audit,
},
type: "POST",
dataType: "JSON",
success: function (res) {
_this.listCount = res.data.count;
$(".evaluate-table").find("tbody").empty();
_this.pageInit(_d);
var d = res.data.list;
if (d.length == 0) {
var html = '<tr><td colspan="8" align="center">无数据</td></tr>';
$(".evaluate-table").find("tbody").append(html);
}
for (var i in d) {
var img_one = d[i].sku_image.split(",")[0];
var html = '';
var isFirstExplain = Boolean(d[i].explain_first) ? 1 : 0;//是否第一次评价
html += '<tr>';
html += '<td>' +
'<div>' +
'<input class="evaluate_id" type="hidden" value=' + d[i].evaluate_id + ' data-is-first-explain="' + isFirstExplain + '" />' +
'<input type="checkbox" name="evaluate" value=' + d[i].evaluate_id + ' lay-skin="primary" lay-filter="evaluate" ' + ($("input[name='check_all']").is(":checked") ? "checked" : "") + ' />' +
'</div>' +
'</td>';
html += '<td>' +
'<div class="table-title">' +
'<div class="title-pic" id="goods_img_'+ i +'">' +
// '<img layer-src src="' + ns.img(d[i].sku_image,'small') + '">' +
'<img layer-src="' + ns.img(img_one,'big') + '" src="' + ns.img(img_one,'small') + '">' +
'</div>' +
'<div class="title-content">' +
'<p class="sku-name">' + d[i].sku_name + '</p>' +
'<p>¥' + d[i].sku_price + '</p>' +
'</div>' +
'</div>' +
'</td>';
html += '<td>' +
'<div class="table-title">' +
'<p>' + d[i].member_name + '</p>' +
'</div>' +
'</td>';
html += '<td>' +
'<div class="table-title evaluate-img">';
if (d[i].explain_type == 1) {
html += `<p class="evaluate-level-good"><img src= "${ns_url.shopImg}/good_evaluate.png" /><span>好评</span></p>`;
} else if (d[i].explain_type == 2) {
html += `<p class="evaluate-level-middel"><img src= "${ns_url.shopImg}/middel_evaluate.png" /><span>中评</span></p>`;
} else {
html += `<p class="evaluate-level-bad"><img src= "${ns_url.shopImg}/bad_evaluate.png" /><span>差评</span></p>`;
}
'</div>' +
'</td>';
if(d[i].again_images.length > 0 && d[i].images.length == false){
html += '<td style="padding-top:45px">';
html += '<div class="evaluate" style="margin-bottom:45px">'+
'<p>' + d[i].content + '</p>'+
'</div>';
}else{
html += '<td>';
html += '<div class="evaluate">'+
'<p>' + d[i].content + '</p>'+
'</div>';
}
if (d[i].images) {
html += '<div class="evaluate-img">';
var images = d[i].images.split(",");
for (var j=0; j<images.length; j++) {
html += '<div class="title-pic" id="eva_img_'+ i +'_'+ j +'">';
html += '<img layer-src src="' + ns.img(images[j]) + '" onerror=src="'+ns.img('public/static/img/null.png')+'">';
html += '</div>';
}
html += '</div>';
}
if (d[i].explain_first) {
html += '<div class="evaluate-explain bg-color-light-9">'+
'<span class="again-evaluate required">商家回复:</span>'+
'<p>' + d[i].explain_first + '</p>' +
'</div>';
}
if (d[i].again_content) {
html += '<hr />';
html += '<div class="evaluate-again">' +
'<span class="again-evaluate required">追评:</span>' +
'<p>' + d[i].again_content + '</p>' +
'</div>';
if (d[i].again_images) {
html += '<div class="evaluate-img">';
var again_images = d[i].again_images.split(",");
for (var k=0; k<again_images.length; k++) {
html += '<div class="title-pic" id="again_img_'+ i +'_'+ k +'">';
html += '<img layer-src src="' + ns.img(again_images[k]) + '" onerror=src="'+ns.img('public/static/img/null.png')+'">';
html += '</div>';
}
html += '</div>';
}
}
if (d[i].again_explain) {
html += '<div class="evaluate-again-explain">'+
'<span class="again-evaluate required">[商家回复]</span>'+
'<p>' + d[i].again_explain + '</p>' +
'</div>';
}
html += '</td>';
if(d[i].again_time != 0){
if(d[i].again_images.length > 0 ){
html += '<td>' +
'<div class="table-title">' +
'<p>' + ns.time_to_date(d[i].create_time) + '</p>' +
'</div>' +
'<hr style="margin:45px 0px;>' +
'<div class="table-title">' +
'<p>' + ns.time_to_date(d[i].again_time) + '</p>' +
'</div>' +
'</td>';
}else{
html += '<td>' +
'<div class="table-title">' +
'<p>' + ns.time_to_date(d[i].create_time) + '</p>' +
'</div>' +
'<hr>' +
'<div class="table-title">' +
'<p>' + ns.time_to_date(d[i].again_time) + '</p>' +
'</div>' +
'</td>';
}
}else{
html += '<td>' +
'<div class="table-title">' +
'<p>' + ns.time_to_date(d[i].create_time) + '</p>' +
'</div>' +
'</td>';
}
var audit = "已审核";
var audit_action = '';
if(d[i].is_audit == 0){
audit = "未审核";
audit_action = '<a class="default layui-btn" onclick="audit(this,1)">审核通过</a>';
audit_action += '<a class="default layui-btn" onclick="audit(this,2)">审核拒绝</a>';
audit_action += '<a class=" layui-btn" onclick="toDelete(this)">删除评论</a>';
}else if(d[i].is_audit == 1){
audit = "审核通过";
audit_action += '<a class="layui-btn" onclick="toDelete(this)">删除评论</a>';
}else if(d[i].is_audit == 2){
audit = "审核拒绝";
audit_action += '<a class="layui-btn" onclick="toDelete(this)">删除评论</a>';
}
var again_audit = "未追评";
if (d[i].again_time){
if(d[i].again_is_audit == 0){
again_audit = "未审核";
if (d[i].is_audit != 0 && d[i].again_is_audit == 0){
audit_action = '<a class="default layui-btn" onclick="again_audit(this,1)">通过追评</a>';
audit_action += '<a class="default layui-btn" onclick="again_audit(this,2)">拒绝追评</a>';
}
}else if(d[i].again_is_audit == 1){
again_audit = "审核通过";
}else if(d[i].again_is_audit == 2){
again_audit = "审核拒绝";
}
}
html += '<td style="text-align:center;">' + audit + '</td>';
html += '<td><div class="table-btn order-list-top-line">';
html += audit_action;
if(d[i].is_audit == 1) {
if ((d[i].content != "" && d[i].explain_first == "")) {
html += '<a class="default layui-btn" onclick="replay(this)">回复</a>';
} else if ((d[i].again_content != "" && d[i].again_explain == "" && d[i].again_is_audit == 1)) {
html += '<a class="default layui-btn" onclick="replay(this)">追评回复</a>';
}
if ((d[i].content != "" && d[i].explain_first != "")) {
html += '<a class="default layui-btn" onclick="deleteContent(this,0)">删除回复</a>';
}
if ((d[i].again_content != "" && d[i].again_explain != "")) {
html += '<a class="default layui-btn" onclick="deleteContent(this,1)">删除追评回复</a>';
}
}
html += '</div></td>';
html += '</tr>';
$(".evaluate-table").find("tbody").append(html);
layui.use(['form', 'layer'],function(){
var form = layui.form,
layer = layui.layer;
form.render();
layer.photos({
photos: '.title-pic',
anim: 5
});
});
}
}
});
};
Evaluate.prototype.pageInit = function (d) {
var _this = d._this;
layui.use('laypage', function () {
var laypage = layui.laypage;
laypage.render({
elem: 'laypage',
curr:_this.page,
count: _this.listCount,
limit: _this.limit,
limits: _this.limits,
prev: '<i class="layui-icon layui-icon-left"></i>',
next: '<i class="layui-icon layui-icon-right"></i>',
layout: ['count','limit','prev', 'page', 'next'],
jump: function (obj, first) {
_this.limit = obj.limit;
if (!first) {
_this.page = obj.curr;
_this.getList({
_this: _this,
"search_type": d.search_type,
"search_text": d.search_text,
"explain_type": d.explain_type,
"start_time": d.start_time,
"end_time": d.end_time,
"goods_id" : d.goods_id,
"is_audit" : d.is_audit
});
}
}
});
});
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,727 @@
layui.use(['form', 'layer'], function () {
// 加载资源
var $ = layui.jquery, layer = layui.layer, form = layui.form;
form.render();
//模板ID
var freeshipping_id = Number($("#freeshipping_id").val());
//地区等级
var area_level = Number($("#area_level").val());
//剩余地区 id数据
var surplus_area_ids = $("#surplus_area_ids").val();
//剩余地区完整数据
var surplus_area = {};
//选中地区完整数据
var selected_area = {};
//提交表单数据
var submit_data = {};
//地区位置标识
var area_target = [0];
//操作类型
var opt_type = 1;
//当前操作序号
var opt_num = 0;
//总操作序号
var opt_total = 0;
//临时数据
var temp_area = {};
//layer弹框的标记
var layer_index;
//layer加载标记
var layer_load;
//ajax是否已经返回数据
var area_data_flag = false;
//是否已经点击提交按钮
var submit_flag = false;
/**
* 获取地区列表 立即执行
*/
(function () {
$.ajax({
type: "post",
url: ns.url('shop/express/getarealist'),
data: {
level: area_level,
},
dataType: 'json',
success: function (data) {
if (freeshipping_id == 0) {
surplus_area = copy_obj(data);
} else {
surplus_area = get_data_by_ids(data, surplus_area_ids);
submit_data = initSubmitData();
for (var num in submit_data) {
selected_area[num] = get_data_by_ids(data, submit_data[num]['area_ids']);
}
}
//改变地区加载标记 关闭弹框 重新渲染数据
area_data_flag = true;
if (layer_load) {
layer.close(layer_load);
if (opt_type == 2) {
// 将临时数据对象清零并重新赋值
temp_area = new Object();
temp_area = copy_obj(selected_area[opt_num]);
}
compile_new_data();
}
}
})
}());
/**
* 未选中数据
*/
function initSurplus(data) {
var area_list = get_area_ids(copy_obj(data));
$('.area_ids').each(function (i, e) {
var surplus_ids = JSON.parse($(e).val());
for (var level = count_obj(surplus_ids); level > 0; level--) {
for (var i in surplus_ids[level]) {
for (var i2 in surplus_ids[level][i]) {
area_list = delData(area_list, level, i, surplus_ids[level][i][i2]);
}
}
}
});
return JSON.stringify(area_list);
}
/**
* 提交数据
*/
function initSubmitData() {
var data = {};
var num = 1;
$('.area_ids').each(function (i, e) {
data[num] = {};
data[num]['area_ids'] = $(e).val();
data[num]['area_names'] = $(e).attr('data-name');
num++;
});
return data;
}
/**
* 删除指定数据
*/
function delData(list, level, pid, id) {
for (var i in list[level]) {
if (list[level] && list[level][pid] && level == 4) {
for (var i2 in list[level][pid]) {
if (list[level][pid][i2] && list[level][pid][i2] == id) {
delete list[level][pid][i2];
compactObj(list[level][pid]);
return list;
}
}
}
if (list[level] && list[level][pid]) {
for (var i2 in list[level][pid]) {
if (list[level][pid][i2] && list[level][pid][i2] == id && count_obj(list[level + 1][id]) == 0) {
delete list[level][pid][i2];
compactObj(list[level][pid]);
return list;
}
}
}
}
return list;
}
/**
* 渲染列表
*/
function compile_list(area_list, level, pid, html) {
if (!area_list[level] || !area_list[level][pid]) return html;
html += '<ul>';
for (var id in area_list[level][pid]['child_list']) {
var item = area_list[level][pid]['child_list'][id];
if (item == undefined) {
continue;
}
var has_num = 0;
if (area_list[level + 1] && area_list[level + 1][id]) has_num = count_obj(area_list[level + 1][id]['child_list']);
var extended = item.extended ? item.extended : item.extended = 0;
var selected = item.selected ? item.selected : item.selected = 0;
var extended_html = extended == 0 ? '+' : '-';
var selected_html = selected == 1 ? 'selected' : '';
area_target[level] = item.id;
area_target = area_target.slice(0, level + 1);
html += '<li class="' + selected_html + '" data-level="' + item.level + '" data-pid="' + item.pid + '" data-id="' + item.id + '" data-extended="' + extended + '" data-selected="' + selected + '" data-target="' + area_target.toString() + '">';
html += '<div class="title-div" >';
if (has_num > 0 && item.level != area_level) html += '<div class="area-btn ' + selected_html + '" >' + extended_html + '</div>';
else html += '<div class="area-btn-null"></div>';
html += '<div class="name-div" >' + item.name + '</div>';
html += '<div class="area-delete">×</div>';
html += '</div>';
if (extended == 1 && has_num > 0) html += compile_list(area_list, level + 1, id, '');
html += '</li>';
}
html += '</ul>';
return html;
}
/**
* 渲染列表数据
*/
function compile_new_data() {
var surplus_html = compile_list(surplus_area, 1, 0, '');
$(".area-modal .all-area .box").html(surplus_html);
var temp_html = compile_list(temp_area, 1, 0, '');
$(".area-modal .selected-area .box").html(temp_html);
}
/**
* 统计对象属性个数
*/
function count_obj(obj) {
var count = 0;
if (!obj) return count;
for (var index in obj) {
count++
}
return count;
}
/**
* 拷贝一个对象
*/
function copy_obj(obj) {
var res = new Object();
for (var i in obj) {
res[i] = obj[i];
}
return res;
}
/**
* 向下遍历改变数据对象的状态
*/
function area_down_alter(area_list, level, pid, alter_res, key) {
if (area_list[level + 1] && area_list[level + 1][pid]) {
for (var id in area_list[level + 1][pid]['child_list']) {
var item = area_list[level + 1][pid]['child_list'][id];
if (item == undefined) {
continue;
}
item[key] = alter_res;
item['choosed'] = alter_res;
if (area_list[level + 2]) area_down_alter(area_list, level + 1, item['id'], alter_res, key);
}
}
}
/**
* 向上遍历改变数据对象的状态
*/
function area_up_alter(area_list, level, target, key) {
if (level > 1) {
var alter_res = 1;
for (var id in area_list[level][target[level - 1]]['child_list']) {
if (!area_list[level][target[level - 1]]['child_list'][id][key]) {
alter_res = 0;
break;
}
}
var choosed = 0;
for (var id in area_list[level][target[level - 1]]['child_list']) {
if (area_list[level][target[level - 1]]['child_list'][id] == undefined) {
continue;
}
if (area_list[level][target[level - 1]]['child_list'][id]['choosed'] == 1) {
choosed = 1;
break;
}
}
area_list[level - 1][target[level - 2]]['child_list'][target[level - 1]][key] = alter_res;
area_list[level - 1][target[level - 2]]['child_list'][target[level - 1]]['choosed'] = choosed;
area_up_alter(area_list, level - 1, target, key);
}
}
/**
* 处理数据
*/
function deal_data(area_list, key) {
var temp = {};
for (var level in area_list) {
var level_temp = {};
for (var pid in area_list[level]) {
var pid_temp = {child_list: {}};
var total_num = 0;
var del_num = 0;
for (var id in area_list[level][pid]['child_list']) {
if (area_list[level][pid]['child_list'][id] == undefined) {
continue;
}
total_num++;
if (area_list[level][pid]['child_list'][id]['choosed'] == 1) {
pid_temp['child_list'][id] = area_list[level][pid]['child_list'][id];
}
if (area_list[level][pid]['child_list'][id][key] == 1) {
delete area_list[level][pid]['child_list'][id];
del_num++;
}
if (pid_temp['child_list'][id]) {
pid_temp['child_list'][id][key] = 0;
pid_temp['child_list'][id]['choosed'] = 0;
}
}
if (count_obj(pid_temp['child_list']) > 0) {
pid_temp['child_num'] = area_list[level][pid]['child_num'] ? area_list[level][pid]['child_num'] : 0;
level_temp[pid] = pid_temp;
}
if (total_num == del_num && total_num > 0) delete area_list[level][pid];
}
if (count_obj(level_temp) > 0) temp[level] = level_temp;
}
return temp;
}
/**
* 合并两个对象
* selected 提供数据的对象
* receive 接收数据的对象
* 思路如果receive没有就直接添加到receive 如果有就进入下层循环
*/
function combine_data(give, receive) {
for (var level in give) {
if (receive[level]) {
for (var pid in give[level]) {
if (receive[level][pid]) {
for (var id in give[level][pid]['child_list']) {
receive[level][pid]['child_list'][id] = give[level][pid]['child_list'][id];
}
} else {
receive[level][pid] = give[level][pid];
}
}
} else {
receive[level] = give[level];
}
}
}
/**
* 将选中地区结构转换为文字说明
* 思路:选中下级个数同总下级个数相同,说明选中全部,显示当前地区即可,否则要把下级地区也显示出来
*/
function alter_text(area_list, level, pid, html) {
var has_num = 0;
for (var id in area_list[level][pid]['child_list']) {
html += area_list[level][pid]['child_list'][id]['name'];
if (area_list[level + 1] && area_list[level + 1][id]) {
var alter_res = alter_text(area_list, level + 1, id, '');
if (alter_res['has_num'] == area_list[level + 1][id]['child_num']) {
has_num++;
} else {
html += '';
html += alter_res['html'];
html += '';
}
} else {
has_num++;
}
html += '、';
}
html = html.substring(0, html.length - 1);
return {
html: html,
has_num: has_num,
};
}
/**
* 编译表格
* 用在两个地方
* 1在点击保存的时候编译添加和修改的所有模板项
* 2在刚进入页面的时候初始化数据
*/
function compile_table() {
var html = '';
for (var index in submit_data) {
if (count_obj(submit_data[index]) > 0) {
html += '<tr data-selected="' + index + '">';
html += '<td class="area-selected">';
html += '<p class="area-show">' + submit_data[index]['area_names'];
html += '</p>';
html += '</td>';
html += '<td class="area-btn">';
html += '<span class="right-opt"><span class="opt-update text-color" data-selected="' + index + '">修改</span>';
html += '</td>';
html += '</tr>';
}
}
$("#distributionArea tbody").html(html);
}
/**
* 获取ID数据对象
*/
function get_area_ids(area_list) {
var obj = {};
for (var level in area_list) {
obj[level] = {};
for (var pid in area_list[level]) {
obj[level][pid] = [];
for (var id in area_list[level][pid]['child_list']) {
obj[level][pid].push(id);
}
}
}
return obj;
}
/**
* 改变整个对象的某一属性
*/
function alter_data_attr(area_list, key, value) {
for (var level in area_list) {
for (var pid in area_list[level]) {
for (var id in area_list[level][pid]['child_list']) {
area_list[level][pid]['child_list'][id][key] = value;
}
}
}
}
/**
* 由id得到完整数据
*/
function get_data_by_ids(area_list, ids) {
if(!ids) return {};
var obj = JSON.parse(ids);
var temp = {};
for (var level in obj) {
var level_temp = {};
for (var pid in obj[level]) {
var pid_temp = {};
pid_temp['child_list'] = {};
for (var id in obj[level][pid]) {
var area_id = obj[level][pid][id];
pid_temp['child_list'][area_id] = area_list[level][pid]['child_list'][area_id];
}
pid_temp['child_num'] = area_list[level][pid]['child_num'];
level_temp[pid] = pid_temp;
}
temp[level] = level_temp;
}
return temp;
}
/**
* 展开与收起 思路为先改变数据 再重新渲染
*/
$("body").off('click', '.area-list .area-btn').on('click', '.area-list .area-btn', function () {
var li = $(this).parent().parent();
var extended = li.attr('data-extended');
var level = li.attr('data-level');
var pid = li.attr('data-pid');
var id = li.attr('data-id');
var alter_res = extended == 1 ? 0 : 1;
if (surplus_area[level] && surplus_area[level][pid] && surplus_area[level][pid]['child_list'][id]) surplus_area[level][pid]['child_list'][id]['extended'] = alter_res;
if (temp_area[level] && temp_area[level][pid] && temp_area[level][pid]['child_list'][id]) temp_area[level][pid]['child_list'][id]['extended'] = alter_res;
compile_new_data();
});
/**
* 选中与取消 思路同展开与收起 也是先改变数据 再重新渲染
*/
$("body").off('click', '.area-list.all-area ul li .title-div .name-div').on('click', '.area-list.all-area ul li .title-div .name-div', function () {
var li = $(this).parent().parent();
var selected = li.attr('data-selected');
var level = li.attr('data-level');
var pid = li.attr('data-pid');
var id = li.attr('data-id');
var target = li.attr('data-target');
target = target.split(',');
var alter_res = selected == 1 ? 0 : 1;
surplus_area[level][pid]['child_list'][id]['selected'] = alter_res;
surplus_area[level][pid]['child_list'][id]['choosed'] = alter_res;
area_down_alter(surplus_area, Number(level), id, alter_res, 'selected');
area_up_alter(surplus_area, Number(level), target, 'selected');
compile_new_data();
});
/**
* 将选中部分添加到已选中 思路为先遍历和处理数据 再渲染两边的列表
*/
$("body").off("click", ".area-modal .add").on("click", ".area-modal .add", function () {
// 找到新选中部分
var choose = deal_data(surplus_area, 'selected');
combine_data(choose, temp_area);
compile_new_data();
});
/**
* 归还右边删除部分到左边
* 思路:相当于是执行了两步操作 1选中 2反向添加
*/
$("body").off("click", ".area-modal .area-list.selected-area .area-delete").on("click", ".area-modal .area-list.selected-area .area-delete", function () {
// 改变状态
var li = $(this).parent().parent();
var level = li.attr('data-level');
var pid = li.attr('data-pid');
var id = li.attr('data-id');
var target = li.attr('data-target');
target = target.split(',');
var alter_res = 1;
temp_area[level][pid]['child_list'][id]['selected'] = alter_res;
temp_area[level][pid]['child_list'][id]['choosed'] = alter_res;
area_down_alter(temp_area, Number(level), id, alter_res, 'selected');
area_up_alter(temp_area, Number(level), target, 'selected');
// 找到 删除 合并
var choose = deal_data(temp_area, 'selected');
combine_data(choose, surplus_area);
compile_new_data();
});
/**
* 获取弹框html
*/
function get_modal_html() {
var modal_html = '';
modal_html += '<div class="area-modal">' +
'<div class="area-list all-area">' +
'<div class="title bg-color-gray">可选地区</div>' +
'<div class="box"></div>' +
'</div>' +
'<button class="add">添加</button>' +
'<div class="area-list selected-area">' +
'<div class="title bg-color-gray">已选地区</div>' +
'<div id="choice" class="box"></div>' +
'</div>' +
'</div>' +
'<div class="modal-operation">' +
'<button class="layui-btn save-btn">确定</button>' +
'<button class="layui-btn layui-btn-primary" onclick="layer.closeAll()">返回</button>' +
'</div>';
return modal_html;
}
/**
* 开始添加操作
*/
$("#distributionArea").on("click", ".js-add-record", function () {
//打开弹框
layer_index = layer.open({
title: '编辑配送区域',
type: 1,
area: ['700px', '542px'], //宽高
content: get_modal_html(),
});
opt_type = 1;
// 重置临时数据对象
temp_area = new Object();
compile_new_data();
if (area_data_flag == false) {
layer_load = layer.load(1, {
shade: [0.1, '#fff'] //0.1透明度的白色背景
});
}
});
/**
* 开始修改操作
*/
$("#distributionArea").on("click", ".opt-update", function () {
// 操作类型为添加
opt_type = 2;
// 确定正在操作的数据序列
opt_num = parseInt($(this).attr('data-selected'));
// 将临时数据对象清零并重新赋值
temp_area = new Object();
temp_area = copy_obj(selected_area[opt_num]);
//打开弹框
layer_index = layer.open({
title: '编辑配送区域',
type: 1,
area: ['700px', '542px'], //宽高
content: get_modal_html(),
});
// 渲染数据
compile_new_data();
if (area_data_flag == false) {
layer_load = layer.load(1, {
shade: [0.1, '#fff'] //0.1透明度的白色背景
});
}
});
/**
* 保存操作
*/
$("body").off("click", ".save-btn").on("click", ".save-btn", function () {
let boxLength=$('#choice').children().length
if(boxLength==0){
layer.msg('已选地区不能为空', {icon: 5, anim: 6});
return false
}
layer.close(layer_index);
if (count_obj(temp_area) == 0) return;
if (opt_type == 1) {
opt_total++;
opt_num = opt_total;
// 选中地区数据
selected_area[opt_num] = new Object();
// 提交表单数据
submit_data[opt_num] = new Object();
}
submit_data[opt_num]['area_ids'] = new Object();
// 把临时数据变为正式数据
for (var per in temp_area) {
selected_area[opt_num][per] = temp_area[per];
}
submit_data[opt_num]['area_names'] = alter_text(temp_area, 1, 0, '')['html'];
// 编译数据表格
compile_table();
// 获取剩余地区和选中地区的ID数据
surplus_area_ids = JSON.stringify(get_area_ids(surplus_area));
submit_data[opt_num]['area_ids'] = JSON.stringify(get_area_ids(temp_area));
});
/**
* 取消操作
*/
$("body").off("click", ".area-modal .cancel-btn").on("click", ".area-modal .cancel-btn", function () {
layer.close(layer_index);
});
/**
* 删除操作
*/
$("#distributionArea").on("click", ".opt-delete", function () {
// 确定正在删除的数据序列是哪一个
opt_num = parseInt($(this).attr('data-selected'));
//询问框
layer_index = layer.confirm('确定要删除该记录吗', {
btn: ['确定', '取消'] //按钮
}, function () {
alter_data_attr(selected_area[opt_num], 'choosed', 1);
// 归还数据到总数据
combine_data(selected_area[opt_num], surplus_area);
// 销毁当前数据
delete selected_area[opt_num];
//selected_area[opt_num] = new Object();
// 销毁提交数据
delete submit_data[opt_num];
// submit_data[opt_num] = new Object();
// 删除当前行
$("tr[data-selected='" + opt_num + "']").remove();
layer.close(layer_index);
}, function () {
});
});
form.on('submit(save)', function (form_data) {
if (submit_flag == true) return false;
var url = ns.url('freeshipping://shop/freeshipping/add');
if (freeshipping_id) url = ns.url('freeshipping://shop/freeshipping/edit');
//过滤数据
var real_data = new Object();
for (var per in submit_data) {
if (count_obj(submit_data[per]) > 0) {
real_data[per] = submit_data[per];
}
}
var baoyouprice = $("input[name='price']").val();
if (parseFloat(baoyouprice) <= 0) {
layer.msg('包邮金额不能小于0', {icon: 5, anim: 6});
return false;
}
if (count_obj(real_data) == 0) {
layer.msg('至少要设置一个配送地区');
return false;
}
var data_json = {
'price': form_data['field']['price'],
'json': JSON.stringify(real_data),
'freeshipping_id': freeshipping_id,
'surplus_area_ids': surplus_area_ids
};
submit_flag = true;
$.ajax({
type: "post",
url: url,
data: data_json,
dataType: 'json',
success: function (res) {
submit_flag = false;
if (res.code == 0) {
layer.confirm(freeshipping_id ? '编辑成功' : '添加成功', {
title: '操作提示',
btn: ['返回列表', freeshipping_id ? '继续编辑' : '继续添加'],
closeBtn: 0,
yes: function(index, layero) {
location.hash = ns.hash('freeshipping://shop/freeshipping/lists');
layer.close(index);
},
btn2: function(index, layero) {
listenerHash(); // 刷新页面
layer.close(index);
}
});
} else {
layer.msg(res.message);
}
}
});
// return false;
});
/**
* 去除对象中所有符合条件的对象
* @param {Object} obj 来源对象
*/
function compactObj(obj) {
if (!(typeof obj == 'object')) {
return;
}
for (var key in obj) {
if (obj.hasOwnProperty(key)
&& (obj[key] == null || obj[key] == undefined || obj[key] == '')) {
delete obj[key];
}
}
return obj;
}
});

View File

@@ -0,0 +1,137 @@
requestAdd = 'shop/goods/addGoods';
requestEdit = 'shop/goods/editGoods';
// 追加刷新商品sku数据
appendRefreshGoodsSkuData = {
weight: "", // 重量
volume: "", // 体积
};
// 追加单规格数据
function appendSingleGoodsData(data) {
return {
weight: data.field.weight,
volume: data.field.volume
};
}
// 追加保存数据
function appendSaveData(data) {
var supportTradeType = [];
$('[name="support_trade_type"]:checked').each(function () {
supportTradeType.push($(this).val())
});
return {
support_trade_type: supportTradeType.toString()
}
}
$(function () {
layui.use(['element', 'laytpl', 'form'], function () {
form = layui.form;
element = layui.element;
laytpl = layui.laytpl;
form.render();
element.render();
form.on('checkbox(support_trade_type)', function (data) {
if (data.value == 'express') {
if ($(data.elem).is(':checked')) {
$('.trade-type.express').show()
} else {
$('.trade-type.express').hide()
}
}
});
//是否免邮
form.on("radio(is_free_shipping)", function (data) {
if (data.value == 0) {
$(".js-shipping-template").show();
} else {
$(".js-shipping-template").hide();
}
});
// 运费模板刷新
$('.delivery-refresh').click(function () {
$.ajax({
url: ns.url('shop/goods/getexpresstemplatelist'),
dataType: 'JSON',
type: 'POST',
success: function (res) {
if (res.code == 0) {
var html = $("#deliveryHtml").html();
laytpl(html).render({
list: res.data,
shipping_template: $('select[name="shipping_template"] option:selected').val()
}, function (html) {
$('select[name="shipping_template"]').html(html);
form.render();
});
}
}
});
});
form.verify({
//重量
weight: function (value) {
if (!$("input[name='spec_type']").is(":checked")) {
if (value.length > 0) {
if (isNaN(value) || !ns.getRegexp('>0float3').test(value)) {
element.tabChange('goods_tab', "price-stock");
return '重量必须为正数,且最多保留三位小数';
}
}
}
},
//体积
volume: function (value) {
if (!$("input[name='spec_type']").is(":checked")) {
if (value.length > 0) {
if (isNaN(value) || !ns.getRegexp('>0float3').test(value)) {
element.tabChange('goods_tab', "price-stock");
return '体积必须为正数,且最多保留三位小数';
}
}
}
},
//sku重量
sku_weight: function (value) {
if (value.length > 0) {
if (isNaN(value) || !ns.getRegexp('>0float3').test(value)) {
element.tabChange('goods_tab', "price-stock");
return '重量必须为正数,且最多保留三位小数';
}
}
},
//sku体积
sku_volume: function (value) {
if (value.length > 0) {
if (isNaN(value) || !ns.getRegexp('>0float3').test(value)) {
element.tabChange('goods_tab', "price-stock");
return '体积必须为正数,且最多保留三位小数';
}
}
},
express_type: function () {
if ($('[name="support_trade_type"]').val() == undefined) return '请先配置配送方式';
if (!$('[name="support_trade_type"]:checked').val()) return '请选择配送方式';
},
//运费模板
shipping_template: function (value) {
if ($('[name="support_trade_type"][value="express"]').is(':checked') && $("input[name='is_free_shipping']:checked").val() == 0) {
if (value == "") {
element.tabChange('goods_tab', "basic");
return '请选择运费模板';
}
}
}
});
});
});

View File

@@ -0,0 +1,564 @@
var form, laytpl, layerIndex = -1, repeatFlag = false;
var attrValueList = [];// 参数列表
var deleteAttrValueList = [];//要删除的参数
var table;
$(function () {
layui.use(['form', 'laytpl'], function () {
form = layui.form;
laytpl = layui.laytpl;
//编辑商品类型信息
form.on('submit(save_attr)', function (data) {
if (repeatFlag) return false;
repeatFlag = true;
$.ajax({
url: ns.url("shop/goodsattr/editAttr"),
data: data.field,
dataType: 'json',
type: 'post',
success: function (data) {
layer.msg(data.message);
if (data.code == 0) {
layer.close(layerIndex);
listenerHash(); // 刷新页面
} else {
repeatFlag = false;
}
}
});
return false;
});
form.verify({
attr_value: function (value) {
if ($("select[name='attr_type']").val() != 3 && value.length == 0) {
return "请输入参数名称";
}
},
num: function (value) {
if (value == '') {
return;
}
if (value % 1 != 0) {
return '排序数值必须为整数';
}
if (value < 0) {
return '排序数值必须为大于0';
}
}
});
//添加参数、参数值
form.on('submit(save_add_attribute)', function (data) {
if (repeatFlag) return false;
repeatFlag = true;
if (data.field.attr_type != 3) {
var value = [];
for (var i = 0; i < attrValueList.length; i++) {
value.push(attrValueList[i].attr_value_name);
}
data.field.attr_value_list = value.toString();
} else {
data.field.is_query = 0;
}
//开启规格参数后,不参与筛选
if (data.field.is_spec == 1) {
data.field.is_query = 0;
}
var attr_id = 0;
// 添加参数
$.ajax({
url: ns.url("shop/goodsattr/addattribute"),
data: data.field,
dataType: 'json',
type: 'post',
async: false,
success: function (res) {
attr_id = res.data;
if (data.field.attr_type == 3) {
layer.msg(res.message);
if (res.code == 0) {
layer.close(layerIndex);
listenerHash(); // 刷新页面
} else {
repeatFlag = false;
}
}
}
});
//输入类型不需要添加参数值
if (data.field.attr_type != 3) {
// 添加参数值
addAttributeValue(attr_id, function (res) {
layer.msg(res.message);
layer.close(layerIndex);
listenerHash(); // 刷新页面
});
}
return false;
});
table = new Table({
elem: '#attribute_list',
url: ns.url("shop/goodsattr/getAttributeList"),
where: {attr_class_id: attr_class_id},
page: false,
parseData: function (data) {
return {
"code": data.code,
"msg": data.message,
"count": data.data.length,
"data": data.data
};
},
cols: [
[
{
field: 'attr_name',
title: '参数名称',
width: '20%',
unresize: 'false'
},
{
title: '参数类型',
width: '20%',
unresize: 'false',
templet: function (data) {
var h = '';
if (data.attr_type == 1) {
h = '单选';
} else if (data.attr_type == 2) {
h = '多选';
} else if (data.attr_type == 3) {
h = '输入';
}
return h;
}
},
{
field: 'attr_value_list',
title: '参数',
width: '30%',
unresize: 'false'
},
{
unresize: 'false',
field: 'sort',
title: '排序',
width: '15%',
align: 'center',
templet: '#editSort'
},
{
title: '操作',
toolbar: '#attributeOperation',
unresize: 'false',
align:'right'
}
]
]
});
/**
* 监听工具栏操作
*/
table.tool(function (obj) {
var data = obj.data;
switch (obj.event) {
case 'edit':
editAttributePopup(data.attr_id);
break;
case 'delete':
deleteAttribute(data.attr_id);
break;
}
});
//修改参数、参数
form.on('submit(save_edit_attribute)', function (data) {
if (repeatFlag) return false;
repeatFlag = true;
if (data.field.attr_type != 3) {
var value = [];
for (var i = 0; i < attrValueList.length; i++) {
value.push(attrValueList[i].attr_value_name);
}
data.field.attr_value_list = value.toString();
} else {
data.field.is_query = 0;
}
//开启规格参数后,不参与筛选
if (data.field.is_spec == 1) {
data.field.is_query = 0;
}
if (deleteAttrValueList.length > 0) {
// 删除已存在的参数
$.ajax({
url: ns.url("shop/goodsattr/deleteAttributeValue"),
data: {attr_class_id: attr_class_id, attr_id: data.field.attr_id, attr_value_id_arr: deleteAttrValueList.toString()},
dataType: 'json',
type: 'post',
async: false,
success: function (data) {
}
});
}
// 修改已存在的参数
var isEditAttrValue = [];//已存在的参数集合
for (var i = 0; i < attrValueList.length; i++) {
//只有已存在的参数和修改过的参数才进行push
if (attrValueList[i].is_add && attrValueList[i].is_change) {
attrValueList[i].attr_id = data.field.attr_id;
attrValueList[i].attr_class_id = attr_class_id;
isEditAttrValue.push(attrValueList[i]);
}
}
if (isEditAttrValue.length > 0) {
$.ajax({
url: ns.url("shop/goodsattr/editAttributeValue"),
data: {attr_class_id: attr_class_id, data: JSON.stringify(isEditAttrValue)},
dataType: 'json',
type: 'post',
async: false,
success: function (data) {
}
});
}
if (data.field.attr_type != 3) {
// 添加新的参数
addAttributeValue(data.field.attr_id);
}
// 修改参数
$.ajax({
url: ns.url("shop/goodsattr/editAttribute"),
data: data.field,
dataType: 'json',
type: 'post',
async: false,
success: function (data) {
layer.msg(data.message);
if (data.code == 0) {
layer.close(layerIndex);
listenerHash(); // 刷新页面
} else {
repeatFlag = false;
}
}
});
return false;
});
});
//监听参数键盘输入事件
$("body").off("keyup", ".attribute-value-list .table-wrap .layui-table input").on("keyup", ".attribute-value-list .table-wrap .layui-table input", function () {
var name = $(this).attr("name");
var index = $(this).attr("data-index");
if (name == "attr_value_name") attrValueList[index].attr_value_name = $(this).val();
if (name == "attr_value_sort") attrValueList[index].sort = $(this).val();
attrValueList[index].is_change = true;//标记已修改
});
});
/**
* 打开编辑商品类型弹出框
*/
function editAttrClassPopup() {
var edit_attr_class = $("#editAttrClass").html();
laytpl(edit_attr_class).render({}, function (html) {
layerIndex = layer.open({
title: '编辑参数模板',
skin: 'layer-tips-class',
type: 1,
area: ['500px'],
content: html,
});
});
}
/**
* 打开添加参数弹出框
*/
function addAttributePopup() {
var add_attr = $("#addAttribute").html();
laytpl(add_attr).render({}, function (html) {
layerIndex = layer.open({
title: '添加参数',
skin: 'layer-tips-class',
type: 1,
area: ['800px', '500px'],
content: html,
success: function () {
form.render();
form.on('select(attr_type)', function (data) {
if (data.value == 3) {
$(".js-is-query").hide();
$(".attribute-value-list").hide();
} else {
$(".js-is-query").show();
$(".attribute-value-list").show();
}
//检测是否开启规格参数
if ($("input[name='is_spec']").is(":checked")) {
if (data.value == 1) {
$(".js-is-query").hide();
$(".js-is-spec").show();
} else {
$(".js-is-spec").hide();
}
}
});
form.on('switch(is_spec)', function (data) {
var h = '';
if (this.checked) {
h += '<option value="1">单选</option>';
$(".js-is-query").hide();
} else {
h += '<option value="1">单选</option>';
h += '<option value="2">多选</option>';
h += '<option value="3">输入</option>';
$(".js-is-query").show();
}
$("select[name='attr_type']").html(h);
form.render("select");
});
attrValueList = [];
addAttrValue();
}
});
});
}
//添加参数
function addAttrValue() {
attrValueList.push({
attr_value_name: "",
sort: 0
});
refreshAttrValueList();
var scrollHeight = $(".attribute-value-list .table-wrap").prop("scrollHeight");
$(".attribute-value-list .table-wrap").scrollTop(scrollHeight)
}
//刷新参数列表
function refreshAttrValueList() {
var h = '';
for (var i = 0; i < attrValueList.length; i++) {
var item = attrValueList[i];
h += '<tr>';
h += '<td><input name="attr_value_name" type="text" value="' + item.attr_value_name + '" data-index="' + i + '" placeholder="请输入参数名称" lay-verify="attr_value" class="layui-input len-mid" autocomplete="off"></td>';
h += '<td><a class="text-color" href="javascript:deleteAttrValue(' + i + ');">删除</a></td>';
h += '</tr>';
}
$(".attribute-value-list .layui-table tbody").html(h);
}
//删除参数
function deleteAttrValue(index) {
if (attrValueList[index].is_add) {
//删除已添加的参数需要再次确认
layerIndex = layer.confirm('参数已使用,请谨慎操作', function () {
deleteAttrValueList.push(attrValueList[index].attr_value_id);
attrValueList.splice(index, 1);
refreshAttrValueList();
layer.close(layerIndex);
});
} else {
attrValueList.splice(index, 1);
refreshAttrValueList();
}
}
//删除参数
function deleteAttribute(attr_id) {
//删除参数需要再次确认
layerIndex = layer.confirm('确定要删除吗?', function () {
if (repeatFlag) return false;
repeatFlag = true;
$.ajax({
url: ns.url("shop/goodsattr/deleteAttribute"),
data: {attr_class_id: attr_class_id, attr_id: attr_id},
dataType: 'json',
type: 'post',
success: function (data) {
layer.msg(data.message);
if (data.code == 0) {
layer.close(layerIndex);
listenerHash(); // 刷新页面
} else {
repeatFlag = false;
}
}
});
layer.close(layerIndex);
});
}
/**
* 打开编辑参数弹出框
*/
function editAttributePopup(attr_id) {
$.ajax({
url: ns.url("shop/goodsattr/getAttributeDetail"),
data: {attr_class_id: attr_class_id, attr_id: attr_id},
dataType: 'json',
type: 'post',
success: function (res) {
if (res.code == 0) {
var data = res.data;
var edit_attr = $("#editAttribute").html();
laytpl(edit_attr).render(data, function (html) {
var area = ['800px', '500px'];
if (data.attr_type == 3) {
area = ['800px', '350px'];
}
layerIndex = layer.open({
title: '编辑参数',
skin: 'layer-tips-class',
type: 1,
area: area,
content: html,
success: function () {
form.render();
if (data.is_spec == 1) {
$(".js-is-query").hide();
}
if (data.attr_type == 3) {
$(".js-is-query").hide();
$(".attribute-value-list").hide();
}
form.on('switch(is_spec)', function (data) {
//检测是否开启规格参数
if (data.elem.checked) {
$(".js-is-query").hide();
$("input[name=is_spec]").val(1);
} else {
$(".js-is-query").show();
$("input[name=is_spec]").val(0);
}
});
attrValueList = [];//每次编辑时清空参数集合
if (data.attr_type != 3 && data.value) {
for (var i = 0; i < data.value.length; i++) {
attrValueList.push({
attr_value_name: data.value[i].attr_value_name,
sort: data.value[i].sort,
is_add: true,// 已添加参数进行标识
attr_value_id: data.value[i].attr_value_id
});
}
refreshAttrValueList();
}
}
});
});
}
}
});
}
//添加参数
function addAttributeValue(attr_id, callback) {
attr_id = attr_id || 0;
// 添加参数
var addAttrValue = [];
for (var i = 0; i < attrValueList.length; i++) {
if (!attrValueList[i].is_add) {
attrValueList[i].attr_id = attr_id;
attrValueList[i].attr_class_id = attr_class_id;
addAttrValue.push(attrValueList[i]);
}
}
if (addAttrValue.length > 0) {
$.ajax({
url: ns.url("shop/goodsattr/addAttributeValue"),
data: {attr_class_id: attr_class_id, value: JSON.stringify(addAttrValue)},
dataType: 'json',
type: 'post',
async: false,
success: function (data) {
if (callback) callback(data);
}
});
}
}
// 监听单元格编辑
function editSort(attr_class_id,id, event) {
var data = $(event).val();
if (!new RegExp("^-?[1-9]\\d*$").test(data)) {
layer.msg("排序号只能是整数");
return;
}
if(data<0){
layer.msg("排序号必须大于0");
return ;
}
$.ajax({
type: 'POST',
url: ns.url("shop/goodsattr/modifyAttributeSort"),
data: {
sort: data,
attr_class_id:attr_class_id,
attr_id: id
},
dataType: 'JSON',
success: function(res) {
layer.msg(res.message);
if (res.code == 0) {
listenerHash(); // 刷新页面
}
}
});
}

View File

@@ -0,0 +1,407 @@
var link_url_json = $("input[name='link_url']").val();
if(link_url_json) {
link_url_json = JSON.parse(link_url_json);
$(".link-url-show").text(link_url_json.title);
}
var laytpl, form, layerIndex;
var categoryFullName = [];//组装名称
var saveData = null;
var totalUploadNum = 0;
var completeUploadNum = 0;
$(function () {
//编辑时赋值组装名称
if ($("input[name='category_full_name']").length > 0) {
categoryFullName = $("input[name='category_full_name']").val().split("/").slice(0, $("input[name='category_full_name']").val().split("/").length - 1);
}
layui.use(['form', 'laytpl'], function () {
var repeat_flag = false;//防重复标识
laytpl = layui.laytpl;
form = layui.form;
/**
* 表单验证
*/
form.verify({
commission_rate: function (value) {
var reg = /^\d{0,2}(.?\d{0,2})$/;
if (value.length > 0) {
if (isNaN(value)) {
return '佣金比率输入错误';
}
if (!reg.test(value) || value < 0 || value > 100) {
return '佣金比率范围:0~100%';
}
}
},
num: function (value) {
if (value == '') {
return;
}
if (value % 1 != 0) {
return '排序数值必须为整数';
}
if (value < 0) {
return '排序数值必须为大于0';
}
}
});
var upload = new Upload({
elem: '#imgUpload',
size:100,
auto:false,
bindAction:'#imageUploadAction',
callback: function(res) {
uploadComplete('image', res.data.pic_path);
}
});
var adv_upload = new Upload({
elem: '#imgUploadAdv',
auto:false,
bindAction:'#imageAdvUploadAction',
callback: function(res) {
uploadComplete('image_adv', res.data.pic_path);
}
});
function uploadComplete(field, pic_path) {
saveData.field[field] = pic_path;
completeUploadNum += 1;
if(completeUploadNum == totalUploadNum){
saveFunc();
}
}
form.on('submit(save)', function (data) {
saveData = data;
var obj = $("img.img_prev[data-prev='1']");
totalUploadNum = obj.length;
if(totalUploadNum > 0){
obj.each(function(){
var actionId = $(this).attr('data-action-id');
$(actionId).click();
})
}else{
saveFunc();
}
return false;
});
function saveFunc(){
var data = saveData;
categoryFullName.push(data.field.category_name);
data.field.category_full_name = categoryFullName.join("/");
data.field.attr_class_name = $("select[name='attr_class_id'] option:checked").text();
// 删除图片
if(!data.field.image) upload.delete();
if(!data.field.image_adv) adv_upload.delete();
if (repeat_flag) return false;
repeat_flag = true;
var url = ns.url("shop/goodscategory/addCategory");
if (data.field.category_id) url = ns.url("shop/goodscategory/editCategory");
$.ajax({
url: url,
data: data.field,
dataType: 'json',
type: 'post',
success: function (data) {
layer.msg(data.message);
if (data.code == 0) {
location.hash = ns.hash("shop/goodscategory/lists");
} else {
repeat_flag = false;
}
}
});
}
//保存上级分类
form.on('submit(save_pid)', function (data) {
var option_category_id_1 = $("select[name='category_id_1'] option:checked");
var option_category_id_2 = $("select[name='category_id_2'] option:checked[value!='0']");
categoryFullName = [];
var level, category_name, pid;
if (option_category_id_1.length) {
level = parseInt(option_category_id_1.attr("data-level"));
category_name = option_category_id_1.text();
pid = option_category_id_1.val();//上级分类id
var category_id_1 = option_category_id_1.val();//一级分类id
if (category_id_1 > 0) {
$("input[name='category_id_1']").val(category_id_1);
categoryFullName.push(category_name);
}
}
if($("input[name='category_name_1']").length){
categoryFullName.push($("input[name='category_name_1']").val());
}
// 选中了二级商品分类
if (option_category_id_2.length) {
level = parseInt(option_category_id_2.attr("data-level"));
category_name = option_category_id_2.text();
pid = option_category_id_2.val();
var category_id_2 = option_category_id_2.val();//二级分类id
if (category_id_2 > 0) {
$("input[name='category_id_2']").val(category_id_2);
categoryFullName.push(category_name);
}
}
$(".js-pid span").text(category_name);
$("input[name='pid']").val(pid);
$("input[name='level']").val(level + 1);//当前添加的层级+1
layer.close(layerIndex);
return false;
});
setTimeout(()=>{
form.render();
},600)
});
});
//选择商品分类弹出框
function selectedCategoryPopup() {
if ($("input[name='category_id']").length) {
// 修改
editSelectedPid();
} else {
//添加
addSelectedPid();
}
}
/**
* 获取商品分类列表
* @param data
* @param callback
*/
function getCategoryList(data, callback) {
$.ajax({
url: ns.url("shop/goodscategory/getCategoryList"),
data: data,
dataType: 'json',
type: 'post',
async: false,
success: function (res) {
var data = res.data;
if (callback) callback(data);
}
});
}
/**
* 添加时,选择上级分类
*/
function addSelectedPid() {
//查询一级商品分类
getCategoryList({pid: 0}, function (list) {
var html = $("#selectedCategory").html();
var data = {
category_id_1: $("input[name='category_id_1']").val(),
category_list_1: list
};
laytpl(html).render(data, function (html) {
layerIndex = layer.open({
title: '选择商品分类',
skin: 'layer-tips-class',
type: 1,
area: ['450px'],
content: html,
success: function () {
form.render();
form.on('select(category_id_1)', function (item) {
if (item.value > 0) {
getCategoryList({pid: item.value}, function (list) {
var h = '<option value="0">请选择</option>';
for (var i = 0; i < list.length; i++) {
if ($("input[name='category_id_2']").val() == list[i].category_id) {
h += '<option value="' + list[i].category_id + '" data-level="' + list[i].level + '" selected>' + list[i].category_name + '</option>';
} else {
h += '<option value="' + list[i].category_id + '" data-level="' + list[i].level + '">' + list[i].category_name + '</option>';
}
}
$("select[name='category_id_2']").html(h);
form.render("select");
});
} else {
//顶级分类不需要查询
$("select[name='category_id_2']").html('<option value="0">请选择</option>');
form.render("select");
}
});
$("select[name='category_id_1']").siblings("div.layui-form-select").find("dl dd[lay-value='" + $("input[name='category_id_1']").val() + "']").click();
}
});
});
});
}
/**
* 编辑时,选择上级分类
*/
function editSelectedPid() {
var html = $("#selectedCategory").html();
laytpl(html).render({}, function (html) {
layerIndex = layer.open({
title: '选择商品分类',
skin: 'select-category',
type: 1,
area: ['650px'],
content: html,
btn: ['确定', '取消'],
success: function () {
let pid = $('input[name="pid"]').val();
let level = $('input[name="level"]').val();
$('.table_div input[name="category_id"][data-category-id="'+pid+'"]').attr('checked', true);
if(level == 3) $('.table_div div[data-cateid="'+pid+'"]').parents('.table_two_div').show().prev('.table_tr').find('.switch').attr('data-open', 1).html('-');
form.render();
$(".js-switch").click(function (event) {
event.stopPropagation();
var category_id = $(this).attr("data-category-id");
var level = $(this).attr("data-level");
var open = parseInt($(this).attr("data-open").toString());
if(open){
$(".goods-category-list .layui-table tr[data-category-id-"+ level+"='" + category_id + "']").hide();
// $(this).children("img").removeClass('rotate');
$(this).text("+");
if(level == 1) $(this).parents('.table_tr').siblings('.table_two_div').hide();
else if(level == 2) $(this).parents('.table_tr').siblings('.table_three').hide();
}else{
$(".goods-category-list .layui-table tr[data-category-id-"+ level+"='" + category_id + "']").show();
$(this).text("-");
// $(this).children("img").addClass('rotate');
if(level == 1) $(this).parents('.table_tr').siblings('.table_two_div').show();
else if(level == 2) $(this).parents('.table_tr').siblings('.table_three').show();
}
$(this).attr("data-open", (open ? 0 : 1));
});
form.on('checkbox(category)', function (data) {
if(data.elem.checked==true){
$('.table_move').children('div').removeClass('layui-form-checked');
$(".table_move input").prop("checked",false);
}
$(this).parents('.table_move').children('div').addClass('layui-form-checked');
$(this).parents('.table_move').find('input').prop("checked",true);
return false;
});
},
yes: function(index, layero){
let obj = $('.table_div input[name="category_id"]:checked');
let num = $(obj).length;
if(num > 1){
layer.msg('只能选择一个上级');
return false;
}
let parent_level = $(obj).attr('data-level');
let pid = $(obj).val();
let parent_name = $(obj).attr('data-name')
if(num < 1){
parent_level = 0;
pid = 0;
parent_name = '顶级分类';
}
$.ajax({
url: ns.url("shop/goodscategory/checkEditCategory"),
data: {
category_id: $('#category_id').val(),
pid : pid
},
dataType: 'json',
type: 'post',
async: false,
success: function (res) {
if(res.code >= 0){
$(".js-pid span").text(parent_name);
$("input[name='pid']").val(pid);
$("input[name='level']").val(parseInt(parent_level) + 1);//当前添加的层级+1
layer.close(layerIndex);
}else{
layer.msg(res.message)
}
}
});
}
});
});
}
/**
* 获取商品分类信息
* @param category_id
* @param callback
*/
function getCategoryInfo(category_id, callback) {
$.ajax({
url: ns.url("shop/goodscategory/getCategoryInfo"),
data: {category_id: category_id},
dataType: 'json',
type: 'post',
async: false,
success: function (res) {
var data = res.data;
if (callback) callback(data);
}
});
}
function backGoodsCategoryList() {
location.hash = ns.hash("shop/goodscategory/lists")
}
function selectedLink() {
if (link_url_json == "") {
link_url_json = {};
}
ns.select_link(link_url_json, function (data) {
for (var o in data) {
if (data[o] == null) delete data[o];
}
$("input[name='link_url']").val(JSON.stringify(data));
$(".link-url-show-wrap .layui-input-block").find('.link-url-show').remove();
$(".link-url-show-wrap .layui-input-block").prepend(`<span class="link-url-show">${data.title}</span>`);
});
}

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,185 @@
/**
* 手机端自定义模板Vue对象
*/
var vue = new Vue({
el: "#diyView",
data: {
lazyLoad: false,
global: {
title: "商品列表",
pageBgColor: "#ffffff", // 页面背景颜色
topNavColor: "#ffffff",
navStyle: 1, // 导航栏风格
textNavColor: "#333333",
textImgPosLink: 'center',
},
data: {
fontWeight: false,
padding: 10,
cartEvent: "detail",
text: "购买",
textColor: "#FFFFFF",
theme: "default",
aroundRadius: 25,
control: true,
bgColor: "#FF6A00",
style: "button",
nameLineMode: "single",
iconDiy: {
iconType: "icon",
icon: "",
style: {
fontSize: "60",
iconBgColor: [],
iconBgColorDeg: 0,
iconBgImg: "",
bgRadius: 0,
iconColor: [
"#000000"
],
iconColorDeg: 0
}
}
},
nameLineModeList: [
{
text: "单行",
value: "single"
},
{
text: "多行",
value: "multiple"
}
],
},
created: function () {
if ($("#goodsListConfig").val()) {
$('#diyView').css('visibility', 'visible');
$('.preview-wrap .preview-restore-wrap').css('visibility', 'visible');
var self = this;
setTimeout(() => {
this.data = JSON.parse($("#goodsListConfig").val());
fullScreenSize(function () {
self.lazyLoad = true;
self.fetchIconColor();
});
}, 10);
}else{
$('#diyView').css('visibility', 'visible');
$('.preview-wrap .preview-restore-wrap').css('visibility', 'visible');
this.lazyLoad = true;
this.fetchIconColor();
}
},
methods: {
//转换图片路径
changeImgUrl: function (url) {
if (url == null || url === "") return '';
if (url.indexOf("static/img/") > -1) return ns.img(ns_url.staticImg + "/" + url.replace("public/static/img/", ""));
else return ns.img(url);
},
/**
* 选择图标风格
* @param event
*/
iconStyle(event) {
var self = this;
selectIconStyle({
elem: event.currentTarget,
icon: self.data.iconDiy.icon,
callback: function (data) {
if (data) {
self.data.iconDiy.style = data;
} else {
iconStyleSet({
style: JSON.stringify(self.data.iconDiy.style),
query: {
icon: self.data.iconDiy.icon
}
}, function (style) {
self.data.iconDiy.style = style;
})
}
}
})
},
/**
* 渲染颜色组件
* @param id
* @param color
* @param callback
*/
colorRender(id, color, callback) {
setTimeout(function () {
Colorpicker.create({
el: id,
color: color,
change: function (elem, hex) {
callback(elem, hex)
}
});
})
},
// 渲染图标颜色选择器
fetchIconColor() {
var self = this;
self.colorRender('goods-list-color', '', function (elem, color) {
if (self.data.iconDiy.style.iconBgColor.length || self.data.iconDiy.style.iconBgImg) {
self.data.iconDiy.style.iconBgColor = [color];
} else {
self.data.iconDiy.style.iconColor = [color];
}
self.$forceUpdate();
});
}
}
});
// 自适应全屏宽高
function fullScreenSize(callback) {
if(callback) callback();
setTimeout(function () {
var size = 139; // 公式二级面包屑layui-header-crumbs-second 55px+ 自定义模板区域上内边距diyview20px + 底部保存按钮90px
var commonHeight = $(window).height() - size;
['.preview-wrap .preview-restore-wrap .div-wrap'].forEach(function (obj) {
$(obj).css("height", (commonHeight) + "px");
});
$(".edit-attribute .attr-wrap").css("height", (commonHeight - 1) + "px");// 1px是上边框
$(".preview-block").css("min-height", (commonHeight - 104) + "px"); // 公式:高度 - 自定义模板区域上内边距20px - 自定义模板区域下外编辑20px- 自定义模板头部64px
},30);
}
layui.use(['form'], function () {
var form, repeat_flag = false;//防重复标识
form = layui.form;
form.render();
fullScreenSize();
$("body").off("click", ".edit-attribute .attr-wrap .restore-wrap .attr-title .tab-wrap span").on("click", ".edit-attribute .attr-wrap .restore-wrap .attr-title .tab-wrap span", function () {
$(this).addClass('active bg-color').siblings().removeClass('active bg-color');
var type = $(this).attr('data-type');
$(this).parent().parent().parent().find('.edit-content-wrap').hide();
$(this).parent().parent().parent().find('.edit-style-wrap').hide();
$(this).parent().parent().parent().find(`.edit-${type}-wrap`).show();
});
form.on('submit(save)', function(data){
if (repeat_flag) return;
repeat_flag = true;
$.ajax({
type: "post",
url: ns.url('shop/goods/goodslistconfig'),
data: {
value: JSON.stringify(vue.data)
},
dataType: "JSON",
success: function (res) {
repeat_flag = false;
layer.msg(res.message);
}
});
});
});

View File

@@ -0,0 +1,695 @@
// 商品选择弹出框
var form, laytpl, element,table;
var goodsSelectObj = {
mode: 'spu', // 商品模式spu商品sku商品项
maxNum: 0, // 最大商品数量
minNum: 0, // 最小商品数量
disabled: 0, // 不可选中
cols: [], // 列名数据源
filterData: {promotion_type: '', label_id: '', goods_name: ''}, //筛选数据
goodsIdArr: [],
skuIdAll: [],
list:{} // 新方案
};
$(function () {
layui.use(['form', 'laytpl', 'element'], function () {
form = layui.form, laytpl = layui.laytpl, element = layui.element;
$('.select-goods input[type="hidden"]').each(function () {
goodsSelectObj[$(this).attr('name')] = $(this).val();
});
setCols();
checkGoods();
table = new Table({
elem: '#goods_list',
url: ns.url('shop/goods/goodsSelect'),
where: {
is_virtual: goodsSelectObj.is_virtual,
promotion: goodsSelectObj.promotion,
goods_class: goodsSelectObj.goods_class,
is_weigh: goodsSelectObj.is_weigh,
sale_channel: goodsSelectObj.sale_channel
},
cols: goodsSelectObj.cols,
callback: function (res) {
var tempGoodsIdArr = [].concat(goodsSelectObj.goodsIdArr);
var tempSkuIdAll = [].concat(goodsSelectObj.goodsIdArr);
for (var key in goodsSelectObj.list){
if (goodsSelectObj.mode == "spu") {
if(tempGoodsIdArr.indexOf(goodsSelectObj.list[key].goods_id) == -1) {
tempGoodsIdArr.push(goodsSelectObj.list[key].goods_id);
}
}else if (goodsSelectObj.mode == "sku") {
var skuArr = Object.keys(goodsSelectObj.list[key].selected_sku_list);
skuArr.forEach(function(item){
if(tempSkuIdAll.indexOf(parseInt(item.replace('sku_', ''))) == -1) {
tempSkuIdAll.push(parseInt(item.replace('sku_', '')));
}
});
}
}
$.unique(tempGoodsIdArr);
$.unique(tempSkuIdAll);
if (goodsSelectObj.mode == "sku") {
//存储这sku的具体id
$("input[name='goods_checkbox'][data-goods-id]").each(function () {
var goods_id = $(this).attr("data-goods-id");
var tr = $(this).parent().parent().parent();
var data = getGoodsSkuData(goods_id);
laytpl(data.sku_list).render(data, function (html) {
tr.after(html);
form.render();
layer.photos({
photos: '.img-wrap',
anim: 5
});
});
});
}
var isSelectAll = false;
// 更新商品复选框状态
if (goodsSelectObj.mode == 'spu') {
for (var i = 0; i < tempGoodsIdArr.length; i++) {
var goods = $("input[name='goods_checkbox'][data-goods-id='" + tempGoodsIdArr[i] + "']");
if (goods.length) {
goods.prop("checked", true);
if (goodsSelectObj.disabled == 1) {
goods.attr("disabled", "disabled");
}
}
}
if($("input[name='goods_checkbox']").length == $("input[name='goods_checkbox']:checked").length){
isSelectAll = true;
}
} else if (goodsSelectObj.mode == 'sku') {
for (var i = 0; i < tempSkuIdAll.length; i++) {
var selected_goods_sku = $("input[name='goods_sku_checkbox'][data-sku-id='" + tempSkuIdAll[i] + "']");
selected_goods_sku.prop("checked", true);
if (selected_goods_sku.length) {
var goods = $("input[name='goods_checkbox'][data-goods-id='" + selected_goods_sku.attr("data-goods-id") + "']");
goods.prop("checked", true);
if (goodsSelectObj.disabled == 1) {
goods.attr("disabled", "disabled");
}
}
}
if($("input[name='goods_sku_checkbox']").length == $("input[name='goods_sku_checkbox']:checked").length){
isSelectAll = true;
}
}
if (isSelectAll){
$('input[name="goods_checkbox_all"]').prop('checked',true);
}
form.render();
dealWithTableSelectedNum();
}
});
//修改一级分类箭头切换
element.on('collapse(oneCategory)', function (data) {
$(".layui-colla-title").removeClass("active");
if (data.show) {
$(data.title).addClass("active");
}
});
//修改二级分类箭头切换
element.on('collapse(twoCategory)', function (data) {
$(".select-goods-classification .select-goods-classification .layui-colla-title").removeClass("active");
if (data.show) {
$(data.title).addClass("active");
}
});
//搜索商品名称或编码
form.on('submit(search)', function (data) {
formSearch();
});
//搜索类型切换
form.on('select(select_type)', function (data) {
formSearch();
});
//商品标签筛选
form.on('select(label_id)', function (data) {
formSearch();
});
//商品类型筛选
form.on('select(goods_class)', function (data) {
formSearch();
});
// 勾选商品
form.on('checkbox(goods_checkbox_all)', function (data) {
var all_checked = data.elem.checked;
$("input[name='goods_checkbox']").each(function () {
var checked = $(this).prop('checked');
if (all_checked != checked) {
$(this).next().click();
}
});
});
// 勾选商品
form.on('checkbox(goods_checkbox)', function (data) {
var goods_id = $(data.elem).attr("data-goods-id"),
json = {};
$("input[name='goods_sku_checkbox'][data-goods-id='" + goods_id + "']").prop("checked", data.elem.checked);
form.render();
var spuLen = $("input[name='goods_checkbox'][data-goods-id=" + goods_id + "]:checked").length;
if (spuLen) {
json = JSON.parse($("input[name='goods_json'][data-goods-id=" + goods_id + "]").val());
json.selected_sku_list = {};
delete json.LAY_INDEX;
delete json['LAY_TABLE_INDEX'];
goodsSelectObj.list['goods_' + goods_id] = json;
} else {
delete goodsSelectObj.list['goods_' + goods_id];
}
// 选择商品多规格项
if (goodsSelectObj.mode == "sku" && goodsSelectObj.list['goods_' + goods_id]) {
$("input[name='goods_sku_json'][data-goods-id=" + goods_id + "]").each(function () {
var item = JSON.parse($(this).val());
goodsSelectObj.list['goods_' + goods_id].selected_sku_list['sku_' + item.sku_id] = item;
});
}
dealWithTableSelectedNum();
});
// 勾选商品SKU
form.on('checkbox(goods_sku_checkbox)', function (data) {
var goods_id = $(data.elem).attr("data-goods-id"),
sku_id = $(data.elem).attr("data-sku-id"),
json = {};
if ($("input[name='goods_sku_checkbox'][data-goods-id='" + goods_id + "']:checked").length) {
json = JSON.parse($("input[name='goods_json'][data-goods-id=" + goods_id + "]").val());
json.selected_sku_list = {};
delete json.LAY_INDEX;
delete json.LAY_TABLE_INDEX;
if(!goodsSelectObj.list['goods_' + goods_id]){
goodsSelectObj.list['goods_' + goods_id] = json;
}
var skuVal = JSON.parse($("input[name='goods_sku_json'][data-sku-id=" + sku_id + "]").val());
if(data.elem.checked){
goodsSelectObj.list['goods_' + goods_id].selected_sku_list['sku_' + sku_id] = skuVal;
}else{
delete goodsSelectObj.list['goods_' + goods_id].selected_sku_list['sku_' + sku_id];
}
$("input[name='goods_checkbox'][data-goods-id='" + goods_id + "']").prop("checked", true);
} else {
$("input[name='goods_checkbox'][data-goods-id='" + goods_id + "']").prop("checked", false);
if(goodsSelectObj.list['goods_' + goods_id]){
delete goodsSelectObj.list['goods_' + goods_id].selected_sku_list['sku_' + sku_id];
}
// 没有选中,则清空整个商品对象
if(Object.keys(goodsSelectObj.list['goods_' + goods_id].selected_sku_list).length == 0){
delete goodsSelectObj.list['goods_' + goods_id];
}
}
goodsSelectObj.filterData.goods_ids = goodsSelectObj.goodsIdArr.toString();
dealWithTableSelectedNum();
form.render();
});
$(".select-goods .select-goods-left dd").hover(function () {
$(this).addClass("active");
}, function () {
$(this).removeClass("active");
});
$("body").off("click", ".select-goods-left .marketing-campaign dd").on("click", ".select-goods-left .marketing-campaign dd", function () {
$(this).addClass("text-color").siblings().removeClass("text-color");
goodsSelectObj.filterData.promotion_type = $(this).attr("data-type");
table.reload({
page: {
curr: 1
},
where: goodsSelectObj.filterData
});
});
$("body").off("click", ".select-goods-left .commodity-group dd").on("click", ".select-goods-left .commodity-group dd", function () {
$(this).addClass("text-color").siblings().removeClass("text-color");
goodsSelectObj.filterData.label_id = $(this).attr("data-group-id");
table.reload({
page: {
curr: 1
},
where: goodsSelectObj.filterData
});
});
$("body").off("click", ".select-goods-left dl").on("click", ".select-goods-left dl", function () {
if ($(this).hasClass("fold")) {
$(this).removeClass("fold");
} else {
$(this).addClass("fold");
}
});
$("body").off("click", ".select-goods-left dd").on("click", ".select-goods-left dd", function (event) {
$(this).parents("dl").removeClass("fold");
$(this).parents("dl").siblings().addClass("fold");
event.stopPropagation();
});
//分类切换
$("body").off("click", ".classification-item").on("click", ".classification-item", function (event) {
var categoryId = $(this).attr("data-category_id");
$(".classification-item").removeClass("text-color border-after-color");
$(this).addClass("text-color border-after-color");
$("input[name='category_id']").val(categoryId);
formSearch();
event.stopPropagation();
});
// 商品信息展开
$("body").off("click", ".contraction").on("click", ".contraction", function () {
var goods_id = $(this).attr("data-goods-id");
var open = $(this).attr("data-open");
if (open == 1) {
$(this).children("span").text("+");
$(".js-sku-list-" + goods_id).hide();
} else {
$(this).children("span").text("-");
$(".js-sku-list-" + goods_id).show();
}
$(this).attr("data-open", (open == 0 ? 1 : 0));
});
});
});
// 设置列名
function setCols() {
switch (goodsSelectObj.promotion) {
case '':
case 'all':
case 'module':
case 'fenxiao':
case 'bargain':
goodsSelectObj.cols = [
[
{
title: '<input type="checkbox" name="goods_checkbox_all" lay-skin="primary" lay-filter="goods_checkbox_all">',
unresize: 'false',
width: '8%',
templet: '#checkbox',
},
{
title: '商品',
unresize: 'false',
width: '62%',
templet: '#goods_info'
},
{
field: 'goods_stock',
title: '库存',
unresize: 'false',
width: '15%'
},
{
field: 'goods_class_name',
title: '商品类型',
unresize: 'false',
width: '15%'
}
]
];
break;
case 'pintuan':
goodsSelectObj.cols = [
[{
title: '<input type="checkbox" name="goods_checkbox_all" lay-skin="primary" lay-filter="goods_checkbox_all">',
unresize: 'false',
width: '8%',
templet: '#checkbox'
}, {
field: 'pintuan_name',
title: '拼团活动',
unresize: 'false',
width: '20%',
}, {
title: '拼团商品',
unresize: 'false',
width: '33%',
templet: '#goods_info'
}, {
field: 'pintuan_num',
title: '参团人数',
unresize: 'false',
width: '13%'
}, {
field: 'group_num',
title: '开团团队',
unresize: 'false',
width: '13%'
}, {
field: 'order_num',
title: '购买人数',
unresize: 'false',
width: '13%'
}]
];
break;
case 'groupbuy':
goodsSelectObj.cols = [
[{
title: '<input type="checkbox" name="goods_checkbox_all" lay-skin="primary" lay-filter="goods_checkbox_all">',
unresize: 'false',
width: '8%',
templet: '#checkbox'
}, {
title: '团购商品',
unresize: 'false',
width: '47%',
templet: '#goods_info'
}, {
field: 'price',
title: '商品原价',
unresize: 'false',
width: '15%',
templet: function (data) {
return '¥' + data.price;
}
}, {
field: 'groupbuy_price',
title: '团购价格',
unresize: 'false',
width: '15%',
templet: function (data) {
return '¥' + data.groupbuy_price;
}
}, {
field: 'buy_num',
title: '起购量',
unresize: 'false',
width: '15%'
}]
];
break;
case 'presale':
goodsSelectObj.cols = [
[{
title: '<input type="checkbox" name="goods_checkbox_all" lay-skin="primary" lay-filter="goods_checkbox_all">',
unresize: 'false',
width: '8%',
templet: '#checkbox'
}, {
field: 'presale_name',
title: '活动名称',
unresize: 'false',
width: '20%',
}, {
title: '预售商品',
unresize: 'false',
width: '50%',
templet: '#goods_info'
}, {
field: 'presale_stock',
title: '库存',
unresize: 'false',
width: '13%'
}]
];
break;
case 'pinfan':
goodsSelectObj.cols = [
[{
title: '<input type="checkbox" name="goods_checkbox_all" lay-skin="primary" lay-filter="goods_checkbox_all">',
unresize: 'false',
width: '8%',
templet: '#checkbox'
}, {
field: 'pintuan_name',
title: '拼团返利',
unresize: 'false',
width: '20%',
}, {
title: '拼团商品',
unresize: 'false',
width: '33%',
templet: '#goods_info'
}, {
field: 'pintuan_num',
title: '参团人数',
unresize: 'false',
width: '13%'
}, {
field: 'group_num',
title: '开团团队',
unresize: 'false',
width: '13%'
}, {
field: 'order_num',
title: '购买人数',
unresize: 'false',
width: '13%'
}]
];
break;
}
// 服务项目商品展示列名
/*
if(goodsSelectObj.goods_class == 4){
goodsSelectObj.cols = [
[
{
title: '<input type="checkbox" name="goods_checkbox_all" lay-skin="primary" lay-filter="goods_checkbox_all">',
unresize: 'false',
width: '8%',
templet: '#checkbox',
},
{
title: '商品',
unresize: 'false',
width: '62%',
templet: '#goods_info'
},
{
field: 'goods_stock',
title: '库存',
unresize: 'false',
width: '15%'
},
{
field: 'goods_class_name',
title: '商品类型',
unresize: 'false',
width: '15%'
}
]
];
}
*/
}
// 初始化选中商品,并且赋值
function checkGoods() {
// 已选中的商品id
var selectId = localStorage.getItem('goods_select_id') ? localStorage.getItem('goods_select_id').split(',') : [];
if(selectId.length == 0) return;
// 查询已选商品集合,并且赋值
$.ajax({
url: ns.url("shop/goods/checkgoods"),
data: {goods_ids: selectId.toString(), mode: goodsSelectObj.mode},
dataType: 'JSON',
type: 'POST',
async: false,
success: function (res) {
if (res.code >= 0 && res.data) {
var data = res.data;
if (!data) return;
if (goodsSelectObj.mode == 'spu') {
data.forEach(function (item) {
goodsSelectObj.list['goods_' + item.goods_id] = item;
goodsSelectObj.goodsIdArr.push(item.goods_id);
});
} else {
data.forEach(function (item) {
var goods = {
goods_id: item.goods_id,
goods_name: item.goods_name,
goods_class_name: item.goods_class_name,
goods_image: item.goods_image,
price: item.goods_price,
goods_stock: item.goods_stock,
is_virtual: item.is_virtual
};
var sku = {
sku_id: item.sku_id,
sku_name: item.sku_name,
price: item.price,
stock: item.stock,
sku_image: item.sku_image,
goods_id: item.goods_id,
goods_class_name: item.goods_class_name
};
if (!goodsSelectObj.list['goods_' + item.goods_id]) {
goods.selected_sku_list = {};
goodsSelectObj.list['goods_' + item.goods_id] = goods;
}
goodsSelectObj.list['goods_' + item.goods_id].selected_sku_list['sku_' + item.sku_id] = sku;
goodsSelectObj.skuIdAll.push(item.sku_id);
});
}
goodsSelectObj.filterData.goods_ids = goodsSelectObj.goodsIdArr.toString();
dealWithTableSelectedNum();
}
}
});
}
//公共搜索方法
function formSearch() {
var data = {};
data.search_text = $("input[name='search_text']").val();
data.select_type = $("select[name='select_type']").val();
data.label_id = $("select[name='label_id']").val();
data.goods_class = $("select[name='goods_class']").val();
data.category_id = $("input[name='category_id']").val();
data.goods_ids = getSelectGoodsIds().toString();
table.reload({
page: {
curr: 1
},
where: data
});
}
function getGoodsSkuData(goods_id) {
var list = JSON.parse($("input[name='goods_sku_list_json'][data-goods-id='" + goods_id + "']").val().toString());
var sku_list = $("#skuList").html();
var checked = $("input[name='goods_checkbox'][data-goods-id='" + goods_id + "']:checked").length ? true : false;
return {
checked: checked,
sku_list: sku_list,
list: list
};
}
//在表格底部增加了一个容器
function dealWithTableSelectedNum() {
if (goodsSelectObj.mode == 'spu') {
$(".layui-table-bottom-left-container").html('已选择 ' + Object.keys(goodsSelectObj.list).length + ' 个商品');
} else {
var count = 0;
for(var key in goodsSelectObj.list){
count += Object.keys(goodsSelectObj.list[key].selected_sku_list).length;
}
$(".layui-table-bottom-left-container").html('已选择 ' + count + ' 个商品');
}
}
//表单的选中商品数据
function getSelectGoodsIds(){
let goods_ids = [];
Object.values(goodsSelectObj.list).forEach(function (item, index) {
goods_ids.push(item.goods_id);
})
return goods_ids;
}
// 保存回调事件
function selectGoodsListener(callback) {
goodsSelectObj.goodsIdArr = [];
goodsSelectObj.skuIdAll = [];
for (var key in goodsSelectObj.list){
if (goodsSelectObj.mode == "spu") {
goodsSelectObj.goodsIdArr.push(goodsSelectObj.list[key].goods_id);
}else if (goodsSelectObj.mode == "sku") {
var skuArr = Object.keys(goodsSelectObj.list[key].selected_sku_list);
skuArr.forEach(function(item){
goodsSelectObj.skuIdAll.push(parseInt(item.replace('sku_','')));
});
}
}
var res = goodsSelectObj.list;
var num = 0;
if (goodsSelectObj.mode == "spu") {
num = goodsSelectObj.goodsIdArr.length;
if (goodsSelectObj.promotion) {
res = goodsSelectObj.goodsIdArr;
}
} else if (goodsSelectObj.mode == "sku") {
num = goodsSelectObj.skuIdAll.length;
if (goodsSelectObj.promotion) {
res = goodsSelectObj.skuIdAll;
}
}
if (num == 0) {
layer.msg('请选择商品');
return;
}
if (goodsSelectObj.maxNum && goodsSelectObj.maxNum > 0 && num > goodsSelectObj.maxNum) {
layer.msg("所选商品数量不能超过" + goodsSelectObj.maxNum + '件');
return;
}
if (goodsSelectObj.minNum && goodsSelectObj.minNum > 0 && num < goodsSelectObj.minNum) {
layer.msg("所选商品数量不能少于" + goodsSelectObj.minNum + '件');
return;
}
callback(res);
}
// 清空 已选商品 回调事件
function clearGoodsListener(callback) {
var res = {};
if (goodsSelectObj.promotion) {
res = [];
}
callback(res);
}

View File

@@ -0,0 +1,210 @@
/**
* 手机端自定义模板Vue对象
*/
var vue = new Vue({
el: "#diyView",
data: {
lazyLoad: false,
global: {
title: "商品推荐",
pageBgColor: "#ffffff", // 页面背景颜色
topNavColor: "#ffffff",
navStyle: 1, // 导航栏风格
textNavColor: "#333333",
textImgPosLink: 'center',
},
data: {
title: '猜你喜欢',
sources: 'sort',
supportPage: [],
goodsIds: [],
fontWeight: false,
padding: 10,
cartEvent: "detail",
text: "购买",
textColor: "#FFFFFF",
theme: "default",
aroundRadius: 25,
control: true,
bgColor: "#FF6A00",
style: "button",
nameLineMode: "single",
iconDiy: {
iconType: "icon",
icon: "",
style: {
fontSize: "60",
iconBgColor: [],
iconBgColorDeg: 0,
iconBgImg: "",
bgRadius: 0,
iconColor: [
"#000000"
],
iconColorDeg: 0
}
}
},
nameLineModeList: [
{
text: "单行",
value: "single"
},
{
text: "多行",
value: "multiple"
}
],
},
created: function () {
if ($("#guessYouLikeConfig").val()) {
$('#diyView').css('visibility', 'visible');
$('.preview-wrap .preview-restore-wrap').css('visibility', 'visible');
var self = this;
setTimeout(() => {
this.data = JSON.parse($("#guessYouLikeConfig").val());
fullScreenSize(function () {
self.lazyLoad = true;
self.fetchIconColor();
});
}, 10);
} else {
$('#diyView').css('visibility', 'visible');
$('.preview-wrap .preview-restore-wrap').css('visibility', 'visible');
this.lazyLoad = true;
this.fetchIconColor();
}
},
methods: {
//转换图片路径
changeImgUrl: function (url) {
if (url == null || url === "") return '';
if (url.indexOf("static/img/") > -1) return ns.img(ns_url.staticImg + "/" + url.replace("public/static/img/", ""));
else return ns.img(url);
},
/**
* 选择图标风格
* @param event
*/
iconStyle(event) {
var self = this;
selectIconStyle({
elem: event.currentTarget,
icon: self.data.iconDiy.icon,
callback: function (data) {
if (data) {
self.data.iconDiy.style = data;
} else {
iconStyleSet({
style: JSON.stringify(self.data.iconDiy.style),
query: {
icon: self.data.iconDiy.icon
}
}, function (style) {
self.data.iconDiy.style = style;
})
}
}
})
},
/**
* 渲染颜色组件
* @param id
* @param color
* @param callback
*/
colorRender(id, color, callback) {
setTimeout(function () {
Colorpicker.create({
el: id,
color: color,
change: function (elem, hex) {
callback(elem, hex)
}
});
})
},
// 渲染图标颜色选择器
fetchIconColor() {
var self = this;
self.colorRender('goods-list-color', '', function (elem, color) {
if (self.data.iconDiy.style.iconBgColor.length || self.data.iconDiy.style.iconBgImg) {
self.data.iconDiy.style.iconBgColor = [color];
} else {
self.data.iconDiy.style.iconColor = [color];
}
self.$forceUpdate();
});
},
addSupportPage(page) {
var index = this.data.supportPage.indexOf(page);
if (index != -1) {
this.data.supportPage.splice(index, 1);
} else {
this.data.supportPage.push(page);
}
},
addGoods() {
var self = this;
goodsSelect(function (data) {
self.data.goodsIds = [];
for (var key in data) {
self.data.goodsIds.push(data[key].goods_id);
}
}, self.data.goodsIds, {mode: "spu", disabled: 0});
}
}
});
// 自适应全屏宽高
function fullScreenSize(callback) {
if (callback) callback();
setTimeout(function () {
var size = 139; // 公式二级面包屑layui-header-crumbs-second 55px+ 自定义模板区域上内边距diyview20px + 底部保存按钮90px
var commonHeight = $(window).height() - size;
['.preview-wrap .preview-restore-wrap .div-wrap'].forEach(function (obj) {
$(obj).css("height", (commonHeight) + "px");
});
$(".edit-attribute .attr-wrap").css("height", (commonHeight - 1) + "px");// 1px是上边框
$(".preview-block").css("min-height", (commonHeight - 104) + "px"); // 公式:高度 - 自定义模板区域上内边距20px - 自定义模板区域下外编辑20px- 自定义模板头部64px
}, 30);
}
layui.use(['form'], function () {
var form, repeat_flag = false;//防重复标识
form = layui.form;
form.render();
fullScreenSize();
$("body").off("click", ".edit-attribute .attr-wrap .restore-wrap .attr-title .tab-wrap span").on("click", ".edit-attribute .attr-wrap .restore-wrap .attr-title .tab-wrap span", function () {
$(this).addClass('active bg-color').siblings().removeClass('active bg-color');
var type = $(this).attr('data-type');
$(this).parent().parent().parent().find('.edit-content-wrap').hide();
$(this).parent().parent().parent().find('.edit-style-wrap').hide();
$(this).parent().parent().parent().find(`.edit-${type}-wrap`).show();
});
form.on('submit(save)', function (data) {
if (repeat_flag) return;
repeat_flag = true;
$.ajax({
type: "post",
url: ns.url('shop/goods/guessyoulike'),
data: {
value: JSON.stringify(vue.data)
},
dataType: "JSON",
success: function (res) {
repeat_flag = false;
layer.msg(res.message);
}
});
});
});

View File

@@ -0,0 +1,208 @@
//==本JS是加载Lodop插件或Web打印服务CLodop/Lodop7的综合示例可直接使用建议理解后融入自己程序==
//用双端口加载主JS文件Lodop.js(或CLodopfuncs.js兼容老版本)以防其中某端口被占:
var MainJS ="CLodopfuncs.js",
URL_WS1 = "ws://localhost:8000/"+MainJS, //ws用8000/18000
URL_WS2 = "ws://localhost:18000/"+MainJS,
URL_HTTP1 = "http://localhost:8000/"+MainJS, //http用8000/18000
URL_HTTP2 = "http://localhost:18000/"+MainJS,
URL_HTTP3 = "https://localhost.lodop.net:8443/"+MainJS; //https用8000/8443
var CreatedOKLodopObject, CLodopIsLocal, LoadJsState;
//==判断是否需要CLodop(那些不支持插件的浏览器):==
function needCLodop() {
try {
var ua = navigator.userAgent;
if (ua.match(/Windows\sPhone/i) ||
ua.match(/iPhone|iPod|iPad/i) ||
ua.match(/Android/i) ||
ua.match(/Edge\D?\d+/i))
return true;
var verTrident = ua.match(/Trident\D?\d+/i);
var verIE = ua.match(/MSIE\D?\d+/i);
var verOPR = ua.match(/OPR\D?\d+/i);
var verFF = ua.match(/Firefox\D?\d+/i);
var x64 = ua.match(/x64/i);
if ((!verTrident) && (!verIE) && (x64)) return true;
else if (verFF) {
verFF = verFF[0].match(/\d+/);
if ((verFF[0] >= 41) || (x64)) return true;
} else if (verOPR) {
verOPR = verOPR[0].match(/\d+/);
if (verOPR[0] >= 32) return true;
} else if ((!verTrident) && (!verIE)) {
var verChrome = ua.match(/Chrome\D?\d+/i);
if (verChrome) {
verChrome = verChrome[0].match(/\d+/);
if (verChrome[0] >= 41) return true;
}
}
return false;
} catch (err) {
return true;
}
}
//==检查加载成功与否如没成功则用http(s)再试==
//==低版本CLODOP6.561/Lodop7.043及前)用本方法==
function checkOrTryHttp() {
if (window.getCLodop) {
LoadJsState = "complete";
return true;
}
if (LoadJsState == "loadingB" || LoadJsState == "complete") return;
LoadJsState = "loadingB";
var head = document.head || document.getElementsByTagName("head")[0] || document.documentElement;
var JS1 = document.createElement("script")
,JS2 = document.createElement("script")
,JS3 = document.createElement("script");
JS1.src = URL_HTTP1;
JS2.src = URL_HTTP2;
JS3.src = URL_HTTP3;
JS1.onload = JS2.onload = JS3.onload = JS2.onerror = JS3.onerror=function(){LoadJsState = "complete";}
JS1.onerror = function(e) {
if (window.location.protocol !== 'https:')
head.insertBefore(JS2, head.firstChild); else
head.insertBefore(JS3, head.firstChild);
}
head.insertBefore(JS1,head.firstChild);
}
//==加载Lodop对象的主过程:==
(function loadCLodop(){
if (!needCLodop()) return;
CLodopIsLocal = !!((URL_WS1 + URL_WS2).match(/\/\/localho|\/\/127.0.0./i));
LoadJsState = "loadingA";
if (!window.WebSocket && window.MozWebSocket) window.WebSocket=window.MozWebSocket;
//ws方式速度快(小于200ms)且可避免CORS错误,但要求Lodop版本足够新:
try {
var WSK1=new WebSocket(URL_WS1);
WSK1.onopen = function(e) { setTimeout("checkOrTryHttp()",200); }
WSK1.onmessage = function(e) {if (!window.getCLodop) eval(e.data);}
WSK1.onerror = function(e) {
var WSK2=new WebSocket(URL_WS2);
WSK2.onopen = function(e) {setTimeout("checkOrTryHttp()",200);}
WSK2.onmessage = function(e) {if (!window.getCLodop) eval(e.data);}
WSK2.onerror= function(e) {checkOrTryHttp();}
}
} catch(e){
checkOrTryHttp();
}
})();
//==获取LODOP对象主过程,判断是否安装、需否升级:==
function getLodop(oOBJECT, oEMBED) {
var strFontTag = "<div>打印控件";
var strLodopInstall = strFontTag + "未安装!点击这里<a href='http://www.lodop.net/download.html' target='_blank'>执行安装</a>";
var strLodopUpdate = strFontTag + "需要升级!点击这里<a href='http://www.lodop.net/download.html' target='_blank'>执行升级</a>";
var strLodop64Install = strFontTag + "未安装!点击这里<a href='http://www.lodop.net/download.html' target='_blank'>执行安装</a>";
var strLodop64Update = strFontTag + "需要升级!点击这里<a href='http://www.lodop.net/download.html' target='_blank'>执行升级</a>";
var strCLodopInstallA = "<div>Web打印服务CLodop未安装启动点击这里<a href='http://www.lodop.net/download.html' target='_blank' class='text-color'>下载执行安装</a>";
var strCLodopInstallB = "(若此前已安装过,可<a href='http://www.lodop.net/download.html' target='_blank' class='text-color'>点这里直接再次启动</a>";
var strCLodopUpdate = "<div>Web打印服务CLodop需升级!点击这里<a href='http://www.lodop.net/download.html' target='_blank' class='text-color'>执行升级</a>";
var strLodop7FontTag = "<div>Web打印服务Lodop7";
var strLodop7HrefX86 = "点击这里<a href='http://www.lodop.net/download.html' target='_blank' class='text-color'>下载安装</a>(下载后解压点击lodop文件开始执行)";
var strLodop7HrefARM = "点击这里<a href='http://www.lodop.net/download.html' target='_blank' class='text-color'>下载安装</a>(下载后解压点击lodop文件开始执行)";
var strLodop7Install_X86 = strLodop7FontTag + "未安装启动," + strLodop7HrefX86;
var strLodop7Install_ARM = strLodop7FontTag + "未安装启动," + strLodop7HrefARM;
var strLodop7Update_X86 = strLodop7FontTag + "需升级," + strLodop7HrefX86;
var strLodop7Update_ARM = strLodop7FontTag + "需升级," + strLodop7HrefARM;
var strInstallOK = ",成功后请刷新本页面或重启浏览器。</div>";
var LODOP;
try {
var isWinIE = (/MSIE/i.test(navigator.userAgent)) || (/Trident/i.test(navigator.userAgent));
var isWinIE64 = isWinIE && (/x64/i.test(navigator.userAgent));
var isLinuxX86 = (/Linux/i.test(navigator.platform)) && (/x86/i.test(navigator.platform));
var isLinuxARM = (/Linux/i.test(navigator.platform)) && (/aarch/i.test(navigator.platform));
if (needCLodop() || isLinuxX86 || isLinuxARM) {
try {
LODOP = window.getCLodop();
} catch (err) {}
// if (!LODOP && LoadJsState !== "complete") {
// if (!LoadJsState)
// alert("未曾加载Lodop主JS文件请先调用loadCLodop过程."); else
// alert("网页还没下载完毕,请稍等一下再操作.");
// return;
// }
var strAlertMessage;
if (!LODOP) {
if (isLinuxX86)
strAlertMessage = strLodop7Install_X86;
else if (isLinuxARM)
strAlertMessage = strLodop7Install_ARM;
else
strAlertMessage = strCLodopInstallA + (CLodopIsLocal ? strCLodopInstallB : "");
layer.open({
type: 1,
area: ['450px'],
content: strAlertMessage + strInstallOK
});
return;
} else {
if (isLinuxX86 && LODOP.CVERSION < "7.0.7.5")
strAlertMessage = strLodop7Update_X86;
else if (isLinuxARM && LODOP.CVERSION < "7.0.7.5")
strAlertMessage = strLodop7Update_ARM;
else if (CLODOP.CVERSION < "6.5.7.9")
strAlertMessage = strCLodopUpdate;
if (strAlertMessage) {
layer.open({
type: 1,
title: '提示',
area: ['450px'],
content: strAlertMessage + strInstallOK
});
}
}
} else {
//==如果页面有Lodop插件就直接使用,否则新建:==
if (oOBJECT || oEMBED) {
if (isWinIE)
LODOP = oOBJECT;
else
LODOP = oEMBED;
} else if (!CreatedOKLodopObject) {
LODOP = document.createElement("object");
LODOP.setAttribute("width", 0);
LODOP.setAttribute("height", 0);
LODOP.setAttribute("style", "position:absolute;left:0px;top:-100px;width:0px;height:0px;");
if (isWinIE)
LODOP.setAttribute("classid", "clsid:2105C259-1E0C-4534-8141-A753534CB4CA");
else
LODOP.setAttribute("type", "application/x-print-lodop");
document.documentElement.appendChild(LODOP);
CreatedOKLodopObject = LODOP;
} else
LODOP = CreatedOKLodopObject;
//==Lodop插件未安装时提示下载地址:==
if ((!LODOP) || (!LODOP.VERSION)) {
layer.open({
type: 1,
title: '提示',
area: ['450px'],
content: (isWinIE64 ? strLodop64Install : strLodopInstall) + strInstallOK
});
return LODOP;
}
if (LODOP.VERSION < "6.2.2.6") {
layer.open({
type: 1,
title: '提示',
area: ['450px'],
content: (isWinIE64 ? strLodop64Update : strLodopUpdate) + strInstallOK
});
}
}
//===如下空白位置适合调用统一功能(如注册语句、语言选择等):=======================
//===============================================================================
return LODOP;
} catch (err) {
layer.msg("getLodop出错:" + err);
}
}

View File

@@ -0,0 +1,231 @@
var surplus_coupon = [], // 剩余数据
selected_coupon = [], // 被选中数据
selected_coupon_id = [], // 被选中id
temp_coupon = [], //临时数据
clusterId = '';
function renderCoupon(couponIds, cluster_id) {
var couponIds_arr = [];
if (couponIds) {
couponIds_arr = couponIds.split(",");
}
selected_coupon_id = couponIds_arr;
clusterId = cluster_id;
$.ajax({
type: "POST",
data: {
page_size: 0,
status: 1
},
url: ns.url('coupon://shop/coupon/lists'),
dataType: 'JSON',
success: function (data) {
surplus_coupon = get_data_by_ids(data.data.list, 'all', couponIds).all; // 得到剩余的优惠券数据
selected_coupon = get_data_by_ids(data.data.list, 'selected', couponIds).selected;
compile_new_data();
}
})
}
/**
* 获取优惠券数据
*/
function get_data_by_ids(data, obj, ids) {
var id_arr = [], temp = {};
if (ids) {
var arr = ids.split(",");
$.each(arr, function (i, id) {
id = parseInt(id);
id_arr.push(id);
})
}
var temp_all = [], temp_selected = [];
$.each(data, function (index, item) {
if (id_arr.length > 0) {
var index = id_arr.indexOf(item.coupon_type_id);
if (index == -1) {
temp_all.push(item);
} else {
temp_selected.push(item);
}
} else {
temp_all.push(item);
}
temp.all = temp_all;
temp.selected = temp_selected;
})
return temp;
}
/**
* 渲染列表数据
*/
function compile_new_data() {
var surplus_html = compile_list(surplus_coupon, 'all');
$(".coupon-modal .all-coupon .box").html(surplus_html);
var selected_html = compile_list(selected_coupon, 'selected');
$(".coupon-modal .selected-coupon .box").html(selected_html);
}
/**
* 渲染数据
*/
function compile_list(temp_list, obj) {
var html = '<ul>';
$.each(temp_list, function (index, item) {
var selected_html = obj == 'selected' ? 'selected' : '';
if(item.count == -1){
html += '<li class="' + selected_html + '" data-selected="' + index + '" data-id="' + item.coupon_type_id + '" data-count="' + item.count + '" data-max-fetch="' + item.max_fetch + '" data-show="'+ item.is_show +'">';
}else{
html += '<li class="' + selected_html + '" data-selected="' + index + '" data-id="' + item.coupon_type_id + '" data-count="' + (item.count - item.lead_count) + '" data-max-fetch="' + item.max_fetch + '" data-show="'+ item.is_show +'">';
}
html += '<div class="coupon-box">';
if (item.type == 'reward') {
html += '<div class="coupon-money">¥' + item.money + '</div>';
} else {
html += '<div class="coupon-money">' + item.discount + '折</div>';
}
html += '<div class="coupon-name">' + item.coupon_name + '</div>';
if (item.validity_type == 0) {
html += '<div class="coupon-time">失效日期:' + ns.time_to_date(item.end_time) + '</div>';
} else if (item.validity_type == 1) {
html += '<div class="coupon-time">领取后,' + item.fixed_term + '天有效</div>';
} else {
html += '<div class="coupon-time">长期有效</div>';
}
if (obj == 'selected') {
html += `<div class="give-num">
<span>发放数量</span>
<input type="number" class="layui-input len-short num" value="1" max="99">
</div>`
}
html += '</div>';
if (obj == 'selected') {
html += '<div class="coupon-delete">×</div>'
}
html += '</li>';
})
html += '</ul>';
return html;
}
/**
* 选中与取消数据 先改变数据 再重新渲染
*/
temp_coupon = [];
$("body").off('click', '.layui-layer .coupon-list.all-coupon ul li .coupon-box').on('click', '.layui-layer .coupon-list.all-coupon ul li .coupon-box', function () {
var li = $(this).parent();
if ($(this).hasClass("left-selected")) {
$(this).removeClass("left-selected");
var index = '';
$.each(temp_coupon, function (i, item) {
if (item == li.attr('data-id')) {
index = i;
}
})
temp_coupon.splice(index, 1)
} else {
$(this).addClass("left-selected");
temp_coupon.push(li.attr('data-id'))
}
});
// 添加优惠券
$("body").off('click', '.layui-layer .coupon-modal .add').on('click', '.layui-layer .coupon-modal .add', function () {
var ids = ids = selected_coupon_id.concat(temp_coupon);
temp_coupon = [];
renderCoupon(ids.toString(), clusterId);
// compile_new_data();
});
// 删除优惠券
$("body").off('click', '.layui-layer .coupon-modal .coupon-delete').on('click', '.layui-layer .coupon-modal .coupon-delete', function () {
var id = $(this).parents("li").attr("data-id");
var ind = '';
$.each(selected_coupon_id, function (index, item) {
if (id == parseInt(item)) {
ind = index;
}
})
selected_coupon_id.splice(ind, 1);
var ids = selected_coupon_id;
renderCoupon(ids.toString(), clusterId);
});
/**
* 保存操作
*/
var isRepeat = false;
$("body").off("click", ".modal-operation .save-btn").on("click", ".modal-operation .save-btn", function () {
var coupon_data = [], isReturn = false;
$('.coupon-modal .selected-coupon .selected').each(function () {
var num = $(this).find('.num').val();
if (!/[\S]+/.test(num)) {
layer.msg('请输入发放数量');
isReturn = true;
return false;
}
if (num % 1 != 0) {
layer.msg('发放数量格式错误');
isReturn = true;
return false;
}
if (num <= 0) {
layer.msg('发放数量不能小于等于0');
isReturn = true;
return false;
}
if ($(this).attr('data-count') != -1 && $(this).attr('data-show') == 1 && num > $(this).attr('data-count')) {
layer.msg('发放数量不能超出最大值:' + $(this).attr('data-count'));
isReturn = true;
return false;
}
// if ($(this).attr('data-max-fetch') > 0 && num > $(this).attr('data-max-fetch')) {
// layer.msg('发放数量不能超出最大领取数量:' + $(this).attr('data-max-fetch'));
// isReturn = true;
// return false;
// }
coupon_data.push({
coupon_type_id: $(this).attr('data-id'),
num: num
})
})
if (isReturn || isRepeat) return;
if (!coupon_data.length) {
layer.msg('请选择要发放的优惠券');
return;
}
isRepeat = true;
$.ajax({
type: "POST",
data: {
cluster_id: clusterId,
coupon_data: JSON.stringify(coupon_data)
},
url: ns.url('shop/membercluster/sendCoupon'),
dataType: 'JSON',
success: function (res) {
isRepeat = false;
layer.close(layer_coupon);
layer.msg(res.message);
}
})
});

View File

@@ -0,0 +1,724 @@
var form, table, laydate, laytpl, repeat_flag = false, //防重复标识
currentDate = new Date(),
minDate = "",
reg = {
required: /[\S]+/,
mobile: /^1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[0-9])\d{8}$/
}, layCascader, areaTree = [];
layui.use(['form', 'layCascader', 'laydate', 'laytpl'], function () {
form = layui.form;
laydate = layui.laydate;
laytpl = layui.laytpl;
layCascader = layui.layCascader;
form.render();
currentDate.setDate(currentDate.getDate() - 7);
var birthday = $(".birthday").val();
$("input[name=birthday]").attr("value", ns.time_to_date(birthday, "Y-m-d"));
//开始时间
laydate.render({
elem: '#start_date',
type: 'datetime'
});
//结束时间
laydate.render({
elem: '#end_date',
type: 'datetime'
});
form.verify({
mobile: function (value) {
if (value == '') {
return;
}
if (!ns.parse_mobile(value)) {
return '请输入正确的手机号码!';
}
},
isemail: function (value) {
var reg = /^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/;
if (value == '') {
return;
}
if (!reg.test(value)) {
return '请输入正确的邮箱!';
}
},
num: function (value) {
var arrMen = value.split(".");
var val = 0;
if (arrMen.length == 2) {
val = arrMen[1];
}
if (value == "") {
return false;
}
if (val.length > 2) {
return '保留小数点后两位'
}
}
});
var upload = new Upload({
elem: '#headImg'
});
form.on('submit(save)', function (data) {
data.field.member_level_name = $(".member_level").find("option[value=" + data.field.member_level + "]").text();
if (data.field.status == undefined) {
data.field.status = 0;
}
// 删除图片
if (!data.field.headimg) upload.delete();
if (repeat_flag) return false;
repeat_flag = true;
$.ajax({
url: ns.url("shop/member/editMember"),
data: data.field,
dataType: 'JSON', //服务器返回json格式数据
type: 'POST', //HTTP请求类型
success: function (res) {
repeat_flag = false;
if (res.code == 0) {
layer.confirm('编辑成功', {
title: '操作提示',
btn: ['返回列表', '继续操作'],
yes: function(index, layero) {
location.hash = ns.hash("shop/member/memberList")
layer.close(index);
},
btn2: function(index, layero) {
listenerHash(); // 刷新页面
layer.close(index);
}
});
} else {
layer.msg(res.message);
}
}
});
});
//根据账户类型获取来源类型
form.on('select(account_type)', function (data) {
$.ajax({
type: "POST",
url: ns.url("shop/member/getfromtype"),
data: {type: data.value},
dataType: 'JSON',
success: function (res) {
var html = '<option value="">请选择</option>';
$.each(res, function (k, v) {
html += '<option value="' + k + '">' + v.type_name + '</option>';
});
$('.from_type').html(html);
form.render();
}
});
});
form.on('submit(search)', function (data) {
table.reload({
page: {
curr: 1
},
where: data.field
});
return false;
});
form.on('submit(savePoint)', function (data) {
if (repeat_flag) return false;
repeat_flag = true;
if (data.field.adjust_num == 0) {
layer.msg('调整数值不能为0');
repeat_flag = false;
return;
}
var after_value = point * 1 + data.field.adjust_num * 1;
if (after_value < 0) {
layer.msg('调整后积分不可以为负数');
repeat_flag = false;
return;
}
if(after_value >= 99999999){
layer.msg('调整后积分整数位不能超出99999999');
repeat_flag = false;
return;
}
$.ajax({
type: "POST",
url: ns.url("shop/member/adjustPoint"),
data: data.field,
dataType: 'JSON',
success: function (res) {
layer.msg(res.message);
if (res.code == 0) {
$("#member_point").html(res.data.point);
$("#member_point").next().attr('data-num', res.data.point);
point = res.data.point;
layer.closeAll('page');
table.reload();
} else {
repeat_flag = false;
}
}
});
});
form.on('submit(saveBalance)', function (data) {
if (repeat_flag) return false;
repeat_flag = true;
if (data.field.adjust_num == 0) {
layer.msg('调整数值不能为0');
repeat_flag = false;
return;
}
var after_value = balance * 1 + data.field.adjust_num * 1;
if (after_value < 0) {
layer.msg('调整后储值余额不可以为负数');
repeat_flag = false;
return;
}
if(after_value >= 99999999){
layer.msg('调整后储值余额整数位不能超出99999999');
repeat_flag = false;
return;
}
$.ajax({
type: "POST",
url: ns.url("shop/member/adjustBalance"),
data: data.field,
dataType: 'JSON',
success: function (res) {
repeat_flag = false;
if(res.code == 0) {
$("#member_balance").html(res.data.balance);
$("#member_balance").next().attr('data-num', res.data.balance);
balance = res.data.balance;
layer.closeAll('page');
table.reload();
}else{
layer.msg(res.message);
}
}
});
});
form.on('submit(saveGrowth)', function (data) {
if (repeat_flag) return false;
repeat_flag = true;
if (data.field.adjust_num == 0) {
layer.msg('调整数值不能为0');
repeat_flag = false;
return;
}
var after_value = growth * 1 + data.field.adjust_num * 1;
if (after_value < 0) {
layer.msg('调整后成长值不可以为负数');
repeat_flag = false;
return;
}
if(after_value >= 99999999){
layer.msg('调整后成长值整数位不能超出99999999');
repeat_flag = false;
return;
}
$.ajax({
type: "POST",
url: ns.url("shop/member/adjustGrowth"),
data: data.field,
dataType: 'JSON',
success: function (res) {
layer.msg(res.message);
if (res.code == 0) {
$("#member_growth").html(res.data.growth);
$("#member_growth").next().attr('data-num', res.data.growth);
growth = res.data.growth;
layer.closeAll('page');
table.reload();
} else {
repeat_flag = false;
}
}
});
});
form.on('checkbox(memberlevel)', function (data) {
$('#setMemberLevel input[type="checkbox"]').prop('checked', false);
$(data.elem).prop('checked', true);
form.render();
})
});
/**
* 重新渲染结束时间
* */
function reRender() {
$("#reg_end_date").remove();
$(".end-time").html('<input type="text" class="layui-input" name="reg_end_date" id="reg_end_date" placeholder="请输入结束时间">');
laydate.render({
elem: '#reg_end_date',
min: minDate
});
}
function savePoint(e) {
var point = $(e).attr('data-num');
var data = {
point: point
};
laytpl($("#point").html()).render(data, function (html) {
layer.open({
title: '调整积分',
skin: 'layer-tips-class',
type: 1,
area: ['800px'],
content: html,
end: function () {
repeat_flag = false;
}
});
});
$(".integral-bounced .amount input").on("input propertychange", function (val) {
var newIntegral = parseInt($(this).val());
if (!isNaN(newIntegral)) $(this).val(newIntegral);
var currIntegral = parseInt($(".integral-bounced .account-value").text());
if (newIntegral + currIntegral < 0) {
layer.msg("调整数额与当前值积分数相加不能小于0");
$(this).val(-currIntegral);
return false;
}
})
}
function saveBalance(e) {
var balance = $(e).attr('data-num');
var data = {
balance: balance
};
laytpl($("#balance").html()).render(data, function (html) {
layer.open({
title: '调整储值余额',
skin: 'layer-tips-class',
type: 1,
area: ['800px'],
content: html,
end: function () {
repeat_flag = false;
}
});
});
}
function saveGrowth(e) {
var growth = $(e).attr('data-num');
var data = {
growth: growth
};
laytpl($("#growth").html()).render(data, function (html) {
layer.open({
title: '调整成长值',
skin: 'layer-tips-class',
type: 1,
area: ['800px'],
content: html,
end: function () {
repeat_flag = false;
}
});
});
}
function editMember(data, callback) {
if (repeat_flag) return false;
repeat_flag = true;
data.member_id = member_id;
$.ajax({
url: ns.url("shop/member/editMember"),
data: data,
dataType: 'JSON', //服务器返回json格式数据
type: 'POST', //HTTP请求类型
success: function (res) {
repeat_flag = false;
typeof callback == 'function' && callback(res);
}
});
}
function editMemberLevel() {
laytpl($("#memberLevel").html()).render({}, function (html) {
layer.open({
title: '设置会员等级',
skin: 'select-level-layer',
type: 1,
area: ['400px', '300px'],
content: html,
success: function () {
form.render();
form.on('radio(level_type)', function (data) {
$('.level-type').hide();
$('.level-type.type-' + data.value).show();
})
form.on('select(member_card)', function (data) {
$('.member-card').hide();
$('.member-card-' + data.value).show();
})
},
btn: ['保存', '取消'],
yes: function () {
layer.confirm('是否确定变更该客户的会员等级?', {title: '会员等级变更确认'}, function (index) {
var data = {
level_type: $('[name="level_type"]:checked').val() || 0,
member_id: member_id
}
data.level_id = data.level_type == 0 ? $('[name="member_level"]').val() : $('[name="member_card"]').val();
if (data.level_id == 0) {
layer.msg((data.level_type == 0 ? '请选择会员等级' : '请选择会员卡'));
return;
}
if (data.level_type == 1) data.period_unit = $('[name="member_card_' + data.level_id + '"]:checked').val();
layer.close(index);
$.ajax({
type: "POST",
url: ns.url("shop/member/handleMember"),
data: data,
dataType: 'JSON',
success: function (res) {
listenerHash(); // 刷新页面
layer.msg(res.message);
layer.closeAll();
}
});
layer.closeAll();
});
}
});
});
}
function editNickname(event) {
var nickname = $(event).prev('span').text();
var html = `<div class="layui-form form-wrap">
<div class="layui-form-item">
<label class="layui-form-label" style="width:auto"><span class="required">*</span>昵称:</label>
<div class="layui-input-block" style="margin-left: 0;">
<input name="nickname" type="text" lay-verify="required" value="` + nickname + `" class="layui-input len-mid">
</div>
</div>
</div>`;
layer.open({
title: '编辑昵称',
skin: 'edit-member-layer',
type: 1,
area: '360px',
content: html,
success: function () {
form.render();
},
btn: ['保存', '取消'],
yes: function () {
var data = {nickname: $.trim($('[name="nickname"]').val())};
if (!reg.required.test(data.nickname)) {
layer.msg('请输入昵称', {icon: 5});
return;
}
editMember(data, function (res) {
if (res.code == 0) {
$(event).prev('span').text(data.nickname);
layer.closeAll();
} else {
layer.msg(res.message);
}
});
}
})
}
function editRealName(event) {
var realname = $.trim($(event).prev('span').text()) != '暂无' ? $.trim($(event).prev('span').text()) : '';
var html = `<div class="layui-form form-wrap">
<div class="layui-form-item">
<label class="layui-form-label" style="width:auto"><span class="required">*</span>真实姓名:</label>
<div class="layui-input-block" style="margin-left: 0;">
<input name="realname" type="text" lay-verify="required" value="` + realname + `" class="layui-input len-mid">
</div>
</div>
</div>`;
layer.open({
title: '真实姓名',
skin: 'edit-member-layer',
type: 1,
area: '380px',
content: html,
success: function () {
form.render();
},
btn: ['保存', '取消'],
yes: function () {
var data = {realname: $.trim($('[name="realname"]').val())};
if (!reg.required.test(data.realname)) {
layer.msg('请输入真实姓名', {icon: 5});
return;
}
editMember(data, function (res) {
if (res.code == 0) {
$(event).prev('span').text(data.realname);
layer.closeAll();
} else {
layer.msg(res.message);
}
});
}
})
}
function editMobile(event) {
var mobile = $.trim($(event).prev('span').text()) != '暂无' ? $.trim($(event).prev('span').text()) : '';
var html = `<div class="layui-form form-wrap">
<div class="layui-form-item">
<label class="layui-form-label" style="width:auto"><span class="required">*</span>手机号:</label>
<div class="layui-input-block" style="margin-left: 0;">
<input name="mobile" type="text" lay-verify="required" value="` + mobile + `" class="layui-input len-mid">
</div>
</div>
</div>`;
layer.open({
title: '编辑手机号',
skin: 'edit-member-layer',
type: 1,
area: '370px',
content: html,
success: function () {
form.render();
},
btn: ['保存', '取消'],
yes: function () {
var data = {mobile: $.trim($('[name="mobile"]').val())};
if (!reg.required.test(data.mobile)) {
layer.msg('手机号', {icon: 5});
return;
}
if (!ns.parse_mobile(data.mobile)) {
layer.msg('请输入正确的手机号', {icon: 5});
return;
}
editMember(data, function (res) {
if (res.code == 0) {
$(event).prev('span').text(data.mobile);
layer.closeAll();
} else {
layer.msg(res.message);
}
});
}
})
}
function editBirthday(event) {
var birthday = $(event).prev('span').attr('data-value');
var html = `<div class="layui-form form-wrap">
<div class="layui-form-item">
<label class="layui-form-label" style="width:auto"><span class="required">*</span>生日:</label>
<div class="layui-input-block" style="margin-left: 0;">
<input name="birthday" type="text" id="birthday" value="" class="layui-input len-mid">
</div>
</div>
</div>`;
layer.open({
title: '生日',
skin: 'edit-member-layer',
type: 1,
area: '360px',
content: html,
success: function () {
laydate.render({
elem: '#birthday',
max: 0
});
form.render();
},
btn: ['保存', '取消'],
yes: function () {
var data = {birthday: $('[name="birthday"]').val()};
if (!reg.required.test(data.birthday)) {
layer.msg('请选择生日', {icon: 5});
return;
}
editMember(data, function (res) {
if (res.code == 0) {
$(event).prev('span').text(data.birthday);
// $(event).prev('span').attr('data-value', data.sex);
layer.closeAll();
} else {
layer.msg(res.message);
}
});
}
})
}
function editSex(event) {
var sex = $(event).prev('span').attr('data-value');
var html = `<div class="layui-form form-wrap">
<div class="layui-form-item">
<label class="layui-form-label" style="width:auto"><span class="required">*</span>性别:</label>
<div class="layui-input-block" style="margin-left: 0;">
<input type="radio" name="sex" value="1" title="男" ` + (sex == 1 ? 'checked' : '') + `>
<input type="radio" name="sex" value="2" title="女" ` + (sex == 2 ? 'checked' : '') + `>
</div>
</div>
</div>`;
layer.open({
title: '性别',
skin: 'edit-member-layer',
type: 1,
area: '270px',
content: html,
success: function () {
form.render();
},
btn: ['保存', '取消'],
yes: function () {
var data = {sex: $('[name="sex"]:checked').val()};
if (!data.sex) {
layer.msg('请选择性别', {icon: 5});
return;
}
editMember(data, function (res) {
if (res.code == 0) {
$(event).prev('span').text($('[name="sex"]:checked').attr('title'));
$(event).prev('span').attr('data-value', data.sex);
layer.closeAll();
} else {
layer.msg(res.message);
}
});
}
})
}
function editMemberAddress(event) {
var html = `<div class="layui-form form-wrap">
<div class="layui-form-item">
<label class="layui-form-label" style="width:auto"><span class="required">*</span>所在地区:</label>
<div class="layui-input-inline len-mid" style="margin: 0;">
<input name="show_full_address" type="text" lay-verify="required" value="${full_address}" class="layui-input len-mid">
</div>
</div>
</div>
<input name="province_id" type="hidden" value="${province_id}" />
<input name="city_id" type="hidden" value="${city_id}" />
<input name="district_id" type="hidden" value="${district_id}" />
<input name="full_address" type="hidden" value="${full_address}" />
<div class="layui-form form-wrap">
<div class="layui-form-item">
<label class="layui-form-label" style="width:auto"><span class="required">*</span>详细地址:</label>
<div class="layui-input-block" style="margin-left: 0;">
<input name="address" type="text" lay-verify="required" value="${address}" class="layui-input len-mid">
</div>
</div>
</div>`;
layer.open({
title: '会员地址',
skin: 'edit-member-layer',
type: 1,
area: '380px',
content: html,
success: function () {
form.render();
if (!areaTree.length) {
$.ajax({
url: ns.url("shop/express/getareatree"),
dataType: 'JSON',
type: 'POST',
async: false,
success: function (res) {
areaTree = res.data;
}
})
}
if($('[name="show_full_address"]').length) {
var _cascader = layCascader({
elem: $('[name="show_full_address"]'),
options: areaTree,
separator: '-',
props: {
value: 'id',
label: 'name',
children: 'children'
}
});
if (full_address) {
_cascader.setValue(parseInt(district_id));
}
_cascader.changeEvent(function (value, node) {
$('[name="province_id"]').val(node.path[0] ? node.path[0].data.id : 0)
$('[name="city_id"]').val(node.path[1] ? node.path[1].data.id : 0)
$('[name="district_id"]').val(node.path[2] ? node.path[2].data.id : 0)
var fullAddress = [];
node.path.forEach(function (item) {
fullAddress.push(item.data.name);
})
$('[name="full_address"]').val(fullAddress.join('-'));
});
}
},
btn: ['保存', '取消'],
yes: function () {
var data = {
province_id: $.trim($('[name="province_id"]').val()),
city_id: $.trim($('[name="city_id"]').val()),
district_id: $.trim($('[name="district_id"]').val()),
address: $.trim($('[name="address"]').val()),
full_address: $.trim($('[name="full_address"]').val())
};
if (!reg.required.test(data.full_address)) {
layer.msg('请选择所在地区', {icon: 5});
return;
}
if (!reg.required.test(data.address)) {
layer.msg('请输入详细地址', {icon: 5});
return;
}
editMember(data, function (res) {
if (res.code == 0) {
$(event).prev('span').text(data.realname);
layer.closeAll();
listenerHash(); // 刷新页面
} else {
layer.msg(res.message);
}
});
}
})
}

View File

@@ -0,0 +1,222 @@
var surplus_coupon = [], // 剩余数据
selected_coupon = [], // 被选中数据
selected_coupon_id = [], // 被选中id
temp_coupon = [], //临时数据
memberId = '';
function renderCoupon(couponIds, member_id) {
var couponIds_arr = [];
if (couponIds) {
couponIds_arr = couponIds.split(",");
}
selected_coupon_id = couponIds_arr;
memberId = member_id;
$.ajax({
type: "POST",
data: {
page_size: 0,
status: 1
},
url: ns.url('coupon://shop/coupon/lists'),
dataType: 'JSON',
success: function (data) {
surplus_coupon = get_data_by_ids(data.data.list, 'all', couponIds).all; // 得到剩余的优惠券数据
selected_coupon = get_data_by_ids(data.data.list, 'selected', couponIds).selected;
compile_new_data();
}
})
}
/**
* 获取优惠券数据
*/
function get_data_by_ids(data, obj, ids) {
var id_arr = [], temp = {};
if (ids) {
var arr = ids.split(",");
$.each(arr, function (i, id) {
id = parseInt(id);
id_arr.push(id);
})
}
var temp_all = [], temp_selected = [];
$.each(data, function (index, item) {
if (id_arr.length > 0) {
var index = id_arr.indexOf(item.coupon_type_id);
if (index == -1) {
temp_all.push(item);
} else {
temp_selected.push(item);
}
} else {
temp_all.push(item);
}
temp.all = temp_all;
temp.selected = temp_selected;
});
return temp;
}
/**
* 渲染列表数据
*/
function compile_new_data() {
var surplus_html = compile_list(surplus_coupon, 'all');
$(".coupon-modal .all-coupon .box").html(surplus_html);
var selected_html = compile_list(selected_coupon, 'selected');
$(".coupon-modal .selected-coupon .box").html(selected_html);
}
/**
* 渲染数据
*/
function compile_list(temp_list, obj) {
var html = '<ul>';
$.each(temp_list, function (index, item) {
var selected_html = obj == 'selected' ? 'selected' : '';
if(item.count == -1){
html += '<li class="' + selected_html + '" data-selected="' + index + '" data-id="' + item.coupon_type_id + '" data-count="' + item.count + '" data-max-fetch="' + item.max_fetch + '" data-show="'+ item.is_show +'">';
}else{
html += '<li class="' + selected_html + '" data-selected="' + index + '" data-id="' + item.coupon_type_id + '" data-count="' + (item.count - item.lead_count) + '" data-max-fetch="' + item.max_fetch + '" data-show="'+ item.is_show +'">';
}
html += '<div class="coupon-box">';
if (item.type == 'reward') {
html += '<div class="coupon-money">¥' + item.money + '</div>';
} else {
html += '<div class="coupon-money">' + item.discount + '折</div>';
}
html += '<div class="coupon-name">' + item.coupon_name + '</div>';
if (item.validity_type == 0) {
html += '<div class="coupon-time">失效日期:' + ns.time_to_date(item.end_time) + '</div>';
} else if (item.validity_type == 1) {
html += '<div class="coupon-time">领取后,' + item.fixed_term + '天有效</div>';
} else {
html += '<div class="coupon-time">长期有效</div>';
}
if (obj == 'selected') {
html += `<div class="give-num">
<span>发放数量</span>
<input type="number" class="layui-input len-short num" value="1" max="99">
</div>`
}
html += '</div>';
if (obj == 'selected') {
html += '<div class="coupon-delete">×</div>'
}
html += '</li>';
})
html += '</ul>';
return html;
}
/**
* 选中与取消数据 先改变数据 再重新渲染
*/
temp_coupon = [];
$("body").off('click', '.layui-layer .coupon-list.all-coupon ul li .coupon-box').on('click', '.layui-layer .coupon-list.all-coupon ul li .coupon-box', function () {
var li = $(this).parent();
if ($(this).hasClass("left-selected")) {
$(this).removeClass("left-selected");
var index = '';
$.each(temp_coupon, function (i, item) {
if (item == li.attr('data-id')) {
index = i;
}
})
temp_coupon.splice(index, 1)
} else {
$(this).addClass("left-selected");
temp_coupon.push(li.attr('data-id'))
}
});
// 添加优惠券
$("body").off('click', '.layui-layer .coupon-modal .add').on('click', '.layui-layer .coupon-modal .add', function () {
var ids = selected_coupon_id.concat(temp_coupon);
temp_coupon = [];
renderCoupon(ids.toString(), memberId);
// compile_new_data();
});
// 删除优惠券
$("body").off('click', '.layui-layer .coupon-modal .coupon-delete').on('click', '.layui-layer .coupon-modal .coupon-delete', function () {
var id = $(this).parents("li").attr("data-id");
var ind = '';
$.each(selected_coupon_id, function (index, item) {
if (id == parseInt(item)) {
ind = index;
}
})
selected_coupon_id.splice(ind, 1);
var ids = selected_coupon_id;
renderCoupon(ids.toString(), memberId);
});
/**
* 保存操作
*/
var isRepeat = false;
$("body").off("click", ".modal-operation .save-btn").on("click", ".modal-operation .save-btn", function () {
var coupon_data = [], isReturn = false;
$('.coupon-modal .selected-coupon .selected').each(function () {
var num = $(this).find('.num').val();
if (!/[\S]+/.test(num)) {
layer.msg('请输入发放数量');
isReturn = true;
return false;
}
if (num % 1 != 0) {
layer.msg('发放数量格式错误');
isReturn = true;
return false;
}
if (num <= 0) {
layer.msg('发放数量不能小于等于0');
isReturn = true;
return false;
}
coupon_data.push({
coupon_type_id: $(this).attr('data-id'),
num: num
})
})
if (isReturn || isRepeat) return;
if (!coupon_data.length) {
layer.msg('请选择要发放的优惠券');
return;
}
isRepeat = true;
$.ajax({
type: "POST",
data: {
member_id: memberId,
coupon_data: JSON.stringify(coupon_data)
},
url: ns.url('coupon://shop/coupon/send'),
dataType: 'JSON',
success: function (res) {
isRepeat = false;
layer.msg(res.message);
if(res.code>=0) {
layer.close(layer_coupon);
}
}
})
});

View File

@@ -0,0 +1,406 @@
/**
* 渲染订单列表
*/
Order = function () {
};
/**
* 设置数据集
*/
Order.prototype.setData = function (data) {
Order.prototype.data = data;
};
/**
* 列名数据
*/
Order.prototype.cols = [
{
type: 'checkbox',
fixed: 'left',
width: '3%',
merge: true,
template: function (orderitem, order) {
var json = {}
json.order_id = order.order_id;
json.order_no = order.order_no;
json.full_address = order.full_address;
if(order.order_type == 4 && order.order_data_status == 3){
var h = '<div class="sub-selected-checkbox" data-json='+ JSON.stringify(json) +' data-id='+ order.order_id +' disabled>';
h += '<input type="checkbox" lay-skin="primary" lay-filter="subCheckbox" name="" disabled>';
h += '</div>';
}else{
var h = '<div class="sub-selected-checkbox" data-json='+ JSON.stringify(json) +' data-id='+ order.order_id +' >';
h += '<input type="checkbox" lay-skin="primary" lay-filter="subCheckbox" name="" >';
h += '</div>';
}
return h;
}
},
{
title: '<span>商品</span>',
width: "25%",
className: "product-info",
template: function (orderitem, order) {
var h = '<div class="img-block">';
h += '<img layer-src="' + ns.img(orderitem.sku_image,'big') + '" src="' + ns.img(orderitem.sku_image,'small') + '">';
h += '</div>';
h += '<div class="info">';
h += '<a href="' + ns.href("shop/order/detail", {order_id: orderitem.order_id}) + '" target="_blank" title="' + orderitem.sku_name + '" class="multi-line-hiding text-color-sub">'+ (orderitem.supplier_name ? '【'+ orderitem.supplier_name +'】' : '') + orderitem.sku_name + '</a>';
if(orderitem.sku_no){
h += '<span class="text-tile" title="' + orderitem.sku_no + '" >' + orderitem.sku_no + '</span>';
}
//部分发货状态显示
if(order.order_type == 1 && order.order_status == 1 && orderitem.delivery_status == 1){
h += '<span class="text-tile text-color" >已发货</span>';
}
h += '</div>';
return h;
}
},
{
title: "单价(元) / 数量",
width: "8%",
align: "right",
className: "order-price",
template: function (orderitem, order) {
var h = '<div style="padding-right: 15px;">';
h += '<div>';
h += '<span>' + orderitem.price + '</span>';
h += '</div>';
h += '<div>';
h += '<span>' + orderitem.num + '件</span>';
h += '</div>';
h += '</div>';
return h;
}
},
{
title: "维权",
width: "8%",
align: "right",
className: "order-price",
template: function (orderitem, order) {
var refund_money = (Number(orderitem.shop_active_refund_money) + Number(orderitem.refund_real_money)).toFixed(2);
var html = '';
if (orderitem.refund_status != 0) {
html += '<div><a href="' + ns.href("shop/orderrefund/detail", {order_goods_id: orderitem.order_goods_id}) + '" target="_blank" >' + orderitem.refund_status_name + '</a></div>';
if(refund_money > 0){
html += '<div style="color:red;">¥'+ refund_money +'</div>';
}
}else if(order.is_enable_refund == 1 && order.promotion_type != 'blindbox' && orderitem.shop_active_refund == 0){
html += '<div><a class="text-color" style="border:1px solid;padding:2px;" href="javascript:;" onclick="shopActiveRefund('+ orderitem.order_goods_id +')" >主动退款</a></div>';
}
return html;
}
},
{
title: "实付金额(元)",
width: "10%",
align: "right",
className: "order-money",
merge: true,
template: function (orderitem, order) {
var h = '<div style="padding-right: 15px;">';
h += '<span>' + order.real_pay_money + '</span>';
h += '</div>';
return h;
}
},
{
title: "买家/收货人",
width: "15%",
align: "left",
className: "buyers",
merge: true,
template: function (orderitem, order) {
var h = '';
h += '<p>';
h += '<a class="text-color" target="_blank" href="' + ns.href("shop/member/editmember?member_id=") + order.member_id + '">' + order.nickname + '</a>';
h += '</p>';
if (order.order_type != 4) {
if(order.order_type == 2){
h += '<p>';
h += '<span>' + order.delivery_store_name +'</span>';
h += '<span style="margin-left:22px;">' + order.mobile + '</span>';
h += '</p>';
h += '<span class="line-hiding address_box" title="' + order.full_address + ' ' + order.address + '">' + order.full_address + " " + order.address + '</span>';
h += '<input type="text" class="address_input" id="'+ order.order_id +'_address" value="'+ order.full_address +'-'+ order.address +',收货人:'+ order.name +',手机号:'+ order.mobile +'">'
h += '<a style="vertical-align: top" href="javascript:ns.copy(\''+ order.order_id +'_address\');" class="iconfont iconfuzhi"></a>'
}else{
h += '<p>';
h += '<span>' + order.name + '</span>';
h += '<span style="margin-left:22px;">' + order.mobile + '</span>';
h += '</p>';
h += '<span class="line-hiding address_box" title="' + order.full_address + ' ' + order.address + '">' + order.full_address + " " + order.address +'</span>';
h += '<input type="text" class="address_input" id="'+ order.order_id +'_address" value="'+ order.full_address +'-'+ order.address +',收货人:'+ order.name +',手机号:'+ order.mobile +'">'
h += '<a style="vertical-align: top" href="javascript:ns.copy(\''+ order.order_id +'_address\');" class="iconfont iconfuzhi"></a>'
}
} else {
h += '<p>';
h += '<span>' + order.mobile + '</span>';
h += '</p>';
}
return h;
}
},
{
title: "配送方式",
width: "9%",
align: "center",
className: "transaction-status",
merge: true,
template: function (orderitem, order) {
var html = '<div>' + order.delivery_type_name + '</div>';
if (order.store_id) html += '<div class="text-color">' + order.store_name + '</div>';
return html;
}
},
{
title: "交易状态",
width: "10%",
align: "center",
className: "transaction-status",
merge: true,
template: function (orderitem, order) {
// console.log("orderitem",order);
// if(order.order_status_name == '待支付'){
//
// }else if(order.order_status_name == '待发货'){
//
// }
var html = '<div>' + order.order_status_name + '</div>';
html += '<div>' + order.promotion_type_name;
html += order.promotion_status_name != '' ? '(' + order.promotion_status_name + ')' : '';
html += '</div>';
return html;
}
},
// {
// title : "下单时间",
// width : "10%",
// align : "center",
// className : "create-time",
// merge : true,
// template : function(orderitem,order){
// return '<div>' + ns.time_to_date(order.create_time) + '</div>';
// }
// },
// {
// title : "结算状态",
// width : "10%",
// align : "center",
// className : "settlement",
// merge : true,
// template : function(orderitem,order){
// var settlement_name = order.is_settlement == 1 ? "已结算" : "待结算";
// return '<div>'+settlement_name+'</div>';
// }
// },
{
title: "操作",
align: "right",
className: "operation",
width:"11%",
merge: true,
template: function (orderitem, order) {
var url = "shop/order/detail";
var html = '';
var action_json = order.order_status_action;
var action_arr = JSON.parse(action_json);
var action = action_arr.action;
if (action && action.length) {
html += '<div class="table-btn operation-type">';
for (var k = 0; k < action.length; k++) {
//视频号订单不能改价
if (order.is_video_number == 1) {
if (action[k].action != "orderAdjustMoney") {
html += '<a class="layui-btn text-color" href="javascript:orderAction(\'' + action[k].action + '\', ' + order.order_id + ')">' + action[k].title + '</a>';
}
} else {
html += '<a class="layui-btn text-color" href="javascript:orderAction(\'' + action[k].action + '\', ' + order.order_id + ')">' + action[k].title + '</a>';
}
}
if (order.order_type == 2 && order.order_status == 2) {
html += '<a class="layui-btn" href="javascript:storeOrderTakedelivery(' + order.order_id + ')">提货</a>';
}
html += '</div>';
}
return html;
}
}
];
/**
* 渲染表头
*/
Order.prototype.header = function (hasThead) {
var colgroup = '<colgroup>';
var thead = '';
if (hasThead) thead = '<thead><tr>';
for (var i = 0; i < this.cols.length; i++) {
var align = this.cols[i].align ? "text-align:" + this.cols[i].align : "";
colgroup += '<col width="' + this.cols[i].width + '">';
if (hasThead) {
thead += '<th style="' + align + '" class="' + (this.cols[i].className || "") + '">';
thead += '<div class="layui-table-cell">';
if(this.cols[i].type){
thead += '<div class="all-selected-checkbox">';
thead += '<input type="checkbox" lay-skin="primary" lay-filter="allCheckbox" name="">';
thead += '</div>';
}else{
thead += this.cols[i].title;
}
thead += '</div>';
thead += '</th>';
}
}
colgroup += '</colgroup>';
if (hasThead) thead += '</tr></thead>';
return colgroup + thead;
};
/**
* 渲染内容
*/
Order.prototype.tbody = function () {
var tbody = '<tbody>';
for (var i = 0; i < this.data.list.length; i++) {
var order = this.data.list[i];
var orderitemList = order.order_goods;
var pay_type_name = order.pay_type_name != '' ? order.pay_type_name : "";
var order_type = order.order_type;
if (i > 0) {
//分割行
tbody += '<tr class="separation-row">';
tbody += '<td colspan="' + this.cols.length + '"></td>';
tbody += '</tr>';
}
//订单项头部
tbody += '<tr class="header-row">';
tbody += '<td colspan="7">';
tbody += '<span class="order-item-header" style="margin-right:10px;">订单号:' + order.order_no + '</span>';
tbody += '<span class="order-item-header text-color more" style="margin-right:50px;" onclick="showMore(' + order.order_id + ')">更多';
tbody += '<div class="more-operation" data-order-id="' + order.order_id + '">';
tbody += '<span>支付流水号:' + order.out_trade_no + '</span>';
tbody += '</div></span>';
tbody += '<span class="order-item-header" style="margin-right:50px;">下单时间:' + ns.time_to_date(order.create_time) + '</span>';
tbody += '<span class="order-item-header" style="margin-right:50px;">订单来源:'+ order.order_from_name + (order.is_video_number ? '(视频号)' : '') +'</span>';
if (pay_type_name) tbody += '<span class="order-item-header">支付方式:' + pay_type_name +'</span>';
if (order_type == 2) {
tbody += '<span class="order-item-header" style="margin-left:50px;">要求自提时间:' + order.buyer_ask_delivery_time + '</span>';
}
if (order_type == 3) {
tbody += '<span class="order-item-header" style="margin-left:50px;">要求送达时间:' + order.buyer_ask_delivery_time + '</span>';
}
tbody += '</td>';
tbody += '<td colspan="2">';
tbody += '<div class="table-btn order-list-top-line" style="align:right;">';
if ([1,2,3].indexOf(parseInt(order.order_type)) != -1 && order.order_status != -1) {
tbody += '<a class="layui-btn" href="javascript:printDeliverOrder(' + order.order_id + ');" >打印发货单</a>';
}
if(printer_addon_is_exit == 1 && order.order_status != -1) {
tbody += '<a class="layui-btn" href="javascript:printTicket(' + order.order_id + ');" >打印小票</a>';
}
tbody += '<a class="layui-btn" href="' + ns.href("shop/order/detail", {order_id: order.order_id}) + '" target="_blank">详情</a>';
if (order.order_status == -1) {
tbody += '<a class="layui-btn" href="javascript:orderDelete(' + order.order_id + ');" >删除</a>';
}
tbody += '<a class="layui-btn" href="javascript:orderRemark(' + order.order_id + ');">备注</a> ';
tbody += '</div>';
tbody += '</td>';
tbody += '</tr>';
// tbody += '<tr class="separation-row"><td colspan="6"><hr /></td></tr>';
var orderitemHtml = '';
loadImgMagnify();
for (var j = 0; j < orderitemList.length; j++) {
var orderitem = orderitemList[j];
orderitemHtml += '<tr class="content-row">';
for (var k = 0; k < this.cols.length; k++) {
if (j == 0 && this.cols[k].merge && this.cols[k].template) {
orderitemHtml += '<td class="' + (this.cols[k].className || "") + '" align="' + (this.cols[k].align || "") + '" style="' + (this.cols[k].style || "") + '" rowspan="' + orderitemList.length + '">';
orderitemHtml += this.cols[k].template(orderitem, order);
orderitemHtml += '</td>';
} else if (this.cols[k].template && !this.cols[k].merge) {
orderitemHtml += '<td class="' + (this.cols[k].className || "") + '" align="' + (this.cols[k].align || "") + '" style="' + (this.cols[k].style || "") + '">';
orderitemHtml += this.cols[k].template(orderitem, order);
orderitemHtml += '</td>';
}
}
orderitemHtml += '</tr>';
}
tbody += orderitemHtml;
if (order.buyer_message != '') {
tbody += '<tr class="remark-row">';
tbody += '<td colspan="9">买家备注:' + order.buyer_message + '</td>';
tbody += '</tr>';
}
if (order.remark != '') {
tbody += '<tr class="remark-row">';
tbody += '<td colspan="9">卖家备注:' + order.remark + '</td>';
tbody += '</tr>';
}
}
tbody += '</tbody>';
return tbody;
};
/**
* 渲染表格
*/
Order.prototype.fetch = function () {
if (this.data.list.length > 0) {
return '<table class="layui-table layui-form">' + this.header(true) + '</table><table class="layui-table order-list-table layui-form">' + this.header(false) + this.tbody() + '</table>';
} else {
return '<table class="layui-table order-list-table layui-form">' + this.header(true) + '</table>' + '<div class="order-no-data-block"><ul><li><i class="layui-icon layui-icon-tabs"></i> </li><li>暂无订单</li></ul></div>';
}
};
function showMore(order_id) {
$(".more-operation[data-order-id]").hide();
$(".more-operation[data-order-id='" + order_id + "']").show();
$("body").bind('click',function (e) {
if (!$(e.target).closest(".order-item-header.more").length) {
$(".more-operation[data-order-id='" + order_id + "']").hide();
$("body").unbind('click');
}
});
}
$(".layui-colla-title").on("click", function(){
if($(".layui-colla-title>i").hasClass("layui-icon-down") === false && $(".layui-colla-title>i").hasClass("layui-icon-up") === false){
$(".layui-colla-title .put-open").html("展开");
}else if($(".layui-colla-title>i").hasClass("layui-icon-down") === true){
$(".layui-colla-title .put-open").html("展开");
}else if($(".layui-colla-title>i").hasClass("layui-icon-up") === true){
$(".layui-colla-title .put-open").html("收起");
}
})

View File

@@ -0,0 +1,331 @@
/**
* 渲染订单列表
*/
Order = function () {
};
/**
* 设置数据集
*/
Order.prototype.setData = function (data) {
Order.prototype.data = data;
};
/**
* 列名数据
*/
Order.prototype.cols = [
{
type: 'checkbox',
fixed: 'left',
width: '3%',
merge: true,
template: function (orderitem, order) {
var json = {}
json.order_id = order.order_id;
json.order_no = order.order_no;
json.full_address = order.full_address;
if(order.order_type == 4 && order.order_data_status == 3){
var h = '<div class="sub-selected-checkbox" data-json='+ JSON.stringify(json) +' data-id='+ order.order_id +' disabled>';
h += '<input type="checkbox" lay-skin="primary" lay-filter="subCheckbox" name="" disabled>';
h += '</div>';
}else{
var h = '<div class="sub-selected-checkbox" data-json='+ JSON.stringify(json) +' data-id='+ order.order_id +' >';
h += '<input type="checkbox" lay-skin="primary" lay-filter="subCheckbox" name="" >';
h += '</div>';
}
return h;
}
},
{
title: '<span>商品</span>',
width: "33%",
className: "product-info",
template: function (orderitem, order) {
var h = '<div class="img-block">';
h += '<img layer-src="' + ns.img(orderitem.sku_image,'big') + '" src="' + ns.img(orderitem.sku_image,'small') + '">';
h += '</div>';
h += '<div class="info">';
h += '<a href="' + ns.href("shop/order/detail", {order_id: orderitem.order_id}) + '" target="_blank" title="' + orderitem.sku_name + '" class="multi-line-hiding text-color-sub">' + orderitem.sku_name + '</a>';
if(orderitem.sku_no){
h += '<span class="text-tile" title="' + orderitem.sku_no + '" >' + orderitem.sku_no + '</span>';
}
h += '</div>';
return h;
}
},
{
title: "单价(元) / 数量",
width: "9%",
align: "right",
className: "order-price",
template: function (orderitem, order) {
var h = '<div style="padding-right: 15px;">';
h += '<div>';
h += '<span>' + orderitem.price + '</span>';
h += '</div>';
h += '<div>';
h += '<span>' + orderitem.num + '件</span>';
h += '</div>';
h += '</div>';
return h;
}
},
{
title: "实付金额(元)",
width: "9%",
align: "right",
className: "order-money",
merge: true,
template: function (orderitem, order) {
var h = '<div style="padding-right: 15px;">';
h += '<span>' + order.order_money + '</span>';
h += '</div>';
return h;
}
},
{
title: "提货门店",
width: "15%",
align: "left",
className: "order-money",
merge: true,
template: function (orderitem, order) {
var h = '<div>';
h += '<span>' + order.delivery_store_name + '</span>';
h += '</div>';
return h;
}
},
{
title: "买家/收货人",
width: "15%",
align: "left",
className: "buyers",
merge: true,
template: function (orderitem, order) {
var h = '';
h += '<p>';
h += '<a class="text-color" target="_blank" href="' + ns.href("shop/member/editmember?member_id=") + order.member_id + '">' + order.nickname + '</a>';
h += '</p>';
h += '<p>';
h += '<span style="margin-left:22px;">' + order.mobile + '</span>';
h += '</p>';
h += '<span class="line-hiding address_box" title="' + order.full_address + ' ' + order.address + '">' + order.full_address + " " + order.address + '</span>';
h += '<input type="text" class="address_input" id="'+ order.order_id +'_address" value="'+ order.full_address +'-'+ order.address +',收货人:'+ order.name +',手机号:'+ order.mobile +'">'
h += '<a style="vertical-align: top" href="javascript:ns.copy(\''+ order.order_id +'_address\');" class="iconfont iconfuzhi"></a>'
return h;
}
},
{
title: "操作",
align: "right",
className: "operation",
width:"11%",
merge: true,
template: function (orderitem, order) {
var html = '';
var action_json = order.order_status_action;
var action_arr = JSON.parse(action_json);
var action = action_arr.action;
html += '<div class="table-btn operation-type">';
for (var k = 0; k < action.length; k++) {
//视频号订单不能改价
if(order.is_video_number == 1){
if(action[k].action != "orderAdjustMoney"){
html += '<a class="layui-btn text-color" href="javascript:orderAction(\'' + action[k].action + '\', ' + order.order_id + ')">' + action[k].title + '</a>';
}
}else{
html += '<a class="layui-btn text-color" href="javascript:orderAction(\'' + action[k].action + '\', ' + order.order_id + ')">' + action[k].title + '</a>';
}
}
if(order.order_type == 2 && order.order_status == 2){
html += '<a class="layui-btn" href="javascript:storeOrderTakedelivery(' + order.order_id + ')">提货</a>';
}
html += '</div>';
return html;
}
}
];
/**
* 渲染表头
*/
Order.prototype.header = function (hasThead) {
var colgroup = '<colgroup>';
var thead = '';
if (hasThead) thead = '<thead><tr>';
for (var i = 0; i < this.cols.length; i++) {
var align = this.cols[i].align ? "text-align:" + this.cols[i].align : "";
colgroup += '<col width="' + this.cols[i].width + '">';
if (hasThead) {
thead += '<th style="' + align + '" class="' + (this.cols[i].className || "") + '">';
thead += '<div class="layui-table-cell">';
if(this.cols[i].type){
thead += '<div class="all-selected-checkbox">';
thead += '<input type="checkbox" lay-skin="primary" lay-filter="allCheckbox" name="">';
thead += '</div>';
}else{
thead += this.cols[i].title;
}
thead += '</div>';
thead += '</th>';
}
}
colgroup += '</colgroup>';
if (hasThead) thead += '</tr></thead>';
return colgroup + thead;
};
/**
* 渲染内容
*/
Order.prototype.tbody = function () {
var tbody = '<tbody>';
for (var i = 0; i < this.data.list.length; i++) {
var order = this.data.list[i];
var orderitemList = order.order_goods;
var pay_type_name = order.pay_type_name != '' ? order.pay_type_name : "";
var order_type = order.order_type;
if (i > 0) {
//分割行
tbody += '<tr class="separation-row">';
tbody += '<td colspan="' + this.cols.length + '"></td>';
tbody += '</tr>';
}
//订单项头部
tbody += '<tr class="header-row">';
tbody += '<td colspan="6">';
tbody += '<span class="order-item-header" style="margin-right:10px;">订单号:' + order.order_no + '</span>';
tbody += '<span class="order-item-header text-color more" style="margin-right:50px;" onclick="showMore(' + order.order_id + ')">更多';
tbody += '<div class="more-operation" data-order-id="' + order.order_id + '">';
tbody += '<span>支付流水号:' + order.out_trade_no + '</span>';
tbody += '</div></span>';
tbody += '<span class="order-item-header" style="margin-right:50px;">下单时间:' + ns.time_to_date(order.create_time) + '</span>';
tbody += '<span class="order-item-header" style="margin-right:50px;">订单来源:'+ order.order_from_name + (order.is_video_number ? '(视频号)' : '') +'</span>';
// tbody += '<span class="order-item-header" style="margin-right:50px;">订单类型:' + order.order_type_name + '</span>';
if (pay_type_name) tbody += '<span class="order-item-header">支付方式:' + pay_type_name +'</span>';
if (order_type == 2) {
tbody += '<span class="order-item-header" style="margin-left:50px;">要求自提时间:' + order.buyer_ask_delivery_time + '</span>';
}
if (order_type == 3) {
tbody += '<span class="order-item-header" style="margin-left:50px;">要求送达时间:' + order.buyer_ask_delivery_time + '</span>';
}
tbody += '</td>';
tbody += '<td>';
tbody += '<div class="table-btn order-list-top-line">';
if (order.order_type == 1 && (order.order_status == 0 || order.order_status == 1 || order.order_status == 3 || order.order_status == 4 || order.order_status == 10)) {
tbody += '<a class="layui-btn" href="javascript:printDeliverOrder(' + order.order_id + ');" >打印发货单</a>';
// tbody += '<a href="'+ ns.href('shop/order/printOrder',{order_id:order.order_id}) +'" target="_blank" class="layui-btn">打印发货单</a>';
}
if(printer_addon_is_exit == 1 && [1,2,3].indexOf(parseInt(order.order_type)) != -1 && [1,2,3,10].indexOf(parseInt(order.order_status)) != -1) {
tbody += '<a class="layui-btn" href="javascript:printTicket(' + order.order_id + ');" >打印小票</a>';
}
if (order.order_status == 0) {
tbody += '<a class="layui-btn" href="javascript:offlinePay(' + order.order_id + ');">线下支付</a> ';
}
tbody += '<a class="layui-btn" href="' + ns.href("shop/order/detail", {order_id: order.order_id}) + '" target="_blank">详情</a>';
if (order.order_status == -1) {
tbody += '<a class="layui-btn" href="javascript:orderDelete(' + order.order_id + ');" >删除</a>';
}
tbody += '<a class="layui-btn" href="javascript:orderRemark(' + order.order_id + ');">备注</a> ';
tbody += '</div>';
tbody += '</td>';
tbody += '</tr>';
// tbody += '<tr class="separation-row"><td colspan="6"><hr /></td></tr>';
var orderitemHtml = '';
loadImgMagnify();
for (var j = 0; j < orderitemList.length; j++) {
var orderitem = orderitemList[j];
orderitemHtml += '<tr class="content-row">';
for (var k = 0; k < this.cols.length; k++) {
if (j == 0 && this.cols[k].merge && this.cols[k].template) {
orderitemHtml += '<td class="' + (this.cols[k].className || "") + '" align="' + (this.cols[k].align || "") + '" style="' + (this.cols[k].style || "") + '" rowspan="' + orderitemList.length + '">';
orderitemHtml += this.cols[k].template(orderitem, order);
orderitemHtml += '</td>';
} else if (this.cols[k].template && !this.cols[k].merge) {
orderitemHtml += '<td class="' + (this.cols[k].className || "") + '" align="' + (this.cols[k].align || "") + '" style="' + (this.cols[k].style || "") + '">';
orderitemHtml += this.cols[k].template(orderitem, order);
orderitemHtml += '</td>';
}
}
orderitemHtml += '</tr>';
}
tbody += orderitemHtml;
if(order.buyer_message != '') {
//订单项底部
tbody += '<tr class="bottom-row">';
tbody += '<td colspan="6">';
tbody += '<span class="order-item-header" style="margin-right:10px;">买家备注:' + order.buyer_message + '</span>';
tbody += '</td>';
tbody += '</tr>';
}
if (order.remark != '') {
tbody += '<tr class="remark-row">';
tbody += '<td colspan="' + this.cols.length + '">卖家备注:' + order.remark + '</td>';
tbody += '</tr>';
}
}
tbody += '</tbody>';
return tbody;
};
/**
* 渲染表格
*/
Order.prototype.fetch = function () {
if (this.data.list.length > 0) {
return '<table class="layui-table layui-form">' + this.header(true) + '</table><table class="layui-table order-list-table layui-form">' + this.header(false) + this.tbody() + '</table>';
} else {
return '<table class="layui-table order-list-table layui-form">' + this.header(true) + '</table>' + '<div class="order-no-data-block"><ul><li><i class="layui-icon layui-icon-tabs"></i> </li><li>暂无订单</li></ul></div>';
}
};
function showMore(order_id) {
$(".more-operation[data-order-id]").hide();
$(".more-operation[data-order-id='" + order_id + "']").show();
$("body").bind('click',function (e) {
if (!$(e.target).closest(".order-item-header.more").length) {
$(".more-operation[data-order-id='" + order_id + "']").hide();
$("body").unbind('click');
}
});
}
$(".layui-colla-title").on("click", function(){
if($(".layui-colla-title>i").hasClass("layui-icon-down") === false && $(".layui-colla-title>i").hasClass("layui-icon-up") === false){
$(".layui-colla-title .put-open").html("展开");
}else if($(".layui-colla-title>i").hasClass("layui-icon-down") === true){
$(".layui-colla-title .put-open").html("展开");
}else if($(".layui-colla-title>i").hasClass("layui-icon-up") === true){
$(".layui-colla-title .put-open").html("收起");
}
})

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,246 @@
var map;
/**
* 创建地图
* @param id
* @param lnglat
* @returns {Promise<void>}
*/
async function createMap(id, lnglat) {
var center;
if(lnglat["lat"] != ''|| lnglat["lng"] != '' ){
center = new TMap.LatLng(lnglat.lat,lnglat.lng);
} else {
await getCurrentPosition(function(res){
if (res.status == 0) {
var location = res.result.location;
center = new TMap.LatLng(location.lat, location.lng);
}
})
}
map = new TMap.Map(document.getElementById(id), {
center: center,//设置地图中心点坐标
zoom: 17 //设置地图缩放级别
});
}
var editor_array = {};
/**
* 创建一个圆, 并且给与编辑权限
*/
function createCircle(key, color, border_color, path_param){
if(path_param == undefined){
var center = map.getCenter(); //获取当前地图中心位置
var radius = 1000;
}else{
var center = new TMap.LatLng(path_param.center.latitude, path_param.center.longitude)
var radius = path_param.radius;
}
var multiCircle = new TMap.MultiCircle({
map: map,
styles: { // 设置圆形样式
'circle': new TMap.CircleStyle({
'color': set16ToRgba(color, 0.4),
'showBorder': true,
'borderColor': border_color,
'borderWidth': 2
}),
},
geometries: [
{
styleId: 'circle',
center: center,
radius: radius,
id: key
}
]
});
var circle = new TMap.tools.GeometryEditor({
map: map,
overlayList: [
{
overlay: multiCircle,
id: key,
}
],
actionMode: TMap.tools.constants.EDITOR_ACTION.INTERACT,
activeOverlayId: key, // 激活图层
selectable: true, // 开启点选功能
})
// 缩放地图
map.easeTo({zoom: 14 })
circle.select([key]);
editor_array[key] = circle;
// 初始化数据
editor_array[key].data = {
center: center,
radius: radius
}
circle.on('adjust_complete', function (data) {
editor_array[key].data = data;
})
}
/**
* 创建多边形
* @param key
* @param color
* @param border_color
* @param path_param
*/
function createPolygon(key, color, border_color, path_param){
var center = map.getCenter();
var lat = center.lat;
var lng = center.lng;
if(path_param == undefined){
var path = [
new TMap.LatLng(lat+0.01, lng+0.01),
new TMap.LatLng(lat-0.01, lng+0.01),
new TMap.LatLng(lat-0.01, lng-0.01),
new TMap.LatLng(lat+0.01, lng-0.01),
]
}else{
var path = []
$.each(path_param, function(i, item){
path.push(new TMap.LatLng(item.latitude, item.longitude));
});
}
var multiPolygon = new TMap.MultiPolygon({
map: map,
styles: {
polygon: new TMap.PolygonStyle({
'color': set16ToRgba(color, 0.4),
'showBorder': true,
'borderColor': border_color,
'borderWidth': 2
})
},
geometries: [
{
id: key, // 多边形图形数据的标志信息
styleId: 'polygon', // 样式id
paths: path, // 多边形的位置信息
properties: {
// 多边形的属性数据
title: 'polygon',
},
}
]
});
var polygon = new TMap.tools.GeometryEditor({
map: map,
overlayList: [
{
overlay: multiPolygon,
id: key,
}
],
actionMode: TMap.tools.constants.EDITOR_ACTION.INTERACT,
activeOverlayId: key, // 激活图层
selectable: true, // 开启点选功能
})
// 缩放地图
map.easeTo({zoom: 14 })
polygon.select([key]);
editor_array[key] = polygon;
// 初始化数据
editor_array[key].data = {
paths: path
};
polygon.on('adjust_complete', function (data) {
editor_array[key].data = data;
})
}
/**
* 移除覆盖物
* @param key
*/
function removeOverlayers(key){
var editor = editor_array[key];
editor.delete();//删除覆盖物
}
/**
* 给与覆盖物焦点
*/
function foursOverlayers(key){
}
/**
* 获取覆盖物实例
* @param key
* @returns {*}
*/
function getOverlayersPath(key, type){
var editor = editor_array[key];
switch(type){
//多边形
case 'polygon':{
var return_json = [];
editor.data.paths.forEach(function (item) {
var item_json = {longitude:item.lng,latitude:item.lat};
return_json.push(item_json);
})
return return_json;
break;
}
//圆
case 'circle':{
var return_json = {};
var center = editor.data.center;
return_json['center'] = {longitude:center.lng,latitude:center.lat};
return_json['radius'] = editor.data.radius;
return return_json;
break;
}
}
}
/**
* 获取定位
* @param callback
*/
async function getCurrentPosition(callback){
var ipLocation = new TMap.service.IPLocation();
await ipLocation.locate({}).then(function(res){
callback(res)
})
}
/**
* 16进制转rgba
* @param str
* @param opacity
* @returns {string}
*/
function set16ToRgba(str, opacity){
var reg = /^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/
if(!reg.test(str)){return;}
var newStr = (str.toLowerCase()).replace(/\#/g,'')
var len = newStr.length;
if(len == 3){
var t = ''
for(var i=0;i<len;i++){
t += newStr.slice(i,i+1).concat(newStr.slice(i,i+1))
}
newStr = t
}
var arr = []; //将字符串分隔,两个两个的分隔
for(var i =0;i<6;i=i+2){
var s = newStr.slice(i,i+2)
arr.push(parseInt("0x" + s))
}
return 'rgba(' + arr.join(",") + ', '+ opacity +')';
}

View File

@@ -0,0 +1,199 @@
/**
* 渲染订单列表
*/
Order = function(){};
/**
* 设置数据集
*/
Order.prototype.setData = function(data){
Order.prototype.data = data;
};
/**
* 列名数据
*/
Order.prototype.cols = [
{
title : '<span style="margin-left:10px;">商品信息</span>',
width : "38%",
className : "product-info",
template : function(item){
var h = '<div class="img-block" >';
h += '<img layer-src="'+ ns.img(item.sku_image,'big') +'" src="'+ ns.img(item.sku_image,'small') +'">';
h += '</div>';
h += '<div class="info">';
// h += '<a href="javascript:void(0);" target="_blank">' + item.sku_name + '</a>';
h += '<a href="javascript:void(0);" title="' + item.sku_name + '">' + item.sku_name + '</a>';
h += '</div>';
return h;
}
},
{
title : "订单金额",
width : "10%",
align : "right",
className : "order-money",
template : function(item){
var h = '<div style="padding-right: 15px;">';
h += '<span>¥' + item.real_goods_money + '</span>';
h += '</div>';
return h;
}
},
{
title : "买家",
width : "10%",
align : "right",
className : "order-money",
template : function(item){
var h = '<div style="padding-right: 15px;">';
if(item.member_id)
h += '<a class="text-color" target="_blank" href="' + ns.href("shop/member/editmember?member_id=") + item.member_id + '">' + item.nickname + '</a>';
else
h += '<span>散客</span>';
h += '</div>';
return h;
}
},
{
title : "退款金额",
width : "8%",
align : "right",
className : "refund-money",
template : function(item){
var h = '<div style="padding-right: 15px;">';
h += '<span>¥' + (Number(item.refund_status == 3 ? item.refund_real_money : item.refund_apply_money)+Number(item.shop_active_refund_money)).toFixed(2) + '</span>';
h += '</div>';
return h;
}
},
{
title : "操作时间",
width : "13%",
align : "center",
className : "apply-time",
merge : true,
template : function(item){
return '<div title="'+ ns.time_to_date(item.refund_action_time) +'">' + ns.time_to_date(item.refund_action_time) + '</div>';
}
},
{
title : "退款状态",
width : "13%",
align : "center",
className : "refund-status",
merge : true,
template : function(item){
var refund_type_name = "";
if(item.refund_type == 1){
refund_type_name = "仅退款";
}else{
refund_type_name = "退款退货";
}
return '<div>' + item.refund_status_name + '('+ refund_type_name +')</div>';
}
},
{
title : "操作",
width : "8%",
align : "right",
className : "operation",
merge : true,
template : function(item){
var html = '';
html += '<div class="table-btn operation-type">';
html += '<a class="layui-btn" href="'+ ns.href("shop/orderrefund/detail",{order_goods_id:item.order_goods_id})+'" target="_blank">详情</a>';
html += '</div>';
return html;
}
}
];
/**
* 渲染表头
*/
Order.prototype.header = function(){
var colgroup = '<colgroup>';
var thead = '<thead><tr>';
for(var i=0;i<this.cols.length;i++){
var align = this.cols[i].align ? "text-align:" + this.cols[i].align : "";
colgroup += '<col width="' + this.cols[i].width + '">';
thead += '<th style="' + align + '" class="' + (this.cols[i].className || "") + '">';
thead += '<div class="layui-table-cell">' + this.cols[i].title + '</div>';
thead += '</th>';
}
colgroup += '</colgroup>';
thead += '</tr></thead>';
return colgroup + thead;
};
/**
* 渲染内容
*/
Order.prototype.tbody = function(){
var tbody = '<tbody>';
for(var i=0;i<this.data.list.length;i++){
var item = this.data.list[i];
//分割行
tbody += '<tr class="separation-row">';
tbody += '<td colspan="' + this.cols.length + '"></td>';
tbody += '</tr>';
// tbody += '<tr class="separation-row"><td colspan="7"><hr /></td></tr>';
tbody += '<tr class="header-row">';
tbody += '<td colspan="7">';
tbody += '<span class="order-item-header" style="margin-right:50px;">退款编号:' + item.refund_no + '</span>';
tbody += '<a class="order-item-header text-color" style="margin-right:50px;" target="_blank" href="' + ns.href("shop/order/lists?order_label=order_no&page=1&search=") + item.order_no + '">订单编号:' + item.order_no + '</a>';
// tbody += '<span class="order-item-header" style="display: inline-block;height: 23px;padding: 0 8px 0 0; margin: 5px 0 5px 5px;">订单状态:' + item.delivery_status_name + '</span>';
tbody += '</td>';
tbody += '</tr>';
var orderitemHtml = '';
loadImgMagnify();
// for(var j=0;j<orderitemList.length;j++){
//
// var orderitem = orderitemList[j];
orderitemHtml += '<tr class="content-row">';
for(var k=0;k<this.cols.length;k++){
//
// if(j == 0 && this.cols[k].merge && this.cols[k].template){
//
// orderitemHtml += '<td class="' + (this.cols[k].className || "") + '" align="' + (this.cols[k].align || "") + '" style="border-right-width: 1px;' + (this.cols[k].style || "") + '" rowspan="' + orderitemList.length + '">';
// orderitemHtml += this.cols[k].template(orderitem,order);
// orderitemHtml += '</td>';
//
// }else if(this.cols[k].template && !this.cols[k].merge){
orderitemHtml += '<td class="' + (this.cols[k].className || "") + '" align="' + (this.cols[k].align || "") + '" style="' + (this.cols[k].style || "") + '">';
orderitemHtml += this.cols[k].template(item);
orderitemHtml += '</td>';
// }
}
orderitemHtml += '</tr>';
// }
tbody += orderitemHtml;
}
tbody += '</tbody>';
return tbody;
};
/**
* 渲染表格
*/
Order.prototype.fetch = function(){
if(this.data.list.length > 0){
return '<table class="layui-table order-list-table layui-form">' + this.header() + this.tbody() + '</table>';
}else{
return '<table class="layui-table order-list-table layui-form">' + this.header() + '</table>'+'<div class="order-no-data-block"><ul><li><i class="layui-icon layui-icon-tabs"></i> </li><li>暂无数据</li></ul></div>';
}
};

483
app/shop/view/public/js/route.js Executable file
View File

@@ -0,0 +1,483 @@
window.yuanMenu = []; // 原菜单数据
window.baseMenu = []; // 处理后的菜单
window.firstMenu = []; // 一级菜单
window.secondMenu = []; // 二级菜单
window.forthMenu = []; // 四级菜单
window.crumbs = []; // 面包屑
window.crumbsName = []; // 面包屑
window.currentMenu = {}; // 当前菜单
window.quickAddonMenu = {}; // 营销活动快捷方式才是
window.isRefreshSecondMenu = false; // 是否刷新二级菜单
// layui对象
window.form = null;
window.laytpl = null;
window.element = null;
function getMenuList() {
$.ajax({
url: ns.url("shop/index/menu"),
dataType: 'JSON',
type: 'POST',
data: {
app_module: ns_url.appModule
},
success: function (data) {
window.userIsAdmin = data.user_is_admin;
window.yuanMenu = data.yuan_menu;
window.quickAddonMenu = data.quick_addon_menu;
loadMenu(getRoute().url)
}
});
}
/**
* 加载菜单
* @param url 页面路径
*/
function loadMenu(url) {
if (window.yuanMenu && window.yuanMenu.length == 0) return;
url = url.toLowerCase();
window.baseMenu = []; // 原菜单
window.firstMenu = []; // 一级菜单
window.secondMenu = []; // 二级菜单
window.forthMenu = []; // 四级菜单
window.crumbs = []; // 面包屑
window.crumbsName = []; // 面包屑
window.currentMenu = {}; // 当前菜单
var current = window.yuanMenu.filter(function (item) {
if (item.url.toLowerCase() == url) {
return item;
}
});
current.sort((a, b) => {
return b.level - a.level
});
window.currentMenu = current[0];
if (window.currentMenu) {
// 菜单树结构,面包屑
getMenuTree(window.currentMenu.name);
window.crumbs.sort((a, b) => {
return a.level - b.level;
});
}
window.baseMenu = initMenu(window.yuanMenu, '');
// 四级菜单
initForthMenu();
renderMenu();
}
// 渲染菜单
function renderMenu() {
// 渲染一级菜单
var html = '';
window.baseMenu.forEach(function (item, index) {
html += '<li class="layui-nav-item">';
html += `<a ${item.selected ? 'class="active"' : ''} href="${ns.href(item.url)}" data-menu-level="${item.level}" ${item.name == 'CASHIER' ? 'target="_blank"' : ''}>`;
html += `<i class="iconfont ${item.icon}"></i>`;
html += `<span>${item.title}</span>`;
html += `</a>`;
html += `</li>`;
if (item.selected) {
window.secondMenu = item.child_list;
window.firstMenu = item;
}
});
// 加载一级菜单
$('.menu-first-wrap').html(html);
// 顶部面包屑
$('.layui-header-crumbs-first span').text(window.firstMenu.title);
// 删除四级菜单
$('.forth-menu-wrap').remove();
// 加载二、三、四级菜单
if (window.secondMenu.length) {
// 处理营销活动菜单
if (window.crumbs.length && window.crumbs[0]['name'] == 'PROMOTION_ROOT') {
// 加载快捷方式的插件菜单
window.secondMenu.forEach(function (item, index) {
if (item.name == 'PROMOTION_CENTER') {
handlePromotionMenu(index, 'promotion');
} else if (item.name == 'PROMOTION_TOOL') {
handlePromotionMenu(index, 'tool');
}
});
}
var secondHtml = '';
window.secondMenu.forEach(function (item, index) {
var childList = item.child_list;
var childLength = childList.length;
secondHtml += `<li class="layui-nav-item layui-nav-itemed ${item.selected ? 'layui-this' : ''}">`;
secondHtml += `<a href="${childLength ? 'javascript:;' : ns.href(item.url)}" data-menu-level="${item.level}" class="layui-menu-tips ${childLength == 0 && item.selected ? 'second-selected-nav' : ''}">`;
secondHtml += `<span>${item.title}</span>`;
secondHtml += `</a>`;
// 加载三级菜单
if (childLength) {
secondHtml += `<dl class="layui-nav-child">`;
childList.forEach(function (third, thirdIndex) {
secondHtml += `<dd class="${third.selected ? 'layui-this' : ''}">`;
secondHtml += `<a href="${ns.href(third.url)}" data-menu-level="${third.level}" class="layui-menu-tips">`;
secondHtml += `<span class="layui-left-nav">${third.title}</span>`;
secondHtml += `</a>`;
secondHtml += `</dd>`;
});
secondHtml += `</dl>`;
}
secondHtml += `</li>`;
});
$('.second-nav .layui-nav-tree').html(secondHtml);
// 加载四级菜单
if (window.forthMenu.length) {
var forthMenuHtml = '';
forthMenuHtml += `<div class="fourstage-nav layui-tab layui-tab-brief forth-menu-wrap">`;
forthMenuHtml += `<ul class="layui-tab-title">`;
window.forthMenu.forEach(function (item, index) {
var query = getRoute().query;
var arr = [];
var href = item.url;
for (var key in query) {
arr.push(`${key}=${query[key]}`)
}
if (arr.length) {
href += `?${arr.join('&')}`;
}
forthMenuHtml += `<li class="${item.selected ? 'layui-this' : ''}">`;
forthMenuHtml += `<a href="${ns.href(href)}" data-menu-level="${item.level}">${item.title}</a>`;
forthMenuHtml += `</li>`;
});
forthMenuHtml += `</ul>`;
forthMenuHtml += `</div>`;
$('.body-wrap.layui-body').prepend(forthMenuHtml)
}
var crumbHtml = '';
window.crumbs.forEach(function (item, index) {
if (index > 0) {
crumbHtml += `<a href="${(index == window.crumbs.length - 1) ? 'javascript:;' : ns.href(item.url)}" data-menu-level="${item.level}">${item.title}</a>`;
}
});
$('.layui-header-crumbs-second .layui-breadcrumb').html(crumbHtml);
$('.layui-header-crumbs-second').show();
$('.body-wrap').css({
left: '256px',
visibility:'visible'
});
$('.second-nav').show();
} else {
$('.second-nav').hide();
$('.layui-header-crumbs-second').hide();
$('.body-wrap').css({
left: '124px',
visibility:'visible'
});
}
// 如果二级菜单发生了变化,滚动位置要回到顶部
if (window.isRefreshSecondMenu) $('.second-nav .layui-side-scroll').scrollTop(0);
// 切换功能,内容区域,滚动位置要回到顶部
$('.layui-layout-admin .layui-body').scrollTop(0);
if (window.crumbs.length) document.title = window.crumbs[window.crumbs.length - 1].title + ' - ' + window.ns_url.siteName;
window.element.render('breadcrumb');
window.element.init();
}
// a标签跳转点击事件
$('.layui-side').on('click', 'a', (function () {
var href = $(this).attr('href'); // 跳转链接
var target = $(this).attr('target');
var level = $(this).attr('data-menu-level'); // 菜单等级,滚动定位
var url = ''; // 页面地址
var hash = '';
// 拦截空链接
if (!href) return;
// 外链地址无须处理
if (href.indexOf(ns_url.baseUrl) == -1) return;
// 打开新窗口
if (target == '_blank') {
window.open(href);
return false;
}
// 退出登录
if (href.indexOf('shop/login/logout') != -1) {
return;
}
var arr = href.split('#');
// 网址无参数时进入概况页面
if (arr.length == 1) {
url = 'shop/index/index';
hash = 'url=' + url;
} else {
hash = arr[1];
// 找到当前页面地址
var query = hash.split('&');
for (var i = 0; i < query.length; i++) {
if (query[i].indexOf('url=') != -1) {
url = query[i].replace('url=', '');
break;
}
}
}
window.isRefreshSecondMenu = level == 1;
loadMenu(url);
location.hash = hash;
return false;
}));
window.onhashchange = function (event) {
var oldUrl = searchUrl(event.oldURL);
var newUrl = searchUrl(event.newURL);
// 页面相同,只是表单筛选条件搜索,则不刷新页面
if (oldUrl == newUrl && localStorage.getItem('formSubmit') == 'search') {
// 表单搜索完成后清空
localStorage.removeItem('formSubmit'); // 表单搜索标识
return;
}
listenerHash();
};
// 监听回退键事件
window.addEventListener('popstate', function() {
// 关闭弹框
layer.closeAll();
});
// 获取哈希值数组
function getHashArr() {
var hash = ns.urlReplace(location.hash);
return hash.substr(1).split("&"); // 移除#
}
// 监听hash值变化加载页面
function listenerHash(isLoadMenu = true) {
var params = getRoute();
//有的客户会出现同一个链接,直接页面访问 和 ajax访问 无法区分的情况,特此做区分
params.query._type = 'html';
var url = params.url;
// 加载页面前,显示加载动画进行过渡
var html = '<div class="common-loading-wrap">';
html += '<i class="common-loading-layer layui-icon layui-icon-loading layui-anim layui-anim-rotate layui-anim-loop"></i>';
html += '</div>';
$('.layui-layout-admin .layui-body .body-content').html(html);
// 切换页面,删除弹框、依赖
$('.el-popper').remove();
$('.colorpicker-layer').remove();
$('.layui-layer-shade').remove();
$('.layui-layer-move').remove();
$('#edui_fixedlayer').remove();
$('.global-zeroclipboard-container').remove();
$('.layui-layer-page').remove();
var beforeUrl = ns.url(url); // 请求前的页面地址
$.ajax({
url: beforeUrl,
data: params.query,
dataType: 'html',
type: 'get',
success: function (html) {
try {
var res = JSON.parse(html);
if (res.code == -1) {
// 权限不足
location.hash = 'url=' + res.data.url;
return;
}
} catch (e) {
}
var afterUrl = ns.url(getRoute().url); // 请求后的的页面地址
// 渲染页面时,检测当前打开页面和请求的是否一致
if (beforeUrl == afterUrl) {
$('.layui-layout-admin .layui-body .body-content').html(html).css('visibility','hidden');
setTimeout(function () {
$('.layui-layout-admin .layui-body .body-content').css('visibility','visible');
window.form.render();
tipsShow();
loadImgMagnify();
}, 20);
// 是否加载菜单
if (html !== '权限不足,请联系管理员' && isLoadMenu) {
loadMenu(url);
}
}
}
});
}
// 找到当前页面路径
function searchUrl(url) {
var result = '';
var arr = url.split('#');
if (arr.length > 1) {
var hash = arr[1];
var hash_arr = hash.split('&');
for (var i = 0; i < hash_arr.length; i++) {
var hash_data = hash_arr[i].split('=');
if(hash_data[0] == 'url'){
result = hash_data[1];
break;
}
}
}
return result;
}
function initMenu(menus_list, parent) {
var temp_list = [];
if (menus_list.length) {
menus_list.forEach(function (item, index) {
if (crumbsName.indexOf(item.name) != -1) {
item.selected = true;
} else {
item.selected = false;
}
if (item["parent"] == parent && item["is_show"] == 1 && item['type'] == 'page') {
var temp_item = {
'name': item['name'],
'level': item['level'],
'addon': item['addon'],
'selected': item.selected,
'url': item['url'],
'title': item['title'],
'icon': item['picture'],
'icon_selected': item['picture_select'],
'target': '',
'parent': item['parent'],
'sort': item['sort']
};
temp_item["child_list"] = initMenu(menus_list, item["name"]);//获取下级的菜单
if(!userIsAdmin && temp_item["child_list"].length > 0){
temp_item['url'] = temp_item["child_list"][0]['url'];
}
temp_list.push(temp_item);
}
})
}
return temp_list;
}
/**
* 生成菜单树结构,面包屑
* @param name
*/
function getMenuTree(name) {
if (name) {
var menu = window.yuanMenu.filter(function (item) {
if (item.name == name) {
return item;
}
});
window.crumbs.push(menu[0]); // name 是唯一的,所以数组只有一项
window.crumbsName.push(menu[0].name);
getMenuTree(menu[0].parent);
}
}
function initForthMenu() {
if (window.crumbs.length == 0) return;
var child = window.crumbs[window.crumbs.length - 1];
if (child.is_show == 0) return;
// 如果当前菜单是隐藏的,那就不显示
var menu = window.yuanMenu.filter(function (item) {
if (item.parent == child.parent && item.is_show == 1 && item.level > 3) {
return item;
}
});
menu.forEach(function (item) {
item.selected = (item.name == child.name);
});
window.forthMenu = menu;
}
// 处理营销活动菜单
function handlePromotionMenu(index, key) {
var emptyAddon = []; // 保留营销活动主菜单
var promotionAddon = []; // 快捷方式中的有效插件菜单
var currentAddon = []; // 当前选中插件菜单,不在快捷方式中,要展示出来
var addon = window.crumbs[window.crumbs.length - 1].addon;
window.secondMenu[index].child_list.forEach(function (menuItem, menuIndex) {
if (menuItem.addon == '') {
emptyAddon.push(menuItem);
} else if (menuItem.addon) {
if (window.quickAddonMenu[key].indexOf(menuItem.addon) != -1) {
promotionAddon.push(menuItem);
} else if (addon && addon == menuItem.addon && window.quickAddonMenu[key].indexOf(addon) == -1) {
currentAddon.push(menuItem);
}
}
});
window.secondMenu[index].child_list = emptyAddon;
if (currentAddon.length) window.secondMenu[index].child_list = window.secondMenu[index].child_list.concat(currentAddon);
if (promotionAddon.length) window.secondMenu[index].child_list = window.secondMenu[index].child_list.concat(promotionAddon);
}
layui.use(['form', 'laytpl', 'element'], function () {
window.form = layui.form;
window.element = layui.element;
window.laytpl = layui.laytpl;
getMenuList();
listenerHash(false);
});

208
app/shop/view/public/js/tree.js Executable file
View File

@@ -0,0 +1,208 @@
var form;
//权限列表目标标记
var tree_target = [];
var total_level = 5;//权限总级别
//背景颜色配置
var bg_arr = ['#FFF', '#FFF', '#FFF', '#FFF'];
layui.use(['form'], function () {
form = layui.form;
form.render();
form.on('checkbox(group_form)', function(data){
var checked = $(this).prop('checked');
var target = $(this).attr('data-target');
target = target.split(',');
var curr_data = find_data_by_target(tree_data, target);
curr_data['checked'] = checked;
down_alter(curr_data['child_list'], checked);
up_alter(tree_data, target);
$("#tree_box").html(createTable(tree_data));
form.render();
});
//初始化
initTreeBox();
});
function initTreeBox(){
$("#tree_box").html(createTable(tree_data));
form.render();
}
function createTable(data){
var html = "<table class='layui-table'>";
var compile_tree_result = compile_tree(data, 0, '');
html += '<tr>'+compile_tree_result.first_html+'</tr>';
html += compile_tree_result.last_html;
html += "</table>";
return html;
}
//编译树
function compile_tree(data, level, html) {
var child_num_arr = [];
var rowspan_num = 0;
var total_child_num = 0;
var total_num = 0;
var html_obj = [];
var first_html = "";
var last_html = "";
$.each(data,function(i,data_item){
var child_num = data_item['child_num'];
child_num_arr.push(child_num);
total_num += 1;
total_child_num += child_num;
var checked = data_item['checked'];
html_obj.push({checked:checked,child_num:child_num,data:data_item,name:data_item.name});
})
if(total_num > 0){
if(total_child_num > 0){
var is_first = true;
$.each(html_obj,function(i,item){
var item_obj = item.data;
var item_html = "";
var rowspan = 0;
var name = item['name'];
tree_target[level] = name;
tree_target = tree_target.slice(0, level + 1);
var checked_html = item.checked ? 'checked' : '';
var input_html = '<input class="group-checkbox" type="checkbox" ' + checked_html + ' lay-filter="group_form" lay-skin="primary" '+ checked_html +' title="'+item['data']['title']+'" data-target="' + tree_target.toString() + '" value="' + name + '"/>';
var child_num = item.child_num;
var colspan_html = "";
var child_first_html = "";
var child_last_html = "";
if (child_num > 0){
var item_result = compile_tree(item_obj['child_list'], level + 1, '');
var rowspan = item_result.rowspan;
var child_first_html = item_result.first_html;
var child_last_html = item_result.last_html;
}
if(child_first_html == '' ){
var colspan_num = total_level - level;
colspan_html = " colspan="+colspan_num;
}
if(!is_first){
item_html += '<tr>';
}
if(rowspan > 1){
rowspan_num = rowspan_num + rowspan;
item_html += '<td rowspan = "'+rowspan+'" '+colspan_html+' >';
}else{
rowspan_num += 1;
item_html += '<td '+colspan_html+'>';
}
item_html += input_html;
item_html += '</td>';
item_html += child_first_html;
if(!is_first) {
item_html += '</tr>';
}
item_html += child_last_html;
if(is_first){
first_html += item_html;
is_first = false;
}else{
last_html += item_html;
}
})
}else{
var colspan_num = total_level - level;
var colspan_html = " colspan="+colspan_num;
first_html += '<td '+colspan_html+' >';
rowspan_num = 1;
$.each(html_obj,function(i,item){
var name = item['name'];
tree_target[level] = name;
tree_target = tree_target.slice(0, level + 1);
var checked_html = item.checked ? 'checked' : '';
var input_html = '<input class="group-checkbox" type="checkbox" ' + checked_html + ' lay-filter="group_form" lay-skin="primary" '+ checked_html +' title="'+item['data']['title']+'" data-target="' + tree_target.toString() + '" value="' + name + '"/>';
first_html += input_html;
})
first_html += '</td>';
}
}
return {rowspan:rowspan_num,first_html:first_html,last_html:last_html};
}
//通过标记找到数据位置
function find_data_by_target(list, target) {
var data = list;
for (var per in target) {
if (per == 0) {
data = data[target[per]];
} else {
data = data['child_list'][target[per]];
}
}
return data;
}
//向上遍历
function up_alter(list, target) {
target = target.slice(0, target.length - 1);
if (target.length == 0) return;
var curr_data = find_data_by_target(tree_data, target);
var count = 0;
for (var per in curr_data['child_list']) {
if (curr_data['child_list'][per]['checked']) {
count++;
break;
}
}
if (count == 0) {
curr_data['checked'] = false;
} else {
curr_data['checked'] = true;
}
up_alter(list, target);
}
//向下遍历
function down_alter(list, checked) {
for (var per in list) {
list[per]['checked'] = checked;
if (list[per]['child_num'] > 0) down_alter(list[per]['child_list'], checked)
}
}
//绑定点击事件
$("#tree_box").on('click', '.menu-cell input', function () {
var checked = $(this).prop('checked');
var target = $(this).attr('data-target');
target = target.split(',');
var curr_data = find_data_by_target(tree_data, target);
curr_data['checked'] = checked;
down_alter(curr_data['child_list'], checked);
up_alter(tree_data, target);
$("#tree_box").html(createTable(tree_data));
form.render();
});

View File

@@ -0,0 +1,924 @@
// Copyright 2006 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Known Issues:
//
// * Patterns are not implemented.
// * Radial gradient are not implemented. The VML version of these look very
// different from the canvas one.
// * Clipping paths are not implemented.
// * Coordsize. The width and height attribute have higher priority than the
// width and height style values which isn't correct.
// * Painting mode isn't implemented.
// * Canvas width/height should is using content-box by default. IE in
// Quirks mode will draw the canvas using border-box. Either change your
// doctype to HTML5
// (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype)
// or use Box Sizing Behavior from WebFX
// (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html)
// * Non uniform scaling does not correctly scale strokes.
// * Optimize. There is always room for speed improvements.
// Only add this code if we do not already have a canvas implementation
if (!document.createElement('canvas').getContext) {
(function() {
// alias some functions to make (compiled) code shorter
var m = Math;
var mr = m.round;
var ms = m.sin;
var mc = m.cos;
var abs = m.abs;
var sqrt = m.sqrt;
// this is used for sub pixel precision
var Z = 10;
var Z2 = Z / 2;
/**
* This funtion is assigned to the <canvas> elements as element.getContext().
* @this {HTMLElement}
* @return {CanvasRenderingContext2D_}
*/
function getContext() {
return this.context_ ||
(this.context_ = new CanvasRenderingContext2D_(this));
}
var slice = Array.prototype.slice;
/**
* Binds a function to an object. The returned function will always use the
* passed in {@code obj} as {@code this}.
*
* Example:
*
* g = bind(f, obj, a, b)
* g(c, d) // will do f.call(obj, a, b, c, d)
*
* @param {Function} f The function to bind the object to
* @param {Object} obj The object that should act as this when the function
* is called
* @param {*} var_args Rest arguments that will be used as the initial
* arguments when the function is called
* @return {Function} A new function that has bound this
*/
function bind(f, obj, var_args) {
var a = slice.call(arguments, 2);
return function() {
return f.apply(obj, a.concat(slice.call(arguments)));
};
}
var G_vmlCanvasManager_ = {
init: function(opt_doc) {
if (/MSIE/.test(navigator.userAgent) && !window.opera) {
var doc = opt_doc || document;
// Create a dummy element so that IE will allow canvas elements to be
// recognized.
doc.createElement('canvas');
doc.attachEvent('onreadystatechange', bind(this.init_, this, doc));
}
},
init_: function(doc) {
// create xmlns
if (!doc.namespaces['g_vml_']) {
doc.namespaces.add('g_vml_', 'urn:schemas-microsoft-com:vml',
'#default#VML');
}
if (!doc.namespaces['g_o_']) {
doc.namespaces.add('g_o_', 'urn:schemas-microsoft-com:office:office',
'#default#VML');
}
// Setup default CSS. Only add one style sheet per document
if (!doc.styleSheets['ex_canvas_']) {
var ss = doc.createStyleSheet();
ss.owningElement.id = 'ex_canvas_';
ss.cssText = 'canvas{display:inline-block;overflow:hidden;' +
// default size is 300x150 in Gecko and Opera
'text-align:left;width:300px;height:150px}' +
'g_vml_\\:*{behavior:url(#default#VML)}' +
'g_o_\\:*{behavior:url(#default#VML)}';
}
// find all canvas elements
var els = doc.getElementsByTagName('canvas');
for (var i = 0; i < els.length; i++) {
this.initElement(els[i]);
}
},
/**
* Public initializes a canvas element so that it can be used as canvas
* element from now on. This is called automatically before the page is
* loaded but if you are creating elements using createElement you need to
* make sure this is called on the element.
* @param {HTMLElement} el The canvas element to initialize.
* @return {HTMLElement} the element that was created.
*/
initElement: function(el) {
if (!el.getContext) {
el.getContext = getContext;
// Remove fallback content. There is no way to hide text nodes so we
// just remove all childNodes. We could hide all elements and remove
// text nodes but who really cares about the fallback content.
el.innerHTML = '';
// do not use inline function because that will leak memory
el.attachEvent('onpropertychange', onPropertyChange);
el.attachEvent('onresize', onResize);
var attrs = el.attributes;
if (attrs.width && attrs.width.specified) {
// TODO: use runtimeStyle and coordsize
// el.getContext().setWidth_(attrs.width.nodeValue);
el.style.width = attrs.width.nodeValue + 'px';
} else {
el.width = el.clientWidth;
}
if (attrs.height && attrs.height.specified) {
// TODO: use runtimeStyle and coordsize
// el.getContext().setHeight_(attrs.height.nodeValue);
el.style.height = attrs.height.nodeValue + 'px';
} else {
el.height = el.clientHeight;
}
//el.getContext().setCoordsize_()
}
return el;
}
};
function onPropertyChange(e) {
var el = e.srcElement;
switch (e.propertyName) {
case 'width':
el.style.width = el.attributes.width.nodeValue + 'px';
el.getContext().clearRect();
break;
case 'height':
el.style.height = el.attributes.height.nodeValue + 'px';
el.getContext().clearRect();
break;
}
}
function onResize(e) {
var el = e.srcElement;
if (el.firstChild) {
el.firstChild.style.width = el.clientWidth + 'px';
el.firstChild.style.height = el.clientHeight + 'px';
}
}
G_vmlCanvasManager_.init();
// precompute "00" to "FF"
var dec2hex = [];
for (var i = 0; i < 16; i++) {
for (var j = 0; j < 16; j++) {
dec2hex[i * 16 + j] = i.toString(16) + j.toString(16);
}
}
function createMatrixIdentity() {
return [
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]
];
}
function matrixMultiply(m1, m2) {
var result = createMatrixIdentity();
for (var x = 0; x < 3; x++) {
for (var y = 0; y < 3; y++) {
var sum = 0;
for (var z = 0; z < 3; z++) {
sum += m1[x][z] * m2[z][y];
}
result[x][y] = sum;
}
}
return result;
}
function copyState(o1, o2) {
o2.fillStyle = o1.fillStyle;
o2.lineCap = o1.lineCap;
o2.lineJoin = o1.lineJoin;
o2.lineWidth = o1.lineWidth;
o2.miterLimit = o1.miterLimit;
o2.shadowBlur = o1.shadowBlur;
o2.shadowColor = o1.shadowColor;
o2.shadowOffsetX = o1.shadowOffsetX;
o2.shadowOffsetY = o1.shadowOffsetY;
o2.strokeStyle = o1.strokeStyle;
o2.globalAlpha = o1.globalAlpha;
o2.arcScaleX_ = o1.arcScaleX_;
o2.arcScaleY_ = o1.arcScaleY_;
o2.lineScale_ = o1.lineScale_;
}
function processStyle(styleString) {
var str, alpha = 1;
styleString = String(styleString);
if (styleString.substring(0, 3) == 'rgb') {
var start = styleString.indexOf('(', 3);
var end = styleString.indexOf(')', start + 1);
var guts = styleString.substring(start + 1, end).split(',');
str = '#';
for (var i = 0; i < 3; i++) {
str += dec2hex[Number(guts[i])];
}
if (guts.length == 4 && styleString.substr(3, 1) == 'a') {
alpha = guts[3];
}
} else {
str = styleString;
}
return {color: str, alpha: alpha};
}
function processLineCap(lineCap) {
switch (lineCap) {
case 'butt':
return 'flat';
case 'round':
return 'round';
case 'square':
default:
return 'square';
}
}
/**
* This class implements CanvasRenderingContext2D interface as described by
* the WHATWG.
* @param {HTMLElement} surfaceElement The element that the 2D context should
* be associated with
*/
function CanvasRenderingContext2D_(surfaceElement) {
this.m_ = createMatrixIdentity();
this.mStack_ = [];
this.aStack_ = [];
this.currentPath_ = [];
// Canvas context properties
this.strokeStyle = '#000';
this.fillStyle = '#000';
this.lineWidth = 1;
this.lineJoin = 'miter';
this.lineCap = 'butt';
this.miterLimit = Z * 1;
this.globalAlpha = 1;
this.canvas = surfaceElement;
var el = surfaceElement.ownerDocument.createElement('div');
el.style.width = surfaceElement.clientWidth + 'px';
el.style.height = surfaceElement.clientHeight + 'px';
el.style.overflow = 'hidden';
el.style.position = 'absolute';
surfaceElement.appendChild(el);
this.element_ = el;
this.arcScaleX_ = 1;
this.arcScaleY_ = 1;
this.lineScale_ = 1;
}
var contextPrototype = CanvasRenderingContext2D_.prototype;
contextPrototype.clearRect = function() {
this.element_.innerHTML = '';
};
contextPrototype.beginPath = function() {
// TODO: Branch current matrix so that save/restore has no effect
// as per safari docs.
this.currentPath_ = [];
};
contextPrototype.moveTo = function(aX, aY) {
var p = this.getCoords_(aX, aY);
this.currentPath_.push({type: 'moveTo', x: p.x, y: p.y});
this.currentX_ = p.x;
this.currentY_ = p.y;
};
contextPrototype.lineTo = function(aX, aY) {
var p = this.getCoords_(aX, aY);
this.currentPath_.push({type: 'lineTo', x: p.x, y: p.y});
this.currentX_ = p.x;
this.currentY_ = p.y;
};
contextPrototype.bezierCurveTo = function(aCP1x, aCP1y,
aCP2x, aCP2y,
aX, aY) {
var p = this.getCoords_(aX, aY);
var cp1 = this.getCoords_(aCP1x, aCP1y);
var cp2 = this.getCoords_(aCP2x, aCP2y);
bezierCurveTo(this, cp1, cp2, p);
};
// Helper function that takes the already fixed cordinates.
function bezierCurveTo(self, cp1, cp2, p) {
self.currentPath_.push({
type: 'bezierCurveTo',
cp1x: cp1.x,
cp1y: cp1.y,
cp2x: cp2.x,
cp2y: cp2.y,
x: p.x,
y: p.y
});
self.currentX_ = p.x;
self.currentY_ = p.y;
}
contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) {
// the following is lifted almost directly from
// http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes
var cp = this.getCoords_(aCPx, aCPy);
var p = this.getCoords_(aX, aY);
var cp1 = {
x: this.currentX_ + 2.0 / 3.0 * (cp.x - this.currentX_),
y: this.currentY_ + 2.0 / 3.0 * (cp.y - this.currentY_)
};
var cp2 = {
x: cp1.x + (p.x - this.currentX_) / 3.0,
y: cp1.y + (p.y - this.currentY_) / 3.0
};
bezierCurveTo(this, cp1, cp2, p);
};
contextPrototype.arc = function(aX, aY, aRadius,
aStartAngle, aEndAngle, aClockwise) {
aRadius *= Z;
var arcType = aClockwise ? 'at' : 'wa';
var xStart = aX + mc(aStartAngle) * aRadius - Z2;
var yStart = aY + ms(aStartAngle) * aRadius - Z2;
var xEnd = aX + mc(aEndAngle) * aRadius - Z2;
var yEnd = aY + ms(aEndAngle) * aRadius - Z2;
// IE won't render arches drawn counter clockwise if xStart == xEnd.
if (xStart == xEnd && !aClockwise) {
xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something
// that can be represented in binary
}
var p = this.getCoords_(aX, aY);
var pStart = this.getCoords_(xStart, yStart);
var pEnd = this.getCoords_(xEnd, yEnd);
this.currentPath_.push({type: arcType,
x: p.x,
y: p.y,
radius: aRadius,
xStart: pStart.x,
yStart: pStart.y,
xEnd: pEnd.x,
yEnd: pEnd.y});
};
contextPrototype.rect = function(aX, aY, aWidth, aHeight) {
this.moveTo(aX, aY);
this.lineTo(aX + aWidth, aY);
this.lineTo(aX + aWidth, aY + aHeight);
this.lineTo(aX, aY + aHeight);
this.closePath();
};
contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) {
var oldPath = this.currentPath_;
this.beginPath();
this.moveTo(aX, aY);
this.lineTo(aX + aWidth, aY);
this.lineTo(aX + aWidth, aY + aHeight);
this.lineTo(aX, aY + aHeight);
this.closePath();
this.stroke();
this.currentPath_ = oldPath;
};
contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) {
var oldPath = this.currentPath_;
this.beginPath();
this.moveTo(aX, aY);
this.lineTo(aX + aWidth, aY);
this.lineTo(aX + aWidth, aY + aHeight);
this.lineTo(aX, aY + aHeight);
this.closePath();
this.fill();
this.currentPath_ = oldPath;
};
contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) {
var gradient = new CanvasGradient_('gradient');
gradient.x0_ = aX0;
gradient.y0_ = aY0;
gradient.x1_ = aX1;
gradient.y1_ = aY1;
return gradient;
};
contextPrototype.createRadialGradient = function(aX0, aY0, aR0,
aX1, aY1, aR1) {
var gradient = new CanvasGradient_('gradientradial');
gradient.x0_ = aX0;
gradient.y0_ = aY0;
gradient.r0_ = aR0;
gradient.x1_ = aX1;
gradient.y1_ = aY1;
gradient.r1_ = aR1;
return gradient;
};
contextPrototype.drawImage = function(image, var_args) {
var dx, dy, dw, dh, sx, sy, sw, sh;
// to find the original width we overide the width and height
var oldRuntimeWidth = image.runtimeStyle.width;
var oldRuntimeHeight = image.runtimeStyle.height;
image.runtimeStyle.width = 'auto';
image.runtimeStyle.height = 'auto';
// get the original size
var w = image.width;
var h = image.height;
// and remove overides
image.runtimeStyle.width = oldRuntimeWidth;
image.runtimeStyle.height = oldRuntimeHeight;
if (arguments.length == 3) {
dx = arguments[1];
dy = arguments[2];
sx = sy = 0;
sw = dw = w;
sh = dh = h;
} else if (arguments.length == 5) {
dx = arguments[1];
dy = arguments[2];
dw = arguments[3];
dh = arguments[4];
sx = sy = 0;
sw = w;
sh = h;
} else if (arguments.length == 9) {
sx = arguments[1];
sy = arguments[2];
sw = arguments[3];
sh = arguments[4];
dx = arguments[5];
dy = arguments[6];
dw = arguments[7];
dh = arguments[8];
} else {
throw Error('Invalid number of arguments');
}
var d = this.getCoords_(dx, dy);
var w2 = sw / 2;
var h2 = sh / 2;
var vmlStr = [];
var W = 10;
var H = 10;
// For some reason that I've now forgotten, using divs didn't work
vmlStr.push(' <g_vml_:group',
' coordsize="', Z * W, ',', Z * H, '"',
' coordorigin="0,0"' ,
' style="width:', W, 'px;height:', H, 'px;position:absolute;');
// If filters are necessary (rotation exists), create them
// filters are bog-slow, so only create them if abbsolutely necessary
// The following check doesn't account for skews (which don't exist
// in the canvas spec (yet) anyway.
if (this.m_[0][0] != 1 || this.m_[0][1]) {
var filter = [];
// Note the 12/21 reversal
filter.push('M11=', this.m_[0][0], ',',
'M12=', this.m_[1][0], ',',
'M21=', this.m_[0][1], ',',
'M22=', this.m_[1][1], ',',
'Dx=', mr(d.x / Z), ',',
'Dy=', mr(d.y / Z), '');
// Bounding box calculation (need to minimize displayed area so that
// filters don't waste time on unused pixels.
var max = d;
var c2 = this.getCoords_(dx + dw, dy);
var c3 = this.getCoords_(dx, dy + dh);
var c4 = this.getCoords_(dx + dw, dy + dh);
max.x = m.max(max.x, c2.x, c3.x, c4.x);
max.y = m.max(max.y, c2.y, c3.y, c4.y);
vmlStr.push('padding:0 ', mr(max.x / Z), 'px ', mr(max.y / Z),
'px 0;filter:progid:DXImageTransform.Microsoft.Matrix(',
filter.join(''), ", sizingmethod='clip');")
} else {
vmlStr.push('top:', mr(d.y / Z), 'px;left:', mr(d.x / Z), 'px;');
}
vmlStr.push(' ">' ,
'<g_vml_:image src="', image.src, '"',
' style="width:', Z * dw, 'px;',
' height:', Z * dh, 'px;"',
' cropleft="', sx / w, '"',
' croptop="', sy / h, '"',
' cropright="', (w - sx - sw) / w, '"',
' cropbottom="', (h - sy - sh) / h, '"',
' />',
'</g_vml_:group>');
this.element_.insertAdjacentHTML('BeforeEnd',
vmlStr.join(''));
};
contextPrototype.stroke = function(aFill) {
var lineStr = [];
var lineOpen = false;
var a = processStyle(aFill ? this.fillStyle : this.strokeStyle);
var color = a.color;
var opacity = a.alpha * this.globalAlpha;
var W = 10;
var H = 10;
lineStr.push('<g_vml_:shape',
' filled="', !!aFill, '"',
' style="position:absolute;width:', W, 'px;height:', H, 'px;"',
' coordorigin="0 0" coordsize="', Z * W, ' ', Z * H, '"',
' stroked="', !aFill, '"',
' path="');
var newSeq = false;
var min = {x: null, y: null};
var max = {x: null, y: null};
for (var i = 0; i < this.currentPath_.length; i++) {
var p = this.currentPath_[i];
var c;
switch (p.type) {
case 'moveTo':
c = p;
lineStr.push(' m ', mr(p.x), ',', mr(p.y));
break;
case 'lineTo':
lineStr.push(' l ', mr(p.x), ',', mr(p.y));
break;
case 'close':
lineStr.push(' x ');
p = null;
break;
case 'bezierCurveTo':
lineStr.push(' c ',
mr(p.cp1x), ',', mr(p.cp1y), ',',
mr(p.cp2x), ',', mr(p.cp2y), ',',
mr(p.x), ',', mr(p.y));
break;
case 'at':
case 'wa':
lineStr.push(' ', p.type, ' ',
mr(p.x - this.arcScaleX_ * p.radius), ',',
mr(p.y - this.arcScaleY_ * p.radius), ' ',
mr(p.x + this.arcScaleX_ * p.radius), ',',
mr(p.y + this.arcScaleY_ * p.radius), ' ',
mr(p.xStart), ',', mr(p.yStart), ' ',
mr(p.xEnd), ',', mr(p.yEnd));
break;
}
// TODO: Following is broken for curves due to
// move to proper paths.
// Figure out dimensions so we can do gradient fills
// properly
if (p) {
if (min.x == null || p.x < min.x) {
min.x = p.x;
}
if (max.x == null || p.x > max.x) {
max.x = p.x;
}
if (min.y == null || p.y < min.y) {
min.y = p.y;
}
if (max.y == null || p.y > max.y) {
max.y = p.y;
}
}
}
lineStr.push(' ">');
if (!aFill) {
var lineWidth = this.lineScale_ * this.lineWidth;
// VML cannot correctly render a line if the width is less than 1px.
// In that case, we dilute the color to make the line look thinner.
if (lineWidth < 1) {
opacity *= lineWidth;
}
lineStr.push(
'<g_vml_:stroke',
' opacity="', opacity, '"',
' joinstyle="', this.lineJoin, '"',
' miterlimit="', this.miterLimit, '"',
' endcap="', processLineCap(this.lineCap), '"',
' weight="', lineWidth, 'px"',
' color="', color, '" />'
);
} else if (typeof this.fillStyle == 'object') {
var fillStyle = this.fillStyle;
var angle = 0;
var focus = {x: 0, y: 0};
// additional offset
var shift = 0;
// scale factor for offset
var expansion = 1;
if (fillStyle.type_ == 'gradient') {
var x0 = fillStyle.x0_ / this.arcScaleX_;
var y0 = fillStyle.y0_ / this.arcScaleY_;
var x1 = fillStyle.x1_ / this.arcScaleX_;
var y1 = fillStyle.y1_ / this.arcScaleY_;
var p0 = this.getCoords_(x0, y0);
var p1 = this.getCoords_(x1, y1);
var dx = p1.x - p0.x;
var dy = p1.y - p0.y;
angle = Math.atan2(dx, dy) * 180 / Math.PI;
// The angle should be a non-negative number.
if (angle < 0) {
angle += 360;
}
// Very small angles produce an unexpected result because they are
// converted to a scientific notation string.
if (angle < 1e-6) {
angle = 0;
}
} else {
var p0 = this.getCoords_(fillStyle.x0_, fillStyle.y0_);
var width = max.x - min.x;
var height = max.y - min.y;
focus = {
x: (p0.x - min.x) / width,
y: (p0.y - min.y) / height
};
width /= this.arcScaleX_ * Z;
height /= this.arcScaleY_ * Z;
var dimension = m.max(width, height);
shift = 2 * fillStyle.r0_ / dimension;
expansion = 2 * fillStyle.r1_ / dimension - shift;
}
// We need to sort the color stops in ascending order by offset,
// otherwise IE won't interpret it correctly.
var stops = fillStyle.colors_;
stops.sort(function(cs1, cs2) {
return cs1.offset - cs2.offset;
});
var length = stops.length;
var color1 = stops[0].color;
var color2 = stops[length - 1].color;
var opacity1 = stops[0].alpha * this.globalAlpha;
var opacity2 = stops[length - 1].alpha * this.globalAlpha;
var colors = [];
for (var i = 0; i < length; i++) {
var stop = stops[i];
colors.push(stop.offset * expansion + shift + ' ' + stop.color);
}
// When colors attribute is used, the meanings of opacity and o:opacity2
// are reversed.
lineStr.push('<g_vml_:fill type="', fillStyle.type_, '"',
' method="none" focus="100%"',
' color="', color1, '"',
' color2="', color2, '"',
' colors="', colors.join(','), '"',
' opacity="', opacity2, '"',
' g_o_:opacity2="', opacity1, '"',
' angle="', angle, '"',
' focusposition="', focus.x, ',', focus.y, '" />');
} else {
lineStr.push('<g_vml_:fill color="', color, '" opacity="', opacity,
'" />');
}
lineStr.push('</g_vml_:shape>');
this.element_.insertAdjacentHTML('beforeEnd', lineStr.join(''));
};
contextPrototype.fill = function() {
this.stroke(true);
}
contextPrototype.closePath = function() {
this.currentPath_.push({type: 'close'});
};
/**
* @private
*/
contextPrototype.getCoords_ = function(aX, aY) {
var m = this.m_;
return {
x: Z * (aX * m[0][0] + aY * m[1][0] + m[2][0]) - Z2,
y: Z * (aX * m[0][1] + aY * m[1][1] + m[2][1]) - Z2
}
};
contextPrototype.save = function() {
var o = {};
copyState(this, o);
this.aStack_.push(o);
this.mStack_.push(this.m_);
this.m_ = matrixMultiply(createMatrixIdentity(), this.m_);
};
contextPrototype.restore = function() {
copyState(this.aStack_.pop(), this);
this.m_ = this.mStack_.pop();
};
function matrixIsFinite(m) {
for (var j = 0; j < 3; j++) {
for (var k = 0; k < 2; k++) {
if (!isFinite(m[j][k]) || isNaN(m[j][k])) {
return false;
}
}
}
return true;
}
function setM(ctx, m, updateLineScale) {
if (!matrixIsFinite(m)) {
return;
}
ctx.m_ = m;
if (updateLineScale) {
// Get the line scale.
// Determinant of this.m_ means how much the area is enlarged by the
// transformation. So its square root can be used as a scale factor
// for width.
var det = m[0][0] * m[1][1] - m[0][1] * m[1][0];
ctx.lineScale_ = sqrt(abs(det));
}
}
contextPrototype.translate = function(aX, aY) {
var m1 = [
[1, 0, 0],
[0, 1, 0],
[aX, aY, 1]
];
setM(this, matrixMultiply(m1, this.m_), false);
};
contextPrototype.rotate = function(aRot) {
var c = mc(aRot);
var s = ms(aRot);
var m1 = [
[c, s, 0],
[-s, c, 0],
[0, 0, 1]
];
setM(this, matrixMultiply(m1, this.m_), false);
};
contextPrototype.scale = function(aX, aY) {
this.arcScaleX_ *= aX;
this.arcScaleY_ *= aY;
var m1 = [
[aX, 0, 0],
[0, aY, 0],
[0, 0, 1]
];
setM(this, matrixMultiply(m1, this.m_), true);
};
contextPrototype.transform = function(m11, m12, m21, m22, dx, dy) {
var m1 = [
[m11, m12, 0],
[m21, m22, 0],
[dx, dy, 1]
];
setM(this, matrixMultiply(m1, this.m_), true);
};
contextPrototype.setTransform = function(m11, m12, m21, m22, dx, dy) {
var m = [
[m11, m12, 0],
[m21, m22, 0],
[dx, dy, 1]
];
setM(this, m, true);
};
/******** STUBS ********/
contextPrototype.clip = function() {
// TODO: Implement
};
contextPrototype.arcTo = function() {
// TODO: Implement
};
contextPrototype.createPattern = function() {
return new CanvasPattern_;
};
// Gradient / Pattern Stubs
function CanvasGradient_(aType) {
this.type_ = aType;
this.x0_ = 0;
this.y0_ = 0;
this.r0_ = 0;
this.x1_ = 0;
this.y1_ = 0;
this.r1_ = 0;
this.colors_ = [];
}
CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) {
aColor = processStyle(aColor);
this.colors_.push({offset: aOffset,
color: aColor.color,
alpha: aColor.alpha});
};
function CanvasPattern_() {}
// set up externs
G_vmlCanvasManager = G_vmlCanvasManager_;
CanvasRenderingContext2D = CanvasRenderingContext2D_;
CanvasGradient = CanvasGradient_;
CanvasPattern = CanvasPattern_;
})();
} // if

View File

@@ -0,0 +1,8 @@
/*
HTML5 Shiv v3.7.0 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
*/
(function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag();
a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/[\w\-]+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x<style>article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}</style>";
c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="<xyz></xyz>";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode||
"undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:"3.7.0",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f);
if(g)return a.createDocumentFragment();for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;d<h;d++)c.createElement(e[d]);return c}};l.html5=e;q(f)})(this,document);

View File

@@ -0,0 +1,167 @@
// Generated by CoffeeScript 1.3.3
/*
Easy pie chart is a jquery plugin to display simple animated pie charts for only one value
Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
Built on top of the jQuery library (http://jquery.com)
@source: http://github.com/rendro/easy-pie-chart/
@autor: Robert Fleischmann
@version: 1.0.1
Inspired by: http://dribbble.com/shots/631074-Simple-Pie-Charts-II?list=popular&offset=210
Thanks to Philip Thrasher for the jquery plugin boilerplate for coffee script
*/
(function() {
(function($) {
$.easyPieChart = function(el, options) {
var addScaleLine, animateLine, drawLine, easeInOutQuad, renderBackground, renderScale, renderTrack,
_this = this;
this.el = el;
this.$el = $(el);
this.$el.data("easyPieChart", this);
this.init = function() {
var percent;
_this.options = $.extend({}, $.easyPieChart.defaultOptions, options);
percent = parseInt(_this.$el.data('percent'), 10);
_this.percentage = 0;
_this.canvas = $("<canvas width='" + _this.options.size + "' height='" + _this.options.size + "'></canvas>").get(0);
_this.$el.append(_this.canvas);
if (typeof G_vmlCanvasManager !== "undefined" && G_vmlCanvasManager !== null) {
G_vmlCanvasManager.initElement(_this.canvas);
}
_this.ctx = _this.canvas.getContext('2d');
_this.ctx.translate(_this.options.size / 2, _this.options.size / 2);
_this.$el.addClass('easyPieChart');
_this.$el.css({
width: _this.options.size,
height: _this.options.size,
lineHeight: "" + _this.options.size + "px"
});
_this.update(percent);
return _this;
};
this.update = function(percent) {
if (_this.options.animate === false) {
return drawLine(percent);
} else {
return animateLine(_this.percentage, percent);
}
};
renderScale = function() {
var i, _i, _results;
_this.ctx.fillStyle = _this.options.scaleColor;
_this.ctx.lineWidth = 1;
_results = [];
for (i = _i = 0; _i <= 24; i = ++_i) {
_results.push(addScaleLine(i));
}
return _results;
};
addScaleLine = function(i) {
var offset;
offset = i % 6 === 0 ? 0 : _this.options.size * 0.017;
_this.ctx.save();
_this.ctx.rotate(i * Math.PI / 12);
_this.ctx.fillRect(_this.options.size / 2 - offset, 0, -_this.options.size * 0.05 + offset, 1);
return _this.ctx.restore();
};
renderTrack = function() {
var offset;
offset = _this.options.size / 2 - _this.options.lineWidth / 2;
if (_this.options.scaleColor !== false) {
offset -= _this.options.size * 0.08;
}
_this.ctx.beginPath();
_this.ctx.arc(0, 0, offset, 0, Math.PI * 2, true);
_this.ctx.closePath();
_this.ctx.strokeStyle = _this.options.trackColor;
_this.ctx.lineWidth = _this.options.lineWidth;
return _this.ctx.stroke();
};
renderBackground = function() {
if (_this.options.scaleColor !== false) {
renderScale();
}
if (_this.options.trackColor !== false) {
return renderTrack();
}
};
drawLine = function(percent) {
var offset;
renderBackground();
_this.ctx.strokeStyle = $.isFunction(_this.options.barColor) ? _this.options.barColor(percent) : _this.options.barColor;
_this.ctx.lineCap = _this.options.lineCap;
offset = _this.options.size / 2 - _this.options.lineWidth / 2;
if (_this.options.scaleColor !== false) {
offset -= _this.options.size * 0.08;
}
_this.ctx.save();
_this.ctx.rotate(-Math.PI / 2);
_this.ctx.beginPath();
_this.ctx.arc(0, 0, offset, 0, Math.PI * 2 * percent / 100, false);
_this.ctx.stroke();
return _this.ctx.restore();
};
animateLine = function(from, to) {
var currentStep, fps, steps;
fps = 30;
steps = fps * _this.options.animate / 1000;
currentStep = 0;
_this.options.onStart.call(_this);
_this.percentage = to;
if (_this.animation) {
clearInterval(_this.animation);
_this.animation = false;
}
return _this.animation = setInterval(function() {
_this.ctx.clearRect(-_this.options.size / 2, -_this.options.size / 2, _this.options.size, _this.options.size);
renderBackground.call(_this);
drawLine.call(_this, [easeInOutQuad(currentStep, from, to - from, steps)]);
currentStep++;
if ((currentStep / steps) > 1) {
clearInterval(_this.animation);
_this.animation = false;
return _this.options.onStop.call(_this);
}
}, 1000 / fps);
};
easeInOutQuad = function(t, b, c, d) {
t /= d / 2;
if (t < 1) {
return c / 2 * t * t + b;
} else {
return -c / 2 * ((--t) * (t - 2) - 1) + b;
}
};
return this.init();
};
$.easyPieChart.defaultOptions = {
barColor: '#ef1e25',
trackColor: '#f2f2f2',
scaleColor: '#dfe0e0',
size: 350,
lineWidth: 3,
animate: false,
onStart: $.noop,
onStop: $.noop
};
$.fn.easyPieChart = function(options) {
return $.each(this, function(i, el) {
var $el;
$el = $(el);
if (!$el.data('easyPieChart')) {
return $el.data('easyPieChart', new $.easyPieChart(el, options));
}
});
};
return void 0;
})(jQuery);
}).call(this);

View File

@@ -0,0 +1,127 @@
requestAdd = 'shop/virtualgoods/addGoods';
requestEdit = 'shop/virtualgoods/editGoods';
// 追加刷新商品sku数据
appendRefreshGoodsSkuData = {
verify_num: 1
};
// 追加刷新规格表格
function appendSkuTableData() {
return {
isNeedVerify: $('[name="virtual_deliver_type"]:checked').val() == 'verify' ? 1 : 0
};
}
// 追加单规格数据
function appendSingleGoodsData(data) {
return {
verify_num: data.field.verify_num
};
}
// 追加保存数据
function appendSaveData(data) {
return {
is_need_verify: $('[name="virtual_deliver_type"]:checked').val() == 'verify' ? 1 : 0,
verify_validity_type: $('[name="verify_validity_type"]:checked').val()
}
}
$(function () {
layui.use(['element', 'laytpl', 'form', 'laydate'], function () {
form = layui.form;
element = layui.element;
laytpl = layui.laytpl;
laydate = layui.laydate;
form.render();
var time = new Date();
var currentTime = time.toLocaleDateString + " " + time.getHours() + ":" + time.getMinutes() + ":" + time.getSeconds();
//核销有效期
laydate.render({
elem: '#virtual_time', //指定元素
type: 'datetime',
min: currentTime
});
// 是否需核销
form.on("radio(virtual_deliver_type)", function (data) {
if (data.value == 'verify') {
$('.need-receive').addClass('layui-hide');
$('.need-verify').removeClass('layui-hide');
} else {
$('.need-verify').addClass('layui-hide');
$('.need-receive').removeClass('layui-hide');
}
refreshSkuTable();
});
//核销有效期类型
form.on('radio(verify_validity_type)', function (data) {
var value = parseInt(data.value);
$('.validity-type').addClass('layui-hide');
$('.validity-type.validity-type-' + value).removeClass('layui-hide');
});
form.verify({
// 总核销次数
goods_verify_num: function (value) {
if ($('input[name="spec_type"]').is(":checked") === false) {
var is_need_verify = $('[name="virtual_deliver_type"]:checked').val() == 'verify' ? 1 : 0;
if (is_need_verify) {
if (isNaN(value) || !regExp.number.test(value)) {
element.tabChange('goods_tab', "price-stock");
return '[核销次数]格式输入错误';
}
if (value < 1) {
element.tabChange('goods_tab', "price-stock");
return '核销次数不能小于1';
}
}
}
},
//有效期
virtual_indate: function (value) {
var is_need_verify = $('[name="virtual_deliver_type"]:checked').val() == 'verify' ? 1 : 0;
var verify_validity_type = $('[name="verify_validity_type"]:checked').val();
if (is_need_verify && verify_validity_type == 1) {
if (isNaN(value) || !regExp.number.test(value)) {
element.tabChange('goods_tab', "basic");
return '[核销有效期]格式输入错误';
}
if (value < 1) {
element.tabChange('goods_tab', "basic");
return '核销有效期不能小于1天';
}
}
},
virtual_time: function (value) {
var is_need_verify = $('[name="virtual_deliver_type"]:checked').val() == 'verify' ? 1 : 0;
var verify_validity_type = $('[name="verify_validity_type"]:checked').val();
if (is_need_verify && verify_validity_type == 2 && value.length == 0) {
element.tabChange('goods_tab', "basic");
return "请输入有效期";
}
},
verify_num: function (value) {
var is_need_verify = $('[name="virtual_deliver_type"]:checked').val() == 'verify' ? 1 : 0;
if (is_need_verify) {
if (isNaN(value) || !regExp.number.test(value)) {
element.tabChange('goods_tab', "basic");
return '[核销次数]格式输入错误';
}
if (value < 1) {
element.tabChange('goods_tab', "basic");
return '核销次数不能小于1';
}
}
}
});
});
});