| @@ -12,3 +12,5 @@ yarn-error.log* | |||
| *.ntvs* | |||
| *.njsproj | |||
| *.sln | |||
| dist.* | |||
| @@ -0,0 +1,181 @@ | |||
| import request from '@/utils/request' | |||
| // 查询统计报列表 | |||
| export function listReporttitle(query) { | |||
| return request({ | |||
| url: '/entity/reporttitle/list', | |||
| method: 'get', | |||
| params: query | |||
| }) | |||
| } | |||
| // 导出统计报 | |||
| export function exportReporttitle(query) { | |||
| return request({ | |||
| url: '/entity/reporttitle/export', | |||
| method: 'get', | |||
| params: query | |||
| }) | |||
| } | |||
| // 查询统计报详细 | |||
| export function getReporttitle(id) { | |||
| return request({ | |||
| url: '/entity/reporttitle/get/' + id, | |||
| method: 'get' | |||
| }) | |||
| } | |||
| // 新增统计报 | |||
| export function addReporttitle(data) { | |||
| return request({ | |||
| url: '/entity/reporttitle/add', | |||
| method: 'post', | |||
| data: data | |||
| }) | |||
| } | |||
| // 修改统计报 | |||
| export function updateReporttitle(data) { | |||
| return request({ | |||
| url: '/entity/reporttitle/edit', | |||
| method: 'post', | |||
| data: data | |||
| }) | |||
| } | |||
| // 删除统计报 | |||
| export function delReporttitle(id) { | |||
| return request({ | |||
| url: '/entity/reporttitle/remove/' + id, | |||
| method: 'get' | |||
| }) | |||
| } | |||
| // 启用统计报 | |||
| export function enableReporttitle(id) { | |||
| return request({ | |||
| url: '/entity/reporttitle/enable/' + id, | |||
| method: 'post' | |||
| }) | |||
| } | |||
| // 禁用统计报 | |||
| export function disableReporttitle(id) { | |||
| return request({ | |||
| url: '/entity/reporttitle/disable/' + id, | |||
| method: 'post' | |||
| }) | |||
| } | |||
| // 获取模板 | |||
| export function getReportTemplate(id) { | |||
| return request({ | |||
| url: '/entity/reporttitle/template/' + id, | |||
| method: 'get' | |||
| }) | |||
| } | |||
| // 获取横向模板 | |||
| export function getReportHorizontalTemplate(id) { | |||
| return request({ | |||
| url: '/entity/reporttitle/horizontalTemplate/' + id, | |||
| method: 'get' | |||
| }) | |||
| } | |||
| // 查询统计填报列表 | |||
| export function listReport(query) { | |||
| return request({ | |||
| url: '/entity/report/list', | |||
| method: 'get', | |||
| params: query | |||
| }) | |||
| } | |||
| // 导出统计填报 | |||
| export function exportReport(query) { | |||
| return request({ | |||
| url: '/entity/report/export', | |||
| method: 'get', | |||
| params: query | |||
| }) | |||
| } | |||
| // 查询统计填报详细 | |||
| export function getReport(id) { | |||
| return request({ | |||
| url: '/entity/report/get/' + id, | |||
| method: 'get' | |||
| }) | |||
| } | |||
| // 新增统计填报 | |||
| export function addReport(data) { | |||
| return request({ | |||
| url: '/entity/report/add', | |||
| method: 'post', | |||
| data: data | |||
| }) | |||
| } | |||
| // 修改统计填报 | |||
| export function updateReport(data) { | |||
| return request({ | |||
| url: '/entity/report/edit', | |||
| method: 'post', | |||
| data: data | |||
| }) | |||
| } | |||
| // 删除统计填报 | |||
| export function delReport(id) { | |||
| return request({ | |||
| url: '/entity/report/remove/' + id, | |||
| method: 'get' | |||
| }) | |||
| } | |||
| // 导出统计填报 | |||
| export function reportExport(id) { | |||
| return request({ | |||
| url: '/entity/report/reportExport/' + id, | |||
| method: 'get', | |||
| }) | |||
| } | |||
| // 竖向统计 | |||
| export function summaryStatistics(query) { | |||
| return request({ | |||
| url: '/entity/report/summaryStatistics', | |||
| method: 'get', | |||
| params: query | |||
| }) | |||
| } | |||
| // 导出竖向统计 | |||
| export function summaryStatisticsExport(query) { | |||
| return request({ | |||
| url: '/entity/report/summaryStatisticsExport', | |||
| method: 'get', | |||
| params: query | |||
| }) | |||
| } | |||
| // 横向统计 | |||
| export function horizontalSummaryStatistics(query) { | |||
| return request({ | |||
| url: '/entity/report/horizontalSummaryStatistics', | |||
| method: 'get', | |||
| params: query | |||
| }) | |||
| } | |||
| // 导出横向统计 | |||
| export function horizontalSummaryStatisticsExport(query) { | |||
| return request({ | |||
| url: '/entity/report/horizontalSummaryStatisticsExport', | |||
| method: 'get', | |||
| params: query | |||
| }) | |||
| } | |||
| @@ -14,18 +14,33 @@ | |||
| :rules="rules" | |||
| :required="required" | |||
| :label-width="labelWidth || 'auto'" | |||
| :input-align="inputAlign || 'left'" | |||
| > | |||
| <!-- <template #button> | |||
| <van-icon name="notes-o" size="20"/> | |||
| </template>--> | |||
| </van-field> | |||
| <van-popup v-model="popupVisible" position="bottom"> | |||
| <van-popup v-model="popupVisible" position="bottom" v-if="type === 'year'"> | |||
| <van-picker | |||
| ref="picker" | |||
| :title="label" | |||
| show-toolbar | |||
| :columns="yearColumns" | |||
| :readonly="readonly" | |||
| v-model="internalValue" | |||
| @confirm="onConfirm" | |||
| @cancel="onCancel" | |||
| @change="onChanged" | |||
| /> | |||
| </van-popup> | |||
| <van-popup v-model="popupVisible" position="bottom" v-else> | |||
| <van-datetime-picker | |||
| ref="picker" | |||
| v-model="internalValue" | |||
| :type="type || 'date'" | |||
| :readonly="readonly" | |||
| :title="label" | |||
| :title="label || ''" | |||
| @confirm="onConfirm" | |||
| @cancel="onCancel" | |||
| @change="onChanged" | |||
| @@ -37,14 +52,16 @@ | |||
| <script> | |||
| import { formatDate } from "element-ui/src/utils/date-util.js" | |||
| import {strtotime} from "@/utils"; | |||
| export default { | |||
| name: "fieldDatePicker", | |||
| props: [ | |||
| 'name', 'readonly', 'value', 'label', 'placeholder', 'required', 'rules', 'labelWidth', | |||
| 'type', // 类型, 仅支持 datetime date time year-month month-day datehour | |||
| 'name', 'readonly', 'value', 'label', 'placeholder', 'required', 'rules', 'labelWidth', 'inputAlign', | |||
| 'type', // 类型, 仅支持 datetime date time year-month month-day datehour, 额外支持year(但formatter必须为yyyy, 可以提供yearRangeLength=<Number>指定年范围) | |||
| 'formatter', // value的格式化 String|Function|undefined 字符串为格式字符串, 函数则必须有返回 undefined则不转换 | |||
| 'clearable', // 点击取消时清空绑定值 | |||
| 'yearRangeLength', // type === 'year' 时生成的年份数量范围 [YEAR - yearRangeLength, YEAR + yearRangeLength] | |||
| ], | |||
| watch: { | |||
| value: function (newVal, oldVal) { | |||
| @@ -75,7 +92,7 @@ export default { | |||
| openPopup() { | |||
| if(!this.readonly) | |||
| { | |||
| console.log(this.internalValue); | |||
| //console.log(this.internalValue); | |||
| this.popupVisible = true; | |||
| this.$nextTick(() => { | |||
| try | |||
| @@ -83,8 +100,9 @@ export default { | |||
| if(1) | |||
| { | |||
| let values = (this.visibleValue || this.getValue(new Date)).split(/\D+/); //TODO: 按非数字符号粗略分割解析初始值, 仅对于类似yyyy-MM-dd | |||
| console.log(values); | |||
| this.$refs.picker.getPicker().setValues(values); | |||
| //console.log(values); | |||
| let picker = this.$refs.picker.getPicker ? this.$refs.picker.getPicker() : this.$refs.picker; | |||
| picker.setValues(values); | |||
| } | |||
| else { | |||
| //TODO: 打开时保存初始值, 取消或点击遮罩未确定的时候恢复该初始值到v-model | |||
| @@ -132,7 +150,39 @@ export default { | |||
| this.internalValue = data; | |||
| this.visibleValue = this.getValue(data); | |||
| }, | |||
| genYearColumns(num) { | |||
| let d; | |||
| try | |||
| { | |||
| if(this.value) | |||
| { | |||
| d = strtotime(this.value, 'yyyy'); | |||
| } | |||
| else | |||
| d = new Date; | |||
| } | |||
| catch(e) | |||
| { | |||
| d = new Date; | |||
| } | |||
| let y = d.getFullYear(); | |||
| let arr = ['' + y]; | |||
| for(let i = 1; i <= num; i++) | |||
| { | |||
| arr.push('' + (y + i)); | |||
| arr.splice(0, 0, '' + (y - i)); | |||
| } | |||
| return arr; | |||
| }, | |||
| strtotime, | |||
| }, | |||
| computed: { | |||
| yearColumns() { | |||
| if(this.type !== 'year') | |||
| return []; | |||
| return this.genYearColumns(this.yearRangeLength || 100); | |||
| }, | |||
| } | |||
| } | |||
| </script> | |||
| @@ -3444,6 +3444,24 @@ export const constantRoutes = [ | |||
| }, | |||
| component: (resolve) => require(['@/views/sunVillage_info/list_register_detail'], resolve) | |||
| }, | |||
| { // 综合填报 | |||
| path: '/sunVillage_info/entityReportList', | |||
| name: 'entityReportList', | |||
| meta: { | |||
| title: '综合填报', | |||
| hidden: true, | |||
| }, | |||
| component: (resolve) => require(['@/views/sunVillage_info/entityReport/reportList'], resolve) | |||
| }, | |||
| { // 综合填报 | |||
| path: '/sunVillage_info/entityReportView', | |||
| name: 'entityReportView', | |||
| meta: { | |||
| title: '综合填报', | |||
| hidden: true, | |||
| }, | |||
| component: (resolve) => require(['@/views/sunVillage_info/entityReport/reportView'], resolve) | |||
| }, | |||
| { // 统计填报 | |||
| path: '/sunVillage_info/statistical_report', | |||
| name: 'sunVillageInfoStatisticalReport', | |||
| @@ -0,0 +1,512 @@ | |||
| export const Expression = function(_str, _flag = 0, _placeholderValueMap = {}) | |||
| { | |||
| this.pos = 0; // 当前解析表达式字符串的位置 | |||
| this.str = _str; // 表达式 | |||
| this.errno = Expression.NO_ERROR; // 当前错误码 | |||
| this.placeholderValueMap = _placeholderValueMap; // 占位符值字典 | |||
| this.flag = _flag | Expression.PARSE_FLAG_ERROR_HANDLE_SCHEME_THROW_EXCEPTION; // 行为标记 | |||
| this.placeholders = []; | |||
| } | |||
| Expression.NO_ERROR = 0; | |||
| Expression.ERROR = 1; | |||
| Expression.NULL_STRING = 2; | |||
| Expression.BY_ZERO = 3; | |||
| Expression.MISSING_DIGIT = 4; | |||
| Expression.MISSING_RIGHT_PARENT = 5; | |||
| Expression.MISSING_OPERATOR = 6; | |||
| Expression.INVALID_CHARACTER = 7; | |||
| Expression.MISSING_PLACEHOLDER = 8; | |||
| Expression.INVALID_DIGIT = 9; | |||
| Expression.INVALID_PLACEHOLDER = 10; | |||
| Expression.MISSING_RIGHT_PLACEHOLDER_END = 11; | |||
| Expression.INVALID_PLACEHOLDER_FUNCTION = 12; | |||
| Expression.MISSING_COMPARE_OPERATOR = 13; | |||
| Expression.INVALID_COMPARE_OPERATOR = 14; | |||
| Expression.INCOMPLETE = 15; | |||
| Expression.ErrorStr = [ | |||
| "", | |||
| "错误", | |||
| "空字符串", | |||
| "除0", | |||
| "缺失数字", | |||
| "缺失右括号", | |||
| "缺失运算符", | |||
| "无效字符", | |||
| "缺失占位符", | |||
| "无效数字", | |||
| "无效占位符", | |||
| "缺失占位符结尾标识", | |||
| "无效占位符内置函数", | |||
| "缺失比较运算符", | |||
| "无效比较运算符", | |||
| "表达式不完整", | |||
| ]; | |||
| Expression.PARSE_FLAG_NONE = 0; | |||
| Expression.PARSE_FLAG_ERROR_HANDLE_SCHEME_RETURN_ZERO = 1; // 解析到错误则当前部分返回0 | |||
| Expression.PARSE_FLAG_ERROR_HANDLE_SCHEME_THROW_EXCEPTION = 1 << 1; // 解析到错误则抛出异常 | |||
| Expression.PARSE_FLAG_ALL_NUMBER_AS_PLACEHOLDER = 1 << 3; // 所有数字都作为占位符 | |||
| Expression.PARSE_FLAG_IGNORE_ERROR_MISSING_PLACEHOLDER = 1 << 4; // 忽略占位符缺失 | |||
| Expression.PARSE_FLAG_IGNORE_ERROR_BY_ZERO = 1 << 5; // 忽略除0 | |||
| // 是否读取到字符串结尾 | |||
| Expression.prototype.__EOF = function() | |||
| { | |||
| return !this.str || this.pos >= this.str.length; | |||
| }; | |||
| // 字符串转为数字 | |||
| Expression.prototype.__StrTo = function(numStr) | |||
| { | |||
| return Number(numStr) | |||
| }; | |||
| // 开始解析, 重置状态 | |||
| Expression.prototype.__Ready = function() | |||
| { | |||
| this.pos = 0; | |||
| this.errno = Expression.NO_ERROR; | |||
| this.placeholders = []; | |||
| let err = this.__CheckStr(); | |||
| return (err === Expression.NO_ERROR); | |||
| }; | |||
| // 解析 值 括号 占位符 的优先级最高的表达式 | |||
| Expression.prototype.__EvalV = function() | |||
| { | |||
| if(this.__EOF()) | |||
| { | |||
| return this.__FatalError(Expression.INCOMPLETE); | |||
| } | |||
| this.__SkipBlank(); | |||
| let nStr = this.str.substring(this.pos); | |||
| let p = 0; | |||
| let nag = false; | |||
| let result = 0; | |||
| if(nStr.charAt(p) === '-') | |||
| { | |||
| nag = true; | |||
| this.pos++; | |||
| p++; | |||
| } | |||
| p += this.__SkipBlank(); | |||
| if(nStr.charAt(p) === '(') // 括号表达式 | |||
| { | |||
| p++; | |||
| this.pos++; | |||
| result = this.__EvalP(); | |||
| if(this.str.charAt(this.pos) !== ')') | |||
| { | |||
| return this.__FatalError(Expression.MISSING_RIGHT_PARENT); | |||
| } | |||
| this.pos++; | |||
| } | |||
| else if(nStr.charAt(p) === '{') // 占位符 | |||
| { | |||
| p++; | |||
| this.pos++; | |||
| p += this.__SkipBlank(); | |||
| let d = ''; | |||
| let size = 0; | |||
| let ch = nStr.charAt(p); | |||
| while("`~@#%^&*()-+=,/?:;\"'|\\[{]}".indexOf(ch) === -1) // 中文支持 | |||
| { | |||
| size++; | |||
| d += ch; | |||
| p++; | |||
| this.pos++; | |||
| if(p >= nStr.length) | |||
| { | |||
| return this.__FatalError(Expression.MISSING_RIGHT_PLACEHOLDER_END); | |||
| } | |||
| ch = nStr.charAt(p); | |||
| } | |||
| p += this.__SkipBlank(); | |||
| if(this.str.charAt(this.pos) !== '}') | |||
| { | |||
| return this.__FatalError(Expression.MISSING_RIGHT_PLACEHOLDER_END); | |||
| } | |||
| this.pos++; | |||
| if(size > 0) | |||
| { | |||
| result = this.__ParsePlaceholder(d); | |||
| } | |||
| else | |||
| { | |||
| return this.__NormalError(Expression.MISSING_PLACEHOLDER); | |||
| } | |||
| } | |||
| else // 纯数字 | |||
| { | |||
| let d = ''; | |||
| let size = 0; | |||
| let ch = nStr.charAt(p); | |||
| while((ch >= '0' && ch <= '9') || ch === '.') | |||
| { | |||
| size++; | |||
| d += ch; | |||
| p++; | |||
| this.pos++; | |||
| if(p >= nStr.length) | |||
| break; | |||
| ch = nStr.charAt(p); | |||
| } | |||
| if(size > 0) | |||
| { | |||
| let m = d.indexOf("."); | |||
| if(m !== -1) | |||
| { | |||
| let n = d.lastIndexOf("."); | |||
| if(n !== -1 && m !== n) | |||
| { | |||
| return this.__FatalError(Expression.INVALID_DIGIT); | |||
| } | |||
| if(m === 0 || m === d.length - 1) | |||
| d = d.substr(0, m) + d.substr(m + 1); | |||
| } | |||
| if(this.flag & Expression.PARSE_FLAG_ALL_NUMBER_AS_PLACEHOLDER) | |||
| result = this.__ParsePlaceholder(d); | |||
| else | |||
| result = this.__StrTo(d); | |||
| } | |||
| else | |||
| { | |||
| return this.__FatalError(Expression.MISSING_DIGIT); | |||
| } | |||
| } | |||
| if(nag) | |||
| result = -result; | |||
| return result; | |||
| }; | |||
| // 解析* /的优先级相对较高的表达式 | |||
| Expression.prototype.__EvalM = function() | |||
| { | |||
| if(this.__EOF()) | |||
| { | |||
| return this.__FatalError(Expression.INCOMPLETE); | |||
| } | |||
| let first = this.__EvalV(); | |||
| let result = first; | |||
| this.__SkipBlank(); | |||
| let nStr = this.str.substring(this.pos); | |||
| while(nStr.length > 0) | |||
| { | |||
| let ch = nStr.charAt(0); | |||
| if(ch !== '*' && ch !== '/') | |||
| return result; | |||
| else | |||
| { | |||
| this.pos++; | |||
| let second = this.__EvalV(); | |||
| if(ch === '*') | |||
| result = result *second; | |||
| else | |||
| { | |||
| if(second === 0) | |||
| { | |||
| return this.__NormalError(Expression.BY_ZERO); | |||
| } | |||
| result = result / second; | |||
| } | |||
| } | |||
| nStr = this.str.substring(this.pos); | |||
| } | |||
| return result; | |||
| }; | |||
| // 解析+ -的优先级最低的表达式 | |||
| Expression.prototype.__EvalP = function() | |||
| { | |||
| if(this.__EOF()) | |||
| { | |||
| return this.__FatalError(Expression.INCOMPLETE); | |||
| } | |||
| this.__SkipBlank(); | |||
| let first = this.__EvalM(); | |||
| let result = first; | |||
| let nStr = this.str.substring(this.pos); | |||
| while(nStr.length > 0) | |||
| { | |||
| let ch = nStr.charAt(0); | |||
| if(ch !== '+' && ch !== '-') | |||
| return result; | |||
| else | |||
| { | |||
| this.pos++; | |||
| let second = this.__EvalM(); | |||
| if(ch === '+') | |||
| result = result + second; | |||
| else | |||
| result = result - second; | |||
| } | |||
| nStr = this.str.substring(this.pos); | |||
| } | |||
| return result; | |||
| }; | |||
| // 解析比较运算符 | |||
| Expression.prototype.__EvalCmp = function() | |||
| { | |||
| if(this.__EOF()) | |||
| { | |||
| return this.__FatalError(Expression.MISSING_COMPARE_OPERATOR); | |||
| } | |||
| this.__SkipBlank(); | |||
| let result = ''; | |||
| let nStr = this.str.substring(this.pos); | |||
| while(nStr.length > 0) | |||
| { | |||
| let ch = nStr.charAt(0); | |||
| if(ch !== '=' && ch !== '!' && ch !== '>' && ch !== '<') | |||
| break; | |||
| else | |||
| { | |||
| if(result.length === 0) | |||
| { | |||
| result += ch; | |||
| this.pos++; | |||
| } | |||
| else // === 1 | |||
| { | |||
| if(result !== "=") // 如果第一个字符不是=, 第二个字符必定是= | |||
| { | |||
| if(ch !== '=') | |||
| return this.__FatalError(Expression.INVALID_COMPARE_OPERATOR); | |||
| } | |||
| else // 如果第一个字符是=, 第二个字符可以是= | |||
| { | |||
| if(ch === '=') | |||
| result += ch; | |||
| else | |||
| { | |||
| break; | |||
| } | |||
| } | |||
| result += ch; | |||
| this.pos++; | |||
| } | |||
| } | |||
| if(result.length >= 2) | |||
| break; | |||
| nStr = this.str.substring(this.pos); | |||
| } | |||
| if(result === "=") | |||
| result = "=="; | |||
| return result; | |||
| }; | |||
| // 开始计算 | |||
| Expression.prototype.Calc = function() | |||
| { | |||
| if(!this.__Ready()) | |||
| return this.__OnError(0); | |||
| return this.__EvalP(); | |||
| }; | |||
| // 判断表达式断言 | |||
| Expression.prototype.Predicate = function() | |||
| { | |||
| if(!this.__Ready()) | |||
| return this.__OnError(false); | |||
| let a = this.__EvalP(); | |||
| if(this.HasError()) | |||
| return this.__OnError(false); | |||
| let op = this.__EvalCmp(); | |||
| if(this.HasError()) | |||
| return this.__OnError(false); | |||
| let b = this.__EvalP(); | |||
| if(this.HasError()) | |||
| return this.__OnError(false); | |||
| //console.log(a + op + b); | |||
| return eval(a + op + b); | |||
| }; | |||
| Expression.prototype.FLAG = function(flags) | |||
| { | |||
| for(let i of arguments) | |||
| { | |||
| if((this.flag & i) === i) | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| // 普通错误, 仅设置可允许忽略的错误时调用, 错误被忽略时不设置错误码 | |||
| Expression.prototype.__NormalError = function(err) | |||
| { | |||
| switch(err) | |||
| { | |||
| case Expression.BY_ZERO: | |||
| if(this.FLAG(Expression.PARSE_FLAG_IGNORE_ERROR_BY_ZERO)) | |||
| return 0; | |||
| break; | |||
| case Expression.MISSING_PLACEHOLDER: | |||
| if(this.FLAG(Expression.PARSE_FLAG_IGNORE_ERROR_MISSING_PLACEHOLDER)) | |||
| return 0; | |||
| break; | |||
| case Expression.INVALID_DIGIT: | |||
| if(this.FLAG(Expression.PARSE_FLAG_IGNORE_ERROR_INVALID_DIGIT)) | |||
| return 0; | |||
| break; | |||
| } | |||
| return this.__FatalError(err); | |||
| }; | |||
| // 全局错误处理 | |||
| Expression.prototype.__OnError = function(ifError) | |||
| { | |||
| if(this.FLAG(Expression.PARSE_FLAG_ERROR_HANDLE_SCHEME_THROW_EXCEPTION)) // 抛异常 | |||
| { | |||
| throw new Error(this.Error()); | |||
| } | |||
| else // 返回0 | |||
| { | |||
| return ifError; | |||
| } | |||
| }; | |||
| // 计算是否有错误 | |||
| Expression.prototype.HasError = function() | |||
| { | |||
| return this.errno !== Expression.NO_ERROR; | |||
| }; | |||
| // 返回计算的错误, 并清除错误 | |||
| Expression.prototype.GetError = function() | |||
| { | |||
| let e = this.errno; | |||
| this.errno = Expression.NO_ERROR; | |||
| return e; | |||
| } | |||
| // 获取当前错误的字符串 | |||
| Expression.prototype.Error = function() | |||
| { | |||
| return Expression.ErrorStr[this.errno]; | |||
| } | |||
| // 致命错误 | |||
| Expression.prototype.__FatalError = function(err) | |||
| { | |||
| this.errno = err; | |||
| throw new Error(this.Error()); | |||
| }; | |||
| Expression.prototype.ParsedPlaceholders = function() | |||
| { | |||
| return this.placeholders; | |||
| } | |||
| // 解析占位符 | |||
| Expression.prototype.__ParsePlaceholder = function(name) | |||
| { | |||
| this.placeholders.push(name); | |||
| if(!this.placeholderValueMap) | |||
| { | |||
| return this.__NormalError(Expression.MISSING_PLACEHOLDER); | |||
| } | |||
| if(name.startsWith("$")) // 特殊环境变量 | |||
| return this.__ParseNumber(this.placeholderValueMap[name]); | |||
| let ptr = this.placeholderValueMap; | |||
| let d = null; | |||
| let notFetch = false; | |||
| let i = 0; | |||
| do | |||
| { | |||
| let index = name.indexOf(".", i); | |||
| let s = index === -1 ? name.substring(i) : name.substring(i, index); | |||
| i += s.length + 1; | |||
| s = s.trim(); | |||
| if(s.startsWith("$")) // 函数管线 | |||
| { | |||
| if(!notFetch) // 此时当前值应该是数字, 不再继续向下取Object/Map | |||
| { | |||
| d = this.__ParseNumber(ptr); // 当前值转换为数字 | |||
| notFetch = true; // 此时当前值应该是数字, 不再继续向下取Object/Map | |||
| } | |||
| switch(s.substring(1).toLowerCase()) | |||
| { | |||
| case "abs": | |||
| d = Math.abs(d); | |||
| break; | |||
| case "neg": | |||
| d = -d; | |||
| break; | |||
| case "lt0": | |||
| if(d >= 0) | |||
| return 0; | |||
| break; | |||
| case "gt0": | |||
| if(d <= 0) | |||
| return 0; | |||
| break; | |||
| default: | |||
| return this.__FatalError(Expression.INVALID_PLACEHOLDER_FUNCTION); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| if(notFetch/*null != d*/) // TODO: 被管线函数处理过, 占位符表达式书写不应该出现该情况, 管线函数应都在表达式尾部, 并且不在表达式起始 | |||
| return d; | |||
| ptr = ptr[s]; | |||
| if(null === ptr || undefined === ptr) | |||
| { | |||
| return this.__NormalError(Expression.MISSING_PLACEHOLDER); | |||
| } | |||
| } | |||
| } while(i < name.length); | |||
| if(null == d) | |||
| return this.__ParseNumber(ptr); | |||
| else | |||
| return d; | |||
| }; | |||
| // 检查表达式字符串 | |||
| Expression.prototype.__CheckStr = function() | |||
| { | |||
| if(!this.str) | |||
| { | |||
| return Expression.NULL_STRING; | |||
| } | |||
| return Expression.NO_ERROR; | |||
| }; | |||
| // 跳过空白符 | |||
| Expression.prototype.__SkipBlank = function() | |||
| { | |||
| let i = 0; | |||
| for(; (this.pos + i) < this.str.length; i++) | |||
| { | |||
| if(!/\s/.test(this.str.charAt(this.pos + i))) | |||
| break; | |||
| } | |||
| this.pos += i; | |||
| return i; | |||
| }; | |||
| // 对象转数字 | |||
| Expression.prototype.__ParseNumber = function(val) | |||
| { | |||
| if(null === val) | |||
| return this.__NormalError(Expression.INVALID_DIGIT); | |||
| if(val instanceof Number) | |||
| return val; | |||
| else | |||
| { | |||
| try | |||
| { | |||
| return this.__StrTo(val.toString()); | |||
| } | |||
| catch(e) | |||
| { | |||
| console.error(e); | |||
| return this.__NormalError(Expression.INVALID_DIGIT); | |||
| } | |||
| } | |||
| }; | |||
| @@ -1206,3 +1206,14 @@ export function manual_page(list, page_no = 1, page_size = 10) | |||
| let start = (page_no - 1) * page_size; | |||
| return list.slice(start, start + page_size); | |||
| } | |||
| export function array_toMap(arr, byFunc, overriding) | |||
| { | |||
| let res = {}; | |||
| arr.forEach((x) => { | |||
| let a = byFunc(x); | |||
| if(!res.hasOwnProperty(a) || overriding) | |||
| res[a] = x; | |||
| }); | |||
| return res; | |||
| } | |||
| @@ -158,3 +158,7 @@ export function isBankCard (str_cardNo) { | |||
| return false; | |||
| } | |||
| } | |||
| export function is_not_number(val) { | |||
| return (val === null || val === undefined || val === ''); | |||
| } | |||
| @@ -0,0 +1,278 @@ | |||
| <template> | |||
| <div class="app-container"> | |||
| <div class="header_main-placeholder"> | |||
| <div class="header_main"> | |||
| 综合填报 | |||
| <div class="return_btn" @click="$router.back()"></div> | |||
| <div class="add_btn" @click="add"></div> | |||
| </div> | |||
| </div> | |||
| <van-pull-refresh v-model="refreshing" @refresh="getList()"> | |||
| <van-list | |||
| class="list_main" | |||
| v-model="loading" | |||
| :finished="finished" | |||
| finished-text="没有更多了" | |||
| @load="getList('+1')" | |||
| > | |||
| <van-swipe-cell class="item" v-for="(item,index) in list" :key="index"> | |||
| <div class="item_box" @click="view(item)"> | |||
| <div class="head_block"> | |||
| <i class="icon"></i> | |||
| <div class="title">{{item.reportName}}</div> | |||
| </div> | |||
| <div class="order_block"> | |||
| <div class="flex_block"> | |||
| <i class="icon icon_1"></i> | |||
| <div class="text">{{item.operatorDate}}</div> | |||
| </div> | |||
| <div class="flex_block" v-if="item.operatorName"> | |||
| <i class="icon icon_2"></i> | |||
| <div class="text">{{item.operatorName}}</div> | |||
| </div> | |||
| <div class="flex_block" v-if="item.operatorDepartment"> | |||
| <i class="icon icon_2"></i> | |||
| <div class="text">{{item.operatorDepartment}}</div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <template #right> | |||
| <van-row class="full-height toolbar"> | |||
| <van-col class="full-height"> | |||
| <van-button square text="修改" type="info" :to="{name:'entityReportView', query: {reportId:item.id, intent: 'edit'}}" class="full-height" /> | |||
| </van-col> | |||
| <van-col class="full-height"> | |||
| <van-button square text="删除" type="danger" @click="remove(item,index)" class="full-height" /> | |||
| </van-col> | |||
| </van-row> | |||
| </template> | |||
| </van-swipe-cell> | |||
| </van-list> | |||
| </van-pull-refresh> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import {delReport, listReport} from "@/api/sunVillage_info/entity/report.js"; | |||
| export default { | |||
| name: "ReportList", | |||
| data() { | |||
| return { | |||
| list:[], | |||
| loading: false, | |||
| finished: false, | |||
| refreshing: false, | |||
| total: 0, | |||
| queryParams:{ | |||
| pageNum:1, | |||
| pageSize:10, | |||
| orderByColumn:'createTime', | |||
| isAsc:'desc' | |||
| } | |||
| }; | |||
| }, | |||
| created() { | |||
| this.getList(); | |||
| }, | |||
| methods: { | |||
| add() { | |||
| this.$router.push({ | |||
| name: 'entityReportView', | |||
| query: { | |||
| intent: 'add', | |||
| } | |||
| }); | |||
| }, | |||
| view(row){ | |||
| this.$router.push({ | |||
| name: 'entityReportView', | |||
| query: { | |||
| intent: 'view', | |||
| reportId: row.id, | |||
| } | |||
| }); | |||
| }, | |||
| getList(target){ | |||
| let type = typeof (target); | |||
| //console.log(type, target); | |||
| if(target && this.finished) | |||
| return; | |||
| if (target === 0) { | |||
| this.refreshing = true; | |||
| this.finished = true; | |||
| this.total = 0; | |||
| this.queryParams.pageNum = 1; | |||
| this.list = []; | |||
| } | |||
| else if (type === 'number') | |||
| this.queryParams.pageNum = target; | |||
| else if (type === 'string') { | |||
| this.queryParams.pageNum = eval(this.queryParams.pageNum + target) | |||
| } | |||
| else | |||
| { | |||
| this.refreshing = true; | |||
| this.finished = true; | |||
| this.total = 0; | |||
| this.queryParams.pageNum = 1; | |||
| this.list = [] | |||
| } | |||
| listReport(this.queryParams).then(response => { | |||
| if (response.rows.length === 0) { | |||
| this.finished = true; | |||
| return; | |||
| } | |||
| this.list = response.rows; | |||
| this.total += response.rows.length; | |||
| this.finished = this.total >= response.total; | |||
| }).finally(() => { | |||
| this.loading = false; | |||
| this.refreshing = false; | |||
| }); | |||
| }, | |||
| remove(row, index){ | |||
| this.$dialog.confirm({ | |||
| message: '您确认删除综合填报?', | |||
| }) | |||
| .then(() => { | |||
| delReport(row.id).then(res => { | |||
| this.$toast.success('删除成功'); | |||
| this.list.splice(index,1); | |||
| }); | |||
| }) | |||
| .catch(() => { | |||
| }); | |||
| }, | |||
| refresh() { | |||
| this.getList(); return; | |||
| this.list = []; | |||
| this.queryParams.pageNum = 1; | |||
| this.refreshing = true; | |||
| this.finished = false; | |||
| }, | |||
| }, | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .app-container { | |||
| //padding: 0.2rem 3%; | |||
| width: 100vw; | |||
| height: 100vh; | |||
| } | |||
| .full-height { | |||
| height: 100%; | |||
| } | |||
| .header_main-placeholder { | |||
| height: 116px; | |||
| } | |||
| .header_main { | |||
| height: 116px; | |||
| background: url('../../../assets/images/sunVillage_info/list_head.png') no-repeat; | |||
| background-size: 100% 100%; | |||
| position: fixed; | |||
| top: 0; | |||
| left: 0; | |||
| width: 100%; | |||
| font-size: 36px; | |||
| line-height: 116px; | |||
| text-align: center; | |||
| color: #fff; | |||
| z-index: 999; | |||
| .return_btn { | |||
| width: 24px; | |||
| height: 43.2px; | |||
| background: url('../../../assets/images/sunVillage_info/list_icon_5.png') center center no-repeat; | |||
| background-size: 20px 36px; | |||
| position: absolute; | |||
| left: 38px; | |||
| top: 36px; | |||
| } | |||
| .add_btn { | |||
| width: 56.4px; | |||
| height: 40.8px; | |||
| background: url('../../../assets/images/sunVillage_info/list_icon_9.png') center center no-repeat; | |||
| background-size: 47px 34px; | |||
| position: absolute; | |||
| right: 38px; | |||
| top: 36px; | |||
| } | |||
| } | |||
| .list_main{ | |||
| padding:26px 22px 0; | |||
| .item{ | |||
| height: 162px; | |||
| border-radius: 30px; | |||
| background: #fff; | |||
| box-shadow: 4px 6px 5px rgba(63, 68, 75, 0.1); | |||
| margin-bottom: 20px; | |||
| .item_box{ | |||
| padding:25px 32px; | |||
| } | |||
| .head_block{ | |||
| height: 62px; | |||
| display: flex; | |||
| align-items: center; | |||
| width: 100%; | |||
| .icon{ | |||
| width: 34px; | |||
| height: 30px; | |||
| background: url('../../../assets/images/sunVillage_info/fixedAssets_icon_4.png') no-repeat; | |||
| background-size: 100% 100%; | |||
| display: block; | |||
| margin-right: 12px; | |||
| } | |||
| .title{ | |||
| flex:1; | |||
| font-size: 32px; | |||
| color: #252525; | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| white-space: nowrap; | |||
| padding-right: 20px; | |||
| } | |||
| } | |||
| .order_block{ | |||
| display: flex; | |||
| height: 52px; | |||
| padding-top: 12px; | |||
| font-size: 24px; | |||
| color: #858585; | |||
| align-items: center; | |||
| padding-bottom: 10px; | |||
| .flex_block{ | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: center; | |||
| margin-right: 28px; | |||
| height: 42px; | |||
| .icon{ | |||
| width: 25px; | |||
| height: 25px; | |||
| margin-top: 3px; | |||
| margin-right: 8px; | |||
| &.icon_1{ | |||
| background: url('../../../assets/images/sunVillage_info/fixedAssets_icon_3.png') no-repeat; | |||
| background-size: 100% 100%; | |||
| } | |||
| &.icon_2{ | |||
| background: url('../../../assets/images/sunVillage_info/fixedAssets_icon_5.png') no-repeat; | |||
| background-size: 100% 100%; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| .toolbar { | |||
| margin-left: 2px; | |||
| } | |||
| </style> | |||
| @@ -0,0 +1,595 @@ | |||
| <template> | |||
| <div class="app-container"> | |||
| <div class="header_main-placeholder"> | |||
| <div class="header_main"> | |||
| 综合填报 | |||
| <div class="return_btn" @click="back"></div> | |||
| <div class="add_btn" @click="save" v-if="(isAdd || isEdit) && editorData.templateId"></div> | |||
| </div> | |||
| </div> | |||
| <van-form ref="form" :class="{'form_readonly': disableEdit}"> | |||
| <van-row> | |||
| <van-col :span="editorData.templateId ? 16 : 24"> | |||
| <field-select | |||
| class="template-selector" | |||
| v-model="editorData.templateId" | |||
| label=" 模板" | |||
| value-key="reportName" | |||
| data-key="id" | |||
| placeholder="报表模板" | |||
| :rules="[{ required: true }]" | |||
| :required="true" | |||
| :readonly="disableEdit" | |||
| :columns="templateList" | |||
| @input="getTemplate" | |||
| /> | |||
| </van-col> | |||
| <van-col span="8" v-if="!!editorData.templateId"> | |||
| <field-date-picker | |||
| class="field_no-label" | |||
| v-model="editorData.reportYear" | |||
| placeholder="报表年度" | |||
| formatter="yyyy" | |||
| :readonly="disableEdit" | |||
| input-align="center" | |||
| type="year" | |||
| /> | |||
| </van-col> | |||
| </van-row> | |||
| <van-row v-if="!!editorData.templateId"> | |||
| <van-col span="8"> | |||
| <van-field class="field_no-label" :readonly="disableEdit" v-model="editorData.titleLeft" label="" placeholder="左上" input-align="left"/> | |||
| </van-col> | |||
| <van-col span="8"> | |||
| <van-field class="field_no-label" :readonly="disableEdit" v-model="editorData.titleCenter" label="" placeholder="中上" input-align="center"/> | |||
| </van-col> | |||
| <van-col span="8"> | |||
| <van-field class="field_no-label" :readonly="disableEdit" v-model="editorData.titleRight" label="" placeholder="右上" input-align="right"/> | |||
| </van-col> | |||
| </van-row> | |||
| <div class="main-table" v-if="!!editorData.templateId"> | |||
| <table> | |||
| <thead> | |||
| <tr> | |||
| <td v-for="(header) in removePlaceholder(editorData.headers)" :colspan="header.colspan" :style="{ | |||
| 'background-color': calcColor(header.type), | |||
| 'color': calcTextColor(header.type), | |||
| }"> | |||
| {{header.headerName}} | |||
| </td> | |||
| </tr> | |||
| </thead> | |||
| <tbody> | |||
| <tr v-for="(row, rindex) in editorData.rows"> | |||
| <td v-for="(col) in removePlaceholder(row)" :colspan="col.colspan" :rowspan="col.rowspan" :style="{ | |||
| 'text-align': calcAlign(editorData.headers[col.colIndex].type), | |||
| 'background-color': calcColor(editorData.headers[col.colIndex].type), | |||
| }"> | |||
| <div class="full-height" v-if="editorData.headers[col.colIndex].type === '2'" :class="{'validate-error': col.error, 'validate-error-box': col.error,}"> | |||
| <input class="input-field align-right full-height" v-model="col.val" :readonly="disableEdit" type="number"></input> | |||
| </div> | |||
| <div class="full-height" v-else-if="editorData.headers[col.colIndex].type === '4'"> | |||
| <input class="input-field align-center full-height" v-model="col.name" :readonly="disableEdit"></input> | |||
| </div> | |||
| <div v-else :style="{'text-align': calcAlign(editorData.headers[col.colIndex].type)}">{{col.name}}</div> | |||
| </td> | |||
| </tr> | |||
| </tbody> | |||
| </table> | |||
| </div> | |||
| <template v-if="!!editorData.templateId"> | |||
| <div> | |||
| <van-field :readonly="disableEdit" v-model="editorData.reportRemark" label="备注" placeholder="报表备注"/> | |||
| </div> | |||
| <div> | |||
| <van-field readonly :value="editorData.rule" label="规则" placeholder="报表效验公式"> | |||
| <template #extra> | |||
| <van-button :disabled="!editorData.rule" style="height: 100%;" type="primary" size="small" @click="validate(true)">效 验</van-button> | |||
| </template> | |||
| </van-field> | |||
| </div> | |||
| <van-row> | |||
| <van-col span="8"> | |||
| <van-field class="field_no-label" :readonly="disableEdit" v-model="editorData.operatorDepartment" label="" placeholder="填报单位" input-align="left"/> | |||
| </van-col> | |||
| <van-col span="8"> | |||
| <van-field class="field_no-label" :readonly="disableEdit" v-model="editorData.operatorName" label="" placeholder="填报人" input-align="center"/> | |||
| </van-col> | |||
| <van-col span="8"> | |||
| <field-date-picker | |||
| class="field_no-label" | |||
| v-model="editorData.operatorDate" | |||
| placeholder="填报日期" | |||
| formatter="yyyy-MM-dd" | |||
| :readonly="disableEdit" | |||
| input-align="right" | |||
| /> | |||
| </van-col> | |||
| </van-row> | |||
| </template> | |||
| </van-form> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import FieldSelect from "@/components/form/FieldSelect"; | |||
| import { | |||
| addReport, delReport, | |||
| getReport, | |||
| getReportTemplate, | |||
| listReporttitle, | |||
| updateReport | |||
| } from "@/api/sunVillage_info/entity/report"; | |||
| import {array_grouping, array_toMap, date_format} from "@/utils"; | |||
| import {Expression} from "@/utils/expression"; | |||
| import {is_not_number} from "@/utils/utils"; | |||
| import FieldDatePicker from "@/components/form/FieldDatePicker"; | |||
| import {Notify} from "vant"; | |||
| export default { | |||
| name: "ReportView", | |||
| components: {FieldDatePicker, FieldSelect}, | |||
| data() { | |||
| return { | |||
| editorData: { | |||
| id: null, | |||
| templateId: null, | |||
| reportRemark: null, | |||
| titleLeft: null, | |||
| titleCenter: null, | |||
| titleRight: null, | |||
| reportStatus: "0", | |||
| createBy: null, | |||
| createTime: null, | |||
| updateBy: null, | |||
| updateTime: null, | |||
| reportName: '', | |||
| operatorName: '', | |||
| operatorDate: '', | |||
| operatorDepartment: '', | |||
| rule: null, | |||
| reportYear: date_format('%Y'), | |||
| headers: [], | |||
| rows: [], | |||
| cells: [], | |||
| rules: [], | |||
| }, | |||
| templateList: [], | |||
| loading: false, | |||
| disableEdit: false, | |||
| intent: 'add', | |||
| reportId: null, | |||
| }; | |||
| }, | |||
| created() { | |||
| this.getTemplateList(); | |||
| this.parseQuery(); | |||
| }, | |||
| mounted(){ | |||
| this.init(); | |||
| }, | |||
| methods: { | |||
| getTemplateList() { | |||
| listReporttitle({reportStatus: '0'}).then((resp) => { | |||
| this.templateList = resp.rows; | |||
| }); | |||
| }, | |||
| getTemplate() { | |||
| if(!this.editorData.templateId && !this.editorData.id) | |||
| return; | |||
| this.loading = true; | |||
| if(this.editorData.id) // 修改 | |||
| { | |||
| getReport(this.editorData.id).then((resp) => { | |||
| let reportData = resp.data; | |||
| getReportTemplate(reportData.templateId).then((resp) => { | |||
| let templateData = resp.data; | |||
| this.setTableData(templateData, reportData); | |||
| }).finally(() => { | |||
| this.loading = false; | |||
| }); | |||
| }).catch(() => { | |||
| this.loading = false; | |||
| }); | |||
| } | |||
| else | |||
| { | |||
| getReportTemplate(this.editorData.templateId).then((resp) => { | |||
| let templateData = resp.data; | |||
| this.setTableData(templateData); | |||
| }).finally(() => { | |||
| this.loading = false; | |||
| }); | |||
| } | |||
| }, | |||
| setTableData(templateData, reportData) { | |||
| let data; | |||
| if(!reportData) | |||
| { | |||
| data = templateData; | |||
| data.rows.forEach((x) => { | |||
| x.forEach((y) => { | |||
| y.error = false; | |||
| }); | |||
| }); | |||
| } | |||
| else | |||
| { | |||
| let cells = reportData.cells; | |||
| data = reportData; | |||
| data.headers = templateData.headers; | |||
| data.rows = templateData.rows; | |||
| data.cells = templateData.cells; | |||
| data.rules = templateData.rules; | |||
| data.rule = templateData.rule; | |||
| let group = array_grouping(cells, (x) => x.rowIndex); | |||
| Object.keys(group).forEach((x) => group[x] = array_toMap(group[x], (x) => x.colIndex)); | |||
| data.rows.forEach((cols, rowIndex) => { | |||
| cols.forEach((x) => { | |||
| if(group[rowIndex] && group[rowIndex][x.colIndex]) | |||
| { | |||
| if(templateData.headers[x.colIndex].type === '4') | |||
| x.name = group[rowIndex][x.colIndex].name; | |||
| x.val = group[rowIndex][x.colIndex].val; | |||
| } | |||
| }) | |||
| }); | |||
| } | |||
| this.editorData = data; | |||
| if(this.editorData.id) | |||
| this.validate(); | |||
| }, | |||
| cellIsPlaceholder(x) { | |||
| return x.colspan <= 0 || (x.hasOwnProperty('rowspan') && x.rowspan <= 0); | |||
| }, | |||
| removePlaceholder(cells) { | |||
| return cells.filter((x) => !this.cellIsPlaceholder(x)); | |||
| }, | |||
| calcAlign(type) { | |||
| switch(type) | |||
| { | |||
| case '2': | |||
| return 'right'; | |||
| case '3': | |||
| case '4': | |||
| return 'center'; | |||
| case '1': | |||
| return 'left'; | |||
| } | |||
| }, | |||
| calcColor(type) { | |||
| switch(type) | |||
| { | |||
| case '2': | |||
| return 'unset'; | |||
| case '4': | |||
| return 'unset'; | |||
| case '3': | |||
| return '#d7e8f3'; | |||
| case '1': | |||
| return '#aad8f6'; | |||
| } | |||
| }, | |||
| calcTextColor(type) { | |||
| switch(type) | |||
| { | |||
| case '2': | |||
| case '4': | |||
| return '#2facfe'; | |||
| case '3': | |||
| case '1': | |||
| return '#858585'; | |||
| } | |||
| }, | |||
| save() { | |||
| let validateResult = this.validate(); | |||
| if(validateResult) | |||
| this.requestSave(); | |||
| else | |||
| { | |||
| this.$dialog.confirm({ | |||
| message: '报表存在不通过的效验, 是否继续提交?', | |||
| }) | |||
| .then(() => { | |||
| return this.requestSave(); | |||
| }) | |||
| .catch(() => { | |||
| }); | |||
| } | |||
| }, | |||
| requestSave() { | |||
| this.$refs.form.validate().then(() => { | |||
| this.preHandle(); | |||
| this.loading = true; | |||
| let func = this.editorData.id ? updateReport : addReport; | |||
| func(this.editorData).then((resp) => { | |||
| this.notify("保存成功!", 'success'); | |||
| this.back(); | |||
| }).finally(() => { | |||
| this.loading = false; | |||
| }); | |||
| }).catch(() => { | |||
| this.notify("请填写完整表单", 'danger'); | |||
| this.$refs.form.scrollToField(); | |||
| }); | |||
| }, | |||
| preHandle() { | |||
| this.editorData.cells = []; | |||
| this.editorData.rows.forEach((x) => this.editorData.cells.push(...x)); | |||
| }, | |||
| reset() { | |||
| this.$refs.form.resetValidation(); | |||
| this.editorData = { | |||
| id: null, | |||
| deptId: null, | |||
| deptName: null, | |||
| templateId: null, | |||
| reportName: null, | |||
| reportYear: null, | |||
| reportRemark: null, | |||
| titleLeft: null, | |||
| titleCenter: null, | |||
| titleRight: null, | |||
| rule: null, | |||
| operatorName: null, | |||
| operatorDate: null, | |||
| createBy: null, | |||
| createTime: null, | |||
| updateBy: null, | |||
| updateTime: null, | |||
| headers: [], | |||
| rows: [], | |||
| cells: [], | |||
| rules: [], | |||
| }; | |||
| }, | |||
| validate(showMsg) { | |||
| if(!this.editorData.rules || !this.editorData.rules.length) | |||
| return true; | |||
| let errors = []; | |||
| for(let i in this.editorData.headers) | |||
| { | |||
| let header = this.editorData.headers[i]; | |||
| if(header.type !== '2') | |||
| continue; | |||
| let map = {}; | |||
| for(let m in this.editorData.rows) | |||
| { | |||
| let cell = this.editorData.rows[m][i]; | |||
| map['' + (Number(m) + 1)] = is_not_number(cell.val) ? 0 : Number(cell.val); | |||
| this.$set(this.editorData.rows[Number(m)][Number(i)], 'error', false); | |||
| } | |||
| for(let m in this.editorData.rules) | |||
| { | |||
| let rule = this.editorData.rules[m]; | |||
| let exp = new Expression(rule, Expression.PARSE_FLAG_ALL_NUMBER_AS_PLACEHOLDER | Expression.PARSE_FLAG_ERROR_HANDLE_SCHEME_THROW_EXCEPTION, map); | |||
| try | |||
| { | |||
| let res = exp.Predicate(); | |||
| //console.log(rule, res); | |||
| if(!res) | |||
| { | |||
| errors.push(`第${Number(i) + 1}列效验错误: ${rule}`); | |||
| } | |||
| let placeholders = exp.ParsedPlaceholders(); | |||
| for(let n in placeholders) | |||
| { | |||
| if(!res) | |||
| this.$set(this.editorData.rows[Number(placeholders[n]) - 1][Number(i)], 'error', true); | |||
| } | |||
| } | |||
| catch(e) | |||
| { | |||
| console.log(e); | |||
| errors.push(e); | |||
| } | |||
| } | |||
| } | |||
| if(showMsg) | |||
| { | |||
| this.$dialog.alert({ | |||
| title: errors.length ? '效验错误' : '效验成功', | |||
| message: errors.join('<br/>'), | |||
| allowHtml: true, | |||
| }); | |||
| } | |||
| return errors.length === 0; | |||
| }, | |||
| parseQuery() { | |||
| let query = this.$route.query; | |||
| this.reportId = query.reportId; | |||
| this.intent = query.intent; | |||
| if(!this.reportId) | |||
| { | |||
| this.intent = 'add'; | |||
| return; | |||
| } | |||
| if(this.intent === 'add') | |||
| { | |||
| this.reportId = null; | |||
| } | |||
| }, | |||
| init() { | |||
| this.editorData.id = this.reportId; | |||
| this.getTemplate(); | |||
| this.disableEdit = this.intent === 'view'; | |||
| }, | |||
| back() { | |||
| this.$router.back(); | |||
| }, | |||
| notify(message, type) { | |||
| Notify.clear(); | |||
| Notify({ type: type || 'primary', message: message }); | |||
| }, | |||
| }, | |||
| computed: { | |||
| isAdd() { | |||
| return this.intent === 'add'; | |||
| }, | |||
| isEdit() { | |||
| return this.intent === 'edit'; | |||
| }, | |||
| isView() { | |||
| return this.intent === 'view'; | |||
| }, | |||
| } | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .app-container{ | |||
| background: #e9e9e9; | |||
| min-height: 100vh; | |||
| width: 100vw; | |||
| .header_main-placeholder { | |||
| height: 116px; | |||
| } | |||
| .header_main { | |||
| height: 116px; | |||
| background: url('../../../assets/images/sunVillage_info/list_head.png') no-repeat; | |||
| background-size: 100% 100%; | |||
| position: fixed; | |||
| top: 0; | |||
| left: 0; | |||
| width: 100%; | |||
| font-size: 36px; | |||
| line-height: 116px; | |||
| text-align: center; | |||
| color: #fff; | |||
| z-index: 999; | |||
| .return_btn { | |||
| width: 24px; | |||
| height: 43.2px; | |||
| background: url('../../../assets/images/sunVillage_info/list_icon_5.png') center center no-repeat; | |||
| background-size: 20px 36px; | |||
| position: absolute; | |||
| left: 38px; | |||
| top: 36px; | |||
| } | |||
| .add_btn { | |||
| width: 56.4px; | |||
| height: 40.8px; | |||
| background: url('../../../assets/images/sunVillage_info/list_icon_9.png') center center no-repeat; | |||
| background-size: 47px 34px; | |||
| position: absolute; | |||
| right: 38px; | |||
| top: 36px; | |||
| } | |||
| } | |||
| .main-table { | |||
| overflow-x: auto; | |||
| overflow-y: auto; | |||
| position: relative; | |||
| background-color: #ffffff; | |||
| padding: 0.15rem 0.15rem; | |||
| border-radius: 0.15rem; | |||
| margin: 0.1rem 0.1rem; | |||
| table { | |||
| width: max-content; | |||
| border-collapse: collapse; | |||
| border: 0.01rem solid #1989fa; | |||
| table-layout: fixed; | |||
| } | |||
| thead td { | |||
| text-align: center; | |||
| border: 0.01rem solid #1989fa; | |||
| height: 1rem; | |||
| font-size: 0.32rem; | |||
| padding: 0 0.4rem; | |||
| margin: 0; | |||
| font-weight: bold; | |||
| max-width: 1.2rem; | |||
| } | |||
| tbody td { | |||
| font-size: 0.3rem; | |||
| border: 0.01rem solid #1989fa; | |||
| height: 1rem; | |||
| white-space: break-spaces; | |||
| word-wrap: break-word; | |||
| overflow-wrap: break-word; | |||
| padding: 0; | |||
| margin: 0; | |||
| max-width: 1.5rem; | |||
| position: relative; | |||
| } | |||
| .input-field { | |||
| width: 100%; | |||
| background-color: unset; | |||
| border: 0; | |||
| } | |||
| .validate-error { | |||
| color: #F56C6C; | |||
| } | |||
| .validate-error-box { | |||
| color: #F56C6C; | |||
| border: 0.02rem solid #F56C6C; | |||
| } | |||
| } | |||
| .align-right { | |||
| text-align: right; | |||
| } | |||
| .align-center { | |||
| text-align: center; | |||
| } | |||
| .full-height { | |||
| height: 100%; | |||
| } | |||
| /deep/ .van-field__label { | |||
| background-color: #2facfe; | |||
| margin: 0; | |||
| color: #fff; | |||
| border-top-left-radius: 0.15rem; | |||
| border-bottom-left-radius: 0.15rem; | |||
| padding: 0 0.2rem; | |||
| display: flex; | |||
| align-items: center; | |||
| } | |||
| /deep/ .van-field__body { | |||
| background-color: #ffffff; | |||
| border-top-right-radius: 0.15rem; | |||
| border-bottom-right-radius: 0.15rem; | |||
| padding: 0 0.1rem; | |||
| } | |||
| /deep/ .van-field__body { | |||
| height: 100%; | |||
| } | |||
| /deep/ .van-field { | |||
| background-color: unset; | |||
| padding: 0.1rem 0.15rem; | |||
| height: 1rem; | |||
| } | |||
| .field_no-label /deep/ .van-field__body { | |||
| border-top-left-radius: 0.15rem; | |||
| border-bottom-left-radius: 0.15rem; | |||
| } | |||
| .template-selector /deep/ span { | |||
| padding-left: 0.8rem; | |||
| background: #2facfe url('../../../assets/images/sunVillage_info/list_icon_11.png') left center no-repeat; | |||
| background-size: 0.45rem; | |||
| } | |||
| .form_readonly /deep/ .van-icon-arrow-down { | |||
| display: none; | |||
| } | |||
| } | |||
| </style> | |||