123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254 |
- class DataHandler {
- constructor() {
- this[CONSTANTS.KEY_QUOTA_COMPANY] = [];
- this[CONSTANTS.KEY_QUOTA_MERCHANT] = [];
- this[CONSTANTS.KEY_QUOTA_CHANNEL] = [];
- this[CONSTANTS.KEY_QUOTA_SUMMARY] = [];
- this[CONSTANTS.KEY_QUOTA_CONDITION] = [];
- this.structureMapping = {
- // company结构: 排序(sort_order), 主体名称(name), 总额度(total_quota), 已用额度(used_quota), 备注(remark)
- [CONSTANTS.KEY_QUOTA_COMPANY]: ['sort', 'name', 'total_quota', 'used_quota', 'remark'],
- // merchant结构: 对应主体(subject), 机构id(mch_id), 已开票总金额(total_invoiced), 上次开票日期(last_invoice_date)
- [CONSTANTS.KEY_QUOTA_MERCHANT]: ['sort','subject', 'mch_id', 'total_invoiced', 'last_invoice_date', 'remark', 'month_opened'],
- // channel结构: 对应主体(subject), 通道id(store_id), 已开票总金额(total_invoiced), 上次开票日期(last_invoice_date)
- [CONSTANTS.KEY_QUOTA_CHANNEL]: ['sort', 'subject', 'store_id', 'total_invoiced', 'last_invoice_date', 'remark', 'month_opened'],
- //summary结构: 主体(subject)
- [CONSTANTS.KEY_QUOTA_SUMMARY]: ['sort', 'subject', 'invoice_remaining_amount', 'remaining_tickets', 'invoice_needed_amount', 'ticket_difference', 'adjustment_value'],
- //condition结构: 月份(month)
- [CONSTANTS.KEY_QUOTA_CONDITION]: ['month']
- };
- }
- translateToIndex(structure, data) {
- return this.structureMapping[structure].map((key, index) => data[key]);
- }
- translateToField(structure, data) {
- let translatedData = {};
- this.structureMapping[structure].forEach((key, index) => {
- translatedData[key] = data[index];
- });
- return translatedData;
- }
- getCompanyList() {
- const list = [], that = this;
- this[CONSTANTS.KEY_QUOTA_COMPANY].forEach(v => {
- list.push(that.translateToField(CONSTANTS.KEY_QUOTA_COMPANY, v));
- });
- return list;
- }
- getMerchantList() {
- const list = [], that = this;
- this[CONSTANTS.KEY_QUOTA_MERCHANT].forEach((v) => {
- list.push(that.translateToField(CONSTANTS.KEY_QUOTA_MERCHANT, v));
- });
- return list;
- }
- getChannelList() {
- const list = [], that = this;
- this[CONSTANTS.KEY_QUOTA_CHANNEL].forEach((v) => {
- list.push(that.translateToField(CONSTANTS.KEY_QUOTA_CHANNEL, v));
- });
- return list;
- }
- getSummaryList() {
- const list = [], that = this;
- this[CONSTANTS.KEY_QUOTA_SUMMARY].forEach((v) => {
- list.push(that.translateToField(CONSTANTS.KEY_QUOTA_SUMMARY, v));
- });
- return list;
- }
- getConditionList() { //条件设置只会有一条数据
- const list = [], that = this;
- this[CONSTANTS.KEY_QUOTA_CONDITION].forEach((v) => {
- list.push(that.translateToField(CONSTANTS.KEY_QUOTA_CONDITION, v));
- });
- return list;
- }
- async addOrUpdateData(structure, newData, uni_key) {
- let list = this[structure];
- let translatedData = this.translateToIndex(structure, newData);
- let index = list.findIndex(item => item[uni_key] === translatedData[uni_key]);
- if (index !== -1) {
- list[index] = translatedData;
- } else {
- list.push(translatedData);
- }
- await this.saveDataToBackend(structure);
- }
- async updateAllData(structure, dataList) {
- let list = this[structure];
- list.length = 0;
- dataList.forEach(data => {
- let translatedData = this.translateToIndex(structure, data);
- list.push(translatedData);
- });
- await this.saveDataToBackend(structure);
- }
- async removeData(structure, index) {
- let list = this[structure];
- if (index >= 0 && index < list.length) {
- list.splice(index, 1);
- await this.saveDataToBackend(structure);
- }
- }
- async saveDataToBackend(structure) {
- this.checkAndFixData(structure);
- const compressedData = this.compressData(structure);
- await statsApi.setStatsSettings(structure, compressedData);
- }
- checkAndFixData(structure) {
- let list = this[structure];
- let structureLength = this.structureMapping[structure].length;
- list.forEach(item => {
- if (item.length < structureLength) {
- for (let i = item.length; i < structureLength; i++) {
- item.push('');
- }
- }
- });
- }
- compressData(structure) {
- return this[structure];
- }
- decompressData(structure, data) {
- this[structure] = data[structure] || [];
- this.checkAndFixData(structure);
- }
- async loadComapny() {
- const data = await statsApi.getStatsSettings([CONSTANTS.KEY_QUOTA_COMPANY]);
- if (data.state !== true) {
- showErr('网络异常,请刷新页面重试');
- return;
- }
- this.decompressData(CONSTANTS.KEY_QUOTA_COMPANY, data);
- }
- async loadMerchant() {
- const data = await statsApi.getStatsSettings([CONSTANTS.KEY_QUOTA_MERCHANT]);
- if (data.state !== true) {
- showErr('网络异常,请刷新页面重试');
- return;
- }
- this.decompressData(CONSTANTS.KEY_QUOTA_MERCHANT, data);
- }
- async loadChannel() {
- const data = await statsApi.getStatsSettings([CONSTANTS.KEY_QUOTA_CHANNEL]);
- if (data.state !== true) {
- showErr('网络异常,请刷新页面重试');
- return;
- }
- this.decompressData(CONSTANTS.KEY_QUOTA_CHANNEL, data);
- }
- async loadSummary() {
- const data = await statsApi.getStatsSettings([CONSTANTS.KEY_QUOTA_SUMMARY]);
- if (data.state !== true) {
- showErr('网络异常,请刷新页面重试');
- return;
- }
- this.decompressData(CONSTANTS.KEY_QUOTA_SUMMARY, data);
- }
- async loadCondition() {
- const data = await statsApi.getStatsSettings([CONSTANTS.KEY_QUOTA_CONDITION]);
- if (data.state !== true) {
- showErr('网络异常,请刷新页面重试');
- return;
- }
- this.decompressData(CONSTANTS.KEY_QUOTA_CONDITION, data);
- }
- }
- class QuotaApiService extends BaseService {
- getStatsSettings(keys = []) {
- const endpoint = '?act=refill_tax_quota_stats&op=stats_settings&key=' + keys.join(',');
- return this.request(endpoint, 'GET', {});
- };
- setStatsSettings(key, value) {
- const endpoint = '?act=refill_tax_quota_stats&op=stats_settings_save';
- let data = {
- key: key,
- value: value
- };
- return this.request(endpoint, 'POST', data);
- };
- getSysMchs() {
- const endpoint = '?act=refill_tax_quota_stats&op=sys_mchs';
- return this.request(endpoint, 'GET', {});
- };
- getSysMchAmounts(mchids, month) {
- const endpoint = `?act=refill_tax_quota_stats&op=sys_mchs_amounts&mchids=${mchids}&month=${month}` ;
- return this.request(endpoint, 'GET', {});
- };
- getSysChans() {
- const endpoint = '?act=refill_tax_quota_stats&op=sys_chans';
- return this.request(endpoint, 'GET', {});
- };
- getSysChanAmounts(storeIds, month) {
- const endpoint = `?act=refill_tax_quota_stats&op=sys_chans_amounts&store_ids=${storeIds}&month=${month}`;
- return this.request(endpoint, 'GET', {});
- };
- }
- const statsApi = new QuotaApiService('');
- const dataHelper = new DataHandler();
- class CompanyComponent extends Component {
- constructor(options) {
- super(Object.assign(options, {
- template: `
- <div id="{{comp-id}}">
- <div class="quota-tablebar">
- <button v-on:click="open" type="button" class="layui-btn layui-bg-green">新增</button>
- <span>1、主体额度说明:(按月统计)</span>
- </div>
- <div id="company-model-{{comp-id}}" class="company-model" style="display: none;">
- <div class="leftmenu-manager-container selected-items" id="selected-items-{{comp-id}}"></div>
- <div class="model-form">
- <div class="form-group">
- <label for="name-{{comp-id}}"><span class="req-flag">*</span>主体名称:</label>
- <input type="text" id="name-{{comp-id}}" />
- </div>
- <div class="form-group">
- <label for="total_quota-{{comp-id}}">总额度(元):</label>
- <input type="text" id="total_quota-{{comp-id}}" />
- <span style="display: inline-block;margin-left: 10px;color: red;" id="total_quota_cn-{{comp-id}}"></span>
- </div>
- <div class="form-group">
- <label for="used_quota-{{comp-id}}">已用额度(元):</label>
- <input type="text" id="used_quota-{{comp-id}}" />
- <span style="display: inline-block;margin-left: 10px;color: red;" id="used_quota-{{comp-id}}"></span>
- </div>
- <div class="form-group">
- <label for="remark-{{comp-id}}">备注:</label>
- <textarea id="remark-{{comp-id}}"></textarea>
- </div>
- <button v-on:click="save" class="layui-btn layui-btn-sm">保存</button>
- </div>
- </div>
- </div>
- `
- }));
- this.parent = options.parent;
- this.cacheKey = this.props['type'];
- this.lastData = undefined;
- this.sortChange = false;
- }
- async mounted() {
- const that = this;
- $('#selected-items-' + this.id).sortable({
- containment: "parent",
- cursor: "move",
- update: function(event, ui) {
- that.sortChange = true;
- }
- }).disableSelection();
- this.inputEvent($('#total_quota-' + this.id));
- this.inputEvent($('#used_quota-' + this.id));
- }
- async open() {
- this.companyLeftList();
- const that = this;
- layer.open({
- type: 1,
- title: '新增主体',
- content: $('#company-model-' + this.props['comp-id']),
- area: ['800px', '500px'],
- success: function () {
- },
- end: async function () {
- if (that.sortChange === true) {
- const loadIndex = layer.load(2, {shade: [0.2, '#000']});
- await that.updateSort();
- layer.close(loadIndex);
- }
- if (that.isEdit() === true || that.sortChange === true) {
- if (that.parent && typeof that.parent.emit === 'function') {
- that.parent.emit(that.props['emit'], that.cacheKey, that.cacheData);
- }
- }
- }
- });
- }
- isEdit() {
- const companyList = dataHelper.getCompanyList();
- if (this.lastData.length !== companyList.length) {
- return true;
- }
- for (let i = 0; i < this.lastData.length; i++) {
- if (this.lastData[i].name !== companyList[i].name) {
- return true;
- }
- }
- return false;
- }
- companyLeftList() {
- const content = this.createModelContent();
- $('#company-model-' + this.id + ' .leftmenu-manager-container').html(content);
- this.bindEvents(); //左列表刷新后需要重新绑定v-on事件
- }
- createModelContent() {
- const companyList = dataHelper.getCompanyList();
- if (this.lastData === undefined) {
- this.lastData = deepCloneData(companyList);
- }
- let html = '';
- for (let i = 0; i < companyList.length; i++) {
- html += '<label class="ch-tags sortable-item" data-name="' + companyList[i].name + '">' +
- companyList[i].name +
- '<span class="delete-btn" v-on:click="delete" data-index="' + i + '">×</span>' +
- '</label>';
- }
- return html;
- }
- async save() {
- const that = this;
- const name = $('#name-' + this.id).val().trim();
- let total_quota = $('#total_quota-' + this.id).val().trim();
- let used_quota = $('#used_quota-' + this.id).val().trim();
- let remark = $('#remark-' + this.id).val().trim();
- if (name === '') {
- showErr('主体名称 未填写');
- return;
- }
- const companyList = dataHelper.getCompanyList();
- const used = companyList.find(item => item.name === name);
- if (used !== undefined) {
- showErr('不能重复设置主体');
- return;
- }
- total_quota = total_quota === '' ? 0 : parseFloat(total_quota);
- used_quota = used_quota === '' ? 0 : parseFloat(used_quota);
- const data = {
- sort: 0,
- name: name,
- total_quota: formatDecimals(total_quota, 2),
- used_quota: formatDecimals(used_quota, 2),
- remark: remark
- }
- await dataHelper.addOrUpdateData(CONSTANTS.KEY_QUOTA_COMPANY, data, 1);
- this.companyLeftList();
- }
- delete(event) {
- const that = this;
- const index = event.currentTarget.getAttribute('data-index');
- const list = dataHelper.getCompanyList();
- const company = list[index].name;
- const merchantList = dataHelper.getMerchantList();
- const usedMch = merchantList.find(item => item.subject === company);
- if (usedMch !== undefined) {
- showErr('机构统计中有该主体关联,不能删除');
- return;
- }
- const channelList = dataHelper.getChannelList();
- const usedChan = channelList.find(item => item.subject === company);
- if (usedChan !== undefined) {
- showErr('上游统计中有该主体关联,不能删除');
- return;
- }
- const summaryList = dataHelper.getSummaryList();
- const usedSummary = summaryList.find(item => item.subject === company);
- if (usedSummary !== undefined) {
- showErr('综合统计中有该主体关联,不能删除');
- return;
- }
- layer.confirm('确定要删除 "' + company + '" 吗?', {
- title: '删除确认',
- icon: 3,
- btn: ['删除', '取消'],
- btn1: async function (btn_i) {
- const loadIndex = layer.load(2, {shade: [0.2, '#000']});
- await dataHelper.removeData(CONSTANTS.KEY_QUOTA_COMPANY, index);
- that.companyLeftList();
- layer.close(loadIndex);
- layer.close(btn_i);
- }
- });
- }
- async updateSort() {
- const selectedItems = $('#' + this.id).find('#selected-items-' + this.id + ' .sortable-item');
- const that = this;
- const companyList = dataHelper.getCompanyList();
- selectedItems.each(function (index) {
- const value = $(this).data('name');
- const currIndex = companyList.findIndex(item => item.name === value);
- if (currIndex !== -1) {
- companyList[currIndex].sort = index;
- }
- });
- companyList.sort((a, b) => a.sort - b.sort);
- await dataHelper.updateAllData(CONSTANTS.KEY_QUOTA_COMPANY, companyList);
- }
- inputEvent(jqObj) {
- jqObj.off('input', handleInputNormal2)
- .off('keypress')
- .off('blur')
- .on('input', handleInputNormal2)
- .on('keypress', function (e) {
- if (e.keyCode === 13) {
- e.preventDefault();
- jqObj.blur();
- }
- })
- .on('blur', function () {
- let val = jqObj.val();
- if (!isNumeric(val)) {
- jqObj.val('0');
- return;
- }
- val = normalizeAmount(val);//过滤,比如前导 0
- jqObj.val(formatDecimals(val));
- const $span = jqObj.next('span');
- if ($span.length > 0) {
- $span.text('(' + cnMoneyFormat(val) + ')');
- }
- });
- }
- }
- class MerchantComponent extends Component {
- constructor(options) {
- super(Object.assign(options, {
- template: `
- <div id="{{comp-id}}">
- <div class="quota-tablebar">
- <button v-on:click="open" type="button" class="layui-btn layui-bg-green">新增</button>
- <span>2、下游(机构)</span>
- </div>
- <div id="merchant-model-{{comp-id}}" class="merchant-model" style="display: none;">
- <div class="leftmenu-manager-container selected-items" id="selected-items-{{comp-id}}"></div>
- <div class="model-form">
- <div class="form-group">
- <label for="company-{{comp-id}}"><span class="req-flag">*</span>主体:</label>
- <select id="company-{{comp-id}}">
-
- </select>
- </div>
- <div class="form-group">
- <label for="merchant-{{comp-id}}"><span class="req-flag">*</span>机构:</label>
- <div class="layui-form" lay-filter="mch_select_{{comp-id}}" style="width:220px;">
- <select id="merchant-{{comp-id}}" lay-search style="width:220px;">
-
- </select>
- </div>
- </div>
- <div class="form-group">
- <label for="total_invoiced-{{comp-id}}">已开票金额(元):</label>
- <input type="text" id="total_invoiced-{{comp-id}}" />
- </div>
- <div class="form-group">
- <label for="last_invoice_date-{{comp-id}}">上次开票日期:</label>
- <input type="text" id="last_invoice_date-{{comp-id}}" class="date" />
- </div>
- <div class="form-group">
- <label for="remark-{{comp-id}}">备注:</label>
- <textarea id="remark-{{comp-id}}"></textarea>
- </div>
- <button v-on:click="save" class="layui-btn layui-btn-sm">保存</button>
- </div>
- </div>
- </div>
- `
- }));
- this.parent = options.parent;
- this.cacheKey = this.props['type'];
- this.lastData = undefined;
- this.sortChange = false;
- this.sysMchs = [];
- }
- async mounted() {
- const that = this;
- $('#selected-items-' + this.id).sortable({
- containment: "parent",
- cursor: "move",
- update: function(event, ui) {
- that.sortChange = true;
- }
- }).disableSelection();
- this.inputEvent($('#total_invoiced-' + this.id));
- laydate.render({
- elem: '#last_invoice_date-' + this.id,
- type: 'date',
- trigger: 'click',
- max: new Date().setDate(new Date().getDate() - 1)
- });
- }
- async open() {
- this.companySelector();
- await this.mchSelector();
- this.merchantLeftList();
- const that = this;
- layer.open({
- type: 1,
- title: '新增下游',
- content: $('#merchant-model-' + this.props['comp-id']),
- area: ['800px', '580px'],
- success: function () {
- },
- end: async function () {
- if (that.sortChange === true) {
- const loadIndex = layer.load(2, {shade: [0.2, '#000']});
- await that.updateSort();
- layer.close(loadIndex);
- }
- if (that.isEdit() === true) {
- if (that.parent && typeof that.parent.emit === 'function') {
- that.parent.emit(that.props['emit'], that.cacheKey, that.cacheData);
- }
- }
- }
- });
- }
- isEdit() {
- const merchantList = dataHelper.getMerchantList();
- if (this.lastData.length !== merchantList.length) {
- return true;
- }
- for (let i = 0; i < this.lastData.length; i++) {
- if (this.lastData[i].mch_id !== merchantList[i].mch_id) {
- return true;
- }
- }
- return false;
- }
- merchantLeftList() {
- const content = this.createModelContent();
- $('#merchant-model-' + this.id + ' .leftmenu-manager-container').html(content);
- this.bindEvents();
- }
- createModelContent() {
- const merchantList = dataHelper.getMerchantList();
- if (this.lastData === undefined) {
- this.lastData = deepCloneData(merchantList);
- }
- let html = '';
- for (let i = 0; i < merchantList.length; i++) {
- const sysItem = this.sysMchs.find(sItem => sItem.mch_id === merchantList[i].mch_id);
- let mchName = '';
- if (sysItem !== undefined) {
- mchName = sysItem.mch_name;
- } else {
- mchName = merchantList[i].mch_id + '(无效项)';
- }
- html += '<label class="ch-tags sortable-item" data-name="' + mchName + '">' +
- mchName +
- '<span class="delete-btn" v-on:click="delete" data-index="' + i + '">×</span>' +
- '</label>';
- }
- return html;
- }
- companySelector() {
- let content = '';
- const companyList = dataHelper.getCompanyList();
- companyList.forEach(item=> {
- content += '<option>' + item.name + '</option>';
- });
- $('#merchant-model-' + this.id + ' #company-' + this.id).html(content);
- }
- async mchSelector() {
- let content = '';
- const mchData = await statsApi.getSysMchs();
- if (mchData.state === true) {
- mchData.list.forEach(item => {
- content += '<option value="' + item.mch_id + '">' + item.mch_name + '</option>';
- });
- $('#merchant-model-' + this.id + ' #merchant-' + this.id).html(content);
- this.sysMchs = mchData.list;
- }
- //只能在渲染option之后才可以设置select搜索组件
- const componentId = this.id;
- layui.use('form', function() {
- const form = layui.form;
- form.render('select', 'mch_select_' + componentId);
- });
- }
- async save() {
- const subject = $('#company-' + this.id).val();
- let mch_id = $('#merchant-' + this.id).val();
- let total_invoiced = $('#total_invoiced-' + this.id).val().trim();
- let last_invoice_date = $('#last_invoice_date-' + this.id).val();
- let remark = $('#remark-' + this.id).val().trim();
- if (subject === '') {
- showErr('主体未选择');
- return;
- }
- if (mch_id === '') {
- showErr('机构未选择');
- return;
- }
- if (last_invoice_date !== '' && !isValidDate(last_invoice_date)) {
- showErr('开票日期格式错误');
- return;
- }
- const merchantList = dataHelper.getMerchantList();
- const used = merchantList.find(item => item.mch_id === mch_id);
- if (used !== undefined) {
- showErr('不能重复设置机构');
- return;
- }
- total_invoiced = total_invoiced === '' ? 0 : parseFloat(total_invoiced);
- const data = {
- sort: 0,
- subject: subject,
- mch_id: mch_id,
- total_invoiced: formatDecimals(total_invoiced, 2),
- last_invoice_date: last_invoice_date,
- remark: remark
- }
- await dataHelper.addOrUpdateData(CONSTANTS.KEY_QUOTA_MERCHANT, data, 2);
- this.merchantLeftList();
- }
- delete(event) {
- const that = this;
- const index = event.currentTarget.getAttribute('data-index');
- const list = dataHelper.getMerchantList();
- const mch_id = list[index].mch_id;
- let mch_name = '';
- const sysItem = this.sysMchs.find(sItem => sItem.mch_id === mch_id);
- if (sysItem !== undefined) {
- mch_name = sysItem.mch_name;
- } else {
- mch_name = `${mch_id}(无效项)`;
- }
- layer.confirm('确定要删除 "' + mch_name + '" 吗?', {
- title: '删除确认',
- icon: 3,
- btn: ['删除', '取消'],
- btn1: async function (btn_i) {
- const loadIndex = layer.load(2, {shade: [0.2, '#000']});
- await dataHelper.removeData(CONSTANTS.KEY_QUOTA_MERCHANT, index);
- that.merchantLeftList();
- layer.close(loadIndex);
- layer.close(btn_i);
- }
- });
- }
- async updateSort() {
- const selectedItems = $('#' + this.id).find('#selected-items-' + this.id + ' .sortable-item');
- const that = this;
- const merchantList = dataHelper.getMerchantList();
- selectedItems.each(function (index) {
- const value = $(this).data('name');
- const sysItem = that.sysMchs.find(sItem => sItem.mch_name === value);
- if (sysItem === undefined) {
- return;
- }
- const currIndex = merchantList.findIndex(item => item.mch_id === sysItem.mch_id);
- if (currIndex !== -1) {
- merchantList[currIndex].sort = index;
- }
- });
- merchantList.sort((a, b) => a.sort - b.sort);
- await dataHelper.updateAllData(CONSTANTS.KEY_QUOTA_MERCHANT, merchantList);
- }
- inputEvent(jqObj) {
- jqObj.off('input', handleInputNormal2)
- .off('keypress')
- .off('blur')
- .on('input', handleInputNormal2)
- .on('keypress', function (e) {
- if (e.keyCode === 13) {
- e.preventDefault();
- jqObj.blur();
- }
- })
- .on('blur', function () {
- let val = jqObj.val();
- if (!isNumeric(val)) {
- jqObj.val('0');
- return;
- }
- val = normalizeAmount(val);//过滤,比如前导 0
- jqObj.val(formatDecimals(val));
- });
- }
- }
- class ChannelComponent extends Component {
- constructor(options) {
- super(Object.assign(options, {
- template: `
- <div id="{{comp-id}}">
- <div class="quota-tablebar">
- <button v-on:click="open" type="button" class="layui-btn layui-bg-green">新增</button>
- <span>3、上游</span>
- </div>
- <div id="channel-model-{{comp-id}}" class="channel-model" style="display: none;">
- <div class="leftmenu-manager-container selected-items" id="selected-items-{{comp-id}}"></div>
- <div class="model-form">
- <div class="form-group">
- <label for="company-{{comp-id}}"><span class="req-flag">*</span>主体:</label>
- <select id="company-{{comp-id}}">
-
- </select>
- </div>
- <div class="form-group">
- <label for="channel-{{comp-id}}"><span class="req-flag">*</span>通道:</label>
- <div class="layui-form" lay-filter="chan_select_{{comp-id}}" style="width:220px;">
- <select id="channel-{{comp-id}}" lay-search style="width:220px;">
-
- </select>
- </div>
- </div>
- <div class="form-group">
- <label for="total_invoiced-{{comp-id}}">已开票金额(元):</label>
- <input type="text" id="total_invoiced-{{comp-id}}" />
- </div>
- <div class="form-group">
- <label for="last_invoice_date-{{comp-id}}">上次开票日期:</label>
- <input type="text" id="last_invoice_date-{{comp-id}}" class="date" />
- </div>
- <div class="form-group">
- <label for="remark-{{comp-id}}">备注:</label>
- <textarea id="remark-{{comp-id}}"></textarea>
- </div>
- <button v-on:click="save" class="layui-btn layui-btn-sm">保存</button>
- </div>
- </div>
- </div>
- `
- }));
- this.parent = options.parent;
- this.cacheKey = this.props['type'];
- this.lastData = undefined;
- this.sortChange = false;
- this.sysChans = [];
- }
- async mounted() {
- const that = this;
- $('#selected-items-' + this.id).sortable({
- containment: "parent",
- cursor: "move",
- update: function(event, ui) {
- that.sortChange = true;
- }
- }).disableSelection();
- this.inputEvent($('#total_invoiced-' + this.id));
- laydate.render({
- elem: '#last_invoice_date-' + this.id,
- type: 'date',
- trigger: 'click',
- max: new Date().setDate(new Date().getDate() - 1)
- });
- }
- async open() {
- this.companySelector();
- await this.chanSelector();
- this.channelLeftList();
- const that = this;
- layer.open({
- type: 1,
- title: '新增上游',
- content: $('#channel-model-' + this.props['comp-id']),
- area: ['800px', '580px'],
- success: function () {
- },
- end: async function () {
- if (that.sortChange === true) {
- const loadIndex = layer.load(2, {shade: [0.2, '#000']});
- await that.updateSort();
- layer.close(loadIndex);
- }
- if (that.isEdit() === true) {
- if (that.parent && typeof that.parent.emit === 'function') {
- that.parent.emit(that.props['emit'], that.cacheKey, that.cacheData);
- }
- }
- }
- });
- }
- isEdit() {
- const channelList = dataHelper.getChannelList();
- if (this.lastData.length !== channelList.length) {
- return true;
- }
- for (let i = 0; i < this.lastData.length; i++) {
- if (this.lastData[i].store_id !== channelList[i].store_id) {
- return true;
- }
- }
- return false;
- }
- channelLeftList() {
- const content = this.createModelContent();
- $('#channel-model-' + this.id + ' .leftmenu-manager-container').html(content);
- this.bindEvents();
- }
- createModelContent() {
- const channelList = dataHelper.getChannelList();
- if (this.lastData === undefined) {
- this.lastData = deepCloneData(channelList);
- }
- let html = '';
- for (let i = 0; i < channelList.length; i++) {
- const sysItem = this.sysChans.find(sItem => sItem.store_id === channelList[i].store_id);
- let chanName = '';
- if (sysItem !== undefined) {
- chanName = sysItem.store_name;
- } else {
- chanName = channelList[i].store_id + '(无效项)';
- }
- html += '<label class="ch-tags sortable-item" data-name="' + chanName + '">' +
- chanName +
- '<span class="delete-btn" v-on:click="delete" data-index="' + i + '">×</span>' +
- '</label>';
- }
- return html;
- }
- companySelector() {
- let content = '';
- const companyList = dataHelper.getCompanyList();
- companyList.forEach(item=> {
- content += '<option>' + item.name + '</option>';
- });
- $('#channel-model-' + this.id + ' #company-' + this.id).html(content);
- }
- async chanSelector() {
- let content = '';
- const chanData = await statsApi.getSysChans();
- if (chanData.state === true) {
- chanData.list.forEach(item => {
- content += '<option value="' + item.store_id + '">' + item.store_name + '</option>';
- });
- $('#channel-model-' + this.id + ' #channel-' + this.id).html(content);
- this.sysChans = chanData.list;
- }
- //只能在渲染option之后才可以设置select搜索组件
- const componentId = this.id;
- layui.use('form', function() {
- const form = layui.form;
- form.render('select', 'chan_select_' + componentId);
- });
- }
- async save() {
- const subject = $('#company-' + this.id).val();
- let store_id = $('#channel-' + this.id).val();
- let total_invoiced = $('#total_invoiced-' + this.id).val().trim();
- let last_invoice_date = $('#last_invoice_date-' + this.id).val();
- let remark = $('#remark-' + this.id).val().trim();
- if (subject === '') {
- showErr('主体未选择');
- return;
- }
- if (store_id === '') {
- showErr('通道未选择');
- return;
- }
- if (last_invoice_date !== '' && !isValidDate(last_invoice_date)) {
- showErr('开票日期格式错误');
- return;
- }
- const channelList = dataHelper.getChannelList();
- const used = channelList.find(item => item.store_id === store_id);
- if (used !== undefined) {
- showErr('不能重复设置通道')
- }
- total_invoiced = total_invoiced === '' ? 0 : parseFloat(total_invoiced);
- const data = {
- sort: 0,
- subject: subject,
- store_id: store_id,
- total_invoiced: formatDecimals(total_invoiced, 2),
- last_invoice_date: last_invoice_date,
- remark: remark
- }
- await dataHelper.addOrUpdateData(CONSTANTS.KEY_QUOTA_CHANNEL, data, 2);
- this.channelLeftList();
- }
- delete(event) {
- const that = this;
- const index = event.currentTarget.getAttribute('data-index');
- const list = dataHelper.getChannelList();
- const store_id = list[index].store_id;
- let store_name = '';
- const sysItem = this.sysChans.find(sItem => sItem.store_id === store_id);
- if (sysItem !== undefined) {
- store_name = sysItem.store_name;
- } else {
- store_name = `${store_id}(无效项)`;
- }
- layer.confirm('确定要删除 "' + store_name + '" 吗?', {
- title: '删除确认',
- icon: 3,
- btn: ['删除', '取消'],
- btn1: async function (btn_i) {
- const loadIndex = layer.load(2, {shade: [0.2, '#000']});
- await dataHelper.removeData(CONSTANTS.KEY_QUOTA_CHANNEL, index);
- that.channelLeftList();
- layer.close(loadIndex);
- layer.close(btn_i);
- }
- });
- }
- async updateSort() {
- const selectedItems = $('#' + this.id).find('#selected-items-' + this.id + ' .sortable-item');
- const that = this;
- const channelList = dataHelper.getChannelList();
- selectedItems.each(function (index) {
- const value = $(this).data('name');
- const sysItem = that.sysChans.find(sItem => sItem.store_name === value);
- if (sysItem === undefined) {
- return;
- }
- const currIndex = channelList.findIndex(item => item.store_id === sysItem.store_id);
- if (currIndex !== -1) {
- channelList[currIndex].sort = index;
- }
- });
- channelList.sort((a, b) => a.sort - b.sort);
- await dataHelper.updateAllData(CONSTANTS.KEY_QUOTA_CHANNEL, channelList);
- }
- inputEvent(jqObj) {
- jqObj.off('input', handleInputNormal2)
- .off('keypress')
- .off('blur')
- .on('input', handleInputNormal2)
- .on('keypress', function (e) {
- if (e.keyCode === 13) {
- e.preventDefault();
- jqObj.blur();
- }
- })
- .on('blur', function () {
- let val = jqObj.val();
- if (!isNumeric(val)) {
- jqObj.val('0');
- return;
- }
- val = normalizeAmount(val);//过滤,比如前导 0
- jqObj.val(formatDecimals(val));
- });
- }
- }
- class SummaryComponent extends Component {
- constructor(options) {
- super(Object.assign(options, {
- template: `
- <div id="{{comp-id}}">
- <div class="quota-tablebar">
- <button v-on:click="open" type="button" class="layui-btn layui-bg-green">新增</button>
- <span>4、综合统计</span>
- </div>
- <div id="summary-model-{{comp-id}}" class="summary-model" style="display: none;">
- <div class="leftmenu-manager-container selected-items" id="selected-items-{{comp-id}}"></div>
- <div class="model-form" style="height: 400px">
- <div class="form-group">
- <label for="company-{{comp-id}}"><span class="req-flag">*</span>主体:</label>
- <div id="company-{{comp-id}}">
- </div>
- </div>
- <button v-on:click="save" class="layui-btn layui-btn-sm">保存</button>
- </div>
- </div>
- </div>
- `
- }));
- this.parent = options.parent;
- this.cacheKey = this.props['type'];
- this.lastData = undefined;
- this.sortChange = false;
- }
- async mounted() {
- const that = this;
- $('#selected-items-' + this.id).sortable({
- containment: "parent",
- cursor: "move",
- update: function(event, ui) {
- that.sortChange = true;
- }
- }).disableSelection();
- }
- async open() {
- this.companySelector();
- this.summaryLeftList();
- const that = this;
- layer.open({
- type: 1,
- title: '设置综合统计主体',
- content: $('#summary-model-' + this.props['comp-id']),
- area: ['800px', '580px'],
- success: function () {
- },
- end: async function () {
- if (that.sortChange === true) {
- const loadIndex = layer.load(2, {shade: [0.2, '#000']});
- await that.updateSort();
- layer.close(loadIndex);
- }
- if (that.isEdit() === true) {
- if (that.parent && typeof that.parent.emit === 'function') {
- that.parent.emit(that.props['emit'], that.cacheKey, that.cacheData);
- }
- }
- }
- });
- }
- isEdit() {
- const companyList = dataHelper.getCompanyList();
- if (this.lastData.length !== companyList.length) {
- return true;
- }
- for (let i = 0; i < this.lastData.length; i++) {
- if (this.lastData[i].store_id !== companyList[i].store_id) {
- return true;
- }
- }
- return false;
- }
- summaryLeftList() {
- const content = this.createModelContent();
- $('#summary-model-' + this.id + ' .leftmenu-manager-container').html(content);
- this.bindEvents();
- }
- createModelContent() {
- const summaryList = dataHelper.getSummaryList();
- if (this.lastData === undefined) {
- this.lastData = deepCloneData(summaryList);
- }
- let html = '';
- for (let i = 0; i < summaryList.length; i++) {
- html += '<label class="ch-tags sortable-item" data-name="' + summaryList[i].subject + '">' +
- summaryList[i].subject +
- '<span class="delete-btn" v-on:click="delete" data-index="' + i + '">×</span>' +
- '</label>';
- }
- return html;
- }
- companySelector() {
- let content = '';
- const companyList = dataHelper.getCompanyList();
- const summaryList = dataHelper.getSummaryList();
- const selectedSubjects = summaryList.map(item => item.subject);
- companyList.forEach(item=> {
- const isChecked = selectedSubjects.includes(item.name) ? 'checked' : '';
- content += `
- <label class="company-checkbox">
- <input type="checkbox" name="summary_company" value="${item.name}" ${isChecked}>
- <span>${item.name}</span>
- </label>
- `;
- });
- $('#summary-model-' + this.id + ' #company-' + this.id).html(content);
- }
- async save() {
- const selectedValues = [];
- $('#summary-model-' + this.id + ' #company-' + this.id + ' input[type="checkbox"]:checked').each(function() {
- selectedValues.push($(this).val());
- });
- const summaryList = dataHelper.getSummaryList();
- selectedValues.forEach(item => {
- const activeItem = summaryList.find(sItem => sItem.subject === item);
- if (activeItem === undefined) {
- summaryList.push({
- sort: 0,
- subject: item
- });
- }
- });
- await dataHelper.updateAllData(CONSTANTS.KEY_QUOTA_SUMMARY, summaryList);
- this.summaryLeftList();
- }
- delete(event) {
- const that = this;
- const index = event.currentTarget.getAttribute('data-index');
- const list = dataHelper.getSummaryList();
- const subject = list[index].subject;
- layer.confirm('确定要删除 "' + subject + '" 吗?', {
- title: '删除确认',
- icon: 3,
- btn: ['删除', '取消'],
- btn1: async function (btn_i) {
- const loadIndex = layer.load(2, {shade: [0.2, '#000']});
- await dataHelper.removeData(CONSTANTS.KEY_QUOTA_SUMMARY, index);
- that.summaryLeftList();
- layer.close(loadIndex);
- layer.close(btn_i);
- }
- });
- }
- async updateSort() {
- const selectedItems = $('#' + this.id).find('#selected-items-' + this.id + ' .sortable-item');
- const that = this;
- const summaryList = dataHelper.getSummaryList();
- selectedItems.each(function (index) {
- const value = $(this).data('name');
- const currIndex = summaryList.findIndex(item => item.subject === value);
- if (currIndex !== -1) {
- summaryList[currIndex].sort = index;
- }
- });
- summaryList.sort((a, b) => a.sort - b.sort);
- await dataHelper.updateAllData(CONSTANTS.KEY_QUOTA_SUMMARY, summaryList);
- }
- }
- function filterSubjectPrefix(str) {
- return str.replace(/^\d+-/, '');
- }
- function sortBySubjectContinuity(data) {
- const groups = {};
- const ordered = [];
- data.forEach(item => {
- if (!groups[item.subject]) {
- groups[item.subject] = [];
- }
- groups[item.subject].push(item);
- });
- const added = new Set();
- data.forEach(item => {
- if (!added.has(item)) {
- ordered.push(item);
- added.add(item);
- groups[item.subject].forEach(other => {
- if (!added.has(other)) {
- ordered.push(other);
- added.add(other);
- }
- });
- }
- });
- return ordered;
- }
|