Commit 528ab007 authored by 陶进's avatar 陶进

提交一下

parent 745a1a49
...@@ -3,6 +3,8 @@ const fs = require('fs') ...@@ -3,6 +3,8 @@ const fs = require('fs')
const http = require('http') const http = require('http')
const loadUrl = require('./build_config/url').loadUrl const loadUrl = require('./build_config/url').loadUrl
console.log(loadUrl)
var appPath = app.getAppPath() var appPath = app.getAppPath()
var getRemoteModule = async function (name, url) { var getRemoteModule = async function (name, url) {
......
const fs = require('fs')
const os = require('os')
const platform = os.platform()
const filePath = __filename.replace('.js','.vue')
var name
if(platform == 'darwin'){
name = filePath.split('/').pop().replace('.vue','')
}else{
name = filePath.split('\\').pop().replace('.vue','')
}
var data = fs.readFileSync(filePath);
var str = data.toString()
str.substring(0, str.lastIndexOf('</template>'))
str = str.replace('<template>','')
var keyBord = require('../../lib/keyBord')
var merge = require('../../lib/merge')
// const company = require('../../../components/indexConditions/company/company.js')
const conditionFuns = require('../../lib/conditionFun')
module.exports = {
name: name,
data: function () {
return {
initIndexId: 0,
indexParams: {},
numParams: {},
dateParams: {},
symbolParams: {},
functionParams: {},
keybordData: [],
mergeTypeData: merge.mergeData,
selectedController: {},
searchCompanyLoading: false,
companyData: [],
//添加指标
addIndexVisible: false,
modalActiveTab: '1',
selectedIndex: {
name: '',
code: '',
mark: '',
typeContent: null,
mergeType: '合并本期',
yearType: 1,
quarterType: 1,
t: 0,
q: 0,
inputYear: '',
inputQuarter: '',
needMergeType: false,
needReportData: false,
needCompany: false
},
selectedMergeType: '',
selectedReportYearType: '',
selectedReportQuarterType: '',
Tyear: 0,
Qquarter: 0,
selectedReportQuarter: '',
selectedReportYear: '',
filterInput: '',
treeProps: {
children: 'Sub',
label: 'Name'
},
indexNameData: [],
range: null,
selectedNum: 0,
selectedDate: '',
addNumVisible: false,
addDateVisible: false,
copiedController: {},
contentId: 0,
addFuncVisible: false,
editingFuncParamsIndex: 0
}
},
// components: {'company':company },
props:['treeData','type'],
template: str,
computed: {
},
watch: {
selectedController: {
handler: function() {
this.setAppointedIndexName(this.selectedController)
},
deep: true
}
},
mounted() {
this.initKeybord()
this.setSelfId()
this.setKeyboardData()
},
methods: {
deleteFuncParams (index) {
var origin = this.selectedController.originParams.params
var value = this.selectedController.paramsValue
origin.splice(index, 1)
value.splice(index, 1)
this.resetFuncValue(this.selectedController)
},
addMoreParams () {
var origin = this.selectedController.originParams.params
var value = this.selectedController.paramsValue
origin.push(JSON.parse(JSON.stringify(origin[0])))
value.push({})
this.selectedController = Object.assign({}, this.selectedController)
this.resetFuncValue(this.selectedController)
},
getFuncParamsName (arr) {
var obj = {
0: '指标',
1: '数字',
2: '字符',
3: '时间',
4: '公式'
}
var newArr = arr.map(item => {
return obj[item]
})
return newArr.join('或者')
},
openFunctionParams (index, type) {
this.editingFuncParamsIndex = index
this.$parent.editFuctionType = type
this.$parent.editFuctionVisible = true
},
receiveFunctionParam (params) {
this.selectedController.paramsValue[this.editingFuncParamsIndex] = params
this.selectedController = Object.assign({}, this.selectedController)
this.resetFuncValue(this.selectedController)
console.log(this.selectedController)
},
resetActiveInput () {
document.getElementById(this.selectedController.id).classList.add('active')
},
//重新设置指定id的方法的value
resetFuncValue (selectedController) {
var id = selectedController.id
var dom = document.getElementById(id)
var arr = []
selectedController.paramsValue.forEach(item => {
var text = this.getShowDomText(item.showDom)
arr.push(text)
})
var name = selectedController.key.replace('( )','')
var value = name + '(' + arr.join(', ') + ')'
dom.style.width = this.getInputLength(value) + 'px'
dom.setAttribute('value', value)
},
changeFuncParams (index) {
console.log(this.selectedController)
console.log(index)
this.$parent.editFuctionVisible = true
this.$nextTick(()=>{
//要先注入参数
this.$parent.resetFuncParams(this.selectedController, index)
})
},
getShowDomText (html) {
var div = document.createElement('div')
if(html){
div.innerHTML = html
return div.innerText
}else{
return '未设置'
}
},
//设置方法的参数
setKeyboardData () {
if(this.type == 'index'){
this.keybordData = keyBord.keybordData
}else if(this.type == 'function'){
this.keybordData = keyBord.functionKeybord
}
},
//向父组件传递数据
sendDataToHost (saveData) {
var content = document.getElementById(this.contentId)
var inputs = content.getElementsByTagName('input')
var params = {
indexParams: {},
dateParams: {},
numParams: {},
symbolParams: {},
functionParams: {},
dom: ''
}
var typeDic = {
1: 'indexParams',
2: 'dateParams',
3: 'numParams',
4: 'symbolParams',
5: 'functionParams'
}
Array.from(inputs).forEach(item => {
var type = item.getAttribute('type')
var id = item.id
var param = JSON.parse(JSON.stringify(this[typeDic[type]][id]))
params[typeDic[type]][id] = param
})
params.dom = content.innerHTML
params.showDom = this.changeInputToSpan(inputs)
if(!saveData){
this.initCalData()
}
return params
},
//重置所有参数
initCalData () {
this.indexParams = {}
this.numParams = {}
this.dateParams = {}
this.symbolParams = {}
this.functionParams = {}
var content = document.getElementById(this.contentId)
content.innerHTML = ''
this.removeAllActive()
this.selectedController = {}
},
changeInputToSpan (inputs) {
var div = document.createElement('div')
Array.from(inputs).forEach(item => {
var span = document.createElement('span')
span.innerHTML = item.value
span.setAttribute('type', item.getAttribute('type'))
div.appendChild(span)
})
var spans = div.getElementsByTagName('span')
this.formatShowDom(spans)
return div.innerHTML
},
formatShowDom (spans) {
var brackets = []
var numArea = []
Array.from(spans).forEach(item => {
var value = item.innerText
var br = document.createElement('br')
if('()&&||'.indexOf(value) >= 0 || (item.nextSibling && '()&&||'.indexOf(item.nextSibling.innerText) >= 0)){
this.insertAfter(br,item)
}
})
Array.from(spans).forEach((item, index) => {
var value = item.innerText
if(value == '(' || value == ')'){
brackets.push({
indet: 0,
from: item,
value: value,
originIndex: index
})
}
})
brackets.forEach((item,index) => {
if(index == 0){
item.indent = 0
var text = this.createAppointedText(item.indent)
item.from.parentNode.insertBefore(text, item.from)
}else{
var newIndent = brackets[index - 1].indent
if(brackets[index - 1].value !== item.value){
item.indent = newIndent
var text = this.createAppointedText(newIndent)
item.from.parentNode.insertBefore(text, item.from)
}else{
if(item.value == '('){
item.indent = newIndent + 4
}else{
item.indent = newIndent - 4
}
var text = this.createAppointedText(item.indent)
item.from.parentNode.insertBefore(text, item.from)
}
numArea.push({
start: brackets[index - 1].originIndex ,
end: item.originIndex,
indent: brackets[index - 1].indent,
value: brackets[index - 1].value
})
}
})
Array.from(spans).forEach((item, index) => {
var value = item.innerText
if(value !== '(' && value !== ')' && item.previousSibling && item.previousSibling.nodeName == 'BR'){
numArea.forEach(area => {
if(index > area.start && index < area.end){
var newIndent
if(area.value == '('){
newIndent = area.indent + 4
}else{
newIndent = area.indent
}
var text = this.createAppointedText(newIndent)
item.parentNode.insertBefore(text, item)
}
})
}
})
},
formatGrammar () {
var noOtherContent = this.emptyOtherText() //获取清空多余字段后的内容
this.selectAllContent() //选中整个输入框
var formatContent = document.createElement('div')
formatContent.innerHTML = noOtherContent
var inputs = formatContent.getElementsByTagName('input')
Array.from(inputs).forEach(item => {
var value = item.value
var br = document.createElement('br')
if('()&&||+-*/'.indexOf(value) >= 0 || (item.nextSibling && '()&&||+-*/'.indexOf(item.nextSibling.value) >= 0)){
this.insertAfter(br,item)
}
})
//此时得出一个没有缩进的内容
this.findAllbrackets(inputs)
document.execCommand('insertHTML', false, formatContent.innerHTML)
return true
},
findAllbrackets (inputs) {
var brackets = []
var numArea = []
Array.from(inputs).forEach((item, index) => {
var value = item.value
if(value == '(' || value == ')'){
brackets.push({
indet: 0,
from: item,
value: value,
originIndex: index
})
}
})
brackets.forEach((item,index) => {
if(index == 0){
item.indent = 0
var text = this.createAppointedText(item.indent)
item.from.parentNode.insertBefore(text, item.from)
}else{
var newIndent = brackets[index - 1].indent
if(brackets[index - 1].value !== item.value){
item.indent = newIndent
var text = this.createAppointedText(newIndent)
item.from.parentNode.insertBefore(text, item.from)
}else{
if(item.value == '('){
item.indent = newIndent + 4
}else{
item.indent = newIndent - 4
}
var text = this.createAppointedText(item.indent)
item.from.parentNode.insertBefore(text, item.from)
}
numArea.push({
start: brackets[index - 1].originIndex ,
end: item.originIndex,
indent: brackets[index - 1].indent,
value: brackets[index - 1].value
})
}
})
Array.from(inputs).forEach((item, index) => {
var value = item.value
if(value !== '(' && value !== ')' && item.previousSibling && item.previousSibling.nodeName == 'BR'){
numArea.forEach(area => {
if(index > area.start && index < area.end){
var newIndent
if(area.value == '('){
newIndent = area.indent + 4
}else{
newIndent = area.indent
}
var text = this.createAppointedText(newIndent)
item.parentNode.insertBefore(text, item)
}
})
}
})
},
createAppointedText (num) {
var str = '', text
for(var i = 0; i < num; i++){
str+='\u00A0'
}
text = document.createTextNode(str)
return text
},
insertAfter(newElement, targetElement) {
var parent = targetElement.parentNode
if (parent.lastChild == targetElement){
parent.appendChild(targetElement)
} else {
parent.insertBefore(newElement, targetElement.nextSibling);
}
},
//清空多余字段并返回新的内容
emptyOtherText () {
var content = document.getElementById(this.contentId)
var newHTML = ''
var inputs = content.getElementsByTagName('input')
Array.from(inputs).forEach(item => {
newHTML+=item.outerHTML
})
this.selectAllContent()
return newHTML
},
//选中整个输入框
selectAllContent () {
var content = document.getElementById(this.contentId)
var selection = window.getSelection()
var range = document.createRange()
range.selectNodeContents(content)
selection.removeAllRanges()
selection.addRange(range)
},
setHtml (html) {
var content = document.getElementById(this.contentId)
content.innerHTML = html
this.$nextTick(()=>{
this.removeAllActive()
})
},
setSelfId () {
this.contentId = this.createIndexId()
},
//校验语法
checkGrammar (type) {
var content = document.getElementById(this.contentId)
var inputs = content.getElementsByTagName('input')
var code = 'var func;'
Array.from(inputs).forEach(item => {
var str = item.value
var type = item.getAttribute('type')
if(item.getAttribute('type') == 3){ //数字
str = str.replace(/\[.*?\]/g,'')
}else if(type == 1){ //指标
str = '100'
}else if(type == 5){ //函数
str = 'func'
}
str.replace(/\[.*?\]/g,'')
code+=str
})
console.log(code)
var isPass = false
setTimeout(()=>{
if(isPass){
if(type == 'tip'){
this.$message({
message: '语法校验通过',
type: 'success'
})
}
}else{
this.$message({
message: '语法校验未通过',
type: 'error'
})
}
}, 500)
eval(code)
isPass = true
return isPass
},
//复制元素
copyIndex () {
this.copiedController = JSON.parse(JSON.stringify(this.selectedController))
this.$message({
message: '当前元素已复制到剪切板',
type: 'success'
})
},
//粘贴元素
pasteIndex () {
switch (this.copiedController.type) {
case 1: //指标
this.insertIndex(this.copiedController)
break;
case 2: //日期
this.insertDate(this.copiedController.value)
break;
case 3: //数字
this.insertNum(this.copiedController.value)
break;
case 4: //符号
this.insertSymbol(this.copiedController)
break;
case 5: //方法
this.pasteFunc(this.copiedController)
break;
}
},
pasteFunc (copiedController) {
var funcName = copiedController.key.replace('( )','')
var arr = []
copiedController.paramsValue.forEach(item => {
var text = this.getShowDomText(item.showDom)
arr.push(text)
})
var value = funcName + '(' + arr.join(', ') + ')'
var width = this.getInputLength(value) + 'px'
this.setRange()
var id = this.createIndexId()
var width = this.getInputLength(value) + 'px'
this.$nextTick(()=>{
if(!document.execCommand('insertHTML', false, '<input readonly class="cal-index" type="5" id="'+ id +'" style="width:'+ width +'" value="'+ value +'" />')){
this.$message({
message: '请先在输入区定位光标!',
type: 'warning'
})
}else{
var newFuncObj = JSON.parse(JSON.stringify(copiedController))
newFuncObj.id = id
this.functionParams[id] = newFuncObj
this.$set(this, 'selectedController', this.functionParams[id])
this.removeAllActive()
document.getElementById(id).classList.add('active')
}
})
},
filterTreeNode (value, data) {
if (!value) return true;
return data.Name.indexOf(value) !== -1;
},
//过滤指标
filterIndexText () {
this.$refs.tree.filter(this.filterInput);
},
//搜索公司
searchCompany(query) {
var that = this
that.selectLoading = true
http.netPost('Data/Stock/GetHsData', {
'CollectionName': 'hs_stock_basic',
'WhereOr': [
{
'FieldName': 'hs_stock_basic.F001V',
'State': 2,
'Value': query
},
{
'FieldName': 'hs_stock_basic.SECCODE',
'State': 2,
'Value': query
},
{
'FieldName': 'hs_stock_basic.SECNAME',
'State': 2,
'Value': query
}
],
'Current': 0,
'Psize': 10
})
.then((res) => {
that.companyData = res.data.Data.Records
that.searchCompanyLoading = false
})
},
inputKeydown (event) {
if(event.code !== 'Backspace'
&& event.code !== 'Space'
&& event.code !== 'ArrowUp'
&& event.code !== 'ArrowDown'
&& event.code !== 'ArrowLeft'
&& event.code !== 'ArrowRight'
){
if(event.code == 'Enter'){
document.execCommand('insertHTML', false, '<br>')
event.preventDefault();
}else{
event.preventDefault();
}
}else{
}
},
//指标点击事件
contentClick (e) {
if(e.target.classList.contains('cal-index')){
var id = e.target.id
var type = e.target.getAttribute('type')
this.setController(id, type)
this.removeAllActive()
e.target.classList.add('active')
}else{
this.removeAllActive()
this.selectedController = {}
}
},
//设置右侧面板
setController (id, type) {
var type = parseInt(type)
if(type == 1){
this.selectedController = this.indexParams[id]
}else if(type == 2){
this.selectedController = this.dateParams[id]
}else if(type == 3){
this.selectedController = this.numParams[id]
}else if(type == 4){
this.selectedController = this.symbolParams[id]
}else if(type == 5){
this.selectedController = this.functionParams[id]
}
},
//清除所有的active
removeAllActive () {
var containers = document.getElementsByClassName('calculater-display')
Array.from(containers).forEach(item => {
var indexs = item.getElementsByClassName('cal-index')
Array.from(indexs).forEach(index => {
index.classList.remove('active')
})
})
},
//keybord点击事件
clickCalText (e, item) {
var select = window.getSelection()
if(select.type == 'None'){
this.$message({
message: '请先定位光标!',
type: 'warning'
})
return false
}
switch (item.type) {
case 1: //指标
this.selectedIndex = {}
this.addIndexVisible = true
break;
case 2: //日期
this.selectedDate = ''
this.addDateVisible = true
break;
case 3: //数字
this.selectedNum = 0
this.addNumVisible = true
break;
case 4: //计算符号
this.insertSymbol(item)
break;
case 5: //方法
// this.addFuncVisible = true
this.insertFunction(item)
break;
default:
break;
}
},
getNosetFuncValue (item) {
var arr = []
// if(item.isLimited){
// item.params.forEach(child => {
// arr.push('未设置')
// })
// }else{
// arr = ['未设置']
// }
item.params.forEach(child => {
arr.push('未设置')
})
return arr.join(', ')
},
//插入方法
insertFunction (item) {
console.log(item)
var funcName = item.key.replace('( )','')
var value = funcName + '(' + this.getNosetFuncValue(item) + ')'
this.setRange()
var id = this.createIndexId()
var width = this.getInputLength(value) + 'px'
this.$nextTick(()=>{
if(!document.execCommand('insertHTML', false, '<input readonly class="cal-index" type="5" id="'+ id +'" style="width:'+ width +'" value="'+ value +'" />')){
this.$message({
message: '请先在输入区定位光标!',
type: 'warning'
})
}else{
this.functionParams[id] = {
value: item.key,
key: item.key,
type: 5,
id: id,
originParams: JSON.parse(JSON.stringify(item)),
paramsValue: []
}
item.params.forEach((item,index) => {
this.functionParams[id].paramsValue[index] = {}
})
// this.selectedController = this.functionParams[id]
this.$set(this, 'selectedController', this.functionParams[id])
this.removeAllActive()
document.getElementById(id).classList.add('active')
}
})
},
//指标树点击事件
treeNodeClick (obj) {
if(obj.DataType !== 'T'){
var condition = conditionFuns.getIndexType(obj)
this.selectedIndex = {
type: 1,
name: obj.Name,
code: obj.Code,
mark: obj.Mark,
typeContent: obj.TypeContent,
mergeType: '合并本期',
yearType: 1,
quarterType: 1,
t: 0,
q: 0,
inputYear: '',
inputQuarter: '',
isAppointCompany: false,
selectedCompany: '',
needMergeType: condition.needMergeType,
needReportData: condition.needReportData,
needCompany: condition.needCompany
}
}else{
return false
}
},
//保存光标位置
saveRange () {
var selection = window.getSelection()
var range = selection.getRangeAt(0)
this.range = range.cloneRange()
},
//输出光标位置
setRange () {
var selection = window.getSelection()
selection.removeAllRanges()
if(this.range){
selection.addRange(this.range)
}else{
this.$message({
message: '请先在输入区定位光标!',
type: 'warning'
})
}
},
//插入指标事件
insertIndex (selectedIndex) {
this.setRange()
var id = this.createIndexId()
var text = conditionFuns.getFullIndexName(selectedIndex)
var width = this.getInputLength(text) + 'px'
this.$nextTick(()=>{
if(!document.execCommand('insertHTML', false, '<input readonly class="cal-index" type="1" id="'+ id +'" style="width:'+ width +'" value="'+ text +'" />')){
this.$message({
message: '请先在输入区定位光标!',
type: 'warning'
})
}else{
this.indexParams[id] = JSON.parse(JSON.stringify(selectedIndex))
this.indexParams[id].id = id
this.selectedController = this.indexParams[id]
this.removeAllActive()
document.getElementById(id).classList.add('active')
}
})
this.addIndexVisible = false
},
//插入数字
insertNum (selectedNum) {
this.setRange()
var id = this.createIndexId()
var text = selectedNum + "[" + this.getFormatValue(selectedNum) + "]"
var width = this.getInputLength(text) + 'px'
this.$nextTick(()=>{
if(!document.execCommand('insertHTML', false, '<input readonly class="cal-index" type="3" id="'+ id +'" style="width:'+ width +'" value="'+ text +'" />')){
this.$message({
message: '请先在输入区定位光标!',
type: 'warning'
})
}else{
this.numParams[id] = {
type: 3,
value: selectedNum,
id: id
}
this.selectedController = this.numParams[id]
this.removeAllActive()
document.getElementById(id).classList.add('active')
}
})
this.addNumVisible = false
},
//插入日期
insertDate (selectedDate) {
this.setRange()
var id = this.createIndexId()
var text = selectedDate
var width = this.getInputLength(text) + 'px'
this.$nextTick(()=>{
if(!document.execCommand('insertHTML', false, '<input readonly class="cal-index" type="2" id="'+ id +'" style="width:'+ width +'" value="'+ text +'" />')){
this.$message({
message: '请先在输入区定位光标!',
type: 'warning'
})
}else{
this.dateParams[id] = {
type: 2,
value: selectedDate,
id: id
}
this.selectedController = this.dateParams[id]
this.removeAllActive()
document.getElementById(id).classList.add('active')
}
})
this.addDateVisible = false
},
//插入计算符号
insertSymbol (item) {
this.setRange()
var id = this.createIndexId()
var width = this.getInputLength(item.key) + 'px'
this.$nextTick(()=>{
//加入额外的样式
var moreClass = ''
switch (item.key) {
case '(': case ')':
moreClass = 'brackets'
break;
default:
break;
}
if(!document.execCommand('insertHTML', false, '<input readonly class="cal-index ' + moreClass + '" type="4" id="'+ id +'" style="width:'+ width +'" value="'+ item.key +'" />')){
this.$message({
message: '请先在输入区定位光标!',
type: 'warning'
})
}else{
this.symbolParams[id] = {
value: item.key,
key: item.key,
type: 4,
id: id
}
this.selectedController = this.symbolParams[id]
this.removeAllActive()
document.getElementById(id).classList.add('active')
}
})
},
//数字格式化
getFormatValue (value) {
var unit = '', num = 1
if(value < 10000){
unit = '', num = 1
}else if(10000 <= value && value < 100000000){
unit = '', num = 10000
}else if(100000000 <= value && value < 1000000000000){
unit = '亿', num = 100000000
}else if(value >= 1000000000000){
unit = '万亿', num = 1000000000000
}
return (value/num).toFixed(0) + unit
},
// getFullIndexName (index) {
// var indexName = index.name, merge = '', company = '', year = '', quarter = ''
// if(index.needMergeType){
// merge = '[' + index.mergeType + ']'
// }
// if(index.needReportData){
// if(index.yearType == 1){
// year = '[T:' + index.t + ']'
// }else{
// year = '[T:' + index.inputYear + ']'
// }
// if(index.quarterType == 1){
// quarter = '[Q:' + index.q + ']'
// }else{
// quarter = '[Q:' + index.inputQuarter + ']'
// }
// }
// if(index.needCompany && index.isAppointCompany){
// company = '[' + index.selectedCompany + ']'
// }
// return indexName + year + quarter + merge + company
// },
setAppointedIndexName (index) {
var id = index.id
var type = index.type
var indexDom = document.getElementById(id)
switch (type) {
case 1: //1是指标
indexDom.setAttribute('value',conditionFuns.getFullIndexName(index))
var value = indexDom.getAttribute('value')
indexDom.style.width = this.getInputLength(value) + 'px'
break;
case 2: //2是日期
indexDom.setAttribute('value',index.value)
indexDom.style.width = this.getInputLength(indexDom.value) + 'px'
break;
case 3: //3是数字
indexDom.setAttribute('value', index.value + "[" + this.getFormatValue(index.value) + "]")
indexDom.style.width = this.getInputLength(indexDom.value) + 'px'
break;
case 4: //4是符号
indexDom.setAttribute('value',index.value)
indexDom.style.width = this.getInputLength(indexDom.value) + 'px'
break;
default:
break;
}
},
// getIndexType (obj) {
// var newObj = {
// needMergeType: false,
// needReportData: false,
// needCompany: false
// }
// if(obj.TypeContent){
// obj.TypeContent.Parameters.forEach(item => {
// if(item.Encode == 'F91997V'){
// newObj.needMergeType = true
// }
// if(item.Encode == 'F91996D'){
// newObj.needReportData = true
// }
// if(item.Encode == 'F90001V'){
// newObj.needCompany = true
// }
// })
// }
// return newObj
// },
//判断制表格式
conditionContain (array, code) {
var has = false
array.forEach(item => {
if(item.Encode == code){
has = true
}
})
return has
},
//创建一个id
createIndexId () {
this.initIndexId++
var id = new Date().getTime() + this.initIndexId
return id
},
//获取input的长度
getInputLength (text) {
var width = 0, span
if(!document.getElementById('invented')){
span = document.createElement('span')
span.id = 'invented'
span.innerHTML = text
document.body.appendChild(span)
}else{
span = document.getElementById('invented')
span.innerHTML = text
}
width = span.offsetWidth
return width + 4
},
//初始化撤销反撤销
initKeybord () {
document.onkeydown = function (e) {
var ctrlKey = e.ctrlKey || e.metaKey;
if (e.shiftKey && ctrlKey && e.keyCode == 90) {
document.execCommand('redo', false, null)
}
if (ctrlKey && e.keyCode == 90 && !e.shiftKey) {
document.execCommand('undo', false, null)
}
}
}
}
}
\ No newline at end of file
<template>
<div>
<div class="flex">
<div class="cal-container">
<div class="calculater-display"
:id="contentId"
@click="contentClick"
@blur="saveRange"
@keydown="inputKeydown"
contenteditable="true">
</div>
<div class="calculater-keybord"
v-for="item in keybordData">
<el-tooltip class="item"
v-for="(sub, index) in item"
:key-="index"
effect="dark"
:open-delay="1000"
:content="sub.tip"
placement="bottom">
<span class="single-bord"
:class="{
text: sub.isText,
long: sub.isLong
}"
@click="clickCalText($event,sub)">
{{sub.key}}
</span>
</el-tooltip>
</div>
</div>
<!-- 控制面板 -->
<div class="cal-index-detail" style="flex: auto; position: relative;">
<!-- 复制粘贴 -->
<div class="absolute-operation">
<span class="el-icon-document-copy" v-if="selectedController.type" @click="copyIndex"></span>
<span class="el-icon-document-checked" v-if="!selectedController.type" @click="pasteIndex"></span>
</div>
<!-- 当是指标的时候 -->
<div class="index-controller" v-if="selectedController.type == 1">
<div class="controller-item">{{selectedController.name}}</div>
<div class="controller-item">
<span class="gray">报告年度:</span>
<el-radio-group class="mini" v-model="selectedController.yearType">
<el-radio :label="1">T年度</el-radio>
<el-radio :label="2">指定年度</el-radio>
</el-radio-group>
</div>
<div class="controller-item" v-show="selectedController.yearType == 2">
<el-date-picker
style="width:80px"
class="mini"
v-model="selectedController.inputYear"
value-format="yyyy"
type="year"
placeholder="选择年">
</el-date-picker>
</div>
<div class="controller-item" v-show="selectedController.yearType == 1">
<el-input class="mini" style="width: 80px" v-model="selectedController.t" size="mini">
<template slot="append">T</template>
</el-input>
</div>
<div class="controller-item">
<span class="gray">报告季度:</span>
<el-radio-group class="mini" v-model="selectedController.quarterType">
<el-radio :label="1">Q季度</el-radio>
<el-radio :label="2">指定季度</el-radio>
</el-radio-group>
</div>
<div class="controller-item" v-show="selectedController.quarterType == 2">
<el-select v-model="selectedController.inputQuarter"
style="width: 80px"
class="mini" size="mini" placeholder="请选择">
<el-option :key="1" label="03-31" value="03-31"></el-option>
<el-option :key="2" label="06-30" value="06-30"></el-option>
<el-option :key="3" label="09-30" value="09-30"></el-option>
<el-option :key="4" label="12-31" value="12-31"></el-option>
</el-select>
</div>
<div class="controller-item" v-show="selectedController.quarterType == 1">
<el-input class="mini" style="width: 80px" v-model="selectedController.q" size="mini">
<template slot="append">Q</template>
</el-input>
</div>
<div class="controller-item">
<el-select v-model="selectedController.mergeType"
style="width: 164px"
class="mini" size="mini" placeholder="请选择">
<el-option
v-for="(item, index) in mergeTypeData"
:key="index"
:label="item"
:value="item">
</el-option>
</el-select>
</div>
<div class="controller-item">
<span class="gray">指定公司</span>
<el-switch
:width="30"
class="mini"
v-model="selectedController.isAppointCompany">
</el-switch>
</div>
<div class="controller-item" v-show="selectedController.isAppointCompany">
<el-select
v-model="selectedController.selectedCompany"
filterable
remote
reserve-keyword
class="mini"
placeholder="输入公司"
:remote-method="searchCompany"
:loading="searchCompanyLoading"
style="width: 164px">
<el-option
v-for="item in companyData"
:key="item.SECCODE"
:label="item.SECNAME + '-' + item.SECCODE"
:value="item.SECNAME + '-' + item.SECCODE">
</el-option>
</el-select>
</div>
</div>
<!-- 当是日期的时候 -->
<div class="index-controller" v-if="selectedController.type == 2">
<div class="controller-item">日期</div>
<div class="controller-item">
<el-date-picker
style="width:120px"
class="mini"
v-model="selectedController.value"
type="date"
value-format="yyyy-MM-dd"
placeholder="选择日期">
</el-date-picker>
</div>
</div>
<!-- 当是数字的时候 -->
<div class="index-controller" v-if="selectedController.type == 3">
<div class="controller-item">数字</div>
<div class="controller-item">
<el-input class="mini" style="width: 160px" v-model="selectedController.value" size="mini"></el-input>
<span>{{getFormatValue(selectedController.value)}}</span>
</div>
</div>
<!-- 当是符号的时候 -->
<div class="index-controller" v-if="selectedController.type == 4">
<div class="controller-item">计算符号</div>
<div class="controller-item">
<span>{{selectedController.value}}</span>
</div>
</div>
<!-- 当没选中的时候 -->
<div class="index-controller" v-if="!selectedController.type">
<div class="controller-item">未选中元素</div>
</div>
<!-- 当是公式的时候 -->
<div class="index-controller" v-if="selectedController.type == 5">
<div class="controller-item" style="margin-bottom: 20px">计算函数</div>
<div class="column">
<div class="column-title">能力</div>
<div>{{selectedController.originParams.describe}}</div>
</div>
<div class="column">
<div class="column-title" >示例</div>
<div>{{selectedController.originParams.case}}</div>
</div>
<div class="column">
<div class="column-title">参数</div>
<div class="function-params">
<div class="function-params-item" :key="index" v-for="(item, index) in selectedController.originParams.params">
<div class="item-title">参数{{index + 1}}:{{getFuncParamsName(item)}}</div>
<div class="func-show-dom" v-html="selectedController.paramsValue[index].showDom"></div>
<div class="item-function"
v-show="!selectedController.paramsValue[index].showDom"
@click="openFunctionParams(index, selectedController.originParams.params[index])" style="color: #d0021b; cursor: pointer">
未设置,点击设置
</div>
<div class="item-function"
style="color: #d0021b; cursor: pointer"
@click="changeFuncParams(index)"
v-show="selectedController.paramsValue[index].showDom">
修改
</div>
<span
@click="deleteFuncParams(index)"
v-if="!selectedController.originParams.isLimited && index !== 0" class="delete-func el-icon-error">
</span>
</div>
<div
style="color: #d0021b; cursor: pointer; padding: 12px 0"
@click="addMoreParams"
v-show="!selectedController.originParams.isLimited">
继续添加
</div>
</div>
</div>
</div>
</div>
</div>
<div style="padding-top: 12px; color: #999; font-size: 12px">操作提示:键盘按键↑、↓、←、→、Enter、空格、删除键可用,其它按键不可用</div>
<div class="calculater-operation" style="font-size: 12px">
<span @click="checkGrammar('tip')">校验语法</span>
<span @click="formatGrammar">格式化条件</span>
</div>
<!-- 插入指标 -->
<el-dialog title="插入指标"
:visible.sync="addIndexVisible"
width="900px"
append-to-body
:close-on-click-modal="false"
:close-on-press-escape="false"
:modal="false"
class="index-choose-dialog"
style="user-select: none">
<div class="index-choose-dialog-inner">
<div class="mini-size" style="width: 240px;height: 390px;">
<div class="index-list" style="border: 0; background: #fff">
<div class="index-list-search">
<el-input v-model="filterInput" size="mini" clearable placeholder="请输入指标,按确认件搜索"
@keyup.enter.native="filterIndexText"></el-input>
</div>
<div class="index-list-tree" style="max-height: 360px; height: 360px">
<el-tree :data="treeData" :indent="8" @node-click="treeNodeClick" :highlight-current="true" ref="tree"
:filter-node-method="filterTreeNode" :default-expand-all="true" :props="treeProps"></el-tree>
</div>
</div>
</div>
<div class="index-detail">
<div class="index-detail-edit">
<div class="single-column">
<div class="title">已选指标:</div>
<div class="detail">
<div class="selected-tree-index" v-show="!selectedIndex.name">请从左边列表选择参数, 目前只支持选择单指标</div>
<div class="selected-tree-index" v-if="selectedIndex.name">
<span>{{selectedIndex.name}}</span>
<span>{{selectedIndex.code}}</span>
</div>
</div>
</div>
<div class="single-column">
<div class="title">指标说明:</div>
<div class="detail">
<div class="selected-tree-index" v-show="!selectedIndex">未选择指标</div>
<div class="selected-tree-index" v-if="selectedIndex">
<span>{{selectedIndex.mark || '暂无说明'}}</span>
</div>
</div>
</div>
<div class="single-column"
v-if="selectedIndex.needMergeType">
<div class="title">合并类型:</div>
<div class="detail">
<el-radio-group v-model="selectedIndex.mergeType">
<el-radio :label="'合并本期'">合并本期</el-radio>
<el-radio :label="'合并上期'">合并上期</el-radio>
<el-radio :label="'母公司本期'">母公司本期</el-radio>
<el-radio :label="'母公司上期'">母公司上期</el-radio>
</el-radio-group>
</div>
</div>
<div class="single-column"
v-if="selectedIndex.needReportData"
style="align-items: baseline">
<div class="title">报告年度:</div>
<div class="detail">
<div>
<el-radio-group v-model="selectedIndex.yearType">
<el-radio :label="1">T年度</el-radio>
<el-radio :label="2">指定年度</el-radio>
</el-radio-group>
</div>
<div v-show="selectedIndex.yearType == 1" style="margin-top: 12px">
<span>T + </span>
<el-input-number size="mini" v-model="selectedIndex.t"></el-input-number>
</div>
<div v-show="selectedIndex.yearType == 2" style="margin-top: 12px">
<el-date-picker
v-model="selectedIndex.inputYear"
type="year"
size="mini"
value-format="yyyy"
placeholder="选择年">
</el-date-picker>
</div>
</div>
</div>
<div class="single-column" style="align-items: baseline"
v-if="selectedIndex.needReportData">
<div class="title">报告期:</div>
<div class="detail">
<div style="margin-bottom: 12px">
<el-radio-group v-model="selectedIndex.quarterType">
<el-radio :label="1">Q报告期</el-radio>
<el-radio :label="2">指定报告期</el-radio>
</el-radio-group>
</div>
<div v-show="selectedIndex.quarterType == 1">
<span>Q + </span>
<el-input-number size="mini" v-model="selectedIndex.q"></el-input-number>
</div>
<div v-show="selectedIndex.quarterType == 2">
<el-select size="mini" v-model="selectedIndex.inputQuarter" placeholder="请选择">
<el-option label="03-31" value="03-31"></el-option>
<el-option label="06-30" value="06-30"></el-option>
<el-option label="09-30" value="09-30"></el-option>
<el-option label="12-31" value="12-31"></el-option>
</el-select>
</div>
</div>
</div>
<div class="single-column"
style="align-items: flex-start;"
v-if="selectedIndex.needCompany">
<div class="title">指定公司:</div>
<div class="detail">
<div>
<el-switch
class=""
v-model="selectedIndex.isAppointCompany">
</el-switch>
</div>
<div style="margin-top: 12px">
<el-select
v-show="selectedIndex.isAppointCompany"
v-model="selectedIndex.selectedCompany"
filterable
remote
reserve-keyword
size='mini'
placeholder="输入公司"
:remote-method="searchCompany"
:loading="searchCompanyLoading"
style="width: 164px">
<el-option
v-for="item in companyData"
:key="item.SECCODE"
:label="item.SECNAME + '-' + item.SECCODE"
:value="item.SECNAME + '-' + item.SECCODE">
</el-option>
</el-select>
</div>
</div>
</div>
</div>
<div class="single-column" style="margin-top: 20px">
<el-button size="mini" type="primary" @click="insertIndex(selectedIndex)">确认</el-button>
<el-button size="mini" @click="addIndexVisible = false">取消</el-button>
</div>
</div>
</div>
</el-dialog>
<!-- 插入数字 -->
<el-dialog title="插入数字"
:visible.sync="addNumVisible"
width="300px"
append-to-body
:close-on-click-modal="false"
:close-on-press-escape="false"
:modal="false"
class="index-choose-dialog"
style="user-select: none">
<div class="index-choose-dialog-inner">
<div class="single-column" style="align-items: flex-start;">
<div class="title">插入数字:</div>
<div class="detail">
<div>
<el-input size="mini" v-model="selectedNum"></el-input>
</div>
<div style="margin-top: 8px">
<span>{{getFormatValue(selectedNum)}}</span>
</div>
</div>
</div>
</div>
<div slot="footer">
<el-button size="mini" type="primary" @click="insertNum(selectedNum)">确认</el-button>
<el-button size="mini" @click="addNumVisible = false">取消</el-button>
</div>
</el-dialog>
<!-- 插入日期 -->
<el-dialog title="插入日期"
:visible.sync="addDateVisible"
width="300px"
append-to-body
:close-on-click-modal="false"
:close-on-press-escape="false"
:modal="false"
class="index-choose-dialog"
style="user-select: none">
<div class="index-choose-dialog-inner">
<div class="single-column">
<div class="title">插入日期:</div>
<div class="detail">
<div>
<el-date-picker
style="width: 160px"
size="mini"
v-model="selectedDate"
value-format="yyyy-MM-dd"
type="date"
placeholder="选择日期">
</el-date-picker>
</div>
</div>
</div>
</div>
<div slot="footer">
<el-button size="mini" type="primary" @click="insertDate(selectedDate)">确认</el-button>
<el-button size="mini" @click="addDateVisible = false">取消</el-button>
</div>
</el-dialog>
<!-- 插入函数 -->
<el-dialog title="插入方法"
:visible.sync="addFuncVisible"
width="720px"
append-to-body
:close-on-click-modal="false"
:close-on-press-escape="false"
:modal="false"
class="index-choose-dialog"
style="user-select: none">
<div class="add-function-dialog">
<!-- <div class="function-list">
<div class="title">可用方法</div>
<ul>
<li>abs{}</li>
<li>ave{}</li>
</ul>
</div> -->
<div class="function-detail">
<!-- <div class="title">方法参数</div> -->
<div class="detail-content">
<div class="single-column">
<span class="title">备注:</span>
<span class="detail">计算指标的绝对值</span>
</div>
<div class="single-column">
<span class="title">示例:</span>
<span class="detail">abs{归属于母公司所有者的净利润[T:0][Q:1]}</span>
</div>
<div class="single-column">
<span class="title">参数类型:</span>
<span class="detail">指标或计算公式,数量单个</span>
</div>
<div class="single-column">
<span class="title">参数:</span>
<span class="detail">
<div>
</div>
</span>
</div>
</div>
</div>
</div>
<div slot="footer">
<el-button size="mini" type="primary" @click="insertDate(selectedDate)">确认</el-button>
<el-button size="mini" @click="addFuncVisible = false">取消</el-button>
</div>
</el-dialog>
</div>
</template>
\ No newline at end of file
var init = require('../../lib/init.js')
var value = init(__filename, __dirname)
//以上代码引入vue、css等,初始化
module.exports = {
name: value.name,
data: function () {
return {
testYear: '',
testQuarter: '',
testMergeType: '',
requiredCondition: []
}
},
props:['params','allParams'],
template: value.template,
computed: {
},
mounted() {
this.getRequiredCondition()
},
methods: {
getRequiredCondition () { //1证券代码 2合并类型 4报告期
var arr = []
this.allParams.forEach(item => {
if (this.params & item.Id) {
arr.push(item)
}
})
this.requiredCondition = arr
},
isContains (id) {
console.log('执行')
var isRequired = false
this.requiredCondition.forEach(item => {
if(item.Id == id){
isRequired = true
}
})
return isRequired
}
}
}
\ No newline at end of file
<template>
<div>
<div class="detail-index" v-show="isContains(4)">
<div class="title">报告期:</div>
<div class="detail">
<el-date-picker
style="width: 120px"
size="mini"
v-model="testYear"
type="year"
value-format="yyyy"
placeholder="选择年度"
></el-date-picker>
<el-select
placeholder="选择季度"
style="width: 120px; margin-left: 12px"
size="mini"
v-model="testQuarter"
>
<el-option value="03-31">03-31</el-option>
<el-option value="06-30">06-30</el-option>
<el-option value="09-30">09-30</el-option>
<el-option value="12-31">12-31</el-option>
</el-select>
</div>
</div>
<div class="detail-index" v-show="isContains(2)">
<div class="title">合并类型:</div>
<div class="detail">
<el-select style="width: 120px" size="mini" v-model="testMergeType" placeholder="选择合并类型">
<el-option value="合并本期">合并本期</el-option>
<el-option value="合并上期">合并上期</el-option>
<el-option value="母公司本期">母公司本期</el-option>
<el-option value="母公司上期">母公司上期</el-option>
</el-select>
</div>
</div>
</div>
</template>
\ No newline at end of file
#app.production-line-container{
flex-direction: column;
padding: 0px;
flex: 1;
color: #333;
min-width: 1200px;
width: 100%;
height: 100%;
}
.editor-inner{
height: 100%;
display: flex;
flex-direction: column;
}
.index-box{
width: 320px;
min-width: 320px;
padding-right: 20px;
box-sizing: border-box;
border-right: 1px solid #eaeaea;
display: flex;
flex-direction: column;
}
.split-index-box{
padding-right: 20px;
box-sizing: border-box;
display: flex;
flex-direction: column;
height: 100%;
}
.small-tree .el-tree-node__label{
font-size: 12px;
}
.tree-search-input{
margin-bottom: 12px;
}
.input-box{
min-height: 40px;
}
.tree-box{
flex: auto;
overflow: overlay;
}
.container-inner{
width: 100%;
display: flex;
flex: auto;
}
.index-detail{
flex: auto;
padding-left: 20px;
display: flex;
flex-direction: column;
/* overflow: scroll; */
position: relative;
height: 100%;
}
.tree-container{
flex: auto;
overflow: overlay;
}
.detail-index{
display: flex;
width: 100%;
align-items: baseline;
}
.detail-index .title{
min-width: 120px;
text-align: right;
margin-right: 20px;
color: #666;
}
.detail-index .detail{
flex: auto;
}
.detail-index .detail.active{
background: #FFE9E9;
}
.detail-container{
padding: 20px 0;
/* padding-top: 40px; */
}
.detail-index+.detail-index{
margin-top: 20px;
}
.sub-detail+.sub-detail{
margin-top: 8px;
}
.detail-from{
color: #999;
}
.primary{
color: #d0021b;
cursor: pointer;
}
.gray{
color: #999;
}
.el-checkbox__label{
font-size: 12px;
}
.el-radio__label{
font-size: 12px;
}
/* .calculater-display{
border: 1px solid #eaeaea;
height: 320px;
box-sizing: border-box;
padding: 10px;
max-width: 600px;
overflow: scroll;
overflow-x: hidden;
} */
/* .calculater-keybord{
font-size: 0px;
border: 1px solid #eaeaea;
border-top: 0;
box-sizing: border-box;
max-width: 600px;
height: 40px;
} */
.calculater-keybord .single-bord:last-child{
border-right: 1px solid #eaeaea;
}
.calculater-keybord .single-bord{
width: 40px;
height: 40px;
text-align: center;
line-height: 40px;
font-size: 20px;
color: #333;
box-sizing: border-box;
cursor: pointer;
user-select: none;
float: left;
border-right: 1px solid #eaeaea;
}
.calculater-keybord .single-bord.long{
width: 80px;
}
.calculater-keybord .single-bord.active{
color: #d0021b;
background: #FFE7E7;
}
.calculater-keybord .single-bord.active:active{
color: #fff;
background: #d0021b;
}
.calculater-keybord .single-bord:active{
background: #FFE7E7;
}
.calculater-keybord .single-bord:hover{
color: #d0021b;
}
.calculater-keybord .single-bord+.single-bord{
/* border-left: 1px solid #eaeaea; */
}
.calculater-keybord .single-bord.text{
font-size: 12px;
}
.calculater-operation{
margin-top: 12px;
}
/* .calculater-tip{
font-size: 12px;
} */
.calculater-operation span{
display: inline-block;
padding: 4px 8px;
border: 1px solid #eaeaea;
border-radius: 4px;
cursor: pointer;
}
.calculater-operation span:active{
color: #d0021b;
background: #FFE7E7;
}
.calculater-operation span:hover{
background: #FFE7E7;
}
.activeLink{
color: #d0021b;
}
.el-divider__text, .el-link{
font-size: 12px;
}
.el-divider__text, .el-link+.el-link{
margin-left: 10px;
}
.el-link.el-link--default{
color: #d0021b;
}
.header-search-box{
width: 50%;
margin: 0 auto;
background: #f1f1f1;
line-height: 36px;
padding: 0 12px;
box-sizing: border-box;
}
.header-search-box .icon{
font-size: 14px;
}
.header-search-box input{
border: 0;
outline: 0;
background: #f1f1f1;
line-height: 36px;
font-size: 14px;
width: calc(100% - 20px);
box-sizing: border-box;
}
.header-search-box input:focus{
outline: 0;
}
.flex{
display: flex;
align-items: center;
}
.more-icon{
font-size: 16px;
background: #f1f1f1;
border-radius: 20px;
padding: 4px;
cursor: pointer;
}
.cal-index-detail{
border: 1px solid #eaeaea;
font-size: 12px;
padding: 10px;
box-sizing: border-box;
margin-left: 10px;
height: 400px;
overflow: overlay;
min-width: 240px;
max-width: 240px;
}
.cal-index{
background: #FFE7E7;
margin: 0 2px;
}
.cal-index.active{
color: #d0021b;
}
.calculater-display input{
outline: 0;
border: 0;
cursor: pointer;
font-size: 12px;
margin-bottom: 4px;
}
.calculater-display input:focus{
outline: 0;
}
.calculater-display .cal-index.brackets{
background: #d0daff;
}
#invented{
position: fixed;
opacity: 0;
left: 0;
top: 0;
z-index: -1;
font-size: 12px;
}
.table-condition{
border-bottom: 1px solid #eaeaea;
padding-bottom: 12px;
}
.mini.el-input--mini .el-input__inner{
height: 20px;
line-height: 20px;
/* border-radius: 4px; */
padding: 0 4px;
}
.mini.el-input--mini .el-input-group__append{
min-width: 10px;
text-align: center;
padding: 0 4px;
}
.mini.el-select .el-input--mini .el-input__inner{
height: 20px;
line-height: 20px;
padding-left: 4px;
padding-right: 4px;
}
.mini.el-select .el-input .el-select__caret{
line-height: 20px;
}
.controller-item+.controller-item{
margin-top: 8px;
}
.mini .el-switch__core{
height: 14px;
}
.mini .el-switch__core:after{
height: 10px;
width: 10px;
}
.mini.el-switch.is-checked .el-switch__core::after{
width: 10px;
height: 10px;
}
.mini.el-switch.is-checked .el-switch__core::after{
margin-left: -11px;
}
.mini .el-input__inner{
height: 20px;
line-height: 20px;
font-size: 12px;
}
.mini .el-input__icon{
line-height: 20px;
}
.mini.el-input--suffix .el-input__inner{
padding-right: 0;
}
.mini .el-input__icon{
width: 20px;
}
.mini .el-input__inner{
font-size: 12px;
line-height: 20px;
height: 20px;
}
.mini.el-select .el-input__inner{
padding-left: 4px;
}
.cal-container{
position: relative;
flex: auto;
max-width: 600px;
}
.empty-status{
min-height: 400px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.empty-status img{
width: 130px;
height: auto;
margin-bottom: 10px;
}
.empty-status .empty-tip{
font-size: 14px;
color: #999;
}
.absolute-operation{
position: absolute;
right: 4px;
top: 8px;
font-size: 14px;
cursor: pointer;
}
.absolute-operation:hover{
color: #D0021B;
}
.index-choose-dialog .single-column{
display: flex;
align-items: center;
padding: 8px 0;
}
.index-choose-dialog .single-column .title{
min-width: 80px;
text-align: right;
margin-right: 12px;
color: #999;
}
.index-choose-dialog .single-column .detail{
flex: auto;
}
.mini-size .el-tabs__item{
font-size: 12px;
height: 28px;
line-height: 28px;
}
.index-choose-dialog-inner{
display: flex
}
.index-choose-dialog .el-dialog__body{
font-size: 12px;
border-top: 1px solid #EBEEF5;
}
.index-choose-dialog .index-detail{
padding-left: 20px;
border-left: 1px solid #EBEEF5;
flex: auto;
}
.index-choose-dialog .index-list{
padding-right: 20px;
}
.index-list-tree{
max-height: 300px;
overflow-y: scroll;
overflow-x: hidden;
}
.mini-size .el-tree-node__label{
font-size: 12px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.mini .el-radio__inner {
width: 10px;
height: 10px;
}
.detail-container .el-radio {
margin-right: 16px;
}
.add-function-dialog{
display: flex;
}
.add-function-dialog .title{
font-size: 12px;
font-weight: bold;
}
.function-list{
margin-right: 12px;
}
.function-list ul{
background: rgb(245, 247, 250);
padding: 8px;
min-width: 200px;
margin-top: 12px;
border-radius: 4px;
}
.detail-content{
/* margin-top: 12px; */
}
.function-list ul li{
cursor: pointer;
}
.function-list ul li:hover{
color: #d0021b;
}
.function-list ul li+li{
margin-top: 8px;
}
.function-detail{
flex: auto;
/* border-left: 1px solid #eaeaea;
padding-left: 8px; */
}
.cal-index.function::before{
content: '123';
}
.index-controller .column{
margin-bottom: 12px;
}
.index-controller .column .column-title{
color: #999;
margin-bottom: 6px;
}
.function-params-item{
background: rgb(245, 247, 250);
padding: 8px;
border-radius: 4px;
position: relative;
}
.function-params-item+.function-params-item{
margin-top: 8px;
}
.function-params-item .item-title{
margin-bottom: 4px;
}
.index-detail-title{
display: flex;
align-items: center;
min-height: 32px;
border-bottom: 1px solid #eaeaea;
padding-bottom: 8px;
}
.detail-container{
height: calc(100% -30px);
overflow: scroll;
}
.func-show-dom{
padding-bottom: 4px;
}
.delete-func{
position: absolute;
right: -6px;
top: -6px;
font-size: 16px;
cursor: pointer;
color: #999;
}
.delete-func:hover{
color: #d0021b;
}
.calculater-box{
width: 600px;
padding: 12px;
border: 1px solid #eaeaea;
border-radius: 4px;
box-sizing: border-box;
}
.calculater-box span[type = '4']{
color: #d0021b;
margin: 0 4px;
}
.hover-icon{
cursor: pointer;
}
.hover-icon:hover{
color: #d0021b;
}
.index-box-tab{
min-height: 32px;
line-height: 32px;
border-bottom: 1px solid #eaeaea;
padding-bottom: 8px;
display: flex;
align-items: center;
}
.index-box-tab h3+h3{
margin-left: 20px;
}
.index-box-tab h3{
color: #999;
flex: auto;
}
.index-box-tab h3.active{
color: #333;
}
.my-radio .el-radio-button--mini .el-radio-button__inner{
font-size: 12px;
padding: 4px;
}
.test-run-box{
font-size: 13px;
}
.test-run-box .title{
color: #999;
}
.industry-tree-box{
max-height: 200px;
overflow: scroll;
overflow-x: hidden;
}
.model-list{
padding: 12px;
border: 1px solid #eaeaea;
border-radius: 4px;
width: 600px;
box-sizing: border-box;
}
.model-check-list+.model-check-list{
margin-top: 8px;
}
.model-list .model-name{
margin-bottom: 12px;
font-weight: bold;
}
.model-list+.model-list{
margin-top: 8px;
}
.action-list .icon{
padding: 0 10px;
cursor: pointer;
}
.action-list span:hover{
color: #d0021b;
}
.action-list span+span{
border-left: 1px solid #eaeaea;
}
.action-list{
/* border-bottom: 1px solid #eaeaea; */
padding: 12px 0;
background: #f9f9f9;
margin-top: 12px;
border-radius: 4px;
}
.double-detail-box{
display: flex;
align-items: baseline;
}
.double-detail-box .title{
min-width: 80px;
}
.side-modal{
position: fixed;
width: 400px;
background: #fff;
height: 100%;
right: 0px;
top: 0;
z-index: 100;
box-shadow: -8px 0 8px rgba(0, 0, 0, 0.1);
padding: 20px 12px;
box-sizing: border-box;
}
.slide-fade-enter-active {
transition: all .3s ease;
}
.slide-fade-leave-active {
transition: all .1s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.slide-fade-enter, .slide-fade-leave-to
/* .slide-fade-leave-active for below version 2.1.8 */ {
transform: translateX(50px);
opacity: 0;
}
.side-close{
font-size: 20px;
color: #999;
position: absolute;
right: 10px;
top: 10px;
cursor: pointer;
}
.side-close:hover{
color: #D0021B;
}
.side-modal-column{
display: flex;
align-items: baseline;
}
.side-modal-column .title{
min-width: 80px;
text-align: right;
color: #999;
margin-right: 10px;
}
.side-modal-column .detail{
flex: auto;
}
.side-modal h3{
margin-bottom: 20px;
}
.side-modal-column+.side-modal-column{
margin-top: 20px;
}
.detail-line-list+.detail-line-list{
margin-top: 8px;
}
.side-modal-operation{
position: absolute;
width: 100%;
bottom: 0px;
left: 0;
padding: 8px 12px;
box-sizing: border-box;
border-top: 1px solid #eaeaea;
}
.side-modal-inner{
overflow: scroll;
overflow-x: hidden;
height: calc(100% - 66px);
padding-bottom: 12px;
box-sizing: border-box;
}
.side-tree-box{
border: 1px solid #eaeaea;
padding: 12px;
height: 500px;
max-height: 500px;
overflow: scroll;
overflow-x: hidden;
}
.change-detail-left{
min-width: 300px;
}
.change-detail-left h3{
font-size: 14px;
}
.change-detail-right{
flex: auto;
}
.change-detail-right h3{
font-size: 14px;
}
.sub-detail.active{
background: #ffeded;
}
.activeLink span{
color: #d0021b;
}
.custom-tree-node.active{
background: #d0021b;
color: #fff;
}
.splitter-pane-resizer{
opacity: .1 !important;
}
.noLeft .splitter-pane-resizer{
display: none !important;
}
.index-resolution-list{
display: inline-block;
margin-right: 8px;
background: rgb(245, 247, 250);
border-radius: 4px;
margin-bottom: 8px;
margin-right: 4px;
}
.index-resolution-list span {
padding: 4px 8px;
}
.index-resolution-list .icon{
cursor: pointer;
}
.index-resolution-list .icon:hover{
color: #d0021b;
}
.smartCenter-page-container .header{
background: #fff;
padding: 20px 0;
position: relative;
}
.header-input {
padding: 0 20px;
background: #EFEFEF;
display: flex;
align-items: center;
border-radius: 100px;
width: 260px;
margin: 0 auto;
}
.header-input input{
outline: 0;
border: 0;
font-size: 15px;
padding: 8px 0;
background: #EFEFEF;
flex: auto;
color: #333;
}
.header-input span{
color: #C3C3C3;
}
.header-tab{
font-size: 18px;
position: absolute;
left: 20px;
top: calc(50% - 12px);
cursor: pointer;
}
div{
outline: 0;
}
.header-tab>div:hover{
color: #D0021B;
}
.header-tab i{
margin-right: 8px;
}
.smartCenter-page-container .container{
width: 1120px;
margin: 0 auto;
}
.container-tab{
display: flex;
padding: 20px 0;
border-bottom: 1px solid #DEDEDE;
align-items: center;
}
.container-tab>.container-tablist{
flex: 1;
font-size: 15px;
text-align: center;
max-width: 15%;
}
.container-tablist>div{
display: inline-block;
padding: 8px 24px;
border-radius: 100px;
cursor: pointer;
transition: all .3s;
}
.container-tablist.active>div{
background: #F5E4E6;
color: #D0021B;
}
.container-tablist.active:hover>div{
background: #F5E4E6;
color: #D0021B;
}
.container-tablist:hover>div{
background: #EBEBEB;
}
.widget-container{
display: flex;
flex-wrap: wrap;
padding: 36px 0;
}
.widget-container .widget-list{
max-width: 20%;
width: 20%;
text-align: center;
margin-bottom: 12px;
animation: fade .3s linear;
position:relative;
}
/* .widget-list-inner:hover{
transform: scale(1.05);
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08)
} */
.widget-list-inner.active{
transform: scale(1.05);
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08)
}
.widget-list-inner{
width: 150px;
height: 168px;
background: #fff;
border-radius: 8px;
margin: 0 auto;
text-align: center;
transition: all .3s;
cursor: pointer;
position: relative;
}
.widget-list-inner img{
width: 100px;
height: 100px;
}
.widget-list-inner.block-list-inner img{
width: 132px;
height: auto;
}
.widget-list-inner .widget-image{
padding-top: 24px;
}
@keyframes fade
{
from {top:20px; opacity: 0;}
to {top:0px; opacity: 1;}
}
.more-info{
position: absolute;
right: 12px;
bottom: 12px;
color: #999;
width: 24px;
height: 24px;
border-radius: 24px;
}
.more-info:hover{
background: #F0F0F0;
}
.more-info.active{
background: #F0F0F0;
}
.more-info i{
line-height: 24px;
}
.more-list{
padding: 6px 12px;
cursor: pointer;
}
.more-list:hover{
background: #F5E4E6;
color: #D0021B;
}
.blockEdit-page-container {
height: 100%;
}
.blockEdit-page-container .header{
background: #fff;
padding: 0 20px;
position: relative;
z-index: 2;
}
.blockEdit-page-container .container{
position: relative;
z-index: 1;
}
.blockEdit-page-container .container{
height: calc(100% - 73px);
position: relative;
}
.blockEdit-page-container .header .iconfont{
color: #999;
font-size: 15px;
margin-left: 4px;
}
.blockname{
font-size: 18px;
padding: 24px 0;
width: 232px;
}
.operation-container-left{
height: 100%;
background: #fff;
box-sizing: border-box;
border-right: 1px solid #E4E4E4;
width: 232px;
position: absolute;
left: 0;
top: 0;
}
.index-tabs{
font-size: 0;
border-bottom: 1px solid #f0f0f0;
}
.index-tabs span{
display: inline-block;
padding: 6px 20px;
font-size: 13px;
vertical-align: middle;
background: #F7F7F7;
border-right: 1px solid #f0f0f0;
position: relative;
cursor: pointer;
}
.index-tabs span:hover{
color: #D0021B;
}
.index-tabs span.active{
background: #fff;
color: #D0021B;
}
.index-tabs span.active::before{
content: '';
height: 1px;
background: #fff;
position: absolute;
left: 0;
bottom: -1px;
width: 100%;
}
.blockEdit-page-container .header{
display: flex;
}
.action-container{
display: flex;
font-size: 11px;
align-items: center;
margin-left: 72px;
}
.action-container>div{
text-align: center;
padding: 0 16px;
cursor: pointer;
}
.action-container img{
width: 28px;
height: 28px;
}
.insert-controller-container{
font-size: 12px;
position: fixed;
top: 73px;
left: 0;
z-index: 2;
background: #fff;
width: calc(100% - 48px);
padding: 16px 24px;
animation: fadeTopToBottom .3s linear;
padding-bottom: 0;
padding-top: 8px;
}
.insert-controller-header{
display: flex;
padding: 12px;
border-bottom: 1px solid #f0f0f0;
align-items: center;
}
.controller-type-list>div{
padding: 0 24px;
cursor: pointer;
}
.controller-type-list{
display: flex;
margin-left: 12px;
}
.insert-controller-header input{
border-radius: 100px;
background: #F4F4F4;
border: 1px solid #f0f0f0;
outline: 0;
padding: 4px 16px;
font-size: 12px;
}
.controller-name-list img{
width: 45px;
height: 45px;
display: block;
}
.controller-name-list.block-name-list img{
width: 85px;
height: 85px;
display: block;
border: 1px solid #DCDFE6;
border-radius: 4px;
}
.single-controller-name{
display: flex;
align-items: center;
background: none;
cursor: move;
}
.single-controller-box{
display: inline-block;
background: none;
margin-right: 24px;
}
.controller-name-list{
padding: 24px 0;
}
.insert-close{
position: absolute;
right: 16px;
top: 16px;
}
.insert-close .iconfont{
font-size: 24px;
cursor: pointer;
color: #999;
}
.insert-close{
width: 26px;
height: 26px;
border-radius: 26px;
text-align: center;
}
.insert-close:hover{
background: #F0F0F0;
}
.insert-close:hover .iconfont{
color: #333;
}
@keyframes fadeTopToBottom
{
from {top:53px; opacity: 0;}
to {top:73px; opacity: 1;}
}
.index-select{
width: calc(100% - 24px);
margin: 0 auto;
background: #F7F7F7;
border-radius: 24px;
border: 1px solid #f0f0f0;
margin-top: 12px;
display: flex;
align-items: center;
/* padding-right: 12px; */
}
.index-select input{
border: 0;
background: #F7F7F7;
outline: 0;
font-size: 12px;
padding: 4px 12px;
border-radius: 24px;
flex: auto;
}
.operation-container-right{
height: 100%;
background: #fff;
box-sizing: border-box;
border-left: 1px solid #E4E4E4;
width: 232px;
position: absolute;
right: 0;
top: 0;
display: flex;
flex-direction: column;
}
.main-container-inner{
height: 100%;
text-align: center;
margin: 0 auto;
position: relative;
overflow-y: scroll;
overflow-x: hidden;
min-width: 720px;
max-width: 800px;
width: 54%;
}
.main-editor{
width: 100%;
margin: 0 auto;
min-height: 960px;
background: #fff;
box-sizing: border-box;
bottom: 0;
transition: all .2s;
text-align: left;
font-size: 14px;
padding: 48px 32px;
}
.tree-box{
padding: 12px;
height: calc(100% - 91px);
overflow-y: scroll;
overflow-x: hidden;
}
.tree-box .el-tree-node__label{
font-size: 12px;
}
.index-container{
height: 50%;
border-bottom: 1px solid #f0f0f0;
box-sizing: border-box;
}
.index-container.side-editor{
flex: 1;
overflow-y: scroll;
overflow-x: hidden;
padding-bottom: 24px;
}
.side-editor h3{
font-size: 14px;
padding: 12px;
font-weight: normal;
}
.editor-list{
display: flex;
padding: 6px 12px;
font-size: 12px;
}
.editor-list .title{
flex: 1;
}
.editor-list .detail{
flex: 3;
}
.editor-list input{
outline: 0;
line-height: 18px;
border-radius: 2px;
border: 1px solid #f0f0f0;
box-sizing: border-box;
font-size: 12px;
width: 100%;
text-indent: 4px;
box-sizing: border-box;
}
.more-detail{
margin-bottom: 8px;
font-size: 0;
display: flex;
align-items: center;
}
.more-detail span{
color: #999;
margin-right: 8px;
font-size: 12px;
}
.more-detail i{
color: #999;
font-size: 12px;
cursor: pointer;
position: absolute;
right: 0;
}
.more-detail i:hover{
color: #D0021B;
}
.more-detail>div{
font-size: 12px;
flex: auto;
}
.switch{
background: #DBDBDB;
height: 10px;
width: 28px;
border-radius: 24px;
display: inline-block;
position: relative;
cursor: pointer;
}
.switch.active{
background: #D0021B;
}
.switch .switch-btn{
width: 14px;
height: 14px;
border-radius: 14px;
background: #fff;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.2);
position: absolute;
left: -1px;
top: -2px;
transition: all .2s;
}
.switch.active .switch-btn{
left: calc(100% - 13px);
}
.editor-list .input-box{
margin-bottom: 8px;
}
.more-detail .select{
display: inline-block;
background: #F9F9F9;
border: 1px solid #f0f0f0;
box-sizing: border-box;
line-height: 18px;
text-indent: 4px;
position: relative;
border-radius: 2px;
cursor: pointer;
}
.more-detail .select.active{
border: 1px solid #D0021B;
}
.select-inner{
padding-right: 4px;
display: flex;
align-items: center;
}
.select-inner .choosed{
flex: auto;
padding-left: 4px;
}
.select-inner .iconfont{
font-size: 5px;
margin-right: 0;
color: #999;
}
.select.active .select-list{
display: block;
}
.select .icon{
text-align: center;
}
.select-list {
position: absolute;
top: calc(100% + 2px);
background: #fff;
width: 100%;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.1);
z-index: 1;
border-radius: 2px;
display: none;
animation: fadeSelect .1s linear;
}
.select-list.custom{
width: 212px;
right: 0;
}
@keyframes fadeSelect
{
from {top:calc(100% + 6px); opacity: 0;}
to {top:calc(100% + 2px); opacity: 1;}
}
.select-list P{
padding-left: 4px;
margin: 8px 0;
cursor: pointer;
}
.select-list P:hover{
color: #D0021B;
background: #FAE5E8;
}
.update-btn{
color: #fff;
background: #D0021B;
display: inline-block;
width: 80%;
line-height: 24px;
font-size: 12px;
margin: 0 auto;
border-radius: 2px;
margin-top: 32px;
cursor: pointer;
transition: all .2s;
}
.update-btn:hover{
/* background: #BE0017; */
box-shadow: 0 4px 4px rgba(208, 2, 27, 0.3)
}
.more-detail.right-icon{
padding-right: 20px;
position: relative;
}
/* .main-editor img{
width: 100%;
margin: 0 auto;
display: block;
} */
.main-editor img.cover{
border: 1px solid #D0021B;
}
.main-editor .custom-block{
cursor: move;
outline: 0;
padding: 12px 0;
box-sizing: border-box;
}
.custom-block.image-block{
padding: 0;
margin: 24px auto;
border: 2px solid rgba(0, 0, 0, 0)
}
.custom-block.image-block.active{
border: 2px solid #D0021B;
}
.controller-type-list>div.active{
color: #D0021B;
}
.controller-box-container{
overflow: scroll;
width: 100%;
white-space: nowrap;
}
.text-container{
border: 1px dashed #DADADA;
padding: 12px;
text-align: justify;
position: relative;
}
.normal-text{
display: inline;
cursor: pointer;
/* padding: 4px; */
border: 1px dashed #fff;
}
.seat-block{
display: none;
background: #ffdfdf;
padding: 16px;
border: 1px dashed #DADADA;
color: #D0021B;
margin-bottom: 16px;
}
.text-block.active .text-container{
border-color: #ff0000;
}
/* .el-tree.is-dragging.is-drop-not-allow .el-tree-node__content{
cursor: move;
} */
.tree-box li{
padding-left: 16px;
}
.tree-box li span{
line-height: 24px;
font-size: 12px;
display: inline-block;
vertical-align: middle;
}
.tree-box .iconfont{
font-size: 8px;
color: #C0C4CC;
cursor: pointer;
transition: all .3s;
display: inline-block;
vertical-align: middle;
}
.tree-box .iconfont.active{
transform: rotate(90deg)
}
.tree-box .empty{
width: 10px;
display: inline-block;
}
.tree-box .tree-title{
cursor: pointer;
}
.tree-box .tree-title:hover span{
color: #D0021B;
}
.tree-box .icon-box{
display: inline-block;
width: 10px;
vertical-align: middle;
}
.index-block{
/* background: #D8EAFF; */
display: inline;
/* padding: 4px; */
color: #308FFF;
cursor: pointer;
box-sizing: border-box;
border: 1px dashed rgba(0, 0, 0, 0);
}
.index-block.active{
border-bottom: 2px solid #ff6476;
}
.normal-text.active{
border-bottom: 2px solid #ff6476;
/* background: #ff6476; */
}
.normal-text.editing{
background: #D8EAFF;
cursor: text;
border: 1px solid rgba(0, 0, 0, 0);
}
.index-list{
border: 1px solid #f0f0f0;
background: #F9F9F9;
border-radius: 2px;
padding: 4px;
}
.single-list{
background: #fff;
border: 1px solid #f0f0f0;
line-height: 18px;
display: flex;
flex: auto;
align-items: center;
cursor: move;
}
.single-list-box{
display: flex;
align-items: center;
}
.single-list span{
flex: auto;
padding-left: 4px;
}
.single-list i{
font-size: 9px;
color:#999;
padding-right: 4px;
}
.single-list-box>i{
padding-left: 4px;
cursor: pointer;
font-size: 13px;
}
.single-list-box>i:hover{
color: #D0021B;
}
.single-list-box{
margin-bottom: 4px;
}
.index-list .single-list-box:last-child{
margin-bottom: 0;
}
.choosed-editing-index{
margin-bottom: 8px;
}
.range-container .title{
font-size: 12px;
padding: 6px 0;
padding-left: 6px;
box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.08);
cursor: pointer;
border-bottom: 1px solid #f9f9f9;
box-sizing: border-box;
}
.range-container i{
font-size: 10px;
margin-right: 4px;
color: #999;
display: inline-block;
}
.range-container.active{
flex: 1;
}
.range-container.active .icontree-tag{
transform: rotate(90deg)
}
.empty-tip{
text-align: center;
color: #999;
font-size: 12px;
padding-top: 36px;
}
.empty-tip img{
width: 126px;
height: auto;
}
.pisition-light{
display: inline;
padding: 2px 1px;
background: #D0021B;
margin: 0 4px;
display: none;
}
.text-inline-block{
margin: 0 4px;
}
.container-tab-index>div{
display: inline-block;
}
.container-tab-index{
font-size: 13px;
flex: auto;
text-align: right;
}
.container-tab-index .iconfont{
font-size: 8px;
color: #999;
}
.block-center-container .time{
font-size: 12px;
color: #999;
margin-top: 0;
}
.block-center-container p{
margin-bottom: 4px;
}
.add-new-block img{
width: 52px;
height: auto;
margin-top: 20px;
}
@keyframes blockfade
{
from {top:8px; opacity: 0;}
to {top:0px; opacity: 1;}
}
.block-container{
padding: 16px;
border: 1px dashed #DADADA;
cursor: move;
margin-bottom: 16px;
text-align: justify;
animation: blockfade .2s linear;
position: relative;
top: 0;
transition: transform .5s;
}
.block-container.active{
border-color: #ff0000;
}
.block-container.cover{
border-color: #ff0000;
}
.inline-text{
display: inline;
position: relative;
}
.inline-text.active{
border: 1px solid #D4D4D4;
}
.inline-text:hover{
border-bottom: 2px solid #308FFF;
}
.inline-text.cover-left{
border-left: 2px solid #308FFF;
padding-left: 2px;
margin-left: 2px;
}
.inline-text.cover-right, .inline-text.cover{
border-right: 2px solid #308FFF;
padding-right: 2px;
margin-right: 2px;
}
.inline-text.edit{
cursor: text;
background: #D7E9FF;
}
.index-text{
color: #308FFF;
}
.image-box{
display: inline-block;
width: 70%;
margin: 0 auto;
position: relative;
}
.image-box.active{
border: 1px solid #dadada;
}
.image-box.active .drag-left-top{
position: absolute;
width: 8px;
height: 8px;
background: #fff;
border: 1px solid #dadada;
left: -4px;
top: -4px;
cursor: nwse-resize;
}
.image-box.active .drag-right-top{
position: absolute;
width: 8px;
height: 8px;
background: #fff;
border: 1px solid #dadada;
right: -4px;
top: -4px;
cursor: nesw-resize;
}
.image-box.active .drag-left-bottom{
position: absolute;
width: 8px;
height: 8px;
background: #fff;
border: 1px solid #dadada;
left: -4px;
bottom: -4px;
cursor: nesw-resize;
}
.image-box.active .drag-right-bottom{
position: absolute;
width: 8px;
height: 8px;
background: #fff;
border: 1px solid #dadada;
right: -4px;
bottom: -4px;
cursor: nwse-resize;
}
#mainBoard:before{
content: attr(placeholder);
color:#bbb;
cursor: text;
}
#mainBoard.inputing:before{
content: none;
}
#gragbox{
position: fixed;
z-index: 100;
left: 0;
top: 0;
display: none;
}
#light{
width: 2px;
height: 16px;
background: #ff0000;
position: absolute;
left: 0;
top: 0;
z-index: 1000;
display: none;
opacity: 0;
}
#cloneBox{
width: 100%;
margin: 0 auto;
box-sizing: border-box;
text-align: left;
font-size: 14px;
padding: 32px;
position: absolute;
top: 24px;
left: 0;
z-index: -1;
opacity: 0;
}
#sizeChange{
width: 100px;
height: 100px;
box-sizing: border-box;
position: absolute;
border: 1px dashed #0096fd;
left: 0;
top: 0;
}
#sizeChange .size-btn{
width: 9px;
height: 9px;
background: #0096fd;
position: absolute;
border: 2px solid #fff;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.5);
border-radius: 2px;
}
#sizeChange .right-top{
right: -7px;
top: -7px;
cursor: nesw-resize;
}
#sizeChange .left-top{
left: -7px;
top: -7px;
cursor: nwse-resize;
}
#sizeChange .left-bottom{
left: -7px;
bottom: -7px;
cursor: nesw-resize;
}
#sizeChange .right-bottom{
right: -7px;
bottom: -7px;
cursor: nwse-resize;
}
.tools-box{
width: 100%;
margin: 0 auto;
font-size: 14px;
border-bottom: 1px solid #e8e8e8;
/* box-shadow: 0 1px 24px rgba(0, 0, 0, 0.1); */
cursor: default
}
.tools-box .tools-child{
min-width: 40px;
text-align: center;
padding: 12px 16px;
position: relative;
cursor: pointer;
box-sizing: border-box;
}
.tools-box .tools-child .iconfont{
font-size: 14px;
}
.tools-box .tools-child span{
line-height: 14px;
}
.tools-box .tools-child:hover{
background: #e8e8e8;
}
.tools-box .tools-box-inner{
min-width: 720px;
max-width: 800px;
width: 54%;
margin: 0 auto;
display: flex;
align-items: center;
}
.tool-color{
position: absolute;
bottom: 8px;
height: 2px;
background: #ff0000;
width: 14px;
}
.tools-child.border::after{
content: '';
height: 14px;
width: 1px;
position: absolute;
right: 0;
background: #e8e8e8;
top: calc(50% - 7px)
}
.tool-select{
position: absolute;
right: 12px;
top: calc(50% - 10px);
}
.tool-select span{
font-size: 5px !important;
color: #999;
}
.single-color{
min-width: 16px;
height: 16px;
background: #ff0000;
margin: 4px;
cursor: pointer;
position: relative;
}
.single-color:hover{
top: -2px;
}
.color-box{
display: flex;
flex-wrap: wrap;
}
.analyzer-container{
padding: 12px;
flex-direction: column;
padding: 12px;
flex: 1;
color: #333;
min-width: 1200px;
}
.analyzer-header{
background: #fff;
margin-bottom: 12px;
}
.analyzer-content{
background: #fff;
padding: 20px;
padding-top: 0;
font-size: 13px;
flex: auto;
/* overflow: scroll; */
display: flex;
flex-direction: column;
}
.analyzer-header-title{
display: flex;
align-items: center;
border-bottom: 1px solid #EBEEF5;
padding: 16px 24px;
}
.analyzer-header-tab{
display: flex;
align-items: center;
}
.analyzer-header-title-name{
font-size: 16px;
font-weight: bold;
margin-right: 46px;
}
.analyzer-header-tab>div{
padding: 0 20px;
border-right: 1px solid #EBEEF5;
cursor: pointer;
font-size: 14px;
}
.analyzer-header-tab>div.active{
color: #D0021B;
}
.analyzer-header-tab>div:last-child{
border-right: 0;
}
.analyzer-header-condition{
padding: 24px 20px;
display: flex;
}
.analyzer-header-condition .common-condition{
/* flex: auto; */
padding-right: 20px;
/* min-width: 1008px; */
}
.analyzer-header-condition .self-condition{
min-width: 200px;
border-left: 1px solid #EBEEF5;
padding-left: 20px;
flex: auto;
}
.smallSize .el-radio__label{
font-size: 12px;
padding-left: 6px;
}
.smallSize .el-radio{
margin-right: 12px;
}
.smallSize .el-radio__inner{
width:12px;
height: 12px;
}
.smallSize .el-radio{
font-size: 12px;
}
/* .smallSize .el-radio__inner{
height: 12px;
width: 12px;
} */
.smallSize .el-checkbox__label{
font-size: 12px;
}
.analyzer-header-condition{
font-size: 12px;
}
.condition-title{
margin-right: 8px;
color: #999;
min-width: 54px;
padding: 4px 0;
}
.condition-column{
display: flex;
align-items: center;
}
.single-condition{
display: flex;
align-items: center;
}
.more-condition{
color: #D0021B;
margin-left: 24px;
cursor: pointer;
min-width: 96px;
}
.light{
color: #999;
}
.table-title{
font-size: 13px;
color: #333;
margin: 16px 0;
padding-left: 12px;
border-left: 2px solid #D0021B;
line-height: 13px;
}
.table-box-container{
display: flex;
flex: auto;
}
.table-box{
flex: auto;
overflow: scroll;
overflow-x: hidden;
}
.quick-router{
min-width: 120px;
margin-left: 28px;
padding: 24px 0;
}
.quick-router ul{
text-align: left;
font-size: 12px;
padding-left: 12px;
border-left: 1px solid #EBEEF5;
}
.quick-router ul li{
margin-bottom: 12px;
}
.quick-router ul li.active{
color: #D0021B;
position: relative;
}
.quick-router ul li.active::before{
content: '';
width: 7px;
height: 7px;
border-radius: 7px;
position: absolute;
left: -18px;
top: 3px;
background: #D0021B;
border: 2px solid #FFD2D8;
}
.table-wrap{
padding: 12px 0;
}
.search-content{
font-size: 12px;
max-height: 100px;
overflow: scroll;
}
.search-content>div{
padding: 4px 8px;
cursor: pointer;
}
.search-content>div:hover{
background: rgb(245, 247, 250);
}
.block-box{
margin-bottom: 24px;
}
.block-box-title{
color: #999;
font-size: 12px;
margin-bottom: 12px;
}
.outline-table{
font-size: 14px;
width: 886px;
margin: 0 auto;
/* border: 1px solid #EBEEF5; */
margin-top: 36px;
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.1);
padding: 20px 48px;
color: #666;
background: #fff;
margin-bottom: 24px;
}
.outline-table-header{
text-align: center;
padding: 20px 0;
border-bottom: 1px solid #EBEEF5;
padding-bottom: 28px;
}
.outline-table-header .title{
font-size: 20px;
font-weight: bold;
padding: 12px 0;
color: #333;
}
.outline-table-content{
text-align: left;
padding: 24px 0;
}
.outline-table-content .title{
font-weight: bold;
margin-bottom: 8px;
font-size: 14px;
color: #333;
}
.outline-table-content .project{
padding: 16px 0;
padding-left: 20px;
position: relative;
}
.outline-table-content .project::before{
content: '';
position: absolute;
left: 0;
top: 21px;
width: 8px;
height: 8px;
border-radius: 8px;
}
.outline-table-content .project.red::before{
background: #FF6159;
}
.outline-table-content .project.green::before{
background: #28CB42;
}
.outline-table-content .project.yellow::before{
background: #FFBD2E;
}
.outline-table-content .project.blue::before{
background: #2869CB;
}
.dimension-check-box{
background: #eaeaea;
border-radius: 4px;
padding: 4px 8px;
margin-right: 8px;
margin-bottom: 8px;
display: inline-block;
}
.dimension-check-box i{
cursor: pointer;
font-size: 12px;
margin-left: 4px;
color: #999;
}
.dimension-check-box i:hover{
color: #D0021B;
}
.all-dimension{
text-align: left;
padding: 4px;
}
.dimension-check-box.add-more{
background: #F9E6E8;
color: #D6263B;
cursor: pointer;
box-sizing: border-box;
}
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="../../../static/plTable/index.css">
<link rel="stylesheet" href="../../../static/element/theme/index.css">
<link rel="stylesheet" href="../../../static/global/global.css">
<link rel="stylesheet" href="./indexManage.css">
</head>
<body>
<div id="app" class="production-line-container" v-cloak>
<router-view></router-view>
</div>
</body>
<script src="../../../static/vue/vue.min.js"></script>
<script src="../../../static/element/index.js"></script>
<script src="../../../static/vue-router/vue-router.js"></script>
<script src='../../../static/xlsx/xlsx.full.min.js'></script>
<script src="../../../static/plTable/index.js"></script>
<!-- <script src="../../lib/vue/vue.js"></script>
<script src="../../lib/element/index.js"></script>
<script type="text/javascript" src='../../lib/xlsx/xlsx.full.min.js'></script>
<script src="../../lib/vue-router/vue-router.js"></script>
<script src="../../lib/plTable/index.js"></script>
<script src="../../lib/echarts/echarts.min.js"></script> -->
<script>
const { app } = require('electron').remote
const path = app.getAppPath()
const { routes } = require(path + '/src/views/main_views/indexManage/routers/router.js')
const router = new VueRouter({ routes })
const http = require(path + '/src/assist/axios.js')
var info = JSON.parse(localStorage.getItem('userInfo'))
const { splitPane } = require('vue-splitpane')
Vue.component('split-pane', splitPane)
new Vue({
router,
el: '#app',
data: function() {
return {
hasPadding: true
}
},
mounted () {
},
methods: {
}
})
</script>
</html>
\ No newline at end of file
//有关于条件的一些方法
function getFormatValue (value) {
var unit = '', num = 1
if(value < 10000){
unit = '', num = 1
}else if(10000 <= value && value < 100000000){
unit = '', num = 10000
}else if(100000000 <= value && value < 1000000000000){
unit = '亿', num = 100000000
}else if(value >= 1000000000000){
unit = '万亿', num = 1000000000000
}
return (value/num).toFixed(0) + unit
}
function getInputLength (text) {
var width = 0, span
if(!document.getElementById('invented')){
span = document.createElement('span')
span.id = 'invented'
span.innerHTML = text
document.body.appendChild(span)
}else{
span = document.getElementById('invented')
span.innerHTML = text
}
width = span.offsetWidth
return width + 4
}
exports.getFullIndexName = (index) => {
var indexName = index.name, merge = '', company = '', year = '', quarter = ''
if(index.needMergeType){
merge = '[' + index.mergeType + ']'
}
if(index.needReportData){
if(index.yearType == 1){
year = '[T:' + index.t + ']'
}else{
year = '[T:' + index.inputYear + ']'
}
if(index.quarterType == 1){
quarter = '[Q:' + index.q + ']'
}else{
quarter = '[Q:' + index.inputQuarter + ']'
}
}
if(index.needCompany && index.isAppointCompany){
company = '[' + index.selectedCompany + ']'
}
return indexName + year + quarter + merge + company
}
exports.getIndexType = (obj) => {
var newObj = {
needMergeType: false,
needReportData: false,
needCompany: false
}
if(obj.TypeContent){
obj.TypeContent.Parameters.forEach(item => {
if(item.Encode == 'F91997V'){
newObj.needMergeType = true
}
if(item.Encode == 'F91996D'){
newObj.needReportData = true
}
if(item.Encode == 'F90001V'){
newObj.needCompany = true
}
})
}
return newObj
}
exports.setSaveCondition = (condition)=>{ //格式化保存的条件,原名 getSaveCalCondition
var operands = []
var div = document.createElement('div')
div.innerHTML = condition.params.dom
var inputs = div.getElementsByTagName('input')
//后台的定义 0指标1符号2数字3时间4方法
//前台的定义 1指标2时间3数字4字符5方法
Array.from(inputs).forEach(item => {
var obj = {}, id = item.id
switch (parseInt(item.getAttribute('type'))) {
case 1: //指标
var param = condition.params.indexParams[id]
var dateYear = '1900'
var dateQuater = '06-30'
var evalArray = []
if (param.yearType == 1) {
evalArray.push({
"EvalOption": 1,
"Value": param.t
})
} else if (param.yearType == 2) {
dateYear = param.inputYear
}
if (param.quarterType == 1) {
evalArray.push({
"EvalOption": 2,
"Value": param.q
})
} else if (param.quarterType == 2) {
dateQuater = param.inputQuarter
}
var where = [
{
"State": 1,
"Encode": "F91996D",
"Value": dateYear + '-' + dateQuater,
"Eval": evalArray
},
{
"State": 1,
"Value": param.mergeType,
"Encode": "F91997V",
"Eval": []
}
]
if(param.isAppointCompany){
where.push({
"State": 1,
"Value": param.selectedCompany.split('-')[1],
"Encode": "F90001V",
"Eval": []
})
}
obj = {
"List": [param.code],
"Where": where,
"OperandType": 0,
}
break;
case 2: //时间
obj = {
"Value": item.value,
"OperandType": 3
}
break;
case 3: //数字
obj = {
"Value": item.value.replace(/\[.*?\]/g,''),
"OperandType": 2
}
break;
case 4: //字符
obj = {
"Value": item.value,
"OperandType": 1
}
break;
default:
break;
}
operands.push(obj)
})
return operands
}
exports.getSaveCondition = (
id, conditionContents, conditionSignature, paramsList, initIndexObj,companyNameObj, getEval, initIndex, that
)=>{ //格式化获取的条件原名 setCalCondition, 启动参数中 setEditCondition, 公司名称 searchCompanyName, 所有指标 getIndexCateGory(initIndexObj)
if(conditionSignature && that.conditionIndex < parseInt(conditionSignature)){
that.conditionIndex = parseInt(conditionSignature)
}
if(that){
that.$set(paramsList, id, {
id: id == 'start'?'start':(conditionSignature?conditionSignature:null),
params: {
indexParams: {},
dateParams: {},
numParams: {},
symbolParams: {},
dom: '',
showDom: ''
}
})
}
var param = paramsList[id].params
conditionContents.forEach(item => {
initIndex++
var id = new Date().getTime() + initIndex
var obj = {}
var inputDom = ''
var showDom = ''
var paramsType = ''
switch (item.OperandType) {
case 0: //指标
var index = initIndexObj[item.List[0]]
var condition = this.getIndexType(index)
var evalObj = getEval(item.Where[0])
obj = {
code: item.List[0],
id: id,
inputQuarter: evalObj.selsetQuarter,
inputYear: evalObj.selectYear,
q: evalObj.qQuarter,
t: evalObj.tYear,
quarterType: evalObj.reportQuarterType,
yearType: evalObj.reportYearType,
mergeType: item.Where[1].Value,
type: 1,
isAppointCompany: item.Where[2]?true:false,
selectedCompany: item.Where[2]?(companyNameObj[item.Where[2].Value] + '-' + item.Where[2].Value):'',
mark: index.Mark,
name: index.Name,
needMergeType: condition.needMergeType,
needReportData: condition.needReportData,
needCompany: condition.needCompany,
typeContent: index.TypeContent
}
var text = this.getFullIndexName(obj)
var width = getInputLength(text) + 'px'
inputDom = '<input readonly class="cal-index" type="1" id="'+ id +'" style="width:'+ width +'" value="'+ text +'" />'
showDom = '<span type="1">' + text + '</span>'
paramsType = 'indexParams'
break;
case 1: //符号
obj = {
id: id,
key: item.Value,
type: 4,
value: item.Value
}
var width = getInputLength(item.Value) + 'px'
var moreClass = ''
switch (item.Value) {
case '(': case ')':
moreClass = 'brackets'
break;
default:
break;
}
inputDom = '<input readonly class="cal-index ' + moreClass + '" type="4" id="'+ id +'" style="width:'+ width +'" value="'+ item.Value +'" />'
showDom = '<span type="4">' + item.Value + '</span>'
paramsType = 'symbolParams'
break;
case 2: //数字
obj = {
id: id,
type: 3,
value: item.Value
}
var text = item.Value + "[" + getFormatValue(item.Value) + "]"
var width = getInputLength(text) + 'px'
inputDom = '<input readonly class="cal-index" type="3" id="'+ id +'" style="width:'+ width +'" value="'+ text +'" />'
showDom = '<span type="3">' + text + '</span>'
paramsType = 'numParams'
break;
case 3: //时间
obj = {
id: id,
type: 2,
value: item.Value
}
var text = item.Value
var width = getInputLength(text) + 'px'
inputDom = '<input readonly class="cal-index" type="2" id="'+ id +'" style="width:'+ width +'" value="'+ text +'" />'
showDom = '<span type="2">' + text + '</span>'
paramsType = 'dateParams'
break;
case 4: //方法,暂不做处理
break;
default:
break;
}
// param[paramsType] = {}
param[paramsType][id] = obj
param.dom+=inputDom
param.showDom+=showDom
})
if(!param.showDom){
param.showDom = '<span>暂未设置条件</span>'
}
}
module.exports = (filename, dirname)=>{
const fs = require('fs')
const os = require('os')
const platform = os.platform()
const filePath = filename.replace('.js','.vue')
const dirName = dirname.replace('.js','.vue')
var name
if(platform == 'darwin'){
name = dirName.split('/').pop()
}else{
name = dirName.split('\\').pop()
}
var data = fs.readFileSync(filePath);
var str = data.toString()
str.substring(0, str.lastIndexOf('</template>'))
str = str.replace('<template>','')
var head = document.getElementsByTagName('head')[0];
var link = document.createElement('link');
var href = filename.replace('.js','.css')
link.href = href;
link.rel = 'stylesheet';
link.type = 'text/css';
head.appendChild(link);
return {
name: name,
template: str
}
}
\ No newline at end of file
//条件上的键盘
var keybordData = [
[
{
key: '插入指标',
isActive: false,
isText: true,
isLong: true,
isFunction: false,
tip: '插入指标',
type: 1,
},
{
key: '插入日期',
isActive: false,
isText: true,
isLong: true,
isFunction: false,
tip: '插入日期',
type: 2
},
{
key: '插入数字',
isActive: false,
isText: true,
isLong: true,
isFunction: false,
tip: '插入数字',
type: 3
},
{
key: 'Kdp( )',
isActive: false,
isText: true,
isLong: false,
isFunction: true,
tip: '保留小数位函数',
type: 5,
funcId: 0,
describe: '保留小数位',
case: 'Kdp(归属于母公司所有者的净利润[T:0][Q:0][合并本期], 2)',
params: [[0,4],[1]], //0指标 1数字 2字符 3时间 4公式
isLimited: true
},
{
key: 'Abs( )',
isActive: false,
isText: true,
isLong: false,
isFunction: true,
tip: '绝对值函数',
type: 5,
funcId: 1,
describe: '求指标或计算片段的绝对值',
case: 'Abs(归属于母公司所有者的净利润[T:0][Q:0][合并本期])',
params: [[0,4]], //0指标 1数字 2字符 3时间 4公式
isLimited: true
},
// {
// key: 'Tf( )',
// isActive: false,
// isText: true,
// isLong: false,
// isFunction: true,
// tip: '时间格式化函数',
// type: 5,
// funcId: 2,
// describe: '对时间进行格式化操作',
// case: 'Abs(上市日期, yyyy-MM-dd)',
// params: [[3],[2]], //0指标 1数字 2字符 3时间 4公式
// isLimited: true
// },
{
key: 'Ave( )',
isActive: false,
isText: true,
isLong: false,
isFunction: true,
tip: '平均值函数',
type: 5,
funcId: 3,
describe: '计算一组数据的平均值',
case: 'Ave(营业总收入[T:-1][Q:0][合并本期], 营业总收入[T:-2][Q:0][合并本期])',
params: [[0,1,4]], //0指标 1数字 2字符 3时间 4公式
isLimited: false
},
{
key: 'Mer( )',
isActive: false,
isText: true,
isLong: false,
isFunction: true,
tip: '当该指标为年报时,用下一年合并上期数据',
type: 5,
funcId: 8,
describe: '计算下一年年报合并上期',
case: 'Mer(营业总收入[T:-1][Q:0][合并本期])',
params: [[0]], //0指标 1数字 2字符 3时间 4公式
isLimited: true
}
],[
{
key: '+',
isActive: false,
isText: true,
isLong: false,
isFunction: false,
tip: '计算符号:加号',
type: 4
},
{
key: '-',
isActive: false,
isText: true,
isLong: false,
isFunction: false,
tip: '计算符号:减号',
type: 4
},
{
key: '*',
isActive: false,
isText: true,
isLong: false,
isFunction: false,
tip: '计算符号:乘号',
type: 4
},
{
key: '/',
isActive: false,
isText: true,
isLong: false,
isFunction: false,
tip: '计算符号:除号',
type: 4
},
{
key: '(',
isActive: false,
isText: true,
isLong: false,
isFunction: false,
tip: '计算符号:左括号',
type: 4
},
{
key: ')',
isActive: false,
isText: true,
isLong: false,
isFunction: false,
tip: '计算符号:右括号',
type: 4
},
{
key: 'Sum( )',
isActive: false,
isText: true,
isLong: false,
isFunction: true,
tip: '求和函数',
type: 5,
funcId: 4,
describe: '计算一组数据的总和',
case: 'Sum(营业总收入[T:-1][Q:0][合并本期], 营业总收入[T:-2][Q:0][合并本期])',
params: [[0,1,4]], //0指标 1数字 2字符 3时间 4公式
isLimited: false
},
{
key: 'Max( )',
isActive: false,
isText: true,
isLong: false,
isFunction: true,
tip: '最大值函数',
type: 5,
funcId: 5,
describe: '计算一组数据的最大值',
case: 'Max(营业总收入[T:-1][Q:0][合并本期], 营业总收入[T:-2][Q:0][合并本期])',
params: [[0,1,4]], //0指标 1数字 2字符 3时间 4公式
isLimited: false
},
{
key: 'Min( )',
isActive: false,
isText: true,
isLong: false,
isFunction: true,
tip: '最小值函数',
type: 5,
funcId: 6,
describe: '计算一组数据的最小值',
case: 'Min(营业总收入[T:-1][Q:0][合并本期], 营业总收入[T:-2][Q:0][合并本期])',
params: [[0,1,4]], //0指标 1数字 2字符 3时间 4公式
isLimited: false
},
{
key: 'Fac( )',
isActive: false,
isText: true,
isLong: false,
isFunction: true,
tip: '阶乘函数',
type: 5,
funcId: 7,
describe: '计算一组数据的阶乘',
case: 'Fac(营业总收入[T:-1][Q:0][合并本期])',
params: [[0,1,4]], //0指标 1数字 2字符 3时间 4公式
isLimited: true
}
]
]
//条件上的键盘
var functionKeybord = [
[
{
key: '插入指标',
isActive: false,
isText: true,
isLong: true,
isFunction: false,
tip: '插入指标',
type: 1,
},
{
key: '插入日期',
isActive: false,
isText: true,
isLong: true,
isFunction: false,
tip: '插入日期',
type: 2
},
{
key: '插入数字',
isActive: false,
isText: true,
isLong: true,
isFunction: false,
tip: '插入数字',
type: 3
}
],[
{
key: '+',
isActive: false,
isText: true,
isLong: false,
isFunction: false,
tip: '计算符号:加号',
type: 4
},
{
key: '-',
isActive: false,
isText: true,
isLong: false,
isFunction: false,
tip: '计算符号:减号',
type: 4
},
{
key: '*',
isActive: false,
isText: true,
isLong: false,
isFunction: false,
tip: '计算符号:乘号',
type: 4
},
{
key: '/',
isActive: false,
isText: true,
isLong: false,
isFunction: false,
tip: '计算符号:除号',
type: 4
},
{
key: '(',
isActive: false,
isText: true,
isLong: false,
isFunction: false,
tip: '计算符号:左括号',
type: 4
},
{
key: ')',
isActive: false,
isText: true,
isLong: false,
isFunction: false,
tip: '计算符号:右括号',
type: 4
}
]
]
module.exports = {
keybordData, functionKeybord
}
var mergeData = ['合并本期','合并上期','母公司本期','母公司上期']
module.exports = {
mergeData
}
// exports.getDefaultType = (defaultTypeList) => {
// return new Promise((resolve, reject) => {
// http.netPost('Data/CustomIndex/GetAllIndexArgs', {
// "AccountId": store.get('accountId')
// })
// .then((res) => {
// if (res.data.Status == 1) {
// defaultTypeList = res.data.Data
// resolve()
// }
// })
// })
// }
exports.getKeyboardObj = (keyBord, keyboardObj) => {
var arr = keyBord.keybordData
arr.forEach(item => {
item.forEach(sub => {
if(sub.type == 5){
keyboardObj[sub.funcId] = sub
}
})
})
}
exports.getIndexs = (initIndexObj) => {
return new Promise((resolve, reject) => {
http.netPost('Data/Encode/GetEncodeList', {
"Current": 0,
"Psize": 100,
"Code": "B",
'Name': '',
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
this.creatIndexObj(res.data.Data.Records, initIndexObj)
resolve()
}
})
})
}
exports.creatIndexObj = (initData, initIndexObj) => {
initData.forEach(element => {
if(element.Sub.length > 0){
this.creatIndexObj(element.Sub, initIndexObj)
}else{
initIndexObj[element.Code] = element
var tableName = element.Origin?element.Origin.TableComment:null
var dbName = element.Origin?element.Origin.DbComment:null
initIndexObj[element.Code].originText = tableName + '-' + dbName
}
})
}
exports.getUsedCompany = (params,companyNameObj) => {
var codes = []
params.forEach(item => {
if(item.OperandType == 0 && item.Where[2]){
codes.push(item.Where[2].Value)
}else if(item.OperandType == 4){
item.Args.forEach(sub => {
sub.forEach(child => {
if(child.OperandType == 0 && child.Where[2]){
codes.push(child.Where[2].Value)
}
})
})
}
})
var where = [{
"Encode": "F90001V",
"State": 7,
"Value": codes.join(','),
}]
return new Promise((resolve, reject) => {
http.netPost('Data/Query/Query', {
"List": ['F90001V', 'F90002V'],
"Where": where,
"Current": 0,
"Psize": 100
})
.then((res) => {
if (res.data.Status == 1) {
res.data.Data.Records.forEach(item => {
companyNameObj[item.F90001V] = item.F90002V
})
resolve()
}else if(res.data.Status == 0){
resolve()
}else{
reject()
}
})
})
}
exports.getSaveCondition = (activeIndexCondition, condition, initIndex, initIndexObj, companyNameObj, keyboardObj) => {
condition.forEach(item => {
initIndex++
var id = new Date().getTime() + initIndex
var obj = {}
var inputDom = ''
var showDom = ''
var paramsType = ''
switch (item.OperandType) {
case 0: //指标
var index = initIndexObj[item.List[0]]
var condition = this.getIndexType(index)
var evalObj = this.getEval(item.Where[0])
obj = {
code: item.List[0],
id: id,
inputQuarter: evalObj.selsetQuarter,
inputYear: evalObj.selectYear,
q: evalObj.qQuarter,
t: evalObj.tYear,
quarterType: evalObj.reportQuarterType,
yearType: evalObj.reportYearType,
mergeType: item.Where[1].Value,
type: 1,
isAppointCompany: item.Where[2]?true:false,
selectedCompany: item.Where[2]?(companyNameObj[item.Where[2].Value] + '-' + item.Where[2].Value):'',
mark: index.Mark,
name: index.Name,
needMergeType: condition.needMergeType,
needReportData: condition.needReportData,
needCompany: condition.needCompany,
typeContent: index.TypeContent || []
}
var text = this.getFullIndexName(obj)
var width = this.getInputLength(text) + 'px'
inputDom = '<input readonly class="cal-index" type="1" id="'+ id +'" style="width:'+ width +'" value="'+ text +'" />'
showDom = '<span type="1">' + text + '</span>'
paramsType = 'indexParams'
break;
case 1: //符号
obj = {
id: id,
key: item.Value,
type: 4,
value: item.Value
}
var width = this.getInputLength(item.Value) + 'px'
var moreClass = ''
switch (item.Value) {
case '(': case ')':
moreClass = 'brackets'
break;
default:
break;
}
inputDom = '<input readonly class="cal-index ' + moreClass + '" type="4" id="'+ id +'" style="width:'+ width +'" value="'+ item.Value +'" />'
showDom = '<span type="4">' + item.Value + '</span>'
paramsType = 'symbolParams'
break;
case 2: //数字
obj = {
id: id,
type: 3,
value: item.Value
}
var text = item.Value + "[" + this.getFormatValue(item.Value) + "]"
var width = this.getInputLength(text) + 'px'
inputDom = '<input readonly class="cal-index" type="3" id="'+ id +'" style="width:'+ width +'" value="'+ text +'" />'
showDom = '<span type="3">' + text + '</span>'
paramsType = 'numParams'
break;
case 3: //时间
obj = {
id: id,
type: 2,
value: item.Value
}
var text = item.Value
var width = this.getInputLength(text) + 'px'
inputDom = '<input readonly class="cal-index" type="2" id="'+ id +'" style="width:'+ width +'" value="'+ text +'" />'
showDom = '<span type="2">' + text + '</span>'
paramsType = 'dateParams'
break;
case 4:
var origin = keyboardObj[item.Action]
obj = {
value: origin.key,
key: origin.key,
type: 5,
id: id,
originParams: JSON.parse(JSON.stringify(origin)),
paramsValue: []
}
item.Args.forEach((sub,index) => {
if(index > origin.length){
obj.originParams.params.push(JSON.parse(JSON.stringify(obj.originParams.params[0])))
}
obj.paramsValue[index] = {
indexParams: {},
dateParams: {},
numParams: {},
symbolParams: {},
functionParams: {},
dom: '',
showDom: ''
}
initIndex++
this.getSaveCondition(obj.paramsValue[index], item.Args[index], initIndex, initIndexObj, companyNameObj, keyboardObj)
})
// origin.params.forEach((item,index) => {
// this.getFuncCondition(obj.paramsValue[index], item.Args[index])
// })
var arr = []
obj.paramsValue.forEach(item => {
var text = this.getShowDomText(item.showDom)
arr.push(text)
})
var name = obj.key.replace('( )','')
var value = name + '(' + arr.join(', ') + ')'
var text = value
var width = this.getInputLength(text) + 'px'
inputDom = '<input readonly class="cal-index" type="5" id="'+ id +'" style="width:'+ width +'" value="'+ text +'" />'
showDom = '<span type="5">' + text + '</span>'
paramsType = 'functionParams'
break;
default:
break;
}
activeIndexCondition[paramsType][id] = obj
activeIndexCondition.dom+=inputDom
activeIndexCondition.showDom+=showDom
})
if(!activeIndexCondition.showDom){
activeIndexCondition.showDom = '<span>暂未设置计算公式</span>'
}
}
exports.getIndexType = (obj) => {
var newObj = {
needMergeType: false,
needReportData: false,
needCompany: false
}
if(obj.TypeContent){
obj.TypeContent.Parameters.forEach(item => {
if(item.Encode == 'F91997V'){
newObj.needMergeType = true
}
if(item.Encode == 'F91996D'){
newObj.needReportData = true
}
if(item.Encode == 'F90001V'){
newObj.needCompany = true
}
})
}
return newObj
}
exports.getEval = (item) => {
var newObj = {
reportYearType: 1,
tYear: 0,
selectYear: '',
reportQuarterType: 1,
qQuarter: 0,
selsetQuarter: ''
}
switch (item.Eval.length) {
case 0:
newObj.reportYearType = 2
newObj.selectYear = item.Value.slice(0,4)
newObj.reportQuarterType = 2
newObj.qQuarter = 0
newObj.tYear = 0
newObj.selsetQuarter = item.Value.slice(5,10)
break;
case 1:
if(item.Eval[0].EvalOption == 1) { //年度为t
newObj.reportYearType = 1
newObj.tYear = item.Eval[0].Value
newObj.selectYear = item.Value.slice(0,4)
newObj.reportQuarterType = 2
newObj.qQuarter = 0
newObj.selsetQuarter = item.Value.slice(5,10)
}else if(item.Eval[0].EvalOption == 2){
newObj.reportYearType = 2
newObj.tYear = 0
newObj.selectYear = item.Value.slice(0,4)
newObj.reportQuarterType = 1
newObj.qQuarter = item.Eval[0].Value
newObj.selsetQuarter = item.Value.slice(5,10)
}
break;
case 2:
newObj.reportYearType = 1
newObj.selectYear = ''
newObj.reportQuarterType = 1
newObj.selsetQuarter = ''
newObj.qQuarter = item.Eval[1].Value
newObj.tYear = item.Eval[0].Value
break;
default:
break;
}
return newObj
}
exports.getFullIndexName = (index) =>{
var indexName = index.name, merge = '', company = '', year = '', quarter = ''
if(index.needMergeType){
merge = '[' + index.mergeType + ']'
}
if(index.needReportData){
if(index.yearType == 1){
year = '[T:' + index.t + ']'
}else{
year = '[T:' + index.inputYear + ']'
}
if(index.quarterType == 1){
quarter = '[Q:' + index.q + ']'
}else{
quarter = '[Q:' + index.inputQuarter + ']'
}
}
if(index.needCompany && index.isAppointCompany){
company = '[' + index.selectedCompany + ']'
}
return indexName + year + quarter + merge + company
}
exports.getInputLength = (text) => {
var width = 0, span
if(!document.getElementById('invented')){
span = document.createElement('span')
span.id = 'invented'
span.innerHTML = text
document.body.appendChild(span)
}else{
span = document.getElementById('invented')
span.innerHTML = text
}
width = span.offsetWidth
return width + 4
}
exports.getFormatValue = (value) => {
var unit = '', num = 1
if(value < 10000){
unit = '', num = 1
}else if(10000 <= value && value < 100000000){
unit = '', num = 10000
}else if(100000000 <= value && value < 1000000000000){
unit = '亿', num = 100000000
}else if(value >= 1000000000000){
unit = '万亿', num = 1000000000000
}
return (value/num).toFixed(0) + unit
}
exports.getShowDomText =(html) => {
var div = document.createElement('div')
if(html){
div.innerHTML = html
return div.innerText
}else{
return '未设置'
}
}
exports.insertAfter = (newElement, targetElement) => {
var parent = targetElement.parentNode
if (parent.lastChild == targetElement){
parent.appendChild(targetElement)
} else {
parent.insertBefore(newElement, targetElement.nextSibling);
}
}
exports.createAppointedText = (num) => {
var str = '', text
for(var i = 0; i < num; i++){
str+='\u00A0'
}
text = document.createTextNode(str)
return text
}
exports.formatShowDom = (spans) => {
var brackets = []
var numArea = []
Array.from(spans).forEach(item => {
var value = item.innerText
var br = document.createElement('br')
if('()&&||+-*/'.indexOf(value) >= 0 || (item.nextSibling && '()&&||+-*/'.indexOf(item.nextSibling.innerText) >= 0)){
this.insertAfter(br,item)
}
})
Array.from(spans).forEach((item, index) => {
var value = item.innerText
if(value == '(' || value == ')'){
brackets.push({
indet: 0,
from: item,
value: value,
originIndex: index
})
}
})
brackets.forEach((item,index) => {
if(index == 0){
item.indent = 0
var text = this.createAppointedText(item.indent)
item.from.parentNode.insertBefore(text, item.from)
}else{
var newIndent = brackets[index - 1].indent
if(brackets[index - 1].value !== item.value){
item.indent = newIndent
var text = this.createAppointedText(newIndent)
item.from.parentNode.insertBefore(text, item.from)
}else{
if(item.value == '('){
item.indent = newIndent + 4
}else{
item.indent = newIndent - 4
}
var text = this.createAppointedText(item.indent)
item.from.parentNode.insertBefore(text, item.from)
}
numArea.push({
start: brackets[index - 1].originIndex ,
end: item.originIndex,
indent: brackets[index - 1].indent,
value: brackets[index - 1].value
})
}
})
Array.from(spans).forEach((item, index) => {
var value = item.innerText
if(value !== '(' && value !== ')' && item.previousSibling && item.previousSibling.nodeName == 'BR'){
numArea.forEach(area => {
if(index > area.start && index < area.end){
var newIndent
if(area.value == '('){
newIndent = area.indent + 4
}else{
newIndent = area.indent
}
var text = this.createAppointedText(newIndent)
item.parentNode.insertBefore(text, item)
}
})
}
})
}
\ No newline at end of file
const http = require('../../../lib/axios/axios.js')
const { dialog } = require('electron').remote
const officegen = require('officegen')
const path = require('path');
const fs = require('fs')
const filePath = path.resolve(__dirname, './categoryAudit.vue')
let newTemplate = ''
var data = fs.readFileSync(filePath);
var str = data.toString()
var newStr = str.substring(0, str.lastIndexOf('</template>'))
newTemplate = newStr.replace('<template>','')
var keyBord = require('../../lib/keyBord')
var tools = require('../../lib/tools.js')
const condition = require('../../components/condition/index.js')
module.exports = {
categoryAudit: {
data: function () {
return {
tableData: [],
tableType: 2,
searchedName: '',
pageTotal: 0,
pageCurrent: 1,
psize: 15,
tableLoading: true,
activeIndex: {},
activeIndexCondition: {},
subActiveIndex: {},
subActiveIndexCondition: {},
showIndexDetail: false,
defaultTypeList: [],
companyNameObj: {},
initIndexObj: {},
keyboardObj: {},
passCategoryVisible: false,
choosedPassCategory: [],
publicCategoryOptions: [],
publicProps: {
value: 'Code',
label: 'Name',
children: 'Children',
checkStrictly: true
},
passLoading: false,
testRunVisible: false,
rangeCompany: '',
searchCompanyLoading: false,
runningCompanyList: [],
selectedRangeCompany: [],
zjhIndustryData: [],
swIndustryData: [],
marketData:[],
positionData: [],
industryObj: {},
testYear: '',
testQuarter: '',
testMergeType: '合并本期',
activeRangeTab: '3',
showEditIndexDetail: false,
showChangeDetail: false,
initIndex: 1,
currentAccount: 0,
sortType: null,
treeProps: {
children: 'children',
label: 'name'
},
defaultExpandedKeys: [],
myTreeData: [],
isDotEdit: false,
isDotSort: false,
IntervalId: 0,
indexPermission: false
}
},
components: {condition},
template: newTemplate,
mounted () {
this.checkPermission(48, 'indexPermission')
this.currentAccount = store.get('accountId')
this.getIndexData()
this.getBadge(1, 'isDotEdit')
this.getBadge(2, 'isDotSort')
this.IntervalId = setInterval(() => {
this.getBadge(1, 'isDotEdit')
this.getBadge(2, 'isDotSort')
}, 30000);
},
beforeDestroy(){
clearInterval(this.IntervalId)
},
methods: {
checkPermission (id, key) {
return new Promise((resolve, reject) => {
http.netPost('Account/Account/CheckPermission', {
"id": id,
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
if(res.data.Data == 1){
this[key] = true
}
resolve()
}
})
})
},
confirmPassReview (type) {
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/ViewIndexSort', {
"status": type == 'pass'?1:2, //1通过2拒绝
"id": this.activeIndex.Id,
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
this.pagClick(1)
this.$message({
message: '操作成功',
type: 'success'
})
resolve()
}
})
})
},
getIndexData () {
this.tableLoading = true
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/GetPendingViewIndexSort', {
"Current": (this.pageCurrent - 1) * this.psize,
"Psize": this.psize,
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
this.tableData = res.data.Data.Result
this.pageTotal = 1
}
this.tableLoading = false
})
})
},
pagClick (page) {
this.pageCurrent = page
this.getIndexData()
},
openChangeDetail (data) {
this.showChangeDetail = true
this.activeIndex = data
// this.myTreeData = this.setTreeData(this.indexIntoCategroy(this.activeIndex.SortContent.Object), 'myId', 'parentId')
// this.myTreeData.forEach(item => {
// this.defaultExpandedKeys.push(item.myId)
// })
},
getBadge (type, key) {
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/GetTodoCustomIndexCount', {
"countOption": type,
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
if(res.data.Data > 0){
this[key] = true
}else{
this[key] = false
}
resolve(res)
}
this.loadingDetail = false
})
})
}
}
}
}
\ No newline at end of file
<template>
<div class="editor-inner">
<div class="analyzer-header shadow" style="margin-bottom: 0">
<div class="analyzer-header-title">
<div class="analyzer-header-title-name">指标管理</div>
<div class="analyzer-header-tab" style="flex: auto">
<router-link tag="div" active-class="activeLink" exact to="/">我的指标</router-link>
<router-link tag="div" active-class="activeLink" exact to="/publicIndex">公共指标</router-link>
<el-badge :is-dot="isDotEdit && indexPermission" class="item">
<router-link tag="div" active-class="activeLink" exact to="/indexAudit">指标审核</router-link>
</el-badge>
<el-badge :is-dot="isDotSort && indexPermission" class="item">
<router-link tag="div" active-class="activeLink" exact to="/categoryAudit">公共分类修改审核</router-link>
</el-badge>
<router-link tag="div" style="flex: auto; text-align: right" active-class="activeLink" exact to="/indexRecord">
<span class="el-icon-date"> 指标修改日志</span>
</router-link>
</div>
</div>
</div>
<div class="analyzer-content shadow" style="padding-top: 20px">
<div class="table-box">
<div>
<el-table
size="mini"
v-loading="tableLoading"
:data="tableData"
:header-cell-style="{background:'#f5f7fa',color:'#666'}"
border
>
<el-table-column prop="index" label="序号" width="60" type="index"></el-table-column>
<el-table-column prop="resarcher" label="提交人">
<template slot-scope="scope">
<span v-if="(tableType == 4 || tableType == 8) && scope.row.status.Creator">{{scope.row.status.Creator.NickName}}</span>
<span v-if="tableType == 2">{{scope.row.Creator.NickName}}</span>
</template>
</el-table-column>
<el-table-column prop="LastUpdate" label="提交时间"></el-table-column>
<el-table-column prop="formula" width="120" label="详情">
<template slot-scope="scope">
<el-link size="mini" @click="openChangeDetail(scope.row)">查看详情</el-link>
</template>
</el-table-column>
<el-table-column width="280" label="操作">
<template slot-scope="scope">
<el-link type="success" size="mini" @click="activeIndex = scope.row; confirmPassReview('pass')"
v-show="scope.row.CreatorId !== currentAccount">审核通过</el-link>
<el-popconfirm
confirmButtonText='确认'
@onConfirm="activeIndex = scope.row; confirmPassReview('nopass')"
cancelButtonText='取消'
icon="el-icon-info"
iconColor="red"
title="确认驳回该提交?">
<el-link size="mini" type="danger" v-show="scope.row.CreatorId !== currentAccount" slot="reference">审核驳回</el-link>
</el-popconfirm>
<el-popconfirm
confirmButtonText='确认'
@onConfirm="activeIndex = scope.row; confirmPassReview('nopass')"
cancelButtonText='取消'
icon="el-icon-info"
iconColor="red"
title="确认撤销该提交?">
<el-link size="mini" type="danger" v-show="scope.row.CreatorId == currentAccount" slot="reference">撤销提交</el-link>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<div class="pagination-container">
<el-pagination
layout="prev, pager, next"
:current-page="pageCurrent"
@current-change="pagClick"
:page-size="psize"
:total="pageTotal"
></el-pagination>
</div>
</div>
</div>
</div>
<el-dialog title="修改详情" :visible.sync="showChangeDetail" width="800px">
<div class="change-detail-right">
<div>{{activeIndex.Remark}}</div>
</div>
</el-dialog>
</div>
</template>
\ No newline at end of file
const http = require('../../../lib/axios/axios.js')
const { dialog } = require('electron').remote
const officegen = require('officegen')
const path = require('path');
const fs = require('fs')
const filePath = path.resolve(__dirname, './indexAudit.vue')
let newTemplate = ''
var data = fs.readFileSync(filePath);
var str = data.toString()
var newStr = str.substring(0, str.lastIndexOf('</template>'))
newTemplate = newStr.replace('<template>','')
var keyBord = require('../../lib/keyBord')
var tools = require('../../lib/tools.js')
const condition = require('../../components/condition/index.js')
module.exports = {
indexAudit: {
data: function () {
return {
tableData: [],
tableType: 2,
searchedName: '',
pageTotal: 0,
pageCurrent: 1,
psize: 15,
tableLoading: true,
activeIndex: {},
activeIndexCondition: {},
subActiveIndex: {},
subActiveIndexCondition: {},
showIndexDetail: false,
defaultTypeList: [],
companyNameObj: {},
initIndexObj: {},
keyboardObj: {},
passCategoryVisible: false,
choosedPassCategory: [],
publicCategoryOptions: [],
publicProps: {
value: 'Code',
label: 'Name',
children: 'Children',
checkStrictly: true,
multiple: true
},
passLoading: false,
testRunVisible: false,
rangeCompany: '',
searchCompanyLoading: false,
runningCompanyList: [],
selectedRangeCompany: [],
zjhIndustryData: [],
swIndustryData: [],
marketData:[],
positionData: [],
industryObj: {},
testYear: '',
testQuarter: '',
testMergeType: '合并本期',
activeRangeTab: '3',
showEditIndexDetail: false,
showEditWikiDetail: false,
initIndex: 1,
currentAccount: 0,
sortType: null,
companyStatusData: [],
companyStatusCheck: {
isIndeterminate: false,
checkAll: false,
checkedItems: ['013001'],
options: []
},
hasPermission: false,
isDotEdit: false,
isDotSort: false,
IntervalId: 0,
}
},
components: {condition},
template: newTemplate,
mounted () {
this.currentAccount = store.get('accountId')
this.getDefaultType()
this.getPublicCategory()
tools.getKeyboardObj(keyBord, this.keyboardObj)
tools.getIndexs(this.initIndexObj).then(res => {
this.getIndexData()
})
this.getZjhIndustryCategoryList()
this.getSwIndustryCategoryList()
this.getPositionData()
this.getMarketData()
this.getPublicCategory()
this.getCompanyStatusData()
this.checkPermission(48)
this.getBadge(1, 'isDotEdit')
this.getBadge(2, 'isDotSort')
this.IntervalId = setInterval(() => {
this.getBadge(1, 'isDotEdit')
this.getBadge(2, 'isDotSort')
}, 30000);
},
beforeDestroy(){
clearInterval(this.IntervalId)
},
methods: {
checkPermission (id) {
return new Promise((resolve, reject) => {
http.netPost('Account/Account/CheckPermission', {
"id": id,
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
if(res.data.Data == 1){
this.hasPermission = true
}
resolve()
}
})
})
},
getCompanyStatusData () {
return new Promise((resolve, reject) => {
http.netPost('Data/Query/Query', {
"List": [
"F90063V",
"F90064V"
],
"Where": [],
"WhereOr": [],
"WhereOrArrayAnd": [],
"Sort": [{
"Encode":"F90063V",
"State":1
}],
"GPBField": ["F90063V"],
"Current": 0,
"Psize": 100,
"JoinTableWay": 0
})
.then((res) => {
if (res.data.Status == 1) {
this.companyStatusData = []
res.data.Data.Records.forEach(item => {
if(item["F90063V"]){
this.companyStatusData.push(item)
this.companyStatusCheck.options.push(item["F90063V"])
}
})
}
})
})
},
changeSort (res) {
this.sortType = res.order
},
compare (prop, type) {
return function (obj1, obj2) {
var val1 = parseFloat(obj1[prop])
var val2 = parseFloat(obj2[prop])
if (val1 < val2) {
return type == 'ascending'?-1:1;
} else if (val1 > val2) {
return type == 'ascending'?1:-1;
} else {
return 0;
}
}
},
exportExcel () {
var that = this
var excelName = new Date().getTime()
var xlsx = officegen('xlsx')
var filePath = dialog.showSaveDialog({
defaultPath: excelName + '.xlsx',
title: '保存',
buttonLabel: '保存'
})
xlsx.on('finalize', function(written) {
that.$message({
message: '表格导出成功!',
type: 'success'
})
})
xlsx.on('error', function(err) {
console.log(err)
})
var sheet = xlsx.makeNewSheet()
sheet.name = 'sheet'
sheet.orientation = 'landscape'
sheet.data[0] = []
sheet.data[0][0] = '序号'
sheet.data[0][1] = '证券简称'
sheet.data[0][2] = '证券代码'
sheet.data[0][3] = this.activeIndex.IndexName
var newArr = JSON.parse(JSON.stringify(this.selectedRangeCompany))
if(this.sortType == 'descending'){
newArr.sort(that.compare('result', 'descending'))
}else if(this.sortType == 'ascending'){
newArr.sort(that.compare('result', 'ascending'))
}
newArr.forEach((item, index)=>{
sheet.data[index + 1] = []
sheet.data[index + 1][0] = index+1
sheet.data[index + 1][1] = item['name']
sheet.data[index + 1][2] = item['code']
sheet.data[index + 1][3] = item['result']
})
var out = fs.createWriteStream(filePath)
out.on('error', function(err) {
console.log(err)
})
xlsx.generate(out)
},
testRunIndex () {
//判断条件
var args = []
var ref = this.$refs.conditionChoose
if(!ref.testMergeType || !ref.testYear || !ref.testQuarter || this.selectedRangeCompany.length == 0){
this.$message({
message: '参数不完整或标的为空',
type: 'error'
})
return false
}
this.selectedRangeCompany.forEach(item => {
args.push({
stockCode: item.code,
argType: 1
})
})
args.push({
mergeType: ref.testMergeType,
argType: 2
},{
reportingPeriod: ref.testYear + '-' +ref.testQuarter,
argType: 4
})
this.searchCompanyLoading = true
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/TestRunPublicCustomIndex', {
args: args,
"id": this.activeIndex.Id,
"runVersion": 1
})
.then((res) => {
if (res.data.Status == 1) {
this.selectedRangeCompany.forEach(item => {
if(res.data.Data[item.code] !== "NaN"){
item.result = res.data.Data[item.code]
}else{
item.result = '分母为0'
}
})
resolve()
}
this.searchCompanyLoading = false
})
})
},
addRangeCompany(item) {
var code = item.split(',')[1]
var obj = {
name: item.split(',')[0],
code: code,
}
// this.selectedRangeCompany.push([])
this.addAndRemoveCompany([obj])
this.rangeCompany = ''
},
//对数据进行去重
addAndRemoveCompany (arr) {
var oldCompany = {}
this.selectedRangeCompany.forEach(item => {
oldCompany[item.code] = item.name
})
arr.forEach(item => {
if(!oldCompany[item.code]){
this.selectedRangeCompany.push({
code: item.code,
name: item.name,
result: null
})
}
})
},
searchRunningCompany(value) {
this.searchCompanyLoading = true
var checkeds = this.companyStatusCheck.checkedItems
var Where = []
if(checkeds.length > 0){
Where.push({
"Encode": "F90063V",
"State": checkeds.length == 1?1:8,
"Value": checkeds.length == 1?checkeds[0]:checkeds
})
}
return new Promise((resolve, reject) => {
http.netPost('Data/Query/Query', {
"List": ["F90004V", 'F90001V', 'F90002V'],
"WhereOr": [
{
"Encode": "F90004V",
"State": 2,
"Value": value,
},
{
"Encode": "F90001V",
"State": 2,
"Value": value,
},
{
"Encode": "F90002V",
"State": 2,
"Value": value,
},
],
"Where": Where,
"Current": 0,
"Psize": 20
})
.then((res) => {
if (res.data.Status == 1) {
this.runningCompanyList = res.data.Data.Records
}
this.searchCompanyLoading = false
})
})
},
selectedExcel(e) {
var file = e.target.files[0]
var type = file.name.split('.')
if (type[type.length - 1] !== 'xlsx' && type[type.length - 1] !== 'xls') {
this.$message({
message: '所选文件格式不正确!',
type: 'error'
})
e.target.value = ''
return false;
} else {
const reader = new FileReader();
reader.readAsBinaryString(file);
reader.onload = (e) => {
const data = e.target.result;
const zzexcel = window.XLS.read(data, {
type: 'binary'
})
const result = [];
for (let i = 0; i < zzexcel.SheetNames.length; i++) {
const newData = window.XLS.utils.sheet_to_json(zzexcel.Sheets[zzexcel.SheetNames[i]]);
result.push(...newData)
}
var arr = []
result.forEach(item => {
var obj = {
name: item.name,
code: item.code.split('.')[0]
// label: item.name,
// type: 5,
// from: '批量添加'
}
arr.push(obj)
})
this.addAndRemoveCompany(arr)
}
this.$message({
message: '导入成功!',
type: 'success'
})
e.target.value = ''
}
},
handleCheckAllChange(val, obj) {
obj.checkedItems = val ? obj.options : []
obj.isIndeterminate = false
},
handleCheckedResults(value, obj) {
let checkedCount = value.length
obj.checkAll = checkedCount === obj.options.length
obj.isIndeterminate = checkedCount > 0 && checkedCount < obj.options.length
},
getZjhIndustryCategoryList() {
return new Promise((resolve, reject) => {
http.netPost('Data/Query/Query', {
"List": [
"F90013V",
"F90012V",
"F90014V",
"F90015V"
],
"Where": [],
"GPBField": ["F90015V"],
"Current": 0,
"Psize": 10000
})
.then((res) => {
if (res.data.Status == 1) {
this.handleZjhData(res.data.Data.Records)
}
})
})
},
getMarketData() {
http.netPost('Data/Query/Query', {
"List": [
"F90005V",
"F90006V"
],
"Where": [],
"WhereOr": [],
"GPBField": [
"F90005V"
],
"Current": 0,
"Psize": 999
}).then((res) => {
this.marketData = res.data.Data.Records
this.marketData.forEach(item => {
item.label = item.F90006V,
item.searchCode = 'F90006V'
})
})
},
getPositionData() {
return new Promise((resolve, reject) => {
http.netPost('Data/Query/Query', {
"List": [
"F90010V",
"F90011V"
],
"Where": [],
"WhereOr": [],
"GPBField": [
"F90010V",
"F90011V"
],
"Current": 0,
"Psize": 999
}).then((res) => {
if (res.data.Status == 1) {
var parentObj = {}
var newArray = res.data.Data.Records
newArray.forEach(item => {
if (!parentObj[item.F90010V]) {
parentObj[item.F90010V] = {
id: item.F90010V,
label: item.F90010V,
code: 'F90010V',
children: [],
searchCode: 'F90010V',
}
parentObj[item.F90010V].children.push({
id: item.F90011V,
label: item.F90011V,
code: 'F90011V',
searchCode: 'F90011V'
})
} else {
parentObj[item.F90010V].children.push({
id: item.F90011V,
label: item.F90011V,
code: 'F90011V',
searchCode: 'F90011V'
})
}
})
this.positionData = []
for (var key in parentObj) {
if (key !== 'null') {
this.positionData.push(parentObj[key])
}
}
}
})
})
},
handleSwData(data) {
var parentObj = {}
var parentArray = []
var childObj = {}
var childArray = []
data.map((item) => {
if (!parentObj[item.F90016V]) {
parentObj[item.F90016V] = item
parentArray.push({
label: item.F90017V,
id: item.F90016V,
code: 'F90017V',
from: '申万' + '-' + item.F90017V,
searchCode: 'F90017V'
})
this.industryObj[item.F90016V] = '申万' + '-' + item.F90017V
}
if (!childObj[item.F90018V]) {
childObj[item.F90018V] = item
childArray.push({
label: item.F90019V,
id: item.F90018V,
parentId: item.F90016V,
code: 'F90019V',
from: '申万' + '-' + item.F90017V + '-' + item.F90019V,
searchCode: 'F90019V'
})
this.industryObj[item.F90018V] = '申万' + '-' + item.F90017V + '-' + item.F90019V
}
})
childArray.map((chid) => {
chid.children = []
data.map((item) => {
if (chid.id == item.F90018V) {
chid.children.push({
label: item.F90021V,
id: item.F90020V,
code: 'F90021V',
from: chid.from + '-' + item.F90021V,
searchCode: 'F90021V'
})
this.industryObj[item.F90020V] = chid.from + '-' + item.F90021V
}
})
})
parentArray.map((sub) => {
sub.children = []
childArray.map((item) => {
if (sub.id == item.parentId) {
sub.children.push(item)
}
})
})
this.swIndustryData = [
{
label: '申万行业',
id: 0,
code: '0',
from: '',
searchCode: '0',
children: parentArray
}
]
},
//处理证监会行业数据
handleZjhData(data) {
var newObj = {}
var newArray = []
data.map((item) => {
if (!newObj[item.F90014V]) {
newObj[item.F90014V] = item
newArray.push({
label: item.F90012V,
id: item.F90014V,
code: 'F90014V',
from: '证监会' + '-' + item.F90012V,
labelCode: 'F90012V',
searchCode: 'F90012V'
})
this.industryObj[item.F90014V] = '证监会' + '-' + item.F90012V
}
})
newArray.map((chid) => {
chid.children = []
data.map((item, index) => {
if (chid.id == item.F90014V) {
chid.children.push({
label: item.F90013V,
id: item.F90015V,
code: 'F90015V',
labelCode: 'F90013V',
from: chid.from + '-' + item.F90013V,
searchCode: 'F90013V'
})
this.industryObj[item.F90015V] = chid.from + '-' + item.F90013V
}
})
})
this.zjhIndustryData = [
{
label: '证监会行业',
id: 0,
code: '0',
labelCode: '0',
from: '',
searchCode: '0',
children: newArray
}
]
},
getSwIndustryCategoryList() {
return new Promise((resolve, reject) => {
http.netPost('Data/Query/Query', {
"List": [
"F90016V",
"F90017V",
"F90018V",
"F90019V",
"F90020V",
"F90021V"
],
"Where": [],
"GPBField": ["F90020V"],
"Current": 0,
"Psize": 10000
})
.then((res) => {
if (res.data.Status == 1) {
this.handleSwData(res.data.Data.Records)
}
})
})
},
searchCompanyByIndustry(item, type) {
this.searchCompanyLoading = true
var Where = []
var checkeds = this.companyStatusCheck.checkedItems
if(type == 1 || type == 2 || type == 4 || type == 3){
Where.push({
"Encode": item.searchCode,
"State": 1,
"Value": item.label,
})
if(checkeds.length > 0){
Where.push({
"Encode": "F90063V",
"State": checkeds.length == 1?1:8,
"Value": checkeds.length == 1?checkeds[0]:checkeds
})
}
}
this.initIndex++
var params = {
content: {
"List": ['F90001V', 'F90002V'],
"Where": Where,
"Current": 0,
"Psize": 10000
}
}
return new Promise((resolve, reject) => {
var companyObj = {}
this.selectedRangeCompany.forEach(item => {
if(!companyObj[item.F90001V]){
companyObj[item.F90001V] = item.F90001V
}
})
http.netPost('Data/Query/Query', params.content)
.then((res) => {
if (res.data.Status == 1) {
var arr = []
res.data.Data.Records.map((child) => {
if(!companyObj[child.F90001V]){
arr.push({
name: child.F90002V,
code: child.F90001V
})
}
})
this.addAndRemoveCompany(arr)
}
this.searchCompanyLoading = false
})
})
},
openTestRunDialog (row) {
this.activeIndex = row
this.testRunVisible = true
},
confirmPassReview (type) {
this.passLoading = true
var arr = []
if(this.tableType == 2){
this.choosedPassCategory.forEach(item => {
arr.push(item[item.length - 1])
})
}else{
arr = this.choosedPassCategory
}
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/ViewIndex', {
"status": type == 'pass'?16:32,
"id": this.activeIndex.Id,
"codes": arr,
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
this.pagClick(1)
this.getBadge(1, 'isDotEdit')
this.getBadge(2, 'isDotSort')
this.passCategoryVisible = false
this.$message({
message: '操作成功',
type: 'success'
})
resolve()
}
this.passLoading = false
})
})
},
getIndexCategory (code, options) {
var textArr = []
var arr = this.findPathByLeafId(code, options)
if(!arr){
arr = []
}
arr.forEach(item => {
textArr.push(item.name)
})
return textArr.join(' / ')
},
getIndexCategorys (codes, options) {
var arr = []
if(codes){
codes.forEach(item => {
arr.push(this.getIndexCategory(item, options))
})
}
return arr
},
getIsSameCategory (activeIndex, subActiveIndex) {
var activeText = '', subText = ''
if(activeIndex.ArchiveCodes.length == 0){
activeText = '0'
}else{
activeText = JSON.stringify(activeIndex.ArchiveCodes)
}
if(subActiveIndex.ArchiveCodes.length == 0){
subText = ''
}else{
subText = JSON.stringify(subActiveIndex.ArchiveCodes)
}
return subText == activeText
},
findPathByLeafId(leafId, nodes, path) {
if (path === undefined) {
path = []
}
for (var i = 0; i < nodes.length; i++) {
var tmpPath = path.concat()
tmpPath.push({
code: nodes[i].Code,
name: nodes[i].Name
})
if (leafId == nodes[i].Code) {
return tmpPath;
}
if (nodes[i].Children) {
var findResult = this.findPathByLeafId(leafId, nodes[i].Children, tmpPath);
if (findResult) {
return findResult
}
}
}
},
getPublicCategory () {
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/GetPublicArchive', {})
.then((res) => {
if (res.data.Status == 1) {
this.publicCategoryOptions = res.data.Data
resolve()
}
})
})
},
confirmPass (row, type) {
this.activeIndex = row
console.log(row)
if(type == 'add'){
this.choosedPassCategory = this.getEditIndexCategory(row)
this.passCategoryVisible = true
}else if(type == 'edit'){
if(this.tableType == 8){
this.choosedPassCategory = row.ArchiveCodes
}else{
this.choosedPassCategory = row.PendingData.Object.ArchiveCodes
}
this.passCategoryVisible = false
this.confirmPassReview('pass')
}
},
getEditIndexCategory(row) {
var result = []
if(row.PendingData.Object.ArchiveCodes){
row.PendingData.Object.ArchiveCodes.forEach(item => {
var categoryArr = []
var arr = this.findPathByLeafId(item, this.publicCategoryOptions)
if(!arr){
return []
}
arr.forEach((item, index) => {
categoryArr.push(item.code)
})
result.push(categoryArr)
})
}
return result
},
getDefaultType () {
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/GetAllIndexArgs', {
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
this.defaultTypeList = res.data.Data
resolve()
}
})
})
},
getDataType(activeIndex) {
var obj = {
0: '字符',
1: '日期',
2: '数字'
}
return obj[activeIndex.ReturnType]
},
getIndexArgsType (args) {
var arr = []
this.defaultTypeList.forEach(item => {
if(args&item.Id){
arr.push(item.Name)
}
})
return arr.join('')
},
getIndexData () {
this.tableLoading = true
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/GetPendingViewIndex', {
"status": this.tableType,
"Current": (this.pageCurrent - 1) * this.psize,
"Psize": this.psize,
"name": this.searchedName,
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
res.data.Data.Result.forEach(item => {
item.status = this.getCurrentStatus(item.WdCustomIndexWorkflow)
})
this.tableData = res.data.Data.Result
this.pageTotal = res.data.Data.Total
}
this.tableLoading = false
})
})
},
getCurrentStatus (arr) {
var status = {}
arr.forEach(item => {
if(item.IsCurrent == 1){
status = item
}
})
return status
},
pagClick (page) {
this.pageCurrent = page
this.getIndexData()
},
openDetailDialog (data) {
if(this.tableType == 2){ //审核升级
this.openDetail(data)
}else if(this.tableType == 4){ //审核修改
this.openChangeDetail(data)
}else if(this.tableType == 8){ //审核百科
this.openWikiDetail(data)
}
},
openWikiDetail (data) {
this.showEditWikiDetail = true
this.activeIndex = data
},
openChangeDetail (data) {
this.activeIndex = data
this.subActiveIndex = data.PendingData.Object
this.showEditIndexDetail = true
this.setDetailCondition(data, 'conditionBox', 'activeIndexCondition')
this.setDetailCondition(this.subActiveIndex, 'subConditionBox', 'subActiveIndexCondition')
},
setDetailCondition (data, id, key) {
tools.getUsedCompany(data.Algorithm.Object || data.Algorithm, this.companyNameObj).then(res => {
this[key] = {
indexParams: {},
dateParams: {},
numParams: {},
symbolParams: {},
functionParams: {},
dom: '',
showDom: ''
}
tools.getSaveCondition(this[key], data.Algorithm.Object || data.Algorithm, this.initIndex, this.initIndexObj, this.companyNameObj, this.keyboardObj)
this.$nextTick(()=>{
var spans = document.getElementById(id).getElementsByTagName('span')
var html = ''
Array.from(spans).forEach(span => {
html+=span.outerHTML
})
document.getElementById(id).innerHTML = html
var spans = document.getElementById(id).getElementsByTagName('span')
tools.formatShowDom(spans)
})
})
},
openDetail (data) {
this.activeIndex = data
this.showIndexDetail = true
tools.getUsedCompany(data.Algorithm.Object, this.companyNameObj).then(res => {
this.activeIndexCondition = {
indexParams: {},
dateParams: {},
numParams: {},
symbolParams: {},
functionParams: {},
dom: '',
showDom: ''
}
tools.getSaveCondition(this.activeIndexCondition, data.Algorithm.Object, this.initIndex, this.initIndexObj, this.companyNameObj, this.keyboardObj)
this.$nextTick(()=>{
var spans = document.getElementById('conditionBox').getElementsByTagName('span')
var html = ''
Array.from(spans).forEach(span => {
html+=span.outerHTML
})
document.getElementById('conditionBox').innerHTML = html
var spans = document.getElementById('conditionBox').getElementsByTagName('span')
tools.formatShowDom(spans)
})
})
},
getBadge (type, key) {
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/GetTodoCustomIndexCount', {
"countOption": type,
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
if(res.data.Data > 0){
this[key] = true
}else{
this[key] = false
}
resolve(res)
}
this.loadingDetail = false
})
})
},
downloadExample () {
var that = this
var excelName = '示例表格'
var xlsx = officegen('xlsx')
var filePath = dialog.showSaveDialog({
defaultPath: excelName + '.xlsx',
title: '保存',
buttonLabel: '保存'
})
xlsx.on('finalize', function(written) {
that.$message({
message: '下载完成',
type: 'success'
})
})
xlsx.on('error', function(err) {
console.log(err)
})
var sheet = xlsx.makeNewSheet()
sheet.name = 'sheet1'
sheet.orientation = 'landscape'
sheet.data[0] = []
sheet.data[0][0] = 'name'
sheet.data[0][1] = 'code'
sheet.data[1] = []
sheet.data[1][0] = '华夏银行'
sheet.data[1][1] = '600015.sh'
sheet.data[2] = []
sheet.data[2][0] = '贵州茅台'
sheet.data[2][1] = '600519'
sheet.data[3] = []
sheet.data[3][0] = '工商银行'
sheet.data[3][1] = '601398'
var out = fs.createWriteStream(filePath)
out.on('error', function(err) {
console.log(err)
})
xlsx.generate(out)
}
}
}
}
\ No newline at end of file
<template>
<div class="editor-inner">
<div class="analyzer-header shadow">
<div class="analyzer-header-title">
<div class="analyzer-header-title-name">指标管理</div>
<div class="analyzer-header-tab" style="flex: auto">
<router-link tag="div" active-class="activeLink" exact to="/">我的指标</router-link>
<router-link tag="div" active-class="activeLink" exact to="/publicIndex">公共指标</router-link>
<el-badge :is-dot="isDotEdit && hasPermission" class="item">
<router-link tag="div" active-class="activeLink" exact to="/indexAudit">指标审核</router-link>
</el-badge>
<el-badge :is-dot="isDotSort && hasPermission" class="item">
<router-link tag="div" active-class="activeLink" exact to="/categoryAudit">公共分类修改审核</router-link>
</el-badge>
<router-link tag="div" style="flex: auto; text-align: right" active-class="activeLink" exact to="/indexRecord">
<span class="el-icon-date"> 指标修改日志</span>
</router-link>
</div>
</div>
<div class="analyzer-header-condition" style="align-items: center; padding: 14px 20px">
<div>
<el-radio-group v-model="tableType" @change="pagClick(1)" size="small">
<el-radio-button :label="2">审核升级</el-radio-button>
<el-radio-button :label="4">审核修改</el-radio-button>
<el-radio-button :label="8">审核百科</el-radio-button>
</el-radio-group>
</div>
</div>
</div>
<div class="analyzer-content shadow" style="padding-top: 20px">
<div class="table-condition">
<span class="gray">指标搜索:</span>
<el-input clearable style="width: 200px" v-model="searchedName" size="mini" placeholder="请输入指标名称"></el-input>
<el-button type="primary" size="mini" style="margin-left:12px" @click="pagClick(1)">搜索</el-button>
</div>
<div class="table-box">
<div class="table-wrap">
<el-table
size="mini"
v-loading="tableLoading"
:data="tableData"
:header-cell-style="{background:'#f5f7fa',color:'#666'}"
border
>
<el-table-column prop="index" label="序号" width="60" type="index"></el-table-column>
<el-table-column prop="IndexName" width="400" label="指标名称">
<template slot-scope="scope">
<span v-if="(tableType == 4 || tableType == 8) && scope.row.status.Creator">{{scope.row.IndexName}}</span>
<span v-if="tableType == 2">{{scope.row.PendingData.Object.IndexName}}</span>
</template>
</el-table-column>
<el-table-column prop="resarcher" label="提交人">
<template slot-scope="scope">
<span v-if="(tableType == 4 || tableType == 8) && scope.row.status.Creator">{{scope.row.status.Creator.NickName}}</span>
<span v-if="tableType == 2">{{scope.row.status.Creator.NickName}}</span>
</template>
</el-table-column>
<el-table-column prop="LastUpdate" label="提交时间">
<template slot-scope="scope">
<span>{{scope.row.status.CreateDate}}</span>
</template>
</el-table-column>
<el-table-column prop="formula" width="120" label="详情">
<template slot-scope="scope">
<el-link size="mini" type="success" @click="openDetailDialog(scope.row)">查看详情</el-link>
</template>
</el-table-column>
<el-table-column width="280" label="操作">
<template slot-scope="scope">
<!-- <el-link size="mini">查看日志</el-link> -->
<el-link size="mini" type="success" @click="openTestRunDialog(scope.row)">测试运行</el-link>
<el-link size="mini" type="success" @click="confirmPass(scope.row, 'add')" v-show="tableType == 2 && scope.row.PendingData.Object.CreatorId !== currentAccount && hasPermission">审核通过</el-link>
<el-link size="mini" type="success" @click="confirmPass(scope.row, 'edit')" v-show="tableType == 4 && scope.row.PendingData.Object.CreatorId !== currentAccount && hasPermission">审核通过</el-link>
<el-link size="mini" type="success" @click="confirmPass(scope.row, 'edit')" v-show="tableType == 8 && scope.row.PendingData.Object.CreatorId !== currentAccount && hasPermission">审核通过</el-link>
<el-popconfirm
confirmButtonText='确认'
@onConfirm="activeIndex = scope.row; choosedPassCategory = getEditIndexCategory(scope.row); confirmPassReview('delete')"
cancelButtonText='取消'
icon="el-icon-info"
iconColor="red"
title="确认驳回该指标?">
<el-link size="mini" type="danger" v-show="(scope.row.PendingData.Object.CreatorId !== currentAccount && tableType == 2 && hasPermission) || (scope.row.PendingData.Object.CreatorId !== currentAccount && tableType == 4 && hasPermission) || (scope.row.PendingData.Object.CreatorId !== currentAccount && tableType == 8 && hasPermission)" slot="reference">审核驳回</el-link>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<div class="pagination-container">
<el-pagination
layout="prev, pager, next"
:current-page="pageCurrent"
@current-change="pagClick"
:page-size="psize"
:total="pageTotal"
></el-pagination>
</div>
</div>
</div>
</div>
<el-dialog title="指标文件夹选择" :visible.sync="passCategoryVisible" width="600px">
<div class="detail-container" style="padding-top:0; font-size: 13px">
<div class="detail-index">
<div class="title" style="color: #999">所属文件夹:</div>
<div class="detail">
<el-cascader
size="mini"
style="width: 300px"
:props="publicProps"
v-model="choosedPassCategory"
:options="publicCategoryOptions">
</el-cascader>
</div>
</div>
</div>
<div slot="footer">
<el-button size="mini" @click="passCategoryVisible = false">取消</el-button>
<el-button size="mini" type="primary" :loading="passLoading" @click="confirmPassReview('pass')">确认</el-button>
</div>
</el-dialog>
<el-dialog title="指标详情" :visible.sync="showIndexDetail" width="800px">
<div class="detail-container" style="padding-top:0; font-size: 13px">
<div class="detail-index">
<div class="title" style="color: #999">指标名称:</div>
<div class="detail" v-if="activeIndex.PendingData">{{activeIndex.PendingData.Object.IndexName}}</div>
</div>
<div class="detail-index">
<div class="title" style="color: #999">指标创建人:</div>
<div class="detail" v-if="activeIndex.status">{{activeIndex.status.Creator.NickName}}</div>
</div>
<div class="detail-index">
<div class="title" style="color: #999">指标类型:</div>
<div class="detail">{{getDataType(activeIndex)}}</div>
</div>
<div class="detail-index">
<div class="title" style="color: #999">指标参数:</div>
<div class="detail" v-if="activeIndex.Args">{{getIndexArgsType(activeIndex.Args)}}</div>
</div>
<div class="detail-index">
<div class="title" style="color: #999">指标单位:</div>
<div class="detail">{{activeIndex.IndexUnit}}</div>
</div>
<div class="detail-index">
<div class="title" style="color: #999">建议分类:</div>
<div class="detail" v-if="activeIndex.PendingData">
<div v-for="item in getIndexCategorys(activeIndex.PendingData.Object.ArchiveCodes, publicCategoryOptions)">
{{item}}
</div>
</div>
</div>
<div class="detail-index">
<div class="title" style="color: #999">指标百科:</div>
<div class="detail">
<div class="sub-detail">
<span>{{activeIndex.Wiki}}</span>
</div>
</div>
</div>
<div class="detail-index">
<div class="title" style="color: #999">指标算法:</div>
<div class="detail">
<div class="calculater-box" id="conditionBox" v-html="activeIndexCondition.showDom"></div>
</div>
</div>
<div class="detail-index" v-if="activeIndex.WdCustomIndexWorkflow">
<div class="title" style="color: #999">备注:</div>
<div class="detail">
<span>{{activeIndex.WdCustomIndexWorkflow[activeIndex.WdCustomIndexWorkflow.length - 1].Remark}}</span>
</div>
</div>
</div>
</el-dialog>
<el-dialog title="指标详情" :visible.sync="showEditIndexDetail" width="1100px">
<div class="double-detail-box">
<div class="detail-container" style="padding-top:0; font-size: 13px">
<div class="detail-index">
<h3>原数据</h3>
</div>
<div class="detail-index">
<div class="title" style="color: #999">指标名称:</div>
<div class="detail"
:class="{active: activeIndex.IndexName !== subActiveIndex.IndexName}">
{{activeIndex.IndexName}}
</div>
</div>
<div class="detail-index">
<div class="title" style="color: #999">指标创建人:</div>
<div class="detail"
v-if="activeIndex.status">
{{activeIndex.status.Creator.NickName}}
</div>
</div>
<div class="detail-index">
<div class="title" style="color: #999">指标类型:</div>
<div class="detail"
:class="{active: getDataType(activeIndex) !== getDataType(subActiveIndex)}">
{{getDataType(activeIndex)}}
</div>
</div>
<div class="detail-index">
<div class="title" style="color: #999">指标参数:</div>
<div class="detail"
v-if="activeIndex.Args"
:class="{active: getIndexArgsType(activeIndex.Args) !== getIndexArgsType(subActiveIndex.Args)}">
{{getIndexArgsType(activeIndex.Args)}}
</div>
</div>
<div class="detail-index">
<div class="title" style="color: #999">指标单位:</div>
<div class="detail"
:class="{active: activeIndex.IndexUnit !== subActiveIndex.IndexUnit}">
{{activeIndex.IndexUnit}}
</div>
</div>
<div class="detail-index">
<div class="title" style="color: #999">分类:</div>
<div class="detail"
v-if="activeIndex.ArchiveCodes && subActiveIndex.ArchiveCodes"
:class="{active: !getIsSameCategory(activeIndex, subActiveIndex)}">
<div v-for="item in getIndexCategorys(activeIndex.ArchiveCodes, publicCategoryOptions)">{{item}}</div>
</div>
</div>
<div class="detail-index">
<div class="title" style="color: #999">指标百科:</div>
<div class="detail">
<div class="sub-detail"
:class="{active: activeIndex.Wiki !== subActiveIndex.Wiki}">
<span>{{activeIndex.Wiki?activeIndex.Wiki:'-'}}</span>
</div>
</div>
</div>
<div class="detail-index">
<div class="title" style="color: #999">指标算法:</div>
<div class="detail"
:class="{active: activeIndexCondition.showDom !== subActiveIndexCondition.showDom}">
<div style="width: 400px" class="calculater-box" id="conditionBox" v-html="activeIndexCondition.showDom"></div>
</div>
</div>
<!-- <div class="detail-index" v-if="activeIndex.WdCustomIndexWorkflow">
<div class="title" style="color: #999">备注:</div>
<div class="detail">
<span>{{activeIndex.WdCustomIndexWorkflow[activeIndex.WdCustomIndexWorkflow.length - 1].Remark}}</span>
</div>
</div> -->
</div>
<div class="detail-container" style="padding-top:0; font-size: 13px;">
<div class="detail-index">
<h3>修改数据</h3>
</div>
<div class="detail-index">
<div class="title" style="color: #999">指标名称:</div>
<div class="detail">{{subActiveIndex.IndexName}}</div>
</div>
<div class="detail-index">
<div class="title" style="color: #999">指标创建人:</div>
<div class="detail" v-if="activeIndex.status">
{{activeIndex.status.Creator.NickName}}</div>
</div>
<div class="detail-index">
<div class="title" style="color: #999">指标类型:</div>
<div class="detail">{{getDataType(subActiveIndex)}}</div>
</div>
<div class="detail-index">
<div class="title" style="color: #999">指标参数:</div>
<div class="detail" v-if="subActiveIndex.Args">{{getIndexArgsType(subActiveIndex.Args)}}</div>
</div>
<div class="detail-index">
<div class="title" style="color: #999">指标单位:</div>
<div class="detail">{{subActiveIndex.IndexUnit}}</div>
</div>
<div class="detail-index">
<div class="title" style="color: #999">分类:</div>
<div class="detail" v-if="subActiveIndex.ArchiveCodes">
<div v-for="item in getIndexCategorys(activeIndex.ArchiveCodes, publicCategoryOptions)">{{item}}</div>
</div>
</div>
<div class="detail-index">
<div class="title" style="color: #999">指标百科:</div>
<div class="detail">
<div class="sub-detail">
<span>{{subActiveIndex.Wiki}}</span>
</div>
</div>
</div>
<div class="detail-index">
<div class="title" style="color: #999">指标算法:</div>
<div class="detail">
<div style="width: 400px" class="calculater-box" id="subConditionBox" v-html="subActiveIndexCondition.showDom"></div>
</div>
</div>
<div class="detail-index" v-if="activeIndex.WdCustomIndexWorkflow">
<div class="title" style="color: #999">备注:</div>
<div class="detail">
<span>{{activeIndex.WdCustomIndexWorkflow[activeIndex.WdCustomIndexWorkflow.length - 1].Remark}}</span>
</div>
</div>
</div>
</div>
</el-dialog>
<el-dialog title="指标详情" :visible.sync="showEditWikiDetail" width="800px">
<div class="detail-container" style="padding-top:0; font-size: 13px">
<div class="detail-index" v-if="activeIndex.status && activeIndex.status.PreData">
<div class="title" style="color: #999">原百科:</div>
<div class="detail">{{activeIndex.status.PreData.Object.Wiki}}</div>
</div>
<div class="detail-index">
<div class="title" style="color: #999">修改百科:</div>
<div class="detail">{{activeIndex.Wiki}}</div>
</div>
</div>
</el-dialog>
<el-dialog title="测试运行指标"
:close-on-press-escape="false"
:close-on-click-modal="false"
:visible.sync="testRunVisible"
width="800px">
<div class="test-run-box">
<div class="detail-index">
<div class="title">当前指标:</div>
<div class="detail">
<span>{{activeIndex.IndexName}}</span>
</div>
</div>
<condition style="padding: 20px 0" ref="conditionChoose" :params="activeIndex.Args" :allParams="defaultTypeList" />
<div class="detail-index" style="align-items: flex-start">
<div class="title">标的选择:</div>
<div class="detail" style="color: #333">
<div class="flex-form-cintent">
<div style="margin-bottom: 20px">
<el-checkbox
:indeterminate="companyStatusCheck.isIndeterminate"
v-model="companyStatusCheck.checkAll"
@change="handleCheckAllChange($event, companyStatusCheck)"
>全选</el-checkbox>
<el-checkbox-group
v-model="companyStatusCheck.checkedItems"
@change="handleCheckedResults($event, companyStatusCheck)"
>
<el-checkbox
v-for="item in companyStatusData"
:value="item['F90063V']"
:label="item['F90063V']"
:key="item['F90063V']"
>{{item['F90064V']}}</el-checkbox>
</el-checkbox-group>
</div>
<div class="flex-form-detail no-bg">
<el-tabs
v-model="activeRangeTab"
class="mini-size"
style="margin-bottom: 12px"
type="card"
>
<el-tab-pane label="单个添加" :name="'3'">
<div>
<el-select
v-model="rangeCompany"
filterable
remote
@change="addRangeCompany"
placeholder="请输入名称或代码"
:remote-method="searchRunningCompany"
:loading="searchCompanyLoading"
size="mini"
>
<el-option
v-for="item in runningCompanyList"
:key="item.F90001V"
:label="item.F90002V + ' ' + item.F90001V"
:value="item.F90002V + ',' + item.F90001V"
></el-option>
</el-select>
</div>
</el-tab-pane>
<el-tab-pane label="excel导入" :name="'6'">
<div
style="padding-bottom: 8px; color: #999; font-size: 12px"
>excel格式:表为两列, 表头必须为字符"name"、"code", 表身对应为证券简称、证券代码</div>
<div>
<input type="file" @change="selectedExcel" />
</div>
<div style="padding-top: 12px">
<span style="color: #d0021b; font-size: 12px; cursor: pointer" @click="downloadExample">下载示例表格</span>
</div>
</el-tab-pane>
<!-- <el-tab-pane label="证监会行业" :name="'1'">
<div class="mini-size industry-tree-box">
<el-tree
:indent="8"
accordion
:expand-on-click-node="false"
@node-click="searchCompanyByIndustry($event, 1)"
:data="zjhIndustryData"
node-key="id"
ref="zjhCategory"
highlight-current
></el-tree>
</div>
</el-tab-pane> -->
<el-tab-pane label="行业分类" :name="'2'">
<div class="mini-size industry-tree-box">
<el-tree
:indent="8"
accordion
:expand-on-click-node="false"
@node-click="searchCompanyByIndustry($event, 1)"
:data="zjhIndustryData"
node-key="id"
ref="zjhCategory"
></el-tree>
<el-tree
:indent="8"
accordion
:expand-on-click-node="false"
@node-click="searchCompanyByIndustry($event, 2)"
:data="swIndustryData"
node-key="id"
ref="swCategory"
></el-tree>
</div>
</el-tab-pane>
<el-tab-pane label="市场分类" :name="'5'">
<div class="mini-size industry-tree-box">
<el-tree
:indent="8"
accordion
:data="marketData"
highlight-current
ref="marketCategory"
:expand-on-click-node="false"
@node-click="searchCompanyByIndustry($event, 3)"
></el-tree>
</div>
</el-tab-pane>
<el-tab-pane label="地域分类" :name="'4'">
<div class="mini-size industry-tree-box">
<el-tree
:indent="8"
accordion
:data="positionData"
highlight-current
ref="posCategory"
:expand-on-click-node="false"
@node-click="searchCompanyByIndustry($event, 4)"
></el-tree>
</div>
</el-tab-pane>
</el-tabs>
<el-table
@sort-change="changeSort"
size="mini"
max-height="300"
v-loading="searchCompanyLoading"
:data="selectedRangeCompany"
:header-cell-style="{background:'#f5f7fa',color:'#666'}"
border
>
<el-table-column width="50" type="index" label="序号"></el-table-column>
<el-table-column width="80" label="证券名称">
<template slot-scope="scope">{{scope.row.name}}</template>
</el-table-column>
<el-table-column width="80" label="证券代码">
<template slot-scope="scope">{{scope.row.code}}</template>
</el-table-column>
<el-table-column prop="result" sortable label="运行结果">
<template slot-scope="scope">{{scope.row.result}}</template>
</el-table-column>
<el-table-column width="80" label="操作">
<template slot-scope="scope">
<span
class="hover-icon el-icon-delete"
@click="selectedRangeCompany.splice(scope.$index, 1)"
>
删除
</span>
</template>
</el-table-column>
</el-table>
<div style="font-size: 12px; margin-top: 8px; color: #d0021b">
<span
class="el-icon-refresh-right"
style="cursor: pointer"
@click="selectedRangeCompany = []"
>清空表格</span>
<span
class="el-icon-upload2"
style="cursor: pointer; margin-left: 12px"
@click="exportExcel"
>导出excel</span>
</div>
</div>
</div>
</div>
</div>
<div class="detail-index">
<div class="title">操作:</div>
<div class="detail">
<el-button type="primary" size="mini" @click="testRunIndex">点击运行</el-button>
</div>
</div>
</div>
</el-dialog>
</div>
</template>
\ No newline at end of file
const http = require('../../../lib/axios/axios.js')
const { dialog } = require('electron').remote
const officegen = require('officegen')
const path = require('path');
const fs = require('fs')
const filePath = path.resolve(__dirname, './indexRecord.vue')
let newTemplate = ''
var data = fs.readFileSync(filePath);
var str = data.toString()
var newStr = str.substring(0, str.lastIndexOf('</template>'))
newTemplate = newStr.replace('<template>','')
const condition = require('../../components/condition/index.js')
module.exports = {
indexRecord: {
data: function () {
return {
tableData: [],
tableType: 2,
searchedName: '',
pageTotal: 0,
pageCurrent: 1,
psize: 15,
tableLoading: true,
activeIndex: {},
activeIndexCondition: {},
subActiveIndex: {},
subActiveIndexCondition: {},
showIndexDetail: false,
defaultTypeList: [],
companyNameObj: {},
initIndexObj: {},
keyboardObj: {},
passCategoryVisible: false,
choosedPassCategory: [],
publicCategoryOptions: [],
publicProps: {
value: 'Code',
label: 'Name',
children: 'Children',
checkStrictly: true
},
passLoading: false,
testRunVisible: false,
rangeCompany: '',
searchCompanyLoading: false,
runningCompanyList: [],
selectedRangeCompany: [],
zjhIndustryData: [],
swIndustryData: [],
marketData:[],
positionData: [],
industryObj: {},
testYear: '',
testQuarter: '',
testMergeType: '合并本期',
activeRangeTab: '3',
showEditIndexDetail: false,
showChangeDetail: false,
initIndex: 1,
currentAccount: 0,
sortType: null,
treeProps: {
children: 'children',
label: 'name'
},
defaultExpandedKeys: [],
myTreeData: [],
searchName: '',
recordType: 1,
isDotEdit: false,
isDotSort: false,
IntervalId: 0,
indexPermission: false
}
},
components: {condition},
template: newTemplate,
mounted () {
this.checkPermission(48, 'indexPermission')
this.currentAccount = store.get('accountId')
this.getIndexData()
this.getBadge(1, 'isDotEdit')
this.getBadge(2, 'isDotSort')
this.IntervalId = setInterval(() => {
this.getBadge(1, 'isDotEdit')
this.getBadge(2, 'isDotSort')
}, 30000);
},
beforeDestroy(){
clearInterval(this.IntervalId)
},
methods: {
checkPermission (id, key) {
return new Promise((resolve, reject) => {
http.netPost('Account/Account/CheckPermission', {
"id": id,
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
if(res.data.Data == 1){
this[key] = true
}
resolve()
}
})
})
},
getIndexData () {
this.tableLoading = true
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/GetStatusChanges', {
"logOptions": this.recordType,
"Current": (this.pageCurrent - 1) * this.psize,
"Psize": this.psize,
"name": this.searchName,
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
this.tableData = res.data.Data.Records
this.pageTotal = res.data.Data.Total
}
this.tableLoading = false
})
})
},
pagClick (page) {
this.pageCurrent = page
this.getIndexData()
},
openChangeDetail (data) {
this.showChangeDetail = true
this.activeIndex = data
// this.myTreeData = this.setTreeData(this.indexIntoCategroy(this.activeIndex.SortContent.Object), 'myId', 'parentId')
// this.myTreeData.forEach(item => {
// this.defaultExpandedKeys.push(item.myId)
// })
},
changeType () {
this.searchName = ''
this.pagClick(1)
},
getBadge (type, key) {
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/GetTodoCustomIndexCount', {
"countOption": type,
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
if(res.data.Data > 0){
this[key] = true
}else{
this[key] = false
}
resolve(res)
}
this.loadingDetail = false
})
})
}
}
}
}
\ No newline at end of file
<template>
<div class="editor-inner">
<div class="analyzer-header shadow" style="margin-bottom: 0">
<div class="analyzer-header-title">
<div class="analyzer-header-title-name">指标管理</div>
<div class="analyzer-header-tab" style="flex: auto">
<router-link tag="div" active-class="activeLink" exact to="/">我的指标</router-link>
<router-link tag="div" active-class="activeLink" exact to="/publicIndex">公共指标</router-link>
<el-badge :is-dot="isDotEdit && indexPermission" class="item">
<router-link tag="div" active-class="activeLink" exact to="/indexAudit">指标审核</router-link>
</el-badge>
<el-badge :is-dot="isDotSort && indexPermission" class="item">
<router-link tag="div" active-class="activeLink" exact to="/categoryAudit">公共分类修改审核</router-link>
</el-badge>
<router-link tag="div" style="flex: auto; text-align: right" active-class="activeLink" exact to="/indexRecord">
<span class="el-icon-date"> 指标修改日志</span>
</router-link>
</div>
</div>
</div>
<div class="analyzer-content shadow" style="padding-top: 20px">
<div class="table-box">
<div style="margin-bottom: 12px; border-bottom: 1px solid #eaeaea; padding-bottom: 12px">
<span style="color: #999">日志类型:</span>
<el-radio-group v-model="recordType" @change="changeType">
<el-radio :label="1">指标修改</el-radio>
<el-radio :label="2">排序调整</el-radio>
</el-radio-group>
<span style="color: #999; margin-left: 20px">名称搜索:</span>
<el-input style="width: 240px" @keyup.enter.native="pagClick(1)" clearable v-model="searchName" size="mini" placeholder="请输入姓名查询相关日志"></el-input>
<el-button size="mini" style="margin-left: 12px" @click="pagClick(1)" type="primary">搜索</el-button>
</div>
<div>
<el-table
size="mini"
v-loading="tableLoading"
:data="tableData"
:header-cell-style="{background:'#f5f7fa',color:'#666'}"
border>
<el-table-column label="序号" width="60" type="index"></el-table-column>
<el-table-column prop="CreateDate" width="160" label="创建时间"></el-table-column>
<el-table-column prop="StatusChangeMsg" label="详情"></el-table-column>
<el-table-column prop="Remark" label="操作备注"></el-table-column>
</el-table>
<div class="pagination-container">
<el-pagination
layout="prev, pager, next"
:current-page="pageCurrent"
@current-change="pagClick"
:page-size="psize"
:total="pageTotal"
></el-pagination>
</div>
</div>
</div>
</div>
</div>
</template>
\ No newline at end of file
const http = require('../../../lib/axios/axios.js')
const { dialog } = require('electron').remote
const officegen = require('officegen')
const path = require('path');
const fs = require('fs')
const filePath = path.resolve(__dirname, './myIndex.vue')
let newTemplate = ''
var data = fs.readFileSync(filePath);
var str = data.toString()
var newStr = str.substring(0, str.lastIndexOf('</template>'))
newTemplate = newStr.replace('<template>', '')
// const calculater = require('../components/calculater')
const calculater = require('../../../components/complexCondition/index')
var keyBord = require('../../lib/keyBord')
var tools = require('../../lib/tools.js')
const { ipcRenderer } = require('electron')
const condition = require('../../components/condition/index.js')
module.exports = {
myIndex: {
data: function () {
return {
treeData: [],
myTreeData: [],
treeProps: {
children: 'children',
label: 'Name'
},
treeLoading: false,
editingText: '',
showTextEditing: false,
editIndexVisible: true,
editIndex: {
params: []
},
cascaderOptions: [],
cascaderProps: {
value: 'Id',
label: 'Name',
checkStrictly: true
},
publicProps: {
value: 'Code',
label: 'Name',
children: 'Children',
checkStrictly: true,
multiple: true
},
inputedIndex: '',
activeIndex: {},
indexTypeDic: {
},
editMemoryVisible: false,
editingMemoryInput: '',
editFuctionVisible: false,
detailShowType: 1, //1指标详情 2指标编辑 3文件夹操作,
addOrEditCategoryVisible: false,
addOrEditCategoryTitle: '新增分类',
inputedCategoryName: '',
createOrChangeCategoryLoading: false,
editIndexName: "",
editIndexFormat: 2,
editIndexParams: [],
editIndexUnit: "",
editIndexClassify: [],
editIndexCalaulate: {},
editIndexDetail: '',
// editIndexAccuracy: 2,
editFuctionType: [],
initIndex: 1,
deleteCategoryLoading: false,
defaultCategoryId: 0,
addIndexType: 'add',
defaultTypeList: [],
addCategoryType: 'add',
categoryDic: {},
initIndexObj: {},
companyNameObj: {},
addOrEditIndexLoading: false,
activeIndexCondition: {
indexParams: {},
dateParams: {},
numParams: {},
symbolParams: {},
functionParams: {},
dom: '',
showDom: ''
},
keyboardObj: {},
searchInputed: '',
reviewObj: {
1: '未提交',
2: '待审核',
4: '待审核',
16: '审核通过',
32: '审核不通过'
// 1.待提交,2.待审核,4.待审核,修改了指标,8.待审核,修改了百科,16.审核通过,32.审核不通过
},
submitLoading: false,
indexFilterType: 0,
deleteIndexLoading: false,
testRunVisible: false,
//测试运行相关
testYear: '',
testQuarter: '',
testMergeType: '合并本期',
activeRangeTab: '3',
rangeCompany: '',
searchCompanyLoading: false,
runningCompanyList: [],
selectedRangeCompany: [],
zjhIndustryData: [],
swIndustryData: [],
marketData:[],
positionData: [],
industryObj: {},
modelData: [],
submitCategoryVisible: false,
submitCategory: [],
publicCategoryOptions: [],
activeIndexStatus: 0,
sortType: null,
copyConditionHtml: null,
companyStatusData: [],
companyStatusCheck: {
isIndeterminate: false,
checkAll: false,
checkedItems: ['013001'],
options: []
},
defaultExpandedKeys: [],
defaultExpandedNames: [],
loadingDetail: false,
leftWidth: 25,
leftMinWidth: 20,
isDotEdit: false,
isDotSort: false,
IntervalId: 0,
indexPermission: false,
autoRunLoading: false
}
},
components: {
calculater, condition
},
watch: {
detailShowType (val) {
if (val == 1 || val == 3){
this.leftMinWidth = 20
this.leftWidth = 25
}else{
this.leftMinWidth = 0
this.leftWidth = 0
}
}
},
computed: {
},
template: newTemplate,
mounted() {
var that = this
ipcRenderer.on('copy-multiple-condition-reply', function (event, arg) {
that.copyConditionHtml = arg
})
this.checkPermission(48, 'indexPermission')
this.getIndexs().then(res => {
this.getIndexCateGory('init')
this.getDefaultType()
tools.getKeyboardObj(keyBord, this.keyboardObj)
})
this.getZjhIndustryCategoryList()
this.getSwIndustryCategoryList()
this.getPositionData()
this.getMarketData()
this.getPublicCategory()
this.getModelList()
this.getCompanyStatusData()
this.getBadge(1, 'isDotEdit')
this.getBadge(2, 'isDotSort')
this.IntervalId = setInterval(() => {
this.getBadge(1, 'isDotEdit')
this.getBadge(2, 'isDotSort')
}, 30000)
},
beforeDestroy(){
clearInterval(this.IntervalId)
},
methods: {
checkPermission (id, key) {
return new Promise((resolve, reject) => {
http.netPost('Account/Account/CheckPermission', {
"id": id,
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
if(res.data.Data == 1){
this[key] = true
}
resolve()
}
})
})
},
getCompanyStatusData () {
return new Promise((resolve, reject) => {
http.netPost('Data/Query/Query', {
"List": [
"F90063V",
"F90064V"
],
"Where": [],
"WhereOr": [],
"WhereOrArrayAnd": [],
"Sort": [{
"Encode":"F90063V",
"State":1
}],
"GPBField": ["F90063V"],
"Current": 0,
"Psize": 100,
"JoinTableWay": 0
})
.then((res) => {
if (res.data.Status == 1) {
this.companyStatusData = []
res.data.Data.Records.forEach(item => {
if(item["F90063V"]){
this.companyStatusData.push(item)
this.companyStatusCheck.options.push(item["F90063V"])
}
})
}
})
})
},
changeSort (res) {
this.sortType = res.order
},
compare (prop, type) {
return function (obj1, obj2) {
var val1 = parseFloat(obj1[prop])
var val2 = parseFloat(obj2[prop])
if (val1 < val2) {
return type == 'ascending'?-1:1;
} else if (val1 > val2) {
return type == 'ascending'?1:-1;
} else {
return 0;
}
}
},
exportExcel () {
var that = this
var excelName = new Date().getTime()
var xlsx = officegen('xlsx')
var filePath = dialog.showSaveDialog({
defaultPath: excelName + '.xlsx',
title: '保存',
buttonLabel: '保存'
})
xlsx.on('finalize', function(written) {
that.$message({
message: '表格导出成功!',
type: 'success'
})
})
xlsx.on('error', function(err) {
console.log(err)
})
var sheet = xlsx.makeNewSheet()
sheet.name = 'sheet'
sheet.orientation = 'landscape'
sheet.data[0] = []
sheet.data[0][0] = '序号'
sheet.data[0][1] = '证券简称'
sheet.data[0][2] = '证券代码'
sheet.data[0][3] = this.activeIndex.IndexName
var newArr = JSON.parse(JSON.stringify(this.selectedRangeCompany))
if(this.sortType == 'descending'){
newArr.sort(that.compare('result', 'descending'))
}else if(this.sortType == 'ascending'){
newArr.sort(that.compare('result', 'ascending'))
}
newArr.forEach((item, index)=>{
sheet.data[index + 1] = []
sheet.data[index + 1][0] = index+1
sheet.data[index + 1][1] = item['name']
sheet.data[index + 1][2] = item['code']
sheet.data[index + 1][3] = item['result']
})
var out = fs.createWriteStream(filePath)
out.on('error', function(err) {
console.log(err)
})
xlsx.generate(out)
},
cancelSubmit () {
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/UnSubmitIndex', {
"id": this.activeIndex.PublicIndexId,
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
this.$message({
message: "撤销提交成功",
type: "success"
})
this.getIndexCateGory()
resolve()
}
})
})
},
getKeyword (keyword) {
var name = keyword.Name
var arr = []
keyword.Keywords.forEach(item => {
arr.push(item.Name)
})
name = name + '(' + arr.join(',') + ')'
return name
},
handleCheckAllChange(val, obj) {
obj.checkedItems = val ? obj.options : []
obj.isIndeterminate = false
},
handleCheckedResults(value, obj) {
let checkedCount = value.length
obj.checkAll = checkedCount === obj.options.length
obj.isIndeterminate = checkedCount > 0 && checkedCount < obj.options.length
},
getModelList () {
return new Promise((resolve, reject) => {
http.netPost('Module/Basic/GetModelList', {})
.then((res) => {
if (res.data.Status == 1) {
this.modelData = []
res.data.Data.Records.forEach(item => {
var keywordOptions = [], nameOptions = []
item.Keywords.forEach(sub => {
keywordOptions.push(sub.ModelKeywordId)
})
item.DimensionNames.forEach(sub => {
nameOptions.push(sub.ModelDimensionId)
})
item.keywordCheck = {
checkAll: false,
checkedItems: [],
isIndeterminate: false,
options: keywordOptions
}
item.nameCheck = {
checkAll: false,
checkedItems: [],
isIndeterminate: false,
options: nameOptions
}
this.modelData.push(item)
})
resolve()
}
})
})
},
getPublicCategory () {
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/GetPublicArchive', {})
.then((res) => {
if (res.data.Status == 1) {
this.publicCategoryOptions = res.data.Data
resolve()
}
})
})
},
testRunIndex () {
//判断条件
var args = []
var ref = this.$refs.conditionChoose
if(!ref.testMergeType || !ref.testYear || !ref.testQuarter || this.selectedRangeCompany.length == 0){
this.$message({
message: '参数不完整或标的为空',
type: 'error'
})
return false
}
this.selectedRangeCompany.forEach(item => {
args.push({
stockCode: item.code,
argType: 1
})
})
args.push({
mergeType: ref.testMergeType,
argType: 2
},{
reportingPeriod: ref.testYear + '-' +ref.testQuarter,
argType: 4
})
this.searchCompanyLoading = true
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/TestRunCustomIndex', {
args: args,
"id": this.activeIndex.Id
})
.then((res) => {
if (res.data.Status == 1) {
this.selectedRangeCompany.forEach(item => {
if(res.data.Data[item.code] !== "NaN"){
item.result = res.data.Data[item.code]
}else{
item.result = '分母为0'
}
})
resolve()
}
this.searchCompanyLoading = false
})
})
},
openTestRunDialog () {
this.testRunVisible = true
},
//处理证监会行业数据
handleZjhData(data) {
var newObj = {}
var newArray = []
data.map((item) => {
if (!newObj[item.F90014V]) {
newObj[item.F90014V] = item
newArray.push({
label: item.F90012V,
id: item.F90014V,
code: 'F90014V',
from: '证监会' + '-' + item.F90012V,
labelCode: 'F90012V',
searchCode: 'F90012V',
})
this.industryObj[item.F90014V] = '证监会' + '-' + item.F90012V
}
})
newArray.map((chid) => {
chid.children = []
data.map((item, index) => {
if (chid.id == item.F90014V) {
chid.children.push({
label: item.F90013V,
id: item.F90015V,
code: 'F90015V',
labelCode: 'F90013V',
from: chid.from + '-' + item.F90013V,
searchCode: 'F90013V'
})
this.industryObj[item.F90015V] = chid.from + '-' + item.F90013V
}
})
})
this.zjhIndustryData = [
{
label: '证监会行业',
id: 0,
code: '0',
labelCode: '0',
from: '',
searchCode: '0',
children: newArray
}
]
},
handleSwData(data) {
var parentObj = {}
var parentArray = []
var childObj = {}
var childArray = []
data.map((item) => {
if (!parentObj[item.F90016V]) {
parentObj[item.F90016V] = item
parentArray.push({
label: item.F90017V,
id: item.F90016V,
code: 'F90017V',
from: '申万' + '-' + item.F90017V,
searchCode: 'F90017V'
})
this.industryObj[item.F90016V] = '申万' + '-' + item.F90017V
}
if (!childObj[item.F90018V]) {
childObj[item.F90018V] = item
childArray.push({
label: item.F90019V,
id: item.F90018V,
parentId: item.F90016V,
code: 'F90019V',
from: '申万' + '-' + item.F90017V + '-' + item.F90019V,
searchCode: 'F90019V'
})
this.industryObj[item.F90018V] = '申万' + '-' + item.F90017V + '-' + item.F90019V
}
})
childArray.map((chid) => {
chid.children = []
data.map((item) => {
if (chid.id == item.F90018V) {
chid.children.push({
label: item.F90021V,
id: item.F90020V,
code: 'F90021V',
from: chid.from + '-' + item.F90021V,
searchCode: 'F90021V'
})
this.industryObj[item.F90020V] = chid.from + '-' + item.F90021V
}
})
})
parentArray.map((sub) => {
sub.children = []
childArray.map((item) => {
if (sub.id == item.parentId) {
sub.children.push(item)
}
})
})
// this.swIndustryData = parentArray
this.swIndustryData = [
{
label: '申万行业',
id: 0,
code: '0',
from: '',
searchCode: '0',
children: parentArray
}
]
},
getZjhIndustryCategoryList() {
return new Promise((resolve, reject) => {
http.netPost('Data/Query/Query', {
"List": [
"F90013V",
"F90012V",
"F90014V",
"F90015V"
],
"Where": [],
"GPBField": ["F90015V"],
"Current": 0,
"Psize": 10000
})
.then((res) => {
if (res.data.Status == 1) {
this.handleZjhData(res.data.Data.Records)
}
})
})
},
getSwIndustryCategoryList() {
return new Promise((resolve, reject) => {
http.netPost('Data/Query/Query', {
"List": [
"F90016V",
"F90017V",
"F90018V",
"F90019V",
"F90020V",
"F90021V"
],
"Where": [],
"GPBField": ["F90020V"],
"Current": 0,
"Psize": 10000
})
.then((res) => {
if (res.data.Status == 1) {
this.handleSwData(res.data.Data.Records)
}
})
})
},
// 获取市场信息
getMarketData() {
http.netPost('Data/Query/Query', {
"List": [
"F90005V",
"F90006V"
],
"Where": [],
"WhereOr": [],
"GPBField": [
"F90005V"
],
"Current": 0,
"Psize": 999
}).then((res) => {
this.marketData = res.data.Data.Records
this.marketData.forEach(item => {
item.label = item.F90006V
item.searchCode = 'F90006V'
})
})
},
getPositionData() {
return new Promise((resolve, reject) => {
http.netPost('Data/Query/Query', {
"List": [
"F90010V",
"F90011V"
],
"Where": [],
"WhereOr": [],
"GPBField": [
"F90010V",
"F90011V"
],
"Current": 0,
"Psize": 999
}).then((res) => {
if (res.data.Status == 1) {
var parentObj = {}
var newArray = res.data.Data.Records
newArray.forEach(item => {
if (!parentObj[item.F90010V]) {
parentObj[item.F90010V] = {
id: item.F90010V,
label: item.F90010V,
code: 'F90010V',
children: [],
searchCode: 'F90010V',
}
parentObj[item.F90010V].children.push({
id: item.F90011V,
label: item.F90011V,
code: 'F90011V',
searchCode: 'F90011V'
})
} else {
parentObj[item.F90010V].children.push({
id: item.F90011V,
label: item.F90011V,
code: 'F90011V',
searchCode: 'F90011V'
})
}
})
this.positionData = []
for (var key in parentObj) {
if (key !== 'null') {
this.positionData.push(parentObj[key])
}
}
}
})
})
},
searchCompanyByIndustry(item, type) {
this.searchCompanyLoading = true
var Where = []
var checkeds = this.companyStatusCheck.checkedItems
if(type == 1 || type == 2 || type == 4 || type == 3){
Where.push({
"Encode": item.searchCode,
"State": 1,
"Value": item.label,
})
if(checkeds.length > 0){
Where.push({
"Encode": "F90063V",
"State": checkeds.length == 1?1:8,
"Value": checkeds.length == 1?checkeds[0]:checkeds
})
}
}
this.initIndex++
var params = {
content: {
"List": ['F90001V', 'F90002V'],
"Where": Where,
"Current": 0,
"Psize": 10000
}
}
return new Promise((resolve, reject) => {
var companyObj = {}
this.selectedRangeCompany.forEach(item => {
if(!companyObj[item.F90001V]){
companyObj[item.F90001V] = item.F90001V
}
})
http.netPost('Data/Query/Query', params.content)
.then((res) => {
if (res.data.Status == 1) {
var arr = []
res.data.Data.Records.map((child) => {
if(!companyObj[child.F90001V]){
arr.push({
name: child.F90002V,
code: child.F90001V
})
}
})
this.addAndRemoveCompany(arr)
}
this.searchCompanyLoading = false
})
})
},
//测试运行的一些方法开始
addRangeCompany(item) {
var code = item.split(',')[1]
var obj = {
name: item.split(',')[0],
code: code,
}
// this.selectedRangeCompany.push([])
this.addAndRemoveCompany([obj])
this.rangeCompany = ''
},
//对数据进行去重
addAndRemoveCompany (arr) {
var oldCompany = {}
this.selectedRangeCompany.forEach(item => {
oldCompany[item.code] = item.name
})
arr.forEach(item => {
if(!oldCompany[item.code]){
this.selectedRangeCompany.push({
code: item.code,
name: item.name,
result: null
})
}
})
},
searchRunningCompany(value) {
this.searchCompanyLoading = true
var checkeds = this.companyStatusCheck.checkedItems
var Where = []
if(checkeds.length > 0){
Where.push({
"Encode": "F90063V",
"State": checkeds.length == 1?1:8,
"Value": checkeds.length == 1?checkeds[0]:checkeds
})
}
return new Promise((resolve, reject) => {
http.netPost('Data/Query/Query', {
"List": ["F90004V", 'F90001V', 'F90002V'],
"WhereOr": [
{
"Encode": "F90004V",
"State": 2,
"Value": value,
},
{
"Encode": "F90001V",
"State": 2,
"Value": value,
},
{
"Encode": "F90002V",
"State": 2,
"Value": value,
},
],
"Where": Where,
"Current": 0,
"Psize": 20
})
.then((res) => {
if (res.data.Status == 1) {
this.runningCompanyList = res.data.Data.Records
}
this.searchCompanyLoading = false
})
})
},
selectedExcel(e) {
var file = e.target.files[0]
var type = file.name.split('.')
if (type[type.length - 1] !== 'xlsx' && type[type.length - 1] !== 'xls') {
this.$message({
message: '所选文件格式不正确!',
type: 'error'
})
e.target.value = ''
return false;
} else {
const reader = new FileReader();
reader.readAsBinaryString(file);
reader.onload = (e) => {
const data = e.target.result;
const zzexcel = window.XLS.read(data, {
type: 'binary'
})
const result = [];
for (let i = 0; i < zzexcel.SheetNames.length; i++) {
const newData = window.XLS.utils.sheet_to_json(zzexcel.Sheets[zzexcel.SheetNames[i]]);
result.push(...newData)
}
var arr = []
result.forEach(item => {
var obj = {
name: item.name,
code: item.code.split('.')[0]
// label: item.name,
// type: 5,
// from: '批量添加'
}
arr.push(obj)
})
this.addAndRemoveCompany(arr)
}
this.$message({
message: '导入成功!',
type: 'success'
})
e.target.value = ''
}
},
//测试运行的一些方法结束
deleteIndex() {
this.deleteIndexLoading = true
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/RemoveCustomIndex', {
"id": this.activeIndex.Id,
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
this.activeIndex = {}
this.$message({
message: "指标删除成功",
type: 'success'
})
this.getIndexCateGory()
resolve()
}
this.deleteIndexLoading = false
})
})
},
choosePublicCategory () {
// this.getSameText()
this.submitCategoryVisible = true
},
getSameText () {
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/IndexNameSimilarity', {
"customIndexId": this.activeIndex.Id,
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
resolve()
}
})
})
},
confirmSubmit() {
if(!this.submitCategory){
this.$message({
message: '请选择分类',
type: 'error'
})
return false
}
this.submitLoading = true
var arr = []
this.submitCategory.forEach(item => {
arr.push(item[item.length - 1])
})
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/SubmitIndexToView', {
"id": this.activeIndex.Id,
"archiveCodes": arr,
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
this.activeIndex = {}
this.getIndexCateGory()
this.$message({
message: '审核提交成功',
type: 'success'
})
resolve()
}
this.submitLoading = false
this.submitCategoryVisible = false
})
})
},
nodeExpand (data) {
this.defaultExpandedNames.push(data.Name)
},
nodeCollapse (data) {
for(var i = this.defaultExpandedNames.length - 1; i>=0; i--){
if(this.defaultExpandedNames[i] == data.Name){
this.defaultExpandedNames.splice(i, 1)
}
}
},
//获取初始化公司
getUsedCompany(params) {
var codes = []
params.forEach(item => {
if (item.OperandType == 0 && item.Where[2]) {
codes.push(item.Where[2].Value)
} else if (item.OperandType == 4) {
item.Args.forEach(sub => {
sub.forEach(child => {
if (child.OperandType == 0 && child.Where[2]) {
codes.push(child.Where[2].Value)
}
})
})
}
})
var where = [{
"Encode": "F90001V",
"State": 7,
"Value": codes.join(','),
}]
return new Promise((resolve, reject) => {
http.netPost('Data/Query/Query', {
"List": ['F90001V', 'F90002V'],
"Where": where,
"Current": 0,
"Psize": 100
})
.then((res) => {
if (res.data.Status == 1) {
res.data.Data.Records.forEach(item => {
this.companyNameObj[item.F90001V] = item.F90002V
})
resolve()
} else if (res.data.Status == 0) {
resolve()
} else {
reject()
}
})
})
},
getIndexArgsType(args) {
var arr = []
this.defaultTypeList.forEach(item => {
if (args & item.Id) {
arr.push(item.Name)
}
})
return arr.join('')
},
getIndexArgsIds(args) {
var arr = []
this.defaultTypeList.forEach(item => {
if (args & item.Id) {
arr.push(item.Id)
}
})
return arr
},
getDefaultType() {
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/GetAllIndexArgs', {
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
this.defaultTypeList = res.data.Data
res.data.Data.forEach(item => {
this.editIndexParams.push(item.Id)
})
resolve()
}
})
})
},
confirmEditIndex() {
this.addIndexType = 'edit'
this.editIndexName = this.activeIndex.IndexName
this.editIndexFormat = this.activeIndex.ReturnType
this.editIndexParams = this.getIndexArgsIds(this.activeIndex.Args)
this.editIndexUnit = this.activeIndex.IndexUnit
this.editIndexClassify = this.getEditIndexCategory()
this.editIndexDetail = this.activeIndex.Wiki
this.detailShowType = 2
this.$nextTick(() => {
this.$refs.calculater.indexParams = this.activeIndexCondition.indexParams
this.$refs.calculater.numParams = this.activeIndexCondition.numParams
this.$refs.calculater.dateParams = this.activeIndexCondition.dateParams
this.$refs.calculater.symbolParams = this.activeIndexCondition.symbolParams
this.$refs.calculater.functionParams = this.activeIndexCondition.functionParams
for (var key in this.activeIndexCondition.functionParams) {
this.activeIndexCondition.functionParams[key].paramsValue.forEach(item => {
var arr = ['indexParams', 'numParams', 'dateParams', 'symbolParams']
arr.forEach(child => {
for (var key in item[child]) {
this.$refs.calculater.indexParams[key] = item[child]
}
})
})
}
this.$refs.calculater.setHtml(this.activeIndexCondition.dom)
this.setChart('chart1')
})
},
getEditIndexCategory() {
var arr = []
this.activeIndex.from.forEach((item, index) => {
if (index < this.activeIndex.from.length - 1) {
arr.push(item.id)
}
})
return arr
},
openAddNewIndex() {
this.detailShowType = 2
this.addIndexType = 'add'
this.emptyModelData()
//将当前的id带过去
var arr = []
this.activeIndex.from.forEach(item => {
arr.push(item.id)
})
this.editIndexClassify = arr
},
emptyModelData () {
this.modelData.forEach(item => {
this.$set(item.keywordCheck, 'checkAll', false)
this.$set(item.keywordCheck, 'checkedItems', [])
this.$set(item.keywordCheck, 'isIndeterminate', false)
this.$set(item.nameCheck, 'checkAll', false)
this.$set(item.nameCheck, 'checkedItems', [])
this.$set(item.nameCheck, 'isIndeterminate', false)
})
},
deleteCategory() {
this.deleteCategoryLoading = true
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/RemoveArchive', {
"Id": this.activeIndex.Id,
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
this.getIndexCateGory()
resolve()
}
this.deleteCategoryLoading = false
})
})
},
// getIndexs() {
// this.treeLoading = true
// return new Promise((resolve, reject) => {
// http.netPost('Data/Encode/GetEncodeList', {
// "Current": 0,
// "Psize": 100,
// "Code": "B",
// 'Name': '',
// "AccountId": store.get('accountId')
// })
// .then((res) => {
// if (res.data.Status == 1) {
// this.treeData = res.data.Data.Records
// this.creatIndexObj(res.data.Data.Records)
// this.treeLoading = false
// resolve()
// }
// })
// })
// },
getIndexs() {
this.treeLoading = true
this.getIndexsByCodes(['CIF024002001N'])
return new Promise((resolve, reject) => {
http.netPost('Data/Encode/GetEncodeList', {
"Current": 0,
"Psize": 100,
"Code": "B",
'Name': '',
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
this.treeData = res.data.Data.Records
this.creatIndexObj(res.data.Data.Records)
this.treeLoading = false
resolve()
}
})
})
},
creatIndexObj(initData) {
initData.forEach(element => {
if (element.Sub.length > 0) {
this.creatIndexObj(element.Sub)
} else {
this.initIndexObj[element.Code] = element
var tableName = element.Origin ? element.Origin.TableComment : null
var dbName = element.Origin ? element.Origin.DbComment : null
this.initIndexObj[element.Code].originText = tableName + '-' + dbName
}
})
},
backToDetail() {
if (this.activeIndex.isIndex) {
this.detailShowType = 1
} else {
this.detailShowType = 3
}
},
closeEditFuction() {
this.$refs.calculater.resetActiveInput()
},
//重新编辑计算参数
resetFuncParams(selectedController, index) {
//重新注入参数
var obj = JSON.parse(JSON.stringify(selectedController.paramsValue[index]))
this.$refs.functionCalculater.indexParams = obj.indexParams
this.$refs.functionCalculater.dateParams = obj.dateParams
this.$refs.functionCalculater.numParams = obj.numParams
this.$refs.functionCalculater.symbolParams = obj.symbolParams
var id = this.$refs.functionCalculater.contentId
var html = selectedController.paramsValue[index].dom
document.getElementById(id).innerHTML = ''
document.getElementById(id).innerHTML = html
},
confirmAddFunction() {
var params = this.$refs.functionCalculater.sendDataToHost()
// 判断数据类型是否一致
this.$refs.calculater.receiveFunctionParam(params)
this.editFuctionVisible = false
},
//添加指标百科
confirmAddMemo() {
this.editMemoryVisible = false
},
//获取指标来源
getIndexFrom() {
return this.activeIndex.Origin.DataProvider + '/' + this.activeIndex.Origin.DbComment
},
//获取指标参数
getIndexParams(activeIndex) {
var textArr = []
activeIndex.TypeContent.Parameters.forEach(item => {
textArr.push(item.Name)
})
return textArr.join('')
},
//获取指标类型
getDataType(activeIndex) {
var obj = {
0: '字符',
1: '日期',
2: '数字'
}
return obj[activeIndex.ReturnType]
},
getStatus (obj) {
if(!obj){
return 1
}
var status = 0
obj.WdCustomIndexWorkflow.forEach( item => {
if(item.IsCurrent == 1){
status = item.FlowStatus
}
})
return status
},
setChart (refName) {
// setTimeout(()=>{
// var myChart = echarts.init(this.$refs[refName])
// var data2 = {
// "name": "净资产收益率(ROE)",
// "children": [
// {
// "name": "销售净利率",
// "children": []
// },
// {
// "name": "资产周转率",
// "children": []
// },
// {
// "name": "权益乘数",
// "children": []
// }
// ]
// };
// var option = {
// tooltip: {
// trigger: 'item',
// triggerOn: 'mousemove'
// },
// series:[
// {
// type: 'tree',
// name: 'tree2',
// data: [data2],
// top: '20%',
// left: '20%',
// bottom: '22%',
// right: '18%',
// symbolSize: 7,
// orient: 'vertical',
// label: {
// position: 'top',
// verticalAlign: 'middle',
// align: 'center',
// distance: 10
// },
// leaves: {
// label: {
// position: 'bottom',
// verticalAlign: 'middle',
// align: 'center',
// distance: 10
// }
// },
// expandAndCollapse: true,
// animationDuration: 550,
// animationDurationUpdate: 750
// }
// ]
// }
// myChart.setOption(option = option);
// },1000)
},
//指标点击
selecteIndex(value, param) {
var arr = [value.Id]
if (this.detailShowType == 2) {
return false
}
if(value.isIndex){
this.getSingleIndexData(arr).then(res => {
//先恢复初始化
var data = res.data.Data[0]
data.isIndex = value.isIndex
data.CurrentWorkflow = value.CurrentWorkflow
data.myId = value.myId
this.getIndexModel(data)
this.activeIndexStatus = data.CurrentWorkflow
this.detailShowType = 1
this.getUsedCompany(data.Algorithm.Object).then(res => {
this.activeIndexCondition = {
indexParams: {},
dateParams: {},
numParams: {},
symbolParams: {},
functionParams: {},
dom: '',
showDom: ''
}
tools.getSaveCondition(this.activeIndexCondition, data.Algorithm.Object, this.initIndex, this.initIndexObj, this.companyNameObj, this.keyboardObj)
this.$nextTick(() => {
var spans = document.getElementById('conditionBox').getElementsByTagName('span')
var html = ''
Array.from(spans).forEach(span => {
html += span.outerHTML
})
document.getElementById('conditionBox').innerHTML = html
var spans = document.getElementById('conditionBox').getElementsByTagName('span')
tools.formatShowDom(spans)
})
})
this.activeIndex = data
this.activeIndex.from = this.findPathByLeafId(data.myId, this.myTreeData)
})
}else{
this.detailShowType = 3
this.activeIndex = value
this.activeIndex.from = this.findPathByLeafId(value.myId, this.myTreeData)
}
this.setChart('chart')
},
getIndexModel (data) {
//初始化选择
this.modelData.forEach(item => {
this.$set(item.keywordCheck, 'checkAll', false)
this.$set(item.keywordCheck, 'checkedItems', [])
this.$set(item.keywordCheck, 'isIndeterminate', false)
this.$set(item.nameCheck, 'checkAll', false)
this.$set(item.nameCheck, 'checkedItems', [])
this.$set(item.nameCheck, 'isIndeterminate', false)
})
//修改数据
var dimensions = [], keywords = []
data.Dimensions.forEach(item => {
dimensions.push(item.DimensionId)
})
data.Keywords.forEach(item => {
keywords.push(item.KeywordId)
})
this.modelData.forEach(item => {
item.keywordCheck.options.forEach(sub => {
if(keywords.indexOf(sub) >= 0){
item.keywordCheck.checkedItems.push(sub)
}
})
item.nameCheck.options.forEach(sub => {1
if(dimensions.indexOf(sub) >= 0){
item.nameCheck.checkedItems.push(sub)
}
})
if(item.keywordCheck.checkedItems.length == item.keywordCheck.options.length){
item.keywordCheck.checkAll = true
}else if(item.keywordCheck.checkedItems.length > 0 && item.keywordCheck.checkedItems.length < item.keywordCheck.options.length){
item.keywordCheck.isIndeterminate = true
}
if(item.nameCheck.checkedItems.length == item.nameCheck.options.length){
item.nameCheck.checkAll = true
}else if(item.nameCheck.checkedItems.length > 0 && item.nameCheck.checkedItems.length < item.nameCheck.options.length){
item.nameCheck.isIndeterminate = true
}
})
},
formatIndexFrom(arr) {
var newArr = []
arr.forEach(item => {
newArr.push(item.name)
})
return newArr.join(' / ')
},
//树状结构过滤
filterIndexTreeNode(value, data, node) {
if(!node.isLeaf && node.expanded){
this.defaultExpandedNames.push(data.Name)
}
if (!value) {
if (this.indexFilterType == 0) {
return true
} else {
if (this.indexFilterType == 1 && data.CurrentWorkflow == 1) {
return true
}
if (this.indexFilterType == 3 && (data.CurrentWorkflow == 2 || data.CurrentWorkflow == 4)) {
return true
}
if (this.indexFilterType == 16 && data.CurrentWorkflow == 16) {
return true
}
if (this.indexFilterType == 32 && data.CurrentWorkflow == 32) {
return true
}
}
} else {
if (this.indexFilterType == 0 && data.Name.indexOf(value) !== -1) {
return true
} else {
if (this.indexFilterType == 1 && data.CurrentWorkflow == 1 && data.Name.indexOf(value) !== -1) {
return true
}
if (this.indexFilterType == 3 && (data.CurrentWorkflow == 2 || data.CurrentWorkflow == 4) && data.Name.indexOf(value) !== -1) {
return true
}
if (this.indexFilterType == 16 && data.CurrentWorkflow == 16 && data.Name.indexOf(value) !== -1) {
return true
}
if (this.indexFilterType == 32 && data.CurrentWorkflow == 32 && data.Name.indexOf(value) !== -1) {
return true
}
}
}
},
//搜索指标
changeIndexType() {
this.defaultExpandedNames = []
this.$refs.publicIndexTree.filter(this.inputedIndex)
this.searchInputed = this.inputedIndex
},
searchIndex() {
this.defaultExpandedNames = []
this.$refs.publicIndexTree.filter(this.inputedIndex)
this.searchInputed = this.inputedIndex
},
emptySearch() {
this.inputedIndex = ''
this.searchIndex()
},
findPathByLeafId(leafId, nodes, path) {
if (path === undefined) {
path = []
}
for (var i = 0; i < nodes.length; i++) {
var tmpPath = path.concat()
tmpPath.push({
myId: nodes[i].myId,
name: nodes[i].Name,
id: nodes[i].Id
})
if (leafId == nodes[i].myId) {
return tmpPath;
}
if (nodes[i].children) {
var findResult = this.findPathByLeafId(leafId, nodes[i].children, tmpPath);
if (findResult) {
return findResult
}
}
}
},
getIndexCateGory(type) {
this.treeLoading = true
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/GetMyIndexArchivesLight', {
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
res.data.Data.forEach(item => {
this.initIndex++
item.myId = new Date().getTime() + this.initIndex
item.name = item.ArchiveName
this.categoryDic[item.Id] = item.myId
if (item.Required) {
this.defaultCategoryId = item.Id
}
})
res.data.Data.forEach(item => {
item.parentId = this.categoryDic[item.ParentId]
})
var categroyData = JSON.parse(JSON.stringify(res.data.Data))
var cascaderData = JSON.parse(JSON.stringify(res.data.Data))
this.myTreeData = this.setTreeData(this.indexIntoCategroy(categroyData), 'myId', 'parentId')
this.cascaderOptions = this.setTreeData(cascaderData, 'Id', 'ParentId')
if(type == 'init'){
this.myTreeData.forEach(item => {
if(item.children){
item.children.forEach(sub => {
this.defaultExpandedKeys.push(sub.myId)
this.defaultExpandedNames.push(sub.Name)
})
}
})
}else{
var arr = []
res.data.Data.forEach(item => {
this.defaultExpandedNames.forEach(sub => {
if(item.Name == sub){
arr.push(item.myId)
}
})
})
this.defaultExpandedKeys = arr
}
this.treeLoading = false
this.activeIndex = {}
this.detailShowType = 1
this.$nextTick(()=>{
this.changeIndexType()
})
resolve()
}
})
})
},
indexIntoCategroy(data) {
var newData = JSON.parse(JSON.stringify(data))
data.forEach(item => {
item.WdCustomIndex.forEach(sub => {
this.initIndex++
sub.myId = new Date().getTime() + this.initIndex
sub.parentId = item.myId
sub.isIndex = true
newData.push(sub)
})
})
return newData
},
openAddCategory() {
this.inputedCategoryName = ''
this.addOrEditCategoryTitle = '新增分类'
this.addCategoryType = 'add'
this.addOrEditCategoryVisible = true
},
openChangeCategory() {
this.inputedCategoryName = this.activeIndex.ArchiveName
this.addOrEditCategoryTitle = '修改分类'
this.addCategoryType = 'edit'
this.addOrEditCategoryVisible = true
},
createOrChangeCategory() {
this.createOrChangeCategoryLoading = true
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/AddIndexArchive', {
"id": this.addCategoryType == 'add' ? 0 : this.activeIndex.Id,
"archiveName": this.inputedCategoryName,
"parentId": this.addCategoryType == 'add' ? this.activeIndex.Id : this.activeIndex.ParentId,
"AccountId": store.get('accountId')
})
.then((res) => {
this.createOrChangeCategoryLoading = false
if (res.data.Status == 1) {
this.addOrEditCategoryVisible = false
this.getIndexCateGory()
resolve()
}
})
})
},
setTreeData(jsonData, id, pid) {
let result = [], temp = {}
for (let i = 0; i < jsonData.length; i++) {
temp[jsonData[i][id]] = jsonData[i]
}
for (let j = 0; j < jsonData.length; j++) {
let currentElement = jsonData[j]
let tempCurrentElementParent = temp[currentElement[pid]]
if (tempCurrentElementParent) {
if (!tempCurrentElementParent["children"]) {
tempCurrentElementParent["children"] = []
}
tempCurrentElementParent["children"].push(currentElement)
} else {
result.push(currentElement)
}
}
return result
},
addOrChangeIndex() {
this.$refs.calculater.checkGrammar('tip')
var args = 0, keywordIds = [], dimensionIds = []
this.modelData.forEach(item => {
item.keywordCheck.checkedItems.forEach(sub => {
keywordIds.push(sub)
})
item.nameCheck.checkedItems.forEach(sub => {
dimensionIds.push(sub)
})
})
this.editIndexParams.forEach(item => {
args |= item
})
this.addOrEditIndexLoading = true
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/AddCustomIndex', {
"id": this.addIndexType == 'add' ? 0 : this.activeIndex.Id,
"indexName": this.editIndexName,
"archiveId": this.editIndexClassify[this.editIndexClassify.length - 1], //分类Id
"operands": this.getOperands(), //计算参数
"returnType": this.editIndexFormat, //指标类型
"args": args, //指标参数
"unit": this.editIndexUnit, //单位
"remark": this.editIndexDetail, //备注
"keywordIds": keywordIds,
"dimensionIds": dimensionIds,
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
this.backToDetail()
this.getIndexCateGory()
resolve()
}
this.addOrEditIndexLoading = false
})
})
},
getOperands() {
var params = this.$refs.calculater.sendDataToHost(true)
return this.setSaveCondition(params)
},
setSaveCondition(condition) { //格式化保存的条件,原名 getSaveCalCondition
var operands = []
var div = document.createElement('div')
div.innerHTML = condition.dom
var inputs = div.getElementsByTagName('input')
//后台的定义 0指标1符号2数字3时间4方法
//前台的定义 1指标2时间3数字4字符5方法
Array.from(inputs).forEach(item => {
var obj = {},
id = item.id
switch (parseInt(item.getAttribute('type'))) {
case 1: //指标
var param = condition.indexParams[id]
var dateYear = '1900'
var dateQuater = '06-30'
var evalArray = []
if (param.yearType == 1) {
evalArray.push({
"EvalOption": 1,
"Value": param.t
})
} else if (param.yearType == 2) {
dateYear = param.inputYear
}
if (param.quarterType == 1) {
evalArray.push({
"EvalOption": 2,
"Value": param.q
})
} else if (param.quarterType == 2) {
dateQuater = param.inputQuarter
}
var where = [{
"State": 1,
"Encode": "F91996D",
"Value": dateYear + '-' + dateQuater,
"Eval": evalArray
},
{
"State": 1,
"Value": param.mergeType,
"Encode": "F91997V",
"Eval": []
}
]
if (param.isAppointCompany) {
where.push({
"State": 1,
"Value": param.selectedCompany.split('-')[1],
"Encode": "F90001V",
"Eval": []
})
}
obj = {
"List": [param.code],
"Where": where,
"OperandType": 0,
}
break;
case 2: //时间
obj = {
"Value": item.value,
"OperandType": 3
}
break;
case 3: //数字
obj = {
"Value": item.value.replace(/\[.*?\]/g, ''),
"OperandType": 2
}
break;
case 4: //字符
obj = {
"Value": item.value,
"OperandType": 1
}
break;
case 5: //方法
obj = {
"Action": condition.functionParams[id].originParams.funcId,
"Args": this.getFuncArgs(condition.functionParams[id]),
"OperandType": 4
}
break;
default:
break;
}
operands.push(obj)
})
return operands
},
getFuncArgs(functionParams) {
var arr = []
functionParams.paramsValue.forEach(item => {
arr.push(this.setSaveCondition(item))
})
return arr
},
getSingleIndexData (ids) {
this.loadingDetail = true
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/GetMyIndexByIds', {
"ids": ids,
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
resolve(res)
}
this.loadingDetail = false
})
})
},
getBadge (type, key) {
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/GetTodoCustomIndexCount', {
"countOption": type,
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
if(res.data.Data > 0){
this[key] = true
}else{
this[key] = false
}
resolve(res)
}
this.loadingDetail = false
})
})
},
getIndexsByCodes (codes) {
return new Promise((resolve, reject) => {
http.netPost('Data/Encode/GetEncodeDetailsByCodes', {
"codes": codes,
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
resolve(res.data.Data)
}
})
})
},
setInitIndexObj (codes) {
codes.forEach(item => {
this.initIndexObj[item.Code] = item
})
},
downloadExample () {
var that = this
var excelName = '示例表格'
var xlsx = officegen('xlsx')
var filePath = dialog.showSaveDialog({
defaultPath: excelName + '.xlsx',
title: '保存',
buttonLabel: '保存'
})
xlsx.on('finalize', function(written) {
that.$message({
message: '下载完成',
type: 'success'
})
})
xlsx.on('error', function(err) {
console.log(err)
})
var sheet = xlsx.makeNewSheet()
sheet.name = 'sheet1'
sheet.orientation = 'landscape'
sheet.data[0] = []
sheet.data[0][0] = 'name'
sheet.data[0][1] = 'code'
sheet.data[1] = []
sheet.data[1][0] = '华夏银行'
sheet.data[1][1] = '600015.sh'
sheet.data[2] = []
sheet.data[2][0] = '贵州茅台'
sheet.data[2][1] = '600519'
sheet.data[3] = []
sheet.data[3][0] = '工商银行'
sheet.data[3][1] = '601398'
var out = fs.createWriteStream(filePath)
out.on('error', function(err) {
console.log(err)
})
xlsx.generate(out)
},
createAutoTask () {
}
}
}
}
\ No newline at end of file
<template>
<div class="editor-inner">
<div class="analyzer-header shadow">
<div class="analyzer-header-title">
<div class="analyzer-header-title-name">指标管理</div>
<div class="analyzer-header-tab" style="flex: auto">
<router-link tag="div" active-class="activeLink" exact to="/">我的指标</router-link>
<router-link tag="div" active-class="activeLink" exact to="/publicIndex">公共指标</router-link>
<el-badge :is-dot="isDotEdit && indexPermission" class="item">
<router-link tag="div" active-class="activeLink" exact to="/indexAudit">指标审核</router-link>
</el-badge>
<el-badge :is-dot="isDotSort && indexPermission" class="item">
<router-link tag="div" active-class="activeLink" exact to="/categoryAudit">公共分类修改审核</router-link>
</el-badge>
<router-link
tag="div"
style="flex: auto; text-align: right"
active-class="activeLink"
exact
to="/indexRecord"
>
<span class="el-icon-date">指标修改日志</span>
</router-link>
</div>
</div>
<div class="analyzer-header-condition" style="align-items: center; padding: 14px 20px">
<!-- <el-button size="mini" type="primary">创建公共指标</el-button> -->
<div class="header-search-box">
<span class="el-icon-search icon"></span>
<input
:readonly="detailShowType == 2"
:style="{cursor: detailShowType == 2?'not-allowed':'auto'}"
@keyup.enter="searchIndex"
v-model="inputedIndex"
type="text"
placeholder="请输入指标名称进行搜索"
/>
</div>
</div>
</div>
<div class="analyzer-content shadow" style="padding-top: 20px">
<!-- <div class="container-inner"> -->
<split-pane class="container-inner" :class="{noLeft: detailShowType !== 1 && detailShowType !== 3}" :min-percent='leftMinWidth' :default-percent='leftWidth' split="vertical">
<template slot="paneL" v-show="detailShowType == 1 || detailShowType == 3">
<div class="split-index-box" v-show="detailShowType == 1 || detailShowType == 3">
<div class="index-box-tab">
<h3 class="active">我的指标</h3>
<!-- <span class="el-icon-edit hover-icon">归档设置</span> -->
</div>
<div style="margin-top: 12px">
<el-radio-group
class="my-radio"
@change="changeIndexType"
v-model="indexFilterType"
size="mini"
>
<el-radio-button :label="0">全部</el-radio-button>
<el-radio-button :label="1">未提交</el-radio-button>
<el-radio-button :label="3">待审核</el-radio-button>
<el-radio-button :label="16">通过</el-radio-button>
<el-radio-button :label="32">未通过</el-radio-button>
</el-radio-group>
</div>
<div style="margin-bottom: 8px; margin-top: 12px">
<span>当前搜索词:</span>
<span>{{searchInputed?searchInputed:''}}</span>
<span
@click="emptySearch"
v-show="searchInputed"
style="margin-left:4px"
class="el-icon-error hover-icon"
></span>
</div>
<div
class="tree-container"
v-loading="treeLoading"
element-loading-text="数据加载中"
element-loading-spinner="el-icon-loading"
>
<el-tree
@node-click="selecteIndex"
:default-expanded-keys="defaultExpandedKeys"
@node-expand="nodeExpand"
@node-collapse="nodeCollapse"
:filter-node-method="filterIndexTreeNode"
ref="publicIndexTree"
node-key="myId"
class="small-tree"
highlight-current
:expand-on-click-node="false"
:data="myTreeData"
:props="treeProps"
>
<span class="custom-tree-node" slot-scope="{ node, data }">
<span class="el-icon-folder" v-show="!data.isIndex"></span>
<span style="font-size: 12px">{{ node.label }}</span>
</span>
</el-tree>
</div>
</div>
</template>
<template slot="paneR">
<!-- 指标详情显示 -->
<div class="index-detail" v-show="detailShowType == 1">
<div class="index-detail-title">
<h3>指标参数</h3>
</div>
<div class="action-list" v-if="activeIndex.isIndex">
<span class="el-icon-odometer icon" @click="openTestRunDialog()">测试运行</span>
<span
class="el-icon-edit icon"
v-show="activeIndexStatus !== 2"
@click="confirmEditIndex()"
>编辑指标</span>
<el-popconfirm title="是否确认撤销提交该指标?" @onConfirm="cancelSubmit">
<span
slot="reference"
class="el-icon-refresh-left icon"
v-show="activeIndexStatus == 2"
>撤销提交</span>
</el-popconfirm>
<span
class="el-icon-s-check icon"
@click="choosePublicCategory()"
v-show="activeIndexStatus == 1 || activeIndexStatus == 32"
>提交审核</span>
<el-popconfirm title="是否确认删除该指标?" @onConfirm="deleteIndex">
<span
slot="reference"
class="el-icon-delete icon"
v-show="activeIndexStatus !== 2"
>删除指标</span>
</el-popconfirm>
</div>
<!-- 有指标的时候显示 -->
<div class="detail-container" v-if="activeIndex.isIndex" v-loading="loadingDetail">
<div class="detail-index">
<div class="title">指标名称:</div>
<div class="detail">{{activeIndex.IndexName}}</div>
</div>
<div class="detail-index">
<div class="title">指标状态:</div>
<div class="detail">{{reviewObj[activeIndex.CurrentWorkflow]}}</div>
</div>
<div class="detail-index">
<div class="title">最后编辑:</div>
<div class="detail">{{activeIndex.LastUpdate}}</div>
</div>
<div class="detail-index">
<div class="title">指标类型:</div>
<div class="detail">{{getDataType(activeIndex)}}</div>
</div>
<div class="detail-index">
<div class="title">指标参数:</div>
<div class="detail">{{getIndexArgsType(activeIndex.Args)}}</div>
</div>
<div class="detail-index">
<div class="title">指标单位:</div>
<div class="detail">{{activeIndex.IndexUnit?activeIndex.IndexUnit:'-'}}</div>
</div>
<div class="detail-index">
<div class="title">指标所属分类:</div>
<div class="detail">{{formatIndexFrom(activeIndex.from)}}</div>
</div>
<div class="detail-index">
<div class="title">指标百科:</div>
<div class="detail">
<div class="sub-detail">
<span>{{activeIndex.Wiki}}</span>
</div>
</div>
</div>
<div class="detail-index">
<div class="title">指标算法:</div>
<div class="detail">
<div class="calculater-box" id="conditionBox" v-html="activeIndexCondition.showDom"></div>
</div>
</div>
<div class="detail-index">
<div class="title">模型绑定:</div>
<div class="detail">
<div class="model-list" v-for="(item, index) in modelData" :key="item.ModelId">
<div class="model-name">{{item.ShortName}}</div>
<div class="model-check-list">
<el-checkbox
disabled
:indeterminate="item.keywordCheck.isIndeterminate"
v-model="item.keywordCheck.checkAll"
@change="handleCheckAllChange($event,item.keywordCheck)"
>关键词(全选)</el-checkbox>
<el-checkbox-group
disabled
v-model="item.keywordCheck.checkedItems"
@change="handleCheckedResults($event,item.keywordCheck)"
>
<el-checkbox
v-for="keyword in item.Keywords"
:value="keyword.ModelKeywordId"
:label="keyword.ModelKeywordId"
:key="keyword.ModelKeywordId"
>{{getKeyword(keyword)}}</el-checkbox>
</el-checkbox-group>
</div>
<div class="model-check-list">
<el-checkbox
disabled
:indeterminate="item.nameCheck.isIndeterminate"
v-model="item.nameCheck.checkAll"
@change="handleCheckAllChange($event,item.nameCheck)"
>维度替换词(全选)</el-checkbox>
<el-checkbox-group
disabled
v-model="item.nameCheck.checkedItems"
@change="handleCheckedResults($event, item.nameCheck)"
>
<el-checkbox
v-for="name in item.DimensionNames"
:value="name.ModelDimensionId"
:label="name.ModelDimensionId"
:key="name.ModelDimensionId"
>{{name.Name}}</el-checkbox>
</el-checkbox-group>
</div>
</div>
</div>
</div>
<!-- <div class="detail-index" style="align-items: flex-start">
<div class="title">指标分解:</div>
<div class="detail">
<div class="model-list">
<div ref="chart" style="width: 400px; height: 160px; margin: 0 auto"></div>
</div>
</div>
</div> -->
</div>
<!-- 未选中指标的显示 -->
<div class="detail-container" v-if="!activeIndex.isIndex">
<div class="empty-status">
<img src="../../static/image/empty.png" alt />
<div class="empty-tip">请从左侧点击指标或者分类</div>
</div>
</div>
</div>
<!-- 指标编辑显示 -->
<div class="index-detail index-edit" v-if="detailShowType == 2">
<div class="index-detail-title">
<h3 style="flex: auto" v-show="addIndexType == 'edit'">指标编辑 - {{activeIndex.IndexName}}</h3>
<h3 style="flex: auto" v-show="addIndexType == 'add'">新增指标</h3>
<el-popconfirm @onConfirm="backToDetail" title="指标正在编辑中,确认返回?">
<el-button slot="reference" size="mini" icon="el-icon-back">返回</el-button>
</el-popconfirm>
</div>
<div class="detail-container">
<div class="detail-index">
<div class="title">指标名称:</div>
<div class="detail">
<el-input
v-model="editIndexName"
size="mini"
style="width: 300px"
placeholder="请输入指标名称"
></el-input>
</div>
</div>
<div class="detail-index">
<div class="title">指标类型:</div>
<div class="detail">
<el-radio-group v-model="editIndexFormat">
<el-radio :label="0">字符</el-radio>
<el-radio :label="1">日期</el-radio>
<el-radio :label="2">数字</el-radio>
</el-radio-group>
</div>
</div>
<div class="detail-index">
<div class="title">指标参数:</div>
<div class="detail">
<el-checkbox-group v-model="editIndexParams">
<el-checkbox
:key="item.Id"
:label="item.Id"
v-for="item in defaultTypeList"
>{{item.Name}}</el-checkbox>
</el-checkbox-group>
</div>
</div>
<div class="detail-index">
<div class="title">指标单位:</div>
<div class="detail">
<el-input
size="mini"
v-model="editIndexUnit"
style="width: 300px"
placeholder="请输入指标单位(如:元,万元,亿,%等)"
></el-input>
</div>
</div>
<div class="detail-index">
<div class="title">所属分类:</div>
<div class="detail">
<el-cascader
:props="cascaderProps"
size="mini"
style="width: 300px"
v-model="editIndexClassify"
:options="cascaderOptions"
></el-cascader>
</div>
</div>
<div class="detail-index" style="align-items: flex-start">
<div class="title">指标算法:</div>
<div class="detail">
<calculater :treeData="treeData" ref="calculater" type="index" :parentLevel="3" />
</div>
</div>
<div class="detail-index">
<div class="title">模型绑定:</div>
<div class="detail">
<div class="model-list" v-for="(item, index) in modelData" :key="item.ModelId">
<div class="model-name">{{item.ShortName}}</div>
<div class="model-check-list">
<el-checkbox
:indeterminate="item.keywordCheck.isIndeterminate"
v-model="item.keywordCheck.checkAll"
@change="handleCheckAllChange($event,item.keywordCheck)"
>关键词(全选)</el-checkbox>
<el-checkbox-group
v-model="item.keywordCheck.checkedItems"
@change="handleCheckedResults($event,item.keywordCheck)"
>
<el-checkbox
v-for="keyword in item.Keywords"
:value="keyword.ModelKeywordId"
:label="keyword.ModelKeywordId"
:key="keyword.ModelKeywordId"
>{{getKeyword(keyword)}}</el-checkbox>
</el-checkbox-group>
</div>
<div class="model-check-list">
<el-checkbox
:indeterminate="item.nameCheck.isIndeterminate"
v-model="item.nameCheck.checkAll"
@change="handleCheckAllChange($event,item.nameCheck)"
>维度替换词(全选)</el-checkbox>
<el-checkbox-group
v-model="item.nameCheck.checkedItems"
@change="handleCheckedResults($event, item.nameCheck)"
>
<el-checkbox
v-for="name in item.DimensionNames"
:value="name.ModelDimensionId"
:label="name.ModelDimensionId"
:key="name.ModelDimensionId"
>{{name.Name}}</el-checkbox>
</el-checkbox-group>
</div>
</div>
</div>
</div>
<div class="detail-index" style="align-items: flex-start">
<div class="title">指标百科:</div>
<div class="detail">
<el-input
style="max-width: 600px"
type="textarea"
:rows="6"
placeholder="请输入内容"
v-model="editIndexDetail"
></el-input>
</div>
</div>
<!-- <div class="detail-index" style="align-items: flex-start">
<div class="title">指标分解:</div>
<div class="detail">
<div class="model-list">
<div ref="chart1" style="width: 400px; height: 160px; margin: 0 auto"></div>
</div>
<div class="model-list" style="text-align: left">
<div style="margin-bottom: 8px" class="gray">分解指标</div>
<span class="index-resolution-list">
<span>销售净利率</span>
<span class="el-icon-delete icon"></span>
</span>
<span class="index-resolution-list">
<span>资产周转率</span>
<span class="el-icon-delete icon"></span>
</span>
<span class="index-resolution-list">
<span>权益乘数</span>
<span class="el-icon-delete icon"></span>
</span>
<span class="index-resolution-list">
<span class="el-icon-circle-plus-outline icon"></span>
</span>
</div>
</div>
</div> -->
<div class="detail-index">
<div class="title">操作:</div>
<div class="detail">
<el-popconfirm @onConfirm="backToDetail" title="指标正在编辑中,确认取消?">
<el-button slot="reference" size="mini">取消</el-button>
</el-popconfirm>
<el-button
size="mini"
:loading="addOrEditIndexLoading"
type="primary"
@click="addOrChangeIndex"
>确认</el-button>
</div>
</div>
</div>
</div>
<!-- 指标文件夹显示 -->
<div class="index-detail index-edit" v-if="detailShowType == 3">
<div class="index-detail-title">
<h3 style="flex: auto">分类编辑 - 我的分类</h3>
</div>
<div class="detail-container">
<div class="detail-index">
<div class="title" style="text-align: left; color: #999">分类名称:</div>
<div class="detail">{{activeIndex.Name}}</div>
</div>
<div class="detail-index">
<div class="title" style="text-align: left; color: #999">分类路径:</div>
<div class="detail">{{formatIndexFrom(activeIndex.from)}}</div>
</div>
<div class="detail-index">
<div class="title" style="text-align: left; color: #999">操作:</div>
<div class="detail">
<el-button size="mini" @click="openChangeCategory()">修改名称</el-button>
<el-button size="mini" @click="openAddCategory()">新建分类</el-button>
<el-button size="mini" @click="openAddNewIndex">新增指标</el-button>
<el-popconfirm
style="margin-left: 8px"
@onConfirm="deleteCategory"
title="确定删除该分类吗?"
>
<el-button
type="primary"
slot="reference"
size="mini"
:loading="deleteCategoryLoading"
v-show="!activeIndex.Required"
>删除分类</el-button>
</el-popconfirm>
</div>
</div>
</div>
</div>
</template>
</split-pane>
<!-- </div> -->
</div>
<el-dialog title="编辑指标百科" :visible.sync="editMemoryVisible" width="720px">
<div>
<el-input
type="textarea"
:close-on-click-modal="false"
:close-on-press-escape="false"
:autosize="{ minRows: 4, maxRows: 8}"
placeholder="请输入指标百科"
v-model="editingMemoryInput"
></el-input>
</div>
<span slot="footer" class="dialog-footer">
<el-button size="mini" @click="editMemoryVisible = false">取消</el-button>
<el-button size="mini" type="primary" @click="confirmAddMemo">确认</el-button>
</span>
</el-dialog>
<el-dialog
title="方法参数"
@close="closeEditFuction"
:visible.sync="editFuctionVisible"
width="900px"
>
<div>
<calculater ref="functionCalculater" :treeData="treeData" type="function" />
</div>
<span slot="footer" class="dialog-footer">
<el-button size="mini" @click="editFuctionVisible = false">取消</el-button>
<el-button size="mini" type="primary" @click="confirmAddFunction">确认</el-button>
</span>
</el-dialog>
<el-dialog
:title="addOrEditCategoryTitle"
:visible.sync="addOrEditCategoryVisible"
width="360px"
>
<div>
<el-input placeholder="请输入分类名称" size="small" v-model="inputedCategoryName"></el-input>
</div>
<span slot="footer" class="dialog-footer">
<el-button size="mini" @click="addOrEditCategoryVisible = false">取消</el-button>
<el-button
size="mini"
type="primary"
@click="createOrChangeCategory"
:loading="createOrChangeCategoryLoading"
>确认</el-button>
</span>
</el-dialog>
<el-dialog
title="测试运行指标"
:close-on-press-escape="false"
:close-on-click-modal="false"
:visible.sync="testRunVisible"
width="800px"
>
<div class="test-run-box">
<div class="detail-index">
<div class="title">当前指标:</div>
<div class="detail">
<span>{{activeIndex.IndexName}}</span>
</div>
</div>
<condition
style="padding: 20px 0"
ref="conditionChoose"
:params="activeIndex.Args"
:allParams="defaultTypeList"
/>
<div class="detail-index" style="align-items: flex-start">
<div class="title">标的选择:</div>
<div class="detail" style="color: #333">
<div style="margin-bottom: 20px">
<el-checkbox
class="mini"
:indeterminate="companyStatusCheck.isIndeterminate"
v-model="companyStatusCheck.checkAll"
@change="handleCheckAllChange($event, companyStatusCheck)"
>全选</el-checkbox>
<el-checkbox-group
class="mini"
v-model="companyStatusCheck.checkedItems"
@change="handleCheckedResults($event, companyStatusCheck)"
>
<el-checkbox
v-for="item in companyStatusData"
:value="item['F90063V']"
:label="item['F90063V']"
:key="item['F90063V']"
>{{item['F90064V']}}</el-checkbox>
</el-checkbox-group>
</div>
<div class="flex-form-cintent">
<div class="flex-form-detail no-bg">
<el-tabs
v-model="activeRangeTab"
class="mini-size"
style="margin-bottom: 12px"
type="card"
>
<el-tab-pane label="单个添加" :name="'3'">
<div>
<el-select
v-model="rangeCompany"
filterable
remote
@change="addRangeCompany"
placeholder="请输入名称或代码"
:remote-method="searchRunningCompany"
:loading="searchCompanyLoading"
size="mini"
>
<el-option
v-for="item in runningCompanyList"
:key="item.F90001V"
:label="item.F90002V + ' ' + item.F90001V"
:value="item.F90002V + ',' + item.F90001V"
></el-option>
</el-select>
</div>
</el-tab-pane>
<el-tab-pane label="excel导入" :name="'6'">
<div
style="padding-bottom: 8px; color: #999; font-size: 12px"
>excel格式:表为两列, 表头必须为字符"name"、"code", 表身对应为证券简称、证券代码</div>
<div>
<input type="file" @change="selectedExcel" />
</div>
<div style="padding-top: 12px">
<span style="color: #d0021b; font-size: 12px; cursor: pointer" @click="downloadExample">下载示例表格</span>
</div>
</el-tab-pane>
<!-- <el-tab-pane label="证监会行业" :name="'1'">
<div class="mini-size industry-tree-box">
<el-tree
:indent="8"
accordion
:expand-on-click-node="false"
@node-click="searchCompanyByIndustry($event, 1)"
:data="zjhIndustryData"
node-key="id"
ref="zjhCategory"
highlight-current
></el-tree>
</div>
</el-tab-pane> -->
<el-tab-pane label="行业分类" :name="'2'">
<div class="mini-size industry-tree-box">
<el-tree
:indent="8"
accordion
:expand-on-click-node="false"
@node-click="searchCompanyByIndustry($event, 1)"
:data="zjhIndustryData"
node-key="id"
ref="zjhCategory"
></el-tree>
<el-tree
:indent="8"
accordion
:expand-on-click-node="false"
@node-click="searchCompanyByIndustry($event, 2)"
:data="swIndustryData"
node-key="id"
ref="swCategory"
></el-tree>
</div>
</el-tab-pane>
<el-tab-pane label="市场分类" :name="'5'">
<div class="mini-size industry-tree-box">
<el-tree
:indent="8"
accordion
:data="marketData"
highlight-current
ref="marketCategory"
:expand-on-click-node="false"
@node-click="searchCompanyByIndustry($event, 3)"
></el-tree>
</div>
</el-tab-pane>
<el-tab-pane label="地域分类" :name="'4'">
<div class="mini-size industry-tree-box">
<el-tree
:indent="8"
accordion
:data="positionData"
highlight-current
ref="posCategory"
:expand-on-click-node="false"
@node-click="searchCompanyByIndustry($event, 4)"
></el-tree>
</div>
</el-tab-pane>
</el-tabs>
<el-table
@sort-change="changeSort"
size="mini"
max-height="300"
v-loading="searchCompanyLoading"
:data="selectedRangeCompany"
:header-cell-style="{background:'#f5f7fa',color:'#666'}"
border
>
<el-table-column width="50" type="index" label="序号"></el-table-column>
<el-table-column width="80" label="证券名称">
<template slot-scope="scope">{{scope.row.name}}</template>
</el-table-column>
<el-table-column width="80" label="证券代码">
<template slot-scope="scope">{{scope.row.code}}</template>
</el-table-column>
<el-table-column prop="result" sortable label="运行结果">
<template slot-scope="scope">{{scope.row.result}}</template>
</el-table-column>
<el-table-column width="80" label="操作">
<template slot-scope="scope">
<span
class="hover-icon el-icon-delete"
@click="selectedRangeCompany.splice(scope.$index, 1)"
>删除</span>
</template>
</el-table-column>
</el-table>
<div style="font-size: 12px; margin-top: 8px; color: #d0021b">
<span
class="el-icon-refresh-right"
style="cursor: pointer"
@click="selectedRangeCompany = []"
>清空表格</span>
<span
class="el-icon-upload2"
style="cursor: pointer; margin-left: 12px"
@click="exportExcel"
>导出excel</span>
</div>
</div>
</div>
</div>
</div>
<div class="detail-index">
<div class="title">操作:</div>
<div class="detail">
<el-button type="primary" size="mini" @click="testRunIndex">点击运行</el-button>
</div>
</div>
</div>
</el-dialog>
<el-dialog title="选择指标分类" :visible.sync="submitCategoryVisible" width="500px">
<div class="detail-index">
<!-- <div class="title" style="text-align: left; color: #999; min-width: 80px">相似公共指标:</div>
<div class="detail">
</div>-->
</div>
<div class="detail-index">
<div class="title" style="text-align: left; color: #999; min-width: 80px">建议分类:</div>
<div class="detail">
<el-cascader
:props="publicProps"
v-model="submitCategory"
size="mini"
style="width: 300px"
:options="publicCategoryOptions"
></el-cascader>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button size="mini" @click="submitCategoryVisible = false">取消</el-button>
<el-button size="mini" type="primary" @click="confirmSubmit()" :loading="submitLoading">确认</el-button>
</span>
</el-dialog>
</div>
</template>
\ No newline at end of file
const http = require('../../../lib/axios/axios.js')
const { dialog } = require('electron').remote
const officegen = require('officegen')
const path = require('path');
const fs = require('fs')
const filePath = path.resolve(__dirname, './publicIndex.vue')
let newTemplate = ''
var data = fs.readFileSync(filePath);
var str = data.toString()
var newStr = str.substring(0, str.lastIndexOf('</template>'))
newTemplate = newStr.replace('<template>', '')
// const calculater = require('../components/calculater')
const calculater = require('../../../components/complexCondition/index')
var keyBord = require('../../lib/keyBord')
var tools = require('../../lib/tools.js')
const { ipcRenderer } = require('electron')
const condition = require('../../components/condition/index.js')
module.exports = {
publicIndex: {
data: function () {
return {
treeData: [],
myTreeData: [],
treeProps: {
children: 'children',
label: 'Name'
},
treeLoading: false,
editingText: '',
showTextEditing: false,
editIndexVisible: true,
editIndex: {
params: []
},
cascaderOptions: [],
cascaderProps: {
value: 'Code',
label: 'Name',
checkStrictly: true,
multiple: true
},
cascaderCopyProps: {
value: 'Code',
label: 'Name',
checkStrictly: true,
multiple: true
},
publicProps: {
value: 'Code',
label: 'Name',
checkStrictly: true
},
inputedIndex: '',
activeIndex: {},
indexTypeDic: {
},
editMemoryVisible: false,
editingMemoryInput: '',
editFuctionVisible: false,
detailShowType: 1, //1指标详情 2指标编辑 3文件夹操作,
addOrEditCategoryVisible: false,
addOrEditCategoryTitle: '新增分类',
inputedCategoryName: '',
createOrChangeCategoryLoading: false,
editIndexName: "",
editIndexFormat: 2,
editIndexParams: [],
editIndexUnit: "",
editIndexClassify: [],
editIndexCalaulate: {},
editIndexDetail: '',
// editIndexAccuracy: 2,
editFuctionType: [],
initIndex: 1,
deleteCategoryLoading: false,
defaultCategoryId: 0,
addIndexType: 'add',
defaultTypeList: [],
addCategoryType: 'add',
categoryDic: {},
initIndexObj: {},
companyNameObj: {},
addOrEditIndexLoading: false,
activeIndexCondition: {
indexParams: {},
dateParams: {},
numParams: {},
symbolParams: {},
functionParams: {},
dom: '',
showDom: ''
},
keyboardObj: {},
searchInputed: '',
reviewObj: {
1: '未提交',
2: '待审核',
16: '审核通过',
32: '审核不通过'
// 1.待提交,2.待审核,4.待审核,修改了指标,8.待审核,修改了百科,16.审核通过,32.审核不通过
},
submitLoading: false,
indexFilterType: 0,
deleteIndexLoading: false,
testRunVisible: false,
//测试运行相关
testYear: '',
testQuarter: '',
testMergeType: '合并本期',
activeRangeTab: '3',
rangeCompany: '',
searchCompanyLoading: false,
runningCompanyList: [],
selectedRangeCompany: [],
zjhIndustryData: [],
swIndustryData: [],
marketData:[],
positionData: [],
industryObj: {},
modelData: [],
submitCategoryVisible: false,
submitCategory: [],
publicCategoryOptions: [],
activeIndexStatus: 0,
hasPermission: false,
editTip: '编辑完成后需要提交审核,是否继续编辑?',
editConfirmText: '提交审核',
editWikiText: '提交审核',
editIndexRemark: '',
editWikiVisible: false,
editWiki: '',
changeWikiLoading: false,
defaultExpandedKeys: [],
sortType: null,
copyIndexVisible: false,
copyCategory: [],
copyLoading: false,
changePositionVisible: false,
changePositionMemo: '',
copyIndexMemo: '',
copyTreeData: [],
sortLoading: false,
copyConditionHtml: null,
companyStatusData: [],
companyStatusCheck: {
isIndeterminate: false,
checkAll: false,
checkedItems: ['013001'],
options: []
},
systemTreeProps: {
children: 'Sub',
label: 'Name'
},
systemTreeData: [],
selectedChangeIndexs: [],
overingKey: 0,
selectIndexKey: [],
loadingDetail: false,
leftWidth: 25,
leftMinWidth: 20,
isDotEdit: false,
isDotSort: false,
IntervalId: 0,
indexPermission: false
}
},
components: {
calculater, condition
},
watch: {
detailShowType (val) {
if (val == 1 || val == 3){
this.leftMinWidth = 20
this.leftWidth = 25
}else{
this.leftMinWidth = 0
this.leftWidth = 0
}
}
},
computed: {
},
template: newTemplate,
mounted() {
var that = this
ipcRenderer.on('copy-multiple-condition-reply', function (event, arg) {
that.copyConditionHtml = arg
})
this.checkPermission(48, 'indexPermission')
this.getIndexs().then(res => {
this.getIndexCateGory()
this.getDefaultType()
tools.getKeyboardObj(keyBord, this.keyboardObj)
})
this.getZjhIndustryCategoryList()
this.getSwIndustryCategoryList()
this.getPositionData()
this.getMarketData()
this.getPublicCategory()
this.getModelList()
this.checkPermission(48)
this.getCompanyStatusData()
this.getBadge(1, 'isDotEdit')
this.getBadge(2, 'isDotSort')
this.IntervalId = setInterval(() => {
this.getBadge(1, 'isDotEdit')
this.getBadge(2, 'isDotSort')
}, 30000);
},
beforeDestroy(){
clearInterval(this.IntervalId)
},
methods: {
changeTreeProps (type) {
this.$set(this.systemTreeProps, 'label', type)
this.$set(this.treeProps, 'label', type)
},
checkPermission (id, key) {
return new Promise((resolve, reject) => {
http.netPost('Account/Account/CheckPermission', {
"id": id,
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
if(res.data.Data == 1){
this[key] = true
}
resolve()
}
})
})
},
getCompanyStatusData () {
return new Promise((resolve, reject) => {
http.netPost('Data/Query/Query', {
"List": [
"F90063V",
"F90064V"
],
"Where": [],
"WhereOr": [],
"WhereOrArrayAnd": [],
"Sort": [{
"Encode":"F90063V",
"State":1
}],
"GPBField": ["F90063V"],
"Current": 0,
"Psize": 100,
"JoinTableWay": 0
})
.then((res) => {
if (res.data.Status == 1) {
this.companyStatusData = []
res.data.Data.Records.forEach(item => {
if(item["F90063V"]){
this.companyStatusData.push(item)
this.companyStatusCheck.options.push(item["F90063V"])
}
})
}
})
})
},
closeSideModal () {
this.changePositionVisible = false
},
changePosition () {
this.copyTreeData = JSON.parse(JSON.stringify(this.myTreeData))
this.changePositionVisible = true
this.selectIndexKey = []
},
pushDataByLeaf(leafId, nodes) {
for (var i = 0; i < nodes.length; i++) {
if (leafId == nodes[i].Code) {
if(!nodes[i].children){
nodes[i].children = []
}
this.activeIndex.Code = this.activeIndex.Encode
nodes[i].children.push(JSON.parse(JSON.stringify(this.activeIndex)))
return
}
if (nodes[i].children) {
var findResult = this.pushDataByLeaf(leafId, nodes[i].children);
if (findResult) {
return findResult
}
}
}
},
submitCopyChange () {
this.copyLoading = true
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/SortPublicIndex', {
"sortedPublicIndex": this.confirmCopy(),
"remark": this.copyIndexMemo,
"accountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
this.$message({
message: "提交审核成功",
type: "success"
})
this.copyIndexVisible = false
resolve()
}
this.copyLoading = false
})
})
},
submitSortChange () {
this.sortLoading = true
var submitArr = []
console.log(this.copyTreeData)
this.formatIndexCategory(submitArr, this.copyTreeData)
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/SortPublicIndex', {
"sortedPublicIndex": submitArr,
"remark": this.changePositionMemo,
"accountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
this.$message({
message: "提交审核成功",
type: "success"
})
this.changePositionVisible = false
resolve()
}
this.sortLoading = false
})
})
},
confirmCopy () {
var copyArr = JSON.parse(JSON.stringify(this.myTreeData))
this.copyCategory.forEach(item => {
var id = item[item.length - 1]
this.pushDataByLeaf(id, copyArr)
})
var submitArr = []
console.log(copyArr)
this.formatIndexCategory(submitArr, copyArr)
return submitArr
},
formatIndexCategory (newArr, arr) {
for (var i = 0; i < arr.length; i++) {
newArr.push({
"code": arr[i].DataType == 'T'?arr[i].Code:arr[i].Code,
"dataType": arr[i].DataType,
"children": []
})
if (arr[i].children) {
this.formatIndexCategory(newArr[i].children, arr[i].children);
}
}
},
copyIndexToCatrgory () {
this.copyIndexVisible = true
},
changeSort (res) {
this.sortType = res.order
},
compare (prop, type) {
return function (obj1, obj2) {
var val1 = parseFloat(obj1[prop])
var val2 = parseFloat(obj2[prop])
if (val1 < val2) {
return type == 'ascending'?-1:1;
} else if (val1 > val2) {
return type == 'ascending'?1:-1;
} else {
return 0;
}
}
},
exportExcel () {
var that = this
var excelName = new Date().getTime()
var xlsx = officegen('xlsx')
var filePath = dialog.showSaveDialog({
defaultPath: excelName + '.xlsx',
title: '保存',
buttonLabel: '保存'
})
xlsx.on('finalize', function(written) {
that.$message({
message: '表格导出成功!',
type: 'success'
})
})
xlsx.on('error', function(err) {
console.log(err)
})
var sheet = xlsx.makeNewSheet()
sheet.name = 'sheet'
sheet.orientation = 'landscape'
sheet.data[0] = []
sheet.data[0][0] = '序号'
sheet.data[0][1] = '证券简称'
sheet.data[0][2] = '证券代码'
sheet.data[0][3] = this.activeIndex.IndexName
var newArr = JSON.parse(JSON.stringify(this.selectedRangeCompany))
if(this.sortType == 'descending'){
newArr.sort(that.compare('result', 'descending'))
}else if(this.sortType == 'ascending'){
newArr.sort(that.compare('result', 'ascending'))
}
newArr.forEach((item, index)=>{
sheet.data[index + 1] = []
sheet.data[index + 1][0] = index+1
sheet.data[index + 1][1] = item['name']
sheet.data[index + 1][2] = item['code']
sheet.data[index + 1][3] = item['result']
})
var out = fs.createWriteStream(filePath)
out.on('error', function(err) {
console.log(err)
})
xlsx.generate(out)
},
copyIndex () {
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/CopyPublicToMyCustomIndex', {
"id": this.activeIndex.Id,
"accountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
this.$message({
message: "复制成功,指标已存入个人指标库根目录",
type: "success"
})
resolve()
}
})
})
},
openWikiDialog () {
this.editWiki = this.activeIndex.Wiki
this.editWikiVisible = true
},
confirmChangeWiki () {
this.changeWikiLoading = true
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/EditPublicIndexWiki', {
"id": this.activeIndex.Id,
"wiki": this.editWiki,
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
this.$message({
message: "操作成功",
type: "success"
})
this.activeIndex = {}
this.getIndexCateGory()
this.editWikiVisible = false
resolve()
}
this.changeWikiLoading = false
})
})
},
checkPermission (id) {
return new Promise((resolve, reject) => {
http.netPost('Account/Account/CheckPermission', {
"id": id,
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
if(res.data.Data == 1){
this.hasPermission = true
this.editTip = "编辑完成后需要提交审核,是否继续编辑?"
this.editConfirmText = "提交审核"
this.editWikiText = "确认修改"
}
resolve()
}
})
})
},
cancelSubmit () {
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/UnSubmitIndex', {
"id": this.activeIndex.PublicIndexId,
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
this.$message({
message: "撤销提交成功",
type: "success"
})
this.activeIndex = {}
this.getIndexCateGory()
resolve()
}
})
})
},
getKeyword (keyword) {
var name = keyword.Name
var arr = []
keyword.Keywords.forEach(item => {
arr.push(item.Name)
})
name = name + '(' + arr.join(',') + ')'
return name
},
handleCheckAllChange(val, obj) {
obj.checkedItems = val ? obj.options : []
obj.isIndeterminate = false
},
handleCheckedResults(value, obj) {
let checkedCount = value.length
obj.checkAll = checkedCount === obj.options.length
obj.isIndeterminate = checkedCount > 0 && checkedCount < obj.options.length
},
getModelList () {
return new Promise((resolve, reject) => {
http.netPost('Module/Basic/GetModelList', {})
.then((res) => {
if (res.data.Status == 1) {
this.modelData = []
res.data.Data.Records.forEach(item => {
var keywordOptions = [], nameOptions = []
item.Keywords.forEach(sub => {
keywordOptions.push(sub.ModelKeywordId)
})
item.DimensionNames.forEach(sub => {
nameOptions.push(sub.ModelDimensionId)
})
item.keywordCheck = {
checkAll: false,
checkedItems: [],
isIndeterminate: false,
options: keywordOptions
}
item.nameCheck = {
checkAll: false,
checkedItems: [],
isIndeterminate: false,
options: nameOptions
}
this.modelData.push(item)
})
resolve()
}
})
})
},
getPublicCategory () {
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/GetPublicArchive', {})
.then((res) => {
if (res.data.Status == 1) {
this.publicCategoryOptions = res.data.Data
resolve()
}
})
})
},
testRunIndex () {
//判断条件
var args = []
var ref = this.$refs.conditionChoose
if(!ref.testMergeType || !ref.testYear || !ref.testQuarter || this.selectedRangeCompany.length == 0){
this.$message({
message: '参数不完整或标的为空',
type: 'error'
})
return false
}
this.selectedRangeCompany.forEach(item => {
args.push({
stockCode: item.code,
argType: 1
})
})
args.push({
mergeType: ref.testMergeType,
argType: 2
},{
reportingPeriod: ref.testYear + '-' +ref.testQuarter,
argType: 4
})
this.searchCompanyLoading = true
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/TestRunPublicCustomIndex', {
args: args,
"id": this.activeIndex.Id,
"runVersion": 2
})
.then((res) => {
if (res.data.Status == 1) {
this.selectedRangeCompany.forEach(item => {
if(res.data.Data[item.code] !== "NaN"){
item.result = res.data.Data[item.code]
}else{
item.result = '分母为0'
}
})
resolve()
}
this.searchCompanyLoading = false
})
})
},
openTestRunDialog () {
this.testRunVisible = true
},
//处理证监会行业数据
handleZjhData(data) {
var newObj = {}
var newArray = []
data.map((item) => {
if (!newObj[item.F90014V]) {
newObj[item.F90014V] = item
newArray.push({
label: item.F90012V,
id: item.F90014V,
code: 'F90014V',
from: '证监会' + '-' + item.F90012V,
labelCode: 'F90012V',
searchCode: 'F90012V',
})
this.industryObj[item.F90014V] = '证监会' + '-' + item.F90012V
}
})
newArray.map((chid) => {
chid.children = []
data.map((item, index) => {
if (chid.id == item.F90014V) {
chid.children.push({
label: item.F90013V,
id: item.F90015V,
code: 'F90015V',
labelCode: 'F90013V',
from: chid.from + '-' + item.F90013V,
searchCode: 'F90013V'
})
this.industryObj[item.F90015V] = chid.from + '-' + item.F90013V
}
})
})
this.zjhIndustryData = [
{
label: '证监会行业',
id: 0,
code: '0',
labelCode: '0',
from: '',
searchCode: '0',
children: newArray
}
]
},
handleSwData(data) {
var parentObj = {}
var parentArray = []
var childObj = {}
var childArray = []
data.map((item) => {
if (!parentObj[item.F90016V]) {
parentObj[item.F90016V] = item
parentArray.push({
label: item.F90017V,
id: item.F90016V,
code: 'F90017V',
from: '申万' + '-' + item.F90017V,
searchCode: 'F90017V'
})
this.industryObj[item.F90016V] = '申万' + '-' + item.F90017V
}
if (!childObj[item.F90018V]) {
childObj[item.F90018V] = item
childArray.push({
label: item.F90019V,
id: item.F90018V,
parentId: item.F90016V,
code: 'F90019V',
from: '申万' + '-' + item.F90017V + '-' + item.F90019V,
searchCode: 'F90019V'
})
this.industryObj[item.F90018V] = '申万' + '-' + item.F90017V + '-' + item.F90019V
}
})
childArray.map((chid) => {
chid.children = []
data.map((item) => {
if (chid.id == item.F90018V) {
chid.children.push({
label: item.F90021V,
id: item.F90020V,
code: 'F90021V',
from: chid.from + '-' + item.F90021V,
searchCode: 'F90021V'
})
this.industryObj[item.F90020V] = chid.from + '-' + item.F90021V
}
})
})
parentArray.map((sub) => {
sub.children = []
childArray.map((item) => {
if (sub.id == item.parentId) {
sub.children.push(item)
}
})
})
this.swIndustryData = [
{
label: '申万行业',
id: 0,
code: '0',
from: '',
searchCode: '0',
children: parentArray
}
]
},
getZjhIndustryCategoryList() {
return new Promise((resolve, reject) => {
http.netPost('Data/Query/Query', {
"List": [
"F90013V",
"F90012V",
"F90014V",
"F90015V"
],
"Where": [],
"GPBField": ["F90015V"],
"Current": 0,
"Psize": 10000
})
.then((res) => {
if (res.data.Status == 1) {
this.handleZjhData(res.data.Data.Records)
}
})
})
},
getSwIndustryCategoryList() {
return new Promise((resolve, reject) => {
http.netPost('Data/Query/Query', {
"List": [
"F90016V",
"F90017V",
"F90018V",
"F90019V",
"F90020V",
"F90021V"
],
"Where": [],
"GPBField": ["F90020V"],
"Current": 0,
"Psize": 10000
})
.then((res) => {
if (res.data.Status == 1) {
this.handleSwData(res.data.Data.Records)
}
})
})
},
// 获取市场信息
getMarketData() {
http.netPost('Data/Query/Query', {
"List": [
"F90005V",
"F90006V"
],
"Where": [],
"WhereOr": [],
"GPBField": [
"F90005V"
],
"Current": 0,
"Psize": 999
}).then((res) => {
this.marketData = res.data.Data.Records
this.marketData.forEach(item => {
item.label = item.F90006V,
item.searchCode = 'F90006V'
})
})
},
getPositionData() {
return new Promise((resolve, reject) => {
http.netPost('Data/Query/Query', {
"List": [
"F90010V",
"F90011V"
],
"Where": [],
"WhereOr": [],
"GPBField": [
"F90010V",
"F90011V"
],
"Current": 0,
"Psize": 999
}).then((res) => {
if (res.data.Status == 1) {
var parentObj = {}
var newArray = res.data.Data.Records
newArray.forEach(item => {
if (!parentObj[item.F90010V]) {
parentObj[item.F90010V] = {
id: item.F90010V,
label: item.F90010V,
code: 'F90010V',
children: [],
searchCode: 'F90010V',
}
parentObj[item.F90010V].children.push({
id: item.F90011V,
label: item.F90011V,
code: 'F90011V',
searchCode: 'F90011V'
})
} else {
parentObj[item.F90010V].children.push({
id: item.F90011V,
label: item.F90011V,
code: 'F90011V',
searchCode: 'F90011V'
})
}
})
this.positionData = []
for (var key in parentObj) {
if (key !== 'null') {
this.positionData.push(parentObj[key])
}
}
}
})
})
},
searchCompanyByIndustry(item, type) {
this.searchCompanyLoading = true
var Where = []
var checkeds = this.companyStatusCheck.checkedItems
if(type == 1 || type == 2 || type == 4 || type == 3){
Where.push({
"Encode": item.searchCode,
"State": 1,
"Value": item.label,
})
if(checkeds.length > 0){
Where.push({
"Encode": "F90063V",
"State": checkeds.length == 1?1:8,
"Value": checkeds.length == 1?checkeds[0]:checkeds
})
}
}
this.initIndex++
var params = {
content: {
"List": ['F90001V', 'F90002V'],
"Where": Where,
"Current": 0,
"Psize": 10000
}
}
return new Promise((resolve, reject) => {
var companyObj = {}
this.selectedRangeCompany.forEach(item => {
if(!companyObj[item.F90001V]){
companyObj[item.F90001V] = item.F90001V
}
})
http.netPost('Data/Query/Query', params.content)
.then((res) => {
if (res.data.Status == 1) {
var arr = []
res.data.Data.Records.map((child) => {
if(!companyObj[child.F90001V]){
arr.push({
name: child.F90002V,
code: child.F90001V
})
}
})
this.addAndRemoveCompany(arr)
}
this.searchCompanyLoading = false
})
})
},
//测试运行的一些方法开始
addRangeCompany(item) {
var code = item.split(',')[1]
var obj = {
name: item.split(',')[0],
code: code,
}
// this.selectedRangeCompany.push([])
this.addAndRemoveCompany([obj])
this.rangeCompany = ''
},
//对数据进行去重
addAndRemoveCompany (arr) {
var oldCompany = {}
this.selectedRangeCompany.forEach(item => {
oldCompany[item.code] = item.name
})
arr.forEach(item => {
if(!oldCompany[item.code]){
this.selectedRangeCompany.push({
code: item.code,
name: item.name,
result: null
})
}
})
},
searchRunningCompany(value) {
this.searchCompanyLoading = true
var checkeds = this.companyStatusCheck.checkedItems
var Where = []
if(checkeds.length > 0){
Where.push({
"Encode": "F90063V",
"State": checkeds.length == 1?1:8,
"Value": checkeds.length == 1?checkeds[0]:checkeds
})
}
return new Promise((resolve, reject) => {
http.netPost('Data/Query/Query', {
"List": ["F90004V", 'F90001V', 'F90002V'],
"WhereOr": [
{
"Encode": "F90004V",
"State": 2,
"Value": value,
},
{
"Encode": "F90001V",
"State": 2,
"Value": value,
},
{
"Encode": "F90002V",
"State": 2,
"Value": value,
},
],
"Where": Where,
"Current": 0,
"Psize": 20
})
.then((res) => {
if (res.data.Status == 1) {
this.runningCompanyList = res.data.Data.Records
}
this.searchCompanyLoading = false
})
})
},
selectedExcel(e) {
var file = e.target.files[0]
var type = file.name.split('.')
if (type[type.length - 1] !== 'xlsx' && type[type.length - 1] !== 'xls') {
this.$message({
message: '所选文件格式不正确!',
type: 'error'
})
e.target.value = ''
return false;
} else {
const reader = new FileReader();
reader.readAsBinaryString(file);
reader.onload = (e) => {
const data = e.target.result;
const zzexcel = window.XLS.read(data, {
type: 'binary'
})
const result = [];
for (let i = 0; i < zzexcel.SheetNames.length; i++) {
const newData = window.XLS.utils.sheet_to_json(zzexcel.Sheets[zzexcel.SheetNames[i]]);
result.push(...newData)
}
var arr = []
result.forEach(item => {
var obj = {
name: item.name,
code: item.code.split('.')[0]
// label: item.name,
// type: 5,
// from: '批量添加'
}
arr.push(obj)
})
this.addAndRemoveCompany(arr)
}
this.$message({
message: '导入成功!',
type: 'success'
})
e.target.value = ''
}
},
//测试运行的一些方法结束
deleteIndex() {
this.deleteIndexLoading = true
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/RemoveCustomIndex', {
"id": this.activeIndex.Id,
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
this.activeIndex = {}
this.$message({
message: "指标删除成功",
type: 'success'
})
this.getIndexCateGory()
resolve()
}
this.deleteIndexLoading = false
})
})
},
choosePublicCategory () {
this.submitCategoryVisible = true
},
confirmSubmit() {
if(!this.submitCategory){
this.$message({
message: '请选择分类',
type: 'error'
})
return false
}
this.submitLoading = true
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/SubmitIndexToView', {
"id": this.activeIndex.Id,
"archiveCode": this.submitCategory[this.submitCategory.length - 1],
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
this.activeIndex = {}
this.getIndexCateGory()
this.$message({
message: '审核提交成功',
type: 'success'
})
resolve()
}
this.submitLoading = false
this.submitCategoryVisible = false
})
})
},
//获取初始化公司
getUsedCompany(params) {
var codes = []
params.forEach(item => {
if (item.OperandType == 0 && item.Where[2]) {
codes.push(item.Where[2].Value)
} else if (item.OperandType == 4) {
item.Args.forEach(sub => {
sub.forEach(child => {
if (child.OperandType == 0 && child.Where[2]) {
codes.push(child.Where[2].Value)
}
})
})
}
})
var where = [{
"Encode": "F90001V",
"State": 7,
"Value": codes.join(','),
}]
return new Promise((resolve, reject) => {
http.netPost('Data/Query/Query', {
"List": ['F90001V', 'F90002V'],
"Where": where,
"Current": 0,
"Psize": 100
})
.then((res) => {
if (res.data.Status == 1) {
res.data.Data.Records.forEach(item => {
this.companyNameObj[item.F90001V] = item.F90002V
})
resolve()
} else if (res.data.Status == 0) {
resolve()
} else {
reject()
}
})
})
},
getIndexArgsType(args) {
var arr = []
this.defaultTypeList.forEach(item => {
if (args & item.Id) {
arr.push(item.Name)
}
})
return arr.join('')
},
getIndexArgsIds(args) {
var arr = []
this.defaultTypeList.forEach(item => {
if (args & item.Id) {
arr.push(item.Id)
}
})
return arr
},
getDefaultType() {
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/GetAllIndexArgs', {
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
this.defaultTypeList = res.data.Data
res.data.Data.forEach(item => {
this.editIndexParams.push(item.Id)
})
resolve()
}
})
})
},
confirmEditIndex() {
this.addIndexType = 'edit'
this.editIndexName = this.activeIndex.IndexName
this.editIndexFormat = this.activeIndex.ReturnType
this.editIndexParams = this.getIndexArgsIds(this.activeIndex.Args)
this.editIndexUnit = this.activeIndex.IndexUnit
this.editIndexClassify = this.getEditIndexCategory()
this.editIndexDetail = this.activeIndex.Wiki
this.detailShowType = 2
this.$nextTick(() => {
this.$refs.calculater.indexParams = this.activeIndexCondition.indexParams
this.$refs.calculater.numParams = this.activeIndexCondition.numParams
this.$refs.calculater.dateParams = this.activeIndexCondition.dateParams
this.$refs.calculater.symbolParams = this.activeIndexCondition.symbolParams
this.$refs.calculater.functionParams = this.activeIndexCondition.functionParams
for (var key in this.activeIndexCondition.functionParams) {
this.activeIndexCondition.functionParams[key].paramsValue.forEach(item => {
var arr = ['indexParams', 'numParams', 'dateParams', 'symbolParams']
arr.forEach(child => {
for (var key in item[child]) {
this.$refs.calculater.indexParams[key] = item[child]
}
})
})
}
this.$refs.calculater.setHtml(this.activeIndexCondition.dom)
})
},
getEditIndexCategory() {
var result = []
this.activeIndex.ArchiveCodes.forEach(item => {
var categoryArr = []
var arr = this.findAllPathByLeafId(item, this.publicCategoryOptions)
console.log(arr)
if(!arr){
return []
}
arr.forEach((item, index) => {
categoryArr.push(item.code)
})
result.push(categoryArr)
})
console.log(result)
return result
},
findAllPathByLeafId (leafId, nodes, path) {
if (path === undefined) {
path = []
}
for (var i = 0; i < nodes.length; i++) {
var tmpPath = path.concat()
tmpPath.push({
code: nodes[i].Code,
name: nodes[i].Name
})
if (leafId == nodes[i].Code) {
return tmpPath;
}
if (nodes[i].Children) {
var findResult = this.findAllPathByLeafId(leafId, nodes[i].Children, tmpPath);
if (findResult) {
return findResult
}
}
}
},
openAddNewIndex() {
this.detailShowType = 2
this.addIndexType = 'add'
//将当前的id带过去
var arr = []
this.activeIndex.from.forEach(item => {
arr.push(item.id)
})
this.editIndexClassify = arr
},
deleteCategory() {
this.deleteCategoryLoading = true
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/RemoveEmptyPublicIndexArchiveReq', {
"code": this.activeIndex.Code,
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
this.$message({
message: '文件夹删除成功!',
type: 'success'
})
this.getIndexCateGory()
resolve()
}
this.deleteCategoryLoading = false
})
})
},
getIndexs() {
this.treeLoading = true
return new Promise((resolve, reject) => {
http.netPost('Data/Encode/GetEncodeList', {
"Current": 0,
"Psize": 100,
"Code": "B",
'Name': '',
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
this.treeData = res.data.Data.Records
var systemData = JSON.parse(JSON.stringify(res.data.Data.Records))
var newArr = [{
DataType: 'T',
Name: '系统指标',
Sub: []
}]
systemData[0].Sub.forEach((child,index) => {
if(child.Code == 'XTZB'){
systemData[0].Sub[index].Sub.forEach((item, index) => {
if(index == 0 || index == 1){
newArr[0].Sub.push(item)
}
})
}
})
// systemData[0].Sub[1].Sub.forEach((item, index) => {
// if(index == 0 || index == 1){
// newArr[0].Sub.push(item)
// }
// })
// var newArr = systemData[0].Sub[1]
this.systemTreeData = newArr
console.log(this.systemTreeData)
this.creatIndexObj(res.data.Data.Records)
this.treeLoading = false
resolve()
}
})
})
},
creatIndexObj(initData) {
initData.forEach(element => {
if (element.Sub.length > 0) {
this.creatIndexObj(element.Sub)
} else {
this.initIndexObj[element.Code] = element
var tableName = element.Origin ? element.Origin.TableComment : null
var dbName = element.Origin ? element.Origin.DbComment : null
this.initIndexObj[element.Code].originText = tableName + '-' + dbName
}
})
},
backToDetail() {
if (this.activeIndex.isIndex) {
this.detailShowType = 1
} else {
this.detailShowType = 3
}
},
closeEditFuction() {
this.$refs.calculater.resetActiveInput()
},
//重新编辑计算参数
resetFuncParams(selectedController, index) {
//重新注入参数
var obj = JSON.parse(JSON.stringify(selectedController.paramsValue[index]))
this.$refs.functionCalculater.indexParams = obj.indexParams
this.$refs.functionCalculater.dateParams = obj.dateParams
this.$refs.functionCalculater.numParams = obj.numParams
this.$refs.functionCalculater.symbolParams = obj.symbolParams
var id = this.$refs.functionCalculater.contentId
var html = selectedController.paramsValue[index].dom
document.getElementById(id).innerHTML = ''
document.getElementById(id).innerHTML = html
},
confirmAddFunction() {
var params = this.$refs.functionCalculater.sendDataToHost()
// 判断数据类型是否一致
this.$refs.calculater.receiveFunctionParam(params)
this.editFuctionVisible = false
},
//添加指标百科
confirmAddMemo() {
this.editMemoryVisible = false
},
//获取指标来源
getIndexFrom() {
return this.activeIndex.Origin.DataProvider + '/' + this.activeIndex.Origin.DbComment
},
//获取指标参数
getIndexParams(activeIndex) {
var textArr = []
activeIndex.TypeContent.Parameters.forEach(item => {
textArr.push(item.Name)
})
return textArr.join('')
},
//获取指标类型
getDataType(activeIndex) {
var obj = {
0: '字符',
1: '日期',
2: '数字'
}
return obj[activeIndex.ReturnType]
},
getSystemDataType (activeIndex) {
var typeNumber = activeIndex.Code
var newObj = {
type: '',
typeName: ''
}
if (typeNumber.indexOf('N') >= 0) {
newObj.type = 'number'
newObj.typeName = '数字'
} else if (typeNumber.indexOf('V') >= 0) {
newObj.type = 'string'
newObj.typeName = '文本'
} else if (typeNumber.indexOf('D') >= 0) {
newObj.type = 'date'
newObj.typeName = '日期'
}
return newObj.typeName
},
getSystemDataParams (activeIndex) {
var arr = []
activeIndex.TypeContent.Parameters.forEach(item => {
arr.push(item.Name)
})
return arr.join('')
},
getStatus (obj) {
var status = 0, params = {}
obj.WdCustomIndexWorkflow.forEach( item => {
if(item.IsCurrent == 1){
status = item.FlowStatus
params = item
}
})
return {
status: status,
obj: params
}
},
//指标点击
// selecteIndex(value, param) {
// var data = {}, arr = []
// data = value
// arr = value.isIndex?data.Algorithm.Object:[]
// data.status = value.CurrentFlowStatus
// //先恢复初始化
// if (this.detailShowType == 2) {
// return false
// }
// if (data.isIndex) {
// this.activeIndexStatus = data.status
// this.detailShowType = 1
// this.getUsedCompany(arr).then(res => {
// this.activeIndexCondition = {
// indexParams: {},
// dateParams: {},
// numParams: {},
// symbolParams: {},
// functionParams: {},
// dom: '',
// showDom: ''
// }
// tools.getSaveCondition(this.activeIndexCondition, arr, this.initIndex, this.initIndexObj, this.companyNameObj, this.keyboardObj)
// this.$nextTick(() => {
// var spans = document.getElementById('conditionBox').getElementsByTagName('span')
// var html = ''
// Array.from(spans).forEach(span => {
// html += span.outerHTML
// })
// document.getElementById('conditionBox').innerHTML = html
// var spans = document.getElementById('conditionBox').getElementsByTagName('span')
// tools.formatShowDom(spans)
// })
// })
// } else {
// console.log(data)
// this.detailShowType = 3
// if(!data.children || data.children.length == 0){
// data.allowedDelete = true
// }
// }
// this.activeIndex = data
// this.activeIndex.from = this.findPathByLeafId(value.myId, this.myTreeData)
// },
selecteIndex(value, param) {
console.log(value)
var arr = [value.Code]
if (this.detailShowType == 2) {
return false
}
if(value.isIndex){
this.getSingleIndexData(arr).then(res => {
//先恢复初始化
var data = res.data.Data[0]
data.isIndex = value.isIndex
data.DataType = value.DataType
data.Version = value.Version
data.isCustom = value.isCustom
data.CurrentWorkflow = value.CurrentWorkflow
data.myId = value.myId
this.activeIndexStatus = data.CurrentFlow
this.detailShowType = 1
this.getUsedCompany(data.Algorithm).then(res => {
this.activeIndexCondition = {
indexParams: {},
dateParams: {},
numParams: {},
symbolParams: {},
functionParams: {},
dom: '',
showDom: ''
}
this.initIndex++
tools.getSaveCondition(this.activeIndexCondition, data.Algorithm, this.initIndex, this.initIndexObj, this.companyNameObj, this.keyboardObj)
this.$nextTick(() => {
var spans = document.getElementById('conditionBox').getElementsByTagName('span')
var html = ''
Array.from(spans).forEach(span => {
html += span.outerHTML
})
document.getElementById('conditionBox').innerHTML = html
var spans = document.getElementById('conditionBox').getElementsByTagName('span')
tools.formatShowDom(spans)
})
})
this.activeIndex = data
this.activeIndex.from = this.findPathByLeafId(data.myId, this.myTreeData)
console.log(this.activeIndex)
})
}else{
this.detailShowType = 3
if(!value.children || value.children.length == 0){
value.allowedDelete = true
}
this.activeIndex = value
this.activeIndex.from = this.findPathByLeafId(value.myId, this.myTreeData)
}
},
systemIndexClick (data) {
if(data.DataType !== 'T'){
this.activeIndex = data
this.detailShowType = 1
}
},
getIndexModel (data) {
//初始化选择
this.modelData.forEach(item => {
this.$set(item.keywordCheck, 'checkAll', false)
this.$set(item.keywordCheck, 'checkedItems', [])
this.$set(item.keywordCheck, 'isIndeterminate', false)
this.$set(item.nameCheck, 'checkAll', false)
this.$set(item.nameCheck, 'checkedItems', [])
this.$set(item.nameCheck, 'isIndeterminate', false)
})
//修改数据
var dimensions = [], keywords = []
data.WdIndexModelDimensions.forEach(item => {
dimensions.push(item.DimensionId)
})
data.WdIndexModelKeyword.forEach(item => {
keywords.push(item.KeywordId)
})
this.modelData.forEach(item => {
item.keywordCheck.options.forEach(sub => {
if(keywords.indexOf(sub) >= 0){
item.keywordCheck.checkedItems.push(sub)
}
})
item.nameCheck.options.forEach(sub => {1
if(dimensions.indexOf(sub) >= 0){
item.nameCheck.checkedItems.push(sub)
}
})
if(item.keywordCheck.checkedItems.length == item.keywordCheck.options.length){
item.keywordCheck.checkAll = true
}else if(item.keywordCheck.checkedItems.length > 0 && item.keywordCheck.checkedItems.length < item.keywordCheck.options.length){
item.keywordCheck.isIndeterminate = true
}
if(item.nameCheck.checkedItems.length == item.nameCheck.options.length){
item.nameCheck.checkAll = true
}else if(item.nameCheck.checkedItems.length > 0 && item.nameCheck.checkedItems.length < item.nameCheck.options.length){
item.nameCheck.isIndeterminate = true
}
})
},
formatIndexFrom(arr) {
console.log(this.activeIndex)
var newArr = []
arr.forEach(item => {
newArr.push(item.name)
})
return newArr.join(' / ')
},
//树状结构过滤
filterTreeNode(value, data) {
if (!value) return true;
return data.Name.indexOf(value) !== -1;
},
systemFilterTreeNode (value, data) {
if (!value) return true;
return data.Name.indexOf(value) !== -1;
},
copyTreeFilter (value, data) {
if (!value) return true;
return data.Name.indexOf(value) !== -1;
},
deleteCopyTree () {
this.selectedChangeIndexs.forEach(item => {
this.$refs.publicIndexTree.remove(item)
})
},
//搜索指标
searchIndex() {
this.$refs.pbIndexTree.filter(this.inputedIndex)
this.$refs.systemTree.filter(this.inputedIndex)
// this.searchInputed = this.inputedIndex
},
emptySearch() {
this.inputedIndex = ''
this.searchIndex()
},
findPathByLeafId(leafId, nodes, path) {
if (path === undefined) {
path = []
}
for (var i = 0; i < nodes.length; i++) {
var tmpPath = path.concat()
tmpPath.push({
myId: nodes[i].myId,
name: nodes[i].Name,
id: nodes[i].Id
})
if (leafId == nodes[i].myId) {
return tmpPath;
}
if (nodes[i].children) {
var findResult = this.findPathByLeafId(leafId, nodes[i].children, tmpPath);
if (findResult) {
return findResult
}
}
}
},
handleCheckChange () {
this.selectedChangeIndexs = this.$refs.publicIndexTree.getCheckedNodes(true, false)
// this.testRunWords = choosed.filter(item => item.isIndex)
},
getIndexCateGory() {
this.treeLoading = true
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/GetPublicCustomIndexLight', {
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
var copyData = JSON.parse(JSON.stringify(res.data.Data))
copyData.forEach(item => {
this.initIndex++
item.myId = new Date().getTime() + this.initIndex
item.ShortName = item.Name
item.disabled = true
item.isCustom = true
this.categoryDic[item.Code] = item.myId
if (item.Required) {
this.defaultCategoryId = item.Code
}
})
copyData.forEach(item => {
item.parentId = this.categoryDic[item.ParentCode]
})
var categroyData = JSON.parse(JSON.stringify(copyData))
var cascaderData = JSON.parse(JSON.stringify(res.data.Data))
this.myTreeData = this.setTreeData(this.indexIntoCategroy(categroyData), 'myId', 'parentId')
this.myTreeData.forEach(item => {
this.defaultExpandedKeys.push(item.myId)
})
this.copyTreeData = JSON.parse(JSON.stringify(this.myTreeData))
this.cascaderOptions = this.setTreeData(cascaderData, 'Code', 'ParentCode')
this.treeLoading = false
this.activeIndex = {}
this.detailShowType = 1
resolve()
}
})
})
},
indexIntoCategroy(data) {
var newData = JSON.parse(JSON.stringify(data))
data.forEach(item => {
item.Encode.forEach(sub => {
this.initIndex++
sub.myId = new Date().getTime() + this.initIndex
sub.parentId = item.myId
sub.isCustom = true
sub.isIndex = true
newData.push(sub)
})
})
return newData
},
openAddCategory() {
this.inputedCategoryName = ''
this.addOrEditCategoryTitle = '新增分类'
this.addCategoryType = 'add'
this.addOrEditCategoryVisible = true
},
openChangeCategory() {
this.inputedCategoryName = this.activeIndex.ArchiveName
this.addOrEditCategoryTitle = '修改分类'
this.addCategoryType = 'edit'
this.addOrEditCategoryVisible = true
},
createOrChangeCategory() {
this.createOrChangeCategoryLoading = true
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/AddPublicArchive', {
"code": this.addCategoryType == 'add' ? "" : this.activeIndex.Code,
"name": this.inputedCategoryName,
"parentCode": this.addCategoryType == 'add' ? this.activeIndex.Code : this.activeIndex.ParentCode,
"AccountId": store.get('accountId')
})
.then((res) => {
this.createOrChangeCategoryLoading = false
if (res.data.Status == 1) {
this.addOrEditCategoryVisible = false
this.getIndexCateGory()
resolve()
}
})
})
},
setTreeData(jsonData, id, pid) {
let result = [],
temp = {}
for (let i = 0; i < jsonData.length; i++) {
temp[jsonData[i][id]] = jsonData[i]
}
for (let j = 0; j < jsonData.length; j++) {
let currentElement = jsonData[j]
let tempCurrentElementParent = temp[currentElement[pid]]
if (tempCurrentElementParent) {
if (!tempCurrentElementParent["children"]) {
tempCurrentElementParent["children"] = []
}
tempCurrentElementParent["children"].push(currentElement)
} else {
result.push(currentElement)
}
}
return result
},
addOrChangeIndex() {
var args = 0, keywordIds = [], dimensionIds = []
this.modelData.forEach(item => {
item.keywordCheck.checkedItems.forEach(sub => {
keywordIds.push(sub)
})
item.nameCheck.checkedItems.forEach(sub => {
dimensionIds.push(sub)
})
})
this.editIndexParams.forEach(item => {
args |= item
})
this.addOrEditIndexLoading = true
var arr = []
this.editIndexClassify.forEach(item => {
arr.push(item[item.length - 1])
})
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/EditPublicCustomIndex', {
"id": this.activeIndex.Id,
"indexName": this.editIndexName,
"archiveCode": arr, //分类Id
"operands": this.getOperands(), //计算参数
"returnType": this.editIndexFormat, //指标类型
"args": args, //指标参数
"unit": this.editIndexUnit, //单位
"remark": this.editIndexRemark, //备注
"wiki": this.editIndexDetail, //百科
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
this.$message({
message: "提交审核成功",
type: "success"
})
this.backToDetail()
this.getIndexCateGory()
resolve()
}
this.addOrEditIndexLoading = false
})
})
},
getOperands() {
var params = this.$refs.calculater.sendDataToHost(true)
return this.setSaveCondition(params)
},
setSaveCondition(condition) { //格式化保存的条件,原名 getSaveCalCondition
var operands = []
var div = document.createElement('div')
div.innerHTML = condition.dom
var inputs = div.getElementsByTagName('input')
//后台的定义 0指标1符号2数字3时间4方法
//前台的定义 1指标2时间3数字4字符5方法
Array.from(inputs).forEach(item => {
var obj = {},
id = item.id
switch (parseInt(item.getAttribute('type'))) {
case 1: //指标
var param = condition.indexParams[id]
var dateYear = '1900'
var dateQuater = '06-30'
var evalArray = []
if (param.yearType == 1) {
evalArray.push({
"EvalOption": 1,
"Value": param.t
})
} else if (param.yearType == 2) {
dateYear = param.inputYear
}
if (param.quarterType == 1) {
evalArray.push({
"EvalOption": 2,
"Value": param.q
})
} else if (param.quarterType == 2) {
dateQuater = param.inputQuarter
}
var where = [{
"State": 1,
"Encode": "F91996D",
"Value": dateYear + '-' + dateQuater,
"Eval": evalArray
},
{
"State": 1,
"Value": param.mergeType,
"Encode": "F91997V",
"Eval": []
}
]
if (param.isAppointCompany) {
where.push({
"State": 1,
"Value": param.selectedCompany.split('-')[1],
"Encode": "F90001V",
"Eval": []
})
}
obj = {
"List": [param.code],
"Where": where,
"OperandType": 0,
}
break;
case 2: //时间
obj = {
"Value": item.value,
"OperandType": 3
}
break;
case 3: //数字
obj = {
"Value": item.value.replace(/\[.*?\]/g, ''),
"OperandType": 2
}
break;
case 4: //字符
obj = {
"Value": item.value,
"OperandType": 1
}
break;
case 5: //方法
obj = {
"Action": condition.functionParams[id].originParams.funcId,
"Args": this.getFuncArgs(condition.functionParams[id]),
"OperandType": 4
}
break;
default:
break;
}
operands.push(obj)
})
return operands
},
getFuncArgs(functionParams) {
var arr = []
functionParams.paramsValue.forEach(item => {
arr.push(this.setSaveCondition(item))
})
return arr
},
allowDrop (draggingNode, dropNode, type) {
if(dropNode.data.isIndex){
return type === 'prev' || type === 'next'
}else{
return true
}
},
handleDragLeave(draggingNode, dropNode, ev) {
this.overingKey = 0
},
handleDragOver(draggingNode, dropNode, ev) {
this.overingKey = dropNode.id
},
handleDragEnd(draggingNode, dropNode, dropType, ev) {
this.overingKey = 0
},
handleDrop(draggingNode, dropNode, dropType, ev) {
this.overingKey = 0
},
setCheckedKeys(checkedNodes,e) {
this.selectIndexKey = e.checkedKeys
},
getSingleIndexData (ids) {
this.loadingDetail = true
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/GetPublicCustomIndexDetailsByCodes', {
"codes": ids,
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
resolve(res)
}
this.loadingDetail = false
})
})
},
getBadge (type, key) {
return new Promise((resolve, reject) => {
http.netPost('Data/CustomIndex/GetTodoCustomIndexCount', {
"countOption": type,
"AccountId": store.get('accountId')
})
.then((res) => {
if (res.data.Status == 1) {
if(res.data.Data > 0){
this[key] = true
}else{
this[key] = false
}
resolve(res)
}
this.loadingDetail = false
})
})
},
downloadExample () {
var that = this
var excelName = '示例表格'
var xlsx = officegen('xlsx')
var filePath = dialog.showSaveDialog({
defaultPath: excelName + '.xlsx',
title: '保存',
buttonLabel: '保存'
})
xlsx.on('finalize', function(written) {
that.$message({
message: '下载完成',
type: 'success'
})
})
xlsx.on('error', function(err) {
console.log(err)
})
var sheet = xlsx.makeNewSheet()
sheet.name = 'sheet1'
sheet.orientation = 'landscape'
sheet.data[0] = []
sheet.data[0][0] = 'name'
sheet.data[0][1] = 'code'
sheet.data[1] = []
sheet.data[1][0] = '华夏银行'
sheet.data[1][1] = '600015.sh'
sheet.data[2] = []
sheet.data[2][0] = '贵州茅台'
sheet.data[2][1] = '600519'
sheet.data[3] = []
sheet.data[3][0] = '工商银行'
sheet.data[3][1] = '601398'
var out = fs.createWriteStream(filePath)
out.on('error', function(err) {
console.log(err)
})
xlsx.generate(out)
}
}
}
}
\ No newline at end of file
<template>
<div class="editor-inner">
<div class="analyzer-header shadow">
<div class="analyzer-header-title">
<div class="analyzer-header-title-name">指标管理</div>
<div class="analyzer-header-tab" style="flex: auto">
<router-link tag="div" active-class="activeLink" exact to="/">我的指标</router-link>
<router-link tag="div" active-class="activeLink" exact to="/publicIndex">公共指标</router-link>
<el-badge :is-dot="isDotEdit && indexPermission" class="item">
<router-link tag="div" active-class="activeLink" exact to="/indexAudit">指标审核</router-link>
</el-badge>
<el-badge :is-dot="isDotSort && indexPermission" class="item">
<router-link tag="div" active-class="activeLink" exact to="/categoryAudit">公共分类修改审核</router-link>
</el-badge>
<router-link tag="div" style="flex: auto; text-align: right" active-class="activeLink" exact to="/indexRecord">
<span class="el-icon-date"> 指标修改日志</span>
</router-link>
</div>
</div>
<div class="analyzer-header-condition" style="align-items: center; padding: 14px 20px">
<!-- <el-button size="mini" type="primary">创建公共指标</el-button> -->
<div class="header-search-box">
<span class="el-icon-search icon"></span>
<input
:readonly="detailShowType == 2"
:style="{cursor: detailShowType == 2?'not-allowed':'auto'}"
@keyup.enter="searchIndex"
v-model="inputedIndex"
type="text"
placeholder="请输入指标名称进行搜索"
/>
</div>
</div>
</div>
<div class="analyzer-content shadow" style="padding-top: 20px">
<split-pane class="container-inner" :class="{noLeft: detailShowType !== 1 && detailShowType !== 3}" :min-percent='leftMinWidth' :default-percent='leftWidth' split="vertical">
<template slot="paneL" v-show="detailShowType == 1 || detailShowType == 3">
<div class="split-index-box" v-show="detailShowType == 1 || detailShowType == 3">
<div class="index-box-tab">
<h3 class="active">公共指标</h3>
<el-tag style="cursor: pointer" size="mini" type='success' @click="changeTreeProps('Name')"></el-tag>
<el-tag style="cursor: pointer; margin-right: 20px; margin-left: 8px" size="mini" @click="changeTreeProps('ShortName')"></el-tag>
<span class="el-icon-edit hover-icon" @click="changePosition"> 位置调整</span>
</div>
<div style="margin-bottom: 8px; margin-top: 12px">
<span>当前搜索词:</span>
<span>{{searchInputed?searchInputed:''}}</span>
<span
@click="emptySearch"
v-show="searchInputed"
style="margin-left:4px"
class="el-icon-error hover-icon"
></span>
</div>
<div
class="tree-container"
v-loading="treeLoading"
element-loading-text="数据加载中"
element-loading-spinner="el-icon-loading">
<el-tree
:data="systemTreeData"
:indent="8"
ref="systemTree"
class="small-tree"
@node-click="systemIndexClick"
:filter-node-method="systemFilterTreeNode"
:props="systemTreeProps">
<span class="custom-tree-node" slot-scope="{ node, data }">
<span class="el-icon-folder" v-show="data.DataType == 'T'"></span>
<span style="font-size: 12px">{{ node.label }}</span>
</span>
</el-tree>
<el-tree
@node-click="selecteIndex"
:default-expanded-keys="defaultExpandedKeys"
:filter-node-method="filterTreeNode"
ref="pbIndexTree"
node-key="myId"
class="small-tree"
:expand-on-click-node="false"
:data="myTreeData"
:props="treeProps">
<span class="custom-tree-node" slot-scope="{ node, data }">
<span class="el-icon-folder" v-show="!data.isIndex"></span>
<span style="font-size: 12px">{{ node.label }}</span>
</span>
</el-tree>
</div>
</div>
</template>
<template slot="paneR">
<!-- 指标详情显示 -->
<div class="index-detail" v-show="detailShowType == 1">
<div class="index-detail-title">
<h3>指标参数</h3>
</div>
<div class="action-list" v-if="activeIndex.isIndex">
<span class="el-icon-odometer icon" @click="openTestRunDialog()"> 测试运行</span>
<el-popconfirm
:title="editTip"
v-show="activeIndexStatus == 16 || activeIndexStatus == 32"
@onConfirm="confirmEditIndex">
<span class="el-icon-edit icon" slot="reference"> 编辑指标</span>
</el-popconfirm>
<span v-show="activeIndexStatus == 16 || activeIndexStatus == 32" class="el-icon-edit icon" @click="openWikiDialog"> 编辑百科</span>
<span v-show="activeIndexStatus == 16 || activeIndexStatus == 32" class="el-icon-document-copy icon" @click="copyIndex"> 复制到我的指标</span>
<span v-show="activeIndexStatus == 16 || activeIndexStatus == 32" class="el-icon-document-copy icon" @click="copyIndexToCatrgory"> 复制至其它文件夹</span>
<span v-show="activeIndexStatus !== 16 && activeIndexStatus !== 32" style="padding-left: 12px; color: #999; border-left:0">当前指标编辑中,暂时无法编辑和修改百科以及复制</span>
</div>
<!-- 系统指标时候显示 -->
<div class="detail-container" v-if="!activeIndex.isCustom && activeIndex.DataType">
<div class="detail-index">
<div class="title">指标名称:</div>
<div class="detail">{{activeIndex.Name}}</div>
</div>
<div class="detail-index">
<div class="title">指标编码:</div>
<div class="detail">{{activeIndex.Code}}</div>
</div>
<div class="detail-index">
<div class="title">最新版本:</div>
<div class="detail">{{activeIndex.Version}}</div>
</div>
<div class="detail-index">
<div class="title">指标创建人:</div>
<div class="detail">系统指标</div>
</div>
<div class="detail-index">
<div class="title">创建时间:</div>
<div class="detail">{{activeIndex.CreateDate}}</div>
</div>
<div class="detail-index">
<div class="title">指标类型:</div>
<div class="detail">{{getSystemDataType(activeIndex)}}</div>
</div>
<div class="detail-index">
<div class="title">指标参数:</div>
<div class="detail">{{getSystemDataParams(activeIndex)}}</div>
</div>
<div class="detail-index">
<div class="title">指标单位:</div>
<div class="detail">{{activeIndex.Unit}}</div>
</div>
<div class="detail-index">
<div class="title">指标备注:</div>
<div class="detail">
<div class="sub-detail">
<span>{{activeIndex.Mark}}</span>
</div>
</div>
</div>
</div>
<!-- 有指标的时候显示 -->
<div class="detail-container" v-if="activeIndex.isIndex && activeIndex.isCustom">
<div class="detail-index">
<div class="title">指标名称:</div>
<div class="detail">{{activeIndex.IndexName}}</div>
</div>
<div class="detail-index">
<div class="title">指标编码:</div>
<div class="detail">{{activeIndex.Encode}}</div>
</div>
<div class="detail-index">
<div class="title">最新版本:</div>
<div class="detail">{{activeIndex.Version}}</div>
</div>
<div class="detail-index">
<div class="title">指标创建人:</div>
<div class="detail">{{activeIndex.Creator.NickName}}</div>
</div>
<div class="detail-index">
<div class="title">最后编辑:</div>
<div class="detail">{{activeIndex.LastUpdate}}</div>
</div>
<div class="detail-index">
<div class="title">指标类型:</div>
<div class="detail">{{getDataType(activeIndex)}}</div>
</div>
<div class="detail-index">
<div class="title">指标参数:</div>
<div class="detail">{{getIndexArgsType(activeIndex.Args)}}</div>
</div>
<div class="detail-index">
<div class="title">指标单位:</div>
<div class="detail">{{activeIndex.IndexUnit?activeIndex.IndexUnit:'-'}}</div>
</div>
<div class="detail-index">
<div class="title">指标所属分类:</div>
<div class="detail">{{formatIndexFrom(activeIndex.from)}}</div>
</div>
<div class="detail-index">
<div class="title">指标百科:</div>
<div class="detail">
<div class="sub-detail">
<span>{{activeIndex.Wiki}}</span>
</div>
</div>
</div>
<div class="detail-index">
<div class="title">指标算法:</div>
<div class="detail">
<div class="calculater-box" id="conditionBox" v-html="activeIndexCondition.showDom"></div>
</div>
</div>
</div>
<!-- 未选中指标的显示 -->
<div class="detail-container" v-if="!activeIndex.DataType">
<div class="empty-status">
<img src="../../static/image/empty.png" alt />
<div class="empty-tip">请从左侧点击指标或者分类</div>
</div>
</div>
</div>
<!-- 指标编辑显示 -->
<div class="index-detail index-edit" v-if="detailShowType == 2">
<div class="index-detail-title">
<h3 style="flex: auto" v-show="addIndexType == 'edit'">指标编辑 - {{activeIndex.IndeName}}</h3>
<h3 style="flex: auto" v-show="addIndexType == 'add'">新增指标</h3>
<el-popconfirm @onConfirm="backToDetail" title="指标正在编辑中,确认返回?">
<el-button slot="reference" size="mini" icon="el-icon-back">返回</el-button>
</el-popconfirm>
</div>
<div class="detail-container">
<div class="detail-index">
<div class="title">指标名称:</div>
<div class="detail">
<el-input
v-model="editIndexName"
size="mini"
style="width: 300px"
placeholder="请输入指标名称"
></el-input>
</div>
</div>
<div class="detail-index">
<div class="title">指标类型:</div>
<div class="detail">
<el-radio-group v-model="editIndexFormat">
<el-radio :label="0">字符</el-radio>
<el-radio :label="1">日期</el-radio>
<el-radio :label="2">数字</el-radio>
</el-radio-group>
</div>
</div>
<div class="detail-index">
<div class="title">指标参数:</div>
<div class="detail">
<el-checkbox-group v-model="editIndexParams">
<el-checkbox
:key="item.Id"
:label="item.Id"
v-for="item in defaultTypeList"
>{{item.Name}}</el-checkbox>
</el-checkbox-group>
</div>
</div>
<div class="detail-index">
<div class="title">指标单位:</div>
<div class="detail">
<el-input
size="mini"
v-model="editIndexUnit"
style="width: 300px"
placeholder="请输入指标单位(如:元,万元,亿,%等)"
></el-input>
</div>
</div>
<div class="detail-index">
<div class="title">所属分类:</div>
<div class="detail">
<el-cascader
:props="cascaderProps"
size="mini"
style="width: 300px"
v-model="editIndexClassify"
:options="cascaderOptions"
></el-cascader>
</div>
</div>
<div class="detail-index" style="align-items: flex-start">
<div class="title">指标算法:</div>
<div class="detail">
<calculater :treeData="treeData" ref="calculater" type="index" :parentLevel="3" />
</div>
</div>
<div class="detail-index" style="align-items: flex-start">
<div class="title">指标百科:</div>
<div class="detail">
<el-input
style="max-width: 600px"
type="textarea"
:rows="6"
placeholder="请输入内容"
v-model="editIndexDetail"
></el-input>
</div>
</div>
<div class="detail-index" style="align-items: flex-start">
<div class="title">编辑备注:</div>
<div class="detail">
<el-input
style="max-width: 600px"
type="textarea"
:rows="6"
placeholder="请输入编辑备注"
v-model="editIndexRemark"
></el-input>
</div>
</div>
<div class="detail-index">
<div class="title">操作:</div>
<div class="detail">
<el-popconfirm @onConfirm="backToDetail" title="指标正在编辑中,确认取消?">
<el-button slot="reference" size="mini">取消</el-button>
</el-popconfirm>
<el-button
size="mini"
:loading="addOrEditIndexLoading"
type="primary"
@click="addOrChangeIndex"
>{{editConfirmText}}</el-button>
</div>
</div>
</div>
</div>
<!-- 指标文件夹显示 -->
<div class="index-detail index-edit" v-if="detailShowType == 3">
<div class="index-detail-title">
<h3 style="flex: auto">分类编辑 - 我的分类</h3>
</div>
<div class="detail-container">
<div class="detail-index">
<div class="title" style="text-align: left; color: #999">分类名称:</div>
<div class="detail">{{activeIndex.Name}}</div>
</div>
<div class="detail-index">
<div class="title" style="text-align: left; color: #999">分类路径:</div>
<div class="detail">{{formatIndexFrom(activeIndex.from)}}</div>
</div>
<div class="detail-index" v-show="hasPermission">
<div class="title" style="text-align: left; color: #999">操作:</div>
<div class="detail">
<el-button size="mini" :disabled="activeIndex.Id == 'PCI'" @click="openChangeCategory()">修改名称</el-button>
<el-button size="mini" :disabled="!hasPermission" @click="openAddCategory()">新建分类</el-button>
<el-popconfirm
title="是否确认删除该分类?"
@onConfirm="deleteCategory">
<el-button style="margin-left: 10px" size="mini" slot="reference" :disabled="!(activeIndex.allowedDelete && activeIndex.Id !== 'PCI' && hasPermission)" type="primary">删除分类</el-button>
</el-popconfirm>
</el-popconfirm>
<span v-show="activeIndex.Id == 'PCI'" style="margin-left: 20px; color: #999">系统根目录禁止删除和修改</span>
</div>
</div>
</div>
</div>
</template>
</split-pane>
</div>
<el-dialog title="编辑指标百科" :visible.sync="editMemoryVisible" width="720px">
<div>
<el-input
type="textarea"
:close-on-click-modal="false"
:close-on-press-escape="false"
:autosize="{ minRows: 4, maxRows: 8}"
placeholder="请输入指标百科"
v-model="editingMemoryInput"
></el-input>
</div>
<span slot="footer" class="dialog-footer">
<el-button size="mini" @click="editMemoryVisible = false">取消</el-button>
<el-button size="mini" type="primary" @click="confirmAddMemo">确认</el-button>
</span>
</el-dialog>
<el-dialog title="方法参数"
@close="closeEditFuction"
:visible.sync="editFuctionVisible"
width="900px">
<div>
<calculater ref="functionCalculater" :treeData="treeData" type="function" />
</div>
<span slot="footer" class="dialog-footer">
<el-button size="mini" @click="editFuctionVisible = false">取消</el-button>
<el-button size="mini" type="primary" @click="confirmAddFunction">确认</el-button>
</span>
</el-dialog>
<el-dialog :title="addOrEditCategoryTitle"
:visible.sync="addOrEditCategoryVisible"
width="360px" >
<div>
<el-input placeholder="请输入分类名称" size="small" v-model="inputedCategoryName"></el-input>
</div>
<span slot="footer" class="dialog-footer">
<el-button size="mini" @click="addOrEditCategoryVisible = false">取消</el-button>
<el-button
size="mini"
type="primary"
@click="createOrChangeCategory"
:loading="createOrChangeCategoryLoading"
>确认</el-button>
</span>
</el-dialog>
<el-dialog title="测试运行指标"
:close-on-press-escape="false"
:close-on-click-modal="false"
:visible.sync="testRunVisible"
width="800px">
<div class="test-run-box">
<div class="detail-index">
<div class="title">当前指标:</div>
<div class="detail">
<span>{{activeIndex.IndexName}}</span>
</div>
</div>
<condition style="padding: 20px 0" ref="conditionChoose" :params="activeIndex.Args" :allParams="defaultTypeList" />
<div class="detail-index" style="align-items: flex-start">
<div class="title">标的选择:</div>
<div class="detail" style="color: #333">
<div class="flex-form-cintent">
<div style="margin-bottom: 20px">
<el-checkbox
:indeterminate="companyStatusCheck.isIndeterminate"
v-model="companyStatusCheck.checkAll"
@change="handleCheckAllChange($event, companyStatusCheck)"
>全选</el-checkbox>
<el-checkbox-group
v-model="companyStatusCheck.checkedItems"
@change="handleCheckedResults($event, companyStatusCheck)"
>
<el-checkbox
v-for="item in companyStatusData"
:value="item['F90063V']"
:label="item['F90063V']"
:key="item['F90063V']"
>{{item['F90064V']}}</el-checkbox>
</el-checkbox-group>
</div>
<div class="flex-form-detail no-bg">
<el-tabs
v-model="activeRangeTab"
class="mini-size"
style="margin-bottom: 12px"
type="card"
>
<el-tab-pane label="单个添加" :name="'3'">
<div>
<el-select
v-model="rangeCompany"
filterable
remote
@change="addRangeCompany"
placeholder="请输入名称或代码"
:remote-method="searchRunningCompany"
:loading="searchCompanyLoading"
size="mini"
>
<el-option
v-for="item in runningCompanyList"
:key="item.F90001V"
:label="item.F90002V + ' ' + item.F90001V"
:value="item.F90002V + ',' + item.F90001V"
></el-option>
</el-select>
</div>
</el-tab-pane>
<el-tab-pane label="excel导入" :name="'6'">
<div
style="padding-bottom: 8px; color: #999; font-size: 12px"
>excel格式:表为两列, 表头必须为字符"name"、"code", 表身对应为证券简称、证券代码</div>
<div>
<input type="file" @change="selectedExcel" />
</div>
<div style="padding-top: 12px">
<span style="color: #d0021b; font-size: 12px; cursor: pointer" @click="downloadExample">下载示例表格</span>
</div>
</el-tab-pane>
<!-- <el-tab-pane label="证监会行业" :name="'1'">
<div class="mini-size industry-tree-box">
<el-tree
:indent="8"
accordion
:expand-on-click-node="false"
@node-click="searchCompanyByIndustry($event, 1)"
:data="zjhIndustryData"
node-key="id"
ref="zjhCategory"
highlight-current
></el-tree>
</div>
</el-tab-pane> -->
<el-tab-pane label="行业分类" :name="'2'">
<div class="mini-size industry-tree-box">
<el-tree
:indent="8"
accordion
:expand-on-click-node="false"
@node-click="searchCompanyByIndustry($event, 1)"
:data="zjhIndustryData"
node-key="id"
ref="zjhCategory"
></el-tree>
<el-tree
:indent="8"
accordion
:expand-on-click-node="false"
@node-click="searchCompanyByIndustry($event, 2)"
:data="swIndustryData"
node-key="id"
ref="swCategory"
></el-tree>
</div>
</el-tab-pane>
<el-tab-pane label="市场分类" :name="'5'">
<div class="mini-size industry-tree-box">
<el-tree
:indent="8"
accordion
:data="marketData"
highlight-current
ref="marketCategory"
:expand-on-click-node="false"
@node-click="searchCompanyByIndustry($event, 3)"
></el-tree>
</div>
</el-tab-pane>
<el-tab-pane label="地域分类" :name="'4'">
<div class="mini-size industry-tree-box">
<el-tree
:indent="8"
accordion
:data="positionData"
highlight-current
ref="posCategory"
:expand-on-click-node="false"
@node-click="searchCompanyByIndustry($event, 4)"
></el-tree>
</div>
</el-tab-pane>
</el-tabs>
<el-table
@sort-change="changeSort"
size="mini"
max-height="300"
v-loading="searchCompanyLoading"
:data="selectedRangeCompany"
:header-cell-style="{background:'#f5f7fa',color:'#666'}"
border
>
<el-table-column width="50" type="index" label="序号"></el-table-column>
<el-table-column width="80" label="证券名称">
<template slot-scope="scope">{{scope.row.name}}</template>
</el-table-column>
<el-table-column width="80" label="证券代码">
<template slot-scope="scope">{{scope.row.code}}</template>
</el-table-column>
<el-table-column prop="result" sortable label="运行结果">
<template slot-scope="scope">{{scope.row.result}}</template>
</el-table-column>
<el-table-column width="80" label="操作">
<template slot-scope="scope">
<span
class="hover-icon el-icon-delete"
@click="selectedRangeCompany.splice(scope.$index, 1)"
>
删除
</span>
</template>
</el-table-column>
</el-table>
<div style="font-size: 12px; margin-top: 8px; color: #d0021b">
<span
class="el-icon-refresh-right"
style="cursor: pointer"
@click="selectedRangeCompany = []"
>清空表格</span>
<span
class="el-icon-upload2"
style="cursor: pointer; margin-left: 12px"
@click="exportExcel"
>导出excel</span>
</div>
</div>
</div>
</div>
</div>
<div class="detail-index">
<div class="title">操作:</div>
<div class="detail">
<el-button type="primary" size="mini" @click="testRunIndex">点击运行</el-button>
</div>
</div>
</div>
</el-dialog>
<el-dialog title="选择指标分类"
:visible.sync="submitCategoryVisible"
width="500px">
<div class="detail-index">
<div class="title" style="text-align: left; color: #999; min-width: 80px">建议分类:</div>
<div class="detail">
<el-cascader
:props="publicProps"
v-model="submitCategory"
size="mini"
style="width: 300px"
:options="publicCategoryOptions">
</el-cascader>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button size="mini" @click="submitCategoryVisible = false">取消</el-button>
<el-button
size="mini"
type="primary"
@click="confirmSubmit()"
:loading="submitLoading"
>确认</el-button>
</span>
</el-dialog>
<el-dialog title="编辑百科"
:visible.sync="editWikiVisible"
width="500px">
<div class="detail-index" style="align-items: flex-start">
<div class="title" style="text-align: left; color: #999; min-width: 80px">编辑百科:</div>
<div class="detail">
<el-input
type="textarea"
:rows="8"
placeholder="请输入内容"
v-model="editWiki">
</el-input>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button size="mini" @click="editWikiVisible = false">取消</el-button>
<el-button
size="mini"
type="primary"
@click="confirmChangeWiki()"
:loading="changeWikiLoading"
>{{editWikiText}}</el-button>
</span>
</el-dialog>
<el-dialog title="复制到其他文件夹"
:visible.sync="copyIndexVisible"
width="800px">
<div class="detail-index" style="align-items: flex-start">
<div class="title" style="text-align: left; color: #999; min-width: 100px">当前指标:</div>
<div class="detail">
<span>{{activeIndex.IndexName}}</span>
</div>
</div>
<div class="detail-index" style="align-items: flex-start">
<div class="title" style="text-align: left; color: #999; min-width: 100px">选择分类(多选):</div>
<div class="detail">
<div>
<el-cascader
:props="cascaderCopyProps"
size="mini"
style="width: 300px"
v-model="copyCategory"
:options="cascaderOptions"
></el-cascader>
</div>
</div>
</div>
<div class="detail-index" style="align-items: flex-start">
<div class="title" style="text-align: left; color: #999; min-width: 100px">修改备注:</div>
<div class="detail">
<el-input
type="textarea"
:rows="8"
placeholder="请输入修改备注,对操作作具体说明"
v-model="copyIndexMemo">
</el-input>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button size="mini" @click="copyIndexVisible = false">取消</el-button>
<el-button
size="mini"
type="primary"
@click="submitCopyChange()"
:loading="copyLoading"
>提交审核</el-button>
</span>
</el-dialog>
<transition name="slide-fade">
<div class="side-modal" v-show="changePositionVisible">
<span class="el-icon-error side-close" @click="closeSideModal"></span>
<h3>修改指标分类</h3>
<div class="side-modal-inner">
<div class="side-tree-box">
<el-tree
draggable
:default-expanded-keys="defaultExpandedKeys"
ref="publicIndexTree"
node-key="myId"
class="small-tree"
show-checkbox
:filter-node-method="copyTreeFilter"
@check-change="handleCheckChange"
@node-drag-leave="handleDragLeave"
@node-drag-over="handleDragOver"
@node-drag-end="handleDragEnd"
@node-drop="handleDrop"
@check="setCheckedKeys"
highlight-current
:expand-on-click-node="false"
:data="copyTreeData"
:allow-drop="allowDrop"
:props="treeProps">
<span class="custom-tree-node" :class="{active: overingKey == node.id}" slot-scope="{ node, data }">
<span class="el-icon-folder" v-show="!data.isIndex"></span>
<span style="font-size: 12px">{{ node.label }}</span>
</span>
</el-tree>
</div>
<div style="padding-top: 12px" v-show="selectIndexKey.length > 0">
<el-button type="primary" size="mini" plain @click="deleteCopyTree">选中指标从所在分类中移除</el-button>
</div>
<div style="margin-top:20px">
<el-input
type="textarea"
:rows="8"
placeholder="请输入修改备注,对操作作具体说明"
v-model="changePositionMemo">
</el-input>
</div>
</div>
<div class="side-modal-operation">
<el-button size="mini" @click="closeSideModal">取消编辑</el-button>
<el-button size="mini" :loading="sortLoading" type="primary" @click="submitSortChange">提交审核</el-button>
</div>
</div>
</transition>
</div>
</template>
\ No newline at end of file
const { publicIndex } = require('./publicIndex.js')
const { indexAudit } = require('./indexAudit.js')
const { myIndex } = require('./myIndex.js')
const { categoryAudit } = require('./categoryAudit.js')
const { indexRecord } = require('./indexRecord.js')
const routes = [
{ path: '/', component: myIndex },
{ path: '/indexAudit', component: indexAudit },
{ path: '/publicIndex', component: publicIndex },
{ path: '/categoryAudit', component: categoryAudit },
{ path: '/indexRecord', component: indexRecord }
]
module.exports = {
routes: routes
}
\ No newline at end of file
...@@ -96,15 +96,15 @@ ...@@ -96,15 +96,15 @@
path: '../../main_views/stockMarket/stockMarket.html', path: '../../main_views/stockMarket/stockMarket.html',
useful: 1 useful: 1
}, },
{ // {
disable: false, // disable: false,
title: "科创中心", // title: "科创中心",
detail: '', // detail: '',
id: 'kcplateIndex', // id: 'kcplateIndex',
name: '科创板', // name: '科创板',
path: './kcplate/index.html', // path: './kcplate/index.html',
useful: 1 // useful: 1
} // }
] ]
}, },
{ {
...@@ -116,7 +116,7 @@ ...@@ -116,7 +116,7 @@
detail: '', detail: '',
id: 'indexManage', id: 'indexManage',
name: '指标管理', name: '指标管理',
path: './indexManage/index.html', path: '../../main_views/indexManage/indexManage.html',
useful: 1 useful: 1
}, },
{ {
......
const { app } = require('electron').remote // const { app } = require('electron').remote
const path = app.getAppPath() // const path = app.getAppPath()
const { main } = require(path + '/src/views/main_views/stockMarket/routers/main/main.js')
const routes = [ // const { main } = require(path + '/src/views/main_views/stockMarket/routers/main/main.js')
{ path: '/', component: main }
] // const routes = [
// { path: '/', component: main }
// ]
// module.exports = {
// routes: routes
// }
class routers {
constructor() {}
getRouters() {
return [
{ path: '/', component: 'main' }
]
}
}
module.exports = {
routes: routes
}
\ No newline at end of file
...@@ -19,12 +19,21 @@ ...@@ -19,12 +19,21 @@
<script src="../../../static/vue-router/vue-router.js"></script> <script src="../../../static/vue-router/vue-router.js"></script>
<script src='../../../static/xlsx/xlsx.full.min.js'></script> <script src='../../../static/xlsx/xlsx.full.min.js'></script>
<script src="../../../static/plTable/index.js"></script> <script src="../../../static/plTable/index.js"></script>
<script src="./routers/router.js"></script>
<script> <script>
const { app } = require('electron').remote const { app } = require('electron').remote
const path = app.getAppPath() const path = app.getAppPath()
const { routes } = require(path + '/src/views/main_views/stockMarket/routers/router.js')
// const { routes } = require('./routers/router.js')
const routes = new routers().getRouters()
console.log(routes)
const router = new VueRouter({ routes }) const router = new VueRouter({ routes })
const http = require(path + '/src/assist/axios.js') const http = require(path + '/src/assist/axios.js')
var info = JSON.parse(localStorage.getItem('userInfo')) var info = JSON.parse(localStorage.getItem('userInfo'))
const { splitPane } = require('vue-splitpane') const { splitPane } = require('vue-splitpane')
Vue.component('split-pane', splitPane) Vue.component('split-pane', splitPane)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment