purchase-add-or-update.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. <template>
  2. <div>
  3. <el-dialog
  4. :title="!id ? '新增': display ? '详情' : '修改'"
  5. width="70%"
  6. :close-on-click-modal="false"
  7. :visible.sync="visible">
  8. <el-form :model="dataForm" :rules="dataRule" ref="dataForm" label-width="auto">
  9. <el-row class="my-row">
  10. <el-col :span="8">
  11. <el-form-item label="采购编码" prop="purchaseCode">
  12. <el-input v-model="dataForm.purchaseCode" :disabled="display || !id" placeholder="系统自动生成,无需填写"></el-input>
  13. </el-form-item>
  14. </el-col>
  15. <el-col :span="16" style="padding-left: 20px">
  16. <el-form-item label="付款方式" prop="payType">
  17. <el-radio-group v-model="dataForm.payType" :disabled="display">
  18. <el-radio :label='"0"'>对公转账</el-radio>
  19. <el-radio :label='"1"'>先行垫付</el-radio>
  20. <el-radio :label='"2"'>财务预支</el-radio>
  21. </el-radio-group>
  22. </el-form-item>
  23. </el-col>
  24. </el-row>
  25. <el-row class="my-row">
  26. <el-col :span="8">
  27. <el-form-item label="采购类别" prop="purchaseType">
  28. <el-select
  29. v-model="dataForm.purchaseType"
  30. :disabled="display"
  31. remote
  32. placeholder="请选择">
  33. <el-option
  34. v-for="item in optionsType"
  35. :key="item.code"
  36. :label="item.value"
  37. :value="item.code">
  38. </el-option>
  39. </el-select>
  40. </el-form-item>
  41. </el-col>
  42. <el-col :span="8" style="padding-left: 20px">
  43. <el-form-item label="申请人" prop="applierId">
  44. <el-input v-if="display" v-model="dataForm.applierName" disabled></el-input>
  45. <el-select v-else
  46. v-model="dataForm.applierId"
  47. remote
  48. filterable
  49. :remote-method="remoteApplier"
  50. @change="onApplierChanged"
  51. placeholder="请选择">
  52. <el-option
  53. v-for="item in optionsApplier"
  54. :key="item.code"
  55. :label="item.value"
  56. :value="item.code">
  57. </el-option>
  58. </el-select>
  59. </el-form-item>
  60. </el-col>
  61. <el-col :span="8" style="padding-left: 20px">
  62. <el-form-item label="申请部门" prop="deptName">
  63. <el-input v-model="dataForm.deptName" disabled></el-input>
  64. </el-form-item>
  65. </el-col>
  66. </el-row>
  67. <el-row class="my-row">
  68. <el-form-item label="备注" prop="notes">
  69. <el-input v-model="dataForm.notes" :disabled="display" placeholder="备注"></el-input>
  70. </el-form-item>
  71. </el-row>
  72. <div class="title"><span style="color: red">*</span> 采购物品明细</div>
  73. <el-row>
  74. <el-table
  75. :data="materialDetails"
  76. border
  77. style="width: 100%;">
  78. <el-table-column
  79. label="序号"
  80. type="index"
  81. width="50"
  82. align="center">
  83. </el-table-column>
  84. <el-table-column
  85. prop="detailId"
  86. label="ID"
  87. v-if="false">
  88. </el-table-column>
  89. <el-table-column
  90. prop="name"
  91. header-align="center"
  92. align="center"
  93. min-width="120"
  94. label="物品名称">
  95. </el-table-column>
  96. <el-table-column
  97. prop="specification"
  98. header-align="center"
  99. align="center"
  100. min-width="120"
  101. label="型号及规格">
  102. </el-table-column>
  103. <el-table-column
  104. prop="cnt"
  105. header-align="center"
  106. align="center"
  107. label="数量">
  108. </el-table-column>
  109. <el-table-column
  110. prop="unitName"
  111. header-align="center"
  112. align="center"
  113. label="单位">
  114. </el-table-column>
  115. <el-table-column
  116. prop="price"
  117. header-align="center"
  118. align="center"
  119. label="不含税单价">
  120. </el-table-column>
  121. <el-table-column
  122. prop="taxPrice"
  123. header-align="center"
  124. align="center"
  125. label="含税单价">
  126. </el-table-column>
  127. <el-table-column
  128. prop="taxAmount"
  129. header-align="center"
  130. align="center"
  131. label="含税总价">
  132. </el-table-column>
  133. <el-table-column
  134. prop="taxRate"
  135. header-align="center"
  136. align="center"
  137. :formatter="formatPercent"
  138. label="税率">
  139. </el-table-column>
  140. <el-table-column
  141. prop="notes"
  142. header-align="center"
  143. align="center"
  144. label="备注">
  145. </el-table-column>
  146. <el-table-column
  147. v-if="!display"
  148. fixed="right"
  149. header-align="center"
  150. align="center"
  151. width="150"
  152. label="操作">
  153. <template slot-scope="scope">
  154. <el-button type="text" size="small" @click="addMaterialHandle(scope.row, false)">编辑</el-button>
  155. <el-button style="color: red" type="text" size="small" @click="deleteMaterialHandle(scope.row.detailId)">删除</el-button>
  156. </template>
  157. </el-table-column>
  158. </el-table>
  159. </el-row>
  160. <el-row v-if="!display" style="text-align: center; margin-top: 10px;">
  161. <el-button type="primary" icon="el-icon-plus" @click="addMaterial"></el-button>
  162. </el-row>
  163. </el-form>
  164. <span slot="footer" class="dialog-footer">
  165. <el-button @click="visible = false">取消</el-button>
  166. <el-button v-if="!display" type="primary" @click="dataFormSubmit()">确定</el-button>
  167. </span>
  168. </el-dialog>
  169. <!-- 新增物品 -->
  170. <Add v-show="addMaterialVisible" ref="comAddMaterial" @addItem="addMaterialCallback"/>
  171. </div>
  172. </template>
  173. <script>
  174. import Add from './add-material'
  175. import { getDictList } from '@/api/dict'
  176. import { getPurchaseDetail } from '@/api/sale'
  177. import { getUserList } from '@/api/user'
  178. export default {
  179. name: 'purchase-add-or-update',
  180. components: {
  181. Add
  182. },
  183. data () {
  184. return {
  185. visible: false,
  186. display: false,
  187. dataList: [],
  188. id: 0,
  189. dataForm: {},
  190. optionsType: [],
  191. optionsApplier: [],
  192. materialDetails: [],
  193. addMaterialVisible: false,
  194. dataRule: {
  195. purchaseType: [{ required: true, message: '请选择采购类别', trigger: 'change' }],
  196. applierId: [{ required: true, message: '请选择申请人', trigger: 'change' }]
  197. }
  198. }
  199. },
  200. methods: {
  201. // 获取采购类别字典
  202. getTypeList () {
  203. getDictList({type: 'purchase_type'}).then(({data}) => {
  204. if (data) {
  205. this.optionsType = data
  206. }
  207. })
  208. },
  209. async init (id, display) {
  210. this.materialDetails = []
  211. this.dataForm = {
  212. payType: '0'
  213. }
  214. this.visible = true
  215. this.id = id || 0
  216. this.display = display
  217. // 获取采购类别字典
  218. if (!id || !display) {
  219. this.getTypeList()
  220. }
  221. if (!id) return
  222. await getPurchaseDetail(this.id).then(({data}) => {
  223. if (data && data.code === '200') {
  224. this.dataForm = data.data
  225. // 获取采购物品明细
  226. if (data.data.details) {
  227. this.materialDetails = []
  228. this.materialDetails = data.data.details
  229. }
  230. }
  231. })
  232. },
  233. validateField (type) {
  234. this.$refs.dataForm.validateField(type)
  235. },
  236. // 表单提交
  237. dataFormSubmit () {
  238. this.$refs['dataForm'].validate((valid) => {
  239. if (valid) {
  240. this.$http({
  241. url: this.$http.adornUrl(`/biz-service/purchase/save`),
  242. method: 'post',
  243. data: this.$http.adornData({...this.dataForm, orgId: this.orgId})
  244. }).then(({data}) => {
  245. if (data && data.code === '200') {
  246. this.$message({
  247. message: '操作成功',
  248. type: 'success',
  249. duration: 1500,
  250. onClose: () => {
  251. this.visible = false
  252. this.$emit('refreshDataList')
  253. }
  254. })
  255. } else {
  256. this.$message.error(data.msg)
  257. }
  258. })
  259. }
  260. })
  261. },
  262. // 获取申请人
  263. async remoteApplier (query) {
  264. if (!query) return
  265. const params = {
  266. name: query.trimStart()
  267. }
  268. await getUserList(params).then(({data}) => {
  269. if (data && data.code === '200') {
  270. this.optionsApplier = []
  271. data.data.records.forEach((item) => {
  272. this.optionsApplier.push({
  273. code: item.userId,
  274. value: item.name + ' (用户名: ' + item.username + ')',
  275. orgId: item.orgId,
  276. orgName: item.orgName
  277. })
  278. })
  279. }
  280. })
  281. },
  282. addMaterial () {
  283. this.addMaterialVisible = true
  284. this.$nextTick(() => {
  285. this.$refs.comAddMaterial.init()
  286. })
  287. },
  288. addMaterialHandle (row, disable) {
  289. this.addMaterialVisible = true
  290. this.$nextTick(() => {
  291. this.$refs.comAddMaterial.init(row.detailId, disable, row)
  292. })
  293. },
  294. deleteMaterialHandle (id) {
  295. this.materialDetails.splice(this.materialDetails.findIndex((item) => item.id === id))
  296. },
  297. addMaterialCallback (data) {
  298. if (!data) return
  299. this.addMaterialVisible = false
  300. let i = this.materialDetails.findIndex((item) => item.detailId === data.detailId)
  301. if (i > -1) {
  302. this.materialDetails.splice(i)
  303. }
  304. this.materialDetails.push(data)
  305. },
  306. // 百分比
  307. formatPercent (row) {
  308. if (!row.taxRate) return ''
  309. console.log('taxRate: ' + row.taxRate)
  310. let str = (Number(row.taxRate * 100)).toFixed(0)
  311. str += '%'
  312. return str
  313. },
  314. onApplierChanged (val) {
  315. if (!val) return
  316. let item1 = this.optionsApplier.find((item) => item.code === val)
  317. if (!item1) return
  318. this.dataForm.deptName = item1.orgName
  319. this.dataForm.orgId = item1.orgId
  320. }
  321. }
  322. }
  323. </script>
  324. <style scoped>
  325. </style>