/***
* 套餐说明
* 100106设备为串口洗衣机,不能设置名称,不能删除套餐
* 101000是门禁设备阶梯收费模式,只有一个套餐,但是需要至少5个阶梯价格
*
* @param option
* @constructor
*/
function PackageComponent(option) {
var defaultDisplaySwitchs = {
displayPriceSwitch: true,
displayCoinsSwitch: true,
displayTimeSwitch: true,
setBasePriceAble: false, // 底价功能
setPulseAble: false, // 脉冲功能
}
var _el = option.el;
var unitList = [
{value: "分钟", type: "time",},
{value: "秒", type: "time",},
{value: "小时", type: "time",},
{value: "天", type: "time",},
// 以上的type为time 不能配置重复,下面的这些单位,暂时定义为不同类型
{value: "次", type: "次",},
{value: "币", type: "币",},
{value: "杯", type: "杯",},
{value: "包", type: "包",},
{value: "度", type: "elec",},
{value: "升", type: "capacity",},
{value: "毫升", type: "capacity",},
{value: "斤", type: "斤",},
{value: "公斤", type: "公斤",},
]
unitList.forEach(function (item, index) {
// 数据适配,用来给mui picker使用
item.text = item.value
})
// 服务费模式只有度
unitList = unitList.filter(item => {
if (option.payload && option.payload.billAsService && option.payload.billAsService.on) {
return item.type === 'elec'
}
return true
})
// 使用缓存获取,避免刷新后重新向服务器请求
$.ajaxSetup({
cache: true
});
//加载图片压缩插件
$.getScript("https://cdn.washpayer.com/components/lib/image-compressor.min.js", function () {
});
function getDefaultPolicyDialog() {
return {
"power": '',
"price": ''
}
}
function getDefaultPolicyTempData() {
return {
"forApps": {
"policyType": "",
"rule": {
"prices": [],
"price": 0
}
},
"forIdcard": {
"policyType": "",
"billingMethod": "",
"money": 0,
"autoRefund": true,
"rule": {
"prices": [],
"price": 0
}
}
}
}
function getSwitchsTemp() {
return `
`
}
function getCommonPackagesRenderTemp() {
return `
用户套餐
`
}
function getCommonPackageEditDialogTemp() {
return `
`
}
function getPolicyTemp(target) {
return `
`
}
/**
* 100028 到 100103 的设备类型需要提示:不修改主板参数
* 100308-串口洗衣机不能添加套餐。并且名称不可更改;
* 100207-墨小智设备 可以设置充满自停套餐--如果用户输入“充满自停”,则自动设置时间为999,且不能选单位和时间---由于没有 v-hide只有v-show,所以(!v-show==v-hide);
*
* */
var vueConfig = ({
el: _el,
template: `
${getSwitchsTemp()}
套餐计费模式
${getPolicyTemp('forApps')}
在线卡计费模式
${getPolicyTemp('forIdcard')}
计费时机
${getCommonPackagesRenderTemp()}
${getCommonPackageEditDialogTemp()}
`,
data: {
settings: {
showAddPackage: true,
showDeletePackage: true,
disabledPackageName: false,
disabledPackageTime: false,
disabledPackageUnit: false,
showDisplaySwitchs: true,
showPackagePrice: true,
showPackageCoins: true,
showPackageTime: true,
showPackageImg: true,
showPackageDesc: true,
billingMethod: 'prepaid',// 套餐 默认先付费prepaid, 后付费是postpaid -- 目前不传到后台,是根据是否为临时套餐来判断的。
},
isTempPackage: false,
packageMod: 'common',
unit_price: null,
unitPicker: null,// unit picker组件
info: {
tabIndex: 1,// 101280套餐、在线卡切换(仅仅视图)
lastTarget: '', // 101280 当前编辑的对象:forApps、forIdcard
policyTemp: getDefaultPolicyTempData(),
policyDialogIndex: 0,
policyDialogOpen: false,
policyDialogData: getDefaultPolicyDialog(),
/***************分割线****************/
displaySwitchs: defaultDisplaySwitchs,
unit: "",//单位,需要实时update
devData: {},
packages: [],
dialogIndex: 0,
dialogOpen: false,
dialogData: {
// 默认为开启
switch: true,
unit: ''
},
},
imgCompressLoadFlag: false
},
mounted: function () {
var that = this
this.initPackages();// 首次注入的数据必须结构完整,否则可能某些字段无法成功双向绑定渲染
// 延迟绑定事件
setTimeout(function () {
if (mui.PopPicker == null) {
console.log('请引入入 mui picker')
} else {
var unitPicker = new mui.PopPicker();
$('body').on('tap', '.event-unit', function (event) {
// 考虑单位不可选
if (that.settings.disabledPackageUnit) {
return
}
// 保持当前输入框的值==picker组件选中的值
var nowUnit = that.info.dialogData['unit']
console.log('nowUnit:' + nowUnit)
unitPicker.pickers[0].setSelectedIndex(findeUnitIndex(nowUnit));//setSelectedValue似乎不生效
// 选中后更新输入框的值
unitPicker.show(function (items) {
Vue.set(that.info.dialogData, 'unit', items[0].value)
});
});
that.unitPicker = unitPicker
that.setUnitList();
}
}, 100)
function findeUnitIndex(value) {
for (var index in unitList) {
var item = unitList[index]
if (value == item.value) {
return index;
}
}
return -1;
}
},
computed: {
// 整合版的套餐,带设备参数
isIntegration() {
return [101280, 101249, 101270].includes(parseInt(this.info.devData.code))
},
// 101280特有的切换页
showTabIndex1() {
if (this.isIntegration) {
if (this.info.tabIndex === 1) {
return true
}
} else {
return true
}
},
showTabIndex2() {
if (this.isIntegration) {
if (this.info.tabIndex === 2) {
return true
}
} else {
return true
}
},
disabledPackageName() {
if (this.isIntegration) {
var id = this.info.dialogData.id
return ['customPackage', 'autoPackage'].includes(id) || this.settings.disabledPackageName
}
return this.settings.disabledPackageName
},
},
watch: {
'info.policyTemp.forApps.policyType'(newVal) {
if (this.isIntegration) {
this.info.packages.forEach(item => {
item.unit = (newVal === 'elec' ? "度" : "分钟")
})
this.setUnitList()
}
},
},
filters: {},
methods: {
getTimeTitle() {
var info = this.info;
if (info.dialogData && info.dialogData.id) {
if (['customPackage'].includes(info.dialogData.id)) {
return `最大${info.policyTemp.forApps.policyType === 'time' ? '时长' : '电量'}`
} else if (['autoPackage'].includes(info.dialogData.id)) {
return `单次充电最大${info.policyTemp.forApps.policyType==='time'?'时长':'电量'}`
}
}
return '用户获得'
},
isShowSortPackage(obj) {
if (['customPackage', 'autoPackage'].includes(obj.id)) {
return false
}
return true
},
isShowDeletePackage(obj) {
if (['customPackage', 'autoPackage'].includes(obj.id)) {
return false
}
return this.settings.showDeletePackage
},
isShowPackageName(obj) {
var info = this.info
if (info.devData.code == 100207 && obj.name == '充满自停') {
return false
}
return true
},
isShowPackageTime(obj) {
var info = this.info
if (info.devData.code == 100207 && obj.name == '充满自停') {
return false
}
return this.settings.showPackageTime
},
isShowPackagePrice(obj) {
var settings = this.settings
if (settings.billingMethod === 'prepaid' && settings.showPackagePrice) {
return true
}
return false
},
setUnitList() {
var ut = unitList
if (this.isIntegration) {
var newVal = this.info.policyTemp.forApps.policyType
if (newVal === 'elec') {
ut = [{value: '度', text: '度'}]
} else {
ut = [{value: '分钟', text: '分钟'}, {value: '小时', text: '小时'}]
}
}
this.unitPicker && this.unitPicker.setData(ut);
},
getBaseConfig() {
var info = this.info
var reObj = {}
if (this.isIntegration) {
reObj = {
policyTemp: info.policyTemp,
}
}
return reObj
},
powerRadio(item, index, obj) {
return ((obj[index - 1] && obj[index - 1].power) || 0) + "W-" + item.power + "W"
},
addPolicyRule(target) {
this.lastTarget = target;
this.info.policyDialogIndex = this.info.policyTemp[target].rule.prices.length;
this.info.policyDialogOpen = true;
$("body").addClass("over-hide");
this.info.policyDialogData = getDefaultPolicyDialog();
},
editPolicyRule(target, obj, index) {
this.lastTarget = target;
this.info.policyDialogIndex = index;
this.info.policyDialogOpen = true;
$("body").addClass("over-hide");
this.info.policyDialogData = $.extend(true, getDefaultPolicyDialog(), obj);
},
deletePolicyRule: function (target, index) {
this.info.policyTemp[target].rule.prices.splice(index, 1);
},
closePolicyDialog: function () {
this.info.policyDialogOpen = false;
$("body").removeClass("over-hide");//恢复body滚动
},
savePolicyDialog: function () {
var target = this.lastTarget;
var dialogData = this.info.policyDialogData;
var list = this.info.policyTemp[target].rule.prices;
var index = this.info.policyDialogIndex;
if (!isMoney(dialogData.price)) {
mui.toast("请正确输入支付价格");
return;
}
if (!isMoney(dialogData.power)) {
mui.toast("请正确输入功率");
return;
}
let newRow = $.extend(true, {}, this.info.policyDialogData);
list.splice(index, 1, newRow);
this.info.policyDialogOpen = false;
$("body").removeClass("over-hide");//恢复body滚动
},
sortUp(obj, index) {
var packages = this.info.packages
if (index > 0) {
var temp1 = packages[index - 1]
var temp2 = packages[index]
this.$set(packages, index - 1, temp2)
this.$set(packages, index, temp1)
}
},
sortDown(obj, index) {
var packages = this.info.packages
if (index < packages.length - 1) {
var temp1 = packages[index]
var temp2 = packages[index + 1]
this.$set(packages, index, temp2)
this.$set(packages, index + 1, temp1)
}
},
// 适配数据,如果没有单位,默认加上单位;套餐默认开启所有开关
adapterPackagesData: function (opt) {
let settings = this.settings
var payload = opt.payload
var devData = opt.devData
var packages = opt.packages || this.info.packages
var unit_price = opt.payload && opt.payload.unit_price
this.isTempPackage = payload.isTempPackage
this.info.devData = devData
// 这两个是全自动洗衣机
if ([100308, 100307].includes(parseInt(devData.code))) {
settings.disabledPackageName = true
settings.showAddPackage = false
settings.showDeletePackage = false
}
if ([100601, 100279].includes(parseInt(devData.code)) || this.isIntegration) {
settings.showDisplaySwitchs = false
settings.showPackageCoins = false
}
// 特殊设备单位不可用,隐藏名称, 图片, 描叙; 套餐默认后付费、临时套餐默认先付费
if (this.isIntegration) {
settings.showPackageImg = false
settings.showPackageDesc = false
if (payload.isTempPackage) {
settings.billingMethod = "prepaid" // 临时套餐先付费
settings.showPackageTime = false // 临时套餐计费规则定死, 无需填写用户获得
} else {
settings.billingMethod = "postpaid" // 普通套餐后付费
}
}
if ([100601, 100279].includes(parseInt(devData.code))) {
settings.showPackagePrice = false
}
if (devData.code == 101000) {
// 阶梯收费模式
this.packageMod = 'step'
}
// 单价模式
if (unit_price) {
this.unit_price = unit_price
settings.disabledPackageUnit = true;
settings.disabledPackageTime = true;
}
// 防止后台缺少关键key从而无法双绑
this.info.displaySwitchs = $.extend(true, defaultDisplaySwitchs, opt.displaySwitchs);
//自从2020.11.15改版后,默认情况下,所有的子项单位统一,不需要从外面再传单位了。 需要从packages获取(一般都一致)。
if (!this.info.unit) {
var _unit = packages.length > 0 ? packages[0].unit : '分钟';
this.info.unit = _unit
console.log('未发现info.unit!从套餐中获取第一个单位。')
}
for (var index in packages) {
var item = packages[index]
if (!item.unit) {
item.unit = this.info.unit
}
if (item.switch === null || item.switch === undefined) {
item.switch = true
}
}
this.info.packages = packages
if (this.isIntegration) {
this.info.policyTemp = $.extend(true, getDefaultPolicyTempData(), payload.policyTemp)
if (!payload.isTempPackage) {
if (!packages.find(item => item.id === 'customPackage')) {
var obj = this.getDefaultPackageItem()
obj.id = 'customPackage'
obj.name = '自定义'
obj.switch = false
packages.unshift(obj)
}
if (!packages.find(item => item.id === 'autoPackage')) {
var obj = this.getDefaultPackageItem()
obj.id = 'autoPackage'
obj.name = '充满自停'
obj.switch = false
packages.unshift(obj)
}
}
}
},
tapSwitch: function (target) {
this.info.displaySwitchs[target] = !this.info.displaySwitchs[target];
},
tapSwitchForObj: function (obj, target) {
obj[target] = !obj[target];
},
tapSubSwitch: function ($evt, obj) {
$evt.stopPropagation()
obj.switch = !obj.switch
},
changeName: function () {
var devData = this.info.devData;
//墨小智v2 特殊的充满自停套餐
if (devData.code == 100207 && this.info.dialogData.name == "充满自停") {
this.info.dialogData.time = 999;
}
},
initPackages: function () {
//初始化先适配数据,主要是为了适配单位、还有默认开关
this.adapterPackagesData(option);
},
//是否需要图片
getImgFeatures: function () {
return true;//暂定 所有的类型都需要图片
},
getDefaultPackageItem() {
let obj = {}
if (this.packageMod === 'step') {
obj = {
price: "",
maxHour: ""
};
} else if (this.unit_price) {
obj = {
switch: true,
name: "",
imgList: [],
unit: this.unit_price.unit,
time: '',
};
} else {
obj = {
switch: true,
name: "",
imgList: [],
unit: this.info.unit,
time: '',
};
}
if (this.isIntegration) {
obj = $.extend(true, {
autoStop: true,
autoRefund: false,
minAfterStartCoins: 0,
minFee: 0,
}, obj)
}
return obj
},
addPackageRule: function () {
this.imgCompressLoad();
this.info.dialogIndex = this.info.packages.length;
this.info.dialogOpen = true;
$("body").addClass("over-hide");//避免滚动穿透,直接禁止body滚动
this.info.dialogData = this.getDefaultPackageItem();
}
,
editPackageRule: function (obj, index) {
this.info.dialogIndex = index;
this.info.dialogOpen = true;
if (this.packageMod === 'step') {
// nothing
} else {
this.imgCompressLoad();
}
this.info.dialogData = $.extend(true, this.getDefaultPackageItem(), obj)
$("body").addClass("over-hide");//避免滚动穿透,直接禁止body滚动
},
deletePackageRule: function (obj, index) {
var that = this;
var tnArray = ['取消', '确认'];
mui.confirm('确定要删除该套餐?', '温馨提示', tnArray, function (e) {
if (e.index == 0) {
} else {
//点击确认业务
that.info.packages.splice(index, 1);
}
});
},
closeRulePanel: function () {
this.info.dialogOpen = false;
$("body").removeClass("over-hide");//恢复body滚动
},
savePackageRule: function () {
if (this.unit_price) {
this.savePackageRuleForUnitMod()
return;
}
var dialogData = this.info.dialogData;
var devData = this.info.devData;
if (!this.checkName()) {
return;
}
if (this.info.displaySwitchs.setBasePriceAble && !isMoney(dialogData.basePrice)) {
mui.toast("底价填写不正确");
return;
}
if (this.isShowPackagePrice(dialogData)) {
if (!isMoney(dialogData.price)) {
mui.toast("支付价格填写不正确");
return;
}
}
if (this.settings.showPackageCoins) {
if (!isMoney(dialogData.coins)) {
mui.toast("投币填写不正确");
return;
}
}
// 100279 的设备 所有套餐添加上功率计费的属性
if (devData.code == "100279") {
this.info.dialogData.billingMethod = "powerBilling";
}
if (this.info.displaySwitchs.setPulseAble && !isPInt(dialogData.pulse)) {
mui.toast("脉冲写不正确");
return;
}
if (this.settings.showPackageTime) {
if (dialogData.time === "" || dialogData.time == null || dialogData.time <= 0) {
mui.toast(`“${this.getTimeTitle()}”不正确,必须为大于0的数字`);
return;
}
}
this.info.unit = dialogData.unit;// 刷新单位,避免下次增加套餐重选
let list = this.info.packages;
let index = this.info.dialogIndex;
let newRow = $.extend(true, {}, this.info.dialogData);
list.splice(index, 1, newRow);
this.info.dialogOpen = false;
$("body").removeClass("over-hide");//恢复body滚动
},
savePackageRuleForStepMod: function () {
var dialogData = this.info.dialogData;
if (dialogData.maxHour === '') {
mui.toast("时间填写不正确");
return;
}
// 两个字符串比较会有bug,比如 "111"<"2" 是等于true的,所以要进行数据类型换换:parseFloat
if (this.info.dialogIndex - 1 >= 0) {
var prevPackage = this.info.packages[this.info.dialogIndex - 1];
if (parseFloat(dialogData.maxHour) <= parseFloat(prevPackage.maxHour)) {
mui.toast("时间必须大于" + prevPackage.maxHour);
return;
}
}
if (this.info.dialogIndex + 1 < this.info.packages.length) {
var afterPackage = this.info.packages[this.info.dialogIndex + 1];
if (parseFloat(afterPackage.maxHour) <= parseFloat(dialogData.maxHour)) {
mui.toast("时间必须小于" + afterPackage.maxHour);
return;
}
}
if (!isMoney(dialogData.price)) {
mui.toast("价格填写不正确");
return;
}
this.info.packages[this.info.dialogIndex] = this.info.dialogData;
this.info.dialogOpen = false;
$("body").removeClass("over-hide");//恢复body滚动
},
savePackageRuleForUnitMod: function () {
var dialogData = this.info.dialogData;
if (!this.checkName()) {
return;
}
if (!isMoney(dialogData.price)) {
mui.toast("支付价格填写不正确");
return;
}
if (!isMoney(dialogData.coins)) {
mui.toast("投币填写不正确");
return;
}
let list = this.info.packages
let index = this.info.dialogIndex
let newRow = $.extend(true, {}, this.info.dialogData);
list.splice(index, 1, newRow)
this.info.dialogOpen = false;
$("body").removeClass("over-hide");//恢复body滚动
},
checkName() {
let dialogData = this.info.dialogData;
if (this.settings.disabledPackageName || !this.isShowPackageName(dialogData)) {
} else {
if (!dialogData.name) {
mui.toast("名称不能为空");
return false;
}
}
for (let index in this.info.packages) {
let item = this.info.packages[index];
let otherName = item.name;
//和其他套餐匹配,如果名称有重复不能保存
if (index != this.info.dialogIndex && otherName === dialogData.name) {
mui.toast("套餐名称不能重复");
return false;
}
}
return true
},
changeCoins() {
let dialogData = this.info.dialogData;
if (this.unit_price) {
let value1 = this.unit_price.value
if (dialogData) {
dialogData.time = parseFloat((value1 * dialogData.coins).toFixed(2))
dialogData.unit = this.unit_price.unit // 单位也刷新下,因为原套餐可能是错误的
}
}
},
imgCompressLoad: function () {
var that = this;
if (this.imgCompressLoadFlag) {
return;
}
this.imgCompressLoadFlag = true;
// 检测图片特性
if (!this.getImgFeatures()) {
return;
}
if (window.ImageCompressor) {
const imageCompressor = new ImageCompressor();
var imgUpload = $("#addImg");
imgUpload.change(function (evt) {
var file = imgUpload[0].files[0];
if (file) {
imageCompressor.compress(file, {
quality: .7,
// 套餐图片不会太大
maxWidth: 1080,
maxHeight: 1080,
success: function (result) {
var formData = new FormData();
formData.append('file', result, result.name);
var url = '/common/upload?type=packageImg';
myAjax({
url: url,
type: 'POST',
data: formData,
processData: false,
contentType: false,
beforeSend: function () {
showLoading('上传中...');
},
success: function (res) {
if (res.result == 1) {
var url = res.para;
that.info.dialogData.imgList.push(url);
} else {
mui.toast(res.description);
}
},
complete: function (res) {
hideLoading();
//重置文件路径,避免选中重复不触发onchange
var imgUpload = $("#addImg");
imgUpload[0].value = "";
}
});
}
})
}
});
} else {
//图片插件未加载完成提示
mui.toast("图片上传工具未加载,刷新页面重试...");
}
},
deleteImg: function (index) {
var dialogData = this.info.dialogData;
dialogData.imgList.splice(index, 1);
//重置文件路径,避免选中重复文件不生效
var imgUpload = $("#addImg");
imgUpload[0].value = "";
}
}
});
/**
* 射击枪太特殊,重新写一份 code == 101205; 只有3个套餐,只能修改价格; 币数不能改和射击枪次数一致(后台返回写死);套餐1价格8-20,后面的依次翻倍
*/
if (option.devData && option.devData.code == 101205) {
vueConfig = ({
el: _el,
template: `
`,
data: {
info: {
devData: {},
packages: [],
dialogIndex: 0,
dialogOpen: false,
dialogData: {},
},
},
mounted: function () {
var that = this
that.initPackages();// 首次注入的数据必须结构完整,否则可能某些字段无法成功双向绑定渲染
},
methods: {
// 适配数据,如果没有单位,默认加上单位;套餐默认开启所有开关
adapterPackagesData: function (opt) {
var devData = opt.devData
var packages = opt.packages || this.info.packages
this.info.devData = devData
this.info.packages = packages
},
initPackages: function () {
//初始化先适配数据,主要是为了适配单位、还有默认开关
this.adapterPackagesData(option);
},
editPackageRule: function (obj, index) {
this.info.dialogIndex = index;
this.info.dialogOpen = true;
this.info.dialogData = $.extend(true, {
name: "",
}, obj);
$("body").addClass("over-hide");//避免滚动穿透,直接禁止body滚动
},
closeRulePanel: function () {
this.info.dialogOpen = false;
$("body").removeClass("over-hide");//恢复body滚动
},
savePackageRule: function () {
var dialogData = this.info.dialogData;
let list = this.info.packages;
let index = this.info.dialogIndex;
if (!isMoney(dialogData.price) || dialogData.price < 8) {
mui.toast("支付价格最小为8");
return;
}
if (index === 0 && (dialogData.price < 8 || dialogData.price > 20)) {
mui.toast("第一个套餐价格8-20");
return;
}
let newRow = $.extend(true, {}, this.info.dialogData);
list.splice(index, 1, newRow);
// 修改套餐1的价格,则自动修改后续套餐的价格
if (index === 0) {
list.forEach((item, index) => {
if (index > 0) {
item.price = dialogData.price * Math.pow(2, index)
}
})
}
this.info.dialogOpen = false;
$("body").removeClass("over-hide");//恢复body滚动
},
}
});
}
var app = this.app = new Vue(vueConfig);
}
PackageComponent.prototype.getDisplaySwitchs = function () {
return this.app.info.displaySwitchs || {};
};
PackageComponent.prototype.getBaseConfig = function () {
if (this.app.getBaseConfig) {
return this.app.getBaseConfig();
}
return {}
};
PackageComponent.prototype.getPackages = function () {
return this.app.info.packages;
};
PackageComponent.prototype.update = function (data) {
var app = this.app;
for (var key in data) {
Vue.set(app.info, key, data[key]);
}
app.adapterPackagesData(data);
};