index.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. <script>
  2. import { add } from "@/api/business/purchase/purchase-contract";
  3. import { arr2obj } from "@/utils/data-transform";
  4. import {
  5. initDicts,
  6. initRules,
  7. initParams,
  8. initComponents,
  9. } from "@/utils/init-something";
  10. import { initColumns, initTabColumns } from "./column";
  11. export default {
  12. name: "AddPurchaseContractDrawer",
  13. components: initComponents(initColumns()),
  14. dicts: initDicts(initColumns()),
  15. data() {
  16. return {
  17. visible: false,
  18. columns: initColumns(),
  19. rules: initRules(initColumns()),
  20. params: initParams(initColumns()),
  21. tabColumns: initTabColumns(),
  22. tabName: "PuContractItem",
  23. tabTableParams: {
  24. PuContractItem: [],
  25. PuContractClause: [],
  26. PuContractExpense: [],
  27. PuContractAgreement: [],
  28. PuContractApplyOrg: [],
  29. },
  30. currentComponent: { name: "", title: "", value: "", row: {}, source: {} },
  31. };
  32. },
  33. computed: {},
  34. watch: {},
  35. methods: {
  36. beforeOpen() {
  37. const { deptName, nickName, orgName } = this.$store.state.user;
  38. this.params.puOrg = orgName;
  39. this.params.buyer = nickName;
  40. this.params.puDept = deptName;
  41. },
  42. setVisible(prop) {
  43. this.visible = prop;
  44. },
  45. addTableRow(prop) {
  46. this.$notify.info({ message: prop });
  47. this.tabTableParams[prop].push(
  48. arr2obj(
  49. initTabColumns().find((element) => element.key === prop).tableColumns,
  50. "key",
  51. ""
  52. )
  53. );
  54. console.log(this.tabTableParams);
  55. },
  56. cancel() {
  57. this.setVisible(false);
  58. this.params = arr2obj(this.columns, "key", "value");
  59. },
  60. sava() {
  61. this.setVisible(false);
  62. },
  63. async submitSava() {
  64. console.log(this.params);
  65. return;
  66. },
  67. //
  68. openAsyncInputDialog(prop, source, type) {
  69. try {
  70. const {
  71. key,
  72. title,
  73. config: { componentName },
  74. } = prop;
  75. this.currentComponent.row = prop;
  76. this.currentComponent.title = title;
  77. this.currentComponent.name = componentName;
  78. this.currentComponent.source = source;
  79. if (type === "change") {
  80. this.currentComponent.value = this.params[key];
  81. }
  82. if (type === "click") {
  83. this.currentComponent.value = "";
  84. }
  85. this.$nextTick(() => {
  86. const { setVisible } = this.$refs[componentName];
  87. setVisible(true);
  88. });
  89. } catch (err) {
  90. this.$notify.error({ title: "error", message: err });
  91. } finally {
  92. console.log(this.currentComponent, source, this.tabTableParams);
  93. }
  94. },
  95. updateParams(prop) {
  96. const {
  97. config: { dataMapping },
  98. } = this.currentComponent.row;
  99. for (let key in dataMapping) {
  100. this.currentComponent.source[key] = prop[dataMapping[key]];
  101. }
  102. },
  103. },
  104. created() {
  105. // console.log("this,", initComponents(initColumns()));
  106. },
  107. mounted() { },
  108. destroyed() { },
  109. };
  110. </script>
  111. <template>
  112. <el-drawer direction="btt" size="100%" :with-header="false" :visible.sync="visible" @open="beforeOpen">
  113. <el-form size="mini" label-position="right" label-width="135px" :model="params" :rules="rules">
  114. <el-card :body-style="{
  115. padding: '20px',
  116. display: 'flex',
  117. 'flex-wrap': 'wrap',
  118. }" style="margin: 10px">
  119. <div slot="header" style="
  120. display: flex;
  121. justify-content: space-between;
  122. align-items: center;
  123. ">
  124. <h3>新增</h3>
  125. <div style="text-align: right">
  126. <el-button size="mini" @click="cancel">取消</el-button>
  127. <el-button size="mini" type="danger" @click="sava">保存</el-button>
  128. <el-button size="mini" type="info" @click="submitSava">
  129. 保存并新增
  130. </el-button>
  131. </div>
  132. </div>
  133. <component v-if="currentComponent.name" :is="currentComponent.name" :ref="currentComponent.name"
  134. :title="currentComponent.title" :value="currentComponent.value" @confirm="updateParams"></component>
  135. <el-row>
  136. <el-col v-for="(column, index) in columns" :key="index" :span="column.span || 6">
  137. <el-form-item :prop="column.key" :label="column.title">
  138. <el-input v-if="column.type === 'Input'" v-model="params[column.key]" :placeholder="column.placeholder"
  139. :clearable="column.clearable" :disabled="column.disabled" style="width: 100%"></el-input>
  140. <el-input v-if="column.type === 'InputDialog'" v-model="params[column.key]"
  141. :placeholder="column.placeholder" :clearable="column.clearable" :disabled="column.disabled"
  142. style="width: 100%" @blur="openAsyncInputDialog(column, params, 'change')"
  143. @change="openAsyncInputDialog(column, params, 'change')">
  144. <template #suffix>
  145. <el-icon class="el-icon-s-operation" style="cursor: pointer" @click.native.stop="
  146. openAsyncInputDialog(column, params, 'change')
  147. "></el-icon>
  148. </template>
  149. </el-input>
  150. <el-input v-if="column.type === 'Textarea'" v-model="params[column.key]" type="textarea"
  151. :placeholder="column.placeholder" :clearable="column.clearable" :disabled="column.disabled"
  152. style="width: 100%"></el-input>
  153. <el-input-number v-if="column.type === 'InputNumber'" v-model="params[column.key]"
  154. :controls-position="column.config.controlsPosition" :placeholder="column.placeholder"
  155. :clearable="column.clearable" :disabled="column.disabled" style="width: 100%"></el-input-number>
  156. <el-select v-if="column.type === 'Select'" v-model="params[column.key]" :placeholder="column.placeholder"
  157. :clearable="column.clearable" :disabled="column.disabled" style="width: 100%">
  158. <el-option v-for="item in dict.type[column.config.optionsName]" :key="item.value" :label="item.label"
  159. :value="item.value">
  160. </el-option>
  161. </el-select>
  162. <el-select v-if="column.type === 'TagSelect'" v-model="params[column.key]" multiple clearable collapse-tags
  163. :placeholder="column.placeholder" :clearable="column.clearable" :disabled="column.disabled"
  164. style="width: 100%">
  165. <template #prefix>
  166. <el-icon class="el-icon-s-operation" style="cursor: pointer" @click.stop="$message.info(234)"></el-icon>
  167. </template>
  168. <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
  169. </el-option>
  170. </el-select>
  171. <el-date-picker v-if="column.type === 'DatePicker'" v-model="params[column.key]" :type="column.config.type"
  172. :placeholder="column.placeholder" :clearable="column.clearable" :disabled="column.disabled"
  173. :picker-options="column.pickerOptions" style="width: 100%">
  174. </el-date-picker>
  175. <el-upload v-if="column.type === 'Upload'" :file-list="params[column.key]" :disabled="column.disabled" drag
  176. action="https://jsonplaceholder.typicode.com/posts/" multiple>
  177. <i class="el-icon-upload"></i>
  178. <div class="el-upload__text">
  179. 将文件拖到此处,或<em>点击上传</em>
  180. </div>
  181. <div class="el-upload__tip" slot="tip">
  182. 只能上传jpg/png文件,且不超过500kb
  183. </div>
  184. </el-upload>
  185. </el-form-item>
  186. </el-col>
  187. </el-row>
  188. </el-card>
  189. <el-card :body-style="{
  190. padding: '20px',
  191. display: 'flex',
  192. 'flex-wrap': 'wrap',
  193. position: 'relative',
  194. }" style="margin: 10px">
  195. <el-tabs v-model="tabName" @tab-click="handleClick" style="width: 100%">
  196. <el-tab-pane v-for="(column, index) in tabColumns" :key="index" :label="column.title" :name="column.key">
  197. <el-table :data="tabTableParams[column.key]" style="width: 100%">
  198. <el-table-column v-for="(cColumn, cIndex) in column.tableColumns" :key="cIndex" :prop="cColumn.key"
  199. :label="cColumn.title" :width="cColumn.width">
  200. <template slot-scope="scope">
  201. <el-tag v-if="cColumn.key === 'index'">
  202. {{ scope.$index + 1 }}
  203. </el-tag>
  204. <el-input v-if="cColumn.type === 'Input'" v-model="scope.row[cColumn.key]"
  205. :placeholder="cColumn.placeholder" :clearable="cColumn.clearable" :disabled="cColumn.disabled"
  206. size="mini" style="width: 100%"></el-input>
  207. <el-input-number v-if="cColumn.type === 'InputNumber'" v-model="scope.row[cColumn.key]"
  208. :controls-position="cColumn.config.controlsPosition" :placeholder="cColumn.placeholder"
  209. :clearable="cColumn.clearable" :disabled="cColumn.disabled" size="mini"
  210. style="width: 100%"></el-input-number>
  211. <el-input v-if="cColumn.type === 'InputDialog'" v-model="scope.row[cColumn.key]"
  212. :placeholder="cColumn.placeholder" :clearable="cColumn.clearable" :disabled="cColumn.disabled"
  213. size="mini" style="width: 100%" @blur="openAsyncInputDialog(cColumn, scope.row, 'change')"
  214. @change="openAsyncInputDialog(cColumn, scope.row, 'change')">
  215. <template #suffix>
  216. <el-icon class="el-icon-s-operation" style="cursor: pointer" @click.native.stop="
  217. openAsyncInputDialog(cColumn, scope.row, 'click')
  218. "></el-icon>
  219. </template>
  220. </el-input>
  221. </template>
  222. </el-table-column>
  223. </el-table>
  224. </el-tab-pane>
  225. </el-tabs>
  226. <el-row style="position: absolute; top: 20px; right: 20px">
  227. <el-button size="mini" @click="addTableRow(tabName)">增行</el-button>
  228. </el-row>
  229. </el-card>
  230. </el-form>
  231. </el-drawer>
  232. </template>