index.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. <template>
  2. <el-container class="aminui-main-container">
  3. <el-header class="aminui-main-container__query-header">
  4. <el-form :model="params">
  5. <el-row :gutter="15">
  6. <el-col :lg="8" :md="12" :xs="24">
  7. <el-form-item label="所属组织:">
  8. <tree-select ref="deptTreeSelect" v-model="params.deptId" :apiObj="$API.system.dept" isDept check-strictly clearable placeholder="请选择所属组织"></tree-select>
  9. </el-form-item>
  10. </el-col>
  11. <el-col :lg="8" :md="12" :xs="24">
  12. <el-form-item label="采购申请:">
  13. <el-input v-model="params.nameLike" clearable placeholder="请输入采购申请名称"></el-input>
  14. </el-form-item>
  15. </el-col>
  16. <el-col :lg="8" :md="12" :xs="24">
  17. <el-form-item label="采购类别:">
  18. <dict-select ref="dictSelect" v-model="params.type" dic="procurement_category" clearable placeholder="请选择采购类别"></dict-select>
  19. </el-form-item>
  20. </el-col>
  21. <el-col :lg="12" :md="16" :xs="24">
  22. <el-form-item label="申请时间:">
  23. <el-date-picker type="daterange" v-model="createDate" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" value-format="YYYY-MM-DD"></el-date-picker>
  24. </el-form-item>
  25. </el-col>
  26. <el-col :md="8" :xs="24">
  27. <el-form-item>
  28. <el-button @click="dateChange('month')">本月</el-button>
  29. <el-button @click="dateChange('year')" >本年</el-button>
  30. </el-form-item>
  31. </el-col>
  32. </el-row>
  33. </el-form>
  34. <el-button-group>
  35. <el-button type="primary" icon="el-icon-search" @click="reloadTable('add')">查询</el-button>
  36. <el-button icon="el-icon-refresh" @click="reset">重置</el-button>
  37. </el-button-group>
  38. </el-header>
  39. <el-container class="aminui-main-container__table-main">
  40. <el-header>
  41. <div class="left-panel">
  42. <template v-for="(item, key, index) in stepDic" v-bind:key="index">
  43. <el-button v-if="index == 0" type="primary" @click="table_add">发起{{ item }}</el-button>
  44. <el-button v-else type="primary" @click="table_handle(key)">{{ item }}</el-button>
  45. </template>
  46. </div>
  47. </el-header>
  48. <el-main class="nopadding">
  49. <scTable class="scTable" ref="table" row-key="id" :apiObj="api" :params="params" :column="column" tableName="applyTable" pageParams="current" @select="select">
  50. <el-table-column type="selection" align="center" width="55" :selectable="selectable"></el-table-column>
  51. <el-table-column label="序号" type="index" align="center" width="80"></el-table-column>
  52. <template #stepStatus="scope">
  53. <template v-if="scope.row.step">
  54. {{ formatStepStatus(scope.row) }}<sc-status-indicator :type="formatStatus(scope.row[handlerKey(scope.row.step)] || scope.row, 'type')"></sc-status-indicator>
  55. </template>
  56. </template>
  57. <template #planName="scope">{{ scope.row.plan.planName }}</template>
  58. <template #type="scope">{{ formatType(scope.row.type) }}</template>
  59. <template #specialFeeType="scope">{{ formatSpecialType(scope.row.specialFeeType) }}</template>
  60. <template #purchaseType="scope">{{ formatPurchaseType(scope.row.purchaseType) }}</template>
  61. <template #isInPlan="scope">{{ formatBoolean(scope.row.isInPlan) }}</template>
  62. <template #createTime="scope"><span v-time="scope.row.createTime" format="YYYY-MM-DD"></span></template>
  63. <template #deptName="scope">{{ formatDeptName(scope.row.deptId) }}</template>
  64. <template #belongDeptName="scope">{{ formatDeptName(scope.row.belongDeptId) }}</template>
  65. <template #projectName="scope">{{ formatProjectName(scope.row.projectId) }}</template>
  66. <el-table-column label="是否开启" fixed="right" align="center" width="100">
  67. <template #default="scope">
  68. <template v-if="scope.row.bidNotice.processState == 'ENDED'">
  69. <el-switch :model-value="scope.row.oaStatus" :loading="loading" :active-value="0" :inactive-value="1" @change="val => openChange(val, scope.row)"></el-switch>
  70. </template>
  71. </template>
  72. </el-table-column>
  73. <el-table-column label="操作" fixed="right" align="center" width="240">
  74. <template #default="scope">
  75. <template v-if="showBtnGroup(scope.row)">
  76. <el-button text @click="table_detail(scope.row)">提交</el-button><el-divider direction="vertical" />
  77. <el-button text @click="table_detail(scope.row)">编辑</el-button><el-divider direction="vertical" />
  78. <el-button text @click="table_del(scope.row)">删除</el-button><el-divider direction="vertical" />
  79. </template>
  80. <template v-else>
  81. <el-button text @click="table_detail(scope.row)">申请详情</el-button><el-divider direction="vertical" />
  82. </template>
  83. <el-dropdown trigger="click" @command="table_handle($event, scope.row)">
  84. <el-button text>更多</el-button>
  85. <template #dropdown>
  86. <el-dropdown-menu>
  87. <template v-for="(item, key, index) in moreDropdown" v-bind:key="index">
  88. <el-dropdown-item :command="key" :divided="index > 0">{{ item }}</el-dropdown-item>
  89. </template>
  90. </el-dropdown-menu>
  91. </template>
  92. </el-dropdown>
  93. </template>
  94. </el-table-column>
  95. </scTable>
  96. </el-main>
  97. </el-container>
  98. </el-container>
  99. <apply-detail v-if="dialog.detail" ref="applyDetail" @success="reloadTable" @closed="dialog.detail = false"></apply-detail>
  100. <handle-detail v-if="dialog.handle" ref="handleDetail" @success="reloadTable" @closed="dialog.handle = false"></handle-detail>
  101. </template>
  102. <script>
  103. import moment from "moment";
  104. import { column, stepDic } from "./main";
  105. import { statusDic } from "@/views/procurement/plan/main";
  106. import applyDetail from "./detail";
  107. import handleDetail from "./handle";
  108. export default {
  109. components: {
  110. applyDetail,
  111. handleDetail
  112. },
  113. data() {
  114. return {
  115. column, stepDic,
  116. api: this.$API.procurement.ledger,
  117. projects: [],
  118. purchaseTypes: [],
  119. specialTypes: [],
  120. createDate: [],
  121. params: {
  122. orderBy: "createTime_desc",
  123. deptIdIn: this.$TOOL.data.get("USER_INFO").deptIdList,
  124. deptId: null,
  125. nameLike: null,
  126. type: null
  127. },
  128. selectData: null,
  129. dialog: {
  130. detail: false,
  131. handle: false
  132. },
  133. loading: false
  134. }
  135. },
  136. computed: {
  137. moreDropdown() {
  138. const dropdown = {};
  139. for (const key in stepDic) {
  140. if (key != "purchase_apply") dropdown[key] = stepDic[key];
  141. }
  142. return dropdown;
  143. },
  144. depts() {
  145. return this.$refs.deptTreeSelect && this.$refs.deptTreeSelect.treeList || [];
  146. },
  147. dicts() {
  148. return this.$refs.dictSelect && this.$refs.dictSelect.options || [];
  149. }
  150. },
  151. mounted() {
  152. this.getProjects();
  153. this.getPurchaseTypes();
  154. this.getSpecialTypes();
  155. },
  156. methods: {
  157. handlerKey(mode) {
  158. const modeArray = mode.split("purchase_")[1].split("_");
  159. const suffixArray = modeArray.slice(1);
  160. return modeArray[0] + suffixArray.map(str => this.$TOOL.capitalizeWords(str)).join("");
  161. },
  162. formatStepStatus(row) {
  163. const stepName = stepDic[row.step] || "";
  164. const statusName = this.formatStatus(row[this.handlerKey(row.step)] || row, "label");
  165. return stepName && statusName && (stepName + " - " + statusName) || "";
  166. },
  167. formatStatus({ status, processState }, key) {
  168. if (!status) {
  169. if (processState && key == "label") return "审核终止";
  170. if (!processState && key == "label") return "待发起审核";
  171. if (key == "type") return "blue";
  172. }
  173. return statusDic[status][key];
  174. },
  175. formatType(value) {
  176. return this.dicts.find(d => d.value == value) && this.dicts.find(d => d.value == value).label || "";
  177. },
  178. formatSpecialType(value) {
  179. return this.specialTypes.find(p => p.value == value) && this.specialTypes.find(p => p.value == value).label || "";
  180. },
  181. formatPurchaseType(value) {
  182. return this.purchaseTypes.find(p => p.value == value) && this.purchaseTypes.find(p => p.value == value).label || "";
  183. },
  184. formatBoolean(value) {
  185. return value && "是" || "否";
  186. },
  187. formatDeptName(value) {
  188. return this.depts && this.depts.find(d => d.deptId == value) && this.depts.find(d => d.deptId == value).name || "";
  189. },
  190. formatProjectName(value) {
  191. return this.projects && this.projects.find(d => d.id == value) && this.projects.find(d => d.id == value).projectName || "";
  192. },
  193. showBtnGroup(row) {
  194. if (row.processState == "ENDED") return false;
  195. for (const key in stepDic) { // 所有过程中不能有已完成
  196. if (row[this.handlerKey(key)] && row[this.handlerKey(key)].processState == "ENDED") return false;
  197. }
  198. return !row.status || (row.status == "active" && row.step == "purchase_apply");
  199. },
  200. async getProjects() {
  201. this.projects = await this.$API.system.project.all({ orderBy: "id_desc", projectStatus: "active" });
  202. },
  203. async getPurchaseTypes() {
  204. const res = await this.$API.system.dictDetail.get({ page: 0, size: 999, dictName: "procurement_type" });
  205. this.purchaseTypes = res.content;
  206. },
  207. async getSpecialTypes() {
  208. const res = await this.$API.system.dictDetail.get({ page: 0, size: 999, dictName: "special_expenses_type" });
  209. this.specialTypes = res.content;
  210. },
  211. // 本地更新数据
  212. reloadTable(mode = "add") {
  213. this.params["createTimeBegin"] = this.createDate && this.createDate[0] && (this.createDate[0] + " 00:00:00") || "";
  214. this.params["createTimeEnd"] = this.createDate && this.createDate[1] && (this.createDate[1] + " 23:59:59") || "";
  215. const page = mode == "add" && 1 || this.$refs.table.currentPage;
  216. this.$refs.table.reload(this.params, page);
  217. },
  218. reset() {
  219. this.createDate = [];
  220. for (const key in this.params) {
  221. if (key != "orderBy") this.params[key] = null;
  222. }
  223. this.reloadTable();
  224. },
  225. dateChange(type) {
  226. this.createDate = [moment().startOf(type).format("YYYY-MM-DD"), moment().format("YYYY-MM-DD")];
  227. this.reloadTable();
  228. },
  229. selectable(row) {
  230. return !this.selectData || this.selectData.id == row.id;
  231. },
  232. // 表格勾选事件
  233. select(rows, row) {
  234. this.selectData = rows.length && rows.indexOf(row) !== -1 && Object.assign({}, row) || null;
  235. },
  236. // 添加申请
  237. table_add() {
  238. this.dialog.detail = true;
  239. this.$nextTick(() => this.$refs.applyDetail.open());
  240. },
  241. // 申请编辑/详情/审批流
  242. table_detail(row) {
  243. this.dialog.detail = true;
  244. this.$nextTick(() => this.$refs.applyDetail.open("edit").setData(row));
  245. },
  246. table_handle(command, selected = this.selectData) {
  247. if (!selected) return this.$notify.warning({ title: "提示", message: "请选择一个采购申请", duration: 1500 });
  248. this.dialog.handle = true;
  249. this.$nextTick(() => this.$refs.handleDetail.open(command).setData(selected, selected[this.handlerKey(command)]));
  250. },
  251. // 删除申请
  252. table_del({ id }) {
  253. this.$confirm("确认删除当前采购申请吗?", "提示", {
  254. type: "warning",
  255. confirmButtonText: "删除"
  256. }).then(() => {
  257. this.$API.procurement.apply.del({ id }).then(() => {
  258. this.$message.success("操作成功");
  259. this.reloadTable();
  260. }).catch(() => {});
  261. }).catch(() => {});
  262. },
  263. // oa 情况通知-是否开启
  264. openChange(status, { id, oaStatus }) {
  265. if (status === 1 && (oaStatus === undefined || oaStatus === null)) return;
  266. this.loading = true;
  267. this.$API.auth.oa.updateStatus({ id, status }).then(() => {
  268. this.loading = false;
  269. this.$message.success("操作成功");
  270. this.reloadTable("update");
  271. }).catch(() => this.loading = false);
  272. }
  273. }
  274. }
  275. </script>
  276. <style lang="scss" scoped>
  277. .aminui-main-container .aminui-main-container__table-main .scTable {
  278. :deep(.el-table__header) .el-checkbox {
  279. display: none;
  280. }
  281. }
  282. @media (max-width: 992px) {
  283. .aminui-main-container .aminui-main-container__query-header {
  284. padding-bottom: 18px;
  285. }
  286. }
  287. </style>