|
|
@@ -0,0 +1,365 @@
|
|
|
+<template>
|
|
|
+ <div class="edit-view">
|
|
|
+ <div id="gstc"></div>
|
|
|
+ <el-dialog :visible.sync="showEditDialog" :title="formData.id ? '编辑' : '添加'" width="600px">
|
|
|
+ <el-form
|
|
|
+ :model="formData"
|
|
|
+ :rules="rules"
|
|
|
+ ref="form"
|
|
|
+ label-width="80px"
|
|
|
+ label-position="right"
|
|
|
+ size="small"
|
|
|
+ style="max-width: 500px;"
|
|
|
+ >
|
|
|
+ <el-form-item prop="name" label="工序名称">
|
|
|
+ <el-input v-model="formData.name"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item prop="planStart" label="计划开工">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="formData.planStart"
|
|
|
+ type="date"
|
|
|
+ value-format="yyyy-MM-dd"
|
|
|
+ placeholder="选择日期"
|
|
|
+ >
|
|
|
+ </el-date-picker>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item prop="planEnd" label="计划结束">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="formData.planEnd"
|
|
|
+ type="date"
|
|
|
+ value-format="yyyy-MM-dd"
|
|
|
+ placeholder="选择日期"
|
|
|
+ >
|
|
|
+ </el-date-picker>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item prop="days" label="工期">
|
|
|
+ <el-input-number v-model="formData.days"></el-input-number>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item prop="principal" label="负责人">
|
|
|
+ <el-input v-model="formData.principal"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item prop="start" label="开工时间">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="formData.start"
|
|
|
+ type="date"
|
|
|
+ value-format="yyyy-MM-dd"
|
|
|
+ placeholder="选择日期"
|
|
|
+ >
|
|
|
+ </el-date-picker>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item prop="end" label="结束时间">
|
|
|
+ <el-date-picker v-model="formData.end" type="date" value-format="yyyy-MM-dd" placeholder="选择日期">
|
|
|
+ </el-date-picker>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item prop="remark" label="模版">
|
|
|
+ <el-input v-model="formData.remark"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item prop="status" label="状态">
|
|
|
+ <el-select v-model="formData.status" clearable filterable placeholder="请选择">
|
|
|
+ <el-option
|
|
|
+ v-for="item in statusOptions"
|
|
|
+ :key="item.value"
|
|
|
+ :label="item.label"
|
|
|
+ :value="item.value"
|
|
|
+ >
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <div slot="footer">
|
|
|
+ <el-button @click="showEditDialog = false" :disabled="saving">取消</el-button>
|
|
|
+ <el-button @click="onSave" :loading="saving" type="primary">保存</el-button>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+<script>
|
|
|
+import GSTC from 'gantt-schedule-timeline-calendar';
|
|
|
+import zhCN from 'dayjs/locale/zh-cn';
|
|
|
+import 'gantt-schedule-timeline-calendar/dist/style.css';
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: 'ConstructionGantt',
|
|
|
+ created() {},
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ showEditDialog: true,
|
|
|
+ saving: false,
|
|
|
+ formData: {
|
|
|
+ status: 'PENDING'
|
|
|
+ },
|
|
|
+ rules: {
|
|
|
+ constructionId: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: '请输入项目',
|
|
|
+ trigger: 'blur'
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ name: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: '请输入工序名称',
|
|
|
+ trigger: 'blur'
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ planStart: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: '请输入计划开工',
|
|
|
+ trigger: 'blur'
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ planEnd: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: '请输入计划结束',
|
|
|
+ trigger: 'blur'
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ days: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: '请输入工期',
|
|
|
+ trigger: 'blur'
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ principal: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: '请输入负责人',
|
|
|
+ trigger: 'blur'
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ status: [
|
|
|
+ {
|
|
|
+ required: true,
|
|
|
+ message: '请输入状态',
|
|
|
+ trigger: 'blur'
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ constructionIdOptions: [],
|
|
|
+ statusOptions: [
|
|
|
+ { label: '未开工', value: 'PENDING' },
|
|
|
+ { label: '已开工', value: 'IN_PROGRESS' },
|
|
|
+ { label: '已暂停', value: 'PAUSE' },
|
|
|
+ { label: '已完工', value: 'FINISH' }
|
|
|
+ ]
|
|
|
+ };
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ function editRow(row) {
|
|
|
+ console.log(row);
|
|
|
+ }
|
|
|
+ const addRow = () => {
|
|
|
+ if (this.$refs.form) {
|
|
|
+ this.$refs.form.clearValidate();
|
|
|
+ }
|
|
|
+ this.formData = { status: 'PENDING' };
|
|
|
+ this.showEditDialog = true;
|
|
|
+ };
|
|
|
+ const rowsFromDB = [
|
|
|
+ {
|
|
|
+ id: '1',
|
|
|
+ label: 'Row 1'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '2',
|
|
|
+ label: 'Row 2'
|
|
|
+ }
|
|
|
+ ];
|
|
|
+
|
|
|
+ const itemsFromDB = [
|
|
|
+ {
|
|
|
+ id: '1',
|
|
|
+ label: 'Item 1',
|
|
|
+ rowId: '1',
|
|
|
+ time: {
|
|
|
+ start: GSTC.api
|
|
|
+ .date('2020-01-01')
|
|
|
+ .startOf('day')
|
|
|
+ .valueOf(),
|
|
|
+ end: GSTC.api
|
|
|
+ .date('2020-01-02')
|
|
|
+ .endOf('day')
|
|
|
+ .valueOf()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '2',
|
|
|
+ label: 'Item 2',
|
|
|
+ rowId: '1',
|
|
|
+ time: {
|
|
|
+ start: GSTC.api
|
|
|
+ .date('2020-02-01')
|
|
|
+ .startOf('day')
|
|
|
+ .valueOf(),
|
|
|
+ end: GSTC.api
|
|
|
+ .date('2020-02-02')
|
|
|
+ .endOf('day')
|
|
|
+ .valueOf()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '3',
|
|
|
+ label: 'Item 3',
|
|
|
+ rowId: '2',
|
|
|
+ time: {
|
|
|
+ start: GSTC.api
|
|
|
+ .date('2020-01-15')
|
|
|
+ .startOf('day')
|
|
|
+ .valueOf(),
|
|
|
+ end: GSTC.api
|
|
|
+ .date('2020-01-20')
|
|
|
+ .endOf('day')
|
|
|
+ .valueOf()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ];
|
|
|
+
|
|
|
+ const columnsFromDB = [
|
|
|
+ {
|
|
|
+ id: '1',
|
|
|
+ data: ({ row }) => GSTC.api.sourceID(row.id), // show original id (not internal GSTCID)
|
|
|
+ sortable: ({ row }) => Number(GSTC.api.sourceID(row.id)), // sort by id converted to number
|
|
|
+ width: 80,
|
|
|
+ header: {
|
|
|
+ content: '任务'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '2',
|
|
|
+ data: 'label',
|
|
|
+ sortable: 'label',
|
|
|
+ isHTML: false,
|
|
|
+ width: 150,
|
|
|
+ header: {
|
|
|
+ content: '开工时间'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '3',
|
|
|
+ data: 'label',
|
|
|
+ sortable: 'label',
|
|
|
+ isHTML: false,
|
|
|
+ width: 80,
|
|
|
+ header: {
|
|
|
+ content: '工期'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '4',
|
|
|
+ data: 'label',
|
|
|
+ sortable: 'label',
|
|
|
+ isHTML: false,
|
|
|
+ width: 80,
|
|
|
+ header: {
|
|
|
+ content: '状态'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '5',
|
|
|
+ data: 'label',
|
|
|
+ sortable: 'label',
|
|
|
+ isHTML: false,
|
|
|
+ width: 80,
|
|
|
+ header: {
|
|
|
+ content: '负责人'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: '6',
|
|
|
+ data: ({ row, vido }) => {
|
|
|
+ return vido.html`<div class="gantt-cell-edit"><i class="el-icon-edit-outline" @click="${editRow}"></i></div>`;
|
|
|
+ },
|
|
|
+ sortable: false,
|
|
|
+ isHTML: false,
|
|
|
+ width: 60,
|
|
|
+ header: {
|
|
|
+ content: ({ column, vido }) => {
|
|
|
+ return vido.html`<div class="gantt-cell-edit" @click="${addRow}"><i class="el-icon-plus"></i></div>`;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ];
|
|
|
+
|
|
|
+ // Configuration obwject
|
|
|
+ const config = {
|
|
|
+ locale: zhCN,
|
|
|
+ // for free key for your domain please visit https://gstc.neuronet.io/free-key
|
|
|
+ // if you need commercial license please visit https://gantt-schedule-timeline-calendar.neuronet.io/pricing
|
|
|
+ licenseKey:
|
|
|
+ '====BEGIN LICENSE KEY====\nDi0BwKt1EDipAthYGKPXKRDyOWCs03a0nuEOLzxj0EFwoJhDBJhrTsEapJmQ8FQvZdHTTHDG0A6/72Vnq6jCdzqp+7kBMN5kcwRBCMmjSwczcv+2CfQnvek6M/4vHjzqoUQGwEcUXB9JSCFPpAeXasAArp7daRCAQXnOJPMQCmXy/UQoERG4thVPyR5RO5IQMI4dHPO1bNTFArZ5nGwhI1IqBAWLTN3QtPY3je75xW7OH0nhwEFWPl6wA6rRNg282oXfbIdE37Z7mo4FqjXAr2reDElgfxJt0UI9rdHMZk7cZum5hplm4u42NB6RByAt5KJj9w+5u+L/wrUm1RkRFQ==||U2FsdGVkX19Jj6Q/ofSmRAwcXf7vH4ZhkFejzm+pemDiL10NTcMn2hX7WF3JvPirRQBKuyZsyyJEpV6EZNZrLDcwTK+Jz0etUlnDIE6P2Sg=\nqN4naIrZdUg8X/KleT/35brcIj+F5muQ1HK6Gc9ufEDc40DKw/SThRPrHLmLBtboXt0TR8+KfuTiKF232Bkrn6CGhqD+w3C+7rhYOPpgaBV+x5/D6e9zZeMS4/a4KM2lzYZmN0ZqgtWjxS3qmzNYTpG3gl58w9VD8QmbRkI5kMH3HWdQjeXfiSdesobU9IIz6Kqx9YoHGViOKLu6oOFrOY4fsNFqxQ6yqLScczPm06NFGicYbTnuX/cwXJcWuXAlqT4bYU8Llg5kFBKX8YXzd2PdRtSWzOHh6xOIVjeqXInYCxqKmHnzoopgxWJyUbYA9VKIMW7WuJq+gsDN8SRpXg==\n====END LICENSE KEY====',
|
|
|
+
|
|
|
+ list: {
|
|
|
+ columns: {
|
|
|
+ data: GSTC.api.fromArray(columnsFromDB)
|
|
|
+ },
|
|
|
+ rows: GSTC.api.fromArray(rowsFromDB)
|
|
|
+ },
|
|
|
+ chart: {
|
|
|
+ items: GSTC.api.fromArray(itemsFromDB)
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // Generate GSTC state from configuration object
|
|
|
+ const state = GSTC.api.stateFromConfig(config);
|
|
|
+ // Mount the component
|
|
|
+ const app = GSTC({
|
|
|
+ element: document.getElementById('gstc'),
|
|
|
+ state
|
|
|
+ });
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ onSave() {
|
|
|
+ this.$refs.form.validate(valid => {
|
|
|
+ if (valid) {
|
|
|
+ this.submit();
|
|
|
+ } else {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ submit() {
|
|
|
+ let data = { ...this.formData, constructionId: this.$route.query.id };
|
|
|
+
|
|
|
+ this.saving = true;
|
|
|
+ this.$http
|
|
|
+ .post('/constructionProcess/save', data, { body: 'json' })
|
|
|
+ .then(res => {
|
|
|
+ this.saving = false;
|
|
|
+ this.$message.success('成功');
|
|
|
+ this.showEditDialog = false;
|
|
|
+ })
|
|
|
+ .catch(e => {
|
|
|
+ this.saving = false;
|
|
|
+ this.$message.error(e.error);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ onDelete() {
|
|
|
+ this.$alert('删除将无法恢复,确认要删除么?', '警告', { type: 'error' })
|
|
|
+ .then(() => {
|
|
|
+ return this.$http.post(`/constructionProcess/del/${this.formData.id}`);
|
|
|
+ })
|
|
|
+ .then(() => {
|
|
|
+ this.$message.success('删除成功');
|
|
|
+ this.$router.go(-1);
|
|
|
+ })
|
|
|
+ .catch(e => {
|
|
|
+ if (e !== 'cancel') {
|
|
|
+ console.log(e);
|
|
|
+ this.$message.error(e.error);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+</script>
|
|
|
+<style lang="less">
|
|
|
+.gantt-cell-edit {
|
|
|
+ text-align: center;
|
|
|
+ cursor: pointer;
|
|
|
+ font-size: 18px;
|
|
|
+}
|
|
|
+</style>
|