综合办公系统
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

expense.vue 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. <template>
  2. <div class="app-container">
  3. <div class="header">
  4. <el-button icon="el-icon-d-arrow-left" plain type="primary" class="back" @click="goBack">返回</el-button>
  5. <h1>{{ '【' + carInfo.licensePlate + '】' }}车辆明细</h1>
  6. </div>
  7. <el-divider></el-divider>
  8. <el-descriptions class="descriptions" :column="column" border style="text-align: center;">
  9. <el-descriptions-item>
  10. <template slot="label">
  11. <svg-icon slot="prefix" icon-class="car" class="el-input__icon input-icon" />
  12. 车牌号
  13. </template>
  14. {{ carInfo.licensePlate }}
  15. </el-descriptions-item>
  16. <el-descriptions-item>
  17. <template slot="label">
  18. <svg-icon slot="prefix" icon-class="Branding" class="el-input__icon input-icon" />
  19. 品牌
  20. </template>
  21. {{ carInfo.brand }}
  22. </el-descriptions-item>
  23. <el-descriptions-item>
  24. <template slot="label">
  25. <svg-icon slot="prefix" icon-class="PhAppStoreLogoFill" class="el-input__icon input-icon" />
  26. 车型
  27. </template>
  28. {{ carInfo.series }}
  29. </el-descriptions-item>
  30. <el-descriptions-item>
  31. <template slot="label">
  32. <svg-icon slot="prefix" icon-class="cost" class="el-input__icon input-icon" />
  33. 总价(元)
  34. </template>
  35. {{ carInfo.cost }}
  36. </el-descriptions-item>
  37. <el-descriptions-item>
  38. <template slot="label">
  39. <svg-icon slot="prefix" icon-class="date" class="el-input__icon input-icon" />
  40. 上牌时间
  41. </template>
  42. {{ parseTime(carInfo.acquisitionTime, '{y}-{m}-{d}') }}
  43. </el-descriptions-item>
  44. <el-descriptions-item>
  45. <template slot="label">
  46. <i class="el-icon-user-solid"></i>
  47. 驾驶员
  48. </template>
  49. {{ carInfo.driverUser ? carInfo.driverUser.nickName : '' }}
  50. </el-descriptions-item>
  51. <el-descriptions-item>
  52. <template slot="label">
  53. <svg-icon slot="prefix" icon-class="date" class="el-input__icon input-icon" />
  54. 预计使用年限(年)
  55. </template>
  56. {{ carInfo.expectLife }}
  57. </el-descriptions-item>
  58. <el-descriptions-item>
  59. <template slot="label">
  60. <svg-icon slot="prefix" icon-class="car" class="el-input__icon input-icon" />
  61. 预计行驶里程(万千米)
  62. </template>
  63. {{ carInfo.expectKm }}
  64. </el-descriptions-item>
  65. <el-descriptions-item>
  66. <template slot="label">
  67. <svg-icon slot="prefix" icon-class="JamYelpSquare" class="el-input__icon input-icon" />
  68. 是否为租车
  69. </template>
  70. {{ carInfo.isRent == '0' ? '否' : '是' }}
  71. </el-descriptions-item>
  72. <el-descriptions-item>
  73. <template slot="label">
  74. <svg-icon slot="prefix" icon-class="TeenyiconsYenSolid" class="el-input__icon input-icon" />
  75. 单日成本(元)
  76. </template>
  77. {{ carInfo.dayCost }}
  78. </el-descriptions-item>
  79. <el-descriptions-item>
  80. <template slot="label">
  81. <svg-icon slot="prefix" icon-class="remark" class="el-input__icon input-icon" />
  82. 备注
  83. </template>
  84. {{ carInfo.remark }}
  85. </el-descriptions-item>
  86. </el-descriptions>
  87. <!-- 费用明细 -->
  88. <el-divider></el-divider>
  89. <el-card>
  90. <el-row :gutter="10" class="mb8">
  91. <el-col :span="1.5">
  92. <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增</el-button>
  93. </el-col>
  94. <el-col :span="1.5">
  95. <el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single"
  96. @click="handleUpdate">修改</el-button>
  97. </el-col>
  98. <el-col :span="1.5">
  99. <el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple"
  100. @click="handleDelete">删除</el-button>
  101. </el-col>
  102. <el-col :span="1.5">
  103. <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport">导出</el-button>
  104. </el-col>
  105. </el-row>
  106. <el-table v-loading="loading" :data="expenseList" @selection-change="handleSelectionChange">
  107. <el-table-column type="selection" width="55" align="center" />
  108. <el-table-column type="index" width="55" align="center" label="序号" />
  109. <el-table-column label="费用类型" align="center" prop="expenseType">
  110. <template slot-scope="scope">
  111. <el-tag :type="typeStyle(scope.row.expenseType)">{{ expenseTypeText(scope.row.expenseType) }}</el-tag>
  112. </template>
  113. </el-table-column>
  114. <el-table-column label="费用金额" align="center" prop="expense">
  115. <template slot-scope="scope">
  116. {{ scope.row.expense + '元' }}
  117. </template>
  118. </el-table-column>
  119. <el-table-column label="发生日期" align="center" prop="occurDate" width="180">
  120. <template slot-scope="scope">
  121. {{ scope.row.occurDate }}
  122. </template>
  123. </el-table-column>
  124. <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
  125. <template slot-scope="scope">
  126. <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
  127. v-hasPermi="['oa:carExpense:edit']">修改</el-button>
  128. <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
  129. v-hasPermi="['oa:carExpense:remove']">删除</el-button>
  130. </template>
  131. </el-table-column>
  132. </el-table>
  133. <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
  134. @pagination="getList" />
  135. </el-card>
  136. <!-- 添加明细 -->
  137. <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
  138. <el-form ref="expenseForm" :model="form" :rules="rules" label-width="100px">
  139. <el-form-item label="费用类型" prop="expenseType">
  140. <el-select v-model="form.expenseType" placeholder="请选择" clearable>
  141. <el-option label="保险费" value="0"></el-option>
  142. <el-option label="维修/保养费" value="1"></el-option>
  143. <el-option label="轮胎费" value="2"></el-option>
  144. </el-select>
  145. </el-form-item>
  146. <el-form-item label="费用金额" prop="expense">
  147. <el-input v-model="form.expense" placeholder="请输入费用金额" style="width:150px" /> <el-tag>元</el-tag>
  148. </el-form-item>
  149. <el-form-item label="发生日期" prop="occurDate">
  150. <el-date-picker clearable v-model="form.occurDate" type="date" value-format="yyyy-MM-dd"
  151. placeholder="请选择发生日期">
  152. </el-date-picker>
  153. </el-form-item>
  154. </el-form>
  155. <div slot="footer" class="dialog-footer">
  156. <el-button type="primary" @click="submitForm">确 定</el-button>
  157. <el-button @click="cancel">取 消</el-button>
  158. </div>
  159. </el-dialog>
  160. </div>
  161. </template>
  162. <script>
  163. import { getCar } from '@/api/oa/car/car.js'
  164. import { listCarExpense, getCarExpense, delCarExpense, addCarExpense, updateCarExpense } from "@/api/oa/car/carExpense";
  165. export default {
  166. data() {
  167. let validateExpense = (rule, value, callback) => {
  168. setTimeout(() => {
  169. if (!value) {
  170. return callback(new Error('请输入金额'));
  171. }
  172. if (!this.isNumber(Number(value))) {
  173. callback(new Error('请输入数字值'));
  174. } else {
  175. callback();
  176. }
  177. }, 100)
  178. }
  179. return {
  180. column: 4,
  181. carInfo: {},
  182. expenseList: [],
  183. queryParams: {
  184. pageNum: 1,
  185. pageSize: 10,
  186. },
  187. total: 0,
  188. multiple: true,
  189. // 选中数组
  190. ids: [],
  191. // 非单个禁用
  192. single: true,
  193. title: '',
  194. open: false,
  195. form: {},
  196. rules: {
  197. expenseType: [
  198. { required: true, message: '请选择费用类型', trigger: 'change' }
  199. ],
  200. expense: [
  201. { validator: validateExpense, required: true, trigger: 'blur' },
  202. ],
  203. occurDate: [
  204. { required: true, message: '请选择发生日期', trigger: 'change' },
  205. ],
  206. },
  207. loading: false
  208. }
  209. },
  210. created() {
  211. if (this.$route.query) {
  212. getCar(this.$route.query.carId).then(res => {
  213. console.log(res);
  214. this.carInfo = res.data;
  215. })
  216. this.getList();
  217. }
  218. if (this.$store.state.app.device == 'desktop') {
  219. } else {
  220. this.column = 1
  221. }
  222. },
  223. methods: {
  224. getList() {
  225. this.queryParams.carId = this.$route.query.carId
  226. listCarExpense(this.queryParams).then(res => {
  227. console.log(res);
  228. this.expenseList = res.rows;
  229. this.total = res.total;
  230. })
  231. },
  232. goBack() {
  233. let obj = { path: "/car/expense" }
  234. this.$tab.closeOpenPage(obj);
  235. this.$router.push({ path: '/car' });
  236. },
  237. /** 搜索按钮操作 */
  238. handleQuery() {
  239. this.queryParams.pageNum = 1;
  240. this.getList();
  241. },
  242. // 多选框选中数据
  243. handleSelectionChange(selection) {
  244. this.ids = selection.map(item => item.carExpenseId)
  245. this.single = selection.length !== 1
  246. this.multiple = !selection.length
  247. },
  248. handleAdd() {
  249. this.reset();
  250. this.open = true;
  251. this.title = "添加车辆明细";
  252. },
  253. handleUpdate(row) {
  254. this.reset();
  255. const carExpenseId = row.carExpenseId || this.ids
  256. getCarExpense(carExpenseId).then(response => {
  257. this.form = response.data;
  258. this.open = true;
  259. this.title = "修改车辆明细";
  260. });
  261. },
  262. handleDelete(row) {
  263. const carExpenseIds = row.carExpenseId || this.ids;
  264. this.$modal.confirm('是否确认删除车辆费用编号为"' + carExpenseIds + '"的数据项?').then(function () {
  265. return delCarExpense(carExpenseIds);
  266. }).then(() => {
  267. this.getList();
  268. this.$modal.msgSuccess("删除成功");
  269. }).catch(() => { });
  270. },
  271. handleExport() {
  272. this.download('oa/carExpense/export', {
  273. ...this.queryParams
  274. }, `carExpense_${new Date().getTime()}.xlsx`)
  275. },
  276. // 表单重置
  277. reset() {
  278. this.form = {
  279. carExpenseId: null,
  280. carId: null,
  281. expenseType: null,
  282. expense: null,
  283. occurDate: null
  284. };
  285. this.resetForm("expenseForm");
  286. },
  287. submitForm() {
  288. this.$refs["expenseForm"].validate(valid => {
  289. if (valid) {
  290. this.form.carId = this.$route.query.carId
  291. if (this.form.carExpenseId != null) {
  292. updateCarExpense(this.form).then(response => {
  293. this.$modal.msgSuccess("修改成功");
  294. this.open = false;
  295. this.getList();
  296. });
  297. } else {
  298. addCarExpense(this.form).then(response => {
  299. this.$modal.msgSuccess("新增成功");
  300. this.open = false;
  301. this.getList();
  302. });
  303. }
  304. }
  305. });
  306. },
  307. cancel() {
  308. this.open = false;
  309. this.reset();
  310. },
  311. isNumber(value) {
  312. return typeof value === 'number' && /^\d+(\.\d+)?$/.test(value);
  313. },
  314. expenseTypeText(row) {
  315. if (row == '0') {
  316. return '保险费'
  317. }
  318. if (row == '1') {
  319. return '维修/保养费'
  320. }
  321. if (row == '2') {
  322. return '轮胎费'
  323. }
  324. },
  325. typeStyle(row) {
  326. if (row == '0') {
  327. return 'primary'
  328. }
  329. if (row == '1') {
  330. return 'warning'
  331. }
  332. if (row == '2') {
  333. return 'success'
  334. }
  335. }
  336. },
  337. }
  338. </script>
  339. <style lang="scss" scoped>
  340. .header {
  341. position: relative;
  342. text-align: center;
  343. .back {
  344. position: absolute;
  345. left: 12px;
  346. top: -10px;
  347. }
  348. }
  349. .descriptions {
  350. padding: 20px 50px;
  351. }
  352. ::v-deep .el-descriptions-item__label.is-bordered-label {
  353. color: #121212;
  354. background: rgba($color: #46a6ff, $alpha: 0.1);
  355. width: 200px;
  356. }
  357. ::v-deep .el-descriptions .is-bordered .el-descriptions-item__cell {
  358. border: 1px solid #2d3f62;
  359. }
  360. </style>