综合办公系统
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

expense.vue 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  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>{{ '【' + deviceInfo.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. {{ deviceInfo.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. {{ deviceInfo.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. {{ deviceInfo.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. {{ deviceInfo.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(deviceInfo.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. {{ deviceInfo.driver }}
  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. {{ deviceInfo.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. {{ deviceInfo.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. {{ deviceInfo.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. {{ deviceInfo.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. {{ deviceInfo.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 { getDevice } from '@/api/oa/device/device.js'
  165. import { listCarExpense, getCarExpense, delCarExpense, addCarExpense, updateCarExpense } from "@/api/oa/car/carExpense";
  166. export default {
  167. data() {
  168. let validateExpense = (rule, value, callback) => {
  169. setTimeout(() => {
  170. if (!value) {
  171. return callback(new Error('请输入金额'));
  172. }
  173. if (!this.isNumber(Number(value))) {
  174. callback(new Error('请输入数字值'));
  175. } else {
  176. callback();
  177. }
  178. }, 100)
  179. }
  180. return {
  181. column: 4,
  182. deviceInfo: {},
  183. expenseList: [],
  184. queryParams: {
  185. pageNum: 1,
  186. pageSize: 10,
  187. },
  188. total: 0,
  189. multiple: true,
  190. // 选中数组
  191. ids: [],
  192. // 非单个禁用
  193. single: true,
  194. title: '',
  195. open: false,
  196. form: {},
  197. rules: {
  198. expenseType: [
  199. { required: true, message: '请选择费用类型', trigger: 'change' }
  200. ],
  201. expense: [
  202. { validator: validateExpense, required: true, trigger: 'blur' },
  203. ],
  204. occurDate: [
  205. { required: true, message: '请选择发生日期', trigger: 'change' },
  206. ],
  207. },
  208. loading: false
  209. }
  210. },
  211. created() {
  212. if (this.$route.query) {
  213. getDevice(this.$route.query.deviceId).then(res => {
  214. console.log(res);
  215. this.deviceInfo = res.data;
  216. })
  217. this.getList();
  218. }
  219. if (this.$store.state.app.device == 'desktop') {
  220. } else {
  221. this.column = 1
  222. }
  223. },
  224. methods: {
  225. getList() {
  226. this.queryParams.carId = this.$route.query.carId
  227. listCarExpense(this.queryParams).then(res => {
  228. console.log(res);
  229. this.expenseList = res.rows;
  230. this.total = res.total;
  231. })
  232. },
  233. goBack() {
  234. let obj = { path: "/car/expense" }
  235. this.$tab.closeOpenPage(obj);
  236. this.$router.push({ path: '/car' });
  237. },
  238. /** 搜索按钮操作 */
  239. handleQuery() {
  240. this.queryParams.pageNum = 1;
  241. this.getList();
  242. },
  243. // 多选框选中数据
  244. handleSelectionChange(selection) {
  245. this.ids = selection.map(item => item.carExpenseId)
  246. this.single = selection.length !== 1
  247. this.multiple = !selection.length
  248. },
  249. handleAdd() {
  250. this.reset();
  251. this.open = true;
  252. this.title = "添加车辆明细";
  253. },
  254. handleUpdate(row) {
  255. this.reset();
  256. const carExpenseId = row.carExpenseId || this.ids
  257. getCarExpense(carExpenseId).then(response => {
  258. this.form = response.data;
  259. this.open = true;
  260. this.title = "修改车辆明细";
  261. });
  262. },
  263. handleDelete(row) {
  264. debugger
  265. const carExpenseIds = row.carExpenseId || this.ids;
  266. this.$modal.confirm('是否确认删除车辆费用编号为"' + carExpenseIds + '"的数据项?').then(function () {
  267. return delCarExpense(carExpenseIds);
  268. }).then(() => {
  269. this.getList();
  270. this.$modal.msgSuccess("删除成功");
  271. }).catch(() => { });
  272. },
  273. handleExport() {
  274. this.download('oa/carExpense/export', {
  275. ...this.queryParams
  276. }, `carExpense_${new Date().getTime()}.xlsx`)
  277. },
  278. // 表单重置
  279. reset() {
  280. this.form = {
  281. carExpenseId: null,
  282. carId: null,
  283. expenseType: null,
  284. expense: null,
  285. occurDate: null
  286. };
  287. this.resetForm("expenseForm");
  288. },
  289. submitForm() {
  290. this.$refs["expenseForm"].validate(valid => {
  291. if (valid) {
  292. this.form.carId = this.$route.query.carId
  293. if (this.form.carExpenseId != null) {
  294. updateCarExpense(this.form).then(response => {
  295. this.$modal.msgSuccess("修改成功");
  296. this.open = false;
  297. this.getList();
  298. });
  299. } else {
  300. addCarExpense(this.form).then(response => {
  301. this.$modal.msgSuccess("新增成功");
  302. this.open = false;
  303. this.getList();
  304. });
  305. }
  306. }
  307. });
  308. },
  309. cancel() {
  310. this.open = false;
  311. this.reset();
  312. },
  313. isNumber(value) {
  314. return typeof value === 'number' && /^\d+(\.\d+)?$/.test(value);
  315. },
  316. expenseTypeText(row) {
  317. if (row == '0') {
  318. return '保险费'
  319. }
  320. if (row == '1') {
  321. return '维修/保养费'
  322. }
  323. if (row == '2') {
  324. return '轮胎费'
  325. }
  326. },
  327. typeStyle(row) {
  328. if (row == '0') {
  329. return 'primary'
  330. }
  331. if (row == '1') {
  332. return 'warning'
  333. }
  334. if (row == '2') {
  335. return 'success'
  336. }
  337. }
  338. },
  339. }
  340. </script>
  341. <style lang="scss" scoped>
  342. .header {
  343. position: relative;
  344. text-align: center;
  345. .back {
  346. position: absolute;
  347. left: 12px;
  348. top: -10px;
  349. }
  350. }
  351. .descriptions {
  352. padding: 20px 50px;
  353. }
  354. ::v-deep .el-descriptions-item__label.is-bordered-label {
  355. color: #121212;
  356. background: rgba($color: #46a6ff, $alpha: 0.1);
  357. width: 200px;
  358. }
  359. ::v-deep .el-descriptions .is-bordered .el-descriptions-item__cell {
  360. border: 1px solid #2d3f62;
  361. }
  362. </style>