diff --git a/docs/zh-CN/.vuepress/components/changelog/logs.js b/docs/zh-CN/.vuepress/components/changelog/logs.js index f49ff1c2..6fb11b79 100644 --- a/docs/zh-CN/.vuepress/components/changelog/logs.js +++ b/docs/zh-CN/.vuepress/components/changelog/logs.js @@ -1,18 +1,54 @@ // 更新日志 export default [ { - version: '0.32.1', - date: '2020.06.03', + version: '0.34.5', + date: '2020.09.15', log: [ + 'feat: block-mixin文件在created中,init和created生命周期调整', + 'feat: array字段增加getShowState判断', + 'feat: 新增timeline字段', + 'feat: timeline的content支持html', + 'feat: router增加tooltip配置', + 'feat: tag(ams-plugin)增加后端参数', + 'fix: field-tag(ams-plugin)的@clik自定义绑定事件', + ] + }, + { + version: '0.33.7', + date: '2020.08.06', + log: [ + 'feat: 点击 Logo,在首次重复路径后,将会刷新当前页面', + 'feat: routerPush 在异常场景将异常信息 reject 出去', + 'feat: Logo 点击跳转使用 AMS 封装的 routerPush', + 'feat: 新增ams.configs.defaultBlockConfig配置,修复小问题', + 'fix: 动态路由匹配和路由懒加载同时使用时报错', + 'fix: 全局config.resource.api增加responseType', + 'fix: ams.request修复从api的默认取值', + 'fix: 修复list中获取headerSelected的时机', + 'fix: 修复ams-init中的请求登录跳转问题', + 'fix: 修复block-xlsx(ams-plugin)中数值为0的解析问题', + 'fix: 修复init.js中过去materiel缺失问题', + 'fix: Select 字段在远程搜索场景映射值错误', + ] + }, + { + version: '0.32.10', + date: '2020.07.30', + log: [ + 'feat: route配置支持componen', 'feat: 设置add/editDialogDrawer 默认为 append-to-body', 'feat: 添加addItemDrawer和editItemDrawer配置', 'feat: 点击删除的时候,显示弹窗进行二次确认', - 'feat: text增加tooltip配置', - 'feat: multiple的operation增加allowNoSelect配置', - 'feat: list增加表头管理', - 'fix: 修复表头管理设置后operation错乱,先请空触发渲染;增加缓存字段跟resource对比', - 'fix: 修复远程搜索再设置了isInitEmpty:true情况下,设置额外传参报错问题', - 'fix: 更改列表区块的total赋值逻辑' + 'fix: 更改列表区块的total赋值逻辑', + 'fix: 修复列表区块created时导致的渲染异常场景', + 'fix: 修复ams.request读取config中api配置问题', + 'fix: 修复list配置action的responseDataParse,导致search被清空问题', + 'fix: 修复list区块在created阶段的异常', + 'feat: select字段增加autoOptions配置', + 'fix: 优化select字段增加autoOptions配置', + 'fix: 修复图片放大时z-index导致的异常', + 'fix: 修复对象字段内,子字段配置说明文案(desc)后重复渲染的问题', + 'fix: 修复field-get-set中的对于file类型的判断', ] }, { diff --git a/docs/zh-CN/version/cdn-script.md b/docs/zh-CN/version/cdn-script.md index f292d0b7..bbd92823 100644 --- a/docs/zh-CN/version/cdn-script.md +++ b/docs/zh-CN/version/cdn-script.md @@ -12,7 +12,33 @@ ## AMS版本 -[0.32.10](https://h5rsc.vipstatic.com/ams/ams@0.32.10.js) +[0.34.5](https://h5rsc.vipstatic.com/ams/ams@0.34.5.js) + +[0.34.4](https://h5rsc.vipstatic.com/ams/ams@0.34.4.js) + +[0.34.3](https://h5rsc.vipstatic.com/ams/ams@0.34.3.js) + +[0.34.2](https://h5rsc.vipstatic.com/ams/ams@0.34.2.js) + +[0.34.1](https://h5rsc.vipstatic.com/ams/ams@0.34.1.js) + +[0.34.0](https://h5rsc.vipstatic.com/ams/ams@0.34.0.js) + +[0.33.7](https://h5rsc.vipstatic.com/ams/ams@0.33.7.js) + +[0.33.6](https://h5rsc.vipstatic.com/ams/ams@0.33.6.js) + +[0.33.5](https://h5rsc.vipstatic.com/ams/ams@0.33.5.js) + +[0.33.4](https://h5rsc.vipstatic.com/ams/ams@0.33.4.js) + +[0.33.3](https://h5rsc.vipstatic.com/ams/ams@0.33.3.js) + +[0.33.2](https://h5rsc.vipstatic.com/ams/ams@0.33.2.js) + +[0.33.1](https://h5rsc.vipstatic.com/ams/ams@0.33.1.js) + +[0.33.0](https://h5rsc.vipstatic.com/ams/ams@0.33.0.js) [0.32.9](https://h5rsc.vipstatic.com/ams/ams@0.32.9.js) @@ -26,7 +52,7 @@ [0.32.3](https://h5rsc.vipstatic.com/ams/ams@0.32.3.js) -[0.32.1](https://h5rsc.vipstatic.com/ams/ams@0.32.1.js) +[0.34.5](https://h5rsc.vipstatic.com/ams/ams@0.34.5.js) [0.32.0](https://h5rsc.vipstatic.com/ams/ams@0.32.0.js) diff --git a/examples/router/src/ams-config/cases-block/list/list-tab.js b/examples/router/src/ams-config/cases-block/list/list-tab.js new file mode 100644 index 00000000..a00d7937 --- /dev/null +++ b/examples/router/src/ams-config/cases-block/list/list-tab.js @@ -0,0 +1,91 @@ +import ams from '@ams-team/ams'; + +ams.block('list-tab', { + type: 'tabs', + options: { + 'tabs-list1': ' tab1标题', + 'tabs-list2': ' tab2标题' + }, + data: { + active: '' + }, + blocks: { + 'tabs-list1': { + ctx: 'view', + type: 'list', + events: { + init: '@list' + }, + resource: { + api: { + prefix: 'https://www.yournana.club/vipshop/', + list: 'list?page=1&pageSize=20&testText=a' + }, + fields: { + id: { + type: 'textarea', + label: 'ID', + props: { + 'class-name': 'drag-column' + } + }, + testText: { + type: 'text', + label: '店铺' + } + } + }, + data: { + list: [], + pageSize: 20, + pageSizes: [10, 20] + }, + operations: { + multiSetHeader: { + type: 'button', + label: '设置' + } + } + }, + 'tabs-list2': { + ctx: 'view', + type: 'list', + events: { + init: '@list' + }, + resource: { + api: { + prefix: 'https://www.yournana.club/vipshop/', + list: 'list?page=1&pageSize=20&testText=a' + }, + fields: { + id: { + type: 'textarea', + label: 'ID', + props: { + 'class-name': 'drag-column' + } + }, + testText: { + type: 'text', + label: '店铺' + } + } + }, + data: { + list: Array.from(Array(100), (v, k) => ({ + id: k + 1, + testText: `标题${k + 1}` + })), + pageSize: 20, + pageSizes: [10, 20] + }, + operations: { + multiSetHeader: { + type: 'button', + label: '设置' + } + } + } + } +}); diff --git a/examples/router/src/ams-config/cases-block/timeline.js b/examples/router/src/ams-config/cases-block/timeline.js new file mode 100644 index 00000000..7a1773c1 --- /dev/null +++ b/examples/router/src/ams-config/cases-block/timeline.js @@ -0,0 +1,78 @@ +import ams from '@ams-team/ams'; + +ams.block('timeline', { + blocks: { + timeline1Title: { + type: 'title', + options: { + title: '基础用法' + } + }, + timeline1Block: { + type: 'timeline', + props: { + reverse: true + }, + data: [{ + content: '活动按期开始,状态:异常
', + timestamp: '2018-04-15' + }, { + content: '通过审核', + timestamp: '2018-04-13' + }, { + content: '创建成功', + timestamp: '2018-04-11' + }], + operations: { + reverseSelect: { + slot: 'header', + type: 'field', + field: { + type: 'radio', + default: 1, + props: { + options: [ + { label: '正叙', value: 1 }, + { label: '倒叙', value: 0 } + ] + } + } + } + }, + actions: { + fieldChange({ path, value }) { + if (path === 'header.reverseSelect') { + this.block.props.reverse = Boolean(value); + } + } + } + }, + timeline2Title: { + type: 'title', + options: { + title: '自定义节点' + } + }, + timeline2Block: { + type: 'timeline', + data: [{ + content: '支持使用图标', + timestamp: '2018-04-12 20:46', + size: 'large', + type: 'primary', + icon: 'el-icon-more' + }, { + content: '支持自定义颜色', + timestamp: '2018-04-03 20:46', + color: '#0bbd87' + }, { + content: '支持自定义尺寸', + timestamp: '2018-04-03 20:46', + size: 'large' + }, { + content: '默认样式的节点', + timestamp: '2018-04-03 20:46' + }] + } + } +}); \ No newline at end of file diff --git a/examples/router/src/ams-config/cases-field/select.js b/examples/router/src/ams-config/cases-field/select.js index c4830bd9..de5e6ca8 100644 --- a/examples/router/src/ams-config/cases-field/select.js +++ b/examples/router/src/ams-config/cases-field/select.js @@ -149,9 +149,7 @@ ams.block('select', { queryKey: 'requiredName', labelKey: 'name', params: { - params: { - a: 2 - } + a: 2 }, isCache: false, transform($field, data) { diff --git a/examples/router/src/ams-config/index.js b/examples/router/src/ams-config/index.js index 30af0a27..3e324401 100644 --- a/examples/router/src/ams-config/index.js +++ b/examples/router/src/ams-config/index.js @@ -49,6 +49,7 @@ import './cases-block/list/list-pagination'; import './cases-block/list/list-drag'; import './cases-block/list/list-field-convert'; import './cases-block/list/list-simulate'; +import './cases-block/list/list-tab'; import './cases-block/alert'; import './cases-block/calendar'; import './cases-block/dragimage'; @@ -71,4 +72,5 @@ import './cases-block/title'; import './cases-block/drawer'; import './cases-block/table'; import './cases-block/form/edit'; -import './cases-block/form/view'; \ No newline at end of file +import './cases-block/form/view'; +import './cases-block/timeline'; \ No newline at end of file diff --git a/examples/router/src/ams-config/router.js b/examples/router/src/ams-config/router.js index fa775616..dc79d868 100644 --- a/examples/router/src/ams-config/router.js +++ b/examples/router/src/ams-config/router.js @@ -38,6 +38,7 @@ ams.block('router', { } }, router: { + // keepAlive: true, // 设置为true的话,所有菜单都会keepAlive // mode: 'history', // base: '/app/', // 要在history下才会发挥作用 // showMenu: false, // 隐藏所有菜单配置项,默认为true @@ -47,7 +48,7 @@ ams.block('router', { // textColor: '#bfcbd9', // 菜单的文字颜色(仅支持 hex 格式),默认值:#bfcbd9 // activeTextColor: '#409EFF', // 菜单的文字颜色(仅支持 hex 格式),默认值:#409EFF // defaultBreadcrumb: false, // 默认为true,会把首个route作为默认首页加到所有面包屑,设置为false禁用此行为, 0.7.5+支持 - // shwoBreadcrumb: false, // 默认为true,是否显示面包屑 + // showBreadcrumb: false, // 默认为true,是否显示面包屑 routes: [ { name: '首页', @@ -57,6 +58,9 @@ ams.block('router', { // redirect: '/list', meta: { icon: 'el-icon-menu' + }, + tooltip: { + content: '首页提示文字' } }, { @@ -232,6 +236,11 @@ ams.block('router', { name: '前端分页', path: 'list-simulate', block: 'list-simulate' + }, + { + name: 'tab中的list', + path: 'list-tab', + block: 'list-tab' } ] }, @@ -369,6 +378,11 @@ ams.block('router', { name: 'Alert告警', path: 'alert', block: 'alert' + }, + { + name: '时间线', + path: 'timeline', + block: 'timeline' } ] }, diff --git a/package.json b/package.json index a81a9e2b..e5d51fa1 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "vue", "element-ui" ], - "version": "0.33.0", + "version": "0.34.5", "main": "lib/ams.common.js", "unpkg": "lib/ams.js", "scripts": { diff --git a/packages/block-xlsx/package.json b/packages/block-xlsx/package.json index 4dc63915..e1f25414 100644 --- a/packages/block-xlsx/package.json +++ b/packages/block-xlsx/package.json @@ -1,6 +1,6 @@ { "name": "@ams-team/block-xlsx", - "version": "0.9.3", + "version": "0.9.4", "description": "结合ams的resources配置使用的导出导出xlsx插件", "author": "zebin.wu <1069467662@qq.com>", "main": "lib/block-xlsx.js", diff --git a/packages/block-xlsx/src/xlsx/reader.ts b/packages/block-xlsx/src/xlsx/reader.ts new file mode 100644 index 00000000..389b7b9e --- /dev/null +++ b/packages/block-xlsx/src/xlsx/reader.ts @@ -0,0 +1,314 @@ +import { + RawCell, LiteralCell, NotEmptyCell, Dict, Dicts, Data, Opts, WorkbookReaderError, ImportHeader, + XlsxPopulateWorkbook, XlsxPopulateWorksheet, XlsxPopulateRichTextCell +} from './types'; +import { Combiner } from './combiner'; +import { dateParse, formatDate } from '../utils/date'; + +export const reverseDict = (dict: Dict): Dict => Object.keys(dict).reduce((newDict, key) => { + newDict[dict[key]] = key; + return newDict; +}, {}); + +export function numberValidator(value: LiteralCell, min?: any, max?: any, toFixedNumber?: any) { + if (typeof value === 'number') { + const valueToNumber = Number(value); + if (min !== undefined && min > valueToNumber) return `应大于等于${min}`; + if (max !== undefined && max < valueToNumber) return `应小于等于${max}`; + if (toFixedNumber) { + return true; + } + return true; + } + return '应为数字类型'; +} + +export function integerValidator(value: LiteralCell, min?: any, max?: any) { + const isNumber = numberValidator(value); + if (typeof isNumber === 'string') return isNumber; + if (Number.isInteger(value)) { + const valueToNumber = Number(value); + if (min !== undefined && min > valueToNumber) return `应大于等于${min}`; + if (max !== undefined && max < valueToNumber) return `应小于等于${max}`; + return true; + } + return '应为整数'; +} + +export const nonZeroNumberFilter = (v: any): (any | '') => (!isNaN(Number(v)) && Number(v) !== 0 ? v : ''); + +export const valueToString = (value: RawCell): string => { + switch (typeof value) { + case 'number': + case 'string': + return (value).toString(); + default: + return JSON.stringify(value); + } +} +export function valueToDate(value: RawCell) { + switch (typeof value) { + case 'number': { + const num = (value) - 1; // 这里就当作所有日期都在 bug day 1900-02-29 之后 + // const dateBase = new Date(1900, 0, 0); // chrome不同版本计算出来的数据不一致,直接固定写死一个数值,后续排查 + const dateBase = -2209104000000; + const secondsInDay = 60 * 60 * 24; + return new Date(Math.round(num * secondsInDay) * 1000 + dateBase); + } + case 'string': return dateParse(value); + default: return new Date(NaN); + } +} +export const valueToSeconds = (value: RawCell) => { + const date = valueToDate(value); + if (isNaN(date.getTime())) { + throw new Error('日期格式错误'); + } + return Math.round(date.getTime() / 1000); +}; +export const valueToDateString = (format: string) => (value: RawCell) => { + const date = valueToDate(value); + if (isNaN(date.getTime())) { + throw new Error('日期格式错误'); + } + return formatDate(date, format); +} + +export const oaValidator = (value: LiteralCell) => { + if (typeof value === 'string') { + const result = /^([^/]*\/)?[a-zA-Z0-9.]+$/.exec(value); + if (result && result[0] === value) return true; + } + return '请填写正确的 OA,如「张三/san.zhang」或「san.zhang」'; +}; + +/** + * @param {Array<{ name: 'r', children: Array<{ name: 't', children: string }> }>} cell + */ +function richTextCellToString(cell: XlsxPopulateRichTextCell) { + if (Array.isArray(cell)) { + return cell + .filter(node => node.name === 'r') // => rNodes + .map(rNode => rNode.children.filter(child => child.name === 't')) // => Array> + .map(tNodes => tNodes.map(tNode => { + const v = tNode.children[0]; + if (v || `${v}` === '0') return v; + return '' + }).join('')) // => Array + .join(''); + } + return ''; +} + +export abstract class WorkbookReader { + errors: WorkbookReaderError[] = []; + result: object[] = []; + protected abstract headers: ImportHeader[] = []; + protected readonly rowStartAt: number = 1; + protected readonly abstract combiner: Combiner; + protected abstract opts: Opts; + protected sheet: XlsxPopulateWorksheet; + + read(wb: XlsxPopulateWorkbook): void { + this.sheet = this.getSheet(wb); + if (this.isSheetEmpty) { + throw new Error('导入文件中无数据'); + } + const rows: RawCell[][] = this.getRows(this.sheet); + this.preCheck(rows, this.opts); + if (this.hasError) return; + + let count = this.rowStartAt; + const items = this.getGroups(rows).map((group) => { + const preCount = count; + count += group.length; + return this.parseGroup(group, preCount); + }); + this.result = this.postParse(items, this.opts); + + if (this.hasError) return; + this.postCheck(this.result, this.opts); + if (this.hasError) return; + } + + /** + * 在逐行解析前进行一次检查,执行后如果 this.errors 有项,则不再进行解析 + */ + protected preCheck(rows: RawCell[][], opts: Opts): void {} + /** + * 数据解析之后的最后校验 + */ + protected postCheck(items: object[], opts: Opts): void {} + + protected postParse(items: object[], opts: Opts): object[] { + return items; + } + + get hasError() { + return this.errors.length !== 0; + } + + protected getSheet(wb: XlsxPopulateWorkbook): XlsxPopulateWorksheet { + return wb.sheet(0); + } + private getRows(sheet: XlsxPopulateWorksheet): RawCell[][] { + const rowLength = sheet.usedRange()._maxRowNumber; + + let rows = sheet.range(Math.max(this.rowStartAt + 1, 1), 1, rowLength, this.headers.length).value(); + // 若某一行为空行,则不再解析,但要检测以确保剩余行均不为空行 + const blankRowIndex = rows.findIndex((row) => row.every(WorkbookReader.isCellEmpty)) + if (blankRowIndex !== -1) { + if (blankRowIndex === 0) { + throw new Error(`第 ${this.rowStartAt + 1} 行为空行,请检查`); + } + for (let i = blankRowIndex + 1; i < rows.length; i++) { + if (rows[i].some(v => !WorkbookReader.isCellEmpty(v))) { + throw new Error(`第 ${this.rowStartAt - 1 + i} 行为空行,请检查`); + } + } + return rows.slice(0, blankRowIndex); + } + return rows; + } + private getGroups(rows: RawCell[][]): RawCell[][][] { + let groups: RawCell[][][] = []; + let curGroupsStartAt = this.rowStartAt; + const errMsg = (msg: string, i: number) => `第 ${curGroupsStartAt + 1} ~ ${i - 1 + this.rowStartAt + 1} 行:${msg}`; + // rows.slice(this.rowStartAt).forEach((row, i) => { + rows.slice(0).forEach((row, i) => { // 因为在getRows中已经处理了rows = sheet.range(this.rowStartAt + 1) + let result: RawCell[][][]; + try { + result = this.combiner.push(row); + } catch (e) { + throw new Error(errMsg(e.message, i)); + } + // 判断之前的行是否已被分组 + if (result.length > 0) { + curGroupsStartAt = this.rowStartAt + i; + } + }); + try { + this.combiner.end(); + } catch (e) { + throw new Error(errMsg(e.message, rows.length - 1)); + } + return this.combiner.result; + } + private parseGroup(group: RawCell[][], groupStartAt: number): object { + const item = this.parseRow(group[0], false, groupStartAt); + const multirows: object[] = []; + group.forEach((row, i) => { + multirows.push(this.parseRow(row, true, groupStartAt + i)); + }); + this.assignMultirowAndRemoveRowIndex(item, multirows); + return item; + } + protected assignMultirowAndRemoveRowIndex(item: object, multirows: object[]): void {} + private parseRow(richTextRow: RawCell[], multiRow: boolean, rowIndex: number): object { + const parsed: { [field: string]: any, __rowIndex: number } = { __rowIndex: rowIndex }; + const row: LiteralCell[] = richTextRow.map(cell => (typeof cell === 'object' ? richTextCellToString(cell) : cell)) + const rowDict: Data = row + .map((item, i) => ({ [this.headers[i] ? this.headers[i].field : '']: item })) + .reduce((obj, cur) => Object.assign(obj, cur), {}) + this.headers.forEach((header, i) => { + let value = row[i]; + + // 判断是否忽略 + if ( + (typeof header.ignored === 'function' ? header.ignored(value, rowDict, row) : header.ignored) + || (!multiRow && header.multirow) + || (multiRow && !header.multirow) + ) return; + + const pos = `${WorkbookReader.toColumnName(i + 1)}${rowIndex + 1}(${header.label})`; + // 检查必填项 + const required = typeof header.required === 'function' + ? header.required(value, rowDict, row) + : header.required; + if (required && WorkbookReader.isCellEmpty(value)) { + this.addError(pos, '请填写必填项'); + return; + } + if (header.trim !== false && typeof value === 'string') { + value = value.replace(/(^\s*)|(\s*$)/g, ''); + } + // 调用 validate + if (header.validate && !WorkbookReader.isCellEmpty(value)) { + let result; + try { + result = header.validate(value, rowDict, row); + } catch (e) { + result = e.message; + } + if (typeof result === 'string') { + this.addError(pos, result); + return; + } + } + // 转换 + if (header.preConvert && !WorkbookReader.isCellEmpty(value)) { + value = header.preConvert(value); + } + if (header.dict && !WorkbookReader.isCellEmpty(value)) { + value = String(value); + const dict = typeof header.dict === 'function' ? header.dict(value, rowDict, row) : header.dict; + if (typeof header.split === 'string') { + const failures = value.split(header.split).filter(v => !dict.hasOwnProperty(v)); + if (failures.length > 0) { + this.addError(pos, `${failures.map(v => `「${v}」`).join('、')}不存在`); + return; + } else { + parsed[header.field] = value.split(header.split).map(v => dict[v]); + if (typeof header.join === 'string') { + parsed[header.field] = parsed[header.field].join(header.join); + } + } + } else { + if (!dict.hasOwnProperty(value)) { + this.addError(pos, `「${value}」不存在`); + return; + } else { + parsed[header.field] = dict[value]; + } + } + } else if (header.convert) { + if (WorkbookReader.isCellEmpty(value) && !header.convertIfEmpty) return; + try { + parsed[header.field] = header.convert(value, rowDict, row, rowIndex); + } catch (e) { + this.addError(pos, e.message); + return; + } + } else { + parsed[header.field] = WorkbookReader.isCellEmpty(value) ? '' : value; + } + }); + return parsed; + } + private get isSheetEmpty() { + return this.sheet.usedRange()._maxRowNumber < (this.rowStartAt + 1); + } + + protected addError(pos: string, message: string) { + this.errors.push({ pos, message }); + } + + static isCellEmpty(value: RawCell): boolean { + return typeof value === 'undefined' + || (typeof value === 'string' && value.length === 0); + } + + /** + * 将列数转为对应的名。e.g.: 29 -> 'AC' + * @param {number} num 1-based + * @return {string} + */ + static toColumnName(num: number): string { + let result = ''; + for (let a = 1, b = 26; num >= a; a = b, b *= 26) { + num -= a; + result = String.fromCharCode(Math.floor((num % b) / a) + 65) + result; + } + return result; + } +} diff --git a/packages/field-tag/package.json b/packages/field-tag/package.json index d26d5006..6077c56f 100644 --- a/packages/field-tag/package.json +++ b/packages/field-tag/package.json @@ -1,6 +1,6 @@ { "name": "@ams-team/field-tag", - "version": "1.2.7", + "version": "1.2.9", "description": "AMS标签", "author": "ams", "main": "lib/field-tag.js", diff --git a/packages/field-tag/src/edit.vue b/packages/field-tag/src/edit.vue index 9c999675..f63f7b7f 100644 --- a/packages/field-tag/src/edit.vue +++ b/packages/field-tag/src/edit.vue @@ -6,6 +6,7 @@ :key="index" v-on="on" v-bind="field.props" + @click="on && on.click(tag)" @close="handleDelete(tag)"> {{ field.props.template ? field.props.template.replace(idRegExp, tag[field.props['idKey']] || '').replace(nameRegExp, tag[field.props['nameKey']] || '').replace(subNameRegExp, tag[field.props['subNameKey']] || '') : (tag[field.props['nameKey']] || tag) }} @@ -218,9 +219,13 @@ export default { // pageSize: 20 }; if (item) { - params.data[this.field.props['idKey']] = item; - params.data[this.field.props['nameKey']] = item; - params.data[this.field.props['subNameKey']] = item; + if (this.field.props['queryKey']) { + params.data[this.field.props['queryKey']] = item; + } else { + params.data[this.field.props['idKey']] = item; + params.data[this.field.props['nameKey']] = item; + params.data[this.field.props['subNameKey']] = item; + } } } else { params.params = { @@ -228,9 +233,13 @@ export default { // pageSize: 20 }; if (item) { - params.params[this.field.props['idKey']] = item; - params.params[this.field.props['nameKey']] = item; - params.params[this.field.props['subNameKey']] = item; + if (props['queryKey']) { + params.params[props['queryKey']] = item; + } else { + params.params[props['idKey']] = item; + params.params[props['nameKey']] = item; + params.params[props['subNameKey']] = item; + } } } const resource = ams.resources[ams.blocks[this.name].resource]; diff --git a/plugins/vscode/snippets/curd.json b/plugins/vscode/snippets/curd.json index 34c491d5..ed3db47c 100644 --- a/plugins/vscode/snippets/curd.json +++ b/plugins/vscode/snippets/curd.json @@ -11,7 +11,7 @@ " ", " ", " ", - " ", + " ", " ", " ", " \ No newline at end of file diff --git a/src/fields/array/array-edit.vue b/src/fields/array/array-edit.vue index 1a602097..7d11ec42 100644 --- a/src/fields/array/array-edit.vue +++ b/src/fields/array/array-edit.vue @@ -38,13 +38,14 @@ {{field.field.label && field.field.label + (index + 1)}}
- + :class="`ams-field ams-field-${field.field.type}-${field.field.ctx} ${!field.field.label ? 'ams-field-no-label' : ''}`" /> @@ -56,7 +57,7 @@ import mixins from '../../ams/mixins'; export default { - mixins: [mixins.fieldEditArrayMixin], + mixins: [mixins.fieldEditArrayMixin, mixins.getShowState], data() { return { showOperationIndex: -1 diff --git a/src/fields/array/array-view.vue b/src/fields/array/array-view.vue index 1fa69820..eafef1ee 100644 --- a/src/fields/array/array-view.vue +++ b/src/fields/array/array-view.vue @@ -7,7 +7,8 @@ :rules="field.field.rules" class="ams-array-item" :prop="field.field.type !== 'array' && field.field.type !== 'object' ? `${path}[${index}]` : ''"> -