Server IP : 80.87.202.40 / Your IP : 216.73.216.169 Web Server : Apache System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64 User : bitrix ( 600) PHP Version : 8.2.27 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /home/bitrix/ext_www/ilovecveti.ru/bitrix/js/sproduction.datasync/ |
Upload File : |
/** * * SETTINGS AND EXTERNAL VALUES * */ Vue.prototype.$profile_id = profile_id; /** * * MIXINS * */ var componentsFuncs = { mixins: [mainFuncs], methods: { blockSaveData: function (code, callback) { this.$emit('load_start'); this.ajaxReq('iblocks_profile_save', 'post', { id: this.$profile_id, block: code, fields: this.fields, }, (response) => { this.$emit('block_update', code); }, (response) => { }, (response) => { // Callback success if (typeof callback === 'function') { callback(response); } this.$emit('load_stop'); }); }, afterBlockUpdate() { }, }, mounted() { // Blocks update (data received) this.$root.$on('blocks_update', (data, calling_block) => { // console.log(this.code); // console.log(this.fields); let item; for (item in this.fields) { if (data.blocks[this.code][item] !== undefined) { this.fields[item] = data.blocks[this.code][item]; } } this.afterBlockUpdate(); }); }, }; /** * * COMPONENTS * */ // Main settings Vue.component('profile-tab-main', { props: ['crm_iblocks_list', 'crm_iblock_link', 'store_search_fields', 'crm_search_fields'], mixins: [utilFuncs, componentsFuncs], data: function () { return { code: 'main', params: {}, fields: { active: '', crm_iblock_id: 0, store_search_field: '', crm_search_field: '', }, profile_active: false, } }, watch: { profile_active: function (new_value) { new_active_value = new_value ? 'Y' : 'N'; if (this.fields.active != new_active_value) { this.fields.active = new_active_value; } }, 'fields.active': function (new_value) { new_profile_active_value = (this.fields.active == 'Y'); if (this.profile_active != new_profile_active_value) { this.profile_active = new_profile_active_value; } }, }, template: ` <div class="row"> <div class="col-md-12"> <div class="card"> <div class="card-body"> <div class="row mb-2"> <div class="col-sm-6"> <div class="alert alert-info"> <div class="custom-control custom-switch"> <input type="checkbox" class="custom-control-input" id="main_active" v-model="profile_active" value="Y"> <label class="custom-control-label" for="main_active">{{ $t("page.SP_DS_IBLOCKS_EDIT_MAIN_PROFILE_ACTIVE") }}</label> </div> </div> </div> </div> <div class="row"> <div class="col-md-6"> <div class="form-group mb-3"> <label for="main_crm_iblock_id">{{ $t("page.SP_DS_IBLOCKS_EDIT_MAIN_CRM_IBLOCK_ID") }}</label> <b-form-select v-model="fields.crm_iblock_id" id="main_crm_iblock_id"> <option value=0>{{ $t("page.SP_DS_IBLOCKS_EDIT_MAIN_SELECT_NOTSET") }}</option> <option v-for="item in crm_iblocks_list" :value="item.id">{{item.name}} [{{item.id}}]</option> </b-form-select> <b-button v-if="crm_iblock_link.length" :href="crm_iblock_link" target="_blank" variant="primary" class="mt-2">{{ $t("page.SP_DS_IBLOCKS_EDIT_MAIN_CRM_IBLOCK_LINK") }}</b-button> </div> </div> </div> <div v-if="store_search_fields.length > 0" class="row"> <div class="col-md-6"> <div class="form-group mb-3"> <label for="main_crm_iblock_id">{{ $t("page.SP_DS_IBLOCKS_EDIT_MAIN_STORE_SEARCH_FIELD") }}</label> <b-form-select v-model="fields.store_search_field" id="main_crm_iblock_id"> <option value="">{{ $t("page.SP_DS_IBLOCKS_EDIT_MAIN_SELECT_NOTSET") }}</option> <option v-for="item in store_search_fields" :value="item.id">{{item.name}} [{{item.id}}]</option> </b-form-select> </div> </div> </div> <div v-if="crm_search_fields.length > 0" class="row"> <div class="col-md-6"> <div class="form-group mb-3"> <label for="main_crm_iblock_id">{{ $t("page.SP_DS_IBLOCKS_EDIT_MAIN_CRM_SEARCH_FIELD") }}</label> <b-form-select v-model="fields.crm_search_field" id="main_crm_iblock_id"> <option value="">{{ $t("page.SP_DS_IBLOCKS_EDIT_MAIN_SELECT_NOTSET") }}</option> <option v-for="item in crm_search_fields" :value="item.id">{{item.name}} [{{item.id}}]</option> </b-form-select> </div> </div> </div> </div> <!-- end card-body --> <div class="card-footer"> <button class="btn btn-success" @click="blockSaveData(code)">{{ $t("page.SP_DS_IBLOCKS_EDIT_SAVE") }}</button> <!--<vue-ladda button-class="btn btn-success" data-style="expand-left" loading="true">Сохранить</vue-ladda>--> </div> </div> <!-- end card --> </div> </div> `, }); // Base params Vue.component('profile-tab', { props: ['fields_list', 'code'], mixins: [utilFuncs, componentsFuncs], data: function () { return { params: {}, fields: { comp_table: {}, }, info: { fields_list: [], }, field_list: [], } }, methods: { updateList() { if (this.fields_list[this.code] != undefined) { let field_i, field; this.info.fields_list.splice(0); for (field_i in this.fields_list[this.code]['items']) { Vue.set(this.info.fields_list, field_i, this.fields_list[this.code]['items'][field_i]); } //this.info.fields_list = this.fields_list[this.code]['items']; // Compare table initiate for (field_i in this.info.fields_list) { field = this.info.fields_list[field_i]; if (this.fields.comp_table[field.id] === undefined) { this.fields.comp_table[field.id] = { direction: 'all', value: '', }; } } } } }, watch: { 'fields.comp_table': function(new_val, old_val) { // this.updateList(); }, 'fields_list': function(new_val, old_val) { this.updateList(); }, }, template: ` <div class="row"> <div class="col-md-12"> <div class="card"> <div class="card-body"> <h4 class="header-title mb-2">{{ $t("page.SP_DS_IBLOCKS_EDIT_BASE_TITLE") }}</h4> <p class="sub-header">{{ $t("page.SP_DS_IBLOCKS_EDIT_BASE_SUBTITLE") }}</p> <div class="row"> <div class="col-md-6"> <table class="table mb-2 table-params table-params-props table-bordered"> <thead> <tr> <th class="param"><i class="icon icon-bitrix24"></i> {{ $t("page.SP_DS_IBLOCKS_EDIT_TABLE_HEAD_CRM") }}</th> <th class="direct"></th> <th class="value"><i class="icon icon-bitrix"></i> {{ $t("page.SP_DS_IBLOCKS_EDIT_TABLE_HEAD_STORE") }}</th> </tr> </thead> <tbody> <tr v-for="c_field in info.fields_list"> <td class="param"> {{c_field.name}} ({{c_field.id}}) <i class="fa fa-question-circle help-link-icon" v-if="c_field.hint" v-b-tooltip.hover :title="c_field.hint"></i> </td> <td class="direct"> <profile-param-dir-switch :field_data="fields.comp_table[c_field.id]" :allow_dir="c_field.direction" /> </td> <td class="value"> <b-form-select v-model="fields.comp_table[c_field.id].value" :disabled="c_field.fixed"> <option value="">{{ $t('page.SP_DS_IBLOCKS_EDIT_TABLE_NOT_SYNC') }}</option> <optgroup v-for="(group,group_id) in c_field.values" :label="group.title"> <option v-for="s_field in group.items" :value="s_field.id">{{s_field.name}} ({{s_field.id}})</option> </optgroup> </b-form-select> <div v-if="c_field.value_hint">{{ c_field.value_hint }}</div> </td> </tr> </tbody> </table> </div> </div> <div class="row"> <div class="col-md-12"> <button class="btn btn-success" @click="blockSaveData(code)">{{ $t("page.SP_DS_IBLOCKS_EDIT_SAVE") }}</button> </div> </div> </div> </div> <!-- end card --> </div> </div> `, }); // Direction switcher Vue.component('profile-param-dir-switch', { props: ['field_data', 'allow_dir'], methods: { getDirActive: function (check_dir) { let result = false; if (check_dir == 'stoc' && (this.allow_dir == 'stoc' || this.allow_dir == 'all')) { result = true; } else if (check_dir == 'ctos' && (this.allow_dir == 'ctos' || this.allow_dir == 'all')) { result = true; } return result; }, getDirSelected: function (check_dir) { let result = false; let selected_dir = this.field_data.direction; if (selected_dir == 'all' || selected_dir == check_dir) { result = true; } return result; }, getDirHint: function (check_dir) { let hint = ''; // Is possible if (check_dir == 'stoc') { if (this.getDirActive(check_dir, this.allow_dir)) { hint += this.$t("page.SP_DS_IBLOCKS_EDIT_TABLE_STOC_Y_HINT"); } else { hint += this.$t("page.SP_DS_IBLOCKS_EDIT_TABLE_STOC_N_HINT"); } } else if (check_dir == 'ctos') { if (this.getDirActive(check_dir, this.allow_dir)) { hint += this.$t("page.SP_DS_IBLOCKS_EDIT_TABLE_CTOS_Y_HINT"); } else { hint += this.$t("page.SP_DS_IBLOCKS_EDIT_TABLE_CTOS_N_HINT"); } } // Is enabled if (this.getDirActive(check_dir, this.allow_dir)) { let selected_dir = this.field_data.direction; if (selected_dir == 'all' || selected_dir == check_dir) { hint += this.$t("page.SP_DS_IBLOCKS_EDIT_TABLE_ENABLED_HINT"); } else { hint += this.$t("page.SP_DS_IBLOCKS_EDIT_TABLE_DISABLED_HINT"); } } return hint; }, changePropDir: function (check_dir) { let cur_dir = this.field_data.direction; if (cur_dir == 'all') { this.field_data.direction = ((check_dir == 'stoc') ? 'ctos' : 'stoc'); } else if (cur_dir == check_dir) { this.field_data.direction = ''; } else if (cur_dir != '') { this.field_data.direction = 'all'; } else { this.field_data.direction = ((check_dir == 'stoc') ? 'stoc' : 'ctos'); } }, }, template: ` <div class="profile-param-dir-switch"> <span v-if="getDirActive('stoc')" href="#" v-on:click="changePropDir('stoc')" :class="'params-change-direct to-crm enabled' + (getDirSelected('stoc')?' active':'')" v-b-tooltip.hover :title="getDirHint('stoc')"><i class="fa fa-arrow-alt-circle-left"></i></span> <span v-else :class="'params-change-direct to-crm'" v-b-tooltip.hover :title="getDirHint('stoc')"><i class="fa fa-arrow-alt-circle-left"></i></span> <span v-if="getDirActive('ctos')" href="#" v-on:click="changePropDir('ctos')" :class="'params-change-direct to-order enabled' + (getDirSelected('ctos')?' active':'')" v-b-tooltip.hover :title="getDirHint('ctos')"><i class="fa fa-arrow-alt-circle-right"></i></span> <span v-else :class="'params-change-direct to-order'" v-b-tooltip.hover :title="getDirHint('ctos')"><i class="fa fa-arrow-alt-circle-right"></i></span> </div> `, }); // Main settings Vue.component('profile-tab-sync', { mixins: [utilFuncs, componentsFuncs], props: ['state_man_sync', 'state_add_sync', 'crm_iblock_link'], data: function () { return { code: 'sync', params: {}, fields: { man_sync_period: '', man_sync_syncprod_onlynew: false, man_sync_steps: [true, true, true, true, true], add_sync_schedule: '', }, } }, template: ` <b-row> <b-col> <b-alert :show="crm_iblock_link.length">{{ $t("page.SP_DS_IBLOCKS_EDIT_SYNC_CRM_IBLOCK_LINK") }}<a :href="crm_iblock_link" target="_blank">{{crm_iblock_link}}</a></b-alert> <b-card v-if="state_man_sync.display" v-bind:class="{ 'block-disabled': state_man_sync.active == false }"> <h4 class="header-title">{{ $t("page.SP_DS_IBLOCKS_EDIT_SYNC_MAN_SYNC_TITLE") }}</h4> <p class="sub-header">{{ $t("page.SP_DS_IBLOCKS_EDIT_SYNC_MAN_SYNC_SUBTITLE") }}</p> <profile-mansync :tab_fields="fields" @save="blockSaveData(code)"></profile-mansync> </b-card> <!-- end card --> </b-col> <b-col> <b-card v-if="state_add_sync.display" v-bind:class="{ 'block-disabled': state_add_sync.active == false }"> <h4 class="header-title">{{ $t("page.SP_DS_IBLOCKS_EDIT_SYNC_ADD_SYNC_TITLE") }}</h4> <p class="sub-header">{{ $t("page.SP_DS_IBLOCKS_EDIT_SYNC_ADD_SYNC_SUBTITLE") }}</p> <profile-addsync :tab_fields="fields" @save="blockSaveData(code)"></profile-addsync> </b-card> <!-- end card --> </b-col> </b-row> `, }); // Manual synchronization Vue.component('profile-mansync', { props: ['tab_fields'], // JS passes objects by reference data: function () { return { code: 'man_sync', state: { display: true, active: false, }, checkTimer: null, btns_state: 0, progress: [0, 0, 0, 0, 0], progress_step_max_def: [20, 10, 40, 15, 15], progress_step_max: [0, 0, 0, 0, 0], progress_length: 100, hint: '', } }, methods: { runSync: function () { // Set start params this.btns_state = 1; this.updateProgress(0, 0, 0); // Run sync axios .post('/bitrix/sprod_dsync_sync.php?action=run_sync&profile=' + this.$profile_id, {}) .then(response => { if (response.data.status == 'success') { // Start regular status check of process this.checkTimer = setInterval(this.checkSync, 1000); } else { console.log(response); } }) .catch(error => { console.log(error); }); }, checkSync: function () { axios .post('/bitrix/sprod_dsync_sync.php?action=check_sync&profile=' + this.$profile_id, {}) .then(response => { if (response.data.status == 'success') { if (response.data.sync.state == 0) { this.btns_state = 0; this.hint = ''; this.updateProgress(0, 0, 0); clearInterval(this.checkTimer); } else if (response.data.sync.state == 1) { this.btns_state = 1; this.hint = response.data.sync.hint; this.updateProgress(response.data.sync.step, response.data.sync.count, response.data.sync.progress); if (this.checkTimer == null) { this.checkTimer = setInterval(this.checkSync, 1000); } } } else { console.log(response); } }) .catch(error => { console.log(error); }); }, stopSync: function () { this.btns_state = 2; axios .post('/bitrix/sprod_dsync_sync.php?action=stop_sync&profile=' + this.$profile_id, {}) .then(response => { }) .catch(error => { console.log(error); }); }, updateProgress: function (step, count, value) { Vue.set(this.progress, step, count ? (value / count * this.progress_step_max[step]) : 0); for (let i = 0; i < step && i < 5; i++) { Vue.set(this.progress, i, this.progress_step_max[i]); } for (let i = step + 1; i < 5; i++) { Vue.set(this.progress, i, 0); } }, updateBlock() { this.$emit('save', 'sync'); }, changePBarParams() { this.progress_length = 0; for (let i = 0; i < 5; i++) { Vue.set(this.progress_step_max, i, this.tab_fields.man_sync_steps[i] * this.progress_step_max_def[i]); this.progress_length += this.progress_step_max[i]; } } }, watch: { 'tab_fields.man_sync_steps': function(new_val, old_val) { this.changePBarParams(); }, }, mounted() { this.checkSync(); }, template: ` <div> <b-form-group :label="$t('page.SP_DS_IBLOCKS_EDIT_SYNC_MAN_SYNC_SYNC_OPTIONS')" class="mb-3"> <b-form-checkbox v-model="tab_fields.man_sync_steps[0]" @change="updateBlock()" class="checkbox-success">{{ $t("page.SP_DS_IBLOCKS_EDIT_SYNC_MAN_SYNC_SECT_SYNC") }}</b-form-checkbox> <b-form-checkbox v-model="tab_fields.man_sync_steps[1]" @change="updateBlock()" class="checkbox-success">{{ $t("page.SP_DS_IBLOCKS_EDIT_SYNC_MAN_SYNC_SECT_DEL") }}</b-form-checkbox> <b-form-checkbox v-model="tab_fields.man_sync_steps[2]" @change="updateBlock()" class="checkbox-success">{{ $t("page.SP_DS_IBLOCKS_EDIT_SYNC_MAN_SYNC_PROD_SYNC") }}</b-form-checkbox> <b-form-checkbox v-model="tab_fields.man_sync_syncprod_onlynew" @change="updateBlock()" class="checkbox-warning ml-2">{{ $t("page.SP_DS_IBLOCKS_EDIT_SYNC_MAN_SYNC_ONLY_NEW") }}</b-form-checkbox> <b-form-checkbox v-model="tab_fields.man_sync_steps[3]" @change="updateBlock()" class="checkbox-success">{{ $t("page.SP_DS_IBLOCKS_EDIT_SYNC_MAN_SYNC_PRICE_SYNC") }}</b-form-checkbox> <b-form-checkbox v-model="tab_fields.man_sync_steps[4]" @change="updateBlock()" class="checkbox-success">{{ $t("page.SP_DS_IBLOCKS_EDIT_SYNC_MAN_SYNC_PROD_DEL") }}</b-form-checkbox> </b-form-group> <b-button variant="danger" @click="runSync" :disabled="btns_state>0">{{ $t("page.SP_DS_IBLOCKS_EDIT_SYNC_MAN_SYNC_RUN") }} <i class="fas fa-arrow-right"></i></b-button> <b-button @click="stopSync" :disabled="btns_state==0||btns_state==2">{{ $t("page.SP_DS_IBLOCKS_EDIT_SYNC_MAN_SYNC_STOP") }} <i class="fas fa-stop"></i></b-button> <b-progress :max="progress_length" class="mt-3 mb-1" animated> <b-progress-bar :value="progress[0]" variant="success"></b-progress-bar> <b-progress-bar :value="progress[1]" variant="danger"></b-progress-bar> <b-progress-bar :value="progress[2]" variant="success"></b-progress-bar> <b-progress-bar :value="progress[3]" variant="info"></b-progress-bar> <b-progress-bar :value="progress[4]" variant="danger"></b-progress-bar> </b-progress> <p v-if="btns_state">{{ hint }}</p> </div> `, mixins: [utilFuncs, componentsFuncs], }); // Additional synchronization Vue.component('profile-addsync', { props: ['tab_fields'], // JS passes objects by reference data: function () { return { code: 'add_sync', state: { display: true, active: false, }, } }, methods: { updateBlock() { this.$emit('save', 'sync'); } }, template: ` <div> <div class="radio mb-2"> <input v-model="tab_fields.add_sync_schedule" type="radio" name="add_sync_schedule" id="add_sync_schedule_disabled" value="" checked> <label for="add_sync_schedule_disabled"> {{ $t("page.SP_DS_IBLOCKS_EDIT_SYNC_ADD_SYNC_SCHEDULE_DISABLED") }} </label> </div> <div class="radio radio-info mb-2"> <input v-model="tab_fields.add_sync_schedule" type="radio" name="add_sync_schedule" id="add_sync_schedule_1h" value="1h"> <label for="add_sync_schedule_1h"> {{ $t("page.SP_DS_IBLOCKS_EDIT_SYNC_ADD_SYNC_SCHEDULE_1H") }} </label> </div> <div class="radio radio-info mb-2"> <input v-model="tab_fields.add_sync_schedule" type="radio" name="add_sync_schedule" id="add_sync_schedule_1d" value="1d"> <label for="add_sync_schedule_1d"> {{ $t("page.SP_DS_IBLOCKS_EDIT_SYNC_ADD_SYNC_SCHEDULE_1D") }} </label> </div> <button class="btn btn-success" @click="updateBlock()"> {{ $t("page.SP_DS_IBLOCKS_EDIT_SAVE") }} </button> </div> `, mixins: [utilFuncs, componentsFuncs], }); // Info Vue.component('profile-info', { props: [], template: ` <b-alert show variant="warning" v-html="$t('page.SP_DS_IBLOCKS_EDIT_INFO_SAVE_CHANGES')"></b-alert> `, }); /** * * VUE APP * */ const i18n = new VueI18n({ locale: 'ru', messages, }); var app = new Vue({ el: '#app', i18n, mixins: [utilFuncs, mainFuncs], data: { main_error: '', info: { crm: { iblocks: [], iblock_link: '', search_fields: [], }, store: { search_fields: [], }, fields: {}, }, state: { main: { display: true, active: false, messages: [], }, base: { display: true, active: false, messages: [], }, props: { display: true, active: false, messages: [], }, catalog: { display: true, active: false, messages: [], }, other: { display: true, active: false, messages: [], }, sync: { display: true, active: false, messages: [], }, man_sync: { display: true, active: false, messages: [], }, add_sync: { display: true, active: false, messages: [], }, }, }, methods: { // Blocks update updateBlocks: function (calling_block) { this.startLoadingInfo(); this.$emit('blocks_update_before', calling_block); this.ajaxReq('iblocks_profile_info', 'post', { id: this.$profile_id, }, (response) => { this.info = response.data.info; this.state = response.data.state; this.ajaxReq('iblocks_profile_get', 'post', { id: this.$profile_id, }, (response) => { this.$emit('blocks_update', response.data, calling_block); }, (response) => { }, (response) => { // Callback success if (typeof callback === 'function') { callback(response); } this.stopLoadingInfo(); }); }); }, }, mounted() { this.updateBlocks(); }, });