lj-dictionary.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. <!--以一行一个字段的形式展示对象信息-->
  2. <!--文档-->
  3. <!--props:看代码注释-->
  4. <!--events-->
  5. <!--删除按钮确认通过on-delete,参数(value)-->
  6. <!--Action类型的字段点击事件action-row-click,参数{field}-->
  7. <!--column.buttonText不为空时,输入框右边辅助按钮点击事件row-button-click,参数{field}-->
  8. <template>
  9. <group class="lj-group" style="box-sizing: content-box;" label-width="60px">
  10. <cell
  11. class="cell-row"
  12. v-if="deletable"
  13. @click.native="handleDeleteButton">
  14. <span style="color:brown;">
  15. 删除
  16. </span>
  17. </cell>
  18. <template v-for="column in filtedList">
  19. <!-- 静态文本 -->
  20. <cell
  21. v-show="isRowDisplay(column)"
  22. v-if="column.cardParams.type === 'TextField'"
  23. :title="column.label"
  24. :primary="cellPrimary"
  25. :value-align="textAlign"
  26. class="cell-row"
  27. :class="{'readonly': !column.cardParams.enabled}"
  28. :style="column.style">
  29. <div>
  30. <span style="color: #000">{{data[column.property] + (column.append?' '+data[column.append]:'')}}</span>
  31. </div>
  32. </cell>
  33. <!-- 文本输入 -->
  34. <x-input
  35. :ref="column.property"
  36. v-show="isRowDisplay(column)"
  37. v-if="column.cardParams.type === 'TextInput'"
  38. :title="column.label"
  39. v-model="data[column.property]"
  40. :required="column.cardParams.required"
  41. :text-align="textAlign"
  42. :placeholder="column.cardParams.required? '必填' : ''"
  43. :show-clear="false"
  44. :readonly="!column.cardParams.enabled"
  45. class="cell-row"
  46. :class="{'readonly': !column.cardParams.enabled}"
  47. @on-focus="handleInputFocus"
  48. @on-blur="handleInputBlur"
  49. @on-enter="handleEnter(column.property, $event)">
  50. <span slot="right" v-if="column.append">{{data[column.append]}}</span>
  51. <span slot="right" @click="handleIcon(column.property, $event)" v-if="column.icon" style="font-size:20px;margin:0px 15px">
  52. <svg class="icon" aria-hide="true" >
  53. <use :xlink:href="column.icon"></use>
  54. </svg>
  55. </span>
  56. <x-button slot="right" v-if="column.buttonText" type="primary" plain mini
  57. @click.native="handleRowButtonClick(column.property, $event)">{{column.buttonText}}
  58. </x-button>
  59. </x-input>
  60. <!-- 数字输入 -->
  61. <x-input
  62. v-show="isRowDisplay(column)"
  63. v-if="column.cardParams.type === 'Number'"
  64. :title="column.label"
  65. v-model="data[column.property]"
  66. :required="column.cardParams.required"
  67. type="tel"
  68. :show-clear="false"
  69. @on-focus="handleInputFocus"
  70. @on-blur="handleInputBlur"
  71. :text-align="textAlign"
  72. :placeholder="column.cardParams.required? '必填' : ''"
  73. class="cell-row">
  74. <span slot="right" v-if="column.append">&nbsp;{{data[column.append]}}</span>
  75. <span @click="handleIcon(column.property, $event)" v-if="column.icon" style="font-size:20px;margin:0px 15px">
  76. <svg class="icon" aria-hide="true" >
  77. <use :xlink:href="column.icon"></use>
  78. </svg>
  79. </span>
  80. <x-button v-if="column.buttonText" slot="right" type="primary" plain mini
  81. @click.native="handleRowButtonClick(column.property, $event)">{{column.buttonText}}
  82. </x-button>
  83. </x-input>
  84. <!--多行文字输入-->
  85. <x-textarea
  86. v-show="isRowDisplay(column)"
  87. v-if="column.cardParams.type === 'TextArea'"
  88. :title="column.label"
  89. v-model="data[column.property]"
  90. :rows="column.inputLine"
  91. :placeholder="column.cardParams.required? '必填' : ''"
  92. class="cell-row" style="height: auto;">
  93. </x-textarea>
  94. <!--<x-number-->
  95. <!--v-if="column.cardParams.type === 'Number'"-->
  96. <!--:title="column.label"-->
  97. <!--v-model="data[column.property]"-->
  98. <!--:required="column.cardParams.required"-->
  99. <!--text-align="right"-->
  100. <!--fillable-->
  101. <!--:ref="column.property"-->
  102. <!--button-style="round"-->
  103. <!--class="cell-row lj-dictionary-number">-->
  104. <!--<span slot="right" v-if="column.append">{{column.append}}</span>-->
  105. <!--</x-number>-->
  106. <!-- 勾选 -->
  107. <x-switch
  108. v-show="isRowDisplay(column)"
  109. v-if="column.cardParams.type === 'Checkbox'"
  110. :title="column.label"
  111. :value-map="[0, 1]"
  112. class="cell-row"
  113. :class="{'readonly': !column.cardParams.enabled}"
  114. v-model="data[column.property]"
  115. :disabled="!column.cardParams.enabled"
  116. @switch-height="cell-row"
  117. style="padding-top: 10px;padding-bottom: 10px"/>
  118. <!--时间选择器-->
  119. <datetime
  120. v-show="isRowDisplay(column)"
  121. v-if="column.cardParams.type === 'DateTime'"
  122. v-model="data[column.property]"
  123. :readonly="!column.cardParams.enabled"
  124. :title="column.label"
  125. :format="column.cardParams.format"
  126. :display-format="dateTimeDisplayFormatMap[column.cardParams.format]"
  127. :class="{'readonly': !column.cardParams.enabled}"
  128. class="cell-row">
  129. <div style="display: flex;width: 100%;">
  130. <label v-html="titleHtml(column.label)"></label>
  131. <div style="width: 100%">
  132. <div style="float: left;">{{column.inlineDesc}}</div>
  133. <div style="float: right;">{{dateTimeDisplayFormatMap[column.cardParams.format](data[column.property])}}</div>
  134. </div>
  135. </div>
  136. </datetime>
  137. <!--选择器-->
  138. <lj-select
  139. v-show="isRowDisplay(column)"
  140. v-if="column.cardParams.type === 'Select'"
  141. cell
  142. class="cell-row"
  143. :title="titleHtml(column.label)"
  144. :disabled="!column.cardParams.enabled"
  145. v-model="data[column.property]"
  146. :options="column.cardParams.selectOptions.options"
  147. :value-map="column.cardParams.selectOptions.valueMap"
  148. :options-api="column.cardParams.selectOptions.optionsApi"
  149. :api-params="column.cardParams.selectOptions.apiParams"
  150. :extra-options="column.cardParams.selectOptions.extraOptions"
  151. @change="handleRowSelectChange(column.property, $event)"/>
  152. <!-- 右侧带箭头的文本,具有点击动画,触发事件 -->
  153. <cell
  154. v-show="isRowDisplay(column)"
  155. v-if="column.cardParams.type === 'Action'"
  156. :title="column.label"
  157. is-link
  158. @click.native="handleActionRowClick(column.property, $event)"
  159. :value-align="textAlign"
  160. :primary="cellPrimary"
  161. class="cell-row">
  162. <div>
  163. <span style="color: #000">{{data[column.property]}}</span>
  164. </div>
  165. </cell>
  166. </template>
  167. </group>
  168. </template>
  169. <script>
  170. import {XInput, XSwitch, Group, Cell, Datetime, GroupTitle, XNumber, XButton,XTextarea} from 'vux'
  171. import LjSelect from "components/lj-select";
  172. export default {
  173. name: "lj-dictionary",
  174. components: {
  175. XTextarea,
  176. XButton,
  177. LjSelect,
  178. GroupTitle,
  179. Datetime,
  180. Group,
  181. Cell,
  182. XInput,
  183. XSwitch,
  184. XNumber
  185. },
  186. props: {
  187. data: {
  188. // 数据模型
  189. type: Object,
  190. default: function () {
  191. return {};
  192. }
  193. },
  194. columns: {
  195. // 模型字段
  196. type: Array,
  197. default: function () {
  198. return [];
  199. }
  200. // column:{
  201. // label:标题,
  202. // property:字段,
  203. // type: DateTime/Number/Select/Action/AlwaysAction/Boolean/TextField/TextInput,
  204. // format: DateTime所用的时间选择及显示格式,默认YYYY-MM-DD,参考格式YYYY-MM-DD HH:mm
  205. // selectOptions:lj-select属性,
  206. // required: -1不可编辑/0默认/1必填,
  207. // append: 后缀
  208. // buttonText:右侧附加按钮文字
  209. // inputLine: 文字输入行数
  210. // inlineDesc:日期类型-描述
  211. // icon :后置图标
  212. // maxEnable:最高级判断是否能编辑
  213. // }
  214. },
  215. // 是否显示删除按钮
  216. deletable: {
  217. type: Boolean,
  218. default: false
  219. },
  220. // 是否正在编辑状态
  221. editing: {
  222. type: Boolean,
  223. default: false
  224. }
  225. },
  226. mounted() {
  227. this.refreshDisplayColumnList();
  228. },
  229. data() {
  230. return {
  231. styleList: null,
  232. filtedList: [],
  233. cellPrimary: "content",
  234. textAlign: "left",
  235. height: '100px',
  236. dateTimeDisplayFormatMap: {}
  237. }
  238. },
  239. methods: {
  240. titleHtml(label){
  241. // return `<div style="width:60px;font-weight: bold;text-align-last: justify;">${label}</div>`;
  242. return `<div>${label}</div>`;
  243. },
  244. isRowDisplay(column) {
  245. return !(column.hideWhenEditing && this.editing);
  246. },
  247. computeStyleList() {
  248. let self = this;
  249. // 计算标签类型、是否必填、是否可编辑
  250. let list = this.columns;
  251. for (let item of list) {
  252. if (item.display === undefined) {
  253. item.display = true;
  254. }
  255. let cardParams = {};
  256. if (item.type) {
  257. if (item.type === "Boolean") {
  258. cardParams.type = 'Checkbox';
  259. } else if (item.type === 'Select') {
  260. cardParams.type = item.type;
  261. if (item.selectOptions) {
  262. cardParams.selectOptions = item.selectOptions;
  263. } else {
  264. console.error("错误,未设置select属性")
  265. }
  266. } else if (item.type === "DateTime") {
  267. cardParams.type = item.type;
  268. let vuxFormat = "YYYY-MM-DD";
  269. if (item.format) {
  270. vuxFormat = item.format;
  271. }
  272. cardParams.format = vuxFormat;
  273. let ljFormat = vuxFormat.toLowerCase().replace("mm", "MM");
  274. if (!this.dateTimeDisplayFormatMap[vuxFormat]) {
  275. this.dateTimeDisplayFormatMap[vuxFormat] = function (val) {
  276. return $lj.dateformat(val, ljFormat);
  277. }
  278. }
  279. } else {
  280. cardParams.type = item.type; // Number || AlwaysAction|| Action
  281. }
  282. } else {
  283. if (item.inputLine && item.inputLine > 1) {
  284. cardParams.type = 'TextArea';
  285. } else {
  286. cardParams.type = 'TextField';
  287. }
  288. }
  289. var editable = (item.required !== -1);
  290. if (cardParams.type === 'AlwaysAction') {
  291. cardParams.type = 'Action'
  292. } else if (cardParams.type === 'AlwaysInput') {
  293. cardParams.enabled = true;
  294. cardParams.type = 'TextInput';
  295. } else if (this.editing && editable) {
  296. cardParams.enabled = true;
  297. if (cardParams.type === 'TextField') {
  298. cardParams.type = 'TextInput';
  299. } else if (cardParams.type === 'AlwaysAction') {
  300. cardParams.type = 'Action';
  301. }
  302. if (item.required === 1) {
  303. cardParams.required = true;
  304. }
  305. } else {
  306. cardParams.enabled = false;
  307. if ('Checkbox,Select,DateTime'.indexOf(cardParams.type) < 0) {
  308. cardParams.type = 'TextField';
  309. }
  310. }
  311. if (item.maxEnable === true) {
  312. cardParams.enabled = true;
  313. }else if (item.maxEnable === false){
  314. cardParams.enabled = false;
  315. }
  316. item.cardParams = cardParams;
  317. }
  318. this.styleList = list;
  319. },
  320. handleDeleteButton() {
  321. if (!this.deletable) return;
  322. if (!confirm("确定删除所选记录?")) return;
  323. this.$emit('on-delete', this.data);
  324. },
  325. handleActionRowClick(field, event) {
  326. let eventData = {field: field};
  327. this.$emit("action-row-click", eventData);
  328. },
  329. handleRowButtonClick(field, event) {
  330. let eventData = {field: field};
  331. this.$emit("row-button-click", eventData);
  332. },
  333. handleIcon(field, event){
  334. let eventData = {field: field};
  335. this.$emit("row-icon-click",eventData);
  336. },
  337. handleEnter(field, event){
  338. let eventData = {field: field};
  339. this.$emit("row-kd-enter",eventData);
  340. },
  341. handleRowSelectChange(field, value) {
  342. this.$emit("row-select-change",{property: field.property, value: value});
  343. },
  344. refreshDisplayColumnList() {
  345. this.computeStyleList();
  346. this.filtedList = [];
  347. for (let column of this.styleList) {
  348. if (column.display) {
  349. this.filtedList.push(column);
  350. }
  351. }
  352. },
  353. handleInputFocus(value, element) {
  354. element.srcElement.select();
  355. this.$emit('inputfocus');
  356. },
  357. handleInputBlur() {
  358. this.$emit('inputblur');
  359. },
  360. _fnFocus(name) {
  361. this.$refs[name][0] && this.$refs[name][0].focus();
  362. },
  363. _fnReset(name) {
  364. this.$refs[name][0] && this.$refs[name][0].reset();
  365. }
  366. },
  367. watch: {
  368. editing(newVal, oldVal) {
  369. if (newVal !== oldVal) {
  370. this.refreshDisplayColumnList();
  371. }
  372. },
  373. columns(newVal, oldVal) {
  374. if (newVal !== oldVal) {
  375. this.refreshDisplayColumnList();
  376. }
  377. }
  378. }
  379. }
  380. </script>
  381. <style lang="less">
  382. @import "../assets/css/lj-base.less";
  383. .cell-row {
  384. font-size: 15px;
  385. height: @dictionaryCellHeight;
  386. min-height: @dictionaryCellHeight;
  387. }
  388. .cell-row label{
  389. font-weight: bold;
  390. margin:0;
  391. width: 60px;
  392. flex: 0 0 60px;
  393. text-align-last: justify;
  394. margin-right: 10px;
  395. }
  396. .cell-row.readonly label{
  397. color: @secondary;
  398. }
  399. input.weui-input {
  400. padding: 1px 0;
  401. }
  402. </style>