123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563 |
- <template>
- <el-card class="codecount-container">
- <div slot="header" class="header">
- <div class="header-left">
- <span><!-- 代码运算 -->{{$t('EtaBasePage.algorithm_btn')}}</span>
- <span class="opt-btn" @click="operationTipShow=true">
- <img src="~@/assets/img/data_m/icon01.png" alt="">
- <!-- 操作说明 -->
- <span>{{$t('CodeCountPage.opt_tip_btn')}}</span>
- </span>
- </div>
- <div>
- <el-button type="primary" @click="runCodeHandle"><!-- 运行 -->{{$t('CodeCountPage.run_btn')}}</el-button>
- <el-button type="primary" plain @click="saveHandle" v-if="!isView"><!-- 保存 -->{{$t('Dialog.confirm_save_btn')}}</el-button>
- </div>
- </div>
- <div class="bottom">
- <el-col :span="15" class="bottom-wrapper left-wrapper">
- <div class="code-editor">
- <code-mirror ref="codeRef" :code="runCode" @initResult="initResult"/>
- </div>
- <div class="code-result">
- <span><!-- 结果展示 -->{{$t('CodeCountPage.res_show')}}</span>
- <div class="code-result-wrapper" v-if="isShowResult">
- <data-table
- :data="runResultData"
- />
- </div>
- </div>
- </el-col>
- <el-col :span="8" class="bottom-wrapper">
- <el-tabs>
- <el-tab-pane :label="$t('CodeCountPage.tab_info')">
- <el-form
- ref="diaForm"
- label-position="left"
- inline
- label-width="110px"
- :model="formData"
- :disabled="isView"
- >
- <el-form-item :label="$t('Edb.Detail.e_name')" prop="edb_name">
- <el-input
- v-model="formData.edb_name"
- :placeholder="$t('Edb.InputHolderAll.input_name')"
- style="width:220px"
- />
- </el-form-item>
- <el-form-item :label="$t('Edb.Detail.e_unit')" prop="unit">
- <selectUnit
- v-model="formData.unit"
- style="width:220px"
- />
- </el-form-item>
- <el-form-item :label="$t('Edb.Detail.e_fre')" prop="frequency">
- <el-select
- v-model="formData.frequency"
- :placeholder="$t('Edb.InputHolderAll.input_fre')"
- clearable
- style="width:220px">
- <el-option
- v-for="item in frequencyArr"
- :key="item.label"
- :label="item.label"
- :value="item.value">
- </el-option>
- </el-select>
- </el-form-item>
- <el-form-item :label="$t('Edb.Detail.e_menu')" prop="menu">
- <el-cascader
- v-model="formData.menu"
- :options="menuOptions"
- :props="{
- label: 'ClassifyName',
- value: 'ClassifyId',
- children: 'Children',
- checkStrictly: true,
- emitPath: false,
- }"
- @change="menuChange"
- clearable
- style="width:220px"
- :placeholder="$t('Edb.InputHolderAll.input_menu')"/>
- </el-form-item>
- </el-form>
- </el-tab-pane>
- <el-tab-pane :label="$t('CodeCountPage.tab_edb')" v-if="!isView">
- <el-form
- label-position="left"
- inline
- label-width="120px"
- >
- <el-form-item :label="$t('Edb.Detail.source')">
- <el-cascader
- v-model="fromType"
- :options="allFromArr"
- :props="{
- label: 'SourceName',
- value: 'EdbSourceId',
- children: 'Child',
- emitPath: false
- }"
- clearable
- style="width:220px"
- :placeholder="$t('Edb.Detail.source')"/>
- <!-- <el-select
- v-model="fromType"
- placeholder="请选择来源"
- style="width:220px">
- <el-option
- v-for="item in allFromArr"
- :key="item.key"
- :label="item.name"
- :value="item.key">
- </el-option>
- </el-select> -->
- </el-form-item>
- <el-form-item :label="$t('Edb.InputHolderAll.input_name_orid')">
- <el-select
- v-model="search_txt"
- v-loadMore="searchLoad"
- ref="searchRef"
- :filterable="!search_txt"
- remote
- clearable
- :placeholder="$t('Edb.InputHolderAll.input_name_orid')"
- :remote-method="searchHandle"
- @click.native="inputFocusHandle"
- style="width:220px"
- >
- <i slot="prefix" class="el-input__icon el-icon-search"></i>
- <el-option
- v-for="item in searchOptions"
- :key="item.EdbInfoId"
- :label="currentLang==='en'?(item.EdbNameEn||item.EdbName):item.EdbName"
- :value="item.EdbInfoId"
- :disabled="!item.HaveOperaAuth"
- >
- <div>
- <img
- :src="$icons.lock_ico2"
- width="18"
- height="18"
- style="vertical-align:middle"
- v-if="!item.HaveOperaAuth"
- />
- {{currentLang==='en'?(item.EdbNameEn||item.EdbName):item.EdbName}}
- </div>
- </el-option>
- </el-select>
- </el-form-item>
- </el-form>
- <div class="search-result">
- <p>{{$t('CodeCountPage.res_search')}} <span style="color: #999;">(<!-- 展示指标所在表结构及调取指标代码 -->{{$t('CodeCountPage.res_search_tip')}})</span></p>
- <template v-if="resultInfo.sheet_name">
- <table border>
- <thead>
- <tr>
- <td v-for="item in resultInfo.headers" :key="item">{{item}}</td>
- </tr>
- </thead>
- <tbody>
- <tr v-for="(item,index) in resultInfo.sheetArr" :key="item.key">
- <td :rowspan="resultInfo.sheetArr.length" v-if="index === 0">{{resultInfo.sheet_name}}</td>
- <td>{{item.key}}</td>
- <td>{{item.label}}</td>
- </tr>
- </tbody>
- </table>
- <div class="sql-code" v-html="resultInfo.sql_code"></div>
- <el-button type="primary" class="copy-btn" @click="copyCode" :data-clipboard-text="resultInfo.sql_code"><!-- 复制代码 -->{{$t('CodeCountPage.copy_code')}}</el-button>
- </template>
- </div>
- </el-tab-pane>
- </el-tabs>
- </el-col>
- </div>
- <!-- 操作说明 -->
- <el-dialog
- :title="$t('CodeCountPage.opt_tip_btn')"
- :visible.sync="operationTipShow"
- :close-on-click-modal="false"
- center
- v-dialogDrag
- :append-to-body="true"
- width="900px"
- >
- <div class="dialog-container">
- <div style="line-height:20px;color:#000000;font-size: 14px;word-break: normal;" v-html="$t('CodeCountPage.opt_tip_btn_text')"></div>
- </div>
- </el-dialog>
- </el-card>
- </template>
- <script>
- import { dataBaseInterface } from '@/api/api.js';
- import { unitArr,frequencySelectList } from '@/utils/defaultOptions';
- import storage from '@/utils/storage.js';
- import codeMirror from './compoments/codeMirror';
- import dataTable from './compoments/dataTable';
- import { mapState } from 'vuex';
- export default {
- name:'',
- components: { codeMirror,dataTable },
- computed: {
- ...mapState({
- currentLang: state => state.lang,
- }),
- frequencyArr(){
- return frequencySelectList(['半年度'])
- },
- },
- data () {
- return {
- isView: this.$route.query.isView ? true : false,
- formData: {},
- fromType:"",
- unitArr,
- allFromArr:[],//所有指标来源
- /* frequencyArr, */
- menuOptions:[],//目录数组
- search_txt: '',
- search_have_more: false,
- searchOptions:[],
- search_page: 1,
- current_search: '',
- isShowResult: false,
- runCode: '',
- runResultData:[],//运行结果
- resultInfo: {
- // headers: ['表名','字段名','*字段说明'],
- headers: [this.$t('CodeCountPage.table_name'),this.$t('CodeCountPage.field_name'),this.$t('CodeCountPage.field_instru')],
- sheetArr:[],
- sheet_name: '',
- sql_code: ''
- },
- operationTipShow:false
- };
- },
- watch: {
- //每搜索一次记录一次
- search_txt(newval) {
- if(!newval) return;
- let historySearch = storage.get('pycode_seachlist') || [];
- let obj = {
- EdbInfoId: newval,
- EdbName: this.searchOptions.find(_ => _.EdbInfoId===newval).EdbName
- }
- //有搜索记录删除上条
- let index = historySearch.findIndex(_ => _.EdbInfoId === newval)
- if(index !== -1) historySearch.splice(index, 1);
- historySearch.unshift(obj)
- storage.set('pycode_seachlist',historySearch,1)
- this.getEdbSheeetInfo(newval);
- }
- },
- methods: {
- /* 运行代码 */
- runCodeHandle: _.debounce(function() {
- if(!this.$refs.codeRef.codeContent) return this.$message.warning(this.$t('CodeCountPage.no_code_msg'));
- this.isShowResult = false;
- const loading = this.$loading({
- lock: true,
- text: `${this.$t('CodeCountPage.run_ing')}...`,
- target:'.left-wrapper',
- spinner: 'el-icon-loading'
- });
- dataBaseInterface.runCode({
- PythonCode: encodeURIComponent(this.$refs.codeRef.codeContent)
- }).then(res => {
-
- loading.close();
- if(res.Ret !== 200) return
- // this.$message.success('运行成功')
- this.$message.success(this.$t('CodeCountPage.run_success'))
- const { date,value } = res.Data;
- const data_arr = []
- for(let i in date) {
- data_arr.push([date[i],value[i]])
- }
- this.runResultData = data_arr;
- this.isShowResult = true;
- })
- },200),
- /* 获取指标详情 */
- getEdbInfo() {
- if(!this.$route.query.edbid) return;
- dataBaseInterface.countCodeDetail({
- EdbInfoId: Number(this.$route.query.edbid)
- }).then(res => {
- if(res.Ret !== 200) return
-
- const { EdbInfoDetail,PythonCode } = res.Data;
- const { EdbName,EdbNameEn,ClassifyId,Frequency,Unit,UnitEn } = EdbInfoDetail;
- this.formData = {
- edb_name: this.currentLang==='en'?EdbNameEn:EdbName,
- menu: ClassifyId,
- frequency: Frequency,
- unit: this.currentLang==='en'?UnitEn:Unit
- }
- this.runCode = PythonCode
-
- })
- },
- /* 获取表结构 */
- getEdbSheeetInfo(EdbInfoId) {
- dataBaseInterface.edbSheetDetail({
- EdbInfoId
- }).then(res => {
- if(res.Ret !== 200) return
-
- const { ColumnList,TableName,TemplateStr } = res.Data;
- this.resultInfo.sheet_name = TableName;
- this.resultInfo.sql_code = decodeURIComponent(TemplateStr);
- this.resultInfo.sheetArr = ColumnList.map(_ => {
- let key = Object.keys(_)[0];
- return {
- key,
- label: _[key]
- }
- })
- })
- },
- /* code变化时重置结果展示 */
- initResult() {
- this.isShowResult = false
- },
- /* 复制代码 */
- copyCode() {
- var clipboard = new this.Clipboard('.copy-btn')
- clipboard.on('success', e => {
- // this.$message.success('复制成功')
- this.$message.success(this.$t('MsgPrompt.copy_success_msg'))
- e.clearSelection() // 释放内存
- clipboard.destroy()
- })
- // // 浏览器不支持
- clipboard.on('error', e => {
- // this.$message.warning('浏览器暂不支持')
- this.$message.warning(this.$t('MsgPrompt.browser_not_support'))
- // 释放内存
- clipboard.destroy()
- })
- },
-
- /* 保存代码 */
- async saveHandle() {
- if(!this.formData.edb_name || !this.formData.menu || !this.formData.frequency || !this.formData.unit) return this.$message.warning(this.$t('CodeCountPage.noenough_info_msg'))
- if(!this.isShowResult) return this.$message.warning(this.$t('CodeCountPage.run_msg'))
- const loading = this.$loading({
- lock: true,
- text: `${this.$t('MsgPrompt.saveing_msg')}...`,
- target:'.codecount-container',
- spinner: 'el-icon-loading'
- });
-
- const { edb_name,menu,frequency,unit } = this.formData
- let params = {
- PythonCode: encodeURIComponent(this.$refs.codeRef.codeContent),
- EdbName: edb_name,
- Frequency: frequency,
- Unit: unit,
- ClassifyId: menu
- }
-
- const { Ret,Data } = this.$route.query.edbid ? await dataBaseInterface.editCountCode({ ...params,EdbInfoId: Number(this.$route.query.edbid) }) : await dataBaseInterface.addCountCode(params);
-
- loading.close();
- if( Ret !== 200 ) return
- // this.$message.success('保存成功')
- this.$message.success(this.$t('MsgPrompt.saved_msg'))
- const { UniqueCode,EdbInfoId } = Data;
- this.$router.replace({path:'/database', query: {
- code: UniqueCode,
- id: EdbInfoId
- }});
- },
- /* 获取目录结构 */
- getMenu() {
- dataBaseInterface.menuListV3().then((res) => {
- if (res.Ret !== 200) return
- this.filterNodes(res.Data.AllNodes||[]);
- this.menuOptions = res.Data.AllNodes || [];
- });
- },
- // 递归改变第三级目录结构
- filterNodes(arr) {
- arr.length &&
- arr.forEach((item) => {
- item.Children.length && this.filterNodes(item.Children);
- if (!item.Children.length) {
- delete item.Children;
- }
- });
- },
- /* 选择目录 */
- menuChange(val) {
- // this.formData.menu = val.length ? val[val.length - 1] : '';
- },
- /* 搜索 */
- searchHandle(query) {
- this.search_page = 1;
- this.current_search = query;
- this.searchApi(this.current_search)
- },
- searchApi(query,page=1) {
- if(!query){ this.searchOptions = []; return }
- dataBaseInterface.targetSearchByPage({
- KeyWord:query,
- CurrentIndex: page,
- Source: this.fromType || 0,
- }).then(res => {
- if(res.Ret !== 200) return
- const { List,Paging } = res.Data;
- this.search_have_more = page < Paging.Pages;
- this.searchOptions = page === 1 ? List : this.searchOptions.concat(List);
- })
- },
- /* 聚焦获取当前检索 */
- inputFocusHandle(e) {
- this.search_page = 1;
- this.current_search = e.target.value;
- this.searchOptions = this.fromType ? [] : storage.get('pycode_seachlist');
- // this.searchApi(this.current_search);
- },
- searchLoad() {
- if(!this.search_have_more) return;
- this.searchApi(this.current_search,++this.search_page);
- },
- getTargetSource(){
- dataBaseInterface.getCodecountEdbSources().then(res=>{
- if(res.Ret!==200) return
- if(res.Data){
- this.allFromArr = res.Data.map(_ => ({
- ..._,
- Child: _.Child.map(_item => ({
- ..._item,
- Child:null
- }))
- }))
- }
- })
- }
- },
- mounted() {
- this.getEdbInfo();
- this.getMenu();
- this.getTargetSource()
- },
- }
- </script>
- <style lang='scss' scoped>
- *{ box-sizing: border-box;}
- .codecount-container {
- .header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- font-size: 16px;
- .header-left{
- display:flex;
- align-items: center;
- .opt-btn{
- display:inline-flex;
- align-items: center;
- margin-left: 10px;
- cursor: pointer;
- img{
- width: 32px;
- height: 34px;
- }
- span{
- color:rgb(64, 158, 255);
- }
- }
- }
- }
- .bottom {
- height: calc(100vh - 240px);
- .bottom-wrapper {
- padding: 20px;
- height: 100%;
- border: 1px solid #ECECEC;
- border-radius: 4px;
- &:first-child {
- margin-right: 20px;
- padding: 20px 0;
- }
- .code-editor {
- padding: 0 20px;
- }
- .code-result {
- border-top: 1px solid #ECECEC;
- margin-top: 20px;
- padding: 20px;
- }
- .search-result {
- border-top: 1px solid #ECECEC;
- padding: 20px 0;
- table {
- width: 100%;
- margin-top: 22px;
- td{ border-color: #DCDFE6; width: 33%; height: 36px;text-align: center;}
- }
- .sql-code {
- min-height: 100px;
- border: 1px solid #DCDFE6;
- border-top: none;
- }
- .copy-btn {
- display: block;
- margin: 20px auto;
- }
- }
- }
- }
- }
- .dialog-container{
- padding:0 60px 60px ;
- }
- </style>
- <style lang="scss">
- .codecount-container {
- .el-tabs__nav-wrap::after {
- background-color: #fff;
- }
- }
- </style>
|